sproutcore 1.10.3.1 → 1.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (380) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG +4 -8
  3. data/VERSION.yml +2 -2
  4. data/lib/frameworks/sproutcore/Buildfile +5 -4
  5. data/lib/frameworks/sproutcore/CHANGELOG.md +274 -40
  6. data/lib/frameworks/sproutcore/CONTRIBUTORS.md +133 -0
  7. data/lib/frameworks/sproutcore/README.md +31 -144
  8. data/lib/frameworks/sproutcore/apps/showcase/controllers/source_tree_controller.js +9 -4
  9. data/lib/frameworks/sproutcore/apps/showcase/resources/stylesheet.css +5 -0
  10. data/lib/frameworks/sproutcore/apps/showcase/system/views_item_content.js +1 -1
  11. data/lib/frameworks/sproutcore/apps/showcase/views/split_views.js +15 -2
  12. data/lib/frameworks/sproutcore/apps/showcase/views/stacked_views.js +1 -1
  13. data/lib/frameworks/sproutcore/apps/tests/english.lproj/main_page.js +11 -1
  14. data/lib/frameworks/sproutcore/frameworks/ajax/mixins/websocket_delegate.js +90 -0
  15. data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +81 -5
  16. data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +23 -4
  17. data/lib/frameworks/sproutcore/frameworks/ajax/system/websocket.js +475 -0
  18. data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +149 -26
  19. data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/websocket.js +197 -0
  20. data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/xhr_response_test.js +65 -0
  21. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +4 -0
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +232 -52
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +235 -49
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +23 -13
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/object.js +3 -1
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/core.js +81 -1
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/english.lproj/ordinal.js +17 -0
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/string.js +7 -0
  29. data/lib/frameworks/sproutcore/frameworks/{desktop/tests/views/disclosure/methods.js → core_foundation/french.lproj/ordinal.js} +7 -4
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +2 -6
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/main.js +1 -1
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +104 -69
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane_statechart.js +6 -1
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/child_view_layout_protocol.js +59 -0
  35. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/view_transition_protocol.js +18 -1
  36. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/application.js +192 -0
  37. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/bezier_curves.js +52 -0
  38. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +384 -64
  39. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/core_query.js +6 -14
  40. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +21 -35
  41. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +72 -36
  42. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +90 -34
  43. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +55 -7
  44. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +20 -15
  45. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/req_anim_frame.js +9 -10
  46. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +763 -542
  47. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/selection_set.js +4 -3
  48. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +1 -7
  49. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +14 -0
  50. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/touch.js +538 -0
  51. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils/rect.js +56 -1
  52. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +99 -4
  53. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/single_case.js +25 -19
  54. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/core_tests.js +75 -0
  55. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/ext/number_test.js +81 -0
  56. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +4 -4
  57. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/responder_context.js +4 -4
  58. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +19 -1
  59. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/color.js +36 -20
  60. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/design_modes_test.js +83 -0
  61. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/makeMainPane.js +7 -3
  62. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/mouse_events.js +338 -0
  63. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/root_responder.js +14 -89
  64. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/touch.js +106 -0
  65. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/sparse_array.js +2 -2
  66. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/touch.js +136 -0
  67. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/rect.js +42 -1
  68. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/append_remove.js +11 -0
  69. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/child_view.js +5 -5
  70. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/design_mode_test.js +457 -0
  71. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/sendEvent.js +36 -10
  72. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/background_color.js +44 -0
  73. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/border_frame_test.js +51 -24
  74. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/childViewLayout_test.js +176 -1
  75. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +46 -16
  76. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/convertFrames.js +69 -15
  77. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/didAppendToDocument.js +2 -2
  78. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layout.js +7 -1
  79. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +30 -10
  80. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +376 -71
  81. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/static_layout.js +0 -10
  82. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/viewDidResize.js +117 -34
  83. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view_states_test.js +52 -2
  84. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +656 -42
  85. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +159 -38
  86. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +0 -7
  87. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/design_mode.js +206 -0
  88. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +0 -28
  89. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +21 -6
  90. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +372 -450
  91. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +28 -13
  92. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +22 -51
  93. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +59 -30
  94. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +0 -29
  95. data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +22 -10
  96. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +42 -36
  97. data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +54 -3
  98. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +178 -59
  99. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +2 -2
  100. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +206 -132
  101. data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +214 -118
  102. data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +96 -13
  103. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +14 -4
  104. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +82 -42
  105. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +272 -177
  106. data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/store_interaction_test.js +54 -0
  107. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/datetime_recordattribute.js +24 -16
  108. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +6 -3
  109. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/data_store.js +267 -35
  110. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +57 -46
  111. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +150 -53
  112. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +57 -17
  113. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +13 -9
  114. data/lib/frameworks/sproutcore/frameworks/{experimental/frameworks/polymorphism → datastore}/tests/models/polymorphism/many.js +2 -2
  115. data/lib/frameworks/sproutcore/frameworks/{experimental/frameworks/polymorphism → datastore}/tests/models/polymorphism/simple.js +0 -0
  116. data/lib/frameworks/sproutcore/frameworks/{experimental/frameworks/polymorphism → datastore}/tests/models/polymorphism/single.js +12 -2
  117. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +20 -15
  118. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +9 -2
  119. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/many_array/core_methods.js +80 -14
  120. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/autonomous_dataSourceCallbacks.js +280 -0
  121. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/autonomous_pushChanges.js +232 -0
  122. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +31 -5
  123. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/parse.js +16 -2
  124. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +60 -40
  125. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/materializeRecord.js +78 -0
  126. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +13 -1
  127. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +20 -0
  128. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/{resources → english.lproj}/strings.js +0 -0
  129. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/french.lproj/strings.js +45 -0
  130. data/lib/frameworks/sproutcore/frameworks/designer/designers/object_designer.js +7 -3
  131. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +125 -44
  132. data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +139 -48
  133. data/lib/frameworks/sproutcore/frameworks/desktop/panes/draggable.js +202 -0
  134. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +59 -56
  135. data/lib/frameworks/sproutcore/frameworks/desktop/panes/palette.js +13 -49
  136. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +466 -305
  137. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_source.js +49 -12
  138. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +79 -21
  139. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/split.js +12 -2
  140. data/lib/frameworks/sproutcore/frameworks/desktop/resources/menu_item_view.css +8 -0
  141. data/lib/frameworks/sproutcore/frameworks/desktop/resources/overlay-scroller.css +187 -0
  142. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +94 -30
  143. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +163 -3
  144. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/methods.js +97 -78
  145. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +61 -1
  146. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +7 -3
  147. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +47 -22
  148. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/methods.js +66 -9
  149. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +21 -11
  150. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/ui.js +12 -18
  151. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +17 -14
  152. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +2 -1
  153. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +9 -6
  154. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/collection_fast_path.js +54 -21
  155. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/content.js +52 -20
  156. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/itemViewForContentIndex.js +94 -4
  157. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/keyboard.js +177 -0
  158. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/layerIdFor.js +13 -1
  159. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/length.js +9 -9
  160. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +18 -0
  161. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/methods.js +104 -0
  162. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/ui.js +48 -49
  163. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/drag_and_drop.js +22 -18
  164. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/methods.js +17 -5
  165. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/link_view_test.js +136 -0
  166. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/contentIndexesInRect.js +77 -0
  167. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/drag_and_drop.js +53 -16
  168. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/layoutForContentIndex.js +41 -0
  169. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowDelegate.js +25 -25
  170. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowOffsetForContentIndex.js +102 -27
  171. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/{rowHeightForContentIndex.js → rowSizeForContentIndex.js} +7 -6
  172. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_outline.js +2 -0
  173. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_row_heights.js +70 -75
  174. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_simple.js +29 -30
  175. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list_item.js +57 -0
  176. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/menu_scroll_view/menu_scroll_view_test.js +206 -0
  177. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +15 -0
  178. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +15 -7
  179. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/integration.js +16 -11
  180. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +164 -12
  181. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/scale.js +387 -0
  182. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/touch.js +549 -0
  183. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +214 -45
  184. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroller.js +5 -5
  185. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +73 -22
  186. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +88 -3
  187. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +8 -0
  188. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/slider/methods.js +16 -1
  189. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/slider/ui.js +54 -0
  190. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/dividers.js +21 -2
  191. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/static_content.js +31 -25
  192. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +109 -29
  193. data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +10 -1
  194. data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +3 -0
  195. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +779 -603
  196. data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +106 -7
  197. data/lib/frameworks/sproutcore/frameworks/desktop/views/link_view.js +406 -0
  198. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +437 -245
  199. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +13 -0
  200. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +124 -62
  201. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +176 -597
  202. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroller_view.js +206 -0
  203. data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +3 -0
  204. data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +5 -4
  205. data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +3 -0
  206. data/lib/frameworks/sproutcore/frameworks/desktop/views/scene.js +56 -158
  207. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll_view.js +2560 -0
  208. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +458 -242
  209. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +117 -54
  210. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +18 -12
  211. data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +162 -34
  212. data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +30 -15
  213. data/lib/frameworks/sproutcore/frameworks/desktop/views/split_divider.js +33 -7
  214. data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +22 -2
  215. data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +47 -22
  216. data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +0 -6
  217. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +2 -1
  218. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form_row.js +21 -21
  219. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +14 -3
  220. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/mixins/select_view_menu.js +24 -10
  221. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/ext/menu_resizing.js +1 -1
  222. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/bindings.js +7 -4
  223. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/check_selected.js +7 -9
  224. data/lib/frameworks/sproutcore/frameworks/{desktop/tests/panes/select_button/methods.js → experimental/frameworks/select_view/tests/views/select/method.js} +54 -76
  225. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/selected_item.js +35 -0
  226. data/lib/frameworks/sproutcore/frameworks/{desktop/tests/panes/select_button → experimental/frameworks/select_view/tests/views/select}/ui.js +107 -36
  227. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +225 -66
  228. data/lib/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +39 -38
  229. data/lib/frameworks/sproutcore/frameworks/foundation/core.js +5 -18
  230. data/lib/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +12 -0
  231. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/inflections.js +84 -0
  232. data/lib/frameworks/sproutcore/frameworks/foundation/french.lproj/inflections.js +41 -0
  233. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_mixin.js +1 -0
  234. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +7 -0
  235. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_display.js +3 -4
  236. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +6 -2
  237. data/lib/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +408 -239
  238. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
  239. data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +2 -1
  240. data/lib/frameworks/sproutcore/frameworks/foundation/spanish.lproj/inflections.js +38 -0
  241. data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +104 -76
  242. data/lib/frameworks/sproutcore/frameworks/foundation/system/string.js +20 -94
  243. data/lib/frameworks/sproutcore/frameworks/foundation/system/text_selection.js +33 -22
  244. data/lib/frameworks/sproutcore/frameworks/foundation/system/undo_manager.js +475 -0
  245. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_resize_test.js +163 -1
  246. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +41 -0
  247. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/staticLayout.js +2 -5
  248. data/lib/frameworks/sproutcore/frameworks/foundation/tests/private/tree_item_observer/methods.js +268 -0
  249. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/undo_manager.js +231 -0
  250. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +16 -0
  251. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +27 -0
  252. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +24 -0
  253. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +135 -6
  254. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/fade_transition.js +6 -0
  255. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/pop_transition.js +7 -0
  256. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/scale_transition.js +6 -0
  257. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/slide_transition.js +4 -0
  258. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/swap_dissolve_transition.js +3 -1
  259. data/lib/frameworks/sproutcore/frameworks/foundation/validators/credit_card.js +21 -21
  260. data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +65 -15
  261. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +4 -1
  262. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +1 -1
  263. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +193 -213
  264. data/lib/frameworks/sproutcore/frameworks/jquery/{jquery-1.8.3-patched.js → jquery-1.11.1.js} +7507 -6684
  265. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +28 -11
  266. data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +26 -0
  267. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +54 -25
  268. data/lib/frameworks/sproutcore/frameworks/runtime/ext/array.js +0 -6
  269. data/lib/frameworks/sproutcore/frameworks/runtime/ext/number.js +36 -0
  270. data/lib/frameworks/sproutcore/frameworks/runtime/ext/window.js +25 -0
  271. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +3 -3
  272. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
  273. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +156 -66
  274. data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +2 -2
  275. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +150 -65
  276. data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +57 -11
  277. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +68 -49
  278. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +14 -6
  279. data/lib/frameworks/sproutcore/frameworks/runtime/system/string.js +23 -23
  280. data/lib/frameworks/sproutcore/frameworks/runtime/tests/ext/number_test.js +44 -0
  281. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +0 -10
  282. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable/enumerable.js +340 -285
  283. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +104 -3
  284. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/observer_set.js +14 -1
  285. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/string.js +15 -2
  286. data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +21 -18
  287. data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +52 -19
  288. data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/responder/pane.js +27 -24
  289. data/lib/frameworks/sproutcore/frameworks/template_view/controls/button.js +30 -0
  290. data/lib/frameworks/sproutcore/frameworks/template_view/ext/handlebars/bind.js +1 -1
  291. data/lib/frameworks/sproutcore/frameworks/template_view/ext/handlebars/collection.js +2 -0
  292. data/lib/frameworks/sproutcore/frameworks/template_view/ext/handlebars/view.js +1 -0
  293. data/lib/frameworks/sproutcore/frameworks/template_view/tests/mixins/template_helpers/checkbox_support.js +2 -2
  294. data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/handlebars.js +4 -2
  295. data/lib/frameworks/sproutcore/frameworks/template_view/views/bindable_span.js +1 -1
  296. data/lib/frameworks/sproutcore/frameworks/template_view/views/template_collection.js +16 -14
  297. data/lib/frameworks/sproutcore/frameworks/testing/core.js +5 -3
  298. data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +13 -0
  299. data/lib/frameworks/sproutcore/lib/index.rhtml +2 -2
  300. data/lib/frameworks/sproutcore/phantomjs/test_runner.js +28 -7
  301. data/lib/frameworks/sproutcore/scripts/run_sc_server_master.sh +1 -1
  302. data/lib/frameworks/sproutcore/themes/ace/resources/_variables.css +2 -0
  303. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure.css +1 -0
  304. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.css +3 -4
  305. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/horizontal.css +15 -15
  306. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/horizontal_overlay.css +74 -0
  307. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/vertical.css +11 -13
  308. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/vertical_overlay.css +74 -0
  309. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/knob-active.png +0 -0
  310. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/knob-active@2x.png +0 -0
  311. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/knob.png +0 -0
  312. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/knob@2x.png +0 -0
  313. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/{22px → jumbo}/slider.css +9 -4
  314. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/track.png +0 -0
  315. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/jumbo/track@2x.png +0 -0
  316. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/knob-active.png +0 -0
  317. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/knob-active@2x.png +0 -0
  318. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/knob.png +0 -0
  319. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/knob@2x.png +0 -0
  320. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/slider.css +32 -0
  321. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/track.png +0 -0
  322. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/regular/track@2x.png +0 -0
  323. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/slider.css +13 -0
  324. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/knob-active.png +0 -0
  325. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/knob-active@2x.png +0 -0
  326. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/knob.png +0 -0
  327. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/knob@2x.png +0 -0
  328. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/slider.css +32 -0
  329. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/track.png +0 -0
  330. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/small/track@2x.png +0 -0
  331. data/lib/frameworks/sproutcore/themes/ace/resources/split/split.css +2 -3
  332. data/lib/sproutcore/builders/chance_file.rb +3 -3
  333. data/lib/sproutcore/helpers/minifier.rb +1 -0
  334. data/vendor/chance/lib/chance/instance.rb +34 -34
  335. data/vendor/chance/lib/chance/instance/spriting.rb +21 -16
  336. metadata +81 -58
  337. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/visibility.js +0 -17
  338. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_fast_path.js +0 -710
  339. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +0 -267
  340. data/lib/frameworks/sproutcore/frameworks/desktop/resources/touch-scroller.css +0 -196
  341. data/lib/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +0 -224
  342. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +0 -163
  343. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +0 -177
  344. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +0 -2053
  345. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +0 -1024
  346. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +0 -404
  347. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/render_delegates/menu_scroller.js +0 -28
  348. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/tests/menu/scroll.js +0 -235
  349. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +0 -363
  350. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroller.js +0 -250
  351. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +0 -47
  352. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +0 -134
  353. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/desktop_scroller.js +0 -92
  354. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/native_scroll.js +0 -25
  355. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/scroll.js +0 -33
  356. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/touch_scroller.js +0 -76
  357. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +0 -25
  358. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/methods.js +0 -143
  359. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/ui.js +0 -256
  360. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +0 -1164
  361. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroller.js +0 -332
  362. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +0 -236
  363. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroller.js +0 -347
  364. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +0 -15
  365. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroller.js +0 -10
  366. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +0 -804
  367. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroller.js +0 -133
  368. data/lib/frameworks/sproutcore/frameworks/foundation/tasks/preload_bundle.js +0 -41
  369. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/horizontal_touch.css +0 -91
  370. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/vertical_touch.css +0 -92
  371. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/knob.png +0 -0
  372. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/knob_active.png +0 -0
  373. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/slider.css +0 -27
  374. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/knob.png +0 -0
  375. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/knob_active.png +0 -0
  376. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/slider.css +0 -27
  377. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/knob.png +0 -0
  378. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/knob_active.png +0 -0
  379. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/track.png +0 -0
  380. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/track.png +0 -0
@@ -3,11 +3,6 @@ sc_require("views/view");
3
3
  SC.View.reopen(
4
4
  /** @scope SC.View.prototype */ {
5
5
 
6
- init: function(original) {
7
- original();
8
- this._lastTheme = this.get('theme');
9
- }.enhance(),
10
-
11
6
  // ..........................................................
12
7
  // THEME SUPPORT
13
8
  //
@@ -225,30 +220,6 @@ SC.View.reopen(
225
220
  }
226
221
  },
227
222
 
228
- applyAttributesToContext: function(original, context) {
229
- var theme = this.get('theme');
230
- var themeClassNames = theme.classNames, idx, len = themeClassNames.length;
231
-
232
- for (idx = 0; idx < len; idx++) {
233
- context.addClass(themeClassNames[idx]);
234
- }
235
-
236
- original(context);
237
-
238
- var renderDelegate = this.get('renderDelegate');
239
- if (renderDelegate && renderDelegate.className) {
240
- context.addClass(renderDelegate.className);
241
- }
242
-
243
- // @if(debug)
244
- if (renderDelegate && renderDelegate.name) {
245
- SC.Logger.error("Render delegates now use 'className' instead of 'name'.");
246
- SC.Logger.error("Name '%@' will be ignored.", renderDelegate.name);
247
- }
248
- // @endif
249
- }.enhance(),
250
-
251
-
252
223
  /**
253
224
  Invokes a method on the render delegate, if one is present and it implements
254
225
  that method.
@@ -98,7 +98,7 @@ SC.RelationshipSupport = {
98
98
  _srs_inverseDidRelinquishRelationships: function (recordType, ids, attr, inverseId) {
99
99
  ids.forEach(function (id) {
100
100
  this._srs_inverseDidRelinquishRelationship(recordType, id, attr, inverseId);
101
- },this);
101
+ }, this);
102
102
  },
103
103
 
104
104
  /** @private
@@ -115,9 +115,18 @@ SC.RelationshipSupport = {
115
115
 
116
116
  if (SC.instanceOf(proto[key], SC.SingleAttribute)) {
117
117
  delete dataHash[key];
118
- } else if (SC.instanceOf(proto[key], SC.ManyAttribute)
119
- && SC.typeOf(dataHash[key]) === SC.T_ARRAY) {
118
+ } else if (SC.instanceOf(proto[key], SC.ManyAttribute) &&
119
+ SC.typeOf(dataHash[key]) === SC.T_ARRAY) {
120
+
120
121
  dataHash[key].removeObject(relativeID);
122
+
123
+ // If there is a materialized record with a ManyArray we have to clear the
124
+ // internal cache of the ManyArray. Otherwise calling `objectAt` on the
125
+ // Many Array will retrieve the cached record.
126
+ var record = this.records[storeKey];
127
+ if (record) {
128
+ record.get(key)._records = null;
129
+ }
121
130
  }
122
131
 
123
132
  this.pushRetrieve(recordType, id, dataHash, undefined, true);
@@ -132,7 +141,7 @@ SC.RelationshipSupport = {
132
141
  _srs_inverseDidAddRelationships: function (recordType, ids, attr, inverseId) {
133
142
  ids.forEach(function (id) {
134
143
  this._srs_inverseDidAddRelationship(recordType, id, attr, inverseId);
135
- },this);
144
+ }, this);
136
145
  },
137
146
 
138
147
 
@@ -246,7 +255,7 @@ SC.RelationshipSupport = {
246
255
  // update old relationships
247
256
  existingIDs = [currentHash[keyValue] || null].flatten().compact().uniq();
248
257
  this._srs_inverseDidRelinquishRelationships(inverseType, existingIDs, toAttr, id);
249
- });
258
+ });
250
259
 
251
260
  return original(recordType, id, storeKey);
252
261
  }.enhance(),
@@ -275,22 +284,25 @@ SC.RelationshipSupport = {
275
284
  @param {String} keyValue - the property name in the datahash that defines this foreign key relationship
276
285
  */
277
286
  function (inverseType, currentHash, toAttr, keyValue) {
278
- // update old relationships
279
- existingIDs = [currentHash[keyValue] || null].flatten().compact().uniq();
280
287
 
281
- // update new relationships
288
+ // Find the new relations.
282
289
  inverseIDs = [dataHash[keyValue] || null].flatten().compact().uniq();
283
290
 
284
- this._srs_inverseDidRelinquishRelationships(inverseType, existingIDs.filter(
291
+ // Find the old relations.
292
+ existingIDs = [currentHash[keyValue] || null].flatten().compact().uniq();
293
+ existingIDs = existingIDs.filter(
285
294
  function (el) {
286
295
  return inverseIDs.indexOf(el) === -1;
287
- }), toAttr, id);
296
+ });
288
297
 
298
+ // Update the relationships.
299
+ this._srs_inverseDidRelinquishRelationships(inverseType, existingIDs, toAttr, id);
289
300
  this._srs_inverseDidAddRelationships(inverseType, inverseIDs, toAttr, id);
290
301
  });
291
302
  }
292
303
 
293
304
  storeKey = storeKey || recordType.storeKeyFor(id);
305
+
294
306
  return original(recordType, id, dataHash, storeKey);
295
307
  }.enhance()
296
308
  };
@@ -33,76 +33,82 @@ SC.ChildrenAttribute = SC.ChildAttribute.extend(
33
33
  //
34
34
 
35
35
  /** @private - adapted for to many relationship */
36
- toType: function(record, key, value) {
36
+ toType: function (record, key, value) {
37
37
  var attrKey = this.get('key') || key,
38
38
  arrayKey = SC.keyFor('__kidsArray__', SC.guidFor(this)),
39
39
  ret = record[arrayKey],
40
- recordType = this.get('typeClass'), rel;
40
+ recordType = this.get('typeClass'),
41
+ rel;
41
42
 
42
- // lazily create a ManyArray one time. after that always return the
43
+ // lazily create a ChildArray one time. after that always return the
43
44
  // same object.
44
45
  if (!ret) {
45
46
  ret = SC.ChildArray.create({
46
- record: record,
47
- propertyName: attrKey,
47
+ record: record,
48
+ propertyName: attrKey,
48
49
  defaultRecordType: recordType
49
50
  });
50
51
 
51
- record[arrayKey] = ret ; // save on record
52
+ record[arrayKey] = ret; // cache on record
53
+
54
+ // Make sure the child array gets notified of changes to the parent record.
52
55
  rel = record.get('relationships');
53
56
  if (!rel) record.set('relationships', rel = []);
54
- rel.push(ret); // make sure we get notified of changes...
57
+ rel.push(ret);
55
58
  }
56
59
 
57
60
  return ret;
58
61
  },
59
62
 
60
63
  // Default fromType is just returning itself
61
- fromType: function(record, key, value){
64
+ fromType: function (record, key, value) {
62
65
  var sk, store,
63
66
  arrayKey = SC.keyFor('__kidsArray__', SC.guidFor(this)),
64
67
  ret = record[arrayKey];
68
+
65
69
  if (record) {
66
70
  record.writeAttribute(key, value);
71
+
72
+ // If the SC.ChildArray already exists, indicate that its backing content has changed.
67
73
  if (ret) ret = ret.recordPropertyDidChange();
68
74
  }
69
75
 
70
76
  return ret;
71
- },
77
+ }
72
78
 
73
- /**
79
+ /** UNUSED. This seems to have no effect on SC.ChildArray usage. Kept here for quick reference.
74
80
  The core handler. Called from the property.
75
81
  @param {SC.Record} record the record instance
76
82
  @param {String} key the key used to access this attribute on the record
77
83
  @param {Object} value the property value if called as a setter
78
84
  @returns {Object} property value
79
85
  */
80
- call: function(record, key, value) {
81
- var attrKey = this.get('key') || key, cRef,
82
- cacheKey = SC.keyFor('__kid__', SC.guidFor(this));
83
- if (value !== undefined) {
84
- value = this.fromType(record, key, value) ; // convert to attribute.
85
- } else {
86
- value = record.readAttribute(attrKey);
87
- if (SC.none(value) && (value = this.get('defaultValue'))) {
88
- if (typeof value === SC.T_FUNCTION) {
89
- value = this.defaultValue(record, key, this);
90
- // write default value so it doesn't have to be executed again
91
- if (record.attributes()) {
92
- // Check for an array
93
- if (value instanceof Array) {
94
- // Instantiate the construct and replace all of the content.
95
- value = this.toType(record, key, value).replace(0, value.length, value);
96
- } else {
97
- record.writeAttribute(attrKey, value, true);
98
- }
99
- }
100
- }
101
- } else value = this.toType(record, key, value);
102
- }
103
-
104
- return value ;
105
- }
86
+ // call: function(record, key, value) {
87
+ // var attrKey = this.get('key') || key, cRef,
88
+ // cacheKey = SC.keyFor('__kid__', SC.guidFor(this));
89
+ // if (value !== undefined) {
90
+ // value = this.fromType(record, key, value) ; // convert to attribute.
91
+ // } else {
92
+ // value = record.readAttribute(attrKey);
93
+ // if (SC.none(value) && (value = this.get('defaultValue'))) {
94
+ // if (typeof value === SC.T_FUNCTION) {
95
+ // value = this.defaultValue(record, key, this);
96
+ // // write default value so it doesn't have to be executed again
97
+ // if (record.attributes()) {
98
+ // // Check for an array
99
+ // if (value instanceof Array) {
100
+ // // Instantiate the construct and replace all of the content.
101
+ // value = this.toType(record, key, value).replace(0, value.length, value);
102
+ // } else {
103
+ // record.writeAttribute(attrKey, value, true);
104
+ // }
105
+ // }
106
+ // }
107
+ // } else value = this.toType(record, key, value);
108
+ // }
109
+
110
+ // return value ;
111
+ // }
106
112
 
107
113
  });
108
114
 
@@ -14,8 +14,13 @@ sc_require('system/many_array');
14
14
  ManyAttribute is a subclass of `RecordAttribute` and handles to-many
15
15
  relationships.
16
16
 
17
- When setting ( `.set()` ) the value of a `toMany` attribute, make sure
18
- to pass in an array of `SC.Record` objects.
17
+ Relationships in the client are meant to mirror the relationships that
18
+ the real data has in the remote data store on the server. For example,
19
+ if a `Parent` record on the server has an array of `Child` ids, then it is
20
+ appropriate for the `MyApp.Parent` model in the SproutCore app to have a `toMany`
21
+ relationship to the `MyApp.Child` in the app. In this way, changes to the
22
+ relationship in the client will best match how the data should be committed
23
+ to the server.
19
24
 
20
25
  There are many ways you can configure a `ManyAttribute`:
21
26
 
@@ -27,6 +32,25 @@ sc_require('system/many_array');
27
32
  through: 'taggings' // set a relationship this goes through
28
33
  });
29
34
 
35
+ Note: When setting ( `.set()` ) the value of a `toMany` attribute, make sure
36
+ to pass in an array of `SC.Record` objects.
37
+
38
+ ## Using new Records in Relationships
39
+
40
+ Because relationships are based on `id`, new records created in the client
41
+ (that don't have an `id`) are typically not able to be assigned to a
42
+ relationship until after they have been committed to the server. However,
43
+ because it's unwieldy to manually update relationships after the real `id` is
44
+ known, `SC.ManyAttribute` through `SC.ManyArray`, allows new records to be added
45
+ that don't yet have an `id`.
46
+
47
+ As long as the `supportNewRecords` property is true, adding records without an
48
+ `id `to the relationship will assign unique temporary ids to the new records.
49
+
50
+ *Note:* You must update the relationship after the new records are successfully
51
+ committed and have real ids. This is done by calling `updateNewRecordId()`
52
+ on the many array. In the future this should be automatic.
53
+
30
54
  @extends SC.RecordAttribute
31
55
  @since SproutCore 1.0
32
56
  */
@@ -63,6 +87,31 @@ SC.ManyAttribute = SC.RecordAttribute.extend(
63
87
  */
64
88
  orderBy: null,
65
89
 
90
+ /**
91
+ Determines whether the new record support of `SC.ManyArray` should be
92
+ enabled or not.
93
+
94
+ Normally, all records in the relationship should already have been previously
95
+ committed to a remote data store and have an actual `id`. However, with
96
+ `supportNewRecords` set to true, adding records without an `id `to the
97
+ relationship will assign unique temporary ids to the new records.
98
+
99
+ *Note:* You must update the relationship after the new records are successfully
100
+ committed and have real ids. This is done by calling `updateNewRecordId()`
101
+ on the many array. In the future this should be automatic.
102
+
103
+ If you wish to turn this off, SC.ManyArray will throw an exception if you
104
+ add a record without an id to the relationship. If you use temporary `id`s
105
+ for new record, you will need to manually update the relationship, but
106
+ run the risk of committing inverse records with temporary `id`s in their
107
+ datahashes.
108
+
109
+ @type Boolean
110
+ @default true
111
+ @since SproutCore 1.11.0
112
+ */
113
+ supportNewRecords: true,
114
+
66
115
  // ..........................................................
67
116
  // LOW-LEVEL METHODS
68
117
  //
@@ -70,6 +119,7 @@ SC.ManyAttribute = SC.RecordAttribute.extend(
70
119
  /** @private - adapted for to many relationship */
71
120
  toType: function(record, key, value) {
72
121
  var type = this.get('typeClass'),
122
+ supportNewRecords = this.get('supportNewRecords'),
73
123
  attrKey = this.get('key') || key,
74
124
  arrayKey = SC.keyFor('__manyArray__', SC.guidFor(this)),
75
125
  ret = record[arrayKey],
@@ -82,7 +132,8 @@ SC.ManyAttribute = SC.RecordAttribute.extend(
82
132
  recordType: type,
83
133
  record: record,
84
134
  propertyName: attrKey,
85
- manyAttribute: this
135
+ manyAttribute: this,
136
+ supportNewRecords: supportNewRecords
86
137
  });
87
138
 
88
139
  record[arrayKey] = ret ; // save on record
@@ -33,6 +33,72 @@ sc_require('system/query');
33
33
  You can bulk update attributes from the server using the
34
34
  `updateAttributes()` method.
35
35
 
36
+ # Polymorphic Records
37
+
38
+ SC.Record also supports polymorphism, which allows subclasses of a record type to share a common
39
+ identity. Polymorphism is similar to inheritance (i.e. a polymorphic subclass inherits its parents
40
+ properties), but differs in that polymorphic subclasses can be considered to be "equal" to each
41
+ other and their superclass. This means that any memmber of the polymorphic class group should be
42
+ able to stand in for any other member.
43
+
44
+ These examples may help identify the difference. First, let's look at the classic inheritance
45
+ model,
46
+
47
+ // This is the "root" class. All subclasses of MyApp.Person will be unique from MyApp.Person.
48
+ MyApp.Person = SC.Record.extend({});
49
+
50
+ // As a subclass, MyApp.Female inherits from a MyApp.Person, but is not "equal" to it.
51
+ MyApp.Female = MyApp.Person.extend({
52
+ isFemale: true
53
+ });
54
+
55
+ // As a subclass, MyApp.Male inherits from a MyApp.Person, but is not "equal" to it.
56
+ MyApp.Male = MyApp.Person.extend({
57
+ isMale: true
58
+ });
59
+
60
+ // Load two unique records into the store.
61
+ MyApp.store.createRecord(MyApp.Female, { guid: '1' });
62
+ MyApp.store.createRecord(MyApp.Male, { guid: '2' });
63
+
64
+ // Now we can see that these records are isolated from each other.
65
+ var female = MyApp.store.find(MyApp.Person, '1'); // Returns an SC.Record.EMPTY record.
66
+ var male = MyApp.store.find(MyApp.Person, '2'); // Returns an SC.Record.EMPTY record.
67
+
68
+ // These records are MyApp.Person only.
69
+ SC.kindOf(female, MyApp.Female); // false
70
+ SC.kindOf(male, MyApp.Male); // false
71
+
72
+ Next, let's make MyApp.Person a polymorphic class,
73
+
74
+ // This is the "root" polymorphic class. All subclasses of MyApp.Person will be able to stand-in as a MyApp.Person.
75
+ MyApp.Person = SC.Record.extend({
76
+ isPolymorphic: true
77
+ });
78
+
79
+ // As a polymorphic subclass, MyApp.Female is "equal" to a MyApp.Person.
80
+ MyApp.Female = MyApp.Person.extend({
81
+ isFemale: true
82
+ });
83
+
84
+ // As a polymorphic subclass, MyApp.Male is "equal" to a MyApp.Person.
85
+ MyApp.Male = MyApp.Person.extend({
86
+ isMale: true
87
+ });
88
+
89
+ // Load two unique records into the store.
90
+ MyApp.store.createRecord(MyApp.Female, { guid: '1' });
91
+ MyApp.store.createRecord(MyApp.Male, { guid: '2' });
92
+
93
+ // Now we can see that these records are in fact "equal" to each other. Which means that if we
94
+ // search for "people", we will get "males" & "females".
95
+ var female = MyApp.store.find(MyApp.Person, '1'); // Returns record.
96
+ var male = MyApp.store.find(MyApp.Person, '2'); // Returns record.
97
+
98
+ // These records are MyApp.Person as well as their unique subclass.
99
+ SC.kindOf(female, MyApp.Female); // true
100
+ SC.kindOf(male, MyApp.Male); // true
101
+
36
102
  @extends SC.Object
37
103
  @see SC.RecordAttribute
38
104
  @since SproutCore 1.0
@@ -84,27 +150,10 @@ SC.Record = SC.Object.extend(
84
150
  */
85
151
  isRecord: YES,
86
152
 
87
- /**
88
- If you have nested records
89
-
90
- @type Boolean
91
- @default NO
92
- */
93
- isParentRecord: NO,
94
-
95
- // ...............................
96
- // PROPERTIES
153
+ // ----------------------------------------------------------------------------------------------
154
+ // Properties
97
155
  //
98
156
 
99
- /**
100
- This is the primary key used to distinguish records. If the keys
101
- match, the records are assumed to be identical.
102
-
103
- @type String
104
- @default 'guid'
105
- */
106
- primaryKey: 'guid',
107
-
108
157
  /**
109
158
  Returns the id for the record instance. The id is used to uniquely
110
159
  identify this record instance from all others of the same type. If you
@@ -124,6 +173,23 @@ SC.Record = SC.Object.extend(
124
173
  }
125
174
  }.property('storeKey').cacheable(),
126
175
 
176
+ /**
177
+ If you have nested records
178
+
179
+ @type Boolean
180
+ @default NO
181
+ */
182
+ isParentRecord: NO,
183
+
184
+ /**
185
+ This is the primary key used to distinguish records. If the keys
186
+ match, the records are assumed to be identical.
187
+
188
+ @type String
189
+ @default 'guid'
190
+ */
191
+ primaryKey: 'guid',
192
+
127
193
  /**
128
194
  All records generally have a life cycle as they are created or loaded into
129
195
  memory, modified, committed and finally destroyed. This life cycle is
@@ -197,7 +263,7 @@ SC.Record = SC.Object.extend(
197
263
  isEditable: function(key, value) {
198
264
  if (value !== undefined) this._screc_isEditable = value;
199
265
  if (this.get('status') & SC.Record.READY) return this._screc_isEditable;
200
- else return NO ;
266
+ else return NO;
201
267
  }.property('status').cacheable(),
202
268
 
203
269
  /**
@@ -333,7 +399,7 @@ SC.Record = SC.Object.extend(
333
399
  rec.refresh(recordOnly, callback);
334
400
  }
335
401
 
336
- return this ;
402
+ return this;
337
403
  },
338
404
 
339
405
  /**
@@ -367,7 +433,7 @@ SC.Record = SC.Object.extend(
367
433
  rec.destroy(recordOnly);
368
434
  }
369
435
 
370
- return this ;
436
+ return this;
371
437
  },
372
438
 
373
439
  /**
@@ -397,7 +463,7 @@ SC.Record = SC.Object.extend(
397
463
  // status to them.
398
464
  this.propagateToAggregates();
399
465
 
400
- return this ;
466
+ return this;
401
467
  },
402
468
 
403
469
  toJSON: function(){
@@ -424,7 +490,7 @@ SC.Record = SC.Object.extend(
424
490
  */
425
491
  beginEditing: function() {
426
492
  this._editLevel++;
427
- return this ;
493
+ return this;
428
494
  },
429
495
 
430
496
  /**
@@ -442,7 +508,7 @@ SC.Record = SC.Object.extend(
442
508
  this._editLevel = 0;
443
509
  this.recordDidChange(key);
444
510
  }
445
- return this ;
511
+ return this;
446
512
  },
447
513
 
448
514
  /**
@@ -455,7 +521,7 @@ SC.Record = SC.Object.extend(
455
521
  readAttribute: function(key) {
456
522
  var store = this.get('store'), storeKey = this.storeKey;
457
523
  var attrs = store.readDataHash(storeKey);
458
- return attrs ? attrs[key] : undefined ;
524
+ return attrs ? attrs[key] : undefined;
459
525
  },
460
526
 
461
527
  /**
@@ -496,7 +562,7 @@ SC.Record = SC.Object.extend(
496
562
  store.dataHashDidChange(storeKey, null, undefined, key);
497
563
  }
498
564
  }
499
- return this ;
565
+ return this;
500
566
  },
501
567
 
502
568
  /**
@@ -594,11 +660,13 @@ SC.Record = SC.Object.extend(
594
660
  this.notifyPropertyChange('status');
595
661
  this.endPropertyChanges();
596
662
 
597
- } else this.allPropertiesDidChange();
663
+ } else {
664
+ this.allPropertiesDidChange();
665
+ }
598
666
 
599
667
  // also notify manyArrays
600
668
  var manyArrays = this.relationships,
601
- loc = manyArrays ? manyArrays.length : 0 ;
669
+ loc = manyArrays ? manyArrays.length : 0;
602
670
  while(--loc>=0) manyArrays[loc].recordPropertyDidChange(keys);
603
671
  }
604
672
  },
@@ -625,17 +693,19 @@ SC.Record = SC.Object.extend(
625
693
 
626
694
  normalize: function(includeNull) {
627
695
  var primaryKey = this.primaryKey,
628
- recordId = this.get('id'),
629
696
  store = this.get('store'),
630
697
  storeKey = this.get('storeKey'),
631
698
  keysToKeep = {},
632
- key, valueForKey, typeClass, recHash, attrValue, normChild, isRecord,
699
+ key, valueForKey, typeClass, recHash, attrValue, isRecord,
633
700
  isChild, defaultVal, keyForDataHash, attr;
634
701
 
635
702
  var dataHash = store.readEditableDataHash(storeKey) || {};
636
- dataHash[primaryKey] = recordId;
637
703
  recHash = store.readDataHash(storeKey);
638
704
 
705
+ // For now we're going to be agnostic about whether ids should live in the
706
+ // hash or not.
707
+ keysToKeep[primaryKey] = YES;
708
+
639
709
  for (key in this) {
640
710
  // make sure property is a record attribute.
641
711
  valueForKey = this[key];
@@ -656,7 +726,7 @@ SC.Record = SC.Object.extend(
656
726
  if(attrValue!==undefined && (attrValue!==null || includeNull)) {
657
727
  attr = this[key];
658
728
  // if record attribute, make sure we transform with the fromType
659
- if(SC.instanceOf(attr, SC.RecordAttribute)) {
729
+ if(SC.kindOf(attr, SC.RecordAttribute)) {
660
730
  attrValue = attr.fromType(this, key, attrValue);
661
731
  }
662
732
  dataHash[keyForDataHash] = attrValue;
@@ -768,7 +838,6 @@ SC.Record = SC.Object.extend(
768
838
  */
769
839
  commitRecord: function(params, recordOnly, callback) {
770
840
  var store = this.get('store'), rec, ro,
771
- sk = this.get('storeKey'),
772
841
  prKey = store.parentStoreKeyExists();
773
842
 
774
843
  // If we only want to commit this record or it doesn't have a parent record
@@ -780,7 +849,7 @@ SC.Record = SC.Object.extend(
780
849
  rec = store.materializeRecord(prKey);
781
850
  rec.commitRecord(params, recordOnly, callback);
782
851
  }
783
- return this ;
852
+ return this;
784
853
  },
785
854
 
786
855
  // ..........................................................
@@ -808,7 +877,7 @@ SC.Record = SC.Object.extend(
808
877
  @dependsOn isError
809
878
  */
810
879
  errorValue: function() {
811
- return this.get('isError') ? SC.val(this.get('errorObject')) : null ;
880
+ return this.get('isError') ? SC.val(this.get('errorObject')) : null;
812
881
  }.property('isError').cacheable(),
813
882
 
814
883
  /**
@@ -823,7 +892,7 @@ SC.Record = SC.Object.extend(
823
892
  if (this.get('isError')) {
824
893
  var store = this.get('store');
825
894
  return store.readError(this.get('storeKey')) || SC.Record.GENERIC_ERROR;
826
- } else return null ;
895
+ } else return null;
827
896
  }.property('isError').cacheable(),
828
897
 
829
898
  // ...............................
@@ -928,7 +997,7 @@ SC.Record = SC.Object.extend(
928
997
  @param {SC.Record} the record that was materialized
929
998
  */
930
999
  _materializeNestedRecordType: function(value, key){
931
- var childNS, recordType, ret;
1000
+ var childNS, recordType;
932
1001
 
933
1002
  // Get the record type, first checking the "type" property on the hash.
934
1003
  if (SC.typeOf(value) === SC.T_HASH) {
@@ -961,7 +1030,7 @@ SC.Record = SC.Object.extend(
961
1030
  @returns {SC.Record} the nested record created
962
1031
  */
963
1032
  createNestedRecord: function(recordType, hash, psk, path) {
964
- var store = this.get('store'), id, sk, pk, cr = null;
1033
+ var store = this.get('store'), id, sk, cr = null;
965
1034
 
966
1035
  hash = hash || {}; // init if needed
967
1036
 
@@ -974,7 +1043,7 @@ SC.Record = SC.Object.extend(
974
1043
  // that we don't keep making new storeKeys for the same child record each
975
1044
  // time that it is reloaded.
976
1045
  id = hash[recordType.prototype.primaryKey];
977
- if (!id) this.generateIdForChild(cr);
1046
+ if (!id) { id = this.generateIdForChild(cr); }
978
1047
  if (!id) { id = psk + '.' + path; }
979
1048
 
980
1049
  // If there is an id, there may also be a storeKey. If so, update the
@@ -1002,7 +1071,7 @@ SC.Record = SC.Object.extend(
1002
1071
  */
1003
1072
  generateIdForChild: function(childRecord){}
1004
1073
 
1005
- }) ;
1074
+ });
1006
1075
 
1007
1076
  // Class Methods
1008
1077
  SC.Record.mixin( /** @scope SC.Record */ {
@@ -1315,6 +1384,23 @@ SC.Record.mixin( /** @scope SC.Record */ {
1315
1384
  */
1316
1385
  GENERIC_ERROR: SC.$error("Generic Error"),
1317
1386
 
1387
+ /**
1388
+ If true, then searches for records of this type will return subclass instances. For example:
1389
+
1390
+ Person = SC.Record.extend();
1391
+ Person.isPolymorphic = true;
1392
+
1393
+ Male = Person.extend();
1394
+ Female = Person.extend();
1395
+
1396
+ Using SC.Store#find, or a toOne or toMany relationship on Person will then return records of
1397
+ type Male and Female. Polymorphic record types must have unique GUIDs across all subclasses.
1398
+
1399
+ @type Boolean
1400
+ @default NO
1401
+ */
1402
+ isPolymorphic: NO,
1403
+
1318
1404
  /**
1319
1405
  @private
1320
1406
  The next child key to allocate. A nextChildKey must always be greater than 0.
@@ -1361,7 +1447,7 @@ SC.Record.mixin( /** @scope SC.Record */ {
1361
1447
  @returns {SC.RecordAttribute} created instance
1362
1448
  */
1363
1449
  fetch: function(recordType, opts) {
1364
- return SC.FetchedAttribute.attr(recordType, opts) ;
1450
+ return SC.FetchedAttribute.attr(recordType, opts);
1365
1451
  },
1366
1452
 
1367
1453
  /**
@@ -1391,6 +1477,12 @@ SC.Record.mixin( /** @scope SC.Record */ {
1391
1477
  this._throwUnlessRecordTypeDefined(recordType, 'toMany');
1392
1478
 
1393
1479
  if(isNested){
1480
+ //@if(debug)
1481
+ // Let's provide a little developer help for a common misunderstanding.
1482
+ if (!SC.none(opts.inverse)) {
1483
+ SC.error("Developer Error: Nested attributes (toMany and toOne with isNested: YES) may not have an inverse property. Nested attributes shouldn't exist as separate records with IDs and relationships; if they do, it's likely that they should be separate records.\n\nNote that if your API nests separate records for convenient requesting and transport, you should separate them in your data source rather than improperly modeling them with nested attributes.");
1484
+ }
1485
+ //@endif
1394
1486
  attr = SC.ChildrenAttribute.attr(recordType, opts);
1395
1487
  }
1396
1488
  else {
@@ -1420,6 +1512,12 @@ SC.Record.mixin( /** @scope SC.Record */ {
1420
1512
  this._throwUnlessRecordTypeDefined(recordType, 'toOne');
1421
1513
 
1422
1514
  if(isNested){
1515
+ //@if(debug)
1516
+ // Let's provide a little developer help for a common misunderstanding.
1517
+ if (!SC.none(opts.inverse)) {
1518
+ SC.error("Developer Error: Nested attributes (toMany and toOne with isNested: YES) may not have an inverse property. Nested attributes shouldn't exist as separate records with IDs and relationships; if they do, it's likely that they should be separate records.\n\nNote that if your API nests separate records for convenient requesting and transport, you should separate them in your data source rather than improperly modeling them with nested attributes.");
1519
+ }
1520
+ //@endif
1423
1521
  attr = SC.ChildAttribute.attr(recordType, opts);
1424
1522
  }
1425
1523
  else {
@@ -1436,16 +1534,28 @@ SC.Record.mixin( /** @scope SC.Record */ {
1436
1534
  },
1437
1535
 
1438
1536
  /**
1439
- Returns all storeKeys mapped by Id for this record type. This method is
1440
- used mostly by the `SC.Store` and the Record to coordinate. You will rarely
1441
- need to call this method yourself.
1537
+ Returns all storeKeys mapped by Id for this record type. This method is used mostly by the
1538
+ `SC.Store` and the Record to coordinate. You will rarely need to call this method yourself.
1539
+
1540
+ Note that for polymorpic record classes, all store keys are kept on the top-most polymorphic
1541
+ superclass. This ensures that store key by id requests at any level return only the one unique
1542
+ store key.
1442
1543
 
1443
- @returns {Hash}
1544
+ @see SC.Record.storeKeysById
1444
1545
  */
1445
1546
  storeKeysById: function() {
1446
- var key = SC.keyFor('storeKey', SC.guidFor(this)),
1447
- ret = this[key];
1448
- if (!ret) ret = this[key] = {};
1547
+ var superclass = this.superclass,
1548
+ key = SC.keyFor('storeKey', SC.guidFor(this)),
1549
+ ret = this[key];
1550
+
1551
+ if (!ret) {
1552
+ if (this.isPolymorphic && superclass.isPolymorphic && superclass !== SC.Record) {
1553
+ ret = this[key] = superclass.storeKeysById();
1554
+ } else {
1555
+ ret = this[key] = {};
1556
+ }
1557
+ }
1558
+
1449
1559
  return ret;
1450
1560
  },
1451
1561
 
@@ -1462,16 +1572,16 @@ SC.Record.mixin( /** @scope SC.Record */ {
1462
1572
  */
1463
1573
  storeKeyFor: function(id) {
1464
1574
  var storeKeys = this.storeKeysById(),
1465
- ret = storeKeys[id];
1575
+ ret = storeKeys[id];
1466
1576
 
1467
1577
  if (!ret) {
1468
1578
  ret = SC.Store.generateStoreKey();
1469
- SC.Store.idsByStoreKey[ret] = id ;
1470
- SC.Store.recordTypesByStoreKey[ret] = this ;
1471
- storeKeys[id] = ret ;
1579
+ SC.Store.idsByStoreKey[ret] = id;
1580
+ SC.Store.recordTypesByStoreKey[ret] = this;
1581
+ storeKeys[id] = ret;
1472
1582
  }
1473
1583
 
1474
- return ret ;
1584
+ return ret;
1475
1585
  },
1476
1586
 
1477
1587
  /**
@@ -1484,9 +1594,9 @@ SC.Record.mixin( /** @scope SC.Record */ {
1484
1594
  */
1485
1595
  storeKeyExists: function(id) {
1486
1596
  var storeKeys = this.storeKeysById(),
1487
- ret = storeKeys[id];
1597
+ ret = storeKeys[id];
1488
1598
 
1489
- return ret ;
1599
+ return ret;
1490
1600
  },
1491
1601
 
1492
1602
  /**
@@ -1500,10 +1610,19 @@ SC.Record.mixin( /** @scope SC.Record */ {
1500
1610
  return store.find(this, id);
1501
1611
  },
1502
1612
 
1503
- /** @private - enhance extend to notify SC.Query as well. */
1613
+ /** @private - enhance extend to notify SC.Query and ensure polymorphic subclasses are marked as polymorphic as well. */
1504
1614
  extend: function() {
1505
1615
  var ret = SC.Object.extend.apply(this, arguments);
1506
- if(SC.Query) SC.Query._scq_didDefineRecordType(ret);
1507
- return ret ;
1616
+
1617
+ if (SC.Query) SC.Query._scq_didDefineRecordType(ret);
1618
+
1619
+ // All subclasses of a polymorphic class, must also be polymorphic.
1620
+ if (ret.prototype.hasOwnProperty('isPolymorphic')) {
1621
+ ret.isPolymorphic = ret.prototype.isPolymorphic;
1622
+ delete ret.prototype.isPolymorphic;
1623
+ }
1624
+
1625
+ return ret;
1508
1626
  }
1627
+
1509
1628
  });