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
@@ -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) ;