UNPKG

7.15 kBJavaScriptView Raw
1"use strict";
2
3var Compiler = require("./Compiler");
4var Walker = require("./Walker");
5var Parser = require("./Parser");
6var HtmlJsParser = require("./HtmlJsParser");
7var Builder = require("./Builder");
8var extend = require("raptor-util/extend");
9var CompileContext = require("./CompileContext");
10var globalConfig = require("./config");
11var ok = require("assert").ok;
12var fs = require("fs");
13var taglib = require("../taglib");
14var defaults = extend({}, globalConfig);
15
16Object.defineProperty(exports, "defaultOptions", {
17 get: function() {
18 return globalConfig;
19 },
20 enumerable: true,
21 configurable: false
22});
23
24Object.defineProperty(exports, "config", {
25 get: function() {
26 return globalConfig;
27 },
28 enumerable: true,
29 configurable: false
30});
31
32var defaultParser = new Parser(new HtmlJsParser());
33
34function configure(newConfig) {
35 if (!newConfig) {
36 newConfig = {};
37 }
38
39 globalConfig = extend({}, defaults);
40 extend(globalConfig, newConfig);
41}
42
43var defaultCompiler = new Compiler({
44 parser: defaultParser,
45 builder: Builder.DEFAULT_BUILDER
46});
47
48function createBuilder(options) {
49 return new Builder(options);
50}
51
52function createWalker(options) {
53 return new Walker(options);
54}
55
56function isXML(path) {
57 return path.endsWith(".xml") || path.endsWith(".xml.marko");
58}
59
60function _compile(src, filename, userOptions, callback) {
61 registerCoreTaglibs();
62
63 ok(filename, '"filename" argument is required');
64 ok(typeof filename === "string", '"filename" argument should be a string');
65
66 var options = {};
67
68 extend(options, globalConfig);
69
70 if (userOptions) {
71 extend(options, userOptions);
72 }
73
74 var compiler = defaultCompiler;
75
76 if (isXML(filename)) {
77 require("complain")("Using Marko to build XML is deprecated");
78 options.ignoreUnrecognizedTags = true;
79 }
80
81 const context = new CompileContext(src, filename, compiler.builder, options);
82
83 let result;
84
85 try {
86 const compiled = compiler.compile(src, context);
87 result = userOptions.sourceOnly ? compiled.code : compiled;
88 } catch (e) {
89 if (callback) {
90 return callback(e);
91 } else {
92 throw e;
93 }
94 }
95
96 if (callback) {
97 callback(null, result);
98 } else {
99 return result;
100 }
101}
102
103function compile(src, filename, options, callback) {
104 if (typeof options === "function") {
105 callback = options;
106 options = null;
107 }
108
109 options = options || {};
110 options.sourceOnly = options.sourceOnly !== false;
111
112 return _compile(src, filename, options, callback);
113}
114
115function compileForBrowser(src, filename, options, callback) {
116 if (typeof options === "function") {
117 callback = options;
118 options = null;
119 }
120
121 options = extend(
122 {
123 output: "vdom",
124 meta: false,
125 browser: true,
126 sourceOnly: false
127 },
128 options
129 );
130
131 return compile(src, filename, options, callback);
132}
133
134function compileFile(filename, options, callback) {
135 if (typeof options === "function") {
136 callback = options;
137 options = null;
138 }
139
140 options = options || {};
141 options.sourceOnly = options.sourceOnly !== false;
142
143 if (callback) {
144 fs.readFile(filename, { encoding: "utf8" }, function(err, templateSrc) {
145 if (err) {
146 return callback(err);
147 }
148
149 _compile(templateSrc, filename, options, callback);
150 });
151 } else {
152 let templateSrc = fs.readFileSync(filename, { encoding: "utf8" });
153 return _compile(templateSrc, filename, options, callback);
154 }
155}
156
157function compileFileForBrowser(filename, options, callback) {
158 if (typeof options === "function") {
159 callback = options;
160 options = null;
161 }
162
163 options = extend(
164 { output: "vdom", meta: false, browser: true, sourceOnly: false },
165 options
166 );
167 return compileFile(filename, options, callback);
168}
169
170function checkUpToDate(/*templateFile, templateJsFile*/) {
171 return false; // TODO Implement checkUpToDate
172}
173
174function getLastModified(path, options, callback) {
175 if (typeof options === "function") {
176 callback = options;
177 options = null;
178 }
179
180 callback(null, -1); // TODO Implement getLastModified
181}
182
183function clearCaches() {
184 taglib.clearCache();
185}
186
187function parseRaw(templateSrc, filename, options) {
188 return parse(
189 templateSrc,
190 filename,
191 Object.assign(
192 {
193 raw: true,
194 ignorePlaceholders: true
195 },
196 options
197 )
198 );
199}
200
201function parse(templateSrc, filename, options) {
202 registerCoreTaglibs();
203 var context = new CompileContext(
204 templateSrc,
205 filename,
206 Builder.DEFAULT_BUILDER
207 );
208
209 if (options.onContext) {
210 options.onContext(context);
211 }
212 var parsed = defaultParser.parse(templateSrc, context, options);
213
214 if (context.hasErrors()) {
215 var errors = context.getErrors();
216
217 var message =
218 'An error occurred while trying to parse template at path "' +
219 filename +
220 '". Error(s) in template:\n';
221 for (var i = 0, len = errors.length; i < len; i++) {
222 let error = errors[i];
223 message += i + 1 + ") " + error.toString() + "\n";
224 }
225 var error = new Error(message);
226 error.errors = errors;
227 throw error;
228 }
229
230 return parsed;
231}
232
233exports.createBuilder = createBuilder;
234exports.compileFile = compileFile;
235exports.compile = compile;
236exports.compileForBrowser = compileForBrowser;
237exports.compileFileForBrowser = compileFileForBrowser;
238exports.parseRaw = parseRaw;
239exports.parse = parse;
240
241exports.checkUpToDate = checkUpToDate;
242exports.getLastModified = getLastModified;
243exports.createWalker = createWalker;
244exports.builder = Builder.DEFAULT_BUILDER;
245exports.configure = configure;
246exports.clearCaches = clearCaches;
247
248exports.taglibLookup = taglib.lookup;
249exports.taglibLoader = taglib.loader;
250exports.taglibFinder = taglib.finder;
251
252var coreTaglibsRegistered = false;
253
254function registerCoreTaglibs() {
255 if (!coreTaglibsRegistered) {
256 coreTaglibsRegistered = true;
257 taglib.register(
258 require("../core-tags/cache/marko.json"),
259 require.resolve("../core-tags/cache/marko.json")
260 );
261 taglib.register(
262 require("../core-tags/components/marko.json"),
263 require.resolve("../core-tags/components/marko.json")
264 );
265 taglib.register(
266 require("../core-tags/core/marko.json"),
267 require.resolve("../core-tags/core/marko.json")
268 );
269 taglib.register(
270 require("../core-tags/html/marko.json"),
271 require.resolve("../core-tags/html/marko.json")
272 );
273 taglib.register(
274 require("../core-tags/migrate/marko.json"),
275 require.resolve("../core-tags/migrate/marko.json")
276 );
277 taglib.register(
278 require("../core-tags/svg/marko.json"),
279 require.resolve("../core-tags/svg/marko.json")
280 );
281 taglib.register(
282 require("../core-tags/math/marko.json"),
283 require.resolve("../core-tags/math/marko.json")
284 );
285 }
286}
287
288function buildTaglibLookup(dirname) {
289 registerCoreTaglibs();
290 return taglib.buildLookup(dirname);
291}
292
293exports.buildTaglibLookup = buildTaglibLookup;
294
295exports.registerTaglib = function(filePath) {
296 registerCoreTaglibs();
297
298 ok(typeof filePath === "string", '"filePath" should be a string');
299 taglib.registerFromFile(filePath);
300 clearCaches();
301};
302
303exports.isVDOMSupported = true;
304exports.modules = require("./modules");