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
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# This version of jsmin has been adapted for use in a module.
|
|
2
|
+
|
|
3
|
+
# jsmin.rb 2007-07-20
|
|
4
|
+
# Author: Uladzislau Latynski
|
|
5
|
+
# This work is a translation from C to Ruby of jsmin.c published by
|
|
6
|
+
# Douglas Crockford. Permission is hereby granted to use the Ruby
|
|
7
|
+
# version under the same conditions as the jsmin.c on which it is
|
|
8
|
+
# based.
|
|
9
|
+
#
|
|
10
|
+
# /* jsmin.c
|
|
11
|
+
# 2003-04-21
|
|
12
|
+
#
|
|
13
|
+
# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
|
14
|
+
#
|
|
15
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
16
|
+
# this software and associated documentation files (the "Software"), to deal in
|
|
17
|
+
# the Software without restriction, including without limitation the rights to
|
|
18
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
19
|
+
# of the Software, and to permit persons to whom the Software is furnished to do
|
|
20
|
+
# so, subject to the following conditions:
|
|
21
|
+
#
|
|
22
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
# copies or substantial portions of the Software.
|
|
24
|
+
#
|
|
25
|
+
# The Software shall be used for Good, not Evil.
|
|
26
|
+
#
|
|
27
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
28
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
29
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
30
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
31
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
32
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
33
|
+
# SOFTWARE.
|
|
34
|
+
|
|
35
|
+
module SproutCore
|
|
36
|
+
|
|
37
|
+
class JSMin
|
|
38
|
+
EOF = -1
|
|
39
|
+
|
|
40
|
+
# this will minify a single line
|
|
41
|
+
def self.run(str)
|
|
42
|
+
minifier = SproutCore::JSMin.new(str)
|
|
43
|
+
minifier.jsmin
|
|
44
|
+
minifier.stdout
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def initialize(str)
|
|
48
|
+
@theA = ""
|
|
49
|
+
@theB = ""
|
|
50
|
+
@str = str || ''
|
|
51
|
+
@loc = 0
|
|
52
|
+
@stdout = ''
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def stdin_getc
|
|
56
|
+
ret = @str.nil? || (@loc >= @str.size) ? nil : @str[@loc]
|
|
57
|
+
@loc += 1
|
|
58
|
+
return ret
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def stdin_ungetc(str)
|
|
62
|
+
@loc -= 1
|
|
63
|
+
@loc = 0 if @loc < 0
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def stdout_write(chr)
|
|
67
|
+
@stdout << chr
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def stdout
|
|
71
|
+
return @stdout
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#### JSMIN
|
|
75
|
+
## To update, replace the text below with the latest jsmin.rb. Then replace:
|
|
76
|
+
## $theA => @theA, $theB => @theB,
|
|
77
|
+
## $stdin.getc => stdin_getc, $stdin.ungetc => stding_ungetc,
|
|
78
|
+
## $stdout.write => stdout_write
|
|
79
|
+
|
|
80
|
+
# isAlphanum -- return true if the character is a letter, digit,
|
|
81
|
+
# underscore, dollar sign, or non-ASCII character
|
|
82
|
+
def isAlphanum(c)
|
|
83
|
+
return false if !c || c == EOF
|
|
84
|
+
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
|
|
85
|
+
(c >= 'A' && c <= 'Z') || c == '_' || c == '$' ||
|
|
86
|
+
c == '\\' || c[0] > 126)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# get -- return the next character from stdin. Watch out for lookahead.
|
|
90
|
+
# If the character is a control character, translate it to a space or
|
|
91
|
+
# linefeed.
|
|
92
|
+
def get()
|
|
93
|
+
c = stdin_getc
|
|
94
|
+
return EOF if(!c)
|
|
95
|
+
c = c.chr
|
|
96
|
+
return c if (c >= " " || c == "\n" || c.unpack("c") == EOF)
|
|
97
|
+
return "\n" if (c == "\r")
|
|
98
|
+
return " "
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Get the next character without getting it.
|
|
102
|
+
def peek()
|
|
103
|
+
lookaheadChar = stdin_getc
|
|
104
|
+
stdin_ungetc(lookaheadChar)
|
|
105
|
+
return lookaheadChar.chr
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# mynext -- get the next character, excluding comments.
|
|
109
|
+
# peek() is used to see if a '/' is followed by a '/' or '*'.
|
|
110
|
+
def mynext()
|
|
111
|
+
c = get
|
|
112
|
+
if (c == "/")
|
|
113
|
+
if(peek == "/")
|
|
114
|
+
while(true)
|
|
115
|
+
c = get
|
|
116
|
+
if (c <= "\n")
|
|
117
|
+
return c
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
if(peek == "*")
|
|
122
|
+
get
|
|
123
|
+
while(true)
|
|
124
|
+
case get
|
|
125
|
+
when "*"
|
|
126
|
+
if (peek == "/")
|
|
127
|
+
get
|
|
128
|
+
return " "
|
|
129
|
+
end
|
|
130
|
+
when EOF
|
|
131
|
+
raise "Unterminated comment"
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
return c
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# action -- do something! What you do is determined by the argument: 1
|
|
141
|
+
# Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B.
|
|
142
|
+
# (Delete A). 3 Get the next B. (Delete B). action treats a string as a
|
|
143
|
+
# single character. Wow! action recognizes a regular expression if it is
|
|
144
|
+
# preceded by ( or , or =.
|
|
145
|
+
def action(a)
|
|
146
|
+
if(a==1)
|
|
147
|
+
stdout_write @theA
|
|
148
|
+
end
|
|
149
|
+
if(a==1 || a==2)
|
|
150
|
+
@theA = @theB
|
|
151
|
+
if (@theA == "\'" || @theA == "\"")
|
|
152
|
+
while (true)
|
|
153
|
+
stdout_write @theA
|
|
154
|
+
@theA = get
|
|
155
|
+
break if (@theA == @theB)
|
|
156
|
+
raise "Unterminated string literal" if (@theA <= "\n")
|
|
157
|
+
if (@theA == "\\")
|
|
158
|
+
stdout_write @theA
|
|
159
|
+
@theA = get
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
if(a==1 || a==2 || a==3)
|
|
165
|
+
@theB = mynext
|
|
166
|
+
if (@theB == "/" && (@theA == "(" || @theA == "," || @theA == "=" ||
|
|
167
|
+
@theA == ":" || @theA == "[" || @theA == "!" ||
|
|
168
|
+
@theA == "&" || @theA == "|" || @theA == "?" ||
|
|
169
|
+
@theA == "{" || @theA == "}" || @theA == ";" ||
|
|
170
|
+
@theA == "\n"))
|
|
171
|
+
stdout_write @theA
|
|
172
|
+
stdout_write @theB
|
|
173
|
+
while (true)
|
|
174
|
+
@theA = get
|
|
175
|
+
if (@theA == "/")
|
|
176
|
+
break
|
|
177
|
+
elsif (@theA == "\\")
|
|
178
|
+
stdout_write @theA
|
|
179
|
+
@theA = get
|
|
180
|
+
elsif (@theA <= "\n")
|
|
181
|
+
raise "Unterminated RegExp Literal"
|
|
182
|
+
end
|
|
183
|
+
stdout_write @theA
|
|
184
|
+
end
|
|
185
|
+
@theB = mynext
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# jsmin -- Copy the input to the output, deleting the characters which are
|
|
191
|
+
# insignificant to JavaScript. Comments will be removed. Tabs will be
|
|
192
|
+
# replaced with spaces. Carriage returns will be replaced with linefeeds.
|
|
193
|
+
# Most spaces and linefeeds will be removed.
|
|
194
|
+
def jsmin
|
|
195
|
+
@theA = "\n"
|
|
196
|
+
action(3)
|
|
197
|
+
while (@theA != EOF)
|
|
198
|
+
case @theA
|
|
199
|
+
when " "
|
|
200
|
+
if (isAlphanum(@theB))
|
|
201
|
+
action(1)
|
|
202
|
+
else
|
|
203
|
+
action(2)
|
|
204
|
+
end
|
|
205
|
+
when "\n"
|
|
206
|
+
case (@theB)
|
|
207
|
+
when "{","[","(","+","-"
|
|
208
|
+
action(1)
|
|
209
|
+
when " "
|
|
210
|
+
action(3)
|
|
211
|
+
else
|
|
212
|
+
if (isAlphanum(@theB))
|
|
213
|
+
action(1)
|
|
214
|
+
else
|
|
215
|
+
action(2)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
else
|
|
219
|
+
case (@theB)
|
|
220
|
+
when " "
|
|
221
|
+
if (isAlphanum(@theA))
|
|
222
|
+
action(1)
|
|
223
|
+
else
|
|
224
|
+
action(3)
|
|
225
|
+
end
|
|
226
|
+
when "\n"
|
|
227
|
+
case (@theA)
|
|
228
|
+
when "}","]",")","+","-","\"","\\", "'", '"'
|
|
229
|
+
action(1)
|
|
230
|
+
else
|
|
231
|
+
if (isAlphanum(@theA))
|
|
232
|
+
action(1)
|
|
233
|
+
else
|
|
234
|
+
action(3)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
else
|
|
238
|
+
action(1)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
################ END JSMIN
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
end
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module SproutCore
|
|
4
|
+
|
|
5
|
+
# Describes a single library that can contain one or more clients and frameworks.
|
|
6
|
+
# This class is used to automatically locate all installed libraries and to register the
|
|
7
|
+
# clients within them.
|
|
8
|
+
#
|
|
9
|
+
# Libraries are chained, with the child library replacing the parent library's settings.
|
|
10
|
+
# In general, the root library is always the current app while its parent libraries are
|
|
11
|
+
# those found in the load path or explicitly stated in the configs.
|
|
12
|
+
class Library
|
|
13
|
+
|
|
14
|
+
# Creates a chained set of libraries from the passed location and the load path
|
|
15
|
+
def self.library_for(root_path, opts = {})
|
|
16
|
+
|
|
17
|
+
# Find libraries in the search paths, build chain
|
|
18
|
+
root_path = File.expand_path(root_path)
|
|
19
|
+
paths = libraries_in($:).reject { |x| x == root_path }
|
|
20
|
+
paths.unshift(root_path)
|
|
21
|
+
ret = nil
|
|
22
|
+
|
|
23
|
+
# Convert chain to library objects. The last path processed should be
|
|
24
|
+
# the one passed in to this method.
|
|
25
|
+
while path = paths.pop
|
|
26
|
+
ret = self.new(path, opts, ret)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Return library object for root_path
|
|
30
|
+
return ret
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Searches the array of paths, returning the array of paths that are actually libraries.
|
|
34
|
+
#
|
|
35
|
+
# ==== Params
|
|
36
|
+
# paths<Array>:: Array of libraries.
|
|
37
|
+
#
|
|
38
|
+
def self.libraries_in(paths)
|
|
39
|
+
ret = paths.map do |p|
|
|
40
|
+
p = File.expand_path(p) # expand
|
|
41
|
+
[p, p.gsub(/\/lib$/,'')].reject { |x| !is_library?(x) }
|
|
42
|
+
end
|
|
43
|
+
ret.flatten.compact.uniq
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Heuristically determine if a particular location is a library.
|
|
47
|
+
def self.is_library?(path)
|
|
48
|
+
has_it = %w(clients frameworks environment.yml).map do |x|
|
|
49
|
+
File.exists?(File.join(path, x))
|
|
50
|
+
end
|
|
51
|
+
return false unless has_it.pop
|
|
52
|
+
has_it.each { |x| return true if x }
|
|
53
|
+
return false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The root path for this library
|
|
57
|
+
attr_reader :root_path
|
|
58
|
+
|
|
59
|
+
# The raw environment hash loaded from disk. Generally use computed_environment,
|
|
60
|
+
# which combines the parent.
|
|
61
|
+
attr_reader :environment
|
|
62
|
+
|
|
63
|
+
# The parent library, used for load order dependency
|
|
64
|
+
attr_accessor :next_library
|
|
65
|
+
|
|
66
|
+
# The client directories found in this library. This usually maps directly to a
|
|
67
|
+
# client name but it may not if you have set up some other options.
|
|
68
|
+
def client_directories
|
|
69
|
+
return @client_dirs unless @client_dirs.nil?
|
|
70
|
+
client_path = File.join(@root_path, 'clients')
|
|
71
|
+
if File.exists?(client_path)
|
|
72
|
+
@client_dirs = Dir.entries(client_path).reject do |x|
|
|
73
|
+
(/^\./ =~ x) || !File.directory?(File.join(client_path,x))
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
@client_dirs = []
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
return @client_dirs
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The framework directories found in this library
|
|
83
|
+
def framework_directories
|
|
84
|
+
return @framework_dirs unless @framework_dirs.nil?
|
|
85
|
+
framework_path = File.join(@root_path, 'frameworks')
|
|
86
|
+
if File.exists?(framework_path)
|
|
87
|
+
@framework_dirs = Dir.entries(framework_path).reject do |x|
|
|
88
|
+
(/^\./ =~ x) || !File.directory?(File.join(framework_path,x))
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
@framework_dirs = []
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return @framework_dirs
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Returns all of the client names known to the current environment, including
|
|
98
|
+
# through parent libraries.
|
|
99
|
+
def client_names
|
|
100
|
+
return @cache_client_names unless @cache_client_names.nil?
|
|
101
|
+
|
|
102
|
+
ret = next_library.nil? ? [] : next_library.client_directories
|
|
103
|
+
ret += client_directories
|
|
104
|
+
return @cache_client_names = ret.compact.uniq.sort
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Returns all of the framework names known to the current environment, including
|
|
108
|
+
# through parent libraries.
|
|
109
|
+
def framework_names
|
|
110
|
+
return @cache_framework_names unless @cache_framework_names.nil?
|
|
111
|
+
|
|
112
|
+
ret = next_library.nil? ? [] : next_library.framework_directories
|
|
113
|
+
ret += framework_directories
|
|
114
|
+
return @cache_framework_names = ret.compact.uniq.sort
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# ==== Returns
|
|
118
|
+
# A hash of all bundle names mapped to root url. This method is optimized for frequent
|
|
119
|
+
# requests so you can use it to route incoming requests.
|
|
120
|
+
def bundles_grouped_by_url
|
|
121
|
+
return @cached_bundles_by_url unless @cached_bundles_by_url.nil?
|
|
122
|
+
ret = {}
|
|
123
|
+
bundles.each { |b| ret[b.url_root] = b; ret[b.index_root] = b }
|
|
124
|
+
return @cached_bundles_by_url = ret
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# ==== Returns
|
|
128
|
+
# A bundle for the specified name. If the bundle has not already been created, then
|
|
129
|
+
# it will be created.
|
|
130
|
+
def bundle_for(bundle_name)
|
|
131
|
+
bundle_name = bundle_name.to_sym
|
|
132
|
+
@bundles ||= {}
|
|
133
|
+
return @bundles[bundle_name] ||= Bundle.new(bundle_name, environment_for(bundle_name))
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# ==== Returns
|
|
137
|
+
# All of the bundles for registered clients
|
|
138
|
+
def client_bundles
|
|
139
|
+
@cached_client_bundles ||= client_names.map { |x| bundle_for(x) }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# ==== Returns
|
|
143
|
+
# All of the bundles for registered frameworks
|
|
144
|
+
def framework_bundles
|
|
145
|
+
@cached_framework_bundles ||= framework_names.map { |x| bundle_for(x) }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# ==== Returns
|
|
149
|
+
# All known bundles, both framework & client
|
|
150
|
+
def bundles
|
|
151
|
+
@cached_all_bundles ||= (client_bundles + framework_bundles)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Build all of the bundles in the library. This can take awhile but it is the simple
|
|
155
|
+
# way to get all of your code onto disk in a deployable state
|
|
156
|
+
def build(*languages)
|
|
157
|
+
(client_bundles + framework_bundles).each do |bundle|
|
|
158
|
+
puts "building: #{bundle.bundle_name}"
|
|
159
|
+
bundle.build(*languages)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Returns the computed environment for a particular client or framework.
|
|
164
|
+
# This will go up the chain of parent libraries, retrieving and merging any known
|
|
165
|
+
# environment settings. The returned options are suitable for passing to the ClientBuilder
|
|
166
|
+
# for registration.
|
|
167
|
+
def environment_for(bundle_name)
|
|
168
|
+
|
|
169
|
+
is_local_client = client_directories.include?(bundle_name.to_s)
|
|
170
|
+
is_local_framework = framework_directories.include?(bundle_name.to_s)
|
|
171
|
+
ret = nil
|
|
172
|
+
|
|
173
|
+
# CASE 1: If named client or framework is local, then use our local settings
|
|
174
|
+
if (is_local_client || is_local_framework)
|
|
175
|
+
|
|
176
|
+
# start with local environment
|
|
177
|
+
ret = (environment[:all] || {}).dup
|
|
178
|
+
|
|
179
|
+
# Now fill in some default values based on what we know
|
|
180
|
+
# This should be enough to make the bundle load
|
|
181
|
+
ret[:bundle_name] = bundle_name.to_sym
|
|
182
|
+
ret[:bundle_type] = is_local_framework ? :framework : :client
|
|
183
|
+
ret[:requires] = [:prototype, :sproutcore] if ret[:requires].nil?
|
|
184
|
+
|
|
185
|
+
# Fill in the source_root since we know where this came from
|
|
186
|
+
ret[:source_root] = File.join(root_path, ret[:bundle_type].to_s.pluralize, bundle_name.to_s)
|
|
187
|
+
|
|
188
|
+
# CASE 2: Otherwise, if we have a next library, see if the next library has something
|
|
189
|
+
else
|
|
190
|
+
ret = next_library.nil? ? nil : next_library.environment_for(bundle_name)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Final fixup
|
|
194
|
+
unless ret.nil?
|
|
195
|
+
# Always url_prefix & index_prefix are always used.
|
|
196
|
+
all = environment[:all] || {}
|
|
197
|
+
[:url_prefix, :all_prefix, :preferred_language].each do |key|
|
|
198
|
+
ret[key] = all[key] if all.include?(key)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Either way, if we have local settings for this specific client, they override whatever
|
|
202
|
+
# we cooked up just now.
|
|
203
|
+
local_settings = environment[bundle_name.to_sym]
|
|
204
|
+
ret = ret.merge(local_settings) unless local_settings.nil?
|
|
205
|
+
|
|
206
|
+
# Always replace the library with self so that we get the correct root location for
|
|
207
|
+
# public paths, etc.
|
|
208
|
+
ret[:library] = self
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# CASE 3: Next library doesn't know about this client. Neither do we. Even if the
|
|
213
|
+
# user has provided some environmental options, there is no source content, so just
|
|
214
|
+
# return nil
|
|
215
|
+
return ret
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
protected
|
|
219
|
+
|
|
220
|
+
# Load the library at the specified path. Loads the environment.yml if it exists
|
|
221
|
+
# and then detects all clients and frameworks in the library. If you pass any options,
|
|
222
|
+
# those will overlay any :all options you specify in your environment.yml file.
|
|
223
|
+
#
|
|
224
|
+
# You cannot create a library directly using this method. Instead is library_in()
|
|
225
|
+
#
|
|
226
|
+
def initialize(rp, opts = {}, next_lib = nil)
|
|
227
|
+
@root_path = rp
|
|
228
|
+
@next_library = next_lib
|
|
229
|
+
@load_opts = opts
|
|
230
|
+
load_environment!(opts)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Internal method loads the actual environment
|
|
234
|
+
def load_environment!(opts=nil)
|
|
235
|
+
env_path = File.join(root_path, 'environment.yml')
|
|
236
|
+
env = {}
|
|
237
|
+
if File.exists?(env_path)
|
|
238
|
+
f = File.open(env_path)
|
|
239
|
+
env = YAML::load(f) rescue nil
|
|
240
|
+
f.close
|
|
241
|
+
end
|
|
242
|
+
env = {} if env.nil?
|
|
243
|
+
|
|
244
|
+
# symbolize
|
|
245
|
+
@environment = {}
|
|
246
|
+
env.each do |k,v|
|
|
247
|
+
@environment[k.to_sym] = v.respond_to?(:symbolize_keys) ? v.symbolize_keys : v
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Overlay :all opts, if passed
|
|
251
|
+
@environment[:all] = (@environment[:all] || {}).merge(opts) unless opts.nil?
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
require 'sproutcore/jsdoc'
|
|
2
|
+
|
|
3
|
+
module SproutCore
|
|
4
|
+
module Merb
|
|
5
|
+
|
|
6
|
+
# A subclass of this controller handles all incoming requests for the location it is
|
|
7
|
+
# mounted at. For index.html requests, it will rebuild the html file everytime it is
|
|
8
|
+
# requested if you are in development mode. For all other requests, it will build the
|
|
9
|
+
# resource one time and then return the file if it already exists.
|
|
10
|
+
class BundleController < ::Merb::Controller
|
|
11
|
+
|
|
12
|
+
def self.library_for_class(klass)
|
|
13
|
+
(@registered_libraries ||= {})[klass]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.register_library_for_class(library, klass)
|
|
17
|
+
(@registered_libraries ||= {})[klass] = library
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Entry point for all requests routed through the SproutCore controller. Example
|
|
21
|
+
# the request path to determine which bundle should handle the request.
|
|
22
|
+
def main
|
|
23
|
+
|
|
24
|
+
# Before we do anything, set the build_mode for the bundles. This shouldn't change
|
|
25
|
+
# during execution, but if we set this during the router call, the Merb.environment
|
|
26
|
+
# is sometimes not ready yet.
|
|
27
|
+
if ::Merb.environment.to_sym == :production
|
|
28
|
+
Bundle.build_mode = :production
|
|
29
|
+
else
|
|
30
|
+
::SproutCore.logger.level = Logger::DEBUG
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Make sure we can service this with a bundle
|
|
34
|
+
raise(NotFound, "No SproutCore Bundle registered at this location.") if current_bundle.nil?
|
|
35
|
+
|
|
36
|
+
# Check for a few special urls that need to be rewritten
|
|
37
|
+
url = request.path
|
|
38
|
+
puts "BEFORE URL: #{url} current_bundle: #{current_bundle.bundle_name}"
|
|
39
|
+
if request.method == :get
|
|
40
|
+
url = rewrite_bundle_if(url, /^#{current_bundle.index_root}\/-tests/, :sc_test_runner)
|
|
41
|
+
url = rewrite_bundle_if(url, /^#{current_bundle.index_root}\/-docs/, :sc_docs)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# If we are in development mode, reload bundle first
|
|
45
|
+
current_bundle.reload! if current_bundle.build_mode == :development
|
|
46
|
+
|
|
47
|
+
puts "AFTER URL: #{url} current_bundle: #{current_bundle.bundle_name}"
|
|
48
|
+
|
|
49
|
+
# Get the normalized URL for the requested resource
|
|
50
|
+
url = current_bundle.normalize_url(url)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Check for a few special urls for built-in services and route them off
|
|
54
|
+
case url
|
|
55
|
+
when "#{current_bundle.url_root}/-tests/index.js"
|
|
56
|
+
ret = handle_test(url)
|
|
57
|
+
when "#{current_bundle.index_root}/-docs"
|
|
58
|
+
ret = (request.method == :post) ? handle_doc(url) : handle_resource(url)
|
|
59
|
+
|
|
60
|
+
when "#{current_bundle.url_root}/-docs"
|
|
61
|
+
ret = (request.method == :post) ? handle_doc(url) : handle_resource(url)
|
|
62
|
+
|
|
63
|
+
else
|
|
64
|
+
ret = handle_resource(url)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Done!
|
|
68
|
+
return ret
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Invoked whenever you request a regular resource
|
|
72
|
+
def handle_resource(url)
|
|
73
|
+
|
|
74
|
+
# Get the entry for the resource.
|
|
75
|
+
entry = current_bundle.entry_for_url(url, :hidden => :include)
|
|
76
|
+
raise(NotFound, "No matching entry in #{current_bundle.bundle_name}") if entry.nil?
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
build_path = entry.build_path
|
|
80
|
+
|
|
81
|
+
# Found an entry, build the resource. If the resource has already been built, this
|
|
82
|
+
# will not do much. If this the resource is an index.html file, force the build.
|
|
83
|
+
is_index = /\/index\.html$/ =~ url
|
|
84
|
+
puts "building: #{url} - is_index: #{is_index}"
|
|
85
|
+
|
|
86
|
+
current_bundle.build_entry(entry, :force => is_index, :hidden => :include)
|
|
87
|
+
|
|
88
|
+
# Move to final build path if necessary
|
|
89
|
+
if (build_path != entry.build_path) && File.exists?(entry.build_path)
|
|
90
|
+
FileUtils.mv(entry.build_path, build_path)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# And return the file. Set the content type using a mime-map borroed from Rack.
|
|
94
|
+
headers['Content-Type'] = entry.content_type
|
|
95
|
+
headers['Content-Length'] = File.size(build_path).to_s
|
|
96
|
+
ret = File.open(build_path)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# In development mode only, immediately delete built composite resources. We want
|
|
100
|
+
# each request to come directly to us.
|
|
101
|
+
if (current_bundle.build_mode == :development) && (!entry.cacheable?)
|
|
102
|
+
FileUtils.rm(build_path)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
return ret
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Returns JSON containing all of the tests
|
|
109
|
+
def handle_test(url)
|
|
110
|
+
test_entries = current_bundle.entries_for(:test, :hidden => :include)
|
|
111
|
+
content_type = :json
|
|
112
|
+
ret = test_entries.map do |entry|
|
|
113
|
+
{ :name => entry.filename.gsub(/^tests\//,''), :url => "#{entry.url}?#{entry.timestamp}" }
|
|
114
|
+
end
|
|
115
|
+
return ret.to_json
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# If you POST to this URL, regenerates the docs.
|
|
119
|
+
def handle_doc(url)
|
|
120
|
+
JSDoc.generate :bundle => current_bundle
|
|
121
|
+
return "OK"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
######################################################################
|
|
125
|
+
## Support Methods
|
|
126
|
+
##
|
|
127
|
+
|
|
128
|
+
# Returns the library for this class
|
|
129
|
+
def library
|
|
130
|
+
::SproutCore::Merb::BundleController.library_for_class(self.class)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# Returns the bundle for this request
|
|
135
|
+
def current_bundle
|
|
136
|
+
return @current_bundle unless @current_bundle.nil?
|
|
137
|
+
|
|
138
|
+
# Tear down the URL, looking for the first bundle
|
|
139
|
+
bundle_map = library.bundles_grouped_by_url
|
|
140
|
+
url = request.path.split('/')
|
|
141
|
+
ret = nil
|
|
142
|
+
while url.size > 0 && ret.nil?
|
|
143
|
+
ret = bundle_map[url.join('/')]
|
|
144
|
+
url.pop
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Try root path if nothing found
|
|
148
|
+
ret = bundle_map['/'] if ret.nil?
|
|
149
|
+
|
|
150
|
+
# Return
|
|
151
|
+
return (@current_bundle = ret)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# This method is used to redirect certain urls to an alternate bundle. If the
|
|
155
|
+
# match phrase matches the url, then both the url we use to fetch resources and the
|
|
156
|
+
# current_bundle will be swapped out.
|
|
157
|
+
#
|
|
158
|
+
# ===== Params
|
|
159
|
+
# url<String>:: The url to check
|
|
160
|
+
# match<Regex>:: The pattern to match and optionally later replace
|
|
161
|
+
# new_bundle_name<Symbol>:: The name of the new bundle to swap in if matched
|
|
162
|
+
#
|
|
163
|
+
# ===== Returns
|
|
164
|
+
# The rewritten url. May also change the value of current_bundle
|
|
165
|
+
#
|
|
166
|
+
def rewrite_bundle_if(url, match, new_bundle_name)
|
|
167
|
+
return url unless match =~ url
|
|
168
|
+
new_bundle = library.bundle_for(new_bundle_name)
|
|
169
|
+
if new_bundle
|
|
170
|
+
url = url.gsub(match, new_bundle.index_root)
|
|
171
|
+
@current_bundle = new_bundle
|
|
172
|
+
end
|
|
173
|
+
return url
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
end
|