1 | define([ |
---|
2 | "require", |
---|
3 | "../buildControl", |
---|
4 | "../fileUtils", |
---|
5 | "../removeComments", |
---|
6 | "dojo/json", |
---|
7 | "dojo/_base/lang", |
---|
8 | "dojo/_base/loader", |
---|
9 | "../fs" |
---|
10 | ], function(require, bc, fileUtils, removeComments, json, lang, syncLoader, fs){ |
---|
11 | return function(resource){ |
---|
12 | var |
---|
13 | newline = bc.newline, |
---|
14 | |
---|
15 | mix = function(dest, src){ |
---|
16 | dest = dest || {}; |
---|
17 | for(var p in src){ |
---|
18 | dest[p] = src[p]; |
---|
19 | } |
---|
20 | return dest; |
---|
21 | }, |
---|
22 | |
---|
23 | absMid = 0, |
---|
24 | |
---|
25 | aggregateDeps = [], |
---|
26 | |
---|
27 | defineApplied = 0, |
---|
28 | |
---|
29 | simulatedDefine = function(mid, dependencies, factory){ |
---|
30 | defineApplied = 1; |
---|
31 | var arity = arguments.length, |
---|
32 | args = 0, |
---|
33 | defaultDeps = ["require", "exports", "module"]; |
---|
34 | |
---|
35 | // TODO: add the factory scan? |
---|
36 | if(bc.factoryScan && arity == 1 && typeof mid === 'function'){ |
---|
37 | dependencies = []; |
---|
38 | mid.toString() |
---|
39 | .replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "") |
---|
40 | .replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){ |
---|
41 | dependencies.push(dep); |
---|
42 | }); |
---|
43 | args = [0, defaultDeps.concat(dependencies), mid]; |
---|
44 | resource.text = resource.text.replace(/define\s*\(/, 'define(["' + args[1].join('","') + '"],'); |
---|
45 | } |
---|
46 | |
---|
47 | if(!args){ |
---|
48 | args = arity == 1 ? [0, defaultDeps, mid] : |
---|
49 | (arity == 2 ? (mid instanceof Array ? [0, mid, dependencies] : [mid, defaultDeps, dependencies]) : |
---|
50 | [mid, dependencies, factory]); |
---|
51 | } |
---|
52 | |
---|
53 | if(args[1].some(function(item){ |
---|
54 | return !lang.isString(item); |
---|
55 | })){ |
---|
56 | throw new Error("define dependency vector contains elements that are not of type string."); |
---|
57 | } |
---|
58 | |
---|
59 | absMid = args[0]; |
---|
60 | aggregateDeps = aggregateDeps.concat(args[1]); |
---|
61 | }, |
---|
62 | |
---|
63 | _tag_simulatedDefine = simulatedDefine.amd = { |
---|
64 | vendor:"dojotoolkit.org", |
---|
65 | context:"build" |
---|
66 | }, |
---|
67 | |
---|
68 | simulatedRequire = function(depsOrConfig, callbackOrDeps){ |
---|
69 | // add contents of deps vector to aggregateDeps iff it contains no relative ids; do not process deps property in config |
---|
70 | var hasRelativeIds = function(deps){ return deps.some(function(item){ return /^\./.test(item); }); }; |
---|
71 | if(lang.isArray(depsOrConfig) && !hasRelativeIds(depsOrConfig)){ |
---|
72 | aggregateDeps = aggregateDeps.concat(depsOrConfig); |
---|
73 | }else if(lang.isArray(callbackOrDeps) && !hasRelativeIds(callbackOrDeps)){ |
---|
74 | aggregateDeps = aggregateDeps.concat(callbackOrDeps); |
---|
75 | } |
---|
76 | }, |
---|
77 | |
---|
78 | slashName = function(dottedName){ |
---|
79 | return dottedName.replace(/\./g, "/"); |
---|
80 | }, |
---|
81 | |
---|
82 | pluginStrategyRequired = |
---|
83 | // truthy if dojo.loadInit|require[After]If|platformRequire detected that cannot be resolved at build-time; falsy otherwise |
---|
84 | 0, |
---|
85 | |
---|
86 | dojoProvides = |
---|
87 | // vector of modules dojo.provide'd by the resource |
---|
88 | [], |
---|
89 | |
---|
90 | dojoRequires = |
---|
91 | // vector of modules dojo.require'd by the resource |
---|
92 | [], |
---|
93 | |
---|
94 | simulatedDojo = |
---|
95 | // the dojo legacy loader API |
---|
96 | { |
---|
97 | require:function(moduleName, omitModuleCheck){ |
---|
98 | dojoRequires.push(slashName(moduleName)); |
---|
99 | }, |
---|
100 | provide:function(moduleName){ |
---|
101 | dojoProvides.push(slashName(moduleName)); |
---|
102 | }, |
---|
103 | requireLocalization: function(moduleName, bundleName, locale){ |
---|
104 | aggregateDeps.push("dojo/i18n!" + slashName(moduleName) + "/nls/" + (!locale || /root/i.test(locale) ? "" : locale + "/") + slashName(bundleName)); |
---|
105 | }, |
---|
106 | platformRequire:function(modMap){ |
---|
107 | pluginStrategyRequired = 1; |
---|
108 | (modMap.common || []).concat((bc.platform && modMap[bc.platform]) || []).forEach(function(item){ |
---|
109 | dojoRequires.push(lang.isArray(item) ? slashName(item[0]) : slashName(item)); |
---|
110 | }); |
---|
111 | }, |
---|
112 | loadInit:function(callback){ |
---|
113 | pluginStrategyRequired = 1; |
---|
114 | callback(); |
---|
115 | }, |
---|
116 | requireIf:function(expr, moduleName, omitModuleCheck){ |
---|
117 | pluginStrategyRequired = 1; |
---|
118 | expr && dojoRequires.push(slashName(moduleName)); |
---|
119 | }, |
---|
120 | requireAfterIf:function(expr, moduleName, omitModuleCheck){ |
---|
121 | pluginStrategyRequired = 1; |
---|
122 | expr && dojoRequires.push(slashName(moduleName)); |
---|
123 | } |
---|
124 | }, |
---|
125 | |
---|
126 | evaluatorWithNoRuntime = |
---|
127 | new Function("dojo", "__text", "eval(__text);"), |
---|
128 | |
---|
129 | applyLegacyCalls = function(callList){ |
---|
130 | var evaluator; |
---|
131 | if(resource.pack.runtime){ |
---|
132 | // if a runtime is provided, then a special evaluator has to be constructed |
---|
133 | var runtime = resource.pack.runtime, |
---|
134 | args = [], |
---|
135 | params = [], |
---|
136 | p; |
---|
137 | runtime.dojo = mix(runtime.dojo, simulatedDojo); |
---|
138 | for(p in runtime){ |
---|
139 | args.push(runtime[p]); |
---|
140 | params.push(p); |
---|
141 | } |
---|
142 | evaluator = new Function("__bc", "__args", "__text", "(function(" + params.join(",") + "){ eval(__text); }).apply(__bc, __args);"); |
---|
143 | args = [bc, args]; |
---|
144 | }else{ |
---|
145 | args = [simulatedDojo]; |
---|
146 | evaluator = evaluatorWithNoRuntime; |
---|
147 | } |
---|
148 | |
---|
149 | // apply the legacy API calls |
---|
150 | var results = callList.map(function(application){ |
---|
151 | try{ |
---|
152 | evaluator.apply(bc, args.concat(application)); |
---|
153 | return 0; |
---|
154 | }catch(e){ |
---|
155 | pluginStrategyRequired = 1; |
---|
156 | return [e, application]; |
---|
157 | } |
---|
158 | }); |
---|
159 | |
---|
160 | // report the results |
---|
161 | results.forEach(function(item){ |
---|
162 | if(item){ |
---|
163 | bc.log("legacyFailedEval", ["module", resource.mid, "text", item[0], "error", item[1]]); |
---|
164 | } |
---|
165 | }); |
---|
166 | }, |
---|
167 | |
---|
168 | tagAbsMid = function(absMid){ |
---|
169 | if(absMid && absMid!=resource.mid){ |
---|
170 | bc.log("amdInconsistentMid", ["module", resource.mid, "specified", absMid]); |
---|
171 | } |
---|
172 | if(absMid){ |
---|
173 | resource.tag.hasAbsMid = 1; |
---|
174 | } |
---|
175 | }, |
---|
176 | |
---|
177 | processPureAmdModule = function(){ |
---|
178 | // find the dependencies for this resource using the fast path if the module says it's OK |
---|
179 | // pure AMD says the module can be executed in the build environment |
---|
180 | // note: the user can provide a build environment with TODO |
---|
181 | try{ |
---|
182 | if(resource.mid!="dojo/_base/loader" && /dojo\.(require|provide)\s*\(/.test(removeComments(resource.text))){ |
---|
183 | bc.log("amdPureContainedLegacyApi", ["module", resource.mid]); |
---|
184 | } |
---|
185 | (new Function("define", "require", resource.text))(simulatedDefine, simulatedRequire); |
---|
186 | tagAbsMid(absMid); |
---|
187 | }catch (e){ |
---|
188 | bc.log("amdFailedEval", ["module", resource.mid, "error", e]); |
---|
189 | } |
---|
190 | }, |
---|
191 | |
---|
192 | convertToStrings = function(text){ |
---|
193 | var strings = [], |
---|
194 | |
---|
195 | // a DFA, the states... |
---|
196 | spaces = "spaces", |
---|
197 | string = "string", |
---|
198 | endOfString = "endOfString", |
---|
199 | done = "done", |
---|
200 | error = "error", |
---|
201 | |
---|
202 | // the machine... |
---|
203 | dfa = { |
---|
204 | spaces:function(c){ |
---|
205 | if(/\s/.test(c)){ |
---|
206 | return spaces; |
---|
207 | } |
---|
208 | if(c=="'" || c=='"'){ |
---|
209 | quoteType = c; |
---|
210 | current = ""; |
---|
211 | return string; |
---|
212 | } |
---|
213 | if(c==0){ |
---|
214 | return done; |
---|
215 | } |
---|
216 | return error; |
---|
217 | }, |
---|
218 | string:function(c){ |
---|
219 | if(c==quoteType){ |
---|
220 | strings.push(current); |
---|
221 | return "endOfString"; |
---|
222 | }else{ |
---|
223 | current+= c; |
---|
224 | return "string"; |
---|
225 | } |
---|
226 | }, |
---|
227 | endOfString:function(c){ |
---|
228 | if(/\s/.test(c)){ |
---|
229 | return endOfString; |
---|
230 | } |
---|
231 | if(c==0){ |
---|
232 | return done; |
---|
233 | } |
---|
234 | if(c==","){ |
---|
235 | return spaces; |
---|
236 | } |
---|
237 | return error; |
---|
238 | } |
---|
239 | }, |
---|
240 | |
---|
241 | state = spaces, |
---|
242 | |
---|
243 | quoteType, current; |
---|
244 | |
---|
245 | |
---|
246 | for(var i = 0; i<text.length; i++){ |
---|
247 | state = dfa[state](text.charAt(i)); |
---|
248 | if(state==error){ |
---|
249 | return 0; |
---|
250 | } |
---|
251 | } |
---|
252 | if(dfa[state](0)!=error){ |
---|
253 | return strings; |
---|
254 | } |
---|
255 | return 0; |
---|
256 | }, |
---|
257 | |
---|
258 | processPossibleAmdWithRegExs = function(text){ |
---|
259 | // look for AMD define and/or require; require must not have relative mids; require signature with config argument is not discovered |
---|
260 | // (remember, a config could have a string or regex that could have an unmatched right "}", so there is not way to guarantee we can find the correct |
---|
261 | // end of the config arg without parsing) |
---|
262 | |
---|
263 | var amdCallCount = |
---|
264 | // the number of AMD applications found |
---|
265 | 0, |
---|
266 | |
---|
267 | defineExp= |
---|
268 | // look for define applications with an optional string first arg and an optional array second arg; |
---|
269 | // notice the regex stops after the second arg |
---|
270 | // a test run in the console |
---|
271 | // test = [ |
---|
272 | // 'define("test")', |
---|
273 | // 'define("test", ["test1"])', |
---|
274 | // 'define("test", ["test1", "test2"])', |
---|
275 | // 'define(["test1"])', |
---|
276 | // 'define(["test1", "test2"])', |
---|
277 | // 'define("test", ["test1"], function(test){ hello;})', |
---|
278 | // 'define("test", function(test){ hello;})', |
---|
279 | // 'define(["test1"], function(test){ hello;})', |
---|
280 | // 'define(function(test){ hello;})', |
---|
281 | // 'define({a:1})' |
---|
282 | // ] |
---|
283 | // 2 3 4 5 |
---|
284 | /(^|\s)define\s*\(\s*(["'][^'"]+['"])?\s*(,)?\s*(\[[^\]]*?\])?\s*(,)?/g, |
---|
285 | |
---|
286 | result; |
---|
287 | while((result = defineExp.exec(text)) != null){ |
---|
288 | try{ |
---|
289 | if(result[2]){ |
---|
290 | // first arg a string |
---|
291 | if(result[3]){ |
---|
292 | // first arg a module id |
---|
293 | if(result[5]){ |
---|
294 | // (mid, deps, <factory>) |
---|
295 | result = result[0] + "{})"; |
---|
296 | }else if(result[4]){ |
---|
297 | // (mid, <factory:array value>) |
---|
298 | result = result[0] + ")"; |
---|
299 | }else{ |
---|
300 | // (mid, <factory>) |
---|
301 | result = result[0] + "{})"; |
---|
302 | } |
---|
303 | }else{ |
---|
304 | // (<factory:string-value>) |
---|
305 | result = result[0] + ")"; |
---|
306 | } |
---|
307 | }else if(result[4]){ |
---|
308 | // first arg an array |
---|
309 | if(result[5]){ |
---|
310 | // (deps, <factory>) |
---|
311 | result = result[0] + "{})"; |
---|
312 | }else{ |
---|
313 | // (<factory:array-value>) |
---|
314 | result = result[0] + ")"; |
---|
315 | } |
---|
316 | }else{ |
---|
317 | //just a factory |
---|
318 | result = "define({})"; |
---|
319 | } |
---|
320 | amdCallCount++; |
---|
321 | (new Function("define", result))(simulatedDefine); |
---|
322 | tagAbsMid(absMid); |
---|
323 | }catch(e){ |
---|
324 | amdCallCount--; |
---|
325 | bc.log("amdFailedDefineEval", ["module", resource.mid, "text", result, "error", e]); |
---|
326 | } |
---|
327 | } |
---|
328 | |
---|
329 | var requireExp= |
---|
330 | // look for require applications with an array for the first arg; notice the regex stops after the first arg and config signature is not processed |
---|
331 | /(^|\s)require\s*\(\s*\[([^\]]*?)\]/g; |
---|
332 | while((result = requireExp.exec(text)) != null){ |
---|
333 | var mids = convertToStrings(result[2]); |
---|
334 | if(mids){ |
---|
335 | amdCallCount++; |
---|
336 | aggregateDeps = aggregateDeps.concat(mids.filter(function(item){return item.charAt(0)!=".";})); |
---|
337 | } |
---|
338 | } |
---|
339 | return amdCallCount; |
---|
340 | }, |
---|
341 | |
---|
342 | evalNlsResource = function(resource){ |
---|
343 | var bundleValue = 0; |
---|
344 | try{ |
---|
345 | function simulatedDefine(a1, a2){ |
---|
346 | if(lang.isString(a1) && lang.isObject(a2)){ |
---|
347 | tagAbsMid(a1); |
---|
348 | bundleValue = a2; |
---|
349 | }else if(lang.isObject(a1)){ |
---|
350 | bundleValue = a1; |
---|
351 | } |
---|
352 | } |
---|
353 | (new Function("define", resource.text))(simulatedDefine); |
---|
354 | if(bundleValue){ |
---|
355 | resource.bundleValue = bundleValue; |
---|
356 | resource.bundleType = "amd"; |
---|
357 | return; |
---|
358 | } |
---|
359 | }catch(e){ |
---|
360 | // TODO: consider a profile flag to cause errors to be logged |
---|
361 | } |
---|
362 | try{ |
---|
363 | bundleValue = (new Function("return " + resource.text + ";"))(); |
---|
364 | if(lang.isObject(bundleValue)){ |
---|
365 | resource.bundleValue = bundleValue; |
---|
366 | resource.bundleType = "legacy"; |
---|
367 | return; |
---|
368 | } |
---|
369 | }catch(e){ |
---|
370 | // TODO: consider a profile flag to cause errors to be logged |
---|
371 | } |
---|
372 | |
---|
373 | // if not building flattened layer bundles, then it's not necessary for the bundle |
---|
374 | // to be evaluable; still run processPureAmdModule to compute possible dependencies |
---|
375 | processPureAmdModule(); |
---|
376 | if(!defineApplied){ |
---|
377 | bc.log("i18nImproperBundle", ["module", resource.mid]); |
---|
378 | } |
---|
379 | }, |
---|
380 | |
---|
381 | processNlsBundle = function(){ |
---|
382 | // either a v1.x sync bundle or an AMD NLS bundle |
---|
383 | |
---|
384 | // compute and remember the set of localized bundles; attach this info to the root bundle |
---|
385 | var match = resource.mid.match(/(^.*\/nls\/)(([^\/]+)\/)?([^\/]+)$/), |
---|
386 | prefix = resource.prefix = match[1], |
---|
387 | locale = resource.locale = match[3], |
---|
388 | bundle = resource.bundle = match[4], |
---|
389 | rootPath = prefix + bundle, |
---|
390 | rootBundle = bc.amdResources[rootPath]; |
---|
391 | |
---|
392 | // if not root, don't process any localized bundles; a missing root bundle serves as a signal |
---|
393 | // to other transforms (e.g., writeAmd) to ignore this bundle family |
---|
394 | if(!rootBundle){ |
---|
395 | bc.log("i18nNoRoot", ["bundle", resource.mid]); |
---|
396 | return; |
---|
397 | } |
---|
398 | // accumulate all the localized versions in the root bundle |
---|
399 | if(!rootBundle.localizedSet){ |
---|
400 | rootBundle.localizedSet = {}; |
---|
401 | } |
---|
402 | |
---|
403 | // try to compute the value of the bundle; sets properties bundleValue and bundleType |
---|
404 | evalNlsResource(resource); |
---|
405 | |
---|
406 | if((bc.localeList || resource.bundleType=="legacy") && !resource.bundleValue){ |
---|
407 | // profile is building flattened layer bundles or converting a legacy-style bundle |
---|
408 | // to an AMD-style bundle; either way, we need the value of the bundle |
---|
409 | bc.log("i18nUnevaluableBundle", ["module", resource.mid]); |
---|
410 | } |
---|
411 | |
---|
412 | if(resource.bundleType=="legacy" && resource===rootBundle && resource.bundleValue){ |
---|
413 | resource.bundleValue = {root:resource.bundleValue}; |
---|
414 | } |
---|
415 | |
---|
416 | if(resource!==rootBundle){ |
---|
417 | rootBundle.localizedSet[locale] = resource; |
---|
418 | } |
---|
419 | }, |
---|
420 | |
---|
421 | interningDojoUriRegExpString = |
---|
422 | // the following is a direct copy from the v1.6- build util; this is so janky, we dare not touch |
---|
423 | //23 4 5 6 78 9 0 1 |
---|
424 | "(((templatePath|templateCssPath)\\s*(=|:)\\s*)dojo\\.(module)?Url\\(|dojo\\.cache\\s*\\(\\s*)\\s*?[\\\"\\']([\\w\\.\\/]+)[\\\"\\'](([\\,\\s]*)[\\\"\\']([\\w\\.\\/-]*)[\\\"\\'])?(\\s*,\\s*)?([^\\)]*)?\\s*\\)", |
---|
425 | |
---|
426 | interningGlobalDojoUriRegExp = new RegExp(interningDojoUriRegExpString, "g"), |
---|
427 | |
---|
428 | interningLocalDojoUriRegExp = new RegExp(interningDojoUriRegExpString), |
---|
429 | |
---|
430 | internStrings = function() { |
---|
431 | var getText = function(src){ |
---|
432 | return fs.readFileSync(src, "utf8"); |
---|
433 | }, |
---|
434 | skipping = [], |
---|
435 | notFound = [], |
---|
436 | nothing = []; |
---|
437 | |
---|
438 | resource.text = resource.text.replace(interningGlobalDojoUriRegExp, function(matchString){ |
---|
439 | |
---|
440 | var parts = matchString.match(interningLocalDojoUriRegExp); |
---|
441 | |
---|
442 | var textModuleInfo = bc.getSrcModuleInfo(fileUtils.catPath(parts[6].replace(/\./g, "/"), parts[9]), 0, true); |
---|
443 | if(bc.internSkip(textModuleInfo.mid, resource)){ |
---|
444 | return matchString; |
---|
445 | } |
---|
446 | |
---|
447 | var textModule = bc.resources[textModuleInfo.url]; |
---|
448 | if(!textModule){ |
---|
449 | notFound.push(textModuleInfo.url); |
---|
450 | return matchString; |
---|
451 | } |
---|
452 | |
---|
453 | // note: it's possible the module is being processed by a set of transforms that don't add a |
---|
454 | // getText method (e.g., copy); therefore, we provide one for these cases |
---|
455 | var text = (textModule.getText && textModule.getText()) || getText(textModule.src); |
---|
456 | if(!text){ |
---|
457 | nothing.push(textModule.src); |
---|
458 | return matchString; |
---|
459 | } |
---|
460 | |
---|
461 | text = json.stringify(text); |
---|
462 | |
---|
463 | if(matchString.indexOf("dojo.cache") != -1){ |
---|
464 | //Handle dojo.cache-related interning. |
---|
465 | var endContent = parts[11]; |
---|
466 | if(!endContent){ |
---|
467 | endContent = text; |
---|
468 | }else{ |
---|
469 | var braceIndex = endContent.indexOf("{"); |
---|
470 | if(braceIndex != -1){ |
---|
471 | endContent = endContent.substring(0, braceIndex + 1) |
---|
472 | + 'value: ' + text + ',' |
---|
473 | + endContent.substring(braceIndex + 1, endContent.length); |
---|
474 | } |
---|
475 | } |
---|
476 | return 'dojo.cache("' + parts[6] + '", "' + parts[9] + '", ' + endContent + ')'; |
---|
477 | }else if(parts[3] == "templatePath"){ |
---|
478 | //Replace templatePaths |
---|
479 | return "templateString" + parts[4] + text; |
---|
480 | }else{ |
---|
481 | //Dealing with templateCssPath; not doing this anymore |
---|
482 | return matchString; |
---|
483 | } |
---|
484 | }); |
---|
485 | if(skipping.length || notFound.length || nothing.length){ |
---|
486 | var logArgs = ["module", resource.mid]; |
---|
487 | if(skipping.length){ |
---|
488 | logArgs.push("skipping", skipping); |
---|
489 | } |
---|
490 | if(notFound.length){ |
---|
491 | logArgs.push("not found", notFound); |
---|
492 | } |
---|
493 | if(nothing.length){ |
---|
494 | logArgs.push("nothing to intern", nothing); |
---|
495 | } |
---|
496 | bc.log("internStrings", logArgs); |
---|
497 | } |
---|
498 | }, |
---|
499 | |
---|
500 | processWithRegExs = function(){ |
---|
501 | // try to figure out if the module is legacy or AMD and then process the loader applications found |
---|
502 | // |
---|
503 | // Warning: the process is flawed because regexs will find things that are not there and miss things that are, |
---|
504 | // and there is no way around this without a proper parser. Note however, this kind of process has been in use |
---|
505 | // with the v1.x build system from the beginning. |
---|
506 | // |
---|
507 | // TODO: replace this process with a parser |
---|
508 | // |
---|
509 | // do it the unreliable way; first try to find "dojo.provide" et al since those names are less likely |
---|
510 | // to be overloaded than "define" and "require" |
---|
511 | if(bc.internStrings){ |
---|
512 | internStrings(); |
---|
513 | } |
---|
514 | |
---|
515 | var text = |
---|
516 | // apply any replacements before processing |
---|
517 | resource.getText(), |
---|
518 | |
---|
519 | names = |
---|
520 | bc.scopeNames, |
---|
521 | |
---|
522 | extractResult = |
---|
523 | // a vector of legacy loader API applications as pairs of [function-name, complete-function-application-text] + the following two properties |
---|
524 | // * text: the original text with all dojo.loadInit applications preceeded by 0 &&, thereby causing those applications to be discarded by the minifier |
---|
525 | // * extractText: all legacy loader applications, with all dojo.loadInit applications moved to the beginning |
---|
526 | // See dojo.js |
---|
527 | syncLoader.extractLegacyApiApplications(text, removeComments(text)); |
---|
528 | if(!extractResult.extractText && processPossibleAmdWithRegExs(removeComments(text))){ |
---|
529 | // zero legacy calls detected *and* at least one AMD call detected; therefore, assume it's AMD |
---|
530 | bc.log("amdNotPureContainedNoLegacyApi", ["module", resource.mid]); |
---|
531 | return; |
---|
532 | } |
---|
533 | bc.log("legacyAssumed", ["module", resource.mid]); |
---|
534 | |
---|
535 | if(!extractResult){ |
---|
536 | // no legacy API calls to worry about; therefore... |
---|
537 | resource.getText = function(){ return "define(" + json.stringify(names) + ", function(" + names.join(",") + "){" + newline + text + "});" + newline; }; |
---|
538 | return; |
---|
539 | } |
---|
540 | // apply the legacy calls in a special environment |
---|
541 | applyLegacyCalls(extractResult[2]); |
---|
542 | |
---|
543 | // check for multiple or irrational dojo.provides |
---|
544 | if(dojoProvides.length){ |
---|
545 | if(dojoProvides.length>1){ |
---|
546 | bc.log("legacyMultipleProvides", ["module", resource.mid, "provides", dojoProvides]); |
---|
547 | } |
---|
548 | dojoProvides.forEach(function(item){ |
---|
549 | if(item.replace(/\./g, "/")!=resource.mid){ |
---|
550 | bc.log("legacyImproperProvide", ["module", resource.mid, "provide", item]); |
---|
551 | } |
---|
552 | }); |
---|
553 | } |
---|
554 | |
---|
555 | if(pluginStrategyRequired){ |
---|
556 | // some loadInit and/or require[After]If and/or platformRequire applications that could not be resolved at build time |
---|
557 | bc.log("legacyUsingLoadInitPlug", ["module", resource.mid]); |
---|
558 | |
---|
559 | // construct and start the synthetic plugin resource |
---|
560 | var pluginText, mid, pluginResource, pluginResourceId; |
---|
561 | pluginText = |
---|
562 | "// generated by build app" + newline + |
---|
563 | "define([], {" + newline + |
---|
564 | "\tnames:" + json.stringify(names) + "," + newline + |
---|
565 | "\tdef:function(" + names.join(",") + "){" + newline + extractResult[1] + "}" + newline + |
---|
566 | "});" + newline; |
---|
567 | mid = resource.mid + "-loadInit"; |
---|
568 | pluginResource = mix(mix({}, resource), { |
---|
569 | src:resource.src.substring(0, resource.src.length-3) + "-loadInit.js", |
---|
570 | dest:bc.getDestModuleInfo(mid).url, |
---|
571 | mid:mid, |
---|
572 | tag:{loadInitResource:1}, |
---|
573 | deps:[], |
---|
574 | getText:function(){ return pluginText; } |
---|
575 | }); |
---|
576 | bc.start(pluginResource); |
---|
577 | |
---|
578 | pluginResourceId = "dojo/loadInit!" + mid; |
---|
579 | aggregateDeps.push(pluginResourceId); |
---|
580 | }else if(dojoRequires.length){ |
---|
581 | aggregateDeps.push("dojo/require!" + dojoRequires.join(",")); |
---|
582 | } |
---|
583 | aggregateDeps = names.concat(aggregateDeps); |
---|
584 | // need to use extractResult[0] since it may delete the dojo.loadInit applications |
---|
585 | resource.getText = function(){ return "// wrapped by build app" + newline + "define(" + json.stringify(aggregateDeps) + ", function(" + names.join(",") + "){" + newline + extractResult[0] + newline + "});" + newline; }; |
---|
586 | }; |
---|
587 | |
---|
588 | // scan the resource for dependencies |
---|
589 | if(resource.tag.nls){ |
---|
590 | processNlsBundle(); |
---|
591 | }else if(resource.tag.amd || /\/\/>>\s*pure-amd/.test(resource.text)){ |
---|
592 | processPureAmdModule(); |
---|
593 | }else{ |
---|
594 | processWithRegExs(); |
---|
595 | } |
---|
596 | |
---|
597 | // resolve the dependencies into modules |
---|
598 | var deps = resource.deps; |
---|
599 | resource.aggregateDeps = aggregateDeps; |
---|
600 | aggregateDeps.forEach(function(dep){ |
---|
601 | if(!(/^(require|exports|module)$/.test(dep))){ |
---|
602 | try{ |
---|
603 | var module = bc.getAmdModule(dep, resource); |
---|
604 | if(lang.isArray(module)){ |
---|
605 | module.forEach(function(module){ deps.push(module); }); |
---|
606 | }else if(module){ |
---|
607 | deps.push(module); |
---|
608 | }else{ |
---|
609 | bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep]); |
---|
610 | } |
---|
611 | }catch(e){ |
---|
612 | bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep, "error", e]); |
---|
613 | } |
---|
614 | } |
---|
615 | }); |
---|
616 | |
---|
617 | }; |
---|
618 | }); |
---|