sproutit-sproutcore 1.0.20090721145281 → 1.0.20090721145282

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.
Files changed (105) hide show
  1. data/Buildfile +4 -3
  2. data/VERSION.yml +2 -2
  3. data/buildtasks/entry.rake +3 -0
  4. data/buildtasks/manifest.rake +35 -9
  5. data/buildtasks/target.rake +25 -6
  6. data/frameworks/sproutcore/Buildfile +10 -0
  7. data/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +41 -20
  8. data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +14 -43
  9. data/frameworks/sproutcore/frameworks/datastore/models/record.js +11 -0
  10. data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +6 -3
  11. data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +5 -1
  12. data/frameworks/sproutcore/frameworks/datastore/system/query.js +10 -7
  13. data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +19 -20
  14. data/frameworks/sproutcore/frameworks/datastore/system/store.js +126 -93
  15. data/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +9 -3
  16. data/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +6 -1
  17. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +28 -3
  18. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +13 -5
  19. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +46 -23
  20. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +29 -5
  21. data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +13 -4
  22. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +109 -0
  23. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +69 -15
  24. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +20 -1
  25. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/dataHashDidChange.js +4 -1
  26. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/find_all.js +56 -6
  27. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +9 -2
  28. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +45 -2
  29. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +0 -1
  30. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/retrieveRecord.js +53 -6
  31. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/writeDataHash.js +0 -5
  32. data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +47 -27
  33. data/frameworks/sproutcore/frameworks/desktop/system/drag.js +5 -4
  34. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +23 -12
  35. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/render.js +92 -0
  36. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +104 -53
  37. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +2 -0
  38. data/frameworks/sproutcore/frameworks/desktop/views/button.js +4 -3
  39. data/frameworks/sproutcore/frameworks/desktop/views/collection.js +6 -2
  40. data/frameworks/sproutcore/frameworks/desktop/views/list.js +9 -0
  41. data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
  42. data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +3 -3
  43. data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +9 -1
  44. data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +80 -102
  45. data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +0 -1
  46. data/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +5 -1
  47. data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +8 -1
  48. data/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +0 -1
  49. data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +31 -3
  50. data/frameworks/sproutcore/frameworks/foundation/system/event.js +0 -4
  51. data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +3 -7
  52. data/frameworks/sproutcore/frameworks/foundation/system/request.js +3 -4
  53. data/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +78 -17
  54. data/frameworks/sproutcore/frameworks/foundation/system/utils.js +9 -0
  55. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/single_case.js +2 -2
  56. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +2 -2
  57. data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +5 -0
  58. data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +2 -2
  59. data/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +1 -4
  60. data/frameworks/sproutcore/frameworks/foundation/tests/validators/validator.js +20 -0
  61. data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +13 -0
  62. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +132 -0
  63. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisibleInWindow.js +6 -3
  64. data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +8 -5
  65. data/frameworks/sproutcore/frameworks/foundation/views/image.js +18 -5
  66. data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +292 -21
  67. data/frameworks/sproutcore/frameworks/foundation/views/view.js +13 -14
  68. data/frameworks/sproutcore/frameworks/mini/license.js +28 -0
  69. data/frameworks/sproutcore/frameworks/runtime/core.js +35 -0
  70. data/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
  71. data/frameworks/sproutcore/frameworks/runtime/system/sparse_array.js +79 -5
  72. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +6 -6
  73. data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +53 -0
  74. data/frameworks/sproutcore/frameworks/testing/system/plan.js +4 -0
  75. data/frameworks/sproutcore/frameworks/testing/system/runner.js +1 -1
  76. data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +4 -0
  77. data/gen/design/Buildfile +23 -0
  78. data/gen/design/README +1 -0
  79. data/gen/design/USAGE +10 -0
  80. data/gen/design/templates/english.lproj/@filename@.js +16 -0
  81. data/gen/page/Buildfile +36 -0
  82. data/gen/page/README +1 -0
  83. data/gen/page/USAGE +15 -0
  84. data/gen/page/templates/pages/@target_name@/Buildfile +16 -0
  85. data/gen/page/templates/pages/@target_name@/core.js +22 -0
  86. data/gen/page/templates/pages/@target_name@/english.lproj/body.css +1 -0
  87. data/gen/page/templates/pages/@target_name@/english.lproj/body.rhtml +7 -0
  88. data/gen/page/templates/pages/@target_name@/english.lproj/strings.js +15 -0
  89. data/gen/view/README +1 -1
  90. data/gen/view/USAGE +5 -5
  91. data/lib/sproutcore/builders/base.rb +13 -2
  92. data/lib/sproutcore/builders/html.rb +28 -1
  93. data/lib/sproutcore/builders/minify.rb +84 -18
  94. data/lib/sproutcore/builders/test.rb +2 -1
  95. data/lib/sproutcore/helpers/entry_sorter.rb +16 -1
  96. data/lib/sproutcore/helpers/static_helper.rb +32 -4
  97. data/lib/sproutcore/helpers/tag_helper.rb +65 -0
  98. data/lib/sproutcore/models/manifest.rb +40 -6
  99. data/lib/sproutcore/models/target.rb +12 -3
  100. data/lib/sproutcore/rack/builder.rb +56 -4
  101. data/lib/sproutcore/tools/manifest.rb +1 -0
  102. data/lib/sproutcore/tools/server.rb +1 -0
  103. data/lib/sproutcore/tools.rb +21 -1
  104. data/lib/sproutcore.rb +13 -0
  105. metadata +16 -1
@@ -68,7 +68,15 @@ SC.SelectFieldView = SC.FieldView.extend(
68
68
  if true, it means that the nameKey, valueKey or objects changed
69
69
  */
70
70
  cpDidChange: YES,
71
-
71
+
72
+ /**
73
+ if true, it means that no sorting will occur, objects will appear
74
+ in the same order as in the array
75
+ */
76
+ disableSort: NO,
77
+
78
+
79
+
72
80
  /**
73
81
  override this to change the enabled/disabled state of menu items as they
74
82
  are built. Return false if you want the menu item to be disabled.
@@ -89,49 +97,47 @@ SC.SelectFieldView = SC.FieldView.extend(
89
97
  @returns sorted array of objects
90
98
  */
91
99
  sortObjects: function(objects) {
92
- var nameKey = this.get('sortKey') || this.get('nameKey') ;
93
- objects = objects.sort(function(a,b) {
94
- if (nameKey) {
95
- a = a.get ? a.get(nameKey) : a[nameKey] ;
96
- b = b.get ? b.get(nameKey) : b[nameKey] ;
97
- }
98
- return (a<b) ? -1 : ((a>b) ? 1 : 0) ;
99
- }) ;
100
-
100
+ if(!this.get('disableSort')){
101
+ var nameKey = this.get('sortKey') || this.get('nameKey') ;
102
+ objects = objects.sort(function(a,b) {
103
+ if (nameKey) {
104
+ a = a.get ? a.get(nameKey) : a[nameKey] ;
105
+ b = b.get ? b.get(nameKey) : b[nameKey] ;
106
+ }
107
+ return (a<b) ? -1 : ((a>b) ? 1 : 0) ;
108
+ }) ;
109
+ }
101
110
  return objects ;
102
111
  },
103
112
 
104
- /**
105
- call this method to rebuild the menu manually. Normally you should not
106
- need to do this since the menu will be rebuilt as its data changes.
107
- */
108
- rebuildMenu: function(context, firstTime) {
109
-
110
- // get list of objects.
111
- var nameKey = this.get('nameKey') ;
112
- var valueKey = this.get('valueKey') ;
113
- var objects = this.get('objects') ;
114
- var fieldValue = this.get('value') ;
115
- var el, selectElement;
116
-
117
- // get the localization flag.
118
- var shouldLocalize = this.get('localize');
119
-
120
- // convert fieldValue to guid, if it is an object.
121
- if (!valueKey && fieldValue) fieldValue = SC.guidFor(fieldValue) ;
122
- if ((fieldValue === null) || (fieldValue === '')) fieldValue = '***' ;
113
+ render: function(context, firstTime) {
114
+ if (this.get('cpDidChange')) {
115
+ this.set('cpDidChange', NO);
116
+ // get list of objects.
117
+ var nameKey = this.get('nameKey') ;
118
+ var valueKey = this.get('valueKey') ;
119
+ var objects = this.get('objects') ;
120
+ var fieldValue = this.get('value') ;
121
+ var el, selectElement;
122
+
123
+ // get the localization flag.
124
+ var shouldLocalize = this.get('localize');
123
125
 
124
- if (objects) {
125
- objects = this.sortObjects(objects) ; // sort'em.
126
- // var html = [] ;
127
- if(!firstTime){
128
- selectElement=this.$input()[0];
129
- selectElement.innerHTML='';
130
- }
126
+ // convert fieldValue to guid, if it is an object.
127
+ if (!valueKey && fieldValue) fieldValue = SC.guidFor(fieldValue) ;
128
+ if ((fieldValue === null) || (fieldValue === '')) fieldValue = '***' ;
129
+
130
+ if (objects) {
131
+ objects = this.sortObjects(objects) ; // sort'em.
132
+ // var html = [] ;
133
+ if(!firstTime){
134
+ selectElement=this.$input()[0];
135
+ selectElement.innerHTML='';
136
+ }
131
137
 
132
- var emptyName = this.get('emptyName') ;
133
- if (emptyName) {
134
- if (shouldLocalize) emptyName = emptyName.loc() ;
138
+ var emptyName = this.get('emptyName') ;
139
+ if (emptyName) {
140
+ if (shouldLocalize) emptyName = emptyName.loc() ;
135
141
  if(firstTime){
136
142
  context.push('<option value="***">%@</option>'.fmt(emptyName)) ;
137
143
  context.push('<option disabled="disabled"></option>') ;
@@ -144,12 +150,11 @@ SC.SelectFieldView = SC.FieldView.extend(
144
150
  el.disabled="disabled";
145
151
  selectElement.appendChild(el);
146
152
  }
147
- }
153
+ }
148
154
 
149
- // generate option elements.
150
- objects.forEach(function(object) {
155
+ // generate option elements.
156
+ objects.forEach(function(object) {
151
157
  if (object) {
152
-
153
158
  // either get the name from the object or convert object to string.
154
159
  var name = nameKey ? (object.get ? object.get(nameKey) : object[nameKey]) : object.toString() ;
155
160
 
@@ -189,10 +194,27 @@ SC.SelectFieldView = SC.FieldView.extend(
189
194
 
190
195
  this.setFieldValue(fieldValue);
191
196
 
192
- } else {
193
- this.set('value',null);
197
+ } else {
198
+ this.set('value',null);
199
+ }
194
200
  }
195
201
  },
202
+
203
+ displayProperties: ['objects','nameKey','valueKey'],
204
+
205
+ _objectsObserver: function() {
206
+ this.set('cpDidChange', YES);
207
+ }.observes('objects'),
208
+
209
+ _nameKeyObserver: function() {
210
+ this.set('cpDidChange', YES);
211
+ }.observes('nameKey'),
212
+
213
+ _valueKeyObserver: function() {
214
+ this.set('cpDidChange', YES);
215
+ }.observes('valueKey'),
216
+
217
+
196
218
 
197
219
  // .......................................
198
220
  // PRIVATE
@@ -215,6 +237,7 @@ SC.SelectFieldView = SC.FieldView.extend(
215
237
  var value = sc_super(); // get raw value...
216
238
  var valueKey = this.get('valueKey') ;
217
239
  var objects = this.get('objects') ;
240
+ var found;
218
241
 
219
242
  // Handle empty selection.
220
243
  if (value == '***') {
@@ -225,7 +248,7 @@ SC.SelectFieldView = SC.FieldView.extend(
225
248
  } else if (value && objects) {
226
249
  // objects = Array.from(objects) ;
227
250
  var loc = objects.length ;
228
- var found = null ; // matching object goes here.
251
+ found = null ; // matching object goes here.
229
252
  while(!found && (--loc >= 0)) {
230
253
  var object = objects[loc] ;
231
254
 
@@ -239,67 +262,22 @@ SC.SelectFieldView = SC.FieldView.extend(
239
262
  }
240
263
  }
241
264
 
242
- return valueKey ? value : found ;
265
+ return (valueKey || found) ? found : value;
243
266
  },
244
267
 
245
- // object changes to the objects array of objects if possible.
246
- render: function(context, firstTime) {
247
- // if (this.didChangeFor('_objO','objects','nameKey','valueKey')) {
248
- var loc ;
249
- var objects = this.get('objects') ;
250
- var func = this._objectsItemObserver ;
251
-
252
- // stop observing old objects.
253
- if (this._objects) {
254
- loc = this._objects.length ;
255
- while(--loc >= 0) {
256
- var object = this._objects[loc] ;
257
- if (object && object.removeObserver) {
258
- if (this._nameKey && this._valueKey) {
259
- object.removeObserver(this._nameKey, this, func) ;
260
- object.removeObserver(this._valueKey, this, func) ;
261
- } else {
262
- object.removeObserver('*', this, func) ;
263
- } // if (this._nameKey)
264
- } // if (object &&...)
265
- } // while(--loc)
266
- } // if (this._objects)
267
-
268
- // start observing new objects.
269
- this._objects = objects ;
270
- this._nameKey = this.get('nameKey') ;
271
- this._valueKey = this.get('valueKey') ;
272
-
273
- if (this._objects) {
274
- loc = this._objects.length ;
275
- while(--loc >= 0) {
276
- object = this._objects[loc] ;
277
- if (object && object.addObserver) {
278
- if (this._nameKey && this._valueKey) {
279
- object.addObserver(this._nameKey, this, func) ;
280
- object.addObserver(this._valueKey, this, func) ;
281
- } else {
282
- object.addObserver('*', this, func) ;
283
- } // if (this._nameKey)
284
- } // if (object &&...)
285
- } // while(--loc)
286
- } // if (this._objects)
287
- this.rebuildMenu(context, firstTime) ;
288
- //} // if (this.didChangeFor...)
268
+ setFieldValue: function(newValue) {
269
+ if (SC.none(newValue)) { newValue = '' ; }
270
+ else {
271
+ newValue = ((newValue) ? (SC.guidFor(newValue) ? SC.guidFor(newValue) : newValue.toString()) : null );
272
+ }
273
+ this.$input().val(newValue);
274
+ return this ;
289
275
  },
290
-
291
- displayProperties: ['objects','nameKey','valueKey'],
292
-
293
276
 
294
277
 
295
- // this is invoked anytime an item we are interested in in the menu changes
296
- // rebuild the menu when this happens, but only one time.
297
- _objectsItemObserver: function(item, key, value) {
298
- if (item.didChangeFor(SC.guidFor(this), key)) {
299
- this.rebuildMenu() ;
300
- }
301
- },
302
-
278
+
279
+
280
+
303
281
  fieldDidFocus: function() {
304
282
  var isFocused = this.get('isFocused');
305
283
  if (!isFocused) this.set('isFocused', true);
@@ -247,7 +247,6 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
247
247
  if (content.isEnumerable) content.removeObject(object);
248
248
  else {
249
249
  this.set('content', null);
250
- this.enumerableContentDidChange();
251
250
  }
252
251
 
253
252
  if (this.get('destroyOnRemoval') && object.destroy) object.destroy();
@@ -1,10 +1,14 @@
1
1
  /* Common SC.TextFieldView styles - needed to work properly */
2
2
 
3
- .sc-view .sc-text-field-view{
3
+ .sc-view .sc-text-field-view {
4
4
  overflow: visible;
5
5
  z-index:100;
6
6
  }
7
7
 
8
+ .sc-view .sc-text-field-view .sc-text-field-accessory-view {
9
+ z-index:2;
10
+ }
11
+
8
12
  .sc-text-field-view input {
9
13
  position: absolute;
10
14
  top: -2px;
@@ -108,6 +108,8 @@ SC.Pane = SC.View.extend({
108
108
  /** Last known window size. */
109
109
  currentWindowSize: null,
110
110
 
111
+ previousKeyPane: null,
112
+
111
113
  /** The parent dimensions are always the last known window size. */
112
114
  computeParentDimensions: function(frame) {
113
115
  var pframe = this.get('currentWindowSize');
@@ -347,6 +349,7 @@ SC.Pane = SC.View.extend({
347
349
  didBecomeKeyPaneFrom: function(pane) {
348
350
  var isKeyPane = this.get('isKeyPane');
349
351
  this.set('isKeyPane', YES);
352
+ this.set('previousKeyPane', pane);
350
353
  this._forwardKeyChange(!isKeyPane, 'didBecomeKeyResponderFrom', pane, YES);
351
354
  return this ;
352
355
  },
@@ -421,7 +424,11 @@ SC.Pane = SC.View.extend({
421
424
 
422
425
  // remove from the RootResponder also
423
426
  var responder = this.rootResponder ;
424
- if (this.get('isKeyPane')) responder.makeKeyPane(null) ; // orders matter, remove keyPane first
427
+ if (this.get('isKeyPane')) { // orders matter, remove keyPane first
428
+ var oldKeyPane = this.get('previousKeyPane');
429
+ if(!oldKeyPane) responder.makeKeyPane(null) ;
430
+ else responder.makeKeyPane(oldKeyPane) ;
431
+ }
425
432
  if (this.get('isMainPane')) responder.makeMainPane(null) ;
426
433
  responder.panes.remove(this) ;
427
434
  this.rootResponder = responder = null ;
@@ -367,7 +367,6 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
367
367
  treeItemIsGrouped
368
368
  */
369
369
  contentGroupIndexes: function(view, content) {
370
-
371
370
  if (content !== this) return null; // only care about receiver
372
371
 
373
372
  var ret = this._contentGroupIndexes;
@@ -198,7 +198,8 @@ SC.DateTime = SC.Object.extend(SC.Freezable, SC.Copyable,
198
198
  - 'week0', the week number of the current year, starting with
199
199
  the first Monday as the first day of the first week (00..53)
200
200
  - 'lastMonday', 'lastTuesday', etc., 'nextMonday', 'nextTuesday', etc.,
201
- the date of the last or next weekday in comparison to the receiver
201
+ the date of the last or next weekday in comparison to the receiver,
202
+ - 'utc', the UTC formatted time
202
203
 
203
204
  @param {String} key the property name to get
204
205
  @return the value asked for
@@ -236,7 +237,7 @@ SC.DateTime = SC.Object.extend(SC.Freezable, SC.Copyable,
236
237
  %X - Preferred representation for the time alone, no date
237
238
  %y - Year without a century (00..99)
238
239
  %Y - Year with century
239
- %Z - Time zone name
240
+ %Z - Time zone (ISO 8601 formatted)
240
241
  %% - Literal ``%'' character
241
242
 
242
243
  @param {String} format the format string
@@ -246,6 +247,11 @@ SC.DateTime = SC.Object.extend(SC.Freezable, SC.Copyable,
246
247
  return this.constructor._toFormattedString(fmt, this._ms);
247
248
  },
248
249
 
250
+ toISO8601: function(){
251
+ var fmt = '%Y-%m-%dT%H:%M:%S%Z';
252
+ return this.constructor._toFormattedString(fmt, this._ms);
253
+ },
254
+
249
255
  /** @private
250
256
  Creates string representation of the receiver.
251
257
 
@@ -390,6 +396,7 @@ SC.DateTime.mixin(
390
396
  case 'millisecond': return d.getMilliseconds();
391
397
  case 'milliseconds': return d.getTime();
392
398
  case 'timezoneOffset': return d.getTimezoneOffset();
399
+ case 'utc': return d.utcFormat();
393
400
  }
394
401
 
395
402
  // isLeapYear
@@ -589,7 +596,24 @@ SC.DateTime.mixin(
589
596
  case 'X': throw "%X is not implemented";
590
597
  case 'y': opts.year = scanner.scanInt(2); opts.year += (opts.year > 70 ? 1900 : 2000); break;
591
598
  case 'Y': opts.year = scanner.scanInt(4); break;
592
- case 'Z': throw "%Z is not implemented";
599
+ case 'Z':
600
+ var modifier = scanner.scan(1);
601
+ if(modifier == 'Z'){
602
+ opts.timeZoneOffset = 0;
603
+ } else {
604
+ var timeZoneHours = scanner.scanInt(2);
605
+ if(scanner.scan(1) !== ':'){
606
+ scanner.scan(-1);
607
+ }
608
+ var timeZoneMinutes = scanner.scanInt(2);
609
+ var timeZoneSecondsOffset = (timeZoneHours*3600)+(timeZoneMinutes*60);
610
+
611
+ var offset = eval(0 + modifier + timeZoneSecondsOffset);
612
+ opts.timeZoneOffset = offset;
613
+ }
614
+
615
+ break;
616
+ // case 'Z': throw "%Z is not implemented";
593
617
  case '%': scanner.skipString('%'); break;
594
618
  default: scanner.skipString(parts[0]); break;
595
619
  }
@@ -609,6 +633,9 @@ SC.DateTime.mixin(
609
633
  if (!SC.none(check.dayOfWeek) && d.get('dayOfWeek') !== check.dayOfWeek) {
610
634
  return null;
611
635
  }
636
+ if(!SC.none(opts.timeZoneOffset)){
637
+ d = d.advance({second: opts.timeZoneOffset});
638
+ }
612
639
 
613
640
  return d;
614
641
  },
@@ -648,6 +675,7 @@ SC.DateTime.mixin(
648
675
  case 'M': return this._pad(this._get('minute'));
649
676
  case 'p': return this._get('hour') > 11 ? 'PM' : 'AM';
650
677
  case 'S': return this._pad(this._get('second'));
678
+ case 'u': return this._pad(this._get('utc')); //utc
651
679
  case 'U': return this._pad(this._get('week0'));
652
680
  case 'W': return this._pad(this._get('week1'));
653
681
  case 'w': return this._get('dayOfWeek');
@@ -801,10 +801,6 @@ SC.Event.prototype = {
801
801
  modifiers = 'meta_' ;
802
802
  ret = lowercase;
803
803
 
804
- } else if (ret !== lowercase) {
805
- modifiers = 'shift_' ;
806
- ret = lowercase ;
807
-
808
804
  } else ret = null ;
809
805
  }
810
806
 
@@ -712,14 +712,10 @@ SC.RenderContext = SC.Builder.create(/** SC.RenderContext.fn */ {
712
712
  // parse style...
713
713
  attr = this._elem.getAttribute('style');
714
714
 
715
- ////// TODO :LOOK OUT I ADDED TOLOWERCASE BECAUSE IE IS ALWAYS RETURNING STYLE KEYS IN CAPS
716
- ////// THAT MESSES UP CAMELIZING AND WE END UP WITH stuff like c-olor in the styles
717
- ////// I have to add more unit test
718
- ////// JUAN
719
-
720
- if(SC.browser.msie) attr = attr.toLowerCase();
721
-
722
715
  if (attr && (attr = attr.toString()).length>0) {
716
+ if(SC.browser.msie){
717
+ attr = attr.toLowerCase();
718
+ }
723
719
  styles = {};
724
720
 
725
721
  regex = this._STYLE_REGEX ;
@@ -226,7 +226,7 @@ SC.Request.manager = SC.Object.create( SC.DelegateSupport, {
226
226
  var r, xhrRequest;
227
227
  this.set('queue', []);
228
228
  var activeRequests=this.get('currentRequests');
229
- while(r=activeRequests.popObject()){
229
+ while(r=activeRequests.shiftObject()){
230
230
  xhrRequest = r.get('request');
231
231
  xhrRequest.abort();
232
232
  }
@@ -236,7 +236,7 @@ SC.Request.manager = SC.Object.create( SC.DelegateSupport, {
236
236
  fireRequestIfNeeded: function() {
237
237
  if (this.canLoadAnotherRequest()) {
238
238
  this.propertyWillChange('queue') ;
239
- var item = this.get('queue').popObject() ;
239
+ var item = this.get('queue').shiftObject() ;
240
240
  this.propertyDidChange('queue') ;
241
241
 
242
242
  if (item) {
@@ -252,13 +252,12 @@ SC.Request.manager = SC.Object.create( SC.DelegateSupport, {
252
252
  }
253
253
  }
254
254
  }
255
- },
255
+ }.observes('currentRequests'),
256
256
 
257
257
  _transportDidOpen: function(transport) {
258
258
  this.propertyWillChange('currentRequests') ;
259
259
  this.get('currentRequests').pushObject(transport) ;
260
260
  this.propertyDidChange('currentRequests') ;
261
-
262
261
  transport.fire() ;
263
262
  },
264
263
 
@@ -67,13 +67,8 @@ SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {
67
67
  var ret= undefined ;
68
68
 
69
69
  // namespace keyname
70
- if (keyName.indexOf('/')) {
71
- var domain = this.get('appDomain') || 'app';
72
- keyName = [domain, keyName].join(':');
73
- }
74
-
75
- var user = this.get('userDomain') || '' ;
76
- var userKeyName = [user,keyName].join('@');
70
+ keyName = this._normalizeKeyName(keyName);
71
+ var userKeyName = this._userKeyName(keyName);
77
72
 
78
73
  // look into recently written values
79
74
  if (this._written) ret = this._written[userKeyName];
@@ -90,9 +85,9 @@ SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {
90
85
  ret = SC.json.decode(ret);
91
86
  }
92
87
  catch(e) {
93
- ret = null;
88
+ ret = undefined;
94
89
  }
95
- }
90
+ } else ret = undefined;
96
91
  }
97
92
 
98
93
  // if not found in localStorage, try to notify delegate
@@ -118,15 +113,10 @@ SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {
118
113
  @returns {SC.UserDefault} receiver
119
114
  */
120
115
  writeDefault: function(keyName, value) {
121
- // namespace keyname
122
- if (keyName.indexOf('/')) {
123
- var domain = this.get('appDomain') || 'app';
124
- keyName = [domain, keyName].join(':');
125
- }
126
116
 
127
- var user = this.get('userDomain') || '' ;
128
- var userKeyName = [user,keyName].join('@');
129
-
117
+ keyName = this._normalizeKeyName(keyName);
118
+ var userKeyName = this._userKeyName(keyName);
119
+
130
120
  // save to local hash
131
121
  var written = this._written ;
132
122
  if (!written) written = this._written = {};
@@ -150,6 +140,36 @@ SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {
150
140
  return this ;
151
141
  },
152
142
 
143
+ /**
144
+ Removed the passed keyName from the written hash and local storage.
145
+
146
+ @param {String} keyName
147
+ @returns {SC.UserDefaults} receiver
148
+ */
149
+ resetDefault: function(keyName) {
150
+ var fullKeyName = this._normalizeKeyName(keyName);
151
+ var userKeyName = this._userKeyName(fullKeyName);
152
+
153
+ this.propertyWillChange(keyName);
154
+ this.propertyWillChange(fullKeyName);
155
+
156
+ var written = this._written;
157
+ if (written) delete written[userKeyName];
158
+
159
+ var localStorage = window.localStorage ;
160
+ if (!localStorage && window.globalStorage) {
161
+ localStorage = window.globalStorage[window.location.hostname];
162
+ }
163
+
164
+ if (localStorage) {
165
+ delete localStorage[["SC.UserDefaults",userKeyName].join('@')];
166
+ }
167
+
168
+ this.propertyDidChange(keyName);
169
+ this.propertyDidChange(fullKeyName);
170
+ return this ;
171
+ },
172
+
153
173
  unknownProperty: function(key, value) {
154
174
  if (value === undefined) {
155
175
  return this.readDefault(key) ;
@@ -157,6 +177,47 @@ SC.UserDefaults = SC.Object.extend(/** @scope SC.UserDefaults.prototype */ {
157
177
  this.writeDefault(key, value);
158
178
  return value ;
159
179
  }
180
+ },
181
+
182
+ /**
183
+ Normalize the passed key name. Used by all accessors to automatically
184
+ insert an appName if needed.
185
+ */
186
+ _normalizeKeyName: function(keyName) {
187
+ if (keyName.indexOf(':')<0) {
188
+ var domain = this.get('appDomain') || 'app';
189
+ keyName = [domain, keyName].join(':');
190
+ }
191
+ return keyName;
192
+ },
193
+
194
+ /**
195
+ Builds a user key name from the passed key name
196
+ */
197
+ _userKeyName: function(keyName) {
198
+ var user = this.get('userDomain') || '(anonymous)' ;
199
+ return [user,keyName].join('@');
200
+ },
201
+
202
+ _domainDidChange: function() {
203
+ var didChange = NO;
204
+ if (this.get("userDomain") !== this._scud_userDomain) {
205
+ this._scud_userDomain = this.get('userDomain');
206
+ didChange = YES;
207
+ }
208
+
209
+ if (this.get('appDomain') !== this._scud_appDomain) {
210
+ this._scud_appDomain = this.get('appDomain');
211
+ didChange = YES;
212
+ }
213
+
214
+ if (didChange) this.allPropertiesDidChange();
215
+ }.observes('userDomain', 'appDomain'),
216
+
217
+ init: function() {
218
+ sc_super();
219
+ this._scud_userDomain = this.get('userDomain');
220
+ this._scud_appDomain = this.get('appDomain');
160
221
  }
161
222
 
162
223
  });
@@ -194,6 +194,15 @@ SC.mixin( /** @scope SC */ {
194
194
  return { x: r.x, y: r.y, width: r.width, height: r.height } ;
195
195
  },
196
196
 
197
+ /** Returns a string representation of the rect as {x, y, width, height}.
198
+
199
+ @param r {Rect} The rect to stringify.
200
+ @returns {String} A string representation of the rect.
201
+ */
202
+ stringFromRect: function(r) {
203
+ return '{%@, %@, %@, %@}'.fmt(r.x, r.y, r.width, r.height);
204
+ },
205
+
197
206
 
198
207
  /** Finds the absolute viewportOffset for a given element.
199
208
  This method is more accurate than the version provided by prototype.
@@ -5,7 +5,7 @@
5
5
  // License: Licened under MIT license (see license.js)
6
6
  // ==========================================================================
7
7
 
8
- /*globals throws */
8
+ /*globals should_throw */
9
9
 
10
10
  var content, controller, extra;
11
11
 
@@ -51,7 +51,7 @@ test("removeObject - no destroyOnRemoval", function() {
51
51
  controller.set('destroyOnRemoval', NO);
52
52
  controller.addObserver('[]', function() { callCount++; });
53
53
 
54
- SC.run(function() { controller.removeObject(content); });
54
+ controller.removeObject(content);
55
55
 
56
56
  equals(controller.get('content'), null, 'removeObject(content) should set content to null');
57
57
  equals(callCount, 1, 'should notify observer since content did not change');
@@ -358,8 +358,8 @@ test("id", function() {
358
358
 
359
359
  //t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] );
360
360
  //t( "All Children of ID with no children", "#firstUL > *", [] );
361
-
362
- SC.$('<a name="tName1">tName1 A</a><a name="tName2">tName2 A</a><div id="tName1">tName1 Div</div>').appendTo('#main');
361
+ var q=SC.$('<a name="tName1">tName1 A</a><a name="tName2">tName2 A</a><div id="tName1">tName1 Div</div>');
362
+ q.appendTo('#main');
363
363
  equals( SC.$("#tName1")[0].id, 'tName1', "ID selector with same value for a name attribute" );
364
364
  equals( SC.$("#tName2").length, 0, "ID selector non-existing but name attribute on an A tag" );
365
365
  t( "ID Selector on Form with an input that has a name of 'id'", "#lengthtest", ["lengthtest"] );
@@ -122,6 +122,11 @@ test('parse', function() {
122
122
  {year: 1971, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0});
123
123
  });
124
124
 
125
+ test('parse with time zones',function(){
126
+ equals(SC.DateTime.parse('08/05/1985 01:00:22 %a -0700', '%d/%m/%Y %H:%M:%S %%a %Z').toISO8601(),"1985-05-07T18:00:22-07:00");
127
+ equals(SC.DateTime.parse('07/01/2020 18:33:22 %a Z', '%d/%m/%Y %H:%M:%S %%a %Z').toISO8601(),"2020-01-07T18:33:22-08:00");
128
+ });
129
+
125
130
  test('binding', function() {
126
131
  var fromObject = SC.Object.create({value: dt});
127
132
  var toObject = SC.Object.create({value: ''});
@@ -119,8 +119,8 @@ test("Test Multiple Asynchronous GET Request - two immediate, and two in serial"
119
119
 
120
120
  stop() ; // stops the test runner
121
121
  setTimeout( function(){
122
- equals(requestCount, 8, "requestCount should be 4");
123
- equals(responseCount, 6, "responseCount should be 4");
122
+ equals(requestCount, 8, "requestCount should be 8");
123
+ equals(responseCount, 8, "responseCount should be 8");
124
124
  window.start() ; // starts the test runne
125
125
  }, 3000);
126
126
  });
@@ -19,9 +19,6 @@ module("User Defaults",{
19
19
 
20
20
  test("To check if the user defaults are stored and read from local storage",function(){
21
21
  SC.userDefaults.writeDefault('Back',obj.bck);
22
- SC.userDefaults.readDefault('Back');
23
-
24
- // [Exception... "Security error" code: "1000" nsresult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)"
25
- // location: "http://localhost:4020/static/sproutcore/foundation/en/current/source/system/user_defaults.js?1234934251 Line: 131"]
22
+ equals(SC.userDefaults.readDefault('Back'), obj.bck, 'should read written property');
26
23
  });
27
24