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
@@ -9,6 +9,7 @@
9
9
  var MyApp;
10
10
  module("SC.Query querying findAll on a store", {
11
11
  setup: function() {
12
+ SC.RunLoop.begin();
12
13
  // setup dummy app and store
13
14
  MyApp = SC.Object.create({});
14
15
 
@@ -44,10 +45,15 @@ module("SC.Query querying findAll on a store", {
44
45
 
45
46
  // load some data
46
47
  MyApp.DataSource.storeKeys = MyApp.store.loadRecords(MyApp.Foo, records);
48
+ SC.RunLoop.end();
49
+
50
+ SC.RunLoop.begin();
47
51
  // for sanity check, load two record types
48
52
  MyApp.store.loadRecords(MyApp.Faa, records);
53
+ SC.RunLoop.end();
49
54
 
50
55
  }
56
+
51
57
  });
52
58
 
53
59
 
@@ -56,7 +62,6 @@ module("SC.Query querying findAll on a store", {
56
62
  //
57
63
 
58
64
  test("should find records based on boolean", function() {
59
-
60
65
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"married=true"});
61
66
 
62
67
  var records = MyApp.store.findAll(q);
@@ -140,7 +145,7 @@ test("loading more data into the store should propagate to record array", functi
140
145
  });
141
146
 
142
147
  test("loading more data into the store should propagate to record array with query", function() {
143
-
148
+ SC.RunLoop.begin();
144
149
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName = 'John'"});
145
150
 
146
151
  var records = MyApp.store.findAll(q);
@@ -155,16 +160,17 @@ test("loading more data into the store should propagate to record array with que
155
160
  // and should fire original SC.Query again
156
161
 
157
162
  MyApp.DataSource.storeKeys.replace(0,0,newStoreKeys);
158
-
163
+ SC.RunLoop.end();
159
164
  equals(records.get('length'), 2, 'record length after should be 2');
160
165
 
161
166
  // subsequent updates to store keys should also work
162
-
167
+ SC.RunLoop.begin();
163
168
  var newStoreKeys2 = MyApp.store.loadRecords(MyApp.Foo, [
164
169
  { guid: 11, firstName: "John", lastName: "Norman" }
165
170
  ]);
166
171
 
167
172
  MyApp.DataSource.storeKeys.replace(0,0,newStoreKeys2);
173
+ SC.RunLoop.end();
168
174
 
169
175
  equals(records.get('length'), 3, 'record length after should be 3');
170
176
 
@@ -182,6 +188,7 @@ test("SC.Query returned from fetchRecords() should return result set", function(
182
188
 
183
189
  test("Loading records after SC.Query is returned in fetchRecords() should show up", function() {
184
190
 
191
+ SC.RunLoop.begin();
185
192
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName = 'John'"});
186
193
 
187
194
  var records = MyApp.store.findAll(q);
@@ -195,6 +202,7 @@ test("Loading records after SC.Query is returned in fetchRecords() should show u
195
202
  ];
196
203
 
197
204
  MyApp.store.loadRecords(MyApp.Foo, recordsToLoad);
205
+ SC.RunLoop.end();
198
206
 
199
207
  equals(records.get('length'), 3, 'record length should be 3');
200
208
 
@@ -206,6 +214,7 @@ test("Loading records after SC.Query is returned in fetchRecords() should show u
206
214
 
207
215
  test("Loading records after getting empty record array based on SC.Query should update", function() {
208
216
 
217
+ SC.RunLoop.begin();
209
218
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName = 'Maria'"});
210
219
 
211
220
  var records = MyApp.store.findAll(q);
@@ -216,6 +225,7 @@ test("Loading records after getting empty record array based on SC.Query should
216
225
  ];
217
226
 
218
227
  MyApp.store.loadRecords(MyApp.Foo, recordsToLoad);
228
+ SC.RunLoop.end();
219
229
 
220
230
  equals(records.get('length'), 1, 'record length should be 1');
221
231
 
@@ -225,6 +235,8 @@ test("Loading records after getting empty record array based on SC.Query should
225
235
 
226
236
  test("Changing a record should make it show up in RecordArrays based on SC.Query", function() {
227
237
 
238
+ SC.RunLoop.begin();
239
+
228
240
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName = 'Maria'"});
229
241
 
230
242
  var records = MyApp.store.findAll(q);
@@ -233,6 +245,8 @@ test("Changing a record should make it show up in RecordArrays based on SC.Query
233
245
  var record = MyApp.store.find(MyApp.Foo, 1);
234
246
  record.set('firstName', 'Maria');
235
247
 
248
+ SC.RunLoop.end();
249
+
236
250
  equals(records.get('length'), 1, 'record length should be 1');
237
251
 
238
252
  equals(records.objectAt(0).get('firstName'), 'Maria', 'name should be Maria');
@@ -241,13 +255,14 @@ test("Changing a record should make it show up in RecordArrays based on SC.Query
241
255
 
242
256
  test("Deleting a record should make the RecordArray based on SC.Query update accordingly", function() {
243
257
 
258
+ SC.RunLoop.begin();
244
259
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName = 'John'"});
245
260
 
246
261
  var records = MyApp.store.findAll(q);
247
262
  equals(records.get('length'), 1, 'record length should be 1');
248
263
 
249
264
  MyApp.store.destroyRecord(MyApp.Foo, 1);
250
- MyApp.store.commitRecords();
265
+ SC.RunLoop.end();
251
266
 
252
267
  equals(records.get('length'), 0, 'record length should be 0');
253
268
 
@@ -255,6 +270,7 @@ test("Deleting a record should make the RecordArray based on SC.Query update acc
255
270
 
256
271
  test("Using findAll with SC.Query on store with no data source should work", function() {
257
272
 
273
+ SC.RunLoop.begin();
258
274
  // create a store with no data source
259
275
  MyApp.store3 = SC.Store.create();
260
276
 
@@ -268,9 +284,11 @@ test("Using findAll with SC.Query on store with no data source should work", fun
268
284
  { guid: 21, firstName: "John", lastName: "Anderson" },
269
285
  { guid: 22, firstName: "Barbara", lastName: "Jones" }
270
286
  ];
271
-
287
+
272
288
  MyApp.store3.loadRecords(MyApp.Foo, recordsToLoad);
273
289
 
290
+ SC.RunLoop.end();
291
+
274
292
  equals(records.get('length'), 2, 'record length should be 2');
275
293
 
276
294
  });
@@ -288,6 +306,7 @@ test("Using orderBy in SC.Query returned from findAll()", function() {
288
306
 
289
307
  test("Using orderBy in SC.Query returned from findAll() and loading more records to original store key array", function() {
290
308
 
309
+ SC.RunLoop.begin();
291
310
  var q = SC.Query.create({recordType: MyApp.Foo, orderBy:"firstName ASC"});
292
311
 
293
312
  var records = MyApp.store.findAll(q);
@@ -301,6 +320,7 @@ test("Using orderBy in SC.Query returned from findAll() and loading more records
301
320
  ]);
302
321
 
303
322
  MyApp.DataSource.storeKeys.replace(0,0,newStoreKeys2);
323
+ SC.RunLoop.end();
304
324
 
305
325
  equals(records.objectAt(0).get('firstName'), 'Anna', 'name should be Anna');
306
326
  equals(records.objectAt(1).get('firstName'), 'Bert', 'name should be Bert');
@@ -311,6 +331,7 @@ test("Using orderBy in SC.Query returned from findAll() and loading more records
311
331
 
312
332
  test("Using orderBy in SC.Query and loading more records to the store", function() {
313
333
 
334
+ SC.RunLoop.begin();
314
335
  var q = SC.Query.create({recordType: MyApp.Foo, orderBy:"firstName ASC"});
315
336
 
316
337
  var records = MyApp.store.findAll(q);
@@ -320,6 +341,7 @@ test("Using orderBy in SC.Query and loading more records to the store", function
320
341
  MyApp.store.loadRecords(MyApp.Foo, [
321
342
  { guid: 11, firstName: "Anna", lastName: "Petterson" }
322
343
  ]);
344
+ SC.RunLoop.end();
323
345
 
324
346
  equals(records.get('length'), 6, 'record length should be 6');
325
347
 
@@ -347,6 +369,7 @@ test("Chaining findAll() queries", function() {
347
369
 
348
370
  test("Chaining findAll() queries and loading more records", function() {
349
371
 
372
+ SC.RunLoop.begin();
350
373
  var q = SC.Query.create({recordType: MyApp.Foo, conditions:"lastName='Doe'"});
351
374
  var q2 = SC.Query.create({recordType: MyApp.Foo, conditions:"firstName='John'"});
352
375
 
@@ -356,7 +379,34 @@ test("Chaining findAll() queries and loading more records", function() {
356
379
  MyApp.store.loadRecords(MyApp.Foo, [
357
380
  { guid: 11, firstName: "John", lastName: "Doe" }
358
381
  ]);
382
+ SC.RunLoop.end();
359
383
 
360
384
  equals(records.get('length'), 2, 'record length should be 2');
361
385
 
362
386
  });
387
+
388
+
389
+ module("create record");
390
+
391
+ test("creating record appears in future findAll", function() {
392
+ var Rec = SC.Record.extend({ title: SC.Record.attr(String) });
393
+ var store = SC.Store.create();
394
+ SC.run(function() {
395
+ store.loadRecords(Rec,
396
+ [{ title: "A", guid: 1 }, { title: "B", guid: 2 }]);
397
+ });
398
+
399
+ equals(store.findAll(Rec).get('length'), 2, 'should have two initial record');
400
+
401
+ var r;
402
+
403
+ SC.run(function() {
404
+ store.createRecord(Rec, { title: "C" });
405
+ r = store.findAll(Rec);
406
+ equals(r.get('length'), 3, 'should return additional record');
407
+ });
408
+
409
+ r = store.findAll(Rec);
410
+ equals(r.get('length'), 3, 'should return additional record');
411
+
412
+ });
@@ -56,6 +56,7 @@ module("SC.Store#commitRecord", {
56
56
  bool: YES
57
57
  };
58
58
 
59
+ SC.RunLoop.begin();
59
60
  storeKey1 = SC.Store.generateStoreKey();
60
61
  store.writeDataHash(storeKey1, json1, SC.Record.READY_CLEAN);
61
62
  storeKey2 = SC.Store.generateStoreKey();
@@ -70,7 +71,7 @@ module("SC.Store#commitRecord", {
70
71
  store.writeDataHash(storeKey6, json6, SC.Record.READY_ERROR);
71
72
  storeKey7 = SC.Store.generateStoreKey();
72
73
  store.writeDataHash(storeKey7, json7, SC.Record.READY_DESTROYED_CLEAN);
73
-
74
+ SC.RunLoop.end();
74
75
  }
75
76
  });
76
77
 
@@ -89,11 +90,15 @@ test("Confirm that all the states are switched as expected after running commitR
89
90
  status = store.readStatus( storeKey3);
90
91
  equals(status, SC.Record.BUSY_COMMITTING, "the status should be SC.Record.BUSY_COMMITTING");
91
92
 
93
+ store.dataSourceDidComplete(storeKey3);
94
+ status = store.readStatus( storeKey3);
95
+ equals(status, SC.Record.READY_CLEAN, "the status should be SC.Record.READY_CLEAN");
96
+
92
97
  store.commitRecord(undefined, undefined, storeKey4);
93
98
  status = store.readStatus( storeKey4);
94
99
  equals(status, SC.Record.BUSY_DESTROYING, "the status should be SC.Record.BUSY_DESTROYING");
95
100
 
96
- try{
101
+ try {
97
102
  store.commitRecord(undefined, undefined, storeKey5);
98
103
  throwError=false;
99
104
  msg='';
@@ -123,4 +128,6 @@ test("Confirm that all the states are switched as expected after running commitR
123
128
  }
124
129
  equals(msg, SC.Record.NOT_FOUND_ERROR.message, "commitRecord should throw the following error");
125
130
 
131
+
132
+
126
133
  });
@@ -5,11 +5,17 @@
5
5
  // ==========================================================================
6
6
  /*globals module ok equals same test MyApp Sample */
7
7
 
8
- var store, Application;
8
+ var store, Application, dataSource;
9
9
 
10
10
  module("SC.Store Core Methods", {
11
11
  setup: function() {
12
- var dataSource = SC.DataSource.create({});
12
+ dataSource = SC.DataSource.create({
13
+
14
+ gotParams: NO,
15
+
16
+ updateRecord: function(store, storeKey, params) {
17
+ this.gotParams = params && params['param1'] ? YES: NO;
18
+ }});
13
19
 
14
20
  Application = {};
15
21
 
@@ -35,10 +41,12 @@ module("SC.Store Core Methods", {
35
41
  ]
36
42
  };
37
43
 
44
+ SC.RunLoop.begin();
38
45
  store = SC.Store.create().from(dataSource);
39
46
  for(var i in Application.Data) {
40
47
  store.loadRecords(Application[i], Application.Data[i]);
41
48
  }
49
+ SC.RunLoop.end();
42
50
 
43
51
  // make sure RecordType by String can map
44
52
  window.Application = Application;
@@ -71,3 +79,38 @@ test("find() should take both SC.Record object and SC.Record string as recordtyp
71
79
 
72
80
  });
73
81
 
82
+ test("loading more records should not sending _flushRecordChanges() until the end of the runloop", function() {
83
+
84
+ var moreData = [
85
+ { guid: '55', name: 'Home', url: '/emily_parker', isDirectory: true, parent: null, children: 'Collection'},
86
+ { guid: '56', name: 'Documents', fileType: 'documents', url: '/emily_parker/Documents', isDirectory: true, parent: '10', children: 'Collection', createdAt: 'June 15, 2007', modifiedAt: 'October 21, 2007', filetype: 'directory', isShared: false},
87
+ { guid: '57',name: 'Library', fileType: 'library', url: '/emily_parker/Library', isDirectory: true, parent: '10', children: 'Collection', createdAt: 'June 15, 2007', modifiedAt: 'October 21, 2007', filetype: 'directory', isShared: false}
88
+ ];
89
+
90
+ SC.RunLoop.begin();
91
+
92
+ var storeKeys = store.loadRecords(Application.File, moreData);
93
+ equals(storeKeys.length, 3, 'precon - should have loaded three records');
94
+ equals(store.recordPropertyChanges.storeKeys.length, 3, 'should be three storeKeys in changelog');
95
+
96
+ SC.RunLoop.end();
97
+
98
+ // recordPropertyChanges may not exist after notifications have gone out.
99
+ // treat that like having len=0
100
+ var changes = store.recordPropertyChanges;
101
+ var len = (changes && changes.storeKeys) ? changes.storeKeys.length : 0;
102
+ equals(len, 0, 'should be zero storeKeys in changelog');
103
+
104
+ });
105
+
106
+ test("Passing params through commitRecords()", function() {
107
+
108
+ var file = store.find(Application.File, '14');
109
+ file.set('name', 'My Great New Name');
110
+
111
+ store.commitRecords(null, null, null, { param1: 'value1' });
112
+
113
+ equals(dataSource.gotParams, YES, 'params should have travelled through to dataSource updateRecord() call');
114
+
115
+
116
+ });
@@ -70,5 +70,4 @@ test("recordDidChange", function() {
70
70
  status = store.readStatus( storeKey4);
71
71
  equals(status, SC.Record.READY_DIRTY, "the status shouldn't have changed.");
72
72
 
73
-
74
73
  });
@@ -82,20 +82,36 @@ module("SC.Store#retrieveRecord", {
82
82
  store.writeDataHash(storeKey8, json8, SC.Record.READY_CLEAN);
83
83
  }
84
84
  });
85
-
86
- test("Retrieve a record and check for different errors and states", function() {
85
+
86
+ function testStates(canLoad) {
87
87
  var msg, status;
88
+
89
+ SC.RunLoop.begin();
90
+
88
91
  store.retrieveRecord(undefined, undefined, storeKey1, YES);
89
92
  status = store.readStatus( storeKey1);
90
- equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
93
+ if (canLoad) {
94
+ equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
95
+ } else {
96
+ equals(status, SC.Record.ERROR, "the status should remain empty");
97
+ }
98
+
91
99
 
92
100
  store.retrieveRecord(undefined, undefined, storeKey2, YES);
93
101
  status = store.readStatus( storeKey2);
94
- equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
102
+ if (canLoad) {
103
+ equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
104
+ } else {
105
+ equals(status, SC.Record.ERROR, "the status should become empty");
106
+ }
95
107
 
96
108
  store.retrieveRecord(undefined, undefined, storeKey3, YES);
97
109
  status = store.readStatus( storeKey3);
98
- equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
110
+ if (canLoad) {
111
+ equals(status, SC.Record.BUSY_LOADING, "the status should have changed to BUSY_LOADING");
112
+ } else {
113
+ equals(status, SC.Record.ERROR, "the status should become empty");
114
+ }
99
115
 
100
116
  try{
101
117
  store.retrieveRecord(undefined, undefined, storeKey4, YES);
@@ -132,6 +148,37 @@ test("Retrieve a record and check for different errors and states", function() {
132
148
 
133
149
  store.retrieveRecord(undefined, undefined, storeKey8, YES);
134
150
  status = store.readStatus( storeKey8);
135
- ok(SC.Record.BUSY_REFRESH | (status & 0x03), "the status changed to BUSY_REFRESH.");
151
+ if (canLoad) {
152
+ ok(SC.Record.BUSY_REFRESH | (status & 0x03), "the status changed to BUSY_REFRESH.");
153
+ } else {
154
+ equals(status, SC.Record.READY_CLEAN, "the status should remain ready clean");
155
+ }
136
156
 
157
+ SC.RunLoop.end();
158
+ }
159
+
160
+ test("Retrieve a record without a data source", function() {
161
+ testStates(NO);
162
+ });
163
+
164
+ test("Retrieve a record without a working data source and check for different errors and states", function() {
165
+ // build a fake data source that claims to NOT handle retrieval
166
+ var source = SC.DataSource.create({
167
+ retrieveRecords: function() { return NO ; }
168
+ });
169
+ store.set('dataSource', source);
170
+
171
+ testStates(NO);
172
+
173
+ });
174
+
175
+ test("Retrieve a record with working data source and check for different errors and states", function() {
176
+ // build a fake data source that claims to handle retrieval
177
+ var source = SC.DataSource.create({
178
+ retrieveRecords: function() { return YES ; }
179
+ });
180
+ store.set('dataSource', source);
181
+
182
+ testStates(YES);
183
+
137
184
  });
@@ -123,8 +123,3 @@ test("change should not propogate to child if child edit state = EDITABLE", func
123
123
 
124
124
 
125
125
 
126
-
127
-
128
-
129
-
130
-
@@ -31,8 +31,9 @@ SC.MenuPane = SC.PickerPane.extend(
31
31
 
32
32
  @readOnly
33
33
  @type Boolean
34
+ @default isEnabled
34
35
  */
35
- itemIsEnabledKey: YES,
36
+ itemIsEnabledKey: "isEnabled",
36
37
 
37
38
  /**
38
39
  The key that contains the title for each item. If omitted, no icons will
@@ -40,8 +41,9 @@ SC.MenuPane = SC.PickerPane.extend(
40
41
 
41
42
  @readOnly
42
43
  @type String
44
+ @default title
43
45
  */
44
- itemTitleKey: null,
46
+ itemTitleKey: 'title',
45
47
 
46
48
  /**
47
49
  The array of items to display. This can be a simple array of strings,
@@ -59,8 +61,9 @@ SC.MenuPane = SC.PickerPane.extend(
59
61
 
60
62
  @readOnly
61
63
  @type String
64
+ @default value
62
65
  */
63
- itemValueKey: null,
66
+ itemValueKey: 'value',
64
67
 
65
68
  /**
66
69
  The key that contains the icon for each item. If omitted, no icons will
@@ -68,8 +71,9 @@ SC.MenuPane = SC.PickerPane.extend(
68
71
 
69
72
  @readOnly
70
73
  @type String
74
+ @default icon
71
75
  */
72
- itemIconKey: null,
76
+ itemIconKey: 'icon',
73
77
 
74
78
  /**
75
79
  The width for each menu item and ultimately the menu itself.
@@ -97,8 +101,18 @@ SC.MenuPane = SC.PickerPane.extend(
97
101
 
98
102
  @readOnly
99
103
  @type String
104
+ @default height
100
105
  */
101
- itemHeightKey: null,
106
+ itemHeightKey: 'height',
107
+
108
+ /**
109
+ The submenu for a menu item if any.
110
+
111
+ @readOnly
112
+ @type String
113
+ @default subMenu
114
+ */
115
+ subMenuKey: 'subMenu',
102
116
 
103
117
  /**
104
118
  If YES, titles will be localized before display.
@@ -110,56 +124,63 @@ SC.MenuPane = SC.PickerPane.extend(
110
124
 
111
125
  @readOnly
112
126
  @type Boolean
127
+ @default separator
113
128
  */
114
- itemSeparatorKey: null,
129
+ itemSeparatorKey: 'separator',
115
130
 
116
131
  /**
117
132
  This key is need to assign an action to the menu item.
118
133
 
119
134
  @readOnly
120
135
  @type String
136
+ @default action
121
137
  */
122
- itemActionKey: null,
138
+ itemActionKey: 'action',
123
139
 
124
140
  /**
125
141
  The key for setting a checkbox for the menu item.
126
142
 
127
143
  @readOnly
128
144
  @type String
145
+ @default checkbox
129
146
  */
130
- itemCheckboxKey: null,
147
+ itemCheckboxKey: 'checkbox',
131
148
 
132
149
  /**
133
150
  The key for setting a branch for the menu item.
134
151
 
135
152
  @readOnly
136
153
  @type String
154
+ @default branchItem
137
155
  */
138
- itemBranchKey: null,
156
+ itemBranchKey: 'branchItem',
139
157
 
140
158
  /**
141
159
  The key for setting a branch for the menu item.
142
160
 
143
161
  @readOnly
144
162
  @type String
163
+ @default shortcut
145
164
  */
146
- itemShortCutKey: null,
165
+ itemShortCutKey: 'shortcut',
147
166
 
148
167
  /**
149
168
  The key for setting Key Equivalent for the menu item.
150
169
 
151
170
  @readOnly
152
171
  @type String
172
+ @default keyEquivalent
153
173
  */
154
- itemKeyEquivalentKey: null,
174
+ itemKeyEquivalentKey: 'keyEquivalent',
155
175
 
156
176
  /**
157
177
  The key for setting Key Equivalent for the menu item.
158
178
 
159
179
  @readOnly
160
180
  @type String
181
+ @default target
161
182
  */
162
- itemTargetKey: null,
183
+ itemTargetKey: 'target',
163
184
 
164
185
  /** @private */
165
186
  isKeyPane: YES,
@@ -270,7 +291,7 @@ SC.MenuPane = SC.PickerPane.extend(
270
291
  if (loc && cur[0]) cur[0] = cur[0].loc() ;
271
292
  ret[rel] = SC.Object.create({ title: cur[0], value: cur[1],
272
293
  isEnabled: cur[2], icon: cur[3],
273
- isSeparator: cur[4], action: cur[5],
294
+ isSeparator: cur[4]||NO , action: cur[5],
274
295
  isCheckbox: cur[6], isShortCut: cur[7],
275
296
  menuItemNumber: idx, isBranch: cur[8],
276
297
  itemHeight: cur[9], subMenu: cur[10],
@@ -462,7 +483,7 @@ SC.MenuPane = SC.PickerPane.extend(
462
483
  */
463
484
  isAnchorMenuItemType: function() {
464
485
  var anchor = this.get('anchor') ;
465
- return (anchor && anchor.kindOf(SC.MenuItemView)) ;
486
+ return (anchor && anchor.kindOf && anchor.kindOf(SC.MenuItemView)) ;
466
487
  },
467
488
 
468
489
  //..........................................................
@@ -480,12 +501,11 @@ SC.MenuPane = SC.PickerPane.extend(
480
501
  var items, len, menuItems, item, keyEquivalent,
481
502
  action, isEnabled, target;
482
503
  if(!this.get('isEnabled')) return NO ;
483
-
504
+ this.displayItems() ;
484
505
  items = this.get('displayItemsArray') ;
485
506
  if (!items) return NO;
486
507
 
487
508
  len = items.length ;
488
- menuItems = this.get('menuItemViews');
489
509
  for(var idx=0; idx<len; ++idx) {
490
510
  item = items[idx] ;
491
511
  keyEquivalent = item.get('keyEquivalent') ;
@@ -493,13 +513,11 @@ SC.MenuPane = SC.PickerPane.extend(
493
513
  isEnabled = item.get('isEnabled') ;
494
514
  target = item.get('target') || this ;
495
515
  if(keyEquivalent == keyString && isEnabled) {
496
- if(menuItems && menuItems[idx]) {
497
- var retVal = menuItems[idx].triggerAction(evt);
498
- return retVal;
499
- }
516
+ var retVal = SC.RootResponder.responder.sendAction(action,target);
517
+ return retVal;
500
518
  }
501
519
  }
502
- return YES ;
520
+ return NO ;
503
521
  },
504
522
 
505
523
  //Mouse and Key Events
@@ -558,17 +576,18 @@ SC.MenuPane = SC.PickerPane.extend(
558
576
  var menuItemViews = this.get('menuItemViews') ;
559
577
  if(menuItemViews) {
560
578
  var len = menuItemViews.length ;
561
- var idx = (menuItemViews.indexOf(menuItem) === -1) ? len : menuItemViews.indexOf(menuItem) ;
579
+ var menuIdx = idx = (menuItemViews.indexOf(menuItem) === -1) ?
580
+ len : menuItemViews.indexOf(menuItem) ;
562
581
  var isEnabled = NO ;
563
582
  var isSeparator = NO ;
564
- while(--idx >= 0 && !isEnabled && !isSeparator) {
583
+ while((!isEnabled || isSeparator) && --idx !== menuIdx) {
584
+ if(idx === -1) idx = len - 1;
565
585
  isEnabled = menuItemViews[idx].get('isEnabled') ;
566
586
  var content = menuItemViews[idx].get('content') ;
567
587
  if(content) {
568
588
  isSeparator = content.get(menuItemViews[idx].get('isSeparatorKey'));
569
589
  }
570
590
  }
571
- if(idx === -1) idx = len - 1;
572
591
  return menuItemViews[idx];
573
592
  }
574
593
  },
@@ -582,17 +601,18 @@ SC.MenuPane = SC.PickerPane.extend(
582
601
  var menuItemViews = this.get('menuItemViews') ;
583
602
  if(menuItemViews) {
584
603
  var len = menuItemViews.length ;
585
- var idx = (menuItemViews.indexOf(menuItem) === -1) ? 0 : menuItemViews.indexOf(menuItem) ;
604
+ var menuIdx = idx = (menuItemViews.indexOf(menuItem) === -1) ?
605
+ 0 : menuItemViews.indexOf(menuItem) ;
586
606
  var isEnabled = NO ;
587
607
  var isSeparator = NO ;
588
- while(!isEnabled && !isSeparator && ++idx < len) {
608
+ while((!isEnabled || isSeparator) && ++idx !== menuIdx) {
609
+ if(idx === len) idx = 0;
589
610
  isEnabled = menuItemViews[idx].get('isEnabled') ;
590
611
  var content = menuItemViews[idx].get('content') ;
591
612
  if(content) {
592
613
  isSeparator = content.get(menuItemViews[idx].get('isSeparatorKey'));
593
614
  }
594
615
  }
595
- if(idx === len) idx = 0 ;
596
616
  return menuItemViews[idx] ;
597
617
  }
598
618
  },
@@ -334,9 +334,9 @@ SC.Drag = SC.Object.extend(
334
334
  return ; // quickly ignore duplicate calls
335
335
  }
336
336
 
337
- // cache the current location to avoid processing duplicate mouseDragged
338
- // calls
339
- this.set('location', { x: evt.pageX, y: evt.pageY }) ;
337
+ // save the new location to avoid duplicate mouseDragged event processing
338
+ loc = { x: evt.pageX, y: evt.pageY };
339
+ this.set('location', loc) ;
340
340
 
341
341
  // STEP 1: Determine the deepest drop target that allows an operation.
342
342
  // if the drop target selected the last time this method was called
@@ -543,7 +543,8 @@ SC.Drag = SC.Object.extend(
543
543
  for (var idx=0, len=ary.length; idx<len; idx++) {
544
544
  target = ary[idx] ;
545
545
 
546
- // FIXME if (!target.get('isVisibleInWindow')) continue ;
546
+ // If the target is not visible, it is not valid.
547
+ if (!target.get('isVisibleInWindow')) continue ;
547
548
 
548
549
  // get clippingFrame, converted to the pane.
549
550
  frame = target.convertFrameToView(target.get('clippingFrame'), null) ;