*
* usage : x = (new JsRender.NodeToJs(node)).munge();
*
+ *
+ * We are changing this to output as we go.
+ * However... since line-endings on properties have ',' (not ;) like vala.
+ * we have to be a bit smarter about how to output.
+ *
+ *
+ *
*/
static uint indent = 1;
static string indent_str = " ";
+
+
Node node;
Gee.ArrayList<string> doubleStringProps; // need to think if this is a good idea like this
string pad;
-
- Gee.ArrayList<string> els;
- //Gee.ArrayList<string> skip;
- Gee.HashMap<string,string> ar_props;
-
+ public JsRender renderer;
+
Gee.HashMap<string,string> out_props;
Gee.HashMap<string,string> out_listeners;
Gee.HashMap<string,Node> out_nodeprops;
NodeToJs top;
public string ret;
- int cur_line;
+ public int cur_line;
public NodeToJs( Node node, Gee.ArrayList<string> doubleStringProps, string pad, NodeToJs? parent)
this.doubleStringProps = doubleStringProps;
this.pad = pad;
- this.els = new Gee.ArrayList<string>();
- this.ar_props = new Gee.HashMap<string,string>();
+ //this.els = new Gee.ArrayList<string>();
+ //this.ar_props = new Gee.HashMap<string,string>();
+
+
+ // this is the bit that causes issues - we have to output as we go, otherwise we
+ // can not work out which line is which...
this.out_props = new Gee.HashMap<string,string>();
this.out_listeners = new Gee.HashMap<string,string>();
+
+
this.out_nodeprops = new Gee.HashMap<string,Node>() ;
this.out_children = new Gee.ArrayList<Node> ();
- this.out_props_array = new Gee.HashMap<string,Gee.ArrayList<Node>>() ;
+
+ this.out_props_array = new Gee.HashMap<string,Gee.ArrayList<Node>>(); // filled in by 'checkChildren'
this.out_props_array_plain = new Gee.HashMap<string,Gee.ArrayList<string>>() ;
- this.cur_line = parent == null ? 0 : parent.cur_line;
+ this.cur_line = parent == null ? 0 : parent.cur_line ; //-1 as we usuall concat onto the existin gline?
+ if (parent != null) {
+ this.renderer = parent.renderer;
+ }
this.ret = "";
this.top = parent == null ? this : parent.top;
-
+ // reset the maps...
+ if (parent == null) {
+ node.node_lines = new Gee.ArrayList<int>();
+ node.node_lines_map = new Gee.HashMap<int,Node>();
+ }
}
{
//return this.mungeToString(this.node);
- this.node.line_start = this.cur_line;
this.checkChildren();
this.readProps();
- this.readArrayProps();
+ //this.readArrayProps();
this.readListeners();
if (!this.node.props.has_key("* xinclude")) {
// no properties to output...
- if (this.els.size < 1) {
- return "";
- }
-
- this.mungeOut();
-
- // oprops...
-
- var spad = this.pad.substring(0, this.pad.length-indent);
-
-
- var str_props = gLibStringListJoin(",\n" + this.pad , this.els) ;
- //print ("STR PROPS: " + str_props);
-
-
-
- if (!this.node.props.has_key("* xinclude")) {
- return "{\n" +
- this.pad + str_props +
- "\n" + spad + "}";
- }
- // xinclude...
-
+ //if (this.els.size < 1) {
+ // return "";
+ //}
- return "Roo.apply(" + this.node.props.get("* xinclude") + "._tree(), "+
- "{\n" +
- this.pad + str_props +
- "\n" + spad + "})";
-
+ this.mungeOut();
+ return this.ret;
+
}
/**
});
return ret;
}
+ public Gee.ArrayList<string> orderedListenerKeys() {
+
+ var ret = new Gee.ArrayList<string> ();
+ var niter = this.out_listeners.map_iterator();
+ while(niter.next()) {
+ ret.add(niter.get_key());
+ }
+
+ ret.sort(( a, b) => {
+ return ((string)a).collate((string)b);
+ //if (a == b) return 0;
+ //return a < b ? -1 : 1;
+ });
+ return ret;
+ }
public string mungeOut()
{
-
+ this.node.line_start = this.cur_line;
+ this.top.node.setNodeLine(this.cur_line, this.node);
var spad = this.pad.substring(0, this.pad.length-indent);
if (this.node.props.has_key("* xinclude")) {
- this.addLine("Roo.apply(" + this.node.props.get("* xinclude") + "._tree(), {");
+ this.addLine("Roo.apply(" + this.node.props.get("* xinclude") + "._tree(), {",0 );
} else {
- this.addLine("{");
+ this.addLine("{", 0);
}
var suffix = "";
// output the items...
(this.out_children.size > 0 ? 1 : 0);
- // * prop
-
- var niter = this.out_nodeprops.map_iterator();
-
- while(niter.next()) {
- total_nodes--;
- suffix = total_nodes > 0 ? "," : "";
- this.addMultiLine(this.pad + niter.get_key() + " : " +
- this.mungeChildNew(this.pad + indent_str, niter.get_value()) + suffix
- );
- }
// plain properties.
- var iter = this.out_props.map_iterator();
+ var iter = this.orderedPropKeys().list_iterator();
while(iter.next()) {
total_nodes--;
suffix = total_nodes > 0 ? "," : "";
- this.addLine(this.pad + iter.get_key() + " : " + iter.get_value() + suffix);
+ var k = iter.get();
+ var v = this.out_props.get(k);
+
+ this.addLine(this.pad + k + " : " + v + suffix, ',');
}
- /*
- // out_props_array_plain -- not used?
- var paiter = this.out_props_array_plain.map_iterator();
-
- while(paiter.next()) {
+
+ // listeners..
+
+ if (this.out_listeners.size > 0 ) {
total_nodes--;
-
- this.addLine(this.pad + paiter.get_key() + " : [");
- var paliter = paiter.get_value().list_iterator();
- while (paliter.next()) {
- suffix = paliter.has_next() ? "," : "";
- this.addMultiLine(this.pad + indent_str + paliter.get() + suffix);
+ this.addLine(this.pad + "listeners : {", 0);
+ iter = this.orderedListenerKeys().list_iterator();
+
+ while(iter.next()) {
+
+ var k = iter.get();
+ var v = this.out_listeners.get(k);
+ this.addLine(this.pad + indent_str + k + " : ", '');
+ this.node.setLine(this.cur_line, ";",k);
+ this.addLine( v,',');
}
-
suffix = total_nodes > 0 ? "," : "";
-// this.mungeChild(this.pad + indent_str, niter.get_value())
- this.addLine(this.pad + "]" + suffix);
- }
- */
+ this.addLine(this.pad + "}" + suffix);
+
+ }
+ //------- at this point it is the end of the code relating directly to the object..
-
+ this.node.line_end = this.cur_line;
+
+
+
+ // * prop
+
+ var niter = this.out_nodeprops.map_iterator();
+
+ while(niter.next()) {
+ total_nodes--;
+ suffix = total_nodes > 0 ? "," : "";
+ var l = this.pad + niter.get_key() + " : " +
+ this.mungeChildNew(this.pad + indent_str, niter.get_value()) + suffix;
+ this.addMultiLine(l);
+ }
// prop arrays...
var piter = this.out_props_array.map_iterator();
this.addLine(this.pad + "]" + suffix);
}
- // listeners..
- if (this.out_listeners.size > 0 ) {
- total_nodes--;
- this.addLine(this.pad + "listeners : {");
- iter = this.out_listeners.map_iterator();
- var sz = this.out_listeners.size;
- while(iter.next()) {
- sz--;
- suffix = sz > 0 ? "," : "";
- this.addMultiLine(this.pad + indent_str + iter.get_key() + " : " + iter.get_value() + suffix);
- }
- suffix = total_nodes > 0 ? "," : "";
- this.addLine(this.pad + "}" + suffix);
-
- }
// children..
if (this.out_children.size > 0) {
this.addLine(this.pad + "items : [" );
this.ret += spad + "}";
}
-
+ this.node.sortLines();
return this.ret;
}
-
-
-
+ /**
+ * Line endings
+ * if we end with a ','
+ *
+ */
+
+ char last_line_end = 0;
- public void addLine(string str= "")
+ /**
+ * add a line - note we will end up with an extra line break
+ * at beginning of nodes doing this..
+ *
+ * @param str = text to add..
+ * @param line_end = 0 (just add a line break)
+ * line_end = ',' and ","
+ *
+ */
+ public void addLine(string str, char line_end)
{
- this.cur_line ++;
- this.ret += str+ "\n";
+ this.ret += (this.line_end == 0 ? "" : this.last_line_end) + "\n";
+ this.cur_line += str.split("\n").length;
+ this.ret += str;
+ //this.ret += "/*%d(%d-%d)*/ ".printf(this.cur_line -1, this.node.line_start,this.node.line_end) + str + "\n";
+
}
- public void addMultiLine(string str= "")
+/* public void addMultiLine(str= "")
{
-
- this.cur_line += str.split("\n").length;
- //this.ret += "/*%d*/ ".printf(l) + str + "\n";
+
+ //this.ret += "/ * %d(%d-%d) * / ".printf(this.cur_line, this.node.line_start,this.node.line_end)+ str + "\n";
this.ret += str + "\n";
+ this.cur_line += str.split("\n").length;
}
-
- string gLibStringListJoin( string sep, Gee.ArrayList<string> ar)
- {
- var ret = "";
- for (var i = 0; i < ar.size; i++) {
- ret += i>0 ? sep : "";
- ret += ar.get(i);
- }
- return ret;
-
- }
- public string mungeChild(string pad , Node cnode)
- {
- var x = new NodeToJs(cnode, this.doubleStringProps, pad, this);
- return x.munge();
- }
-
- public string mungeChildNew(string pad , Node cnode)
+ */
+ public string mungeChildNew(string pad , Node cnode )
{
var x = new NodeToJs(cnode, this.doubleStringProps, pad, this);
+
x.munge();
return x.ret;
}
-
+ /**
+ * loop through items[] array see if any of the children have '* prop'
+ * -- which means they are a property of this node.
+ * -- ADD TO : this.opt_props_array
+ *
+ */
public void checkChildren ()
{
//var prop = pl['*prop'] + '';
//delete pl['*prop'];
var prop = pl.get("* prop");
- print("got prop "+ prop + "\n");
+ //print("got prop "+ prop + "\n");
// name ends in [];
if (! Regex.match_simple("\\[\\]$", prop)) {
// munge property..??
this.out_nodeprops.set(prop, pl);
-
- this.els.add( prop + " : " + this.mungeChild ( this.pad + indent_str, pl));
-
-
- //keys.push(prop);
+
continue;
}
var sprop = prop.replace("[]", "");
- print("sprop is : " + sprop + "\n");
+ //print("sprop is : " + sprop + "\n");
// it's an array type..
- var old = "";
- if (!this.ar_props.has_key(sprop)) {
-
- this.ar_props.set(sprop, "");
+ //var old = "";
+ if (!this.out_props_array.has_key(sprop)) {
this.out_props_array.set(sprop, new Gee.ArrayList<Node>());
- } else {
- old = this.ar_props.get(sprop);
}
- var nstr = old += old.length > 0 ? ",\n" : "";
- nstr += this.mungeChild( this.pad + indent_str + indent_str + indent_str , pl);
+
+
this.out_props_array.get(sprop).add( pl);
- this.ar_props.set(sprop, nstr);
+ //this.ar_props.set(sprop, nstr);
}
Regex func_regex ;
if (this.node.props.has_key("$ xns")) {
- this.out_props.set("'|xns'", this.node.props.get("$ xns") );
+ this.out_props.set("'|xns'", "'" + this.node.props.get("$ xns") + "'" );
- this.els.add("'|xns' : '" + this.node.props.get("$ xns") + "'");
+ //this.els.add("'|xns' : '" + this.node.props.get("$ xns") + "'");
}
try {
func_regex = new Regex("^\\s+|\\s+$");
- } catch (Error e) {
+ } catch (RegexError e) {
print("failed to build regex");
return;
}
//return a < b ? -1 : 1;
});
-
+ var has_cms = this.node.has("cms-id");
for (var i = 0; i< keys.size; i++) {
var key = this.node.get_key(keys.get(i));
- print("ADD KEY %s\n", key);
+ //("ADD KEY %s\n", key);
string k;
string ktype;
string kflag;
if (kflag == ".") { // |. or . -- do not output..
continue;
}
- if (kflag == "*") {
+ if (kflag == "*") {
// ignore '* prop'; ???
continue;
- }
+ }
+
+ // handle cms-id // html
+ if (has_cms && k == "cms-id") {
+ continue; // ignore it...
+ }
+ // html must not be a dynamic property...
+ // note - we do not translate this either...
+ if (has_cms && k == "html" && kflag != "$") {
+
+
+ this.out_props.set("html", "Pman.Cms.content(" +
+ this.node.quoteString(this.renderer.name + "::" + this.node.get("cms-id")) +
+ ", " +
+ this.node.quoteString(v) +
+ ")");
+
+ continue;
+ }
+
+
if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
}
this.out_props.set(left, nstr);
//print("==> " + str + "\n");
- this.els.add(left + " : "+ nstr);
+ //this.els.add(left + " : "+ nstr);
continue;
}
// standard..
ktype.down() == "int"
) { // boolean or number...?
this.out_props.set(left, v.down());
- this.els.add(left + " : " + v.down() );
+ //this.els.add(left + " : " + v.down() );
continue;
}
// continue;
//}
- if (this.doubleStringProps.index_of(k) > -1) {
+ if ((this.doubleStringProps.index_of(k) > -1) ||
+ (ktype.down() == "string" && k[0] == '_')
+
+ ) {
// then use the translated version...
- this.els.add(left + " : _this._strings['" +
- GLib.Checksum.compute_for_string (ChecksumType.MD5, v) +
- "']"
- );
- this.out_props.set(left, "_this._strings['" +
- GLib.Checksum.compute_for_string (ChecksumType.MD5, v) +
- "']");
- continue;
- }
- if (ktype.down() == "string" && k[0] == '_') {
- this.els.add(left + " : _this._strings['" +
- GLib.Checksum.compute_for_string (ChecksumType.MD5, v) +
- "']"
- );
- this.out_props.set(left, " _this._strings['" +
- GLib.Checksum.compute_for_string (ChecksumType.MD5, v) +
- "']"
- );
-
+ var com = " /* " +
+ (v.split("\n").length > 1 ?
+ ("\n" + this.pad + string.joinv(this.pad + "\n", v.split("\n")).replace("*/", "* - /") + "\n" + this.pad + "*/ ") :
+ (v.replace("*/", "* - /") + " */")
+ );
+ //this.els.add(left + " : _this._strings['" +
+ // GLib.Checksum.compute_for_string (ChecksumType.MD5, v) +
+ // "']"
+ //);
+ this.out_props.set(left, "_this._strings['" +
+ GLib.Checksum.compute_for_string (ChecksumType.MD5, v.strip()) +
+ "']" + com);
continue;
}
+
// otherwise it needs to be encapsulated.. as single quotes..
var vv = this.node.quoteString(v);
// single quote.. v.substring(1, v.length-1).replace("'", "\\'") + "'";
- this.els.add(left + " : " + "'" + vv.substring(1, vv.length-2).replace("'", "\\'") + "'");
+ //this.els.add(left + " : " + "'" + vv.substring(1, vv.length-2).replace("'", "\\'") + "'");
this.out_props.set(left, "'" + vv.substring(1, vv.length-2).replace("'", "\\'") + "'");
}
}
- public void readArrayProps()
- {
-
- // this is not needed in the new version
- // as array props are handled more directly..
-
- // handle the childitems that are arrays.. eg. button[] = { }...
-
- // note this does not handle a mix of nodes and properties with the same
-
- string left;
-
- var iter = this.ar_props.map_iterator();
- while (iter.next()) {
- var k = iter.get_key();
- var right = iter.get_value();
-
- string leftv = k[0] == '|' ? k.substring(1) : k;
- if (Lang.isKeyword(leftv) || Lang.isBuiltin(leftv)) {
- left = "'" + leftv + "'";
- } else if (Regex.match_simple("[^A-Za-z_]+",leftv)) { // not plain a-z... - quoted.
- var val = this.node.quoteString(leftv);
-
- left = "'" + val.substring(1, val.length-2).replace("'", "\\'") + "'";
- } else {
- left = leftv;
- }
-
-
- if (right.length > 0){
- //if (this.out_props_array_plain.has_key(left)) {
- // this.out_props_array_plain.set(left, new Gee.ArrayList<string>());
- //}
- //this.out_props_array_plain.get(left).add(right);
-
- this.els.add(left + " : [\n" + this.pad + indent_str + indent_str +
- right + "\n" + this.pad + "]");
- }
-
-
- }
-
- }
+
public void readListeners()
{
//return a < b ? -1 : 1;
});
- var itms = "listeners : {\n";
-
+
for (var i = 0; i< keys.size; i++) {
var key = keys.get(i);
var val = this.node.listeners.get(key);
- itms += i >0 ? ",\n" : "";
- //
+ //
var str = val.strip();
var lines = str.split("\n");
if (lines.length > 0) {
//str = string.joinv("\n" + this.pad + " ", lines);
str = string.joinv("\n" + this.pad + indent_str + indent_str , lines);
}
-
- itms += this.pad + indent_str + key.replace("|", "") + " : " + str;
+
this.out_listeners.set(key.replace("|", "") ,str);
}
- itms += "\n" + this.pad + "}";
- //print ( "ADD " + itms);
- this.els.add(itms);
+
+
}
return;
}
var itms = "items : [\n";
- var n = 0;
+ //var n = 0;
for(var i = 0; i < this.node.items.size;i++) {
var ele = this.node.items.get(i);
if (ele.props.has_key("* prop")) {
continue;
}
- if (n > 0) {
- itms += ",\n";
- }
- n++;
- itms += this.pad + indent_str +
- this.mungeChild( this.pad + indent_str + indent_str , ele);
+
this.out_children.add(ele);
}
itms += "\n"+ this.pad + "]" + "\n";
- this.els.add(itms);
+ //this.els.add(itms);
}
// finally output listeners...