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,310 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('Core') ;
|
|
7
|
+
require('foundation/object') ;
|
|
8
|
+
require('foundation/input_manager');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
@class A responder is capable of responding to events such as mouse clicks and key presses.
|
|
12
|
+
|
|
13
|
+
All views are a type of responder, but you can extend this class yourself
|
|
14
|
+
as well to implement your own responders if you need to.
|
|
15
|
+
|
|
16
|
+
@extends SC.Object
|
|
17
|
+
|
|
18
|
+
*/
|
|
19
|
+
SC.Responder = SC.Object.extend(
|
|
20
|
+
/** @scope SC.Responder.prototype */
|
|
21
|
+
{
|
|
22
|
+
|
|
23
|
+
// .......................................................................
|
|
24
|
+
// Managing Responder States
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
This method will be called just before you become first responder to see
|
|
29
|
+
if you want to be first responder. If you don't want to handle
|
|
30
|
+
keyboard events, return false. (this is the default). Note that this is
|
|
31
|
+
a property.
|
|
32
|
+
*/
|
|
33
|
+
acceptsFirstResponder: false,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
This property is the next responder that should be allowed to handle
|
|
37
|
+
events if you don't want to handle it. For views, this is automatically
|
|
38
|
+
set to your parentNode.
|
|
39
|
+
*/
|
|
40
|
+
nextResponder: null,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
This property is true whenever you are the first responder. Observable.
|
|
44
|
+
*/
|
|
45
|
+
isFirstResponder: false,
|
|
46
|
+
|
|
47
|
+
pane: null,
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
Call this method to become the first responder. You will now be the
|
|
51
|
+
first to receive keyboard events, etc. Return false if you could not
|
|
52
|
+
be made first responder for some reason.
|
|
53
|
+
*/
|
|
54
|
+
becomeFirstResponder: function()
|
|
55
|
+
{
|
|
56
|
+
if (!this.get('acceptsFirstResponder')) return false; // responder doesn't want it
|
|
57
|
+
|
|
58
|
+
var pane = this.get('pane');
|
|
59
|
+
if (!pane) return false; // there's no pane of which to become FR.. doesn't matter if it *does* want it...
|
|
60
|
+
|
|
61
|
+
if (pane.get('firstResponder') == this) return true; // we already got it... and setting it again will trigger the willResign callback
|
|
62
|
+
|
|
63
|
+
pane.set('firstResponder',this);
|
|
64
|
+
return true;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
Call this method if you no longer want to be first responder. Normally
|
|
69
|
+
you don't need to do this since you will lose firstResponder status
|
|
70
|
+
when the user focuses a different view.
|
|
71
|
+
*/
|
|
72
|
+
resignFirstResponder: function()
|
|
73
|
+
{
|
|
74
|
+
var pane = this.get('pane');
|
|
75
|
+
if (!pane) return false;
|
|
76
|
+
|
|
77
|
+
if (pane.get('firstResponder') != this) return false;
|
|
78
|
+
|
|
79
|
+
pane.set('firstResponder',null);
|
|
80
|
+
return true;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
noResponderFor: function() {},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
This method will be called just before you become the first responder
|
|
87
|
+
so you can make changes.
|
|
88
|
+
*/
|
|
89
|
+
didBecomeFirstResponder: function() {},
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
This method will be called just before you lose first responder status.
|
|
93
|
+
*/
|
|
94
|
+
willLoseFirstResponder: function() {},
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
// .......................................................................
|
|
98
|
+
// Keyboard Events
|
|
99
|
+
//
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
Set this value to an SC.InputManager instance if you want to use a
|
|
103
|
+
custom input manager for this specific instance. If you want to override
|
|
104
|
+
the input manager used for all responders, replace SC.Responder.inputManager.
|
|
105
|
+
*/
|
|
106
|
+
inputManager: function()
|
|
107
|
+
{
|
|
108
|
+
return SC.Responder.inputManager;
|
|
109
|
+
}.property(),
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
this method is invoked on the firstResponder whenever the user presses
|
|
113
|
+
a key. You can interpret this yourself or call interpretKeyEvents()
|
|
114
|
+
which will use the inputManager to handle the event. The default
|
|
115
|
+
version just passes this onto the next responder.
|
|
116
|
+
*/
|
|
117
|
+
keyDown: function(evt) {
|
|
118
|
+
var nr = this.get('nextResponder') ;
|
|
119
|
+
return (nr && nr.keyDown) ? nr.keyDown(evt) : false;
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
This method is invoked on the firstResponder whenever the user releases
|
|
124
|
+
a key. Default version just passes onto the next responder.
|
|
125
|
+
*/
|
|
126
|
+
keyUp: function(evt) {
|
|
127
|
+
var nr = this.get('nextResponder') ;
|
|
128
|
+
return (nr && nr.keyUp) ? nr.keyUp(evt) : false ;
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
This method is invoked whenever the user changes the flag keys that are
|
|
133
|
+
pressed. pressedFlags is a hash. The default version passes on to the
|
|
134
|
+
nextRespoonder.
|
|
135
|
+
*/
|
|
136
|
+
flagsChanged: function(pressedFlags, evt) {
|
|
137
|
+
//var nr = this.get('nextResponder') || SC.window.get('firstResponder') ;
|
|
138
|
+
var nr = this.get('nextResponder') ;
|
|
139
|
+
return (nr && nr.flagsChanges) ? nr.flagsChanges(pressedFlags, evt) : false;
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
This will be called if a keydown event isn't handled by the responder chain.
|
|
144
|
+
*/
|
|
145
|
+
performKeyEquivalent: function(keystring, evt) {
|
|
146
|
+
return false;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
call this method with one or more event objects to process the incoming
|
|
151
|
+
text. This will use the current inputManager (see above) to process
|
|
152
|
+
the event and then to make an appropriate call on the receiver.
|
|
153
|
+
*/
|
|
154
|
+
interpretKeyEvents: function(evts) {
|
|
155
|
+
var inputManager = this.get('inputManager');
|
|
156
|
+
if (inputManager) return inputManager.interpretKeyEvents(evts, this) ;
|
|
157
|
+
return false ;
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Attempt to perform a method. If either the method does not exist, or the method returns false, send the request to the nextResponder.
|
|
162
|
+
* @param {String} method The name of the method to perform
|
|
163
|
+
* @return {SC.Responder} The responder that handled the command, or false
|
|
164
|
+
*/
|
|
165
|
+
doCommand: function(method)
|
|
166
|
+
{
|
|
167
|
+
var responder = this;
|
|
168
|
+
var args = $A(arguments);
|
|
169
|
+
var method = args.shift();
|
|
170
|
+
var aliases = this._commandAliases[method];
|
|
171
|
+
var handled = false;
|
|
172
|
+
|
|
173
|
+
do {
|
|
174
|
+
// attempt to handle the method
|
|
175
|
+
if (this._responderHandledCommand(responder, method, args)) return responder;
|
|
176
|
+
// perhaps under an alias?
|
|
177
|
+
if (aliases)
|
|
178
|
+
{
|
|
179
|
+
for (var i=0, n=aliases.length; i < n; i++)
|
|
180
|
+
{
|
|
181
|
+
if (this._responderHandledCommand(responder, aliases[i], args)) return responder;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// nope... next responder, please...
|
|
185
|
+
} while (responder = responder.get('nextResponder'));
|
|
186
|
+
// ran out of responders...
|
|
187
|
+
return false;
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/** @private */
|
|
191
|
+
_responderHandledCommand: function( responder, method, args )
|
|
192
|
+
{
|
|
193
|
+
// if the method does not explicitly return a false-y value (false, "", 0), it's considered "handled"
|
|
194
|
+
// WARNING: returning null, or void is *not* == false
|
|
195
|
+
return (responder.respondsTo(method) && (responder[method].apply(responder, args) != false));
|
|
196
|
+
},
|
|
197
|
+
/** @private */
|
|
198
|
+
_commandAliases: {
|
|
199
|
+
'mouseDown': ['didMouseDown'],
|
|
200
|
+
'mouseUp': ['didMouseUp'],
|
|
201
|
+
'doubleClick': ['didDoubleClick'],
|
|
202
|
+
'click': ['didClick'],
|
|
203
|
+
'mouseDown': ['didMouseDown']
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// .......................................................................
|
|
207
|
+
// Mouse Event Handlers
|
|
208
|
+
//
|
|
209
|
+
// Implement any of these if you want them to be implemented.
|
|
210
|
+
|
|
211
|
+
// when the mouse is pressed.
|
|
212
|
+
// mouseDown: function(evt) {},
|
|
213
|
+
|
|
214
|
+
// when the mouse is releases
|
|
215
|
+
// mouseUp: function(evt) {},
|
|
216
|
+
|
|
217
|
+
// when the mouse is dragged
|
|
218
|
+
// mouseDragged: function(evt) {},
|
|
219
|
+
|
|
220
|
+
// when the mouse leaves the view responder
|
|
221
|
+
// mouseOut: function(evt) {},
|
|
222
|
+
|
|
223
|
+
// when the mouse enters the view.
|
|
224
|
+
// mouseOver: function(evt) {},
|
|
225
|
+
|
|
226
|
+
// when the mouse is moved.
|
|
227
|
+
// mouseMoved: function(evt) {},
|
|
228
|
+
|
|
229
|
+
// .......................................................................
|
|
230
|
+
// Event Handlers
|
|
231
|
+
//
|
|
232
|
+
// These methods are called by the input manager in response to keyboard
|
|
233
|
+
// events. Most of these methods are defined here for you, but not actually
|
|
234
|
+
// implemented in code.
|
|
235
|
+
|
|
236
|
+
// insert the text or act on the key.
|
|
237
|
+
// insertText: function(text) {},
|
|
238
|
+
|
|
239
|
+
// if the user presses a key-combination event, this will be called so you
|
|
240
|
+
// can run the command.
|
|
241
|
+
// performKeyEquivalent: function(charCode, evt) { return false; },
|
|
242
|
+
|
|
243
|
+
// this method is called if no other view in the current view hierarchy is
|
|
244
|
+
// bound to the escape or command-. key equivalent. You can use this to
|
|
245
|
+
// cancel whatever operation is running.
|
|
246
|
+
//
|
|
247
|
+
// cancel: function(sender, evt) {},
|
|
248
|
+
|
|
249
|
+
// delete the current selection or delete one element backward from the
|
|
250
|
+
// current selection.
|
|
251
|
+
// deleteBackward: function(sender, evt) {},
|
|
252
|
+
|
|
253
|
+
// delete the current selection or delete one element forward from the
|
|
254
|
+
// current selection.
|
|
255
|
+
// deleteForward: function(sender, evt) {},
|
|
256
|
+
|
|
257
|
+
// a field editor might respond by selecting the field before it.
|
|
258
|
+
// insertBacktab: function(sender, evt) {},
|
|
259
|
+
|
|
260
|
+
// insert a newline character or end editing of the receiver.
|
|
261
|
+
// insertNewline: function(sender, evt) {},
|
|
262
|
+
|
|
263
|
+
// insert a tab or move forward to the next field.
|
|
264
|
+
// insertTab: function(sender, evt) {},
|
|
265
|
+
|
|
266
|
+
// move insertion point/selection backward one. (i.e. left arrow key)
|
|
267
|
+
// moveLeft: function(sender, evt) {},
|
|
268
|
+
|
|
269
|
+
// move the insertion point/selection forward one (i.e. right arrow key)
|
|
270
|
+
// in left-to-right text, this could be the left arrow key.
|
|
271
|
+
// moveRight: function(sender, evt) {},
|
|
272
|
+
|
|
273
|
+
// move the insertion point/selection up one (i.e. up arrow key)
|
|
274
|
+
// moveUp: function(sender, evt) {},
|
|
275
|
+
|
|
276
|
+
// move the insertion point/selection down one (i.e. down arrow key)
|
|
277
|
+
// moveDown: function(sender, evt) {},
|
|
278
|
+
|
|
279
|
+
// move left, extending the selection. - shift || alt
|
|
280
|
+
// moveLeftAndModifySelection: function(sender, evt) {},
|
|
281
|
+
|
|
282
|
+
// move right, extending the seleciton - shift || alt
|
|
283
|
+
// moveRightAndModifySelection: function(sender, evt) {},
|
|
284
|
+
|
|
285
|
+
// move up, extending the selection - shift || alt
|
|
286
|
+
// moveUpAndModifySelection: function(sender, evt) {},
|
|
287
|
+
|
|
288
|
+
// move down, extending selection - shift || alt
|
|
289
|
+
// moveDownAndModifySelection: function(sender, evt) {},
|
|
290
|
+
|
|
291
|
+
// move insertion point/selection to beginning of document.
|
|
292
|
+
// moveToBeginningOfDocument: function(sender, evt) {},
|
|
293
|
+
|
|
294
|
+
// move insertion point/selection to end of document.
|
|
295
|
+
// moveToEndOfDocument: function(sender, evt) {},
|
|
296
|
+
|
|
297
|
+
// page down
|
|
298
|
+
// pageDown: function(sender, evt) {},
|
|
299
|
+
|
|
300
|
+
// page up
|
|
301
|
+
// pageUp: function(sender, evt) {},
|
|
302
|
+
|
|
303
|
+
// select all
|
|
304
|
+
// selectAll: function(sender, evt) {},
|
|
305
|
+
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
SC.Responder.mixin({
|
|
309
|
+
inputManager: SC.InputManager.create()
|
|
310
|
+
}) ;
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('foundation/object') ;
|
|
7
|
+
|
|
8
|
+
// Routes makes it possible to load a location in the browser.
|
|
9
|
+
SC.Routes = SC.Object.create({
|
|
10
|
+
|
|
11
|
+
// set this property to your current app lication
|
|
12
|
+
location: function(key,value) {
|
|
13
|
+
if (value !== undefined) {
|
|
14
|
+
if (value === null) value = '' ;
|
|
15
|
+
|
|
16
|
+
// convert an object hash to a string, if it was passed.
|
|
17
|
+
if (typeof(value) == "object") {
|
|
18
|
+
|
|
19
|
+
// get the original route and any params
|
|
20
|
+
var parts = (value.route) ? value.route.split('&') : [''] ;
|
|
21
|
+
var route = parts.shift() ;
|
|
22
|
+
var params = {} ;
|
|
23
|
+
parts.each(function(p) {
|
|
24
|
+
var bits = p.split('=') ;
|
|
25
|
+
params[bits[0]] = bits[1] ;
|
|
26
|
+
}) ;
|
|
27
|
+
|
|
28
|
+
// overlay any params passed in the object.
|
|
29
|
+
for(var key in value) {
|
|
30
|
+
if (!value.hasOwnProperty(key)) continue ;
|
|
31
|
+
if (key != 'route') {
|
|
32
|
+
params[key] = encodeURIComponent(''+value[key]) ;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// now build params.
|
|
37
|
+
parts = [route] ;
|
|
38
|
+
for(var key in params) {
|
|
39
|
+
if (!params.hasOwnProperty(key)) continue ;
|
|
40
|
+
parts.push([key,params[key]].join('=')) ;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// and combine.
|
|
44
|
+
value = parts.join('&') ;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (this._location != value) {
|
|
48
|
+
this._location = value ;
|
|
49
|
+
this._setWindowLocation(value) ;
|
|
50
|
+
//this.gotoRoute(value) ;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return this._location ;
|
|
54
|
+
}.property(),
|
|
55
|
+
|
|
56
|
+
// ensures we are at the current route location.
|
|
57
|
+
ping: function() {
|
|
58
|
+
if (!this._didSetupHistory) {
|
|
59
|
+
this._didSetupHistory = true ;
|
|
60
|
+
this._setupHistory() ;
|
|
61
|
+
}
|
|
62
|
+
this._checkWindowLocation();
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// register a route here. Routes have the following format:
|
|
66
|
+
// static/route/path -- matches this path only.
|
|
67
|
+
// static/route/:path -- matches any static/route, :path passed as param.
|
|
68
|
+
// static/*route -- matches any static, route gets rest of URL.
|
|
69
|
+
//
|
|
70
|
+
// parameters can also be passed using &.
|
|
71
|
+
// static/route¶m1=value¶m2=value2
|
|
72
|
+
//
|
|
73
|
+
addRoute: function(route, func) {
|
|
74
|
+
var parts = route.split('/') ;
|
|
75
|
+
if (!this._routes) this._routes = SC.Routes._Route.create() ;
|
|
76
|
+
this._routes.addRoute(parts,func) ;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// eval routes.
|
|
80
|
+
gotoRoute: function(route) {
|
|
81
|
+
var params = {} ; var parts, route, func ;
|
|
82
|
+
|
|
83
|
+
// save this route for window location sensing
|
|
84
|
+
this._lastRoute = route ;
|
|
85
|
+
|
|
86
|
+
// step 1: split out parameters
|
|
87
|
+
var parts = route.split('&') ;
|
|
88
|
+
if (parts && parts.length > 0) {
|
|
89
|
+
route = parts.shift() ;
|
|
90
|
+
parts.each(function(part) {
|
|
91
|
+
var param = part.split('=') ;
|
|
92
|
+
if (param && param.length > 1) params[param[0]] = decodeURIComponent(param[1]) ;
|
|
93
|
+
}) ;
|
|
94
|
+
} else route = '' ;
|
|
95
|
+
|
|
96
|
+
// step 2: split our route parts
|
|
97
|
+
parts = route.split('/') ;
|
|
98
|
+
|
|
99
|
+
// step 3: evaluate route.
|
|
100
|
+
if (!this._routes) this._routes = SC.Routes._Route.create() ;
|
|
101
|
+
func = this._routes.functionForRoute(parts,params) ;
|
|
102
|
+
if (func) func(params) ;
|
|
103
|
+
else console.log('could not find route for: "'+route+'"') ;
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
init: function() {
|
|
108
|
+
arguments.callee.base.call(this) ;
|
|
109
|
+
if (SC.isSafari() && !SC.isSafari3()) {
|
|
110
|
+
Object.extend(this,this.browserFuncs.safari) ;
|
|
111
|
+
} else if (SC.isIE()) {
|
|
112
|
+
Object.extend(this,this.browserFuncs.ie) ;
|
|
113
|
+
}
|
|
114
|
+
this._didSetupHistory = false ;
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// _checkWindowLocation and _setWindowLocation are implemented separately for
|
|
118
|
+
// each browser. Below are the implementations, which get copied during init.
|
|
119
|
+
browserFuncs: {
|
|
120
|
+
|
|
121
|
+
// for Safari2 and earlier.
|
|
122
|
+
safari: {
|
|
123
|
+
|
|
124
|
+
_setupHistory: function() {
|
|
125
|
+
// get initial cloc.
|
|
126
|
+
var cloc = location.hash ;
|
|
127
|
+
cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
|
|
128
|
+
this._cloc = cloc ;
|
|
129
|
+
|
|
130
|
+
// create back stack.
|
|
131
|
+
this._backStack = [] ;
|
|
132
|
+
this._backStack.length = history.length ;
|
|
133
|
+
this._backStack.push(cloc) ;
|
|
134
|
+
|
|
135
|
+
// create forward stack.
|
|
136
|
+
this._forwardStack = [] ;
|
|
137
|
+
|
|
138
|
+
this._boundChecker = this._checkWindowLocation.bind(this) ;
|
|
139
|
+
this.timer = setTimeout(this._boundChecker,1000) ;
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
_checkWindowLocation: function() {
|
|
143
|
+
// The way we know the user has moved forward or back in the history
|
|
144
|
+
// is when the length of the history array no longer matched our own
|
|
145
|
+
// copy of the history. However, when we first change locations, it
|
|
146
|
+
// takes a little while for Safari to catch up. So what we do instead
|
|
147
|
+
// is first check to see if Safari's length has changed from its last
|
|
148
|
+
// known length and only then check for a delta.
|
|
149
|
+
var historyDidChange = (history.length - this._lastLength) != 0;
|
|
150
|
+
var delta = (historyDidChange) ? (history.length - this._backStack.length) : 0 ;
|
|
151
|
+
this._lastLength = history.length ;
|
|
152
|
+
|
|
153
|
+
if (historyDidChange) console.log('historyDidChange') ;
|
|
154
|
+
|
|
155
|
+
// if the history length has changed, then we need to move forward or
|
|
156
|
+
// back in the history.
|
|
157
|
+
if (delta) {
|
|
158
|
+
if (delta < 0) { // back button has been pushed
|
|
159
|
+
|
|
160
|
+
// shift out the current loc.
|
|
161
|
+
this._forwardStack.push(this._cloc) ;
|
|
162
|
+
|
|
163
|
+
// shift out other items.
|
|
164
|
+
for(var i=0; i < Math.abs(delta+1);i++) {
|
|
165
|
+
this._forwardStack.push(this._backStack.pop()) ;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// set new cloc.
|
|
169
|
+
this._cloc = this._backStack.pop() ;
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
} else { // forward button has been pushed
|
|
173
|
+
|
|
174
|
+
// shift out the current loc.
|
|
175
|
+
this._backStack.push(this._cloc) ;
|
|
176
|
+
|
|
177
|
+
for(var i=0; i < (delta-1); i++) {
|
|
178
|
+
this._backStack.push(this._forwardStack.pop()) ;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this._cloc = this._forwardStack.pop() ;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// if the history has changed but the delta hasn't, then that means
|
|
185
|
+
// a new location was set via _setWindowLocation(). Normally we would
|
|
186
|
+
// call gotoRoute in that method, but doing so will crash Safari.
|
|
187
|
+
// Instead, we wait until Safari registers the change and then do the
|
|
188
|
+
// route change.
|
|
189
|
+
} else if (historyDidChange && this._locationDidChange) {
|
|
190
|
+
this.gotoRoute(this._cloc) ;
|
|
191
|
+
this._locationDidChange = false ;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
var cloc = this._cloc ;
|
|
195
|
+
var loc = this.get('location') ;
|
|
196
|
+
if (cloc != loc) {
|
|
197
|
+
this.set('location',(cloc) ? cloc : '') ;
|
|
198
|
+
this.gotoRoute(cloc) ;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
this.timer = setTimeout(this._boundChecker,50) ;
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
_setWindowLocation: function(loc) {
|
|
205
|
+
var cloc = this._cloc ;
|
|
206
|
+
if (cloc != loc) {
|
|
207
|
+
this._backStack.push(this._cloc) ;
|
|
208
|
+
this._forwardStack.length = 0 ;
|
|
209
|
+
this._cloc = loc ;
|
|
210
|
+
location.hash = (loc && loc.length > 0) ? loc : '' ;
|
|
211
|
+
this._locationDidChange = true ;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
// for IE.
|
|
218
|
+
ie: {
|
|
219
|
+
_setupHistory: function() {
|
|
220
|
+
this._boundChecker = this._checkWindowLocation.bind(this) ;
|
|
221
|
+
// this.timer = setTimeout(this._boundChecker,1000) ;
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
_checkWindowLocation: function() {
|
|
225
|
+
var loc = this.get('location') ;
|
|
226
|
+
var cloc = location.hash ;
|
|
227
|
+
cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
|
|
228
|
+
if (cloc != loc) this.set('location',(cloc) ? cloc : '') ;
|
|
229
|
+
this.timer = setTimeout(this._boundChecker,100) ;
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
_setWindowLocation: function(loc) {
|
|
233
|
+
//console.log('_setWindowLocation('+loc+')') ;
|
|
234
|
+
var cloc = location.hash ;
|
|
235
|
+
cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
|
|
236
|
+
if (cloc != loc) {
|
|
237
|
+
location.hash = (loc && loc.length > 0) ? loc : '#' ;
|
|
238
|
+
}
|
|
239
|
+
this.gotoRoute(loc) ;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
_setupHistory: function() {
|
|
245
|
+
this._boundChecker = this._checkWindowLocation.bind(this) ;
|
|
246
|
+
this.timer = setTimeout(this._boundChecker,1000) ;
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
_checkWindowLocation: function() {
|
|
250
|
+
var loc = this.get('location') ;
|
|
251
|
+
var cloc = location.hash ;
|
|
252
|
+
cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
|
|
253
|
+
if (cloc != loc) this.set('location',(cloc) ? cloc : '') ;
|
|
254
|
+
this.timer = setTimeout(this._boundChecker,100) ;
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
_setWindowLocation: function(loc) {
|
|
258
|
+
//console.log('_setWindowLocation('+loc+')') ;
|
|
259
|
+
var cloc = location.hash ;
|
|
260
|
+
cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
|
|
261
|
+
if (cloc != loc) {
|
|
262
|
+
location.hash = (loc && loc.length > 0) ? loc : '#' ;
|
|
263
|
+
}
|
|
264
|
+
this.gotoRoute(loc) ;
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
_routes: null,
|
|
268
|
+
|
|
269
|
+
// This object handles a single route level.
|
|
270
|
+
_Route: SC.Object.extend({
|
|
271
|
+
|
|
272
|
+
// a route that ends here gets this func.
|
|
273
|
+
_func: null,
|
|
274
|
+
|
|
275
|
+
// staticly named routes.
|
|
276
|
+
_static: null,
|
|
277
|
+
|
|
278
|
+
// dynamically named routes.
|
|
279
|
+
_dynamic: null,
|
|
280
|
+
|
|
281
|
+
// set the wildcard route name here.
|
|
282
|
+
_wildcard: null,
|
|
283
|
+
|
|
284
|
+
addRoute: function(parts, func) {
|
|
285
|
+
if (!parts || parts.length == 0) {
|
|
286
|
+
this._func = func ;
|
|
287
|
+
|
|
288
|
+
// add to route table.
|
|
289
|
+
} else {
|
|
290
|
+
var part = parts.shift() ; // get next route.
|
|
291
|
+
var nextRoute = null ;
|
|
292
|
+
switch(part.slice(0,1)) {
|
|
293
|
+
|
|
294
|
+
// add a dynamic route
|
|
295
|
+
case ':':
|
|
296
|
+
part = part.slice(1,part.length) ;
|
|
297
|
+
var routes = this._dynamic[part] || [] ;
|
|
298
|
+
nextRoute = SC.Routes._Route.create() ;
|
|
299
|
+
routes.push(nextRoute) ;
|
|
300
|
+
this._dynamic[part] = routes ;
|
|
301
|
+
break ;
|
|
302
|
+
|
|
303
|
+
// setup wildcard route
|
|
304
|
+
case '*':
|
|
305
|
+
part = part.slice(1,part.length) ;
|
|
306
|
+
this._wildcard = part ;
|
|
307
|
+
this._func = func ;
|
|
308
|
+
break ;
|
|
309
|
+
|
|
310
|
+
// setup a normal static route.
|
|
311
|
+
default:
|
|
312
|
+
var routes = this._static[part] || [] ;
|
|
313
|
+
nextRoute = SC.Routes._Route.create() ;
|
|
314
|
+
routes.push(nextRoute) ;
|
|
315
|
+
this._static[part] = routes ;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// if we need to go another level deeper, call nextRoute
|
|
319
|
+
if (nextRoute) nextRoute.addRoute(parts,func) ;
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
// process the next level of the route and pass on.
|
|
324
|
+
functionForRoute: function(parts, params) {
|
|
325
|
+
// if parts it empty, then we are here, so return func
|
|
326
|
+
if (!parts || parts.length == 0) {
|
|
327
|
+
return this._func ;
|
|
328
|
+
|
|
329
|
+
// process the next part
|
|
330
|
+
} else {
|
|
331
|
+
var part = parts.shift() ;
|
|
332
|
+
var routes, nextRoute, ret, loc ;
|
|
333
|
+
|
|
334
|
+
// try to match to static
|
|
335
|
+
routes = this._static[part] ;
|
|
336
|
+
if (routes) for(loc=0;(loc < routes.length) && (ret==null);loc++) {
|
|
337
|
+
var clone = parts.slice() ;
|
|
338
|
+
ret = routes[loc].functionForRoute(clone, params) ;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// try to match dynamic if no static match was found.
|
|
342
|
+
if (ret == null) for(var key in this._dynamic) {
|
|
343
|
+
routes = this._dynamic[key] ;
|
|
344
|
+
if (routes) for(loc=0;(loc<routes.length) && (ret == null);loc++) {
|
|
345
|
+
var clone = parts.slice() ;
|
|
346
|
+
ret = routes[loc].functionForRoute(clone,params) ;
|
|
347
|
+
|
|
348
|
+
// if a route was found, save the current part in params.
|
|
349
|
+
if (ret && params) params[key] = part ;
|
|
350
|
+
}
|
|
351
|
+
if (ret) break ;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// if nothing still found, and there is a wildcard, match that.
|
|
355
|
+
if ((ret == null) && this._wildcard) {
|
|
356
|
+
parts.unshift(part) ;
|
|
357
|
+
if (params) params[this._wildcard] = parts.join('/') ;
|
|
358
|
+
ret = this._func ;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return ret ;
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
init: function() {
|
|
366
|
+
arguments.callee.base.call(this) ;
|
|
367
|
+
this._static = {} ; this._dynamic = {} ;
|
|
368
|
+
}
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
}) ;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('Core') ;
|
|
7
|
+
|
|
8
|
+
// RunLoop is used to manage deferred runs. It's lighter weight than setting
|
|
9
|
+
// lots of timeouts.
|
|
10
|
+
SC.runLoop = SC.Object.create({
|
|
11
|
+
|
|
12
|
+
schedule: function() {
|
|
13
|
+
var args = $A(arguments) ;
|
|
14
|
+
var obj = args.shift() ;
|
|
15
|
+
var method = obj[args.shift()];
|
|
16
|
+
var delay = args.pop() ;
|
|
17
|
+
var func = function() { method.apply(obj, args); }
|
|
18
|
+
return setTimeout(func, delay) ;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}) ;
|