sproutcore 1.10.0 → 1.10.1
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.
- checksums.yaml +8 -8
- data/VERSION.yml +1 -1
- data/bin/sc-phantom +13 -0
- data/lib/Buildfile +3 -0
- data/lib/buildtasks/manifest.rake +3 -0
- data/lib/frameworks/sproutcore/CHANGELOG.md +24 -1
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/designer/views/designer_drop_target.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/designer/views/high_light.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/designer/views/page_item_view.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/designer/views/selection_handles.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +4 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/progress.css +4 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +44 -35
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +167 -91
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/touch.js +215 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/drag_and_drop.js +7 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/drag_and_drop.js +7 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +26 -24
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +9 -18
- data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +25 -20
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +29 -29
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +107 -106
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +120 -134
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +14 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/stacked.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +197 -196
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +22 -10
- data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +43 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +2 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +14 -14
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +90 -79
- data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/advanced/event_queuing.js +104 -0
- data/lib/frameworks/sproutcore/frameworks/table/views/table.js +3 -0
- data/lib/frameworks/sproutcore/frameworks/template_view/handlebars.js +2 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/grid.css +17 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +1 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.png +0 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu@2x.png +0 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/panel/panel.css +2 -2
- data/lib/frameworks/sproutcore/themes/empty_theme/theme.js +1 -1
- data/lib/sproutcore/tools.rb +2 -1
- data/lib/sproutcore/tools/phantom.rb +36 -0
- data/sproutcore.gemspec +1 -1
- data/vendor/chance/lib/chance/instance.rb +5 -2
- metadata +11 -4
@@ -1700,11 +1700,13 @@ SC.ScrollView = SC.View.extend({
|
|
1700
1700
|
|
1701
1701
|
// set the scale, vertical, and horizontal offsets to what they technically already are,
|
1702
1702
|
// but don't know they are yet. This will finally update things like, say, the clipping frame.
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1703
|
+
SC.run(function () {
|
1704
|
+
this.beginPropertyChanges();
|
1705
|
+
this.set("scale", this._scale);
|
1706
|
+
this.set("verticalScrollOffset", this._scroll_verticalScrollOffset);
|
1707
|
+
this.set("horizontalScrollOffset", this._scroll_horizontalScrollOffset);
|
1708
|
+
this.endPropertyChanges();
|
1709
|
+
}, this);
|
1708
1710
|
|
1709
1711
|
return;
|
1710
1712
|
}
|
@@ -1719,7 +1721,7 @@ SC.ScrollView = SC.View.extend({
|
|
1719
1721
|
var self = this;
|
1720
1722
|
touch.lastEventTime = Date.now();
|
1721
1723
|
touch.animationID = window.requestAnimationFrame(function () {
|
1722
|
-
|
1724
|
+
self.decelerateAnimation();
|
1723
1725
|
});
|
1724
1726
|
},
|
1725
1727
|
|
@@ -1936,7 +1938,11 @@ SC.ScrollView = SC.View.extend({
|
|
1936
1938
|
forceHeight = mxVOffSet < vOffSet,
|
1937
1939
|
forceWidth = mxHOffSet < hOffSet;
|
1938
1940
|
if (forceHeight || forceWidth) {
|
1941
|
+
// Update the position of the content view to fit.
|
1939
1942
|
this.forceDimensionsRecalculation(forceWidth, forceHeight, vOffSet, hOffSet);
|
1943
|
+
} else {
|
1944
|
+
// Reapply the position. Most importantly, this reapplies the touch transforms on the content view in case they were overwritten.
|
1945
|
+
this.invokeLast(this.adjustElementScroll);
|
1940
1946
|
}
|
1941
1947
|
|
1942
1948
|
// send change notifications since they don't invalidate automatically
|
@@ -2000,7 +2006,8 @@ SC.ScrollView = SC.View.extend({
|
|
2000
2006
|
this._applyCSSTransforms(content.get('layer'));
|
2001
2007
|
}
|
2002
2008
|
|
2003
|
-
|
2009
|
+
// Notify the child that its frame is changing.
|
2010
|
+
content.notifyPropertyChange('frame');
|
2004
2011
|
}
|
2005
2012
|
|
2006
2013
|
if (container && !SC.platform.touch) {
|
@@ -99,7 +99,8 @@ SC.StackedView = SC.CollectionView.extend(
|
|
99
99
|
height = layer ? (layer.offsetTop + layer.offsetHeight) : 1;
|
100
100
|
layer = null; // avoid memory leaks
|
101
101
|
}
|
102
|
-
this.adjust('
|
102
|
+
this.adjust('minHeight', height);
|
103
|
+
this.set('calculatedHeight', height);
|
103
104
|
},
|
104
105
|
|
105
106
|
// ..........................................................
|
@@ -247,14 +247,14 @@ SC.ContentValueSupport = {
|
|
247
247
|
observed keys.
|
248
248
|
*/
|
249
249
|
_control_contentDidChange: function (target, key) {
|
250
|
+
// remove an observer from the old content if necessary
|
251
|
+
this._cleanup_old_content_observers();
|
252
|
+
|
250
253
|
var content = this.get('content'),
|
251
254
|
contentKeys = this.get('contentKeys'), contentKey,
|
252
255
|
oldKeys = this._old_contentValueKeys,
|
253
256
|
f = this.contentPropertyDidChange;
|
254
257
|
|
255
|
-
// remove an observer from the old content if necessary
|
256
|
-
this._cleanup_old_content_observers();
|
257
|
-
|
258
258
|
// add observer to new content if necessary.
|
259
259
|
if (content && content.addObserver) {
|
260
260
|
// set case
|
@@ -349,7 +349,7 @@ SC.ContentValueSupport = {
|
|
349
349
|
if (oldType === SC.T_STRING) {
|
350
350
|
old.removeObserver(oldKeys, this, f);
|
351
351
|
|
352
|
-
oldKeys = null;
|
352
|
+
this._old_contentValueKeys = oldKeys = null;
|
353
353
|
}
|
354
354
|
|
355
355
|
// set case
|
@@ -5,7 +5,8 @@
|
|
5
5
|
// License: Licensed under MIT license (see license.js)
|
6
6
|
// ==========================================================================
|
7
7
|
|
8
|
-
/*
|
8
|
+
/*globals jQuery */
|
9
|
+
|
9
10
|
sc_require('tasks/task');
|
10
11
|
SC.LOG_MODULE_LOADING = YES;
|
11
12
|
|
@@ -30,9 +31,9 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
30
31
|
@param {String} moduleName the name of the module to check
|
31
32
|
@returns {Boolean}
|
32
33
|
*/
|
33
|
-
isModuleReady: function(moduleName) {
|
34
|
-
var moduleInfo = SC.MODULE_INFO[moduleName]
|
35
|
-
return moduleInfo ? !!moduleInfo.isReady : NO
|
34
|
+
isModuleReady: function (moduleName) {
|
35
|
+
var moduleInfo = SC.MODULE_INFO[moduleName];
|
36
|
+
return moduleInfo ? !!moduleInfo.isReady : NO;
|
36
37
|
},
|
37
38
|
|
38
39
|
/**
|
@@ -49,7 +50,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
49
50
|
@param method {Function}
|
50
51
|
@returns {Boolean} YES if already loaded, NO otherwise
|
51
52
|
*/
|
52
|
-
loadModule: function(moduleName, target, method) {
|
53
|
+
loadModule: function (moduleName, target, method) {
|
53
54
|
var module = SC.MODULE_INFO[moduleName], callbacks, targets,
|
54
55
|
args = SC.A(arguments).slice(3),
|
55
56
|
log = SC.LOG_MODULE_LOADING,
|
@@ -100,7 +101,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
100
101
|
// This is because the module may set up bindings.
|
101
102
|
this._addCallbackForModule(moduleName, target, method, args);
|
102
103
|
|
103
|
-
this.invokeLast(function() {
|
104
|
+
this.invokeLast(function () {
|
104
105
|
module.isReady = YES;
|
105
106
|
this._moduleDidBecomeReady(moduleName);
|
106
107
|
});
|
@@ -113,7 +114,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
113
114
|
SC.Module._invokeCallback(moduleName, target, method, args);
|
114
115
|
} else {
|
115
116
|
// Queue callback for when SC has finished loading.
|
116
|
-
SC.ready(SC.Module, function() {
|
117
|
+
SC.ready(SC.Module, function () {
|
117
118
|
SC.Module._invokeCallback(moduleName, target, method, args);
|
118
119
|
});
|
119
120
|
}
|
@@ -149,14 +150,14 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
149
150
|
}
|
150
151
|
},
|
151
152
|
|
152
|
-
_addCallbackForModule: function(moduleName, target, method, args) {
|
153
|
+
_addCallbackForModule: function (moduleName, target, method, args) {
|
153
154
|
var module = SC.MODULE_INFO[moduleName];
|
154
155
|
|
155
156
|
// Retrieve array of callbacks from MODULE_INFO hash.
|
156
|
-
var callbacks = module.callbacks || []
|
157
|
+
var callbacks = module.callbacks || [];
|
157
158
|
|
158
159
|
if (method) {
|
159
|
-
callbacks.push(function() {
|
160
|
+
callbacks.push(function () {
|
160
161
|
SC.Module._invokeCallback(moduleName, target, method, args);
|
161
162
|
});
|
162
163
|
}
|
@@ -177,7 +178,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
177
178
|
|
178
179
|
@param {String} moduleName the name of the module to prefetch
|
179
180
|
*/
|
180
|
-
prefetchModule: function(moduleName) {
|
181
|
+
prefetchModule: function (moduleName) {
|
181
182
|
var module = SC.MODULE_INFO[moduleName];
|
182
183
|
|
183
184
|
if (module.isLoading || module.isLoaded) return;
|
@@ -198,7 +199,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
198
199
|
If a module is marked for lazy instantiation, this method will execute the closure and call
|
199
200
|
any registered callbacks.
|
200
201
|
*/
|
201
|
-
_executeLazilyInstantiatedModule: function(moduleName, targetName, methodName){
|
202
|
+
_executeLazilyInstantiatedModule: function (moduleName, targetName, methodName) {
|
202
203
|
var lazyInfo = SC.LAZY_INSTANTIATION[moduleName];
|
203
204
|
var target;
|
204
205
|
var method;
|
@@ -213,7 +214,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
213
214
|
// Iterate through each function associated with this module, and attempt to execute it.
|
214
215
|
try {
|
215
216
|
lazyInfo[idx]();
|
216
|
-
} catch(e) {
|
217
|
+
} catch (e) {
|
217
218
|
SC.Logger.error("SC.Module: Failed to lazily instatiate entry for '%@'".fmt(moduleName));
|
218
219
|
}
|
219
220
|
}
|
@@ -236,7 +237,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
236
237
|
|
237
238
|
@param {Hash} module the module to evaluate
|
238
239
|
*/
|
239
|
-
_evaluateStringLoadedModule: function(module) {
|
240
|
+
_evaluateStringLoadedModule: function (module) {
|
240
241
|
var moduleSource = module.source;
|
241
242
|
|
242
243
|
// so, force a run loop.
|
@@ -267,8 +268,8 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
267
268
|
|
268
269
|
@param {String} moduleName the name of the module whose CSS should be loaded
|
269
270
|
*/
|
270
|
-
_loadCSSForModule: function(moduleName) {
|
271
|
-
var head = document.getElementsByTagName('head')[0]
|
271
|
+
_loadCSSForModule: function (moduleName) {
|
272
|
+
var head = document.getElementsByTagName('head')[0];
|
272
273
|
var module = SC.MODULE_INFO[moduleName];
|
273
274
|
var styles = module.styles || [];
|
274
275
|
var len = styles.length;
|
@@ -276,32 +277,32 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
276
277
|
var el;
|
277
278
|
var idx;
|
278
279
|
|
279
|
-
if (!head) head = document.documentElement
|
280
|
+
if (!head) head = document.documentElement; // fix for Opera
|
280
281
|
len = styles.length;
|
281
282
|
|
282
283
|
for (idx = 0; idx < len; idx++) {
|
283
|
-
url = styles[idx]
|
284
|
+
url = styles[idx];
|
284
285
|
|
285
286
|
if (url.length > 0) {
|
286
287
|
if (SC.LOG_MODULE_LOADING) SC.debug("SC.Module: Loading CSS file in '%@' -> '%@'", moduleName, url);
|
287
288
|
|
288
289
|
// if we are on a retina device lets load the retina style sheet instead
|
289
290
|
if (window.devicePixelRatio > 1 || window.location.search.indexOf("2x") > -1) {
|
290
|
-
|
291
|
+
url = url.replace('.css', '@2x.css');
|
291
292
|
}
|
292
293
|
|
293
|
-
el = document.createElement('link')
|
294
|
-
el.setAttribute('href', url)
|
295
|
-
el.setAttribute('rel', "stylesheet")
|
296
|
-
el.setAttribute('type', "text/css")
|
297
|
-
head.appendChild(el)
|
294
|
+
el = document.createElement('link');
|
295
|
+
el.setAttribute('href', url);
|
296
|
+
el.setAttribute('rel', "stylesheet");
|
297
|
+
el.setAttribute('type', "text/css");
|
298
|
+
head.appendChild(el);
|
298
299
|
}
|
299
300
|
}
|
300
301
|
|
301
302
|
el = null;
|
302
303
|
},
|
303
304
|
|
304
|
-
_loadJavaScriptForModule: function(moduleName) {
|
305
|
+
_loadJavaScriptForModule: function (moduleName) {
|
305
306
|
var module = SC.MODULE_INFO[moduleName];
|
306
307
|
var el;
|
307
308
|
var url;
|
@@ -332,27 +333,27 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
332
333
|
if (url.length > 0) {
|
333
334
|
if (SC.LOG_MODULE_LOADING) SC.debug("SC.Module: Loading JavaScript file in '%@' -> '%@'", moduleName, url);
|
334
335
|
|
335
|
-
el = document.createElement('script')
|
336
|
-
el.setAttribute('type', "text/javascript")
|
337
|
-
el.setAttribute('src', url)
|
336
|
+
el = document.createElement('script');
|
337
|
+
el.setAttribute('type', "text/javascript");
|
338
|
+
el.setAttribute('src', url);
|
338
339
|
|
339
|
-
if (
|
340
|
-
el.
|
341
|
-
|
342
|
-
SC.
|
340
|
+
if (el.addEventListener) {
|
341
|
+
el.addEventListener('load', function () {
|
342
|
+
SC.run(function () {
|
343
|
+
SC.Module._moduleDidLoad(moduleName);
|
344
|
+
});
|
345
|
+
}, false);
|
346
|
+
} else if (el.readyState) {
|
347
|
+
el.onreadystatechange = function () {
|
348
|
+
if (this.readyState === 'complete' || this.readyState === 'loaded') {
|
349
|
+
SC.run(function () {
|
343
350
|
SC.Module._moduleDidLoad(moduleName);
|
344
351
|
});
|
345
352
|
}
|
346
353
|
};
|
347
|
-
} else {
|
348
|
-
el.onload = function() {
|
349
|
-
SC.run(function(){
|
350
|
-
SC.Module._moduleDidLoad(moduleName);
|
351
|
-
});
|
352
|
-
};
|
353
354
|
}
|
354
355
|
|
355
|
-
document.body.appendChild(el)
|
356
|
+
document.body.appendChild(el);
|
356
357
|
}
|
357
358
|
},
|
358
359
|
|
@@ -364,7 +365,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
364
365
|
@param {String} moduleName the name of the module being checked
|
365
366
|
@returns {Boolean} whether the dependencies are loaded
|
366
367
|
*/
|
367
|
-
_dependenciesMetForModule: function(moduleName) {
|
368
|
+
_dependenciesMetForModule: function (moduleName) {
|
368
369
|
var dependencies = SC.MODULE_INFO[moduleName].dependencies || [];
|
369
370
|
var idx, len = dependencies.length;
|
370
371
|
var dependencyName;
|
@@ -388,171 +389,171 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
388
389
|
Loads all unloaded dependencies for a module, then creates the <script> and <link> tags to
|
389
390
|
load the JavaScript and CSS for the module.
|
390
391
|
*/
|
391
|
-
_loadDependenciesForModule: function(moduleName) {
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
for (idx = 0; idx < len; idx++) {
|
404
|
-
requiredModuleName = dependencies[idx];
|
405
|
-
requiredModule = SC.MODULE_INFO[requiredModuleName];
|
406
|
-
|
407
|
-
// Try to find dependent module in MODULE_INFO
|
408
|
-
if (!requiredModule) {
|
409
|
-
throw new Error("SC.Module: could not find required module '%@' for module '%@'".fmt(requiredModuleName, moduleName));
|
410
|
-
} else {
|
392
|
+
_loadDependenciesForModule: function (moduleName) {
|
393
|
+
// Load module's dependencies first.
|
394
|
+
var moduleInfo = SC.MODULE_INFO[moduleName];
|
395
|
+
var log = SC.LOG_MODULE_LOADING;
|
396
|
+
var dependencies = moduleInfo.dependencies || [];
|
397
|
+
var dependenciesMet = YES;
|
398
|
+
var len = dependencies.length;
|
399
|
+
var idx;
|
400
|
+
var requiredModuleName;
|
401
|
+
var requiredModule;
|
402
|
+
var dependents;
|
411
403
|
|
412
|
-
|
413
|
-
|
414
|
-
|
404
|
+
for (idx = 0; idx < len; idx++) {
|
405
|
+
requiredModuleName = dependencies[idx];
|
406
|
+
requiredModule = SC.MODULE_INFO[requiredModuleName];
|
415
407
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
408
|
+
// Try to find dependent module in MODULE_INFO
|
409
|
+
if (!requiredModule) {
|
410
|
+
throw new Error("SC.Module: could not find required module '%@' for module '%@'".fmt(requiredModuleName, moduleName));
|
411
|
+
} else {
|
420
412
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
}
|
425
|
-
// Required module has not been loaded nor requested yet.
|
426
|
-
else {
|
427
|
-
dependenciesMet = NO ;
|
413
|
+
// Required module has been requested but hasn't loaded yet.
|
414
|
+
if (requiredModule.isLoading) {
|
415
|
+
dependenciesMet = NO;
|
428
416
|
|
429
|
-
|
430
|
-
|
431
|
-
|
417
|
+
dependents = requiredModule.dependents;
|
418
|
+
if (!dependents) requiredModule.dependents = dependents = [];
|
419
|
+
dependents.push(moduleName);
|
420
|
+
}
|
421
|
+
|
422
|
+
// Required module has already been loaded and evaluated, no need to worry about it.
|
423
|
+
else if (requiredModule.isReady) {
|
424
|
+
continue;
|
425
|
+
}
|
426
|
+
// Required module has not been loaded nor requested yet.
|
427
|
+
else {
|
428
|
+
dependenciesMet = NO;
|
432
429
|
|
433
|
-
|
430
|
+
// Register this as a dependent module (used by SC._moduleDidLoad()...)
|
431
|
+
dependents = requiredModule.dependents;
|
432
|
+
if (!dependents) requiredModule.dependents = dependents = [];
|
434
433
|
|
435
|
-
|
434
|
+
dependents.push(moduleName);
|
436
435
|
|
437
|
-
|
438
|
-
|
439
|
-
|
436
|
+
if (log) SC.debug("SC.Module: '%@' depends on '%@', loading dependency…", moduleName, requiredModuleName);
|
437
|
+
|
438
|
+
// Load dependencies
|
439
|
+
SC.Module.loadModule(requiredModuleName);
|
440
440
|
}
|
441
441
|
}
|
442
|
-
}
|
442
|
+
}
|
443
|
+
},
|
443
444
|
|
444
|
-
|
445
|
-
|
445
|
+
/**
|
446
|
+
@private
|
446
447
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
448
|
+
Calls an action on a target to notify the target that a module has loaded.
|
449
|
+
*/
|
450
|
+
_invokeCallback: function (moduleName, targetName, methodName, args) {
|
451
|
+
var method;
|
452
|
+
var target;
|
452
453
|
|
453
|
-
|
454
|
-
|
454
|
+
target = this._targetForTargetName(targetName);
|
455
|
+
method = this._methodForMethodNameInTarget(methodName, target);
|
455
456
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
457
|
+
// If we weren't able to find the callback, this module may be lazily instantiated and
|
458
|
+
// the callback won't exist until we execute the closure that it is wrapped in.
|
459
|
+
if (!method) {
|
460
|
+
if (SC.LAZY_INSTANTIATION[moduleName]) {
|
461
|
+
this._executeLazilyInstantiatedModule(moduleName, targetName, methodName);
|
461
462
|
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
}
|
463
|
+
target = this._targetForTargetName(targetName);
|
464
|
+
method = this._methodForMethodNameInTarget(methodName, target);
|
465
|
+
} else {
|
466
|
+
throw new Error("SC.Module: could not find callback for '%@'".fmt(moduleName));
|
467
467
|
}
|
468
|
+
}
|
468
469
|
|
469
|
-
|
470
|
-
|
471
|
-
|
470
|
+
if (!args) {
|
471
|
+
args = [];
|
472
|
+
}
|
472
473
|
|
473
|
-
|
474
|
-
|
474
|
+
// The first parameter passed to the callback is the name of the module.
|
475
|
+
args.unshift(moduleName);
|
475
476
|
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
method.apply(target, args);
|
481
|
-
});
|
482
|
-
} else {
|
477
|
+
// Invoke the callback. Wrap it in a run loop if we are not in a runloop already.
|
478
|
+
var needsRunLoop = !!SC.RunLoop.currentRunLoop;
|
479
|
+
if (needsRunLoop) {
|
480
|
+
SC.run(function () {
|
483
481
|
method.apply(target, args);
|
484
|
-
}
|
485
|
-
}
|
482
|
+
});
|
483
|
+
} else {
|
484
|
+
method.apply(target, args);
|
485
|
+
}
|
486
|
+
},
|
486
487
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
488
|
+
/** @private
|
489
|
+
Given a module name, iterates through all registered callbacks and calls them.
|
490
|
+
*/
|
491
|
+
_invokeCallbacksForModule: function (moduleName) {
|
492
|
+
var moduleInfo = SC.MODULE_INFO[moduleName], callbacks;
|
493
|
+
if (!moduleInfo) return; // shouldn't happen, but recover anyway
|
493
494
|
|
494
|
-
|
495
|
+
if (SC.LOG_MODULE_LOADING) SC.debug("SC.Module: Module '%@' has completed loading, invoking callbacks.", moduleName);
|
495
496
|
|
496
|
-
|
497
|
+
callbacks = moduleInfo.callbacks || [];
|
497
498
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
499
|
+
for (var idx = 0, len = callbacks.length; idx < len; ++idx) {
|
500
|
+
callbacks[idx]();
|
501
|
+
}
|
502
|
+
},
|
502
503
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
504
|
+
_evaluateAndInvokeCallbacks: function (moduleName) {
|
505
|
+
var moduleInfo = SC.MODULE_INFO;
|
506
|
+
var module = moduleInfo[moduleName];
|
507
|
+
var log = SC.LOG_MODULE_LOADING;
|
507
508
|
|
508
|
-
|
509
|
+
if (log) SC.debug("SC.Module: Evaluating and invoking callbacks for '%@'.", moduleName);
|
509
510
|
|
510
|
-
|
511
|
-
|
512
|
-
|
511
|
+
if (module.source) {
|
512
|
+
this._evaluateStringLoadedModule(module);
|
513
|
+
}
|
513
514
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
515
|
+
// this is ugly, but a module evaluated late like this won't be done instantiating
|
516
|
+
// until the end of a run loop. Also, the code here is not structured in a way that makes
|
517
|
+
// it easy to "add a step" before saying a module is ready. And finally, invokeLater doesn't
|
518
|
+
// accept arguments; hence, the closure.
|
519
|
+
module.isWaitingForRunLoop = YES;
|
520
|
+
this.invokeLast(function () {
|
521
|
+
module.isReady = YES;
|
522
|
+
this._moduleDidBecomeReady(moduleName);
|
523
|
+
});
|
524
|
+
},
|
524
525
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
526
|
+
_moduleDidBecomeReady: function (moduleName) {
|
527
|
+
var moduleInfo = SC.MODULE_INFO;
|
528
|
+
var module = moduleInfo[moduleName];
|
529
|
+
var log = SC.LOG_MODULE_LOADING;
|
529
530
|
|
530
|
-
|
531
|
+
module.isWaitingForRunLoop = NO;
|
531
532
|
|
532
|
-
|
533
|
-
|
533
|
+
if (SC.isReady) {
|
534
|
+
SC.Module._invokeCallbacksForModule(moduleName);
|
535
|
+
delete module.callbacks;
|
536
|
+
} else {
|
537
|
+
SC.ready(SC, function () {
|
538
|
+
SC.Module._invokeCallbacksForModule(moduleName);
|
534
539
|
delete module.callbacks;
|
535
|
-
}
|
536
|
-
|
537
|
-
SC.Module._invokeCallbacksForModule(moduleName) ;
|
538
|
-
delete module.callbacks;
|
539
|
-
});
|
540
|
-
}
|
540
|
+
});
|
541
|
+
}
|
541
542
|
|
542
|
-
|
543
|
-
|
544
|
-
|
543
|
+
// for each dependent module, try and load them again...
|
544
|
+
var dependents = module.dependents || [];
|
545
|
+
var dependentName, dependent;
|
545
546
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
}
|
547
|
+
for (var idx = 0, len = dependents.length; idx < len; idx++) {
|
548
|
+
dependentName = dependents[idx];
|
549
|
+
dependent = moduleInfo[dependentName];
|
550
|
+
if (dependent.isLoaded && this._dependenciesMetForModule(dependentName)) {
|
551
|
+
if (log) SC.debug("SC.Module: Now that %@ has loaded, all dependencies for a dependent %@ are met.", moduleName, dependentName);
|
552
|
+
this._evaluateAndInvokeCallbacks(dependentName);
|
553
553
|
}
|
554
|
+
}
|
554
555
|
|
555
|
-
|
556
|
+
},
|
556
557
|
|
557
558
|
/** @private
|
558
559
|
Called when the JavaScript for a module finishes loading.
|
@@ -562,8 +563,8 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
562
563
|
can continue loading.
|
563
564
|
|
564
565
|
@param moduleName {String} the name of the module that just loaded
|
565
|
-
*/
|
566
|
-
_moduleDidLoad: function(moduleName) {
|
566
|
+
*/
|
567
|
+
_moduleDidLoad: function (moduleName) {
|
567
568
|
var module = SC.MODULE_INFO[moduleName];
|
568
569
|
var log = SC.LOG_MODULE_LOADING;
|
569
570
|
var dependenciesMet;
|
@@ -573,18 +574,18 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
573
574
|
|
574
575
|
if (!module) {
|
575
576
|
if (log) SC.debug("SC._moduleDidLoad() called for unknown module '@'.", moduleName);
|
576
|
-
module = SC.MODULE_INFO[moduleName] = { isLoaded: YES, isReady: YES }
|
577
|
+
module = SC.MODULE_INFO[moduleName] = { isLoaded: YES, isReady: YES };
|
577
578
|
return;
|
578
579
|
}
|
579
580
|
|
580
581
|
if (module.isLoaded) {
|
581
582
|
if (log) SC.debug("SC._moduleDidLoad() called more than once for module '%@'. Skipping.", moduleName);
|
582
|
-
return
|
583
|
+
return;
|
583
584
|
}
|
584
585
|
|
585
586
|
// Remember that we're loaded.
|
586
|
-
delete module.isLoading
|
587
|
-
module.isLoaded = YES
|
587
|
+
delete module.isLoading;
|
588
|
+
module.isLoaded = YES;
|
588
589
|
|
589
590
|
if (!module.isPrefetching) {
|
590
591
|
dependenciesMet = this._dependenciesMetForModule(moduleName);
|
@@ -607,7 +608,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
607
608
|
@param {String|Object} targetName the string or object representing the target
|
608
609
|
@returns Object
|
609
610
|
*/
|
610
|
-
_targetForTargetName: function(targetName){
|
611
|
+
_targetForTargetName: function (targetName) {
|
611
612
|
if (SC.typeOf(targetName) === SC.T_STRING) {
|
612
613
|
return SC.objectForPropertyPath(targetName);
|
613
614
|
}
|
@@ -624,7 +625,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
624
625
|
@param {Object} target the target from which to retrieve the method
|
625
626
|
@returns Object
|
626
627
|
*/
|
627
|
-
_methodForMethodNameInTarget: function(methodName, target){
|
628
|
+
_methodForMethodNameInTarget: function (methodName, target) {
|
628
629
|
if (SC.typeOf(methodName) === SC.T_STRING) {
|
629
630
|
return SC.objectForPropertyPath(methodName, target);
|
630
631
|
}
|
@@ -640,13 +641,13 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
640
641
|
/**
|
641
642
|
Call this in order to prevent expensive tasks from occurring at inopportune times.
|
642
643
|
*/
|
643
|
-
suspend: function() {
|
644
|
+
suspend: function () {
|
644
645
|
|
645
646
|
//Increment the suspension count, to support nested suspend()/resume() pairs.
|
646
647
|
//We only do anything if the suspend count ends up at 1, as that implies it's
|
647
648
|
//the first suspend() call.
|
648
|
-
this._suspendCount = (this._suspendCount||0)+1;
|
649
|
-
if(this._suspendCount!==1) return;
|
649
|
+
this._suspendCount = (this._suspendCount || 0) + 1;
|
650
|
+
if (this._suspendCount !== 1) return;
|
650
651
|
|
651
652
|
//Yummy variables.
|
652
653
|
var methods = this.get('methodsForSuspend'),
|
@@ -654,12 +655,12 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
654
655
|
|
655
656
|
//Now we go through the list of methods to suspend, and overwrite them with
|
656
657
|
//versions that will buffer their calls in a _bufferedCalls array.
|
657
|
-
for(i=0; key=methods[i]; i++) {
|
658
|
-
|
658
|
+
for (i = 0; (key = methods[i]); i++) {
|
659
|
+
//jshint loopfunc: true
|
659
660
|
//Ensure the replacement function exists at a key where it'll be cached.
|
660
|
-
if(!this[replaceKey="__replacement_"+key+"__"]) {
|
661
|
-
(this[replaceKey] = function() {
|
662
|
-
(this._bufferedCalls||(this._bufferedCalls=[])).push({
|
661
|
+
if (!this[replaceKey = "__replacement_" + key + "__"]) {
|
662
|
+
(this[replaceKey] = function () {
|
663
|
+
(this._bufferedCalls || (this._bufferedCalls = [])).push({
|
663
664
|
method: arguments.callee.methodName,
|
664
665
|
arguments: arguments
|
665
666
|
});
|
@@ -667,7 +668,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
667
668
|
}
|
668
669
|
|
669
670
|
//Ensure the original function exists at a key where it'll be cached.
|
670
|
-
if(!this[saveKey="__saved_"+key+"__"]) this[saveKey] = this[key];
|
671
|
+
if (!this[saveKey = "__saved_" + key + "__"]) this[saveKey] = this[key];
|
671
672
|
|
672
673
|
//Ensure that the replacement function exists where the rest of the
|
673
674
|
//code expects the original.
|
@@ -680,19 +681,19 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
680
681
|
finally perform any calls that may have occurred during suspension. Calls
|
681
682
|
will run in the order they were received.
|
682
683
|
*/
|
683
|
-
resume: function() {
|
684
|
+
resume: function () {
|
684
685
|
|
685
686
|
//First, we need to decrement the suspension count, and warn if the suspension
|
686
687
|
//count implied that we weren't already suspended. Furthermore, if the suspend
|
687
688
|
//count is not zero, then we haven't tackled the last suspend() call with a resume(),
|
688
689
|
//and should therefore not resume.
|
689
|
-
this._suspendCount = (this._suspendCount||0)-1;
|
690
|
-
if(this._suspendCount<0) {
|
690
|
+
this._suspendCount = (this._suspendCount || 0) - 1;
|
691
|
+
if (this._suspendCount < 0) {
|
691
692
|
SC.warn("SC.Module.resume() was called without SC.Module having been in a suspended state. Call aborted.");
|
692
693
|
this._suspendCount = 0;
|
693
694
|
return;
|
694
695
|
}
|
695
|
-
if(this._suspendCount>0) return;
|
696
|
+
if (this._suspendCount > 0) return;
|
696
697
|
|
697
698
|
//Yummy variables.
|
698
699
|
var methods = this.get('methodsForSuspend'),
|
@@ -700,13 +701,13 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
700
701
|
key, i, method, call;
|
701
702
|
|
702
703
|
//Restore the original methods to where they belong for normal functionality.
|
703
|
-
for(i=0; (key=methods[i]); i++) this[key] = this["__saved_"+key+"__"];
|
704
|
+
for (i = 0; (key = methods[i]); i++) this[key] = this["__saved_" + key + "__"];
|
704
705
|
|
705
706
|
//Perform any buffered calls that built up during the suspended period.
|
706
|
-
for(i=0; call=calls&&calls[i]; i++) this[call.method].apply(this,call.arguments);
|
707
|
+
for (i = 0; (call = calls) && calls[i]; i++) this[call.method].apply(this, call.arguments);
|
707
708
|
|
708
709
|
//Clear the list of calls, so subsequent resume() calls won't flush them again.
|
709
|
-
if(calls) calls.length = 0;
|
710
|
+
if (calls) calls.length = 0;
|
710
711
|
}
|
711
712
|
});
|
712
713
|
|
@@ -714,7 +715,7 @@ SC.Module = SC.Object.create(/** @scope SC.Module */ {
|
|
714
715
|
Inspect the list of modules and, for every prefetched module, create a
|
715
716
|
background task to load the module when the user remains idle.
|
716
717
|
*/
|
717
|
-
SC.ready(function() {
|
718
|
+
SC.ready(function () {
|
718
719
|
var moduleInfo = SC.MODULE_INFO;
|
719
720
|
var moduleName;
|
720
721
|
var module;
|
@@ -736,7 +737,7 @@ SC.ready(function() {
|
|
736
737
|
|
737
738
|
SC.Module.PrefetchModuleTask = SC.Task.extend({
|
738
739
|
prefetchedModuleName: null,
|
739
|
-
run: function() {
|
740
|
+
run: function () {
|
740
741
|
SC.Module.prefetchModule(this.prefetchedModuleName);
|
741
742
|
}
|
742
743
|
});
|