sproutcore 1.5.0.rc.1 → 1.5.0.rc.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/CHANGELOG +4 -0
  2. data/VERSION.yml +1 -1
  3. data/lib/frameworks/sproutcore/Buildfile +9 -4
  4. data/lib/frameworks/sproutcore/README.md +1 -0
  5. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/QuickLook/Preview.pdf +0 -0
  6. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/QuickLook/Thumbnail.tiff +0 -0
  7. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/data.plist +0 -0
  8. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image10.png +0 -0
  9. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image11.png +0 -0
  10. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image13.png +0 -0
  11. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image15.png +0 -0
  12. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image16.png +0 -0
  13. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image17.png +0 -0
  14. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image18.png +0 -0
  15. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image19.png +0 -0
  16. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image22.tiff +0 -0
  17. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image23.png +0 -0
  18. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image24.png +0 -0
  19. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image25.png +0 -0
  20. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image30.png +0 -0
  21. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image31.png +0 -0
  22. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image8.png +0 -0
  23. data/lib/frameworks/sproutcore/design/{TestRunner_Design.gaffle → TestRunner_Design.graffle}/image9.png +0 -0
  24. data/lib/frameworks/sproutcore/frameworks/animation/core.js +23 -25
  25. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +160 -0
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +73 -82
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/core.js +1 -3
  28. data/lib/frameworks/sproutcore/frameworks/{handlebars/extensions → core_foundation/ext/handlebars}/bind.js +110 -7
  29. data/lib/frameworks/sproutcore/frameworks/{handlebars/extensions → core_foundation/ext/handlebars}/collection.js +10 -7
  30. data/lib/frameworks/sproutcore/frameworks/{handlebars/extensions → core_foundation/ext/handlebars}/localization.js +1 -1
  31. data/lib/frameworks/sproutcore/frameworks/{handlebars/extensions → core_foundation/ext/handlebars}/view.js +4 -2
  32. data/lib/frameworks/sproutcore/frameworks/{handlebars/extensions.js → core_foundation/ext/handlebars.js} +0 -57
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/object.js +1 -3
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +11 -0
  35. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/main.js +1 -3
  36. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +2 -4
  37. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/application.js +14 -16
  38. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/builder.js +29 -37
  39. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/datetime.js +0 -0
  40. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +71 -19
  41. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +3 -7
  42. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/page.js +5 -7
  43. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/selection_set.js +1 -3
  44. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +4 -0
  45. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/timer.js +21 -27
  46. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +3 -5
  47. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +3 -3
  48. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/single_enumerable_case.js +1 -1
  49. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/sparse_array.js +1 -1
  50. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +93 -1
  51. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +1 -1
  52. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/convertLayouts.js +13 -11
  53. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layer.js +2 -6
  54. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +4 -4
  55. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/theme.js +2 -0
  56. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view.js +4 -4
  57. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template.js +6 -2
  58. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template_collection.js +87 -32
  59. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +21 -25
  60. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/cascade.js +15 -19
  61. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +114 -167
  62. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +4 -4
  63. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +4 -6
  64. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +2 -4
  65. data/lib/frameworks/sproutcore/frameworks/datastore/models/fetched_attribute.js +7 -7
  66. data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +18 -20
  67. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +74 -72
  68. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +36 -29
  69. data/lib/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +2 -2
  70. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +97 -78
  71. data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +117 -97
  72. data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +13 -13
  73. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +111 -108
  74. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +231 -198
  75. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +146 -145
  76. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/builders.js +21 -21
  77. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/flush.js +49 -50
  78. data/lib/frameworks/sproutcore/frameworks/datetime/{system → frameworks/core/system}/datetime.js +122 -171
  79. data/lib/frameworks/sproutcore/frameworks/datetime/{tests → frameworks/core/tests}/system/datetime.js +0 -0
  80. data/lib/frameworks/sproutcore/frameworks/datetime/{resources → frameworks/localized/resources}/strings.js +0 -0
  81. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +91 -0
  82. data/lib/frameworks/sproutcore/frameworks/desktop/core.js +18 -2
  83. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +23 -16
  84. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_fast_path.js +56 -45
  85. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_group.js +5 -2
  86. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +21 -19
  87. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +82 -77
  88. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/navigation_builder.js +18 -12
  89. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +29 -17
  90. data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +148 -107
  91. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +31 -16
  92. data/lib/frameworks/sproutcore/frameworks/desktop/panes/modal.js +16 -13
  93. data/lib/frameworks/sproutcore/frameworks/desktop/panes/palette.js +38 -17
  94. data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +37 -25
  95. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +247 -144
  96. data/lib/frameworks/sproutcore/frameworks/desktop/panes/select_button.js +155 -100
  97. data/lib/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +39 -17
  98. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +9 -6
  99. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_source.js +18 -22
  100. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +27 -17
  101. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +77 -44
  102. data/lib/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +68 -33
  103. data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +168 -110
  104. data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +37 -5
  105. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +187 -123
  106. data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +73 -49
  107. data/lib/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +34 -9
  108. data/lib/frameworks/sproutcore/frameworks/desktop/views/file.js +51 -14
  109. data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +38 -8
  110. data/lib/frameworks/sproutcore/frameworks/desktop/views/image_button.js +15 -9
  111. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +54 -34
  112. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +113 -42
  113. data/lib/frameworks/sproutcore/frameworks/desktop/views/master_detail.js +84 -28
  114. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +67 -51
  115. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +122 -35
  116. data/lib/frameworks/sproutcore/frameworks/desktop/views/navigation.js +40 -16
  117. data/lib/frameworks/sproutcore/frameworks/desktop/views/navigation_bar.js +28 -18
  118. data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +27 -31
  119. data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +118 -68
  120. data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +117 -61
  121. data/lib/frameworks/sproutcore/frameworks/desktop/views/scene.js +23 -16
  122. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +241 -77
  123. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +134 -69
  124. data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +107 -25
  125. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +125 -48
  126. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +165 -69
  127. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +73 -24
  128. data/lib/frameworks/sproutcore/frameworks/desktop/views/separator.js +19 -5
  129. data/lib/frameworks/sproutcore/frameworks/desktop/views/source_list.js +16 -4
  130. data/lib/frameworks/sproutcore/frameworks/desktop/views/source_list_group.js +14 -7
  131. data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +43 -37
  132. data/lib/frameworks/sproutcore/frameworks/desktop/views/split_divider.js +8 -1
  133. data/lib/frameworks/sproutcore/frameworks/desktop/views/stacked.js +14 -3
  134. data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +16 -2
  135. data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +99 -0
  136. data/lib/frameworks/sproutcore/frameworks/desktop/views/thumb.js +13 -1
  137. data/lib/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +58 -8
  138. data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +34 -18
  139. data/lib/frameworks/sproutcore/frameworks/desktop/views/well.js +25 -9
  140. data/lib/frameworks/sproutcore/frameworks/desktop/views/workspace.js +70 -36
  141. data/lib/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +10 -5
  142. data/lib/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +28 -17
  143. data/lib/frameworks/sproutcore/frameworks/foundation/delegates/inline_text_field.js +41 -43
  144. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/pinch.js +42 -4
  145. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/swipe.js +94 -4
  146. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/tap.js +41 -1
  147. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_mixin.js +2 -0
  148. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +18 -9
  149. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/collection_content.js +7 -5
  150. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_display.js +7 -8
  151. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +34 -24
  152. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/control.js +48 -18
  153. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +1 -0
  154. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +1 -2
  155. data/lib/frameworks/sproutcore/frameworks/foundation/tasks/preload_bundle.js +1 -1
  156. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +0 -11
  157. data/lib/frameworks/sproutcore/frameworks/foundation/validators/date_time.js +1 -1
  158. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +8 -0
  159. data/lib/frameworks/sproutcore/frameworks/qunit/README.md +24 -0
  160. data/lib/frameworks/sproutcore/frameworks/qunit/package.json +21 -0
  161. data/lib/frameworks/sproutcore/frameworks/qunit/qunit/qunit.css +215 -0
  162. data/lib/frameworks/sproutcore/frameworks/qunit/qunit/qunit.js +1442 -0
  163. data/lib/frameworks/sproutcore/frameworks/qunit/test/headless.html +24 -0
  164. data/lib/frameworks/sproutcore/frameworks/qunit/test/index.html +18 -0
  165. data/lib/frameworks/sproutcore/frameworks/qunit/test/logs.html +17 -0
  166. data/lib/frameworks/sproutcore/frameworks/qunit/test/logs.js +150 -0
  167. data/lib/frameworks/sproutcore/frameworks/qunit/test/same.js +1421 -0
  168. data/lib/frameworks/sproutcore/frameworks/qunit/test/test.js +314 -0
  169. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
  170. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +369 -60
  171. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +2 -405
  172. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +3 -9
  173. data/lib/frameworks/sproutcore/frameworks/runtime/private/property_chain.js +50 -45
  174. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +20 -1
  175. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +0 -9
  176. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/guidFor.js +1 -1
  177. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +36 -14
  178. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable/enumerable.js +0 -34
  179. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable/enumerable_observers.js +50 -61
  180. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +2 -2
  181. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/propertyChanges.js +1 -1
  182. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/registerDependentKeys.js +45 -1
  183. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/propertyChanges.js +1 -1
  184. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/bindings.js +5 -0
  185. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +1 -1
  186. data/lib/frameworks/sproutcore/frameworks/testing/core.js +3 -0
  187. data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +0 -1
  188. data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +0 -1
  189. data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +1 -1
  190. data/vendor/chance/lib/chance/instance.rb +8 -6
  191. metadata +41 -31
  192. data/lib/frameworks/sproutcore/frameworks/testing/jquery.js +0 -3559
  193. data/lib/frameworks/sproutcore/frameworks/testing/qunit.js +0 -827
@@ -10,106 +10,107 @@ sc_require('models/record');
10
10
  /**
11
11
  @class
12
12
 
13
- A RecordArray wraps an array of storeKeys and, optionally, a Query object.
14
- When you access the items of a RecordArray it will automatically convert the
15
- storeKeys into actual SC.Record objects that the rest of your application
16
- can work with.
13
+ A `RecordArray` wraps an array of `storeKeys` and, optionally, a `Query`
14
+ object. When you access the items of a `RecordArray`, it will automatically
15
+ convert the `storeKeys` into actual `SC.Record` objects that the rest of
16
+ your application can work with.
17
17
 
18
- Normally you do not create RecordArray's yourself. Instead, a RecordArray
19
- is returned when you call SC.Store.findAll(), already properly configured.
20
- You can usually just work with the RecordArray instance just like another
21
- array.
18
+ Normally you do not create `RecordArray`s yourself. Instead, a
19
+ `RecordArray` is returned when you call `SC.Store.findAll()`, already
20
+ properly configured. You can usually just work with the `RecordArray`
21
+ instance just like any other array.
22
22
 
23
- The information below about RecordArray internals is only intended for those
24
- who need to override this class for some reason to do something special.
23
+ The information below about `RecordArray` internals is only intended for
24
+ those who need to override this class for some reason to do something
25
+ special.
25
26
 
26
27
  Internal Notes
27
28
  ---
28
29
 
29
- Normally the RecordArray behavior is very simple. Any array-like operations
30
- will be translated into similar calls onto the underlying array of
31
- storeKeys. The underlying array can be a real array or it may be a
32
- SparseArray, which is how you implement incremental loading.
30
+ Normally the `RecordArray` behavior is very simple. Any array-like
31
+ operations will be translated into similar calls onto the underlying array
32
+ of `storeKeys`. The underlying array can be a real array or it may be a
33
+ `SparseArray`, which is how you implement incremental loading.
33
34
 
34
- If the RecordArray is created with an SC.Query object as well (and it
35
- almost always will have a Query object), then the RecordArray will also
35
+ If the `RecordArray` is created with an `SC.Query` object as well (and it
36
+ almost always will have a `Query` object), then the `RecordArray` will also
36
37
  consult the query for various delegate operations such as determining if
37
38
  the record array should update automatically whenever records in the store
38
- changes. It will also ask the Query to refresh the storeKeys whenever records
39
- change in the store.
39
+ changes. It will also ask the `Query` to refresh the `storeKeys` whenever
40
+ records change in the store.
40
41
 
41
- If the SC.Query object has complex matching rules, it might be
42
+ If the `SC.Query` object has complex matching rules, it might be
42
43
  computationally heavy to match a large dataset to a query. To avoid the
43
44
  browser from ever showing a slow script timer in this scenario, the query
44
- matching is by default paced at 100ms. If query matching takes longer than
45
+ matching is by default paced at 100ms. If query matching takes longer than
45
46
  100ms, it will chunk the work with setTimeout to avoid too much computation
46
47
  to happen in one runloop.
47
-
48
-
48
+
49
+
49
50
  @extends SC.Object
50
51
  @extends SC.Enumerable
51
52
  @extends SC.Array
52
53
  @since SproutCore 1.0
53
54
  */
54
55
 
55
- SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
56
+ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
56
57
  /** @scope SC.RecordArray.prototype */ {
57
-
58
+
58
59
  /**
59
60
  The store that owns this record array. All record arrays must have a
60
61
  store to function properly.
61
62
 
62
- NOTE: You MUST set this property on the RecordArray when creating it or
63
- else it will fail.
63
+ NOTE: You **MUST** set this property on the `RecordArray` when creating
64
+ it or else it will fail.
64
65
 
65
66
  @type SC.Store
66
67
  */
67
68
  store: null,
68
69
 
69
70
  /**
70
- The Query object this record array is based upon. All record arrays MUST
71
- have an associated query in order to function correctly. You cannot
72
- change this property once it has been set.
71
+ The `Query` object this record array is based upon. All record arrays
72
+ **MUST** have an associated query in order to function correctly. You
73
+ cannot change this property once it has been set.
73
74
 
74
- NOTE: You MUST set this property on the RecordArray when creating it or
75
- else it will fail.
75
+ NOTE: You **MUST** set this property on the `RecordArray` when creating
76
+ it or else it will fail.
76
77
 
77
78
  @type SC.Query
78
79
  */
79
80
  query: null,
80
81
 
81
82
  /**
82
- The array of storeKeys as retrieved from the owner store.
83
+ The array of `storeKeys` as retrieved from the owner store.
83
84
 
84
85
  @type SC.Array
85
86
  */
86
87
  storeKeys: null,
87
88
 
88
89
  /**
89
- The current status for the record array. Read from the underlying
90
+ The current status for the record array. Read from the underlying
90
91
  store.
91
-
92
+
92
93
  @type Number
93
94
  */
94
95
  status: SC.Record.EMPTY,
95
-
96
+
96
97
  /**
97
98
  The current editabile state based on the query.
98
-
99
- @property
99
+
100
+ @property
100
101
  @type Boolean
101
102
  */
102
103
  isEditable: function() {
103
104
  var query = this.get('query');
104
105
  return query ? query.get('isEditable') : NO;
105
106
  }.property('query').cacheable(),
106
-
107
+
107
108
  // ..........................................................
108
109
  // ARRAY PRIMITIVES
109
- //
110
+ //
110
111
 
111
112
  /** @private
112
- Returned length is a pass-through to the storeKeys array.
113
+ Returned length is a pass-through to the `storeKeys` array.
113
114
  @property
114
115
  */
115
116
  length: function() {
@@ -119,11 +120,11 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
119
120
  }.property('storeKeys').cacheable(),
120
121
 
121
122
  _scra_records: null,
122
-
123
+
123
124
  /** @private
124
- Looks up the store key in the store keys array and materializes a
125
+ Looks up the store key in the `storeKeys array and materializes a
125
126
  records.
126
-
127
+
127
128
  @param {Number} idx index of the object
128
129
  @return {SC.Record} materialized record
129
130
  */
@@ -131,20 +132,20 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
131
132
 
132
133
  this.flush(); // cleanup pending if needed
133
134
 
134
- var recs = this._scra_records,
135
+ var recs = this._scra_records,
135
136
  storeKeys = this.get('storeKeys'),
136
137
  store = this.get('store'),
137
138
  storeKey, ret ;
138
-
139
+
139
140
  if (!storeKeys || !store) return undefined; // nothing to do
140
141
  if (recs && (ret=recs[idx])) return ret ; // cached
141
-
142
+
142
143
  // not in cache, materialize
143
144
  if (!recs) this._scra_records = recs = [] ; // create cache
144
145
  storeKey = storeKeys.objectAt(idx);
145
-
146
+
146
147
  if (storeKey) {
147
- // if record is not loaded already, then ask the data source to
148
+ // if record is not loaded already, then ask the data source to
148
149
  // retrieve it
149
150
  if (store.peekStatus(storeKey) === SC.Record.EMPTY) {
150
151
  store.retrieveRecord(null, null, storeKey);
@@ -157,17 +158,17 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
157
158
  /** @private - optimized forEach loop. */
158
159
  forEach: function(callback, target) {
159
160
  this.flush();
160
-
161
- var recs = this._scra_records,
161
+
162
+ var recs = this._scra_records,
162
163
  storeKeys = this.get('storeKeys'),
163
- store = this.get('store'),
164
+ store = this.get('store'),
164
165
  len = storeKeys ? storeKeys.get('length') : 0,
165
166
  idx, storeKey, rec;
166
-
167
- if (!storeKeys || !store) return this; // nothing to do
167
+
168
+ if (!storeKeys || !store) return this; // nothing to do
168
169
  if (!recs) recs = this._scra_records = [] ;
169
170
  if (!target) target = this;
170
-
171
+
171
172
  for(idx=0;idx<len;idx++) {
172
173
  rec = recs[idx];
173
174
  if (!rec) {
@@ -175,13 +176,13 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
175
176
  }
176
177
  callback.call(target, rec, idx, this);
177
178
  }
178
-
179
+
179
180
  return this;
180
181
  },
181
-
182
+
182
183
  /** @private
183
184
  Pass through to the underlying array. The passed in objects must be
184
- records, which can be converted to storeKeys.
185
+ records, which can be converted to `storeKeys`.
185
186
 
186
187
  @param {Number} idx start index
187
188
  @param {Number} amt end index
@@ -191,42 +192,42 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
191
192
  replace: function(idx, amt, recs) {
192
193
 
193
194
  this.flush(); // cleanup pending if needed
194
-
195
- var storeKeys = this.get('storeKeys'),
195
+
196
+ var storeKeys = this.get('storeKeys'),
196
197
  len = recs ? (recs.get ? recs.get('length') : recs.length) : 0,
197
198
  i, keys;
198
-
199
+
199
200
  if (!storeKeys) throw "storeKeys required";
200
201
 
201
202
  var query = this.get('query');
202
203
  if (query && !query.get('isEditable')) throw SC.RecordArray.NOT_EDITABLE;
203
-
204
- // you can't modify an array whose store keys are autogenerated from a
204
+
205
+ // you can't modify an array whose store keys are autogenerated from a
205
206
  // query.
206
-
207
+
207
208
  // map to store keys
208
209
  keys = [] ;
209
210
  for(i=0;i<len;i++) keys[i] = recs.objectAt(i).get('storeKey');
210
-
211
- // pass along - if allowed, this should trigger the content observer
211
+
212
+ // pass along - if allowed, this should trigger the content observer
212
213
  storeKeys.replace(idx, amt, keys);
213
- return this;
214
+ return this;
214
215
  },
215
-
216
+
216
217
  /**
217
- Returns YES if the passed can be found in the record array. This is
218
+ Returns YES if the passed can be found in the record array. This is
218
219
  provided for compatibility with SC.Set.
219
-
220
+
220
221
  @param {SC.Record} record
221
222
  @returns {Boolean}
222
223
  */
223
224
  contains: function(record) {
224
225
  return this.indexOf(record)>=0;
225
226
  },
226
-
227
+
227
228
  /** @private
228
229
  Returns the first index where the specified record is found.
229
-
230
+
230
231
  @param {SC.Record} record
231
232
  @param {Number} startAt optional starting index
232
233
  @returns {Number} index
@@ -236,18 +237,18 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
236
237
  SC.Logger.warn("Using indexOf on %@ with an object that is not an SC.Record".fmt(record));
237
238
  return -1; // only takes records
238
239
  }
239
-
240
+
240
241
  this.flush();
241
-
242
- var storeKey = record.get('storeKey'),
242
+
243
+ var storeKey = record.get('storeKey'),
243
244
  storeKeys = this.get('storeKeys');
244
-
245
- return storeKeys ? storeKeys.indexOf(storeKey, startAt) : -1;
245
+
246
+ return storeKeys ? storeKeys.indexOf(storeKey, startAt) : -1;
246
247
  },
247
248
 
248
- /** @private
249
+ /** @private
249
250
  Returns the last index where the specified record is found.
250
-
251
+
251
252
  @param {SC.Record} record
252
253
  @param {Number} startAt optional starting index
253
254
  @returns {Number} index
@@ -259,15 +260,15 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
259
260
  }
260
261
 
261
262
  this.flush();
262
-
263
- var storeKey = record.get('storeKey'),
263
+
264
+ var storeKey = record.get('storeKey'),
264
265
  storeKeys = this.get('storeKeys');
265
- return storeKeys ? storeKeys.lastIndexOf(storeKey, startAt) : -1;
266
+ return storeKeys ? storeKeys.lastIndexOf(storeKey, startAt) : -1;
266
267
  },
267
268
 
268
269
  /**
269
270
  Adds the specified record to the record array if it is not already part
270
- of the array. Provided for compatibilty with SC.Set.
271
+ of the array. Provided for compatibilty with `SC.Set`.
271
272
 
272
273
  @param {SC.Record} record
273
274
  @returns {SC.RecordArray} receiver
@@ -277,10 +278,10 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
277
278
  if (this.indexOf(record)<0) this.pushObject(record);
278
279
  return this ;
279
280
  },
280
-
281
+
281
282
  /**
282
283
  Removes the specified record from the array if it is not already a part
283
- of the array. Provided for compatibility with SC.Set.
284
+ of the array. Provided for compatibility with `SC.Set`.
284
285
 
285
286
  @param {SC.Record} record
286
287
  @returns {SC.RecordArray} receiver
@@ -290,43 +291,43 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
290
291
  this.removeObject(record);
291
292
  return this ;
292
293
  },
293
-
294
+
294
295
  // ..........................................................
295
296
  // HELPER METHODS
296
- //
297
+ //
297
298
 
298
299
  /**
299
300
  Extends the standard SC.Enumerable implementation to return results based
300
301
  on a Query if you pass it in.
301
-
302
+
302
303
  @param {SC.Query} query a SC.Query object
303
304
  @param {Object} target the target object to use
304
-
305
- @returns {SC.RecordArray}
305
+
306
+ @returns {SC.RecordArray}
306
307
  */
307
308
  find: function(query, target) {
308
309
  if (query && query.isQuery) {
309
310
  return this.get('store').find(query.queryWithScope(this));
310
311
  } else return sc_super();
311
312
  },
312
-
313
+
313
314
  /**
314
315
  Call whenever you want to refresh the results of this query. This will
315
316
  notify the data source, asking it to refresh the contents.
316
-
317
+
317
318
  @returns {SC.RecordArray} receiver
318
319
  */
319
320
  refresh: function() {
320
321
  this.get('store').refreshQuery(this.get('query'));
321
322
  return this;
322
323
  },
323
-
324
+
324
325
  /**
325
- Will recompute the results based on the SC.Query attached to the record
326
+ Will recompute the results based on the `SC.Query` attached to the record
326
327
  array. Useful if your query is based on computed properties that might
327
- have changed. Use refresh() instead of you want to trigger a fetch on your
328
- data source since this will purely look at records already loaded into
329
- the store.
328
+ have changed. Use `refresh()` instead of you want to trigger a fetch on
329
+ your data source since this will purely look at records already loaded
330
+ into the store.
330
331
 
331
332
  @returns {SC.RecordArray} receiver
332
333
  */
@@ -334,35 +335,35 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
334
335
  this.flush(YES);
335
336
  return this;
336
337
  },
337
-
338
+
338
339
  /**
339
- Destroys the record array. Releases any storeKeys, and deregisters with
340
+ Destroys the record array. Releases any `storeKeys`, and deregisters with
340
341
  the owner store.
341
-
342
+
342
343
  @returns {SC.RecordArray} receiver
343
344
  */
344
345
  destroy: function() {
345
346
  if (!this.get('isDestroyed')) {
346
347
  this.get('store').recordArrayWillDestroy(this);
347
- }
348
-
348
+ }
349
+
349
350
  sc_super();
350
351
  },
351
-
352
+
352
353
  // ..........................................................
353
354
  // STORE CALLBACKS
354
355
  //
355
356
 
356
- // NOTE: storeWillFetchQuery(), storeDidFetchQuery(), storeDidCancelQuery(),
357
- // and storeDidErrorQuery() are tested implicitly through the related
358
- // methods in SC.Store. We're doing it this way because eventually this
359
- // particular implementation is likely to change; moving some or all of this
360
- // code directly into the store. -CAJ
357
+ // **NOTE**: `storeWillFetchQuery()`, `storeDidFetchQuery()`,
358
+ // `storeDidCancelQuery()`, and `storeDidErrorQuery()` are tested implicitly
359
+ // through the related methods in `SC.Store`. We're doing it this way
360
+ // because eventually this particular implementation is likely to change;
361
+ // moving some or all of this code directly into the store. -CAJ
361
362
 
362
363
  /** @private
363
- Called whenever the store initiates a refresh of the query. Sets the
364
+ Called whenever the store initiates a refresh of the query. Sets the
364
365
  status of the record array to the appropriate status.
365
-
366
+
366
367
  @param {SC.Query} query
367
368
  @returns {SC.RecordArray} receiver
368
369
  */
@@ -374,10 +375,10 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
374
375
  this.setIfChanged('status', status);
375
376
  return this ;
376
377
  },
377
-
378
+
378
379
  /** @private
379
380
  Called whenever the store has finished fetching a query.
380
-
381
+
381
382
  @param {SC.Query} query
382
383
  @returns {SC.RecordArray} receiver
383
384
  */
@@ -385,11 +386,11 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
385
386
  this.setIfChanged('status', SC.Record.READY_CLEAN);
386
387
  return this ;
387
388
  },
388
-
389
+
389
390
  /** @private
390
- Called whenever the store has cancelled a refresh. Sets the
391
+ Called whenever the store has cancelled a refresh. Sets the
391
392
  status of the record array to the appropriate status.
392
-
393
+
393
394
  @param {SC.Query} query
394
395
  @returns {SC.RecordArray} receiver
395
396
  */
@@ -403,9 +404,9 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
403
404
  },
404
405
 
405
406
  /** @private
406
- Called whenever the store encounters an error while fetching. Sets the
407
+ Called whenever the store encounters an error while fetching. Sets the
407
408
  status of the record array to the appropriate status.
408
-
409
+
409
410
  @param {SC.Query} query
410
411
  @returns {SC.RecordArray} receiver
411
412
  */
@@ -413,13 +414,13 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
413
414
  this.setIfChanged('status', SC.Record.ERROR);
414
415
  return this ;
415
416
  },
416
-
417
+
417
418
  /** @private
418
419
  Called by the store whenever it changes the state of certain store keys.
419
420
  If the receiver cares about these changes, it will mark itself as dirty.
420
- The next time you try to access the record array it will update any
421
+ The next time you try to access the record array it will update any
421
422
  pending changes.
422
-
423
+
423
424
  @param {SC.Array} storeKeys the effected store keys
424
425
  @param {SC.Set} recordTypes the record types for the storeKeys.
425
426
  @returns {SC.RecordArray} receiver
@@ -428,19 +429,19 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
428
429
  var query = this.get('query');
429
430
  // fast path exits
430
431
  if (query.get('location') !== SC.Query.LOCAL) return this;
431
- if (!query.containsRecordTypes(recordTypes)) return this;
432
-
432
+ if (!query.containsRecordTypes(recordTypes)) return this;
433
+
433
434
  // ok - we're interested. mark as dirty and save storeKeys.
434
435
  var changed = this._scq_changedStoreKeys;
435
436
  if (!changed) changed = this._scq_changedStoreKeys = SC.IndexSet.create();
436
437
  changed.addEach(storeKeys);
437
-
438
+
438
439
  this.set('needsFlush', YES);
439
-
440
+
440
441
  // if we have storeKeys already, then flush immediately because
441
442
  // it will not be as expensive as if we are starting from scratch
442
- if (this.get('storeKeys')) {
443
- this.flush();
443
+ if (this.get('storeKeys')) {
444
+ this.flush();
444
445
  }
445
446
  else {
446
447
  this.enumerableContentDidChange();
@@ -448,18 +449,18 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
448
449
 
449
450
  return this;
450
451
  },
451
-
452
+
452
453
  /**
453
454
  Applies the query to any pending changed store keys, updating the record
454
455
  array contents as necessary. This method is called automatically anytime
455
- you access the RecordArray to make sure it is up to date, but you can
456
+ you access the RecordArray to make sure it is up to date, but you can
456
457
  call it yourself as well if you need to force the record array to fully
457
458
  update immediately.
458
459
 
459
460
  Currently this method only has an effect if the query location is
460
- SC.Query.LOCAL. You can call this method on any RecordArray however,
461
+ `SC.Query.LOCAL`. You can call this method on any `RecordArray` however,
461
462
  without an error.
462
-
463
+
463
464
  @param {Boolean} _flush to force it - use reload() to trigger it
464
465
  @returns {SC.RecordArray} receiver
465
466
  */
@@ -471,19 +472,19 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
471
472
  this.set('needsFlush', YES);
472
473
  return this;
473
474
  }
474
-
475
+
475
476
  if (!this.get('needsFlush') && !_flush) return this; // nothing to do
476
477
  this.set('needsFlush', NO); // avoid running again.
477
-
478
+
478
479
  // fast exit
479
480
  var query = this.get('query'),
480
- store = this.get('store');
481
+ store = this.get('store');
481
482
  if (!store || !query || query.get('location') !== SC.Query.LOCAL) {
482
483
  return this;
483
484
  }
484
-
485
+
485
486
  this._insideFlush = YES;
486
-
487
+
487
488
  // OK, actually generate some results
488
489
  var storeKeys = this.get('storeKeys'),
489
490
  changed = this._scq_changedStoreKeys,
@@ -492,11 +493,11 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
492
493
  storeKeysToPace = [],
493
494
  startDate = new Date(),
494
495
  rec, status, recordType, sourceKeys, scope, included;
495
-
496
+
496
497
  // if we have storeKeys already, just look at the changed keys
497
498
  var oldStoreKeys = storeKeys;
498
499
  if (storeKeys && !_flush) {
499
-
500
+
500
501
  if (changed) {
501
502
  changed.forEach(function(storeKey) {
502
503
  if(storeKeysToPace.length>0 || new Date()-startDate>SC.RecordArray.QUERY_MATCHING_THRESHOLD) {
@@ -509,12 +510,12 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
509
510
  rec = store.materializeRecord(storeKey);
510
511
  included = !!(rec && query.contains(rec));
511
512
  } else included = NO ;
512
-
513
+
513
514
  // if storeKey should be in set but isn't -- add it.
514
515
  if (included) {
515
516
  if (storeKeys.indexOf(storeKey)<0) {
516
- if (!didChange) storeKeys = storeKeys.copy();
517
- storeKeys.pushObject(storeKey);
517
+ if (!didChange) storeKeys = storeKeys.copy();
518
+ storeKeys.pushObject(storeKey);
518
519
  }
519
520
  // if storeKey should NOT be in set but IS -- remove it
520
521
  } else {
@@ -523,31 +524,31 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
523
524
  storeKeys.removeObject(storeKey);
524
525
  } // if (storeKeys.indexOf)
525
526
  } // if (included)
526
-
527
+
527
528
  }, this);
528
529
  // make sure resort happens
529
530
  didChange = YES ;
530
-
531
+
531
532
  } // if (changed)
532
-
533
+
533
534
  //console.log(this.toString() + ' partial flush took ' + (new Date()-startDate) + ' ms');
534
-
535
- // if no storeKeys, then we have to go through all of the storeKeys
535
+
536
+ // if no storeKeys, then we have to go through all of the storeKeys
536
537
  // and decide if they belong or not. ick.
537
538
  } else {
538
-
539
+
539
540
  // collect the base set of keys. if query has a parent scope, use that
540
541
  if (scope = query.get('scope')) {
541
542
  sourceKeys = scope.flush().get('storeKeys');
542
543
  // otherwise, lookup all storeKeys for the named recordType...
543
544
  } else if (recordType = query.get('expandedRecordTypes')) {
544
545
  sourceKeys = SC.IndexSet.create();
545
- recordType.forEach(function(cur) {
546
+ recordType.forEach(function(cur) {
546
547
  sourceKeys.addEach(store.storeKeysFor(recordType));
547
548
  });
548
549
  }
549
-
550
- // loop through storeKeys to determine if it belongs in this query or
550
+
551
+ // loop through storeKeys to determine if it belongs in this query or
551
552
  // not.
552
553
  storeKeys = [];
553
554
  sourceKeys.forEach(function(storeKey) {
@@ -555,24 +556,24 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
555
556
  storeKeysToPace.push(storeKey);
556
557
  return;
557
558
  }
558
-
559
+
559
560
  status = store.peekStatus(storeKey);
560
561
  if (!(status & K.EMPTY) && !((status & K.DESTROYED) || (status === K.BUSY_DESTROYING))) {
561
562
  rec = store.materializeRecord(storeKey);
562
563
  if (rec && query.contains(rec)) storeKeys.push(storeKey);
563
564
  }
564
565
  });
565
-
566
+
566
567
  //console.log(this.toString() + ' full flush took ' + (new Date()-startDate) + ' ms');
567
-
568
+
568
569
  didChange = YES ;
569
570
  }
570
-
571
+
571
572
  // if we reach our threshold of pacing we need to schedule the rest of the
572
573
  // storeKeys to also be updated
573
574
  if(storeKeysToPace.length>0) {
574
575
  var self = this;
575
- // use setTimeout here to guarantee that we hit the next runloop,
576
+ // use setTimeout here to guarantee that we hit the next runloop,
576
577
  // and not the same runloop which the invoke* methods do not guarantee
577
578
  window.setTimeout(function() {
578
579
  SC.run(function() {
@@ -583,18 +584,18 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
583
584
  });
584
585
  }, 1);
585
586
  }
586
-
587
+
587
588
  // clear set of changed store keys
588
589
  if (changed) changed.clear();
589
-
590
+
590
591
  // only resort and update if we did change
591
592
  if (didChange) {
592
-
593
+
593
594
  // storeKeys must be a new instance because orderStoreKeys() works on it
594
595
  if (storeKeys && (storeKeys===oldStoreKeys)) {
595
596
  storeKeys = storeKeys.copy();
596
597
  }
597
-
598
+
598
599
  storeKeys = SC.Query.orderStoreKeys(storeKeys, query, store);
599
600
  if (SC.compare(oldStoreKeys, storeKeys) !== 0){
600
601
  this.set('storeKeys', SC.clone(storeKeys)); // replace content
@@ -606,21 +607,21 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
606
607
  },
607
608
 
608
609
  /**
609
- Set to YES when the query is dirty and needs to update its storeKeys
610
- before returning any results. RecordArrays always start dirty and become
610
+ Set to `YES` when the query is dirty and needs to update its storeKeys
611
+ before returning any results. `RecordArray`s always start dirty and become
611
612
  clean the first time you try to access their contents.
612
-
613
+
613
614
  @type Boolean
614
615
  */
615
616
  needsFlush: YES,
616
617
 
617
618
  // ..........................................................
618
619
  // EMULATE SC.ERROR API
619
- //
620
-
620
+ //
621
+
621
622
  /**
622
- Returns YES whenever the status is SC.Record.ERROR. This will allow you
623
- to put the UI into an error state.
623
+ Returns `YES` whenever the status is `SC.Record.ERROR`. This will allow
624
+ you to put the UI into an error state.
624
625
 
625
626
  @property
626
627
  @type Boolean
@@ -630,8 +631,8 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
630
631
  }.property('status').cacheable(),
631
632
 
632
633
  /**
633
- Returns the receiver if the record array is in an error state. Returns null
634
- otherwise.
634
+ Returns the receiver if the record array is in an error state. Returns
635
+ `null` otherwise.
635
636
 
636
637
  @property
637
638
  @type SC.Record
@@ -639,10 +640,11 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
639
640
  errorValue: function() {
640
641
  return this.get('isError') ? SC.val(this.get('errorObject')) : null ;
641
642
  }.property('isError').cacheable(),
642
-
643
+
643
644
  /**
644
- Returns the current error object only if the record array is in an error state.
645
- If no explicit error object has been set, returns SC.Record.GENERIC_ERROR.
645
+ Returns the current error object only if the record array is in an error
646
+ state. If no explicit error object has been set, returns
647
+ `SC.Record.GENERIC_ERROR.`
646
648
 
647
649
  @property
648
650
  @type SC.Error
@@ -653,65 +655,96 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
653
655
  return store.readQueryError(this.get('query')) || SC.Record.GENERIC_ERROR;
654
656
  } else return null ;
655
657
  }.property('isError').cacheable(),
656
-
658
+
657
659
  // ..........................................................
658
660
  // INTERNAL SUPPORT
659
661
  //
660
-
661
- /** @private
662
- Invoked whenever the storeKeys array changes. Observes changes.
662
+
663
+ propertyWillChange: function(key) {
664
+ if (key === 'storeKeys') {
665
+ var storeKeys = this.get('storeKeys');
666
+ var len = storeKeys ? storeKeys.get('length') : 0;
667
+
668
+ this.arrayContentWillChange(0, len, 0);
669
+ }
670
+
671
+ return sc_super();
672
+ },
673
+
674
+ /** @private
675
+ Invoked whenever the `storeKeys` array changes. Observes changes.
663
676
  */
664
677
  _storeKeysDidChange: function() {
665
678
  var storeKeys = this.get('storeKeys');
666
-
667
- var prev = this._prevStoreKeys,
679
+
680
+ var prev = this._prevStoreKeys, oldLen, newLen,
668
681
  f = this._storeKeysContentDidChange,
669
682
  fs = this._storeKeysStateDidChange;
670
-
671
- if (storeKeys === prev) return; // nothing to do
672
-
673
- if (prev) prev.removeObserver('[]', this, f);
683
+
684
+ if (storeKeys === prev) { return; } // nothing to do
685
+
686
+ if (prev) {
687
+ prev.removeArrayObservers({
688
+ target: this,
689
+ willChange: this.arrayContentWillChange,
690
+ didChange: this._storeKeysContentDidChange
691
+ });
692
+
693
+ oldLen = prev.get('length');
694
+ } else {
695
+ oldLen = 0;
696
+ }
697
+
674
698
  this._prevStoreKeys = storeKeys;
675
- if (storeKeys) storeKeys.addObserver('[]', this, f);
676
-
677
- var rev = (storeKeys) ? storeKeys.propertyRevision : -1 ;
678
- this._storeKeysContentDidChange(storeKeys, '[]', storeKeys, rev);
679
-
699
+ if (storeKeys) {
700
+ storeKeys.addArrayObservers({
701
+ target: this,
702
+ willChange: this.arrayContentWillChange,
703
+ didChange: this._storeKeysContentDidChange
704
+ });
705
+
706
+ newLen = storeKeys.get('length');
707
+ } else {
708
+ newLen = 0;
709
+ }
710
+
711
+ this._storeKeysContentDidChange(0, oldLen, newLen);
712
+
680
713
  }.observes('storeKeys'),
681
-
714
+
682
715
  /** @private
683
- Invoked whenever the content of the storeKeys array changes. This will
716
+ Invoked whenever the content of the `storeKeys` array changes. This will
684
717
  dump any cached record lookup and then notify that the enumerable content
685
718
  has changed.
686
719
  */
687
- _storeKeysContentDidChange: function(target, key, value, rev) {
720
+ _storeKeysContentDidChange: function(start, removedCount, addedCount) {
688
721
  if (this._scra_records) this._scra_records.length=0 ; // clear cache
689
-
690
- this.enumerableContentDidChange();
722
+
723
+ this.arrayContentDidChange(start, removedCount, addedCount);
691
724
  },
692
-
725
+
693
726
  /** @private */
694
727
  init: function() {
695
728
  sc_super();
696
729
  this._storeKeysDidChange();
697
730
  }
698
-
731
+
699
732
  });
700
733
 
701
- SC.RecordArray.mixin(/** @scope SC.RecordArray.prototype */{
702
-
703
- /**
734
+ SC.RecordArray.mixin(/** @scope SC.RecordArray.prototype */{
735
+
736
+ /**
704
737
  Standard error throw when you try to modify a record that is not editable
705
-
738
+
706
739
  @type SC.Error
707
740
  */
708
741
  NOT_EDITABLE: SC.Error.desc("SC.RecordArray is not editable"),
709
-
742
+
710
743
  /**
711
744
  Number of milliseconds to allow a query matching to run for. If this number
712
- is exceeded, the query matching will be paced so as to not lock up the
745
+ is exceeded, the query matching will be paced so as to not lock up the
713
746
  browser (by essentially splitting the work with a setTimeout)
714
-
747
+
715
748
  @type Number
716
749
  */
717
750
  QUERY_MATCHING_THRESHOLD: 100