sproutcore 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +269 -0
- data/README.txt +67 -0
- data/Rakefile +4 -0
- data/app_generators/sproutcore/USAGE +5 -0
- data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
- data/app_generators/sproutcore/templates/README +77 -0
- data/app_generators/sproutcore/templates/environment.yml +4 -0
- data/bin/sc-build +145 -0
- data/bin/sc-gen +24 -0
- data/bin/sc-server +63 -0
- data/bin/sproutcore +21 -0
- data/clients/sc_docs/controllers/docs.js +118 -0
- data/clients/sc_docs/core.js +19 -0
- data/clients/sc_docs/english.lproj/body.css +159 -0
- data/clients/sc_docs/english.lproj/body.rhtml +33 -0
- data/clients/sc_docs/english.lproj/controls.css +0 -0
- data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
- data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
- data/clients/sc_docs/english.lproj/strings.js +14 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
- data/clients/sc_docs/fixtures/doc.js +11 -0
- data/clients/sc_docs/main.js +21 -0
- data/clients/sc_docs/models/doc.js +9 -0
- data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
- data/clients/sc_docs/tests/models/doc.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
- data/clients/sc_docs/views/doc_frame.js +33 -0
- data/clients/sc_docs/views/doc_label.js +20 -0
- data/clients/sc_test_runner/controllers/runner.js +175 -0
- data/clients/sc_test_runner/core.js +19 -0
- data/clients/sc_test_runner/english.lproj/body.css +151 -0
- data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
- data/clients/sc_test_runner/english.lproj/controls.css +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
- data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
- data/clients/sc_test_runner/english.lproj/strings.js +14 -0
- data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
- data/clients/sc_test_runner/fixtures/test.js +12 -0
- data/clients/sc_test_runner/main.js +26 -0
- data/clients/sc_test_runner/models/test.js +11 -0
- data/clients/sc_test_runner/views/runner_frame.js +72 -0
- data/clients/sc_test_runner/views/test_label.js +20 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/environment.yml +9 -0
- data/frameworks/prototype/prototype.js +4186 -0
- data/frameworks/sproutcore/Core.js +378 -0
- data/frameworks/sproutcore/README +3 -0
- data/frameworks/sproutcore/controllers/array.js +236 -0
- data/frameworks/sproutcore/controllers/collection.js +305 -0
- data/frameworks/sproutcore/controllers/controller.js +323 -0
- data/frameworks/sproutcore/controllers/object.js +372 -0
- data/frameworks/sproutcore/drag/drag.js +549 -0
- data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
- data/frameworks/sproutcore/drag/drag_source.js +64 -0
- data/frameworks/sproutcore/drag/drop_target.js +153 -0
- data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
- data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
- data/frameworks/sproutcore/english.lproj/menu.css +121 -0
- data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panes.css +155 -0
- data/frameworks/sproutcore/english.lproj/picker.css +22 -0
- data/frameworks/sproutcore/english.lproj/strings.js +15 -0
- data/frameworks/sproutcore/english.lproj/tab.css +23 -0
- data/frameworks/sproutcore/english.lproj/tests.css +67 -0
- data/frameworks/sproutcore/english.lproj/theme.css +77 -0
- data/frameworks/sproutcore/foundation/animator.js +670 -0
- data/frameworks/sproutcore/foundation/application.js +199 -0
- data/frameworks/sproutcore/foundation/array.js +348 -0
- data/frameworks/sproutcore/foundation/benchmark.js +211 -0
- data/frameworks/sproutcore/foundation/binding.js +384 -0
- data/frameworks/sproutcore/foundation/date.js +357 -0
- data/frameworks/sproutcore/foundation/error.js +39 -0
- data/frameworks/sproutcore/foundation/input_manager.js +153 -0
- data/frameworks/sproutcore/foundation/json.js +296 -0
- data/frameworks/sproutcore/foundation/mock.js +42 -0
- data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
- data/frameworks/sproutcore/foundation/object.js +777 -0
- data/frameworks/sproutcore/foundation/observable.js +451 -0
- data/frameworks/sproutcore/foundation/page.js +63 -0
- data/frameworks/sproutcore/foundation/path_module.js +413 -0
- data/frameworks/sproutcore/foundation/responder.js +310 -0
- data/frameworks/sproutcore/foundation/routes.js +371 -0
- data/frameworks/sproutcore/foundation/run_loop.js +21 -0
- data/frameworks/sproutcore/foundation/server.js +491 -0
- data/frameworks/sproutcore/foundation/set.js +96 -0
- data/frameworks/sproutcore/foundation/string.js +149 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
- data/frameworks/sproutcore/foundation/unittest.js +622 -0
- data/frameworks/sproutcore/foundation/utils.js +61 -0
- data/frameworks/sproutcore/globals/panels.js +182 -0
- data/frameworks/sproutcore/globals/popups.js +60 -0
- data/frameworks/sproutcore/globals/window.js +381 -0
- data/frameworks/sproutcore/lib/index.rhtml +66 -0
- data/frameworks/sproutcore/models/collection.js +395 -0
- data/frameworks/sproutcore/models/record.js +622 -0
- data/frameworks/sproutcore/models/store.js +295 -0
- data/frameworks/sproutcore/panes/dialog.js +16 -0
- data/frameworks/sproutcore/panes/manager.js +164 -0
- data/frameworks/sproutcore/panes/menu.js +45 -0
- data/frameworks/sproutcore/panes/overlay.js +231 -0
- data/frameworks/sproutcore/panes/pane.js +90 -0
- data/frameworks/sproutcore/panes/panel.js +19 -0
- data/frameworks/sproutcore/panes/picker.js +45 -0
- data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
- data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
- data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
- data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
- data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
- data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
- data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
- data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
- data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
- data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
- data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
- data/frameworks/sproutcore/validators/credit_card.js +92 -0
- data/frameworks/sproutcore/validators/date.js +36 -0
- data/frameworks/sproutcore/validators/email.js +29 -0
- data/frameworks/sproutcore/validators/not_empty.js +24 -0
- data/frameworks/sproutcore/validators/number.js +55 -0
- data/frameworks/sproutcore/validators/password.js +78 -0
- data/frameworks/sproutcore/validators/validator.js +304 -0
- data/frameworks/sproutcore/views/button.js +425 -0
- data/frameworks/sproutcore/views/checkbox_field.js +30 -0
- data/frameworks/sproutcore/views/collection.js +1521 -0
- data/frameworks/sproutcore/views/container.js +62 -0
- data/frameworks/sproutcore/views/error_explanation.js +45 -0
- data/frameworks/sproutcore/views/field.js +214 -0
- data/frameworks/sproutcore/views/filter_button.js +29 -0
- data/frameworks/sproutcore/views/form.js +591 -0
- data/frameworks/sproutcore/views/image.js +141 -0
- data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
- data/frameworks/sproutcore/views/label.js +176 -0
- data/frameworks/sproutcore/views/menu_item.js +90 -0
- data/frameworks/sproutcore/views/pagination.js +54 -0
- data/frameworks/sproutcore/views/popup_button.js +86 -0
- data/frameworks/sproutcore/views/popup_menu.js +137 -0
- data/frameworks/sproutcore/views/progress.js +100 -0
- data/frameworks/sproutcore/views/radio_field.js +107 -0
- data/frameworks/sproutcore/views/radio_group.js +48 -0
- data/frameworks/sproutcore/views/segmented.js +80 -0
- data/frameworks/sproutcore/views/select_field.js +272 -0
- data/frameworks/sproutcore/views/spinner.js +11 -0
- data/frameworks/sproutcore/views/tab.js +126 -0
- data/frameworks/sproutcore/views/text_field.js +179 -0
- data/frameworks/sproutcore/views/textarea_field.js +14 -0
- data/frameworks/sproutcore/views/toolbar.js +29 -0
- data/frameworks/sproutcore/views/view.js +1389 -0
- data/frameworks/sproutcore/views/workspace.js +170 -0
- data/generators/client/README +3 -0
- data/generators/client/USAGE +12 -0
- data/generators/client/client_generator.rb +53 -0
- data/generators/client/templates/core.js +19 -0
- data/generators/client/templates/english.lproj/body.css +0 -0
- data/generators/client/templates/english.lproj/body.rhtml +3 -0
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/client/templates/english.lproj/strings.js +14 -0
- data/generators/client/templates/main.js +37 -0
- data/generators/controller/USAGE +16 -0
- data/generators/controller/controller_generator.rb +51 -0
- data/generators/controller/templates/controller.js +21 -0
- data/generators/controller/templates/test.rhtml +21 -0
- data/generators/framework/README +7 -0
- data/generators/framework/USAGE +12 -0
- data/generators/framework/framework_generator.rb +53 -0
- data/generators/framework/templates/core.js +20 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +3 -0
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/strings.js +14 -0
- data/generators/language/USAGE +16 -0
- data/generators/language/language_generator.rb +47 -0
- data/generators/language/templates/strings.js +10 -0
- data/generators/model/USAGE +24 -0
- data/generators/model/model_generator.rb +55 -0
- data/generators/model/templates/fixture.js +11 -0
- data/generators/model/templates/model.js +20 -0
- data/generators/model/templates/test.rhtml +21 -0
- data/generators/test/USAGE +16 -0
- data/generators/test/templates/test.rhtml +21 -0
- data/generators/test/test_generator.rb +47 -0
- data/generators/view/USAGE +16 -0
- data/generators/view/templates/test.rhtml +21 -0
- data/generators/view/templates/view.js +20 -0
- data/generators/view/view_generator.rb +51 -0
- data/jsdoc/README.txt +119 -0
- data/jsdoc/app/DocFile.js +137 -0
- data/jsdoc/app/DocTag.js +110 -0
- data/jsdoc/app/Doclet.js +63 -0
- data/jsdoc/app/Dumper.js +143 -0
- data/jsdoc/app/JsDoc.js +103 -0
- data/jsdoc/app/JsHilite.js +45 -0
- data/jsdoc/app/JsIO.js +163 -0
- data/jsdoc/app/JsParse.js +385 -0
- data/jsdoc/app/JsPlate.js +130 -0
- data/jsdoc/app/JsTestrun.js +129 -0
- data/jsdoc/app/JsToke.js +564 -0
- data/jsdoc/app/Symbol.js +298 -0
- data/jsdoc/app/Transformer.js +14 -0
- data/jsdoc/app/Util.js +97 -0
- data/jsdoc/app/js.jar +0 -0
- data/jsdoc/app/run.js +144 -0
- data/jsdoc/plugins/min.js +316 -0
- data/jsdoc/plugins/strip.js +20 -0
- data/jsdoc/templates/sproutcore/class.tmpl +438 -0
- data/jsdoc/templates/sproutcore/default.css +241 -0
- data/jsdoc/templates/sproutcore/index.html +13 -0
- data/jsdoc/templates/sproutcore/index.tmpl +21 -0
- data/jsdoc/templates/sproutcore/prototype.js +4186 -0
- data/jsdoc/templates/sproutcore/publish.js +236 -0
- data/jsdoc/templates/sproutcore/splash.html +7 -0
- data/lib/sproutcore/build_tools/html_builder.rb +88 -0
- data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
- data/lib/sproutcore/build_tools.rb +44 -0
- data/lib/sproutcore/bundle.rb +517 -0
- data/lib/sproutcore/bundle_manifest.rb +397 -0
- data/lib/sproutcore/generator_helper.rb +170 -0
- data/lib/sproutcore/helpers/capture_helper.rb +42 -0
- data/lib/sproutcore/helpers/static_helper.rb +80 -0
- data/lib/sproutcore/helpers/tag_helper.rb +110 -0
- data/lib/sproutcore/helpers/text_helper.rb +336 -0
- data/lib/sproutcore/helpers.rb +3 -0
- data/lib/sproutcore/jsdoc.rb +40 -0
- data/lib/sproutcore/jsmin.rb +247 -0
- data/lib/sproutcore/library.rb +258 -0
- data/lib/sproutcore/merb/bundle_controller.rb +179 -0
- data/lib/sproutcore/merb/router.rb +43 -0
- data/lib/sproutcore/merb.rb +27 -0
- data/lib/sproutcore/version.rb +9 -0
- data/lib/sproutcore/view_helpers/button_views.rb +302 -0
- data/lib/sproutcore/view_helpers/core_views.rb +284 -0
- data/lib/sproutcore/view_helpers/form_views.rb +258 -0
- data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
- data/lib/sproutcore/view_helpers.rb +628 -0
- data/lib/sproutcore.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/sproutcore_spec.rb +11 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +365 -0
data/jsdoc/app/JsToke.js
ADDED
|
@@ -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
|
+
};
|