jazz-jss 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. data/dist/handlebars/handlebars.js +1493 -0
  2. data/dist/hashchange/{jquery.ba-hashchange.js → hashchange.js} +0 -0
  3. data/dist/jazz/lib/controller.js +1 -1
  4. data/dist/jazz/lib/core.js +3 -0
  5. data/dist/jazz/lib/db.js +1 -1
  6. data/dist/jazz/lib/helper.js +2 -1
  7. data/dist/jazz/lib/model.js +11 -4
  8. data/dist/jazz/lib/view.js +1 -1
  9. data/dist/jazz/module.js +15 -0
  10. data/dist/jquery/jquery.js +0 -0
  11. data/dist/require/require.js +0 -0
  12. data/dist/require/template.js +98 -0
  13. data/dist/underscore/underscore.js +0 -0
  14. data/lib/jazz/app_detector.rb +6 -3
  15. data/lib/jazz/app_generator.rb +12 -8
  16. data/lib/jazz/helper_generator.rb +30 -0
  17. data/lib/jazz/scaffold_generator.rb +4 -0
  18. data/templates/app_root/Rakefile +11 -0
  19. data/templates/app_root/{app → development/app}/assets/javascripts/application.js +0 -0
  20. data/templates/app_root/{app → development/app}/assets/stylesheets/application.css +0 -0
  21. data/templates/app_root/development/app/controllers/application_controller.js +11 -0
  22. data/templates/app_root/development/app/helpers/application_helper.js +7 -0
  23. data/templates/app_root/development/config/glue.js +9 -0
  24. data/templates/app_root/development/config/routes.js +5 -0
  25. data/templates/app_root/scripts/build.js +30 -0
  26. data/templates/app_root/scripts/r.js/LICENSE +58 -0
  27. data/templates/app_root/scripts/r.js/README.md +177 -0
  28. data/templates/app_root/scripts/r.js/build/build.js +26 -0
  29. data/templates/app_root/scripts/r.js/build/buildebug.sh +4 -0
  30. data/templates/app_root/scripts/r.js/build/example.build.js +296 -0
  31. data/templates/app_root/scripts/r.js/build/jslib/blank.js +4 -0
  32. data/templates/app_root/scripts/r.js/build/jslib/build.js +952 -0
  33. data/templates/app_root/scripts/r.js/build/jslib/commandLine.js +23 -0
  34. data/templates/app_root/scripts/r.js/build/jslib/commonJs.js +152 -0
  35. data/templates/app_root/scripts/r.js/build/jslib/env.js +47 -0
  36. data/templates/app_root/scripts/r.js/build/jslib/lang.js +49 -0
  37. data/templates/app_root/scripts/r.js/build/jslib/logger.js +58 -0
  38. data/templates/app_root/scripts/r.js/build/jslib/node.js +106 -0
  39. data/templates/app_root/scripts/r.js/build/jslib/node/args.js +20 -0
  40. data/templates/app_root/scripts/r.js/build/jslib/node/file.js +263 -0
  41. data/templates/app_root/scripts/r.js/build/jslib/node/load.js +17 -0
  42. data/templates/app_root/scripts/r.js/build/jslib/node/optimize.js +10 -0
  43. data/templates/app_root/scripts/r.js/build/jslib/node/print.js +16 -0
  44. data/templates/app_root/scripts/r.js/build/jslib/optimize.js +279 -0
  45. data/templates/app_root/scripts/r.js/build/jslib/opto.build.js +11 -0
  46. data/templates/app_root/scripts/r.js/build/jslib/parse.js +590 -0
  47. data/templates/app_root/scripts/r.js/build/jslib/pragma.js +251 -0
  48. data/templates/app_root/scripts/r.js/build/jslib/requirePatch.js +286 -0
  49. data/templates/app_root/scripts/r.js/build/jslib/rhino.js +22 -0
  50. data/templates/app_root/scripts/r.js/build/jslib/rhino/args.js +21 -0
  51. data/templates/app_root/scripts/r.js/build/jslib/rhino/file.js +244 -0
  52. data/templates/app_root/scripts/r.js/build/jslib/rhino/load.js +12 -0
  53. data/templates/app_root/scripts/r.js/build/jslib/rhino/optimize.js +100 -0
  54. data/templates/app_root/scripts/r.js/build/jslib/rhino/print.js +12 -0
  55. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/README.md +16 -0
  56. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/index.js +21 -0
  57. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/parse-js.js +1342 -0
  58. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/process.js +2005 -0
  59. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/squeeze-more.js +55 -0
  60. data/templates/app_root/scripts/r.js/build/jslib/x.js +243 -0
  61. data/templates/app_root/scripts/r.js/build/tests/all.js +47 -0
  62. data/templates/app_root/scripts/r.js/build/tests/allj.sh +3 -0
  63. data/templates/app_root/scripts/r.js/build/tests/alln.sh +18 -0
  64. data/templates/app_root/scripts/r.js/build/tests/anonSimple.build.js +7 -0
  65. data/templates/app_root/scripts/r.js/build/tests/buildUtils.js +19 -0
  66. data/templates/app_root/scripts/r.js/build/tests/builds.js +489 -0
  67. data/templates/app_root/scripts/r.js/build/tests/circular.build.js +18 -0
  68. data/templates/app_root/scripts/r.js/build/tests/convert.js +18 -0
  69. data/templates/app_root/scripts/r.js/build/tests/css.build.js +6 -0
  70. data/templates/app_root/scripts/r.js/build/tests/css/common/common.css +4 -0
  71. data/templates/app_root/scripts/r.js/build/tests/css/master.css +10 -0
  72. data/templates/app_root/scripts/r.js/build/tests/css/sub/sub1.css +7 -0
  73. data/templates/app_root/scripts/r.js/build/tests/cssTestCompare.css +13 -0
  74. data/templates/app_root/scripts/r.js/build/tests/end.frag +3 -0
  75. data/templates/app_root/scripts/r.js/build/tests/expected/unoExcludeShallow.js +23 -0
  76. data/templates/app_root/scripts/r.js/build/tests/exports.build.js +12 -0
  77. data/templates/app_root/scripts/r.js/build/tests/hasTestModule.build.js +10 -0
  78. data/templates/app_root/scripts/r.js/build/tests/hasTestModule.js +30 -0
  79. data/templates/app_root/scripts/r.js/build/tests/http/httpBuild.js +70 -0
  80. data/templates/app_root/scripts/r.js/build/tests/http/main.html +28 -0
  81. data/templates/app_root/scripts/r.js/build/tests/http/scripts/main.js +18 -0
  82. data/templates/app_root/scripts/r.js/build/tests/http/scripts/one.js +3 -0
  83. data/templates/app_root/scripts/r.js/build/tests/http/scripts/three.js +5 -0
  84. data/templates/app_root/scripts/r.js/build/tests/http/scripts/two.js +7 -0
  85. data/templates/app_root/scripts/r.js/build/tests/i18n.build.js +17 -0
  86. data/templates/app_root/scripts/r.js/build/tests/indexBuilder.build.js +8 -0
  87. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/a.js +17 -0
  88. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/b.js +8 -0
  89. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/build.js +6 -0
  90. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/c.js +7 -0
  91. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/d.js +5 -0
  92. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/expected.js +36 -0
  93. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/LICENSE +58 -0
  94. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/amdefine.js +188 -0
  95. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/package.json +21 -0
  96. data/templates/app_root/scripts/r.js/build/tests/lib/comments/bang.js +10 -0
  97. data/templates/app_root/scripts/r.js/build/tests/lib/comments/build.js +6 -0
  98. data/templates/app_root/scripts/r.js/build/tests/lib/comments/expected.js +9 -0
  99. data/templates/app_root/scripts/r.js/build/tests/lib/comments/license.js +13 -0
  100. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/app.build.js +15 -0
  101. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/main-expected.js +13 -0
  102. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/main.js +7 -0
  103. data/templates/app_root/scripts/r.js/build/tests/lib/empty/build.js +13 -0
  104. data/templates/app_root/scripts/r.js/build/tests/lib/empty/expected.js +8 -0
  105. data/templates/app_root/scripts/r.js/build/tests/lib/empty/main.js +1 -0
  106. data/templates/app_root/scripts/r.js/build/tests/lib/empty/sub1.js +1 -0
  107. data/templates/app_root/scripts/r.js/build/tests/lib/empty/sub2.js +1 -0
  108. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/build.js +6 -0
  109. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/expected.js +12 -0
  110. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/main.js +9 -0
  111. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/build.js +8 -0
  112. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/expected.js +47 -0
  113. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/main.js +6 -0
  114. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/four.js +7 -0
  115. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/one.js +9 -0
  116. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/three.js +14 -0
  117. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/two.js +5 -0
  118. data/templates/app_root/scripts/r.js/build/tests/lib/nested/a.js +12 -0
  119. data/templates/app_root/scripts/r.js/build/tests/lib/nested/b.js +3 -0
  120. data/templates/app_root/scripts/r.js/build/tests/lib/nested/build.js +6 -0
  121. data/templates/app_root/scripts/r.js/build/tests/lib/nested/buildWithCE.js +7 -0
  122. data/templates/app_root/scripts/r.js/build/tests/lib/nested/c.js +3 -0
  123. data/templates/app_root/scripts/r.js/build/tests/lib/nested/d.js +3 -0
  124. data/templates/app_root/scripts/r.js/build/tests/lib/nested/e.js +3 -0
  125. data/templates/app_root/scripts/r.js/build/tests/lib/nested/expected-built.js +36 -0
  126. data/templates/app_root/scripts/r.js/build/tests/lib/nested/expected-builtWithCE.js +42 -0
  127. data/templates/app_root/scripts/r.js/build/tests/lib/nested/main.js +3 -0
  128. data/templates/app_root/scripts/r.js/build/tests/lib/nested/top.js +10 -0
  129. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/a.js +3 -0
  130. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/b.js +3 -0
  131. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/build.js +6 -0
  132. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedAll.js +9 -0
  133. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedB.js +11 -0
  134. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedC.js +11 -0
  135. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedD.js +11 -0
  136. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNested.js +7 -0
  137. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/c.js +3 -0
  138. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/d.js +3 -0
  139. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-built.js +21 -0
  140. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedAll.js +31 -0
  141. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedB.js +24 -0
  142. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedC.js +24 -0
  143. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedD.js +25 -0
  144. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNested.js +31 -0
  145. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/main.js +17 -0
  146. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/build.js +6 -0
  147. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/converter.js +11 -0
  148. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/main.js +6 -0
  149. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/plug.js +29 -0
  150. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/util.js +7 -0
  151. data/templates/app_root/scripts/r.js/build/tests/nameOnly.build.js +10 -0
  152. data/templates/app_root/scripts/r.js/build/tests/nodeAll.js +3 -0
  153. data/templates/app_root/scripts/r.js/build/tests/nodeOptimize.js +12 -0
  154. data/templates/app_root/scripts/r.js/build/tests/nodeOptimizeNoCallback.js +10 -0
  155. data/templates/app_root/scripts/r.js/build/tests/order.build.js +16 -0
  156. data/templates/app_root/scripts/r.js/build/tests/override/override.js +36 -0
  157. data/templates/app_root/scripts/r.js/build/tests/packages.build.js +59 -0
  158. data/templates/app_root/scripts/r.js/build/tests/parse.js +103 -0
  159. data/templates/app_root/scripts/r.js/build/tests/simple.build.js +13 -0
  160. data/templates/app_root/scripts/r.js/build/tests/simpleNamespace.build.js +17 -0
  161. data/templates/app_root/scripts/r.js/build/tests/start.frag +4 -0
  162. data/templates/app_root/scripts/r.js/build/tests/text.build.js +16 -0
  163. data/templates/app_root/scripts/r.js/build/tests/textExclude.build.js +16 -0
  164. data/templates/app_root/scripts/r.js/dist.js +95 -0
  165. data/templates/app_root/scripts/r.js/dist/README.md +6 -0
  166. data/templates/app_root/scripts/r.js/dist/r-1.0.0.js +9042 -0
  167. data/templates/app_root/scripts/r.js/dist/r-edge.js +9191 -0
  168. data/templates/app_root/scripts/r.js/dist/r.js +9099 -0
  169. data/templates/app_root/scripts/r.js/lib/closure/COPYING +202 -0
  170. data/templates/app_root/scripts/r.js/lib/closure/README +292 -0
  171. data/templates/app_root/scripts/r.js/lib/closure/compiler.jar +0 -0
  172. data/templates/app_root/scripts/r.js/lib/rhino/LICENSE +4 -0
  173. data/templates/app_root/scripts/r.js/lib/rhino/js.jar +0 -0
  174. data/templates/app_root/scripts/r.js/require.js +1952 -0
  175. data/templates/app_root/scripts/r.js/tasks.txt +2 -0
  176. data/templates/app_root/scripts/r.js/tests/all.js +49 -0
  177. data/templates/app_root/scripts/r.js/tests/allNode.js +3 -0
  178. data/templates/app_root/scripts/r.js/tests/allj.sh +1 -0
  179. data/templates/app_root/scripts/r.js/tests/alln.sh +2 -0
  180. data/templates/app_root/scripts/r.js/tests/alpha.js +3 -0
  181. data/templates/app_root/scripts/r.js/tests/beta.js +6 -0
  182. data/templates/app_root/scripts/r.js/tests/doh/LICENSE +195 -0
  183. data/templates/app_root/scripts/r.js/tests/doh/README +12 -0
  184. data/templates/app_root/scripts/r.js/tests/doh/_browserRunner.js +855 -0
  185. data/templates/app_root/scripts/r.js/tests/doh/_nodeRunner.js +20 -0
  186. data/templates/app_root/scripts/r.js/tests/doh/_rhinoRunner.js +17 -0
  187. data/templates/app_root/scripts/r.js/tests/doh/_sounds/LICENSE +10 -0
  188. data/templates/app_root/scripts/r.js/tests/doh/_sounds/doh.wav +0 -0
  189. data/templates/app_root/scripts/r.js/tests/doh/_sounds/dohaaa.wav +0 -0
  190. data/templates/app_root/scripts/r.js/tests/doh/_sounds/woohoo.wav +0 -0
  191. data/templates/app_root/scripts/r.js/tests/doh/runner.html +316 -0
  192. data/templates/app_root/scripts/r.js/tests/doh/runner.js +1499 -0
  193. data/templates/app_root/scripts/r.js/tests/doh/runner.sh +3 -0
  194. data/templates/app_root/scripts/r.js/tests/doh/small_logo.png +0 -0
  195. data/templates/app_root/scripts/r.js/tests/node/canvasTest.js +39 -0
  196. data/templates/app_root/scripts/r.js/tests/node/embedded/README.md +15 -0
  197. data/templates/app_root/scripts/r.js/tests/node/embedded/coffee/foo.coffee +1 -0
  198. data/templates/app_root/scripts/r.js/tests/node/embedded/main.js +13 -0
  199. data/templates/app_root/scripts/r.js/tests/node/embedded/scripts/bar.js +13 -0
  200. data/templates/app_root/scripts/r.js/tests/node/index.js +11 -0
  201. data/templates/app_root/scripts/r.js/tests/node/tests/alpha/foo.js +6 -0
  202. data/templates/app_root/scripts/r.js/tests/node/tests/alpha/hello.html +9 -0
  203. data/templates/app_root/scripts/r.js/tests/node/tests/foo.js +3 -0
  204. data/templates/app_root/scripts/r.js/tests/node/tests/server.js +11 -0
  205. data/templates/app_root/scripts/r.js/tests/relative.js +10 -0
  206. data/templates/app_root/scripts/r.js/tests/sub/betaSub.js +3 -0
  207. data/templates/application.js +6 -5
  208. data/templates/boot.js +42 -0
  209. data/templates/helper.js +9 -0
  210. data/templates/index.html +1 -1
  211. metadata +201 -11
  212. data/dist/jazz/main.js +0 -65
  213. data/dist/mustache/mustache.js +0 -324
  214. data/templates/app_root/config/routes.js +0 -4
  215. data/templates/glue.js +0 -4
@@ -0,0 +1,4 @@
1
+ //Just a blank file to use when building the optimizer with the optimizer,
2
+ //so that the build does not attempt to inline some env modules,
3
+ //like Node's fs and path.
4
+
@@ -0,0 +1,952 @@
1
+ /**
2
+ * @license Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
3
+ * Available via the MIT or new BSD license.
4
+ * see: http://github.com/jrburke/requirejs for details
5
+ */
6
+
7
+ /*jslint regexp: false, plusplus: false, nomen: false, strict: false */
8
+ /*global define: false, require: false */
9
+
10
+
11
+ define([ 'lang', 'logger', 'env!env/file', 'parse', 'optimize', 'pragma',
12
+ 'env!env/load', 'requirePatch'],
13
+ function (lang, logger, file, parse, optimize, pragma,
14
+ load, requirePatch) {
15
+ var build, buildBaseConfig,
16
+ endsWithSemiColonRegExp = /;\s*$/;
17
+
18
+ buildBaseConfig = {
19
+ appDir: "",
20
+ pragmas: {},
21
+ paths: {},
22
+ optimize: "uglify",
23
+ optimizeCss: "standard.keepLines",
24
+ inlineText: true,
25
+ isBuild: true,
26
+ optimizeAllPluginResources: false,
27
+ findNestedDependencies: false,
28
+ preserveLicenseComments: true,
29
+ //By default, all files/directories are copied, unless
30
+ //they match this regexp, by default just excludes .folders
31
+ dirExclusionRegExp: file.dirExclusionRegExp
32
+ };
33
+
34
+ /**
35
+ * Some JS may not be valid if concatenated with other JS, in particular
36
+ * the style of omitting semicolons and rely on ASI. Add a semicolon in
37
+ * those cases.
38
+ */
39
+ function addSemiColon(text) {
40
+ if (endsWithSemiColonRegExp.test(text)) {
41
+ return text;
42
+ } else {
43
+ return text + ";";
44
+ }
45
+ }
46
+
47
+ /**
48
+ * If the path looks like an URL, throw an error. This is to prevent
49
+ * people from using URLs with protocols in the build config, since
50
+ * the optimizer is not set up to do network access. However, be
51
+ * sure to allow absolute paths on Windows, like C:\directory.
52
+ */
53
+ function disallowUrls(path) {
54
+ if (path.indexOf('://') !== -1 && path !== 'empty:') {
55
+ throw new Error('Path is not supported: ' + path +
56
+ '\nOptimizer can only handle' +
57
+ ' local paths. Download the locally if necessary' +
58
+ ' and update the config to use a local path.\n' +
59
+ 'http://requirejs.org/docs/errors.html#pathnotsupported');
60
+ }
61
+ }
62
+
63
+ function endsWithSlash(dirName) {
64
+ if (dirName.charAt(dirName.length - 1) !== "/") {
65
+ dirName += "/";
66
+ }
67
+ disallowUrls(dirName);
68
+ return dirName;
69
+ }
70
+
71
+ //Method used by plugin writeFile calls, defined up here to avoid
72
+ //jslint warning about "making a function in a loop".
73
+ function makeWriteFile(anonDefRegExp, namespaceWithDot, layer) {
74
+ function writeFile(name, contents) {
75
+ logger.trace('Saving plugin-optimized file: ' + name);
76
+ file.saveUtf8File(name, contents);
77
+ }
78
+
79
+ writeFile.asModule = function (moduleName, fileName, contents) {
80
+ writeFile(fileName,
81
+ build.toTransport(anonDefRegExp, namespaceWithDot, moduleName, fileName, contents, layer));
82
+ };
83
+
84
+ return writeFile;
85
+ }
86
+
87
+ /**
88
+ * Main API entry point into the build. The args argument can either be
89
+ * an array of arguments (like the onese passed on a command-line),
90
+ * or it can be a JavaScript object that has the format of a build profile
91
+ * file.
92
+ *
93
+ * If it is an object, then in addition to the normal properties allowed in
94
+ * a build profile file, the object should contain one other property:
95
+ *
96
+ * The object could also contain a "buildFile" property, which is a string
97
+ * that is the file path to a build profile that contains the rest
98
+ * of the build profile directives.
99
+ *
100
+ * This function does not return a status, it should throw an error if
101
+ * there is a problem completing the build.
102
+ */
103
+ build = function (args) {
104
+ var buildFile, cmdConfig;
105
+
106
+ if (!args || lang.isArray(args)) {
107
+ if (!args || args.length < 1) {
108
+ logger.error("build.js buildProfile.js\n" +
109
+ "where buildProfile.js is the name of the build file (see example.build.js for hints on how to make a build file).");
110
+ return undefined;
111
+ }
112
+
113
+ //Next args can include a build file path as well as other build args.
114
+ //build file path comes first. If it does not contain an = then it is
115
+ //a build file path. Otherwise, just all build args.
116
+ if (args[0].indexOf("=") === -1) {
117
+ buildFile = args[0];
118
+ args.splice(0, 1);
119
+ }
120
+
121
+ //Remaining args are options to the build
122
+ cmdConfig = build.convertArrayToObject(args);
123
+ cmdConfig.buildFile = buildFile;
124
+ } else {
125
+ cmdConfig = args;
126
+ }
127
+
128
+ return build._run(cmdConfig);
129
+ };
130
+
131
+ build._run = function (cmdConfig) {
132
+ var buildFileContents = "",
133
+ pluginCollector = {},
134
+ buildPaths, fileName, fileNames,
135
+ prop, paths, i,
136
+ baseConfig, config,
137
+ modules, builtModule, srcPath, buildContext,
138
+ destPath, moduleName, moduleMap, parentModuleMap, context,
139
+ resources, resource, pluginProcessed = {}, plugin;
140
+
141
+ //Can now run the patches to require.js to allow it to be used for
142
+ //build generation. Do it here instead of at the top of the module
143
+ //because we want normal require behavior to load the build tool
144
+ //then want to switch to build mode.
145
+ requirePatch();
146
+
147
+ config = build.createConfig(cmdConfig);
148
+ paths = config.paths;
149
+
150
+ if (config.logLevel) {
151
+ logger.logLevel(config.logLevel);
152
+ }
153
+
154
+ if (!config.out && !config.cssIn) {
155
+ //This is not just a one-off file build but a full build profile, with
156
+ //lots of files to process.
157
+
158
+ //First copy all the baseUrl content
159
+ file.copyDir((config.appDir || config.baseUrl), config.dir, /\w/, true);
160
+
161
+ //Adjust baseUrl if config.appDir is in play, and set up build output paths.
162
+ buildPaths = {};
163
+ if (config.appDir) {
164
+ //All the paths should be inside the appDir
165
+ buildPaths = paths;
166
+ } else {
167
+ //If no appDir, then make sure to copy the other paths to this directory.
168
+ for (prop in paths) {
169
+ if (paths.hasOwnProperty(prop)) {
170
+ //Set up build path for each path prefix.
171
+ buildPaths[prop] = paths[prop] === 'empty:' ? 'empty:' : prop.replace(/\./g, "/");
172
+
173
+ //Make sure source path is fully formed with baseUrl,
174
+ //if it is a relative URL.
175
+ srcPath = paths[prop];
176
+ if (srcPath.indexOf('/') !== 0 && srcPath.indexOf(':') === -1) {
177
+ srcPath = config.baseUrl + srcPath;
178
+ }
179
+
180
+ destPath = config.dirBaseUrl + buildPaths[prop];
181
+
182
+ //Skip empty: paths
183
+ if (srcPath !== 'empty:') {
184
+ //If the srcPath is a directory, copy the whole directory.
185
+ if (file.exists(srcPath) && file.isDirectory(srcPath)) {
186
+ //Copy files to build area. Copy all files (the /\w/ regexp)
187
+ file.copyDir(srcPath, destPath, /\w/, true);
188
+ } else {
189
+ //Try a .js extension
190
+ srcPath += '.js';
191
+ destPath += '.js';
192
+ file.copyFile(srcPath, destPath);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ //Figure out source file location for each module layer. Do this by seeding require
201
+ //with source area configuration. This is needed so that later the module layers
202
+ //can be manually copied over to the source area, since the build may be
203
+ //require multiple times and the above copyDir call only copies newer files.
204
+ require({
205
+ baseUrl: config.baseUrl,
206
+ paths: paths,
207
+ packagePaths: config.packagePaths,
208
+ packages: config.packages
209
+ });
210
+ buildContext = require.s.contexts._;
211
+ modules = config.modules;
212
+
213
+ if (modules) {
214
+ modules.forEach(function (module) {
215
+ if (module.name) {
216
+ module._sourcePath = buildContext.nameToUrl(module.name);
217
+ //If the module does not exist, and this is not a "new" module layer,
218
+ //as indicated by a true "create" property on the module, and
219
+ //it is not a plugin-loaded resource, then throw an error.
220
+ if (!file.exists(module._sourcePath) && !module.create &&
221
+ module.name.indexOf('!') === -1) {
222
+ throw new Error("ERROR: module path does not exist: " +
223
+ module._sourcePath + " for module named: " + module.name +
224
+ ". Path is relative to: " + file.absPath('.'));
225
+ }
226
+ }
227
+ });
228
+ }
229
+
230
+ if (config.out) {
231
+ //Just set up the _buildPath for the module layer.
232
+ require(config);
233
+ if (!config.cssIn) {
234
+ config.modules[0]._buildPath = config.out;
235
+ }
236
+ } else if (!config.cssIn) {
237
+ //Now set up the config for require to use the build area, and calculate the
238
+ //build file locations. Pass along any config info too.
239
+ baseConfig = {
240
+ baseUrl: config.dirBaseUrl,
241
+ paths: buildPaths
242
+ };
243
+
244
+ lang.mixin(baseConfig, config);
245
+ require(baseConfig);
246
+
247
+ if (modules) {
248
+ modules.forEach(function (module) {
249
+ if (module.name) {
250
+ module._buildPath = buildContext.nameToUrl(module.name, null);
251
+ if (!module.create) {
252
+ file.copyFile(module._sourcePath, module._buildPath);
253
+ }
254
+ }
255
+ });
256
+ }
257
+ }
258
+
259
+ //Run CSS optimizations before doing JS module tracing, to allow
260
+ //things like text loader plugins loading CSS to get the optimized
261
+ //CSS.
262
+ if (config.optimizeCss && config.optimizeCss !== "none" && config.dir) {
263
+ optimize.css(config.dir, config);
264
+ }
265
+
266
+ if (modules) {
267
+ //For each module layer, call require to calculate dependencies.
268
+ modules.forEach(function (module) {
269
+ module.layer = build.traceDependencies(module, config);
270
+ });
271
+
272
+ //Now build up shadow layers for anything that should be excluded.
273
+ //Do this after tracing dependencies for each module, in case one
274
+ //of those modules end up being one of the excluded values.
275
+ modules.forEach(function (module) {
276
+ if (module.exclude) {
277
+ module.excludeLayers = [];
278
+ module.exclude.forEach(function (exclude, i) {
279
+ //See if it is already in the list of modules.
280
+ //If not trace dependencies for it.
281
+ module.excludeLayers[i] = build.findBuildModule(exclude, modules) ||
282
+ {layer: build.traceDependencies({name: exclude}, config)};
283
+ });
284
+ }
285
+ });
286
+
287
+ modules.forEach(function (module) {
288
+ if (module.exclude) {
289
+ //module.exclude is an array of module names. For each one,
290
+ //get the nested dependencies for it via a matching entry
291
+ //in the module.excludeLayers array.
292
+ module.exclude.forEach(function (excludeModule, i) {
293
+ var excludeLayer = module.excludeLayers[i].layer, map = excludeLayer.buildPathMap, prop;
294
+ for (prop in map) {
295
+ if (map.hasOwnProperty(prop)) {
296
+ build.removeModulePath(prop, map[prop], module.layer);
297
+ }
298
+ }
299
+ });
300
+ }
301
+ if (module.excludeShallow) {
302
+ //module.excludeShallow is an array of module names.
303
+ //shallow exclusions are just that module itself, and not
304
+ //its nested dependencies.
305
+ module.excludeShallow.forEach(function (excludeShallowModule) {
306
+ var path = module.layer.buildPathMap[excludeShallowModule];
307
+ if (path) {
308
+ build.removeModulePath(excludeShallowModule, path, module.layer);
309
+ }
310
+ });
311
+ }
312
+
313
+ //Flatten them and collect the build output for each module.
314
+ builtModule = build.flattenModule(module, module.layer, config);
315
+ file.saveUtf8File(module._buildPath, builtModule.text);
316
+ buildFileContents += builtModule.buildText;
317
+ });
318
+ }
319
+
320
+ //Do other optimizations.
321
+ if (config.out && !config.cssIn) {
322
+ //Just need to worry about one JS file.
323
+ fileName = config.modules[0]._buildPath;
324
+ optimize.jsFile(fileName, fileName, config);
325
+ } else if (!config.cssIn) {
326
+ //Normal optimizations across modules.
327
+
328
+ //JS optimizations.
329
+ fileNames = file.getFilteredFileList(config.dir, /\.js$/, true);
330
+ for (i = 0; (fileName = fileNames[i]); i++) {
331
+ //Generate the module name from the config.dir root.
332
+ moduleName = fileName.replace(config.dir, '');
333
+ //Get rid of the extension
334
+ moduleName = moduleName.substring(0, moduleName.length - 3);
335
+ optimize.jsFile(fileName, fileName, config, moduleName, pluginCollector);
336
+ }
337
+
338
+ //Normalize all the plugin resources.
339
+ context = require.s.contexts._;
340
+
341
+ for (moduleName in pluginCollector) {
342
+ if (pluginCollector.hasOwnProperty(moduleName)) {
343
+ parentModuleMap = context.makeModuleMap(moduleName);
344
+ resources = pluginCollector[moduleName];
345
+ for (i = 0; (resource = resources[i]); i++) {
346
+ moduleMap = context.makeModuleMap(resource, parentModuleMap);
347
+ if (!context.plugins[moduleMap.prefix]) {
348
+ //Set the value in context.plugins so it
349
+ //will be evaluated as a full plugin.
350
+ context.plugins[moduleMap.prefix] = true;
351
+
352
+ //Do not bother if the plugin is not available.
353
+ if (!file.exists(require.toUrl(moduleMap.prefix + '.js'))) {
354
+ continue;
355
+ }
356
+
357
+ //Rely on the require in the build environment
358
+ //to be synchronous
359
+ context.require([moduleMap.prefix]);
360
+
361
+ //Now that the plugin is loaded, redo the moduleMap
362
+ //since the plugin will need to normalize part of the path.
363
+ moduleMap = context.makeModuleMap(resource, parentModuleMap);
364
+ }
365
+
366
+ //Only bother with plugin resources that can be handled
367
+ //processed by the plugin, via support of the writeFile
368
+ //method.
369
+ if (!pluginProcessed[moduleMap.fullName]) {
370
+ //Only do the work if the plugin was really loaded.
371
+ //Using an internal access because the file may
372
+ //not really be loaded.
373
+ plugin = context.defined[moduleMap.prefix];
374
+ if (plugin && plugin.writeFile) {
375
+ plugin.writeFile(
376
+ moduleMap.prefix,
377
+ moduleMap.name,
378
+ require,
379
+ makeWriteFile(
380
+ config.anonDefRegExp,
381
+ config.namespaceWithDot
382
+ ),
383
+ context.config
384
+ );
385
+ }
386
+
387
+ pluginProcessed[moduleMap.fullName] = true;
388
+ }
389
+ }
390
+
391
+ }
392
+ }
393
+
394
+ //console.log('PLUGIN COLLECTOR: ' + JSON.stringify(pluginCollector, null, " "));
395
+
396
+
397
+ //All module layers are done, write out the build.txt file.
398
+ file.saveUtf8File(config.dir + "build.txt", buildFileContents);
399
+ }
400
+
401
+ //If just have one CSS file to optimize, do that here.
402
+ if (config.cssIn) {
403
+ optimize.cssFile(config.cssIn, config.out, config);
404
+ }
405
+
406
+ //Print out what was built into which layers.
407
+ if (buildFileContents) {
408
+ logger.info(buildFileContents);
409
+ return buildFileContents;
410
+ }
411
+
412
+ return '';
413
+ };
414
+
415
+ /**
416
+ * Converts command line args like "paths.foo=../some/path"
417
+ * result.paths = { foo: '../some/path' } where prop = paths,
418
+ * name = paths.foo and value = ../some/path, so it assumes the
419
+ * name=value splitting has already happened.
420
+ */
421
+ function stringDotToObj(result, prop, name, value) {
422
+ if (!result[prop]) {
423
+ result[prop] = {};
424
+ }
425
+ name = name.substring((prop + '.').length, name.length);
426
+ result[prop][name] = value;
427
+ }
428
+
429
+ //Used by convertArrayToObject to convert some things from prop.name=value
430
+ //to a prop: { name: value}
431
+ build.dotProps = [
432
+ 'paths.',
433
+ 'wrap.',
434
+ 'pragmas.',
435
+ 'pragmasOnSave.',
436
+ 'has.',
437
+ 'hasOnSave.',
438
+ 'wrap.',
439
+ 'uglify.',
440
+ 'closure.'
441
+ ];
442
+
443
+ build.hasDotPropMatch = function (prop) {
444
+ return build.dotProps.some(function (dotProp) {
445
+ return prop.indexOf(dotProp) === 0;
446
+ });
447
+ };
448
+
449
+ /**
450
+ * Converts an array that has String members of "name=value"
451
+ * into an object, where the properties on the object are the names in the array.
452
+ * Also converts the strings "true" and "false" to booleans for the values.
453
+ * member name/value pairs, and converts some comma-separated lists into
454
+ * arrays.
455
+ * @param {Array} ary
456
+ */
457
+ build.convertArrayToObject = function (ary) {
458
+ var result = {}, i, separatorIndex, prop, value,
459
+ needArray = {
460
+ "include": true,
461
+ "exclude": true,
462
+ "excludeShallow": true
463
+ };
464
+
465
+ for (i = 0; i < ary.length; i++) {
466
+ separatorIndex = ary[i].indexOf("=");
467
+ if (separatorIndex === -1) {
468
+ throw "Malformed name/value pair: [" + ary[i] + "]. Format should be name=value";
469
+ }
470
+
471
+ value = ary[i].substring(separatorIndex + 1, ary[i].length);
472
+ if (value === "true") {
473
+ value = true;
474
+ } else if (value === "false") {
475
+ value = false;
476
+ }
477
+
478
+ prop = ary[i].substring(0, separatorIndex);
479
+
480
+ //Convert to array if necessary
481
+ if (needArray[prop]) {
482
+ value = value.split(",");
483
+ }
484
+
485
+ if (build.hasDotPropMatch(prop)) {
486
+ stringDotToObj(result, prop.split('.')[0], prop, value);
487
+ } else {
488
+ result[prop] = value;
489
+ }
490
+ }
491
+ return result; //Object
492
+ };
493
+
494
+ build.makeAbsPath = function (path, absFilePath) {
495
+ //Add abspath if necessary. If path starts with a slash or has a colon,
496
+ //then already is an abolute path.
497
+ if (path.indexOf('/') !== 0 && path.indexOf(':') === -1) {
498
+ path = absFilePath +
499
+ (absFilePath.charAt(absFilePath.length - 1) === '/' ? '' : '/') +
500
+ path;
501
+ path = file.normalize(path);
502
+ }
503
+ return path.replace(lang.backSlashRegExp, '/');
504
+ };
505
+
506
+ /**
507
+ * Creates a config object for an optimization build.
508
+ * It will also read the build profile if it is available, to create
509
+ * the configuration.
510
+ *
511
+ * @param {Object} cfg config options that take priority
512
+ * over defaults and ones in the build file. These options could
513
+ * be from a command line, for instance.
514
+ *
515
+ * @param {Object} the created config object.
516
+ */
517
+ build.createConfig = function (cfg) {
518
+ /*jslint evil: true */
519
+ var config = {}, buildFileContents, buildFileConfig,
520
+ paths, props, i, prop, buildFile, absFilePath, originalBaseUrl;
521
+
522
+ lang.mixin(config, buildBaseConfig);
523
+ lang.mixin(config, cfg, true);
524
+
525
+ absFilePath = file.absPath('.');
526
+
527
+ if (config.buildFile) {
528
+ //A build file exists, load it to get more config.
529
+ buildFile = file.absPath(config.buildFile);
530
+
531
+ //Find the build file, and make sure it exists, if this is a build
532
+ //that has a build profile, and not just command line args with an in=path
533
+ if (!file.exists(buildFile)) {
534
+ throw new Error("ERROR: build file does not exist: " + buildFile);
535
+ }
536
+
537
+ absFilePath = config.baseUrl = file.absPath(file.parent(buildFile));
538
+ config.dir = config.baseUrl + "/build/";
539
+
540
+ //Load build file options.
541
+ buildFileContents = file.readFile(buildFile);
542
+ try {
543
+ buildFileConfig = eval("(" + buildFileContents + ")");
544
+ } catch (e) {
545
+ throw new Error("Build file " + buildFile + " is malformed: " + e);
546
+ }
547
+ lang.mixin(config, buildFileConfig, true);
548
+
549
+ //Re-apply the override config values, things like command line
550
+ //args should take precedence over build file values.
551
+ lang.mixin(config, cfg, true);
552
+ } else if (config.cssIn) {
553
+ if (!config.out) {
554
+ throw new Error("ERROR: 'out' option missing.");
555
+ } else {
556
+ config.out = config.out.replace(lang.backSlashRegExp, "/");
557
+ }
558
+ }
559
+
560
+ if (!config.cssIn && !config.baseUrl) {
561
+ throw new Error("ERROR: 'baseUrl' option missing.");
562
+ }
563
+
564
+ if (config.out && !config.cssIn) {
565
+ //Just one file to optimize.
566
+
567
+ //Set up dummy module layer to build.
568
+ config.modules = [
569
+ {
570
+ name: config.name,
571
+ out: config.out,
572
+ include: config.include,
573
+ exclude: config.exclude,
574
+ excludeShallow: config.excludeShallow
575
+ }
576
+ ];
577
+
578
+ //Does not have a build file, so set up some defaults.
579
+ //Optimizing CSS should not be allowed, unless explicitly
580
+ //asked for on command line. In that case the only task is
581
+ //to optimize a CSS file.
582
+ if (!cfg.optimizeCss) {
583
+ config.optimizeCss = "none";
584
+ }
585
+ }
586
+
587
+ //Adjust the path properties as appropriate.
588
+ //First make sure build paths use front slashes and end in a slash,
589
+ //and make sure they are aboslute paths.
590
+ props = ["appDir", "dir", "baseUrl"];
591
+ for (i = 0; (prop = props[i]); i++) {
592
+ if (config[prop]) {
593
+ config[prop] = config[prop].replace(lang.backSlashRegExp, "/");
594
+
595
+ //Add abspath if necessary.
596
+ if (prop === "baseUrl") {
597
+ originalBaseUrl = config.baseUrl;
598
+ if (config.appDir) {
599
+ //If baseUrl with an appDir, the baseUrl is relative to
600
+ //the appDir, *not* the absFilePath. appDir and dir are
601
+ //made absolute before baseUrl, so this will work.
602
+ config.baseUrl = build.makeAbsPath(originalBaseUrl, config.appDir);
603
+ //Set up dir output baseUrl.
604
+ config.dirBaseUrl = build.makeAbsPath(originalBaseUrl, config.dir);
605
+ } else {
606
+ //The dir output baseUrl is same as regular baseUrl, both
607
+ //relative to the absFilePath.
608
+ config.baseUrl = build.makeAbsPath(config[prop], absFilePath);
609
+ config.dirBaseUrl = config.dir || config.baseUrl;
610
+ }
611
+
612
+ //Make sure dirBaseUrl ends in a slash, since it is
613
+ //concatenated with other strings.
614
+ config.dirBaseUrl = endsWithSlash(config.dirBaseUrl);
615
+ } else {
616
+ config[prop] = build.makeAbsPath(config[prop], absFilePath);
617
+ }
618
+
619
+ config[prop] = endsWithSlash(config[prop]);
620
+ }
621
+ }
622
+
623
+ //Do not allow URLs for paths resources.
624
+ if (config.paths) {
625
+ for (prop in config.paths) {
626
+ if (config.paths.hasOwnProperty(prop)) {
627
+ config.paths[prop] = config.paths[prop].replace(lang.backSlashRegExp, "/");
628
+ disallowUrls(config.paths[prop]);
629
+ }
630
+ }
631
+ }
632
+
633
+ //Make sure some other paths are absolute.
634
+ props = ["out", "cssIn"];
635
+ for (i = 0; (prop = props[i]); i++) {
636
+ if (config[prop]) {
637
+ config[prop] = build.makeAbsPath(config[prop], absFilePath);
638
+ }
639
+ }
640
+
641
+ //Get any wrap text.
642
+ try {
643
+ if (config.wrap) {
644
+ if (config.wrap === true) {
645
+ //Use default values.
646
+ config.wrap = {
647
+ start: '(function () {',
648
+ end: '}());'
649
+ };
650
+ } else {
651
+ config.wrap.start = config.wrap.start ||
652
+ file.readFile(build.makeAbsPath(config.wrap.startFile, absFilePath));
653
+ config.wrap.end = config.wrap.end ||
654
+ file.readFile(build.makeAbsPath(config.wrap.endFile, absFilePath));
655
+ }
656
+ }
657
+ } catch (wrapError) {
658
+ throw new Error('Malformed wrap config: need both start/end or ' +
659
+ 'startFile/endFile: ' + wrapError.toString());
660
+ }
661
+
662
+
663
+ //Set up proper info for namespaces and using namespaces in transport
664
+ //wrappings.
665
+ config.namespaceWithDot = config.namespace ? config.namespace + '.' : '';
666
+ config.anonDefRegExp = build.makeAnonDefRegExp(config.namespaceWithDot);
667
+
668
+ //Do final input verification
669
+ if (config.context) {
670
+ throw new Error('The build argument "context" is not supported' +
671
+ ' in a build. It should only be used in web' +
672
+ ' pages.');
673
+ }
674
+
675
+ //Set file.fileExclusionRegExp if desired
676
+ if ('fileExclusionRegExp' in config) {
677
+ if (typeof config.fileExclusionRegExp === "string") {
678
+ file.exclusionRegExp = new RegExp(config.fileExclusionRegExp);
679
+ } else {
680
+ file.exclusionRegExp = config.fileExclusionRegExp;
681
+ }
682
+ } else if ('dirExclusionRegExp' in config) {
683
+ //Set file.dirExclusionRegExp if desired, this is the old
684
+ //name for fileExclusionRegExp before 1.0.2. Support for backwards
685
+ //compatibility
686
+ file.exclusionRegExp = config.dirExclusionRegExp;
687
+ }
688
+
689
+ return config;
690
+ };
691
+
692
+ /**
693
+ * finds the module being built/optimized with the given moduleName,
694
+ * or returns null.
695
+ * @param {String} moduleName
696
+ * @param {Array} modules
697
+ * @returns {Object} the module object from the build profile, or null.
698
+ */
699
+ build.findBuildModule = function (moduleName, modules) {
700
+ var i, module;
701
+ for (i = 0; (module = modules[i]); i++) {
702
+ if (module.name === moduleName) {
703
+ return module;
704
+ }
705
+ }
706
+ return null;
707
+ };
708
+
709
+ /**
710
+ * Removes a module name and path from a layer, if it is supposed to be
711
+ * excluded from the layer.
712
+ * @param {String} moduleName the name of the module
713
+ * @param {String} path the file path for the module
714
+ * @param {Object} layer the layer to remove the module/path from
715
+ */
716
+ build.removeModulePath = function (module, path, layer) {
717
+ var index = layer.buildFilePaths.indexOf(path);
718
+ if (index !== -1) {
719
+ layer.buildFilePaths.splice(index, 1);
720
+ }
721
+
722
+ //Take it out of the specified modules. Specified modules are mostly
723
+ //used to find require modifiers.
724
+ delete layer.specified[module];
725
+ };
726
+
727
+ /**
728
+ * Uses the module build config object to trace the dependencies for the
729
+ * given module.
730
+ *
731
+ * @param {Object} module the module object from the build config info.
732
+ * @param {Object} the build config object.
733
+ *
734
+ * @returns {Object} layer information about what paths and modules should
735
+ * be in the flattened module.
736
+ */
737
+ build.traceDependencies = function (module, config) {
738
+ var include, override, layer, context, baseConfig, oldContext;
739
+
740
+ //Reset some state set up in requirePatch.js, and clean up require's
741
+ //current context.
742
+ oldContext = require._buildReset();
743
+
744
+ //Grab the reset layer and context after the reset, but keep the
745
+ //old config to reuse in the new context.
746
+ baseConfig = oldContext.config;
747
+ layer = require._layer;
748
+ context = layer.context;
749
+
750
+ //Put back basic config, use a fresh object for it.
751
+ //WARNING: probably not robust for paths and packages/packagePaths,
752
+ //since those property's objects can be modified. But for basic
753
+ //config clone it works out.
754
+ require(lang.delegate(baseConfig));
755
+
756
+ logger.trace("\nTracing dependencies for: " + (module.name || module.out));
757
+ include = module.name && !module.create ? [module.name] : [];
758
+ if (module.include) {
759
+ include = include.concat(module.include);
760
+ }
761
+
762
+ //If there are overrides to basic config, set that up now.;
763
+ if (module.override) {
764
+ override = lang.delegate(baseConfig);
765
+ lang.mixin(override, module.override, true);
766
+ require(override);
767
+ }
768
+
769
+ //Figure out module layer dependencies by calling require to do the work.
770
+ require(include);
771
+
772
+ //Pull out the layer dependencies.
773
+ layer.specified = context.specified;
774
+
775
+ //Reset config
776
+ if (module.override) {
777
+ require(baseConfig);
778
+ }
779
+
780
+ return layer;
781
+ };
782
+
783
+ /**
784
+ * Uses the module build config object to create an flattened version
785
+ * of the module, with deep dependencies included.
786
+ *
787
+ * @param {Object} module the module object from the build config info.
788
+ *
789
+ * @param {Object} layer the layer object returned from build.traceDependencies.
790
+ *
791
+ * @param {Object} the build config object.
792
+ *
793
+ * @returns {Object} with two properties: "text", the text of the flattened
794
+ * module, and "buildText", a string of text representing which files were
795
+ * included in the flattened module text.
796
+ */
797
+ build.flattenModule = function (module, layer, config) {
798
+ var buildFileContents = "",
799
+ namespace = config.namespace ? config.namespace + '.' : '',
800
+ context = layer.context,
801
+ anonDefRegExp = config.anonDefRegExp,
802
+ path, reqIndex, fileContents, currContents,
803
+ i, moduleName,
804
+ parts, builder, writeApi;
805
+
806
+ //Use override settings, particularly for pragmas
807
+ if (module.override) {
808
+ config = lang.delegate(config);
809
+ lang.mixin(config, module.override, true);
810
+ }
811
+
812
+ //Start build output for the module.
813
+ buildFileContents += "\n" +
814
+ (config.dir ? module._buildPath.replace(config.dir, "") : module._buildPath) +
815
+ "\n----------------\n";
816
+
817
+ //If there was an existing file with require in it, hoist to the top.
818
+ if (layer.existingRequireUrl) {
819
+ reqIndex = layer.buildFilePaths.indexOf(layer.existingRequireUrl);
820
+ if (reqIndex !== -1) {
821
+ layer.buildFilePaths.splice(reqIndex, 1);
822
+ layer.buildFilePaths.unshift(layer.existingRequireUrl);
823
+ }
824
+ }
825
+
826
+ //Write the built module to disk, and build up the build output.
827
+ fileContents = "";
828
+ for (i = 0; (path = layer.buildFilePaths[i]); i++) {
829
+ moduleName = layer.buildFileToModule[path];
830
+
831
+ //Figure out if the module is a result of a build plugin, and if so,
832
+ //then delegate to that plugin.
833
+ parts = context.makeModuleMap(moduleName);
834
+ builder = parts.prefix && context.defined[parts.prefix];
835
+ if (builder) {
836
+ if (builder.write) {
837
+ writeApi = function (input) {
838
+ fileContents += "\n" + addSemiColon(input);
839
+ };
840
+ writeApi.asModule = function (moduleName, input) {
841
+ fileContents += "\n" +
842
+ addSemiColon(
843
+ build.toTransport(anonDefRegExp, namespace, moduleName, path, input, layer));
844
+ };
845
+ builder.write(parts.prefix, parts.name, writeApi);
846
+ }
847
+ } else {
848
+ currContents = file.readFile(path);
849
+
850
+ if (config.namespace) {
851
+ currContents = pragma.namespace(currContents, config.namespace);
852
+ }
853
+
854
+ currContents = build.toTransport(anonDefRegExp, namespace, moduleName, path, currContents, layer);
855
+
856
+ //Semicolon is for files that are not well formed when
857
+ //concatenated with other content.
858
+ fileContents += "\n" + addSemiColon(currContents);
859
+ }
860
+
861
+ buildFileContents += path.replace(config.dir, "") + "\n";
862
+ //Some files may not have declared a require module, and if so,
863
+ //put in a placeholder call so the require does not try to load them
864
+ //after the module is processed.
865
+ //If we have a name, but no defined module, then add in the placeholder.
866
+ if (moduleName && !layer.modulesWithNames[moduleName] && !config.skipModuleInsertion) {
867
+ //If including jquery, register the module correctly, otherwise
868
+ //register an empty function. For jquery, make sure jQuery is
869
+ //a real object, and perhaps not some other file mapping, like
870
+ //to zepto.
871
+ if (moduleName === 'jquery') {
872
+ fileContents += '\n(function () {\n' +
873
+ 'var jq = typeof jQuery !== "undefined" && jQuery;\n' +
874
+ namespace +
875
+ 'define("jquery", [], function () { return jq; });\n' +
876
+ '}());\n';
877
+ } else {
878
+ fileContents += '\n' + namespace + 'define("' + moduleName + '", function(){});\n';
879
+ }
880
+ }
881
+ }
882
+
883
+ return {
884
+ text: config.wrap ?
885
+ config.wrap.start + fileContents + config.wrap.end :
886
+ fileContents,
887
+ buildText: buildFileContents
888
+ };
889
+ };
890
+
891
+ /**
892
+ * Creates the regexp to find anonymous defines.
893
+ * @param {String} namespace an optional namespace to use. The namespace
894
+ * should *include* a trailing dot. So a valid value would be 'foo.'
895
+ * @returns {RegExp}
896
+ */
897
+ build.makeAnonDefRegExp = function (namespace) {
898
+ //This regexp is not bullet-proof, and it has one optional part to
899
+ //avoid issues with some Dojo transition modules that use a
900
+ //define(\n//begin v1.x content
901
+ //for a comment.
902
+ return new RegExp('(^|[^\\.])(' + (namespace || '').replace(/\./g, '\\.') +
903
+ 'define|define)\\s*\\(\\s*(\\/\\/[^\\n\\r]*[\\r\\n])?(\\[|f|\\{|["\']([^"\']+)["\'])(\\s*,\\s*f)?');
904
+ };
905
+
906
+ build.leadingCommaRegExp = /^\s*,/;
907
+
908
+ build.toTransport = function (anonDefRegExp, namespace, moduleName, path, contents, layer) {
909
+
910
+ //If anonymous module, insert the module name.
911
+ return contents.replace(anonDefRegExp, function (match, start, callName, possibleComment, suffix, namedModule, namedFuncStart) {
912
+ //A named module with either listed dependencies or an object
913
+ //literal for a value. Skip it. If named module, only want ones
914
+ //whose next argument is a function literal to scan for
915
+ //require('') dependecies.
916
+ if (namedModule && !namedFuncStart) {
917
+ return match;
918
+ }
919
+
920
+ //Only mark this module as having a name if not a named module,
921
+ //or if a named module and the name matches expectations.
922
+ if (layer && (!namedModule || namedModule === moduleName)) {
923
+ layer.modulesWithNames[moduleName] = true;
924
+ }
925
+
926
+ var deps = null;
927
+
928
+ //Look for CommonJS require calls inside the function if this is
929
+ //an anonymous define call that just has a function registered.
930
+ //Also look if a named define function but has a factory function
931
+ //as the second arg that should be scanned for dependencies.
932
+ if (suffix.indexOf('f') !== -1 || (namedModule)) {
933
+ deps = parse.getAnonDeps(path, contents);
934
+
935
+ if (deps.length) {
936
+ deps = deps.map(function (dep) {
937
+ return "'" + dep + "'";
938
+ });
939
+ } else {
940
+ deps = [];
941
+ }
942
+ }
943
+
944
+ return start + namespace + "define('" + (namedModule || moduleName) + "'," +
945
+ (deps ? ('[' + deps.toString() + '],') : '') +
946
+ (namedModule ? namedFuncStart.replace(build.leadingCommaRegExp, '') : suffix);
947
+ });
948
+
949
+ };
950
+
951
+ return build;
952
+ });