sproutcore 1.0.1037 → 1.0.1042
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +31 -0
- data/README.txt +3 -1
- data/Rakefile +11 -4
- data/VERSION.yml +3 -3
- data/buildtasks/build.rake +5 -0
- data/frameworks/sproutcore/Buildfile +3 -1
- data/frameworks/sproutcore/frameworks/animation/Buildfile +3 -0
- data/frameworks/sproutcore/frameworks/animation/LICENSE +25 -0
- data/frameworks/sproutcore/frameworks/animation/README.md +102 -0
- data/frameworks/sproutcore/frameworks/animation/core.js +934 -0
- data/frameworks/sproutcore/frameworks/animation/tests/core.js +65 -0
- data/frameworks/sproutcore/frameworks/datastore/models/record.js +28 -16
- data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +5 -2
- data/frameworks/sproutcore/frameworks/datastore/system/many_array.js +4 -0
- data/frameworks/sproutcore/frameworks/datastore/system/query.js +27 -13
- data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +36 -6
- data/frameworks/sproutcore/frameworks/datastore/system/store.js +7 -7
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +2 -1
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +13 -0
- data/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +250 -0
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/list_item.css +0 -12
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/menu_item_view.css +3 -6
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/panel.css +0 -8
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/picker.css +0 -4
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +1 -0
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/well.css +0 -1
- data/frameworks/sproutcore/frameworks/desktop/mixins/border.js +1 -1
- data/frameworks/sproutcore/frameworks/desktop/panes/alert.js +2 -1
- data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +11 -4
- data/frameworks/sproutcore/frameworks/desktop/panes/palette.js +2 -0
- data/frameworks/sproutcore/frameworks/desktop/panes/panel.js +1 -5
- data/frameworks/sproutcore/frameworks/desktop/panes/picker.js +24 -23
- data/frameworks/sproutcore/frameworks/desktop/panes/select_button.js +91 -60
- data/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +124 -24
- data/frameworks/sproutcore/frameworks/desktop/system/drag.js +5 -5
- data/frameworks/sproutcore/frameworks/desktop/system/root_responder.js +33 -25
- data/frameworks/sproutcore/frameworks/desktop/tests/panes/pane_page.js +41 -0
- data/frameworks/sproutcore/frameworks/desktop/tests/panes/select_button/methods.js +30 -1
- data/frameworks/sproutcore/frameworks/desktop/tests/panes/select_button/ui.js +13 -0
- data/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/ui.js +27 -21
- data/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +81 -1
- data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +3 -4
- data/frameworks/sproutcore/frameworks/desktop/views/button.js +65 -36
- data/frameworks/sproutcore/frameworks/desktop/views/collection.js +4 -7
- data/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +8 -4
- data/frameworks/sproutcore/frameworks/desktop/views/list.js +1 -1
- data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +38 -5
- data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +5 -1
- data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +4 -1
- data/frameworks/sproutcore/frameworks/desktop/views/progress.js +19 -13
- data/frameworks/sproutcore/frameworks/desktop/views/radio.js +30 -2
- data/frameworks/sproutcore/frameworks/desktop/views/scroll.js +2 -3
- data/frameworks/sproutcore/frameworks/desktop/views/segmented.js +14 -17
- data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +5 -3
- data/frameworks/sproutcore/frameworks/desktop/views/slider.js +4 -2
- data/frameworks/sproutcore/frameworks/desktop/views/split.js +58 -59
- data/frameworks/sproutcore/frameworks/desktop/views/tab.js +2 -1
- data/frameworks/sproutcore/frameworks/desktop/views/well.js +1 -1
- data/frameworks/sproutcore/frameworks/foundation/core.js +6 -0
- data/frameworks/sproutcore/frameworks/foundation/english.lproj/view.css +2 -1
- data/frameworks/sproutcore/frameworks/foundation/mixins/button.js +33 -30
- data/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +8 -4
- data/frameworks/sproutcore/frameworks/foundation/mixins/string.js +15 -10
- data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +61 -12
- data/frameworks/sproutcore/frameworks/foundation/system/bundle.js +2 -1
- data/frameworks/sproutcore/frameworks/foundation/system/core_query.js +151 -131
- data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +29 -23
- data/frameworks/sproutcore/frameworks/foundation/system/event.js +18 -10
- data/frameworks/sproutcore/frameworks/foundation/system/page.js +7 -5
- data/frameworks/sproutcore/frameworks/foundation/system/ready.js +1 -0
- data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +9 -6
- data/frameworks/sproutcore/frameworks/foundation/system/request.js +41 -6
- data/frameworks/sproutcore/frameworks/foundation/system/response.js +89 -24
- data/frameworks/sproutcore/frameworks/foundation/system/routes.js +1 -1
- data/frameworks/sproutcore/frameworks/foundation/system/utils.js +0 -1
- data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/array_case.js +27 -8
- data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_core.js +6 -6
- data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_style.js +2 -2
- data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +65 -3
- data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/append_remove.js +1 -1
- data/frameworks/sproutcore/frameworks/foundation/tests/views/view/convertLayouts.js +145 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/views/view/didAppendToDocument.js +48 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/views/view/nextValidKeyView.js +91 -0
- data/frameworks/sproutcore/frameworks/foundation/validators/number.js +9 -5
- data/frameworks/sproutcore/frameworks/foundation/views/field.js +16 -14
- data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +89 -67
- data/frameworks/sproutcore/frameworks/foundation/views/view.js +221 -73
- data/frameworks/sproutcore/frameworks/runtime/core.js +43 -22
- data/frameworks/sproutcore/frameworks/runtime/mixins/array.js +6 -0
- data/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +1 -1
- data/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +53 -34
- data/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +7 -3
- data/frameworks/sproutcore/frameworks/runtime/system/binding.js +19 -19
- data/frameworks/sproutcore/frameworks/runtime/system/logger.js +132 -88
- data/frameworks/sproutcore/frameworks/runtime/system/object.js +15 -9
- data/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +6 -0
- data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +69 -0
- data/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +14 -2
- data/frameworks/sproutcore/license.js +3 -1
- data/frameworks/sproutcore/themes/standard_theme/Source/sc-theme-repeat-x.psd +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/icons/mini_222222.png +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/icons/mini_454545.png +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/icons/mini_888888.png +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/icons/mini_ffffff.png +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/panels/sprite-x.png +0 -0
- data/frameworks/sproutcore/{frameworks/desktop → themes/standard_theme}/english.lproj/images/panels/sprite-y.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-repeat-x.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-ysprite.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/list_item.css +15 -1
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/menu_item_view.css +9 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panel.css +33 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/picker.css +17 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +9 -6
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/tab.css +0 -4
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/well.css +36 -0
- data/gen/controller/templates/controllers/@filename@.js +1 -1
- data/lib/sproutcore/builders/minify.rb +45 -13
- data/lib/sproutcore/helpers/static_helper.rb +2 -2
- data/lib/sproutcore/models/manifest_entry.rb +42 -1
- data/lib/sproutcore/tools/build.rb +18 -2
- data/spec/lib/models/manifest_entry/hyperdomain_prefix.rb +34 -0
- data/vendor/yui-compressor/SCyuicompressor-2.4.2.jar +0 -0
- metadata +28 -22
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-fat.jpg +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-thin.jpg +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-edge.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-left-corner.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-right-corner.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/left-edge.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/overlay.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/right-edge.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-edge.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-left-corner.png +0 -0
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-right-corner.png +0 -0
@@ -252,32 +252,34 @@ SC.DateTime = SC.Object.extend(SC.Freezable, SC.Copyable,
|
|
252
252
|
like the C strftime function.
|
253
253
|
|
254
254
|
The format parameter can contain the following characters:
|
255
|
-
%a - The abbreviated weekday name (``Sun'')
|
256
|
-
%A - The full weekday name (``Sunday'')
|
257
|
-
%b - The abbreviated month name (``Jan'')
|
258
|
-
%B - The full month name (``January'')
|
259
|
-
%c - The preferred local date and time representation
|
260
|
-
%d - Day of the month (01..31)
|
261
|
-
%
|
262
|
-
%
|
263
|
-
%
|
264
|
-
%
|
265
|
-
%
|
266
|
-
%
|
267
|
-
%
|
268
|
-
%
|
255
|
+
- %a - The abbreviated weekday name (``Sun'')
|
256
|
+
- %A - The full weekday name (``Sunday'')
|
257
|
+
- %b - The abbreviated month name (``Jan'')
|
258
|
+
- %B - The full month name (``January'')
|
259
|
+
- %c - The preferred local date and time representation
|
260
|
+
- %d - Day of the month (01..31)
|
261
|
+
- %h - Hour of the day, 24-hour clock (0..23)
|
262
|
+
- %H - Hour of the day, 24-hour clock (00..23)
|
263
|
+
- %i - Hour of the day, 12-hour clock (1..12)
|
264
|
+
- %I - Hour of the day, 12-hour clock (01..12)
|
265
|
+
- %j - Day of the year (001..366)
|
266
|
+
- %m - Month of the year (01..12)
|
267
|
+
- %M - Minute of the hour (00..59)
|
268
|
+
- %p - Meridian indicator (``AM'' or ``PM'')
|
269
|
+
- %S - Second of the minute (00..60)
|
270
|
+
- %U - Week number of the current year,
|
269
271
|
starting with the first Sunday as the first
|
270
272
|
day of the first week (00..53)
|
271
|
-
%W - Week number of the current year,
|
273
|
+
- %W - Week number of the current year,
|
272
274
|
starting with the first Monday as the first
|
273
275
|
day of the first week (00..53)
|
274
|
-
%w - Day of the week (Sunday is 0, 0..6)
|
275
|
-
%x - Preferred representation for the date alone, no time
|
276
|
-
%X - Preferred representation for the time alone, no date
|
277
|
-
%y - Year without a century (00..99)
|
278
|
-
%Y - Year with century
|
279
|
-
%Z - Time zone (ISO 8601 formatted)
|
280
|
-
%% - Literal ``%'' character
|
276
|
+
- %w - Day of the week (Sunday is 0, 0..6)
|
277
|
+
- %x - Preferred representation for the date alone, no time
|
278
|
+
- %X - Preferred representation for the time alone, no date
|
279
|
+
- %y - Year without a century (00..99)
|
280
|
+
- %Y - Year with century
|
281
|
+
- %Z - Time zone (ISO 8601 formatted)
|
282
|
+
- %% - Literal ``%'' character
|
281
283
|
|
282
284
|
@param {String} format the format string
|
283
285
|
@return {String} the formatted string
|
@@ -783,7 +785,11 @@ SC.DateTime.mixin(SC.Comparable,
|
|
783
785
|
case 'B': return this.monthNames[this._get('month')-1];
|
784
786
|
case 'c': return this._date.toString();
|
785
787
|
case 'd': return this._pad(this._get('day'));
|
788
|
+
case 'h': return this._get('hour');
|
786
789
|
case 'H': return this._pad(this._get('hour'));
|
790
|
+
case 'i':
|
791
|
+
var hour = this._get('hour');
|
792
|
+
return (hour === 12 || hour === 0) ? 12 : (hour + 12) % 12;
|
787
793
|
case 'I':
|
788
794
|
var hour = this._get('hour');
|
789
795
|
return this._pad((hour === 12 || hour === 0) ? 12 : (hour + 12) % 12);
|
@@ -897,7 +903,7 @@ if (SC.RecordAttribute && !SC.RecordAttribute.transforms[SC.guidFor(SC.DateTime)
|
|
897
903
|
Convert a String to a DateTime
|
898
904
|
*/
|
899
905
|
to: function(str, attr) {
|
900
|
-
if (SC.none(str)) return str;
|
906
|
+
if (SC.none(str) || SC.instanceOf(str, SC.DateTime)) return str;
|
901
907
|
var format = attr.get('format');
|
902
908
|
return SC.DateTime.parse(str, format ? format : SC.DateTime.recordFormat);
|
903
909
|
},
|
@@ -184,12 +184,12 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
|
|
184
184
|
this.add(e, eventType, target, method, context);
|
185
185
|
}, this);
|
186
186
|
return this;
|
187
|
-
} else elem = elem
|
187
|
+
} else elem = elem[0];
|
188
188
|
}
|
189
189
|
if (!elem) return this; // nothing to do
|
190
190
|
|
191
191
|
// cannot register events on text nodes, etc.
|
192
|
-
if ( elem.nodeType
|
192
|
+
if ( elem.nodeType === 3 || elem.nodeType === 8 ) return SC.Event;
|
193
193
|
|
194
194
|
// For whatever reason, IE has trouble passing the window object
|
195
195
|
// around, causing it to be cloned in the process
|
@@ -260,12 +260,12 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
|
|
260
260
|
this.remove(e, eventType, target, method);
|
261
261
|
}, this);
|
262
262
|
return this;
|
263
|
-
} else elem = elem
|
263
|
+
} else elem = elem[0];
|
264
264
|
}
|
265
265
|
if (!elem) return this; // nothing to do
|
266
266
|
|
267
267
|
// don't do events on text and comment nodes
|
268
|
-
if ( elem.nodeType
|
268
|
+
if ( elem.nodeType === 3 || elem.nodeType === 8 ) return SC.Event;
|
269
269
|
|
270
270
|
// For whatever reason, IE has trouble passing the window object
|
271
271
|
// around, causing it to be cloned in the process
|
@@ -389,18 +389,18 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
|
|
389
389
|
this.trigger(e, eventType, args, donative);
|
390
390
|
}, this);
|
391
391
|
return this;
|
392
|
-
} else elem = elem
|
392
|
+
} else elem = elem[0];
|
393
393
|
}
|
394
394
|
if (!elem) return this; // nothing to do
|
395
395
|
|
396
396
|
// don't do events on text and comment nodes
|
397
|
-
if ( elem.nodeType
|
397
|
+
if ( elem.nodeType === 3 || elem.nodeType === 8 ) return undefined;
|
398
398
|
|
399
399
|
// Normalize to an array
|
400
400
|
args = SC.A(args) ;
|
401
401
|
|
402
402
|
var ret, fn = SC.typeOf(elem[eventType] || null) === SC.T_FUNCTION ,
|
403
|
-
event, current, onfoo;
|
403
|
+
event, current, onfoo, isClick;
|
404
404
|
|
405
405
|
// Get the event to pass, creating a fake one if necessary
|
406
406
|
event = args[0];
|
@@ -690,7 +690,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
|
|
690
690
|
|
691
691
|
/** @private Take an incoming event and convert it to a normalized event. */
|
692
692
|
normalizeEvent: function(event) {
|
693
|
-
if (event
|
693
|
+
if (event === window.event) {
|
694
694
|
// IE can't do event.normalized on an Event object
|
695
695
|
return SC.Event.create(event) ;
|
696
696
|
} else {
|
@@ -768,8 +768,16 @@ SC.Event.prototype = {
|
|
768
768
|
normalized: YES,
|
769
769
|
|
770
770
|
/** Returns the pressed character (found in this.which) as a string. */
|
771
|
-
getCharString: function() {
|
772
|
-
|
771
|
+
getCharString: function() {
|
772
|
+
if(SC.browser.msie){
|
773
|
+
if(this.keyCode == 8 || this.keyCode == 9 || (this.keyCode>=37 && this.keyCode<=40)){
|
774
|
+
return String.fromCharCode(0);
|
775
|
+
}else{
|
776
|
+
return (this.keyCode>0) ? String.fromCharCode(this.keyCode) : null;
|
777
|
+
}
|
778
|
+
}else{
|
779
|
+
return (this.charCode>0) ? String.fromCharCode(this.charCode) : null;
|
780
|
+
}
|
773
781
|
},
|
774
782
|
|
775
783
|
/** Returns character codes for the event. The first value is the normalized code string, with any shift or ctrl characters added to the begining. The second value is the char string by itself.
|
@@ -41,7 +41,7 @@ SC.Page = SC.Object.extend(
|
|
41
41
|
this[key] = value = value.create({ page: this }) ;
|
42
42
|
if (!this.get('inDesignMode')) value.awake() ;
|
43
43
|
return value ;
|
44
|
-
} else return sc_super()
|
44
|
+
} else return sc_super();
|
45
45
|
},
|
46
46
|
|
47
47
|
/**
|
@@ -54,9 +54,10 @@ SC.Page = SC.Object.extend(
|
|
54
54
|
*/
|
55
55
|
awake: function() {
|
56
56
|
// step through all views and build them
|
57
|
-
|
57
|
+
var value, key;
|
58
|
+
for(key in this) {
|
58
59
|
if (!this.hasOwnProperty(key)) continue ;
|
59
|
-
|
60
|
+
value = this[key] ;
|
60
61
|
if (value && value.isViewClass) {
|
61
62
|
this[key] = value = value.create({ page: this }) ;
|
62
63
|
}
|
@@ -78,9 +79,10 @@ SC.Page = SC.Object.extend(
|
|
78
79
|
Applies a localization to every view builder defined on the page. You must call this before you construct a view to apply the localization.
|
79
80
|
*/
|
80
81
|
loc: function(locs) {
|
81
|
-
|
82
|
+
var view, key;
|
83
|
+
for(key in locs) {
|
82
84
|
if (!locs.hasOwnProperty(key)) continue ;
|
83
|
-
|
85
|
+
view = this[key] ;
|
84
86
|
if (!view || !view.isViewClass) continue ;
|
85
87
|
view.loc(locs[key]);
|
86
88
|
}
|
@@ -92,6 +92,7 @@ SC.mixin({
|
|
92
92
|
// Only call once
|
93
93
|
if (SC.isReady) return ;
|
94
94
|
if (typeof SC.mapDisplayNames === SC.T_FUNCTION) SC.mapDisplayNames();
|
95
|
+
if (typeof SC.addInvokeOnceLastDebuggingInfo === SC.T_FUNCTION) SC.addInvokeOnceLastDebuggingInfo();
|
95
96
|
|
96
97
|
// setup locale
|
97
98
|
SC.Locale.createCurrentLocale();
|
@@ -297,6 +297,8 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
297
297
|
var elem = this._elem,
|
298
298
|
mode = this.updateMode,
|
299
299
|
key, value, styles, factory, cur, next, before;
|
300
|
+
|
301
|
+
this._innerHTMLReplaced = NO;
|
300
302
|
|
301
303
|
if (!elem) {
|
302
304
|
// throw "Cannot update context because there is no source element";
|
@@ -309,6 +311,7 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
309
311
|
|
310
312
|
// replace innerHTML
|
311
313
|
if (this.length>0) {
|
314
|
+
this._innerHTMLReplaced = YES;
|
312
315
|
if (mode === SC.MODE_REPLACE) {
|
313
316
|
elem.innerHTML = this.join();
|
314
317
|
} else {
|
@@ -398,9 +401,9 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
398
401
|
// generate opening tag.
|
399
402
|
|
400
403
|
// get attributes first. Copy in className + styles...
|
401
|
-
var tag = this._TAG_ARRAY, pair, joined, key
|
402
|
-
|
403
|
-
|
404
|
+
var tag = this._TAG_ARRAY, pair, joined, key ,
|
405
|
+
attrs = this._attrs, className = this._classNames,
|
406
|
+
id = this._id, styles = this._styles;
|
404
407
|
|
405
408
|
// add tag to tag array
|
406
409
|
tag[0] = '<'; tag[1] = this._tagName ;
|
@@ -422,7 +425,7 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
422
425
|
pair[1] = styles[key];
|
423
426
|
if (pair[1] === null) continue; // skip empty styles
|
424
427
|
|
425
|
-
if(typeof pair[1] === SC.T_NUMBER) pair[1] =
|
428
|
+
if(typeof pair[1] === SC.T_NUMBER) pair[1] = pair[1]+"px";
|
426
429
|
joined.push(pair.join(': '));
|
427
430
|
}
|
428
431
|
attrs.style = joined.join('; ') ;
|
@@ -482,7 +485,7 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
482
485
|
},
|
483
486
|
|
484
487
|
/**
|
485
|
-
Generates a with the passed options. Like calling context.begin().end().
|
488
|
+
Generates a tag with the passed options. Like calling context.begin().end().
|
486
489
|
|
487
490
|
@param {String} tagName optional tag name. default 'div'
|
488
491
|
@param {Hash} opts optional tag options. defaults to empty options.
|
@@ -695,7 +698,7 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
|
|
695
698
|
// CSS Styles Support
|
696
699
|
//
|
697
700
|
|
698
|
-
_STYLE_REGEX: /\s*([^:\s]+)\s*:\s*([
|
701
|
+
_STYLE_REGEX: /\s*([^:\s]+)\s*:\s*([^;]+)\s*;?/g,
|
699
702
|
|
700
703
|
/**
|
701
704
|
Retrieves or sets the current styles for the outer tag. If you retrieve
|
@@ -13,7 +13,7 @@ sc_require('system/response');
|
|
13
13
|
Implements support for Ajax requests using XHR, JSON-P and other prototcols.
|
14
14
|
|
15
15
|
SC.Request is much like an inverted version of the request/response objects
|
16
|
-
you receive when
|
16
|
+
you receive when implementing HTTP servers.
|
17
17
|
|
18
18
|
To send a request, you just need to create your request object, configure
|
19
19
|
your options, and call send() to initiate the request.
|
@@ -101,6 +101,21 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
101
101
|
*/
|
102
102
|
type: 'GET',
|
103
103
|
|
104
|
+
/**
|
105
|
+
An optional timeout value of the request, in milliseconds. The timer
|
106
|
+
begins when SC.Response#fire is actually invoked by the request manager
|
107
|
+
and not necessarily when SC.Request#send is invoked. If this timeout is
|
108
|
+
reached before a response is received, the equivalent of
|
109
|
+
SC.Request.manager#cancel() will be invoked on the SC.Response instance
|
110
|
+
and the didTimeout() callback will be called.
|
111
|
+
|
112
|
+
An exception will be thrown if you try to invoke send() on a request that
|
113
|
+
has both a timeout and isAsyncronous set to NO.
|
114
|
+
|
115
|
+
@property {Number}
|
116
|
+
*/
|
117
|
+
timeout: null,
|
118
|
+
|
104
119
|
/**
|
105
120
|
The body of the request. May be an object is isJSON or isXML is set,
|
106
121
|
otherwise should be a string.
|
@@ -149,9 +164,9 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
149
164
|
|
150
165
|
/**
|
151
166
|
Invoked when a response has been received but not yet processed. This is
|
152
|
-
your chance to
|
153
|
-
to continue processing the response call response.cancel().
|
154
|
-
|
167
|
+
your chance to fix up the response based on the results. If you don't
|
168
|
+
want to continue processing the response call response.cancel().
|
169
|
+
|
155
170
|
@param {SC.Response} response the response
|
156
171
|
@returns {void}
|
157
172
|
*/
|
@@ -168,11 +183,21 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
168
183
|
*/
|
169
184
|
didReceive: function(request, response) {},
|
170
185
|
|
186
|
+
/**
|
187
|
+
Invoked when a request times out before a response has been received, as
|
188
|
+
determined by the 'timeout' property. Note that if a request times out,
|
189
|
+
neither willReceive() nor didReceive() will be called.
|
190
|
+
|
191
|
+
@param {SC.Response} response the response
|
192
|
+
@returns {void}
|
193
|
+
*/
|
194
|
+
didTimeout: function(request, response) {},
|
195
|
+
|
171
196
|
// ..........................................................
|
172
197
|
// HELPER METHODS
|
173
198
|
//
|
174
199
|
|
175
|
-
COPY_KEYS: 'isAsynchronous isJSON isXML address type body responseClass willSend didSend willReceive didReceive'.w(),
|
200
|
+
COPY_KEYS: 'isAsynchronous isJSON isXML address type timeout body responseClass willSend didSend willReceive didReceive'.w(),
|
176
201
|
|
177
202
|
/**
|
178
203
|
Returns a copy of the current request. This will only copy certain
|
@@ -291,6 +316,16 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
291
316
|
@returns {SC.Response} new response object
|
292
317
|
*/
|
293
318
|
send: function(body) {
|
319
|
+
// Sanity-check: Be sure a timeout value was not specified if the request
|
320
|
+
// is synchronous (because it wouldn't work).
|
321
|
+
var timeout = this.get('timeout');
|
322
|
+
if (timeout) {
|
323
|
+
if (!this.get('isAsynchronous')) throw "Timeout values cannot be used with synchronous requests";
|
324
|
+
}
|
325
|
+
else if (timeout === 0) {
|
326
|
+
throw "The timeout value must either not be specified or must be greater than 0";
|
327
|
+
}
|
328
|
+
|
294
329
|
if (body) this.set('body', body);
|
295
330
|
return SC.Request.manager.sendRequest(this.copy()._prep());
|
296
331
|
},
|
@@ -343,7 +378,7 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
|
|
343
378
|
notify: function(status, target, action, params) {
|
344
379
|
|
345
380
|
// normalize status
|
346
|
-
var hasStatus = YES
|
381
|
+
var hasStatus = YES ;
|
347
382
|
if (SC.typeOf(status) !== SC.T_NUMBER) {
|
348
383
|
params = SC.A(arguments).slice(2);
|
349
384
|
action = target;
|
@@ -173,6 +173,18 @@ SC.Response = SC.Object.extend(
|
|
173
173
|
*/
|
174
174
|
isCancelled: NO,
|
175
175
|
|
176
|
+
/**
|
177
|
+
Set to YES if the request timed out. Set to NO if the request has
|
178
|
+
completed before the timeout value. Set to null if the timeout timer is
|
179
|
+
still ticking.
|
180
|
+
*/
|
181
|
+
timedOut: null,
|
182
|
+
|
183
|
+
/**
|
184
|
+
The timer tracking the timeout
|
185
|
+
*/
|
186
|
+
timeoutTimer: null,
|
187
|
+
|
176
188
|
// ..........................................................
|
177
189
|
// METHODS
|
178
190
|
//
|
@@ -183,7 +195,6 @@ SC.Response = SC.Object.extend(
|
|
183
195
|
begin the actual request.
|
184
196
|
*/
|
185
197
|
fire: function() {
|
186
|
-
|
187
198
|
var req = this.get('request'),
|
188
199
|
source = req ? req.get('source') : null;
|
189
200
|
|
@@ -198,6 +209,20 @@ SC.Response = SC.Object.extend(
|
|
198
209
|
// immediately if it is synchronous.
|
199
210
|
if (!this.get('isCancelled')) this.invokeTransport();
|
200
211
|
|
212
|
+
|
213
|
+
// If the request specified a timeout value, then set a timer for it now.
|
214
|
+
var timeout = req.get('timeout');
|
215
|
+
if (timeout) {
|
216
|
+
var timer = SC.Timer.schedule({
|
217
|
+
target: this,
|
218
|
+
action: 'timeoutReached',
|
219
|
+
interval: timeout,
|
220
|
+
repeats: NO
|
221
|
+
});
|
222
|
+
this.set('timeoutTimer', timer);
|
223
|
+
}
|
224
|
+
|
225
|
+
|
201
226
|
// if the transport did not cancel the request for some reason, let the
|
202
227
|
// source know that the request was sent
|
203
228
|
if (!this.get('isCancelled') && source && source.didSend) {
|
@@ -210,9 +235,9 @@ SC.Response = SC.Object.extend(
|
|
210
235
|
},
|
211
236
|
|
212
237
|
/**
|
213
|
-
Invoked by the transport when it receives a response. The passed
|
238
|
+
Invoked by the transport when it receives a response. The passed-in
|
214
239
|
callback will be invoked to actually process the response. If cancelled
|
215
|
-
we will pass NO. You
|
240
|
+
we will pass NO. You should clean up instead.
|
216
241
|
|
217
242
|
Invokes callbacks on the source request also.
|
218
243
|
|
@@ -221,25 +246,33 @@ SC.Response = SC.Object.extend(
|
|
221
246
|
@returns {SC.Response} receiver
|
222
247
|
*/
|
223
248
|
receive: function(callback, context) {
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
249
|
+
// If we timed out, we should ignore this response.
|
250
|
+
if (!this.get('timedOut')) {
|
251
|
+
// If we had a timeout timer scheduled, invalidate it now.
|
252
|
+
var timer = this.get('timeoutTimer');
|
253
|
+
if (timer) timer.invalidate();
|
254
|
+
this.set('timedOut', NO);
|
255
|
+
|
256
|
+
var req = this.get('request');
|
257
|
+
var source = req ? req.get('source') : null;
|
258
|
+
|
259
|
+
// invoke the source, giving a chance to fixup the reponse or (more
|
260
|
+
// likely) cancel the request.
|
261
|
+
if (source && source.willReceive) source.willReceive(req, this);
|
262
|
+
|
263
|
+
// invoke the callback. note if the response was cancelled or not
|
264
|
+
callback.call(context, !this.get('isCancelled'));
|
265
|
+
|
266
|
+
// if we weren't cancelled, then give the source first crack at handling
|
267
|
+
// the response. if the source doesn't want listeners to be notified,
|
268
|
+
// it will cancel the response.
|
269
|
+
if (!this.get('isCancelled') && source && source.didReceive) {
|
270
|
+
source.didReceive(req, this);
|
271
|
+
}
|
240
272
|
|
241
|
-
|
242
|
-
|
273
|
+
// notify listeners if we weren't cancelled.
|
274
|
+
if (!this.get('isCancelled')) this.notify();
|
275
|
+
}
|
243
276
|
|
244
277
|
// no matter what, remove from inflight queue
|
245
278
|
SC.Request.manager.transportDidClose(this) ;
|
@@ -252,12 +285,38 @@ SC.Response = SC.Object.extend(
|
|
252
285
|
*/
|
253
286
|
cancel: function() {
|
254
287
|
if (!this.get('isCancelled')) {
|
255
|
-
this.set('isCancelled', YES);
|
256
|
-
this.cancelTransport();
|
288
|
+
this.set('isCancelled', YES) ;
|
289
|
+
this.cancelTransport() ;
|
257
290
|
SC.Request.manager.transportDidClose(this) ;
|
258
291
|
}
|
259
292
|
},
|
260
293
|
|
294
|
+
/**
|
295
|
+
Default method just closes the connection.
|
296
|
+
*/
|
297
|
+
timeoutReached: function() {
|
298
|
+
// If we already received a response yet the timer still fired for some
|
299
|
+
// reason, do nothing.
|
300
|
+
if (this.get('timedOut') === null) {
|
301
|
+
this.set('timedOut', YES);
|
302
|
+
this.cancelTransport();
|
303
|
+
SC.Request.manager.transportDidClose(this);
|
304
|
+
|
305
|
+
// Set our value to an error.
|
306
|
+
var error = SC.$error("HTTP Request timed out", "Request", 408) ;
|
307
|
+
error.set("errorValue", this) ;
|
308
|
+
this.set('isError', YES);
|
309
|
+
this.set('errorObject', error);
|
310
|
+
|
311
|
+
// Invoke the didTimeout callback.
|
312
|
+
var req = this.get('request');
|
313
|
+
var source = req ? req.get('source') : null;
|
314
|
+
if (!this.get('isCancelled') && source && source.didTimeout) {
|
315
|
+
source.didTimeout(req, this);
|
316
|
+
}
|
317
|
+
}
|
318
|
+
},
|
319
|
+
|
261
320
|
/**
|
262
321
|
Override with concrete implementation to actually cancel the transport.
|
263
322
|
*/
|
@@ -453,7 +512,13 @@ SC.XHRResponse = SC.Response.extend({
|
|
453
512
|
|
454
513
|
// if there was an error - setup error and save it
|
455
514
|
if ((status < 200) || (status >= 300)) {
|
456
|
-
|
515
|
+
|
516
|
+
try {
|
517
|
+
msg = rawRequest.statusText || '';
|
518
|
+
} catch(e2) {
|
519
|
+
msg = '';
|
520
|
+
}
|
521
|
+
|
457
522
|
error = SC.$error(msg || "HTTP Request failed", "Request", status) ;
|
458
523
|
error.set("errorValue", this) ;
|
459
524
|
this.set('isError', YES);
|