2ef840c953ad9189ada8026eeb92b3e079e198ec
[roobuilder] / src / JsRender / JsRender.vala
1 //<Script type="text/javascript">
2
3 namespace JsRender {
4
5
6         public errordomain Error {
7                 INVALID_FORMAT,
8                 RENAME_FILE_EXISTS
9         }
10                 
11         public abstract class JsRender  : Object {
12                 /**
13                  * @cfg {Array} doubleStringProps list of properties that can be double quoted.
14                  */
15                 public Gee.ArrayList<string> doubleStringProps;
16                 
17                 public string id;
18                 public string name;   // is the JS name of the file.
19                 public string fullname;
20                 public string path;  // is the full path to the file.
21                 public string parent;  // JS parent.
22                 public string region;  // RooJS - insert region.
23         
24                 public string title;  // a title.. ?? nickname.. ??? -
25                 public string build_module; // module to build if we compile (or are running tests...)
26                 
27
28                 public string permname;
29                 public string language;
30                 public string content_type;
31                 public string modOrder;
32                 public string xtype;
33                 public uint64 webkit_page_id; // set by webkit view - used to extract extension/etc..
34                     
35                 public Project.Project project;
36                 //Project : false, // link to container project!
37                 
38                 public Node tree; // the tree of nodes.
39                 
40                 public GLib.List<JsRender> cn; // child files.. (used by project ... should move code here..)
41
42                 public bool hasParent; 
43                 
44                 public bool loaded;
45                 
46                 public Gee.HashMap<string,string> transStrings; // map of md5 -> string.
47                 public  Gee.HashMap<string,string> namedStrings;
48
49                 public signal void changed (Node? node, string source); 
50                 
51                  
52                 public signal void compile_notice(string type, string file, int line, string message);
53                 /**
54                  * UI componenets
55                  * 
56                  */
57                 //public Xcls_Editor editor;
58                 
59                 
60                 
61                 //abstract JsRender(Project.Project project, string path); 
62                 
63                 public void aconstruct(Project.Project project, string path)
64                 {
65                     
66                         this.cn = new GLib.List<JsRender>();
67                         this.path = path;
68                         this.project = project;
69                         this.hasParent = false;
70                         this.parent = "";
71                         this.tree = null;
72                         this.title = "";
73                         this.region = "";
74                         this.permname = "";
75                         this.modOrder = "";
76                         this.language = "";
77                         this.content_type = "";
78                         this.build_module = "";
79                         this.loaded = false;
80                         //print("JsRender.cto() - reset transStrings\n");
81                         this.transStrings = new Gee.HashMap<string,string>();
82                         this.namedStrings = new Gee.HashMap<string,string>();
83                         // should use basename reallly...
84                         
85                         var ar = this.path.split("/");
86                         // name is in theory filename without .bjs (or .js eventually...)
87                         try {
88                                 Regex regex = new Regex ("\\.(bjs|js)$");
89
90                                 this.name = ar.length > 0 ? regex.replace(ar[ar.length-1],ar[ar.length-1].length, 0 , "") : "";
91                         } catch (GLib.Error e) {
92                                 this.name = "???";
93                         }
94                         this.fullname = (this.parent.length > 0 ? (this.parent + ".") : "" ) + this.name;
95
96                         this.doubleStringProps = new Gee.ArrayList<string>();
97
98                 }
99                 
100                 public void renameTo(string name) throws  Error
101                 {
102                         if (this.xtype == "PlainFile") {
103                                 return;
104                         }
105                         var bjs = GLib.Path.get_dirname(this.path) +"/" +  name + ".bjs";
106                         if (FileUtils.test(bjs, FileTest.EXISTS)) {
107                                 throw new Error.RENAME_FILE_EXISTS("File exists %s\n",name);
108                         }
109                         GLib.FileUtils.remove(this.path);
110                         this.removeFiles();
111                         // remove other files?
112                         
113                         this.name = name;
114                         this.path = bjs;
115                         
116                 }
117                 
118
119                 
120                 // not sure why xt is needed... -> project contains xtype..
121                 
122                 public static JsRender factory(string xt, Project.Project project, string path) throws Error
123                 {
124          
125                         switch (xt) {
126                                 case "Gtk":
127                                         return new Gtk(project, path);
128                                 case "Roo":
129                                         return new Roo(project, path);
130 //                      case "Flutter":
131 //                                      return new Flutter(project, path);
132                                 case "PlainFile":
133                                         return new PlainFile(project, path);
134                         }
135                         throw new Error.INVALID_FORMAT("JsRender Factory called with xtype=%s", xt);
136                         //return null;    
137                 }
138
139         
140         
141                 public string nickType()
142                 {
143                         var ar = this.name.split(".");
144                         string[] ret = {};
145                         for (var i =0; i < ar.length -1; i++) {
146                                 ret += ar[i];
147                         }
148                         return string.joinv(".", ret);
149                         
150                 }
151                 public string nickName()
152                 {
153                         var ar = this.name.split(".");
154                         return ar[ar.length-1];
155                         
156                 }
157                 
158                 public string nickNameSplit()
159                 {
160                         var n = this.nickName();
161                         var ret = "";
162                         var len = 0;
163                         for (var i = 0; i < n.length; i++) {
164                                 if (i!=0 && n.get(i).isupper() && len > 10) {
165                                         ret +="\n";
166                                         len= 0;
167                                 }
168                                 ret += n.get(i).to_string();
169                                 len++;
170                         }
171                         
172
173                         
174                         return ret;
175                 
176                 }
177
178                 
179                 public string getIconFileName(bool return_default)
180                 {
181                          
182                         var m5 = GLib.Checksum.compute_for_string(GLib.ChecksumType.MD5,this.path); 
183
184                         var dir = GLib.Environment.get_home_dir() + "/.Builder/icons";
185                         try {
186                                 if (!FileUtils.test(dir, FileTest.IS_DIR)) {
187                                          File.new_for_path(dir).make_directory();
188                                 }
189                         } catch (GLib.Error e) {
190                                 // eakk.. what to do here...
191                         }
192                         var fname = dir + "/" + m5 + ".png";
193                         
194                         if (!return_default) {
195                                 print("getIconFileName return %s\n", fname);
196                                 return fname;
197                         }
198                         
199                         if (FileUtils.test(fname, FileTest.EXISTS)) {
200                                 print("getIconFileName return %s\n", fname);
201                                 return fname;
202                         }
203                         // we need to create this somehow...
204                         print("getIconFileName return %s\n", GLib.Environment.get_home_dir() + "/.Builder/test.jpg");
205                         return  GLib.Environment.get_home_dir() + "/.Builder/test.jpg";
206
207                 }
208                 
209                 public string toJsonString()
210                 {
211                         if (this.xtype == "PlainFile") {
212                                 return "";
213                         }
214                         var node = new Json.Node(Json.NodeType.OBJECT);
215                         node.set_object(this.toJsonObject());                   
216                         var generator = new JsonGen(node);
217                     generator.indent = 1;
218                     generator.pretty = true;
219                     
220                         
221                         return generator.to_data();
222                 }
223                 
224                 public void saveBJS()
225                 {
226                     if (!this.loaded) {
227                             return;
228                     }
229                     if (this.xtype == "PlainFile") {
230                             return;
231                     }
232                    ;
233                      
234                     
235                     print("WRITE :%s\n " , this.path);// + "\n" + JSON.stringify(write));
236                     try {
237                                 this.writeFile(this.path, this.toJsonString());
238                          
239                     } catch(Error e) {
240                         print("Save failed");
241                     }
242                 }
243                  
244                  
245
246                 public abstract void loadItems() throws GLib.Error;
247                  
248                  
249                  
250                   
251                 public string jsonHasOrEmpty(Json.Object obj, string key) {
252                         return obj.has_member(key) ? 
253                                                 obj.get_string_member(key) : "";
254                 }
255
256                 
257                 public Json.Object toJsonObject ()
258                 {
259                     
260                     
261                         var ret = new Json.Object();
262                         if (this.xtype == "PlainFile") {
263                                 return ret;
264                         }
265                         
266                         //ret.set_string_member("id", this.id); // not relivant..
267                         ret.set_string_member("name", this.name);
268                         ret.set_string_member("parent", this.parent == null ? "" : this.parent);
269                         ret.set_string_member("title", this.title == null ? "" : this.title);
270                         ret.set_string_member("path", this.path);
271                         //ret.set_string_member("items", this.items);
272                         ret.set_string_member("permname", this.permname  == null ? "" : this.permname);
273                         ret.set_string_member("modOrder", this.modOrder  == null ? "" : this.modOrder);
274                         if (this.project.xtype == "Gtk") {
275                                 ret.set_string_member("build_module", this.build_module  == null ? "" : this.build_module);
276                         }
277                         
278                         if (this.transStrings.size > 0) {
279                                 var tr =  new Json.Object();
280                                 var iter = this.transStrings.map_iterator();
281                                 while (iter.next()) {
282                                         tr.set_string_member(iter.get_value(), iter.get_key());
283                                 }
284                                 ret.set_object_member("strings", tr);
285             }
286
287             
288             
289                         if (this.namedStrings.size > 0) {
290                                 var tr =  new Json.Object();
291                                 var iter = this.namedStrings.map_iterator();
292                                 while (iter.next()) {
293                                         tr.set_string_member(iter.get_key(), iter.get_value());
294                                 }
295                                 ret.set_object_member("named_strings", tr);
296             }
297                         
298                         var ar = new Json.Array();
299                         // empty files do not have a tree.
300                         if (this.tree != null) {
301                                 ar.add_object_element(this.tree.toJsonObject());
302                         }
303                         ret.set_array_member("items", ar);
304                 
305                     return ret;
306                 }
307                 
308                 
309
310                 public string getTitle ()
311                 {
312                     if (this.title.length > 0) {
313                         return this.title;
314                     }
315                     var a = this.path.split("/");
316                     return a[a.length-1];
317                 }
318                 public string getTitleTip()
319                 {
320                     if (this.title.length > 0) {
321                         return "<b>" + this.title + "</b> " + this.path;
322                     }
323                     return this.path;
324                 }
325                 /*
326                     sortCn: function()
327                     {
328                         this.cn.sort(function(a,b) {
329                             return a.path > b.path;// ? 1 : -1;
330                         });
331                     },
332                 */
333                     // should be in palete provider really..
334
335
336                 public Palete.Palete palete()
337                 {
338                         // error on plainfile?
339                         return this.project.palete;
340
341                 }
342                 
343                 public string guessName(Node ar) // turns the object into full name.
344                 {
345                      // eg. xns: Roo, xtype: XXX -> Roo.xxx
346                     if (!ar.hasXnsType()) {
347                        return "";
348                     }
349                     
350                     return ar.get("xns") + "." + ar.get("xtype");
351                                       
352                                         
353                 }
354                 /**
355                  *  non-atomic write (replacement for put contents, as it creates temporary files.
356                  */
357                 public void writeFile(string path, string contents) throws GLib.IOError, GLib.Error
358                 {
359
360                                  
361                         var f = GLib.File.new_for_path(path);
362                         var data_out = new GLib.DataOutputStream(
363                                           f.replace(null, false, GLib.FileCreateFlags.NONE, null)
364                        );
365                         data_out.put_string(contents, null);
366                         data_out.close(null);
367                 }
368                  
369                 
370                 
371                 public  Node? lineToNode(int line)
372                 {
373                         if (this.tree == null) {
374                                 return null;
375                         }
376                         return this.tree.lineToNode(line);
377                         
378                         
379                 }
380                 
381                 
382                 public abstract void save();
383                 public abstract void saveHTML(string html);
384                 public abstract string toSource() ;
385                 public abstract string toSourceCode() ; // used by commandline tester..
386                 public abstract void setSource(string str);
387                 public abstract string toSourcePreview() ;
388                 public abstract void removeFiles() ;
389                 public abstract void  findTransStrings(Node? node );
390                 public abstract string toGlade();
391                 public abstract string targetName();
392         } 
393
394 }
395