sproutit-sproutcore 1.0.20090721145281 → 1.0.20090721145282

Sign up to get free protection for your applications and to get access to all the features.
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