sproutcore 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +269 -0
  4. data/README.txt +67 -0
  5. data/Rakefile +4 -0
  6. data/app_generators/sproutcore/USAGE +5 -0
  7. data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
  8. data/app_generators/sproutcore/templates/README +77 -0
  9. data/app_generators/sproutcore/templates/environment.yml +4 -0
  10. data/bin/sc-build +145 -0
  11. data/bin/sc-gen +24 -0
  12. data/bin/sc-server +63 -0
  13. data/bin/sproutcore +21 -0
  14. data/clients/sc_docs/controllers/docs.js +118 -0
  15. data/clients/sc_docs/core.js +19 -0
  16. data/clients/sc_docs/english.lproj/body.css +159 -0
  17. data/clients/sc_docs/english.lproj/body.rhtml +33 -0
  18. data/clients/sc_docs/english.lproj/controls.css +0 -0
  19. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  20. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  21. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  22. data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
  23. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  24. data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
  25. data/clients/sc_docs/english.lproj/strings.js +14 -0
  26. data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
  27. data/clients/sc_docs/fixtures/doc.js +11 -0
  28. data/clients/sc_docs/main.js +21 -0
  29. data/clients/sc_docs/models/doc.js +9 -0
  30. data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
  31. data/clients/sc_docs/tests/models/doc.rhtml +21 -0
  32. data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
  33. data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
  34. data/clients/sc_docs/views/doc_frame.js +33 -0
  35. data/clients/sc_docs/views/doc_label.js +20 -0
  36. data/clients/sc_test_runner/controllers/runner.js +175 -0
  37. data/clients/sc_test_runner/core.js +19 -0
  38. data/clients/sc_test_runner/english.lproj/body.css +151 -0
  39. data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
  40. data/clients/sc_test_runner/english.lproj/controls.css +0 -0
  41. data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
  42. data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
  43. data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
  44. data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
  45. data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
  46. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
  47. data/clients/sc_test_runner/english.lproj/strings.js +14 -0
  48. data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
  49. data/clients/sc_test_runner/fixtures/test.js +12 -0
  50. data/clients/sc_test_runner/main.js +26 -0
  51. data/clients/sc_test_runner/models/test.js +11 -0
  52. data/clients/sc_test_runner/views/runner_frame.js +72 -0
  53. data/clients/sc_test_runner/views/test_label.js +20 -0
  54. data/config/hoe.rb +70 -0
  55. data/config/requirements.rb +17 -0
  56. data/environment.yml +9 -0
  57. data/frameworks/prototype/prototype.js +4186 -0
  58. data/frameworks/sproutcore/Core.js +378 -0
  59. data/frameworks/sproutcore/README +3 -0
  60. data/frameworks/sproutcore/controllers/array.js +236 -0
  61. data/frameworks/sproutcore/controllers/collection.js +305 -0
  62. data/frameworks/sproutcore/controllers/controller.js +323 -0
  63. data/frameworks/sproutcore/controllers/object.js +372 -0
  64. data/frameworks/sproutcore/drag/drag.js +549 -0
  65. data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
  66. data/frameworks/sproutcore/drag/drag_source.js +64 -0
  67. data/frameworks/sproutcore/drag/drop_target.js +153 -0
  68. data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
  69. data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
  70. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  71. data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
  72. data/frameworks/sproutcore/english.lproj/menu.css +121 -0
  73. data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
  74. data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
  75. data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
  76. data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
  77. data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
  78. data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
  79. data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
  80. data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
  81. data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
  82. data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
  83. data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
  84. data/frameworks/sproutcore/english.lproj/panes.css +155 -0
  85. data/frameworks/sproutcore/english.lproj/picker.css +22 -0
  86. data/frameworks/sproutcore/english.lproj/strings.js +15 -0
  87. data/frameworks/sproutcore/english.lproj/tab.css +23 -0
  88. data/frameworks/sproutcore/english.lproj/tests.css +67 -0
  89. data/frameworks/sproutcore/english.lproj/theme.css +77 -0
  90. data/frameworks/sproutcore/foundation/animator.js +670 -0
  91. data/frameworks/sproutcore/foundation/application.js +199 -0
  92. data/frameworks/sproutcore/foundation/array.js +348 -0
  93. data/frameworks/sproutcore/foundation/benchmark.js +211 -0
  94. data/frameworks/sproutcore/foundation/binding.js +384 -0
  95. data/frameworks/sproutcore/foundation/date.js +357 -0
  96. data/frameworks/sproutcore/foundation/error.js +39 -0
  97. data/frameworks/sproutcore/foundation/input_manager.js +153 -0
  98. data/frameworks/sproutcore/foundation/json.js +296 -0
  99. data/frameworks/sproutcore/foundation/mock.js +42 -0
  100. data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
  101. data/frameworks/sproutcore/foundation/object.js +777 -0
  102. data/frameworks/sproutcore/foundation/observable.js +451 -0
  103. data/frameworks/sproutcore/foundation/page.js +63 -0
  104. data/frameworks/sproutcore/foundation/path_module.js +413 -0
  105. data/frameworks/sproutcore/foundation/responder.js +310 -0
  106. data/frameworks/sproutcore/foundation/routes.js +371 -0
  107. data/frameworks/sproutcore/foundation/run_loop.js +21 -0
  108. data/frameworks/sproutcore/foundation/server.js +491 -0
  109. data/frameworks/sproutcore/foundation/set.js +96 -0
  110. data/frameworks/sproutcore/foundation/string.js +149 -0
  111. data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
  112. data/frameworks/sproutcore/foundation/unittest.js +622 -0
  113. data/frameworks/sproutcore/foundation/utils.js +61 -0
  114. data/frameworks/sproutcore/globals/panels.js +182 -0
  115. data/frameworks/sproutcore/globals/popups.js +60 -0
  116. data/frameworks/sproutcore/globals/window.js +381 -0
  117. data/frameworks/sproutcore/lib/index.rhtml +66 -0
  118. data/frameworks/sproutcore/models/collection.js +395 -0
  119. data/frameworks/sproutcore/models/record.js +622 -0
  120. data/frameworks/sproutcore/models/store.js +295 -0
  121. data/frameworks/sproutcore/panes/dialog.js +16 -0
  122. data/frameworks/sproutcore/panes/manager.js +164 -0
  123. data/frameworks/sproutcore/panes/menu.js +45 -0
  124. data/frameworks/sproutcore/panes/overlay.js +231 -0
  125. data/frameworks/sproutcore/panes/pane.js +90 -0
  126. data/frameworks/sproutcore/panes/panel.js +19 -0
  127. data/frameworks/sproutcore/panes/picker.js +45 -0
  128. data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
  129. data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
  130. data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
  131. data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
  132. data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
  133. data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
  134. data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
  135. data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
  136. data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
  137. data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
  138. data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
  139. data/frameworks/sproutcore/validators/credit_card.js +92 -0
  140. data/frameworks/sproutcore/validators/date.js +36 -0
  141. data/frameworks/sproutcore/validators/email.js +29 -0
  142. data/frameworks/sproutcore/validators/not_empty.js +24 -0
  143. data/frameworks/sproutcore/validators/number.js +55 -0
  144. data/frameworks/sproutcore/validators/password.js +78 -0
  145. data/frameworks/sproutcore/validators/validator.js +304 -0
  146. data/frameworks/sproutcore/views/button.js +425 -0
  147. data/frameworks/sproutcore/views/checkbox_field.js +30 -0
  148. data/frameworks/sproutcore/views/collection.js +1521 -0
  149. data/frameworks/sproutcore/views/container.js +62 -0
  150. data/frameworks/sproutcore/views/error_explanation.js +45 -0
  151. data/frameworks/sproutcore/views/field.js +214 -0
  152. data/frameworks/sproutcore/views/filter_button.js +29 -0
  153. data/frameworks/sproutcore/views/form.js +591 -0
  154. data/frameworks/sproutcore/views/image.js +141 -0
  155. data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
  156. data/frameworks/sproutcore/views/label.js +176 -0
  157. data/frameworks/sproutcore/views/menu_item.js +90 -0
  158. data/frameworks/sproutcore/views/pagination.js +54 -0
  159. data/frameworks/sproutcore/views/popup_button.js +86 -0
  160. data/frameworks/sproutcore/views/popup_menu.js +137 -0
  161. data/frameworks/sproutcore/views/progress.js +100 -0
  162. data/frameworks/sproutcore/views/radio_field.js +107 -0
  163. data/frameworks/sproutcore/views/radio_group.js +48 -0
  164. data/frameworks/sproutcore/views/segmented.js +80 -0
  165. data/frameworks/sproutcore/views/select_field.js +272 -0
  166. data/frameworks/sproutcore/views/spinner.js +11 -0
  167. data/frameworks/sproutcore/views/tab.js +126 -0
  168. data/frameworks/sproutcore/views/text_field.js +179 -0
  169. data/frameworks/sproutcore/views/textarea_field.js +14 -0
  170. data/frameworks/sproutcore/views/toolbar.js +29 -0
  171. data/frameworks/sproutcore/views/view.js +1389 -0
  172. data/frameworks/sproutcore/views/workspace.js +170 -0
  173. data/generators/client/README +3 -0
  174. data/generators/client/USAGE +12 -0
  175. data/generators/client/client_generator.rb +53 -0
  176. data/generators/client/templates/core.js +19 -0
  177. data/generators/client/templates/english.lproj/body.css +0 -0
  178. data/generators/client/templates/english.lproj/body.rhtml +3 -0
  179. data/generators/client/templates/english.lproj/controls.css +0 -0
  180. data/generators/client/templates/english.lproj/strings.js +14 -0
  181. data/generators/client/templates/main.js +37 -0
  182. data/generators/controller/USAGE +16 -0
  183. data/generators/controller/controller_generator.rb +51 -0
  184. data/generators/controller/templates/controller.js +21 -0
  185. data/generators/controller/templates/test.rhtml +21 -0
  186. data/generators/framework/README +7 -0
  187. data/generators/framework/USAGE +12 -0
  188. data/generators/framework/framework_generator.rb +53 -0
  189. data/generators/framework/templates/core.js +20 -0
  190. data/generators/framework/templates/english.lproj/body.css +0 -0
  191. data/generators/framework/templates/english.lproj/body.rhtml +3 -0
  192. data/generators/framework/templates/english.lproj/controls.css +0 -0
  193. data/generators/framework/templates/english.lproj/strings.js +14 -0
  194. data/generators/language/USAGE +16 -0
  195. data/generators/language/language_generator.rb +47 -0
  196. data/generators/language/templates/strings.js +10 -0
  197. data/generators/model/USAGE +24 -0
  198. data/generators/model/model_generator.rb +55 -0
  199. data/generators/model/templates/fixture.js +11 -0
  200. data/generators/model/templates/model.js +20 -0
  201. data/generators/model/templates/test.rhtml +21 -0
  202. data/generators/test/USAGE +16 -0
  203. data/generators/test/templates/test.rhtml +21 -0
  204. data/generators/test/test_generator.rb +47 -0
  205. data/generators/view/USAGE +16 -0
  206. data/generators/view/templates/test.rhtml +21 -0
  207. data/generators/view/templates/view.js +20 -0
  208. data/generators/view/view_generator.rb +51 -0
  209. data/jsdoc/README.txt +119 -0
  210. data/jsdoc/app/DocFile.js +137 -0
  211. data/jsdoc/app/DocTag.js +110 -0
  212. data/jsdoc/app/Doclet.js +63 -0
  213. data/jsdoc/app/Dumper.js +143 -0
  214. data/jsdoc/app/JsDoc.js +103 -0
  215. data/jsdoc/app/JsHilite.js +45 -0
  216. data/jsdoc/app/JsIO.js +163 -0
  217. data/jsdoc/app/JsParse.js +385 -0
  218. data/jsdoc/app/JsPlate.js +130 -0
  219. data/jsdoc/app/JsTestrun.js +129 -0
  220. data/jsdoc/app/JsToke.js +564 -0
  221. data/jsdoc/app/Symbol.js +298 -0
  222. data/jsdoc/app/Transformer.js +14 -0
  223. data/jsdoc/app/Util.js +97 -0
  224. data/jsdoc/app/js.jar +0 -0
  225. data/jsdoc/app/run.js +144 -0
  226. data/jsdoc/plugins/min.js +316 -0
  227. data/jsdoc/plugins/strip.js +20 -0
  228. data/jsdoc/templates/sproutcore/class.tmpl +438 -0
  229. data/jsdoc/templates/sproutcore/default.css +241 -0
  230. data/jsdoc/templates/sproutcore/index.html +13 -0
  231. data/jsdoc/templates/sproutcore/index.tmpl +21 -0
  232. data/jsdoc/templates/sproutcore/prototype.js +4186 -0
  233. data/jsdoc/templates/sproutcore/publish.js +236 -0
  234. data/jsdoc/templates/sproutcore/splash.html +7 -0
  235. data/lib/sproutcore/build_tools/html_builder.rb +88 -0
  236. data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
  237. data/lib/sproutcore/build_tools.rb +44 -0
  238. data/lib/sproutcore/bundle.rb +517 -0
  239. data/lib/sproutcore/bundle_manifest.rb +397 -0
  240. data/lib/sproutcore/generator_helper.rb +170 -0
  241. data/lib/sproutcore/helpers/capture_helper.rb +42 -0
  242. data/lib/sproutcore/helpers/static_helper.rb +80 -0
  243. data/lib/sproutcore/helpers/tag_helper.rb +110 -0
  244. data/lib/sproutcore/helpers/text_helper.rb +336 -0
  245. data/lib/sproutcore/helpers.rb +3 -0
  246. data/lib/sproutcore/jsdoc.rb +40 -0
  247. data/lib/sproutcore/jsmin.rb +247 -0
  248. data/lib/sproutcore/library.rb +258 -0
  249. data/lib/sproutcore/merb/bundle_controller.rb +179 -0
  250. data/lib/sproutcore/merb/router.rb +43 -0
  251. data/lib/sproutcore/merb.rb +27 -0
  252. data/lib/sproutcore/version.rb +9 -0
  253. data/lib/sproutcore/view_helpers/button_views.rb +302 -0
  254. data/lib/sproutcore/view_helpers/core_views.rb +284 -0
  255. data/lib/sproutcore/view_helpers/form_views.rb +258 -0
  256. data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
  257. data/lib/sproutcore/view_helpers.rb +628 -0
  258. data/lib/sproutcore.rb +30 -0
  259. data/script/destroy +14 -0
  260. data/script/generate +14 -0
  261. data/script/txt2html +74 -0
  262. data/setup.rb +1585 -0
  263. data/spec/spec.opts +1 -0
  264. data/spec/spec_helper.rb +7 -0
  265. data/spec/sproutcore_spec.rb +11 -0
  266. data/tasks/deployment.rake +34 -0
  267. data/tasks/environment.rake +7 -0
  268. data/tasks/rspec.rake +21 -0
  269. data/tasks/website.rake +17 -0
  270. metadata +365 -0
@@ -0,0 +1,564 @@
1
+ /**
2
+ * @fileOverview A library for finding the parts of JavaScript source code.
3
+ * @name JsToke
4
+ * @author Michael Mathews micmath@gmail.com
5
+ * @url $HeadURL: https://jsdoc-toolkit.googlecode.com/svn/tags/jsdoc_toolkit-1.4.0b/app/JsToke.js $
6
+ * @revision $Id: JsToke.js 213 2007-08-22 10:21:50Z micmath $
7
+ * @license <a href="http://en.wikipedia.org/wiki/MIT_License">X11/MIT License</a>
8
+ * (See the accompanying README file for full details.)
9
+ */
10
+
11
+ /** Defines the internal names for tokens. */
12
+ var TOKN = {};
13
+ TOKN.WHIT = {
14
+ " ": "SPACE",
15
+ "\f": "FORMFEED",
16
+ "\t": "TAB",
17
+ "\u0009": "UNICODE_TAB",
18
+ "\u000A": "UNICODE_NBR",
19
+ "\u0008": "VERTICAL_TAB"
20
+ };
21
+ TOKN.NEWLINE = {
22
+ "\n": "NEWLINE",
23
+ "\r": "RETURN",
24
+ "\u000A": "UNICODE_LF",
25
+ "\u000D": "UNICODE_CR",
26
+ "\u2029": "UNICODE_PS",
27
+ "\u2028": "UNICODE_LS"
28
+ };
29
+ TOKN.KEYW = {
30
+ "=break": "BREAK",
31
+ "=case": "CASE",
32
+ "=catch": "CATCH",
33
+ "=continue": "CONTINUE",
34
+ "=default": "DEFAULT",
35
+ "=delete": "DELETE",
36
+ "=do": "DO",
37
+ "=else": "ELSE",
38
+ "=false": "FALSE",
39
+ "=finally": "FINALLY",
40
+ "=for": "FOR",
41
+ "=function": "FUNCTION",
42
+ "=if": "IF",
43
+ "=in": "IN",
44
+ "=instanceof": "INSTANCEOF",
45
+ "=new": "NEW",
46
+ "=null": "NULL",
47
+ "=return": "RETURN",
48
+ "=switch": "SWITCH",
49
+ "=this": "THIS",
50
+ "=throw": "THROW",
51
+ "=true": "TRUE",
52
+ "=try": "TRY",
53
+ "=typeof": "TYPEOF",
54
+ "=void": "VOID",
55
+ "=while": "WHILE",
56
+ "=with": "WITH",
57
+ "=var": "VAR"
58
+ };
59
+
60
+ TOKN.PUNC = {
61
+ ";": "SEMICOLON",
62
+ ",": "COMMA",
63
+ "?": "HOOK",
64
+ ":": "COLON",
65
+ "||": "OR",
66
+ "&&": "AND",
67
+ "|": "BITWISE_OR",
68
+ "^": "BITWISE_XOR",
69
+ "&": "BITWISE_AND",
70
+ "===": "STRICT_EQ",
71
+ "==": "EQ",
72
+ "=": "ASSIGN",
73
+ "!==": "STRICT_NE",
74
+ "!=": "NE",
75
+ "<<": "LSH",
76
+ "<=": "LE",
77
+ "<": "LT",
78
+ ">>>": "URSH",
79
+ ">>": "RSH",
80
+ ">=": "GE",
81
+ ">": "GT",
82
+ "++": "INCREMENT",
83
+ "--": "DECREMENT",
84
+ "+": "PLUS",
85
+ "-": "MINUS",
86
+ "*": "MUL",
87
+ "/": "DIV",
88
+ "%": "MOD",
89
+ "!": "NOT",
90
+ "~": "BITWISE_NOT",
91
+ ".": "DOT",
92
+ "[": "LEFT_BRACKET",
93
+ "]": "RIGHT_BRACKET",
94
+ "{": "LEFT_CURLY",
95
+ "}": "RIGHT_CURLY",
96
+ "(": "LEFT_PAREN",
97
+ ")": "RIGHT_PAREN"
98
+ };
99
+ TOKN.MATCHING = {
100
+ "LEFT_PAREN": "RIGHT_PAREN",
101
+ "LEFT_CURLY": "RIGHT_CURLY",
102
+ "LEFT_BRACE": "RIGHT_BRACE"
103
+ };
104
+ TOKN.NUMB = /^(\.[0-9]|[0-9]+\.|[0-9])[0-9]*([eE][+-][0-9]+)?$/i;
105
+ TOKN.HEX_DEC = /^0x[0-9A-F]+$/i;
106
+
107
+ String.prototype.isWordChar = function() {
108
+ return /^[a-zA-Z0-9$_.]+$/.test(this);
109
+ }
110
+ String.prototype.isNewline = function() {
111
+ return (typeof TOKN.NEWLINE[this] != "undefined")
112
+ }
113
+ String.prototype.isSpace = function() {
114
+ return (typeof TOKN.WHIT[this] != "undefined");
115
+ }
116
+ String.prototype.last = function() {
117
+ return this.charAt[this.length-1];
118
+ }
119
+
120
+ /**
121
+ * @class Extends built-in Array under a new name.
122
+ * @constructor
123
+ */
124
+ var List = function() {
125
+ that = Array.apply(this, arguments);
126
+
127
+ /**
128
+ * Get the last item on the list.
129
+ * @name last
130
+ * @function
131
+ * @memberOf List
132
+ */
133
+ that.last = function() {
134
+ return this[this.length-1];
135
+ }
136
+ return that;
137
+ }
138
+
139
+ /**
140
+ * @class A single element of the source code.
141
+ * @constructor
142
+ */
143
+ function Token(data, type, name) {
144
+ this.data = data;
145
+ this.type = type;
146
+ this.name = name;
147
+ }
148
+ Token.prototype.toString = function() {
149
+ return "<"+this.type+" name=\""+this.name+"\">"+this.data+"</"+this.type+">";
150
+ }
151
+
152
+ /**
153
+ * Check to see what this token is.
154
+ * @param {string} what Either a name or a token type, like "COMMA" or "PUNC".
155
+ * @return {boolean}
156
+ */
157
+ Token.prototype.is = function(what) {
158
+ return this.name === what || this.type === what;
159
+ }
160
+
161
+ /**
162
+ * @class Like a string that you can easily move forward and backward through.
163
+ * @constructor
164
+ */
165
+ function TextStream(text) {
166
+ this.text = text;
167
+ this.cursor = 0;
168
+ }
169
+
170
+ /**
171
+ * Return the character n places away.
172
+ * @param {integer} n Positive or negative (defaults to zero), where to look relative to the current cursor position.
173
+ * @return {character}
174
+ */
175
+ TextStream.prototype.look = function(n) {
176
+ if (typeof n == "undefined") n = 0;
177
+
178
+ if (this.cursor+n < 0 || this.cursor+n >= this.text.length) {
179
+ var result = new String("");
180
+ result.eof = true;
181
+ return result;
182
+ }
183
+ return this.text.charAt(this.cursor+n);
184
+ }
185
+
186
+ /**
187
+ * Get the next n characters from the string relative to the current cursor position, and advance the cursor to the new position.
188
+ * @param {integer} n Positive (defaults to one), how many tokens to return.
189
+ * @return {string}
190
+ */
191
+ TextStream.prototype.next = function(n) {
192
+ if (typeof n == "undefined") n = 1;
193
+ if (n < 1) return null;
194
+
195
+ var pulled = "";
196
+ for (var i = 0; i < n; i++) {
197
+ if (this.cursor+i < this.text.length) {
198
+ pulled += this.text.charAt(this.cursor+i);
199
+ }
200
+ else {
201
+ var result = new String("");
202
+ result.eof = true;
203
+ return result;
204
+ }
205
+ }
206
+
207
+ this.cursor += n;
208
+ return pulled;
209
+ }
210
+
211
+ /**
212
+ * @class Scan the source code for possible tokens.
213
+ * @constructor
214
+ * @param {string} src The JavaScript source code.
215
+ */
216
+ function TokenReader(src){
217
+ this.src = src;
218
+ this.keepDocs = true;
219
+ this.keepWhite = false;
220
+ this.keepComments = false;
221
+ };
222
+
223
+ /**
224
+ * Turn source code into a Token array.
225
+ * @return {List} All Tokens found in the source code.
226
+ */
227
+ TokenReader.prototype.tokenize = function() {
228
+ var stream = new TextStream(this.src);
229
+ var tokens = new List();
230
+
231
+ while (!stream.look().eof) {
232
+ if (this.read_mlcomment(stream, tokens)) continue;
233
+ if (this.read_slcomment(stream, tokens)) continue;
234
+ if (this.read_dbquote(stream, tokens)) continue;
235
+ if (this.read_snquote(stream, tokens)) continue;
236
+ if (this.read_regx(stream, tokens)) continue;
237
+ if (this.read_numb(stream, tokens)) continue;
238
+ if (this.read_punc(stream, tokens)) continue;
239
+ if (this.read_space(stream, tokens)) continue;
240
+ if (this.read_newline(stream, tokens)) continue;
241
+ if (this.read_word(stream, tokens)) continue;
242
+
243
+ tokens.push(new Token(stream.next(), "TOKN", "UNKNOWN_TOKEN")); // This is an error case.
244
+ }
245
+ return tokens;
246
+ }
247
+
248
+ TokenReader.prototype.read_word = function(stream, tokens) {
249
+ var found = "";
250
+ while (!stream.look().eof && stream.look().isWordChar()) {
251
+ found += stream.next();
252
+ }
253
+
254
+ if (found === "") {
255
+ return false;
256
+ }
257
+ else {
258
+ var name;
259
+ if ((name = TOKN.KEYW["="+found])) tokens.push(new Token(found, "KEYW", name));
260
+ else tokens.push(new Token(found, "NAME", "NAME"));
261
+ return true;
262
+ }
263
+ }
264
+ TokenReader.prototype.read_punc = function(stream, tokens) {
265
+ var found = "";
266
+ var name;
267
+ while (!stream.look().eof && TOKN.PUNC[found+stream.look()]) {
268
+ found += stream.next();
269
+ }
270
+
271
+ if (found === "") {
272
+ return false;
273
+ }
274
+ else {
275
+ tokens.push(new Token(found, "PUNC", TOKN.PUNC[found]));
276
+ return true;
277
+ }
278
+ }
279
+ TokenReader.prototype.read_space = function(stream, tokens) {
280
+ var found = "";
281
+
282
+ while (!stream.look().eof && stream.look().isSpace()) {
283
+ found += stream.next();
284
+ }
285
+
286
+ if (found === "") {
287
+ return false;
288
+ }
289
+ else {
290
+ if (this.collapseWhite) found = " ";
291
+ if (this.keepWhite) tokens.push(new Token(found, "WHIT", "SPACE"));
292
+ return true;
293
+ }
294
+ }
295
+ TokenReader.prototype.read_newline = function(stream, tokens) {
296
+ var found = "";
297
+
298
+ while (!stream.look().eof && stream.look().isNewline()) {
299
+ found += stream.next();
300
+ }
301
+
302
+ if (found === "") {
303
+ return false;
304
+ }
305
+ else {
306
+ if (this.collapseWhite) found = "\n";
307
+ if (this.keepWhite) tokens.push(new Token(found, "WHIT", "NEWLINE"));
308
+ return true;
309
+ }
310
+ }
311
+ TokenReader.prototype.read_mlcomment = function(stream, tokens) {
312
+ if (stream.look() == "/" && stream.look(1) == "*") {
313
+ var found = stream.next(2);
314
+
315
+ while (!stream.look().eof && !(stream.look(-1) == "/" && stream.look(-2) == "*")) {
316
+ found += stream.next();
317
+ }
318
+
319
+ if (/^\/\*\*[^*]/.test(found) && this.keepDocs) tokens.push(new Token(found, "COMM", "JSDOC"));
320
+ else if (this.keepComments) tokens.push(new Token(found, "COMM", "MULTI_LINE_COMM"));
321
+ return true;
322
+ }
323
+ return false;
324
+ }
325
+ TokenReader.prototype.read_slcomment = function(stream, tokens) {
326
+ var found;
327
+ if (
328
+ (stream.look() == "/" && stream.look(1) == "/" && (found=stream.next(2)))
329
+ ||
330
+ (stream.look() == "<" && stream.look(1) == "!" && stream.look(2) == "-" && stream.look(3) == "-" && (found=stream.next(4)))
331
+ ) {
332
+
333
+ while (!stream.look().eof && !stream.look().isNewline()) {
334
+ found += stream.next();
335
+ }
336
+
337
+ if (this.keepComments) {
338
+ tokens.push(new Token(found, "COMM", "SINGLE_LINE_COMM"));
339
+ }
340
+ return true;
341
+ }
342
+ return false;
343
+ }
344
+ TokenReader.prototype.read_dbquote = function(stream, tokens) {
345
+ if (stream.look() == "\"") {
346
+ // find terminator
347
+ var string = stream.next();
348
+
349
+ while (!stream.look().eof) {
350
+ if (stream.look() == "\\") {
351
+ if (stream.look(1).isNewline()) {
352
+ do {
353
+ stream.next();
354
+ } while (!stream.look().eof && stream.look().isNewline());
355
+ string += "\\\n";
356
+ }
357
+ else {
358
+ string += stream.next(2);
359
+ }
360
+ }
361
+ else if (stream.look() == "\"") {
362
+ string += stream.next();
363
+ tokens.push(new Token(string, "STRN", "DOUBLE_QUOTE"));
364
+ return true;
365
+ }
366
+ else {
367
+ string += stream.next();
368
+ }
369
+ }
370
+ }
371
+ return false; // error! unterminated string
372
+ }
373
+ TokenReader.prototype.read_snquote = function(stream, tokens) {
374
+ if (stream.look() == "'") {
375
+ // find terminator
376
+ var string = stream.next();
377
+
378
+ while (!stream.look().eof) {
379
+ if (stream.look() == "\\") { // escape sequence
380
+ string += stream.next(2);
381
+ }
382
+ else if (stream.look() == "'") {
383
+ string += stream.next();
384
+ tokens.push(new Token(string, "STRN", "SINGLE_QUOTE"));
385
+ return true;
386
+ }
387
+ else {
388
+ string += stream.next();
389
+ }
390
+ }
391
+ }
392
+ return false; // error! unterminated string
393
+ }
394
+ TokenReader.prototype.read_numb = function(stream, tokens) {
395
+ if (stream.look() === "0" && stream.look(1) == "x") {
396
+ return this.read_hex(stream, tokens);
397
+ }
398
+
399
+ var found = "";
400
+
401
+ while (!stream.look().eof && TOKN.NUMB.test(found+stream.look())){
402
+ found += stream.next();
403
+ }
404
+
405
+ if (found === "") {
406
+ return false;
407
+ }
408
+ else {
409
+ if (/^0[0-7]/.test(found)) tokens.push(new Token(found, "NUMB", "OCTAL"));
410
+ else tokens.push(new Token(found, "NUMB", "DECIMAL"));
411
+ return true;
412
+ }
413
+ }
414
+ TokenReader.prototype.read_hex = function(stream, tokens) {
415
+ var found = stream.next(2);
416
+
417
+ while (!stream.look().eof) {
418
+ if (TOKN.HEX_DEC.test(found) && !TOKN.HEX_DEC.test(found+stream.look())) { // done
419
+ tokens.push(new Token(found, "NUMB", "HEX_DEC"));
420
+ return true;
421
+ }
422
+ else {
423
+ found += stream.next();
424
+ }
425
+ }
426
+ return false;
427
+ }
428
+ TokenReader.prototype.read_regx = function(stream, tokens) {
429
+ if (
430
+ stream.look() == "/"
431
+ &&
432
+ (
433
+ !tokens.last()
434
+ ||
435
+ (
436
+ !tokens.last().is("NUMB")
437
+ && !tokens.last().is("NAME")
438
+ && !tokens.last().is("RIGHT_PAREN")
439
+ && !tokens.last().is("RIGHT_BRACKET")
440
+ )
441
+ )
442
+ ) {
443
+ var regex = stream.next();
444
+
445
+ while (!stream.look().eof) {
446
+ if (stream.look() == "\\") { // escape sequence
447
+ regex += stream.next(2);
448
+ }
449
+ else if (stream.look() == "/") {
450
+ regex += stream.next();
451
+
452
+ while (/[gmi]/.test(stream.look())) {
453
+ regex += stream.next();
454
+ }
455
+
456
+ tokens.push(new Token(regex, "REGX", "REGX"));
457
+ return true;
458
+ }
459
+ else {
460
+ regex += stream.next();
461
+ }
462
+ }
463
+ // error: unterminated regex
464
+ }
465
+ return false;
466
+ }
467
+
468
+ /**
469
+ * @class Like a array that you can easily move forward and backward through.
470
+ * @constructor
471
+ * @param {List} array The list of tokens to use.
472
+ */
473
+ function TokenStream(tokens) {
474
+ this.tokens = (tokens || []);
475
+ this.cursor = -1;
476
+ }
477
+
478
+ /**
479
+ * Return the token n places away from the current position.
480
+ * @param {integer} n Positive or negative (defaults to zero), where to look relative to the current cursor position.
481
+ * @param {boolean} considerWhitespace If whitespace is in the tokenStream they will normally be ignored here, but set this to true if you want to consider whitespace.
482
+ */
483
+ TokenStream.prototype.look = function(n, considerWhitespace) {
484
+ if (typeof n == "undefined") n = 0;
485
+
486
+ if (considerWhitespace == true) {
487
+ if (this.cursor+n < 0 || this.cursor+n > this.tokens.length) return {};
488
+ return this.tokens[this.cursor+n];
489
+ }
490
+ else {
491
+ var count = 0;
492
+ var i = this.cursor;
493
+ var voidToken = {is: function(){return false;}}
494
+ while (true) {
495
+ if (i < 0 || i > this.tokens.length) return voidToken;
496
+ if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("SPACE") || this.tokens[i].is("NEWLINE"))) {
497
+ if (n < 0) i--; else i++;
498
+ continue;
499
+ }
500
+
501
+ if (count == Math.abs(n)) {
502
+ return this.tokens[i];
503
+ }
504
+ count++;
505
+ (n < 0)? i-- : i++;
506
+ }
507
+ return voidToken; // because null isn't an object and caller always expects an object
508
+ }
509
+ };
510
+
511
+ /**
512
+ * Get the next n tokens from the stream relative to the current cursor position, and advance the cursor to the new position.
513
+ * @param {integer} howMany Positive (defaults to one), how many tokens to return.
514
+ */
515
+ TokenStream.prototype.next = function(howMany) {
516
+ if (typeof howMany == "undefined") howMany = 1;
517
+ if (howMany < 1) return null;
518
+ var got = [];
519
+
520
+ for (var i = 1; i <= howMany; i++) {
521
+ if (this.cursor+i >= this.tokens.length) {
522
+ return null;
523
+ }
524
+ got.push(this.tokens[this.cursor+i]);
525
+ }
526
+ this.cursor += howMany;
527
+
528
+ if (howMany == 1) {
529
+ return got[0];
530
+ }
531
+ else return got;
532
+ };
533
+
534
+ /**
535
+ * Get all the tokens between a starting token and the stop token. The stop token will be found considering its balance with
536
+ * the start token. That is, it must be the one that closes the start token, not necessarily the first stop token.
537
+ * @param {TOKN} start The token to start collecting on, must be present somewhere in the stream ahead of the cursor.
538
+ * @param {TOKN} [stop] The token to stop collecting on, must be present somewhere in the stream ahead of the cursor and after the start token.
539
+ * If this is not given, the matching token to start will be used if it exists. Like ( and ) or { and }.
540
+ */
541
+ TokenStream.prototype.balance = function(start, stop) {
542
+ if (!stop) stop = TOKN.MATCHING[start];
543
+
544
+ var depth = 0;
545
+ var got = [];
546
+ var started = false;
547
+
548
+ while ((token = this.look())) {
549
+ if (token.is(start)) {
550
+ depth++;
551
+ started = true;
552
+ }
553
+
554
+ if (started) {
555
+ got.push(token);
556
+ }
557
+
558
+ if (token.is(stop)) {
559
+ depth--;
560
+ if (depth == 0) return got;
561
+ }
562
+ if (!this.next()) break;
563
+ }
564
+ };