1 | var FS = require("fs");
|
2 | var Path = require("path");
|
3 | var Tree = require("./htmltree");
|
4 | var Util = require("./util");
|
5 | var Fatal = require("./fatal");
|
6 | var Source = require("./source");
|
7 | var Template = require("./template");
|
8 | var ParserHTML = require("./tlk-htmlparser");
|
9 | var CompilerCOM = require("./compiler-com");
|
10 | var CompilerHTML = require("./compiler-html2");
|
11 |
|
12 |
|
13 | module.exports = function(source, components, scopes, output) {
|
14 | var ID = 0;
|
15 | function setVar(key, val) {
|
16 | scopes[scopes.length - 1][key] = val;
|
17 | }
|
18 | function getVar(key) {
|
19 | var k, v;
|
20 | for (k = scopes.length - 1; k >= 0; k--) {
|
21 | v = scopes[k][key];
|
22 | if (typeof v !== 'undefined') {
|
23 | return v;
|
24 | }
|
25 | }
|
26 | return '';
|
27 | }
|
28 |
|
29 | var compilationOptions = {};
|
30 |
|
31 | var prj = source.prj();
|
32 |
|
33 | |
34 |
|
35 |
|
36 |
|
37 | function dirname() {
|
38 | var absoluteDirname = Path.dirname(source.getAbsoluteFilePath());
|
39 | var absoluteSrcPath = source.prj().srcPath();
|
40 | return absoluteDirname.substr(absoluteSrcPath.length);
|
41 | }
|
42 |
|
43 | var libs = {
|
44 | Tree: Tree,
|
45 | Template: Template,
|
46 |
|
47 | compileHTML: function(src) {
|
48 | CompilerHTML.compile(src, compilationOptions);
|
49 | output.include[src] = 1;
|
50 | },
|
51 | |
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 | getBackToRoot: function (path) {
|
58 |
|
59 | var standardFolderSepCount = 0;
|
60 |
|
61 | var windowsFolderSepCount = 0;
|
62 |
|
63 | var i;
|
64 |
|
65 | var c;
|
66 |
|
67 | for (i = 0; i < path.length; i++) {
|
68 | c = path.charAt(i);
|
69 | if (c == '/') standardFolderSepCount++;
|
70 | if (c == '\\') windowsFolderSepCount++;
|
71 | }
|
72 | var folderSepCount = Math.max(standardFolderSepCount, windowsFolderSepCount);
|
73 | if (folderSepCount == 0) {
|
74 |
|
75 | return '';
|
76 | }
|
77 |
|
78 | var result = '';
|
79 | var folderSep = '/';
|
80 | for (i = 0; i < folderSepCount; i++) {
|
81 | result += '..' + folderSep;
|
82 | }
|
83 | return result;
|
84 | },
|
85 | fatal: function(msg, tree) {
|
86 | if (typeof tree !== 'undefined' && typeof tree.pos === 'number') {
|
87 | msg += "\n\n" + Fatal.extractCodeAtPos(source.read(), tree.pos);
|
88 | }
|
89 | Fatal.fire(msg, "Component");
|
90 | },
|
91 | warning: function(msg, filename, content, pos) {
|
92 | filename = filename || source.name();
|
93 | console.log("------------------------------------------------------------".yellow);
|
94 | console.log("Warning in file ".bold.yellow + filename.cyan.bold);
|
95 | console.log(msg.bold.yellow);
|
96 | console.log();
|
97 | if (typeof content === 'string') {
|
98 |
|
99 | console.log(Fatal.extractCodeAtPos(content, pos).yellow);
|
100 | }
|
101 | },
|
102 | nextID: function() {
|
103 | ID++;
|
104 | return 'x-' + ID;
|
105 | },
|
106 | setVar: setVar,
|
107 | getVar: getVar,
|
108 | fileExists: function(relPath) {
|
109 | var name = Path.join( Path.dirname( source.name() ), relPath );
|
110 | var srcPath = source.prj().srcOrLibPath( name );
|
111 | return srcPath;
|
112 | },
|
113 | filePath: function(relPath) {
|
114 | var name = Path.join( Path.dirname( source.name() ), relPath );
|
115 | var srcPath = source.prj().srcOrLibPath( name );
|
116 | return srcPath;
|
117 | },
|
118 | |
119 |
|
120 |
|
121 |
|
122 | dirname: dirname,
|
123 | |
124 |
|
125 |
|
126 |
|
127 | htmPath: function(path) {
|
128 | return source.prj().srcPath(Path.join(dirname(), path));
|
129 | },
|
130 | readFileContent: function(relPath) {
|
131 | try {
|
132 | var name = Path.join( Path.dirname( source.name() ), relPath );
|
133 | var srcPath = source.prj().srcOrLibPath( name );
|
134 | if( !srcPath ) return "";
|
135 | return FS.readFileSync( srcPath ).toString();
|
136 | }
|
137 | catch (ex) {
|
138 | Fatal.bubble(ex, "readFileContent(\"" + relPath + "\")", "");
|
139 | }
|
140 | },
|
141 | addDynamicModule: function( name, code ) {
|
142 | output.dynamicModules['mod/' + name] =
|
143 | "require('" + name + "', function(exports, module) {\n"
|
144 | + code + "\});\n";
|
145 | },
|
146 | addDependency: function(dependency) {
|
147 | output.dependencies[dependency] = 1;
|
148 | },
|
149 | addInnerCSS: function(contentCSS) {
|
150 | output.innerCSS[contentCSS] = 1;
|
151 | },
|
152 | addInitJS: function(code) {
|
153 | output.initJS[code] = 1;
|
154 | },
|
155 | addPostInitJS: function(code) {
|
156 | output.postInitJS[code] = 1;
|
157 | },
|
158 | addInclude: function(src) {
|
159 | output.include[src] = 1;
|
160 | },
|
161 | addResourceText: function(name, dst, txt) {
|
162 | output.resource[name] = {dst: dst, txt: txt};
|
163 | },
|
164 | addResourceFile: function(name, dst, src) {
|
165 | output.resource[name] = {dst: dst, src: src};
|
166 | },
|
167 | require: function(moduleName) {
|
168 | var prefix = moduleName.substr(0, 4);
|
169 | if (prefix != 'mod/' && prefix != 'cls/') {
|
170 |
|
171 | moduleName = 'mod/' + moduleName;
|
172 | }
|
173 | output.require[moduleName] = 1;
|
174 | },
|
175 | parseHTML: ParserHTML.parse
|
176 | };
|
177 |
|
178 |
|
179 | var cfg = prj._config;
|
180 | setVar('$filename', source.name());
|
181 | setVar('$title', cfg.name);
|
182 | setVar('$author', cfg.author);
|
183 | setVar('$version', cfg.version);
|
184 |
|
185 |
|
186 | function compileChildren(root) {
|
187 | if (Array.isArray(root.children)) {
|
188 |
|
189 | var result = [];
|
190 | root.children.forEach(function (child) {
|
191 | libs.compile(child);
|
192 | if (child.type == Tree.VOID || typeof child.type === 'undefined') {
|
193 | result.push.apply( result, child.children );
|
194 | } else {
|
195 | result.push( child );
|
196 | }
|
197 | });
|
198 | root.children = result;
|
199 | }
|
200 | }
|
201 | libs.compileChildren = compileChildren;
|
202 | libs.compile = function(root, options) {
|
203 | compilationOptions = options;
|
204 | if (root.type !== Tree.TAG) {
|
205 | compileChildren(root);
|
206 | return;
|
207 | } else {
|
208 | var component = CompilerCOM.getCompilerForTag(root.name);
|
209 | if (component) {
|
210 | if (component.$.css) {
|
211 | libs.addInnerCSS(component.$.css);
|
212 | }
|
213 | if (component.$.res) {
|
214 |
|
215 | var dstPath = source.name();
|
216 | libs.addResourceFile(
|
217 | Path.join('com', component.$.id),
|
218 | Path.join('css', Path.dirname(dstPath), Path.join('com', component.$.id)),
|
219 | component.$.res
|
220 | );
|
221 | }
|
222 | try {
|
223 | scopes.push({});
|
224 | component.compile(root, libs);
|
225 | scopes.pop();
|
226 | }
|
227 | catch (ex) {
|
228 | Fatal.bubble(ex, "Tag: " + root.name + ", HTML file: " + source.name());
|
229 | }
|
230 | } else {
|
231 |
|
232 | compileChildren(root);
|
233 | }
|
234 | }
|
235 | };
|
236 | return libs;
|
237 | };
|