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,11 @@
1
+ ({
2
+ baseUrl: '.',
3
+ optimize: 'none',
4
+ paths: {
5
+ fs: 'blank',
6
+ path: 'blank'
7
+ },
8
+ skipModuleInsertion: true,
9
+ name: '../build',
10
+ out: 'optotext.js'
11
+ })
@@ -0,0 +1,590 @@
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 plusplus: false, strict: false */
8
+ /*global define: false */
9
+
10
+ define(['uglifyjs/index'], function (uglify) {
11
+ var parser = uglify.parser,
12
+ processor = uglify.uglify,
13
+ ostring = Object.prototype.toString,
14
+ isArray;
15
+
16
+ if (Array.isArray) {
17
+ isArray = Array.isArray;
18
+ } else {
19
+ isArray = function (it) {
20
+ return ostring.call(it) === "[object Array]";
21
+ };
22
+ }
23
+
24
+ /**
25
+ * Determines if the AST node is an array literal
26
+ */
27
+ function isArrayLiteral(node) {
28
+ return node[0] === 'array';
29
+ }
30
+
31
+ /**
32
+ * Determines if the AST node is an object literal
33
+ */
34
+ function isObjectLiteral(node) {
35
+ return node[0] === 'object';
36
+ }
37
+
38
+ /**
39
+ * Converts a regular JS array of strings to an AST node that
40
+ * represents that array.
41
+ * @param {Array} ary
42
+ * @param {Node} an AST node that represents an array of strings.
43
+ */
44
+ function toAstArray(ary) {
45
+ var output = [
46
+ 'array',
47
+ []
48
+ ],
49
+ i, item;
50
+
51
+ for (i = 0; (item = ary[i]); i++) {
52
+ output[1].push([
53
+ 'string',
54
+ item
55
+ ]);
56
+ }
57
+
58
+ return output;
59
+ }
60
+
61
+ /**
62
+ * Validates a node as being an object literal (like for i18n bundles)
63
+ * or an array literal with just string members. If an array literal,
64
+ * only return array members that are full strings. So the caller of
65
+ * this function should use the return value as the new value for the
66
+ * node.
67
+ *
68
+ * This function does not need to worry about comments, they are not
69
+ * present in this AST.
70
+ *
71
+ * @param {Node} node an AST node.
72
+ *
73
+ * @returns {Node} an AST node to use for the valid dependencies.
74
+ * If null is returned, then it means the input node was not a valid
75
+ * dependency.
76
+ */
77
+ function validateDeps(node) {
78
+ var newDeps = ['array', []],
79
+ arrayArgs, i, dep;
80
+
81
+ if (!node) {
82
+ return null;
83
+ }
84
+
85
+ if (isObjectLiteral(node) || node[0] === 'function') {
86
+ return node;
87
+ }
88
+
89
+ //Dependencies can be an object literal or an array.
90
+ if (!isArrayLiteral(node)) {
91
+ return null;
92
+ }
93
+
94
+ arrayArgs = node[1];
95
+
96
+ for (i = 0; i < arrayArgs.length; i++) {
97
+ dep = arrayArgs[i];
98
+ if (dep[0] === 'string') {
99
+ newDeps[1].push(dep);
100
+ }
101
+ }
102
+ return newDeps[1].length ? newDeps : null;
103
+ }
104
+
105
+ /**
106
+ * Gets dependencies from a node, but only if it is an array literal,
107
+ * and only if the dependency is a string literal.
108
+ *
109
+ * This function does not need to worry about comments, they are not
110
+ * present in this AST.
111
+ *
112
+ * @param {Node} node an AST node.
113
+ *
114
+ * @returns {Array} of valid dependencies.
115
+ * If null is returned, then it means the input node was not a valid
116
+ * array literal, or did not have any string literals..
117
+ */
118
+ function getValidDeps(node) {
119
+ var newDeps = [],
120
+ arrayArgs, i, dep;
121
+
122
+ if (!node) {
123
+ return null;
124
+ }
125
+
126
+ if (isObjectLiteral(node) || node[0] === 'function') {
127
+ return null;
128
+ }
129
+
130
+ //Dependencies can be an object literal or an array.
131
+ if (!isArrayLiteral(node)) {
132
+ return null;
133
+ }
134
+
135
+ arrayArgs = node[1];
136
+
137
+ for (i = 0; i < arrayArgs.length; i++) {
138
+ dep = arrayArgs[i];
139
+ if (dep[0] === 'string') {
140
+ newDeps.push(dep[1]);
141
+ }
142
+ }
143
+ return newDeps.length ? newDeps : null;
144
+ }
145
+
146
+ /**
147
+ * Main parse function. Returns a string of any valid require or define/require.def
148
+ * calls as part of one JavaScript source string.
149
+ * @param {String} moduleName the module name that represents this file.
150
+ * It is used to create a default define if there is not one already for the file.
151
+ * This allows properly tracing dependencies for builds. Otherwise, if
152
+ * the file just has a require() call, the file dependencies will not be
153
+ * properly reflected: the file will come before its dependencies.
154
+ * @param {String} moduleName
155
+ * @param {String} fileName
156
+ * @param {String} fileContents
157
+ * @param {Object} options optional options. insertNeedsDefine: true will
158
+ * add calls to require.needsDefine() if appropriate.
159
+ * @returns {String} JS source string or null, if no require or define/require.def
160
+ * calls are found.
161
+ */
162
+ function parse(moduleName, fileName, fileContents, options) {
163
+ options = options || {};
164
+
165
+ //Set up source input
166
+ var moduleDeps = [],
167
+ result = '',
168
+ moduleList = [],
169
+ needsDefine = true,
170
+ astRoot = parser.parse(fileContents),
171
+ i, moduleCall, depString;
172
+
173
+ parse.recurse(astRoot, function (callName, config, name, deps) {
174
+ //If name is an array, it means it is an anonymous module,
175
+ //so adjust args appropriately. An anonymous module could
176
+ //have a FUNCTION as the name type, but just ignore those
177
+ //since we just want to find dependencies.
178
+ if (name && isArrayLiteral(name)) {
179
+ deps = name;
180
+ name = null;
181
+ }
182
+
183
+ if (!(deps = getValidDeps(deps))) {
184
+ deps = [];
185
+ }
186
+
187
+ //Get the name as a string literal, if it is available.
188
+ if (name && name[0] === 'string') {
189
+ name = name[1];
190
+ } else {
191
+ name = null;
192
+ }
193
+
194
+ if (callName === 'define' && (!name || name === moduleName)) {
195
+ needsDefine = false;
196
+ }
197
+
198
+ if (!name) {
199
+ //If there is no module name, the dependencies are for
200
+ //this file/default module name.
201
+ moduleDeps = moduleDeps.concat(deps);
202
+ } else {
203
+ moduleList.push({
204
+ name: name,
205
+ deps: deps
206
+ });
207
+ }
208
+
209
+ //If define was found, no need to dive deeper, unless
210
+ //the config explicitly wants to dig deeper.
211
+ return !options.findNestedDependencies;
212
+ }, options);
213
+
214
+ if (options.insertNeedsDefine && needsDefine) {
215
+ result += 'require.needsDefine("' + moduleName + '");';
216
+ }
217
+
218
+ if (moduleDeps.length || moduleList.length) {
219
+ for (i = 0; (moduleCall = moduleList[i]); i++) {
220
+ if (result) {
221
+ result += '\n';
222
+ }
223
+
224
+ //If this is the main module for this file, combine any
225
+ //"anonymous" dependencies (could come from a nested require
226
+ //call) with this module.
227
+ if (moduleCall.name === moduleName) {
228
+ moduleCall.deps = moduleCall.deps.concat(moduleDeps);
229
+ moduleDeps = [];
230
+ }
231
+
232
+ depString = moduleCall.deps.length ? '["' + moduleCall.deps.join('","') + '"]' : '[]';
233
+ result += 'define("' + moduleCall.name + '",' + depString + ');';
234
+ }
235
+ if (moduleDeps.length) {
236
+ if (result) {
237
+ result += '\n';
238
+ }
239
+ depString = moduleDeps.length ? '["' + moduleDeps.join('","') + '"]' : '[]';
240
+ result += 'define("' + moduleName + '",' + depString + ');';
241
+ }
242
+ }
243
+
244
+ return result ? result : null;
245
+ }
246
+
247
+ //Add some private methods to object for use in derived objects.
248
+ parse.isArray = isArray;
249
+ parse.isObjectLiteral = isObjectLiteral;
250
+ parse.isArrayLiteral = isArrayLiteral;
251
+
252
+ /**
253
+ * Handles parsing a file recursively for require calls.
254
+ * @param {Array} parentNode the AST node to start with.
255
+ * @param {Function} onMatch function to call on a parse match.
256
+ * @param {Object} [options] This is normally the build config options if
257
+ * it is passed.
258
+ */
259
+ parse.recurse = function (parentNode, onMatch, options) {
260
+ var hasHas = options && options.has,
261
+ i, node;
262
+
263
+ if (isArray(parentNode)) {
264
+ for (i = 0; i < parentNode.length; i++) {
265
+ node = parentNode[i];
266
+ if (isArray(node)) {
267
+ //If has config is in play, if calls have been converted
268
+ //by this point to be true/false values. So, if
269
+ //options has a 'has' value, skip if branches that have
270
+ //literal false values.
271
+
272
+ //uglify returns if constructs in an array:
273
+ //[0]: 'if'
274
+ //[1]: the condition, ['name', true | false] for the has replaced case.
275
+ //[2]: the block to process if true
276
+ //[3]: the block to process if false
277
+ //For if/else if/else, the else if is in the [3],
278
+ //so only ever have to deal with this structure.
279
+ if (hasHas && node[0] === 'if' && node[1] && node[1][0] === 'name' &&
280
+ (node[1][1] === 'true' || node[1][1] === 'false')) {
281
+ if (node[1][1] === 'true') {
282
+ this.recurse([node[2]], onMatch, options);
283
+ } else {
284
+ this.recurse([node[3]], onMatch, options);
285
+ }
286
+ } else {
287
+ if (this.parseNode(node, onMatch)) {
288
+ //The onMatch indicated parsing should
289
+ //stop for children of this node.
290
+ continue;
291
+ }
292
+ this.recurse(node, onMatch, options);
293
+ }
294
+ }
295
+ }
296
+ }
297
+ };
298
+
299
+ /**
300
+ * Determines if the file defines require().
301
+ * @param {String} fileName
302
+ * @param {String} fileContents
303
+ * @returns {Boolean}
304
+ */
305
+ parse.definesRequire = function (fileName, fileContents) {
306
+ var astRoot = parser.parse(fileContents);
307
+ return this.nodeHasRequire(astRoot);
308
+ };
309
+
310
+ /**
311
+ * Finds require("") calls inside a CommonJS anonymous module wrapped in a
312
+ * define(function(require, exports, module){}) wrapper. These dependencies
313
+ * will be added to a modified define() call that lists the dependencies
314
+ * on the outside of the function.
315
+ * @param {String} fileName
316
+ * @param {String} fileContents
317
+ * @returns {Array} an array of module names that are dependencies. Always
318
+ * returns an array, but could be of length zero.
319
+ */
320
+ parse.getAnonDeps = function (fileName, fileContents) {
321
+ var astRoot = parser.parse(fileContents),
322
+ defFunc = this.findAnonDefineFactory(astRoot);
323
+
324
+ return parse.getAnonDepsFromNode(defFunc);
325
+ };
326
+
327
+ /**
328
+ * Finds require("") calls inside a CommonJS anonymous module wrapped
329
+ * in a define function, given an AST node for the definition function.
330
+ * @param {Node} node the AST node for the definition function.
331
+ * @returns {Array} and array of dependency names. Can be of zero length.
332
+ */
333
+ parse.getAnonDepsFromNode = function (node) {
334
+ var deps = [],
335
+ funcArgLength;
336
+
337
+ if (node) {
338
+ this.findRequireDepNames(node, deps);
339
+
340
+ //If no deps, still add the standard CommonJS require, exports, module,
341
+ //in that order, to the deps, but only if specified as function args.
342
+ //In particular, if exports is used, it is favored over the return
343
+ //value of the function, so only add it if asked.
344
+ funcArgLength = node[2] && node[2].length;
345
+ if (funcArgLength) {
346
+ deps = (funcArgLength > 1 ? ["require", "exports", "module"] :
347
+ ["require"]).concat(deps);
348
+ }
349
+ }
350
+ return deps;
351
+ };
352
+
353
+ /**
354
+ * Finds the function in define(function (require, exports, module){});
355
+ * @param {Array} node
356
+ * @returns {Boolean}
357
+ */
358
+ parse.findAnonDefineFactory = function (node) {
359
+ var callback, i, n, call, args;
360
+
361
+ if (isArray(node)) {
362
+ if (node[0] === 'call') {
363
+ call = node[1];
364
+ args = node[2];
365
+ if ((call[0] === 'name' && call[1] === 'define') ||
366
+ (call[0] === 'dot' && call[1][1] === 'require' && call[2] === 'def')) {
367
+
368
+ //There should only be one argument and it should be a function,
369
+ //or a named module with function as second arg
370
+ if (args.length === 1 && args[0][0] === 'function') {
371
+ return args[0];
372
+ } else if (args.length === 2 && args[0][0] === 'string' &&
373
+ args[1][0] === 'function') {
374
+ return args[1];
375
+ }
376
+ }
377
+ }
378
+
379
+ //Check child nodes
380
+ for (i = 0; i < node.length; i++) {
381
+ n = node[i];
382
+ if ((callback = this.findAnonDefineFactory(n))) {
383
+ return callback;
384
+ }
385
+ }
386
+ }
387
+
388
+ return null;
389
+ };
390
+
391
+ /**
392
+ * Finds all dependencies specified in dependency arrays and inside
393
+ * simplified commonjs wrappers.
394
+ * @param {String} fileName
395
+ * @param {String} fileContents
396
+ *
397
+ * @returns {Array} an array of dependency strings. The dependencies
398
+ * have not been normalized, they may be relative IDs.
399
+ */
400
+ parse.findDependencies = function (fileName, fileContents) {
401
+ //This is a litle bit inefficient, it ends up with two uglifyjs parser
402
+ //calls. Can revisit later, but trying to build out larger functional
403
+ //pieces first.
404
+ var dependencies = parse.getAnonDeps(fileName, fileContents),
405
+ astRoot = parser.parse(fileContents);
406
+
407
+ parse.recurse(astRoot, function (callName, config, name, deps) {
408
+ //Normalize the input args.
409
+ if (name && isArrayLiteral(name)) {
410
+ deps = name;
411
+ name = null;
412
+ }
413
+
414
+ if ((deps = getValidDeps(deps))) {
415
+ dependencies = dependencies.concat(deps);
416
+ }
417
+ });
418
+
419
+ return dependencies;
420
+ };
421
+
422
+ parse.findRequireDepNames = function (node, deps) {
423
+ var moduleName, i, n, call, args;
424
+
425
+ if (isArray(node)) {
426
+ if (node[0] === 'call') {
427
+ call = node[1];
428
+ args = node[2];
429
+
430
+ if (call && call[0] === 'name' && call[1] === 'require') {
431
+ moduleName = args[0];
432
+ if (moduleName[0] === 'string') {
433
+ deps.push(moduleName[1]);
434
+ }
435
+ }
436
+
437
+
438
+ }
439
+
440
+ //Check child nodes
441
+ for (i = 0; i < node.length; i++) {
442
+ n = node[i];
443
+ this.findRequireDepNames(n, deps);
444
+ }
445
+ }
446
+ };
447
+
448
+ /**
449
+ * Determines if a given node contains a require() definition.
450
+ * @param {Array} node
451
+ * @returns {Boolean}
452
+ */
453
+ parse.nodeHasRequire = function (node) {
454
+ if (this.isDefineNode(node)) {
455
+ return true;
456
+ }
457
+
458
+ if (isArray(node)) {
459
+ for (var i = 0, n; i < node.length; i++) {
460
+ n = node[i];
461
+ if (this.nodeHasRequire(n)) {
462
+ return true;
463
+ }
464
+ }
465
+ }
466
+
467
+ return false;
468
+ };
469
+
470
+ /**
471
+ * Is the given node the actual definition of define(). Actually uses
472
+ * the definition of define.amd to find require.
473
+ * @param {Array} node
474
+ * @returns {Boolean}
475
+ */
476
+ parse.isDefineNode = function (node) {
477
+ //Actually look for the define.amd = assignment, since
478
+ //that is more indicative of RequireJS vs a plain require definition.
479
+ var assign;
480
+ if (!node) {
481
+ return null;
482
+ }
483
+
484
+ if (node[0] === 'assign' && node[1] === true) {
485
+ assign = node[2];
486
+ if (assign[0] === 'dot' && assign[1][0] === 'name' &&
487
+ assign[1][1] === 'define' && assign[2] === 'amd') {
488
+ return true;
489
+ }
490
+ }
491
+ return false;
492
+ };
493
+
494
+ /**
495
+ * Determines if a specific node is a valid require or define/require.def call.
496
+ * @param {Array} node
497
+ * @param {Function} onMatch a function to call when a match is found.
498
+ * It is passed the match name, and the config, name, deps possible args.
499
+ * The config, name and deps args are not normalized.
500
+ *
501
+ * @returns {String} a JS source string with the valid require/define call.
502
+ * Otherwise null.
503
+ */
504
+ parse.parseNode = function (node, onMatch) {
505
+ var call, name, config, deps, args, cjsDeps;
506
+
507
+ if (!isArray(node)) {
508
+ return false;
509
+ }
510
+
511
+ if (node[0] === 'call') {
512
+ call = node[1];
513
+ args = node[2];
514
+
515
+ if (call) {
516
+ if (call[0] === 'name' &&
517
+ (call[1] === 'require' || call[1] === 'requirejs')) {
518
+
519
+ //It is a plain require() call.
520
+ config = args[0];
521
+ deps = args[1];
522
+ if (isArrayLiteral(config)) {
523
+ deps = config;
524
+ config = null;
525
+ }
526
+
527
+ if (!(deps = validateDeps(deps))) {
528
+ return null;
529
+ }
530
+
531
+ return onMatch("require", null, null, deps);
532
+
533
+ } else if (call[0] === 'name' && call[1] === 'define') {
534
+
535
+ //A define call
536
+ name = args[0];
537
+ deps = args[1];
538
+ //Only allow define calls that match what is expected
539
+ //in an AMD call:
540
+ //* first arg should be string, array, function or object
541
+ //* second arg optional, or array, function or object.
542
+ //This helps weed out calls to a non-AMD define, but it is
543
+ //not completely robust. Someone could create a define
544
+ //function that still matches this shape, but this is the
545
+ //best that is possible, and at least allows UglifyJS,
546
+ //which does create its own internal define in one file,
547
+ //to be inlined.
548
+ if (((name[0] === 'string' || isArrayLiteral(name) ||
549
+ name[0] === 'function' || isObjectLiteral(name))) &&
550
+ (!deps || isArrayLiteral(deps) ||
551
+ deps[0] === 'function' || isObjectLiteral(deps) ||
552
+ // allow define(['dep'], factory) pattern
553
+ (isArrayLiteral(name) && deps[0] === 'name' && args.length === 2))) {
554
+
555
+ //If first arg is a function, could be a commonjs wrapper,
556
+ //look inside for commonjs dependencies.
557
+ //Also, if deps is a function look for commonjs deps.
558
+ if (name && name[0] === 'function') {
559
+ cjsDeps = parse.getAnonDepsFromNode(name);
560
+ if (cjsDeps.length) {
561
+ name = toAstArray(cjsDeps);
562
+ }
563
+ } else if (deps && deps[0] === 'function') {
564
+ cjsDeps = parse.getAnonDepsFromNode(deps);
565
+ if (cjsDeps.length) {
566
+ deps = toAstArray(cjsDeps);
567
+ }
568
+ }
569
+
570
+ return onMatch("define", null, name, deps);
571
+ }
572
+ }
573
+ }
574
+ }
575
+
576
+ return false;
577
+ };
578
+
579
+ /**
580
+ * Converts an AST node into a JS source string. Does not maintain formatting
581
+ * or even comments from original source, just returns valid JS source.
582
+ * @param {Array} node
583
+ * @returns {String} a JS source string.
584
+ */
585
+ parse.nodeToString = function (node) {
586
+ return processor.gen_code(node, true);
587
+ };
588
+
589
+ return parse;
590
+ });