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
@@ -69,56 +69,57 @@ SC.TreeController = SC.ObjectController.extend(SC.SelectionSupport,
69
69
 
70
70
  @type SC.Array
71
71
  */
72
- arrangedObjects: function () {
73
- var content = this.get('content'),
74
- ret;
75
-
76
- if (content) {
77
- ret = SC.TreeItemObserver.create({ item: content, delegate: this });
78
- ret.bind('allowsSelection', this, 'allowsSelection');
79
- ret.bind('allowsMultipleSelection', this, 'allowsMultipleSelection');
80
- ret.bind('allowsEmptySelection', this, 'allowsEmptySelection');
81
-
82
- ret.addObserver('[]', this, this._sctc_arrangedObjectsContentDidChange);
83
- } else {
84
- ret = null; // empty!
85
- }
86
-
87
- // Cache the current tree item observer, so we have it when it changes.
88
- this._sctc_arrangedObjects = ret;
89
-
90
- return ret;
91
- }.property().cacheable(),
72
+ arrangedObjects: null,
92
73
 
93
74
  // ..........................................................
94
75
  // PRIVATE
95
76
  //
96
77
 
97
- /**
98
- @private
78
+ /** @private - setup observer on init if needed. */
79
+ init: function() {
80
+ sc_super();
99
81
 
100
- Manually invalidate the arrangedObjects cache so that we can teardown
101
- any existing value. We do it via an observer so that this will fire
102
- immediately instead of waiting on some other component to get
103
- arrangedObjects again.
104
- */
105
- _sctc_invalidateArrangedObjects: function () {
106
- this.propertyWillChange('arrangedObjects');
82
+ // Initialize arrangedObjects.
83
+ this._contentDidChange();
84
+ },
107
85
 
108
- // Clean up! Destroy the previous tree item observer.
109
- var ret = this._sctc_arrangedObjects;
110
- if (ret) { ret.destroy(); }
111
- this._sctc_arrangedObjects = null;
86
+ /** @private */
87
+ _contentDidChange: function () {
88
+ var arrangedObjects = this.get('arrangedObjects'),
89
+ content = this.get('content');
112
90
 
113
- this.propertyDidChange('arrangedObjects');
91
+ if (content) {
92
+ if (arrangedObjects) {
93
+ arrangedObjects.set('item', content);
94
+ } else {
95
+ arrangedObjects = SC.TreeItemObserver.create({ item: content, delegate: this });
114
96
 
115
- // Fix up the selection with the new arrangedObjects.
116
- this.updateSelectionAfterContentChange();
117
- }.observes('content', 'treeItemIsExpandedKey', 'treeItemChildrenKey', 'treeItemIsGrouped'),
97
+ // Bind selection properties across to the observer.
98
+ arrangedObjects.bind('allowsSelection', this, 'allowsSelection');
99
+ arrangedObjects.bind('allowsMultipleSelection', this, 'allowsMultipleSelection');
100
+ arrangedObjects.bind('allowsEmptySelection', this, 'allowsEmptySelection');
101
+
102
+ // Observe the enumerable property in order to update the selection when it changes.
103
+ arrangedObjects.addObserver('[]', this, this._sctc_arrangedObjectsContentDidChange);
118
104
 
105
+ this.set('arrangedObjects', arrangedObjects);
106
+ }
107
+ } else {
108
+ // Since there is no content. Destroy the previous tree item observer and indicate that arrangedObjects has changed.
109
+ if (arrangedObjects) {
110
+ arrangedObjects.destroy();
111
+ this.set('arrangedObjects', null);
112
+
113
+ // Update the selection if it exists.
114
+ this._sctc_arrangedObjectsContentDidChange();
115
+ }
116
+ }
117
+ }.observes('content'),
118
+
119
+ /** @private */
119
120
  _sctc_arrangedObjectsContentDidChange: function () {
120
121
  this.updateSelectionAfterContentChange();
121
- },
122
+ }.observes(),
122
123
 
123
124
  canSelectGroups: NO,
124
125
 
@@ -1,23 +1,10 @@
1
1
 
2
2
  /**
3
- If true, then all SC.Controls can be focused when the
4
- user presses the tab key. Otherwise, only TextFieldViews
5
- will be focused.
3
+ If true, then all SproutCore controls can be focused when the user presses the
4
+ tab key. Otherwise, only `SC.TextFieldView`'s will be focused.
6
5
 
7
- @type String
6
+ @type Boolean
7
+ @default false
8
8
  @constant
9
9
  */
10
- SC.FOCUS_ALL_CONTROLS = NO;
11
-
12
- /*
13
- TODO [CC @ 1.5] Remove this deprecation warning eventually
14
- */
15
- SC.ready(function() {
16
- var focus = SC.SAFARI_FOCUS_BEHAVIOR;
17
- if (focus !== null && focus !== undefined) {
18
- // @if (debug)
19
- SC.Logger.warn("SC.SAFARI_FOCUS_BEHAVIOR is deprecated. Please use SC.FOCUS_ALL_CONTROLS instead");
20
- // @endif
21
- SC.FOCUS_ALL_CONTROLS = SC.SAFARI_FOCUS_BEHAVIOR;
22
- }
23
- });
10
+ SC.FOCUS_ALL_CONTROLS = false;
@@ -199,3 +199,15 @@ SC.ControlTestPane.show = function() {
199
199
  SC.RunLoop.end();
200
200
  });
201
201
  };
202
+
203
+ /**
204
+ Makes the test pane the key pane, so that key handling methods can be properly tested.
205
+ */
206
+ SC.ControlTestPane.becomeKeyPane = function () {
207
+ var pane = this._pane || this._showPane;
208
+ if (pane) {
209
+ SC.run(function () {
210
+ pane.becomeKeyPane();
211
+ });
212
+ }
213
+ };
@@ -0,0 +1,84 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2011 Strobe Inc. and contributors.
4
+ // Portions ©2008-2011 Apple Inc. All rights reserved.
5
+ // License: Licensed under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+ /** @private
9
+ Active Support style inflection constants
10
+ */
11
+ SC.hashesForLocale('en', 'inflectionConstants', {
12
+ /** @private */
13
+ PLURAL: [
14
+ [/(quiz)$/i, "$1zes" ],
15
+ [/^(ox)$/i, "$1en" ],
16
+ [/([m|l])ouse$/i, "$1ice" ],
17
+ [/(matr|vert|ind)ix|ex$/i, "$1ices" ],
18
+ [/(x|ch|ss|sh)$/i, "$1es" ],
19
+ [/([^aeiouy]|qu)y$/i, "$1ies" ],
20
+ [/(hive)$/i, "$1s" ],
21
+ [/(?:([^f])fe|([lr])f)$/i, "$1$2ves"],
22
+ [/sis$/i, "ses" ],
23
+ [/([ti])um$/i, "$1a" ],
24
+ [/(buffal|tomat)o$/i, "$1oes" ],
25
+ [/(bu)s$/i, "$1ses" ],
26
+ [/(alias|status)$/i, "$1es" ],
27
+ [/(octop|vir)us$/i, "$1i" ],
28
+ [/(ax|test)is$/i, "$1es" ],
29
+ [/s$/i, "s" ],
30
+ [/$/, "s" ]
31
+ ],
32
+
33
+ /** @private */
34
+ SINGULAR: [
35
+ [/(quiz)zes$/i, "$1" ],
36
+ [/(matr)ices$/i, "$1ix" ],
37
+ [/(vert|ind)ices$/i, "$1ex" ],
38
+ [/^(ox)en/i, "$1" ],
39
+ [/(alias|status)es$/i, "$1" ],
40
+ [/(octop|vir)i$/i, "$1us" ],
41
+ [/(cris|ax|test)es$/i, "$1is" ],
42
+ [/(shoe)s$/i, "$1" ],
43
+ [/(o)es$/i, "$1" ],
44
+ [/(bus)es$/i, "$1" ],
45
+ [/([m|l])ice$/i, "$1ouse" ],
46
+ [/(x|ch|ss|sh)es$/i, "$1" ],
47
+ [/(m)ovies$/i, "$1ovie" ],
48
+ [/(s)eries$/i, "$1eries"],
49
+ [/([^aeiouy]|qu)ies$/i, "$1y" ],
50
+ [/([lr])ves$/i, "$1f" ],
51
+ [/(tive)s$/i, "$1" ],
52
+ [/(hive)s$/i, "$1" ],
53
+ [/([^f])ves$/i, "$1fe" ],
54
+ [/(^analy)ses$/i, "$1sis" ],
55
+ [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis"],
56
+ [/([ti])a$/i, "$1um" ],
57
+ [/(n)ews$/i, "$1ews" ],
58
+ [/s$/i, "" ]
59
+ ],
60
+
61
+ /** @private */
62
+ IRREGULAR: [
63
+ ['move', 'moves' ],
64
+ ['sex', 'sexes' ],
65
+ ['child', 'children'],
66
+ ['man', 'men' ],
67
+ ['person', 'people' ],
68
+ ['woman', 'women' ],
69
+ ['self', 'selves' ]
70
+ ],
71
+
72
+ /** @private */
73
+ UNCOUNTABLE: [
74
+ "sheep",
75
+ "fish",
76
+ "series",
77
+ "species",
78
+ "money",
79
+ "rice",
80
+ "information",
81
+ "info",
82
+ "equipment"
83
+ ]
84
+ });
@@ -0,0 +1,41 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2011 Strobe Inc. and contributors.
4
+ // Portions ©2008-2011 Apple Inc. All rights reserved.
5
+ // License: Licensed under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+ /** @private
9
+ Active Support style inflection constants
10
+ */
11
+ SC.hashesForLocale('fr', 'inflectionConstants', {
12
+ /** @private */
13
+ PLURAL: [
14
+ [/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)$/i, '$1x'],
15
+ [/(bleu|émeu|landau|lieu|pneu|sarrau)$/i, '$1s'],
16
+ [/al$/i, 'aux'],
17
+ [/ail$/i, 'ails'],
18
+ [/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/i, '$1aux'],
19
+ [/(s|x|z)$/i, '$1'],
20
+ [/$/, "s"]
21
+ ],
22
+
23
+ /** @private */
24
+ SINGULAR: [
25
+ [/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/i, '$1'],
26
+ [/(journ|chev)aux$/i, '$1al'],
27
+ [/ails$/i, 'ail'],
28
+ [/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/i, '$1ail'],
29
+ [/s$/i, ""]
30
+ ],
31
+
32
+ /** @private */
33
+ IRREGULAR: [
34
+ ['monsieur', 'messieurs'],
35
+ ['madame', 'mesdames'],
36
+ ['mademoiselle', 'mesdemoiselles']
37
+ ],
38
+
39
+ /** @private */
40
+ UNCOUNTABLE: []
41
+ });
@@ -6,6 +6,7 @@
6
6
  // ==========================================================================
7
7
 
8
8
  /**
9
+ @deprecated SC.AutoMixin is deprecated. Please use the property autoMixins of SC.View instead
9
10
  @namespace
10
11
 
11
12
  Use this mixin to automatically mix in a list of mixins into all
@@ -313,6 +313,13 @@ SC.AutoResize = {
313
313
  if (this.get('shouldAutoFitText') && this.get('calculatedFontSize') !== maxFontSize) {
314
314
  layer.style.fontSize = maxFontSize + "px";
315
315
  }
316
+
317
+ // When resizing only the height, we should restrict the width to that of the given
318
+ // layer. This way, the height will grow appropriately to fit the target as
319
+ // text *wraps* within the current width.
320
+ if (!this.get('shouldResizeWidth')) {
321
+ layer.style.maxWidth = $(layer).outerWidth() + 'px';
322
+ }
316
323
  },
317
324
 
318
325
  /**
@@ -18,7 +18,9 @@
18
18
  ## Example
19
19
 
20
20
  MyApp.MyViewClass = SC.View.extend(SC.ContentDisplay, {
21
- contentDisplayProperties: 'title isEnabled hasChildren'.w(),
21
+
22
+ contentDisplayProperties: ['title', 'isEnabled', 'hasChildren'],
23
+
22
24
  ...
23
25
  });
24
26
 
@@ -29,9 +31,6 @@ SC.ContentDisplay = {
29
31
  /** @private */
30
32
  concatenatedProperties: 'contentDisplayProperties',
31
33
 
32
- /** @private */
33
- displayProperties: ['content'],
34
-
35
34
  /**
36
35
  Add an array with the names of any property on the content object that
37
36
  should trigger an update of the display for your view. Changes to the
@@ -138,6 +138,8 @@ SC.FlowedLayout = {
138
138
  /** @private */
139
139
  initMixin: function() {
140
140
  this._scfl_tileOnce();
141
+ // register observer to detect the childViews changes
142
+ this.addObserver( 'childViews.[]', this, this._scfl_childViewsDidChange );
141
143
  },
142
144
 
143
145
  /** @private
@@ -145,7 +147,7 @@ SC.FlowedLayout = {
145
147
  */
146
148
  _scfl_childViewsDidChange: function(c) {
147
149
  this._scfl_tileOnce();
148
- }.observes('childViews'),
150
+ },
149
151
 
150
152
  /** @private */
151
153
  _scfl_layoutPropertyDidChange: function(childView) {
@@ -772,7 +774,7 @@ SC.FlowedLayout = {
772
774
  // second, observe all children, and stop observing any children we no longer
773
775
  // should be observing.
774
776
  var previouslyObserving = this._scfl_isObserving || SC.CoreSet.create(),
775
- nowObserving = SC.CoreSet.create();
777
+ nowObserving = this._scfl_isObserving = SC.CoreSet.create();
776
778
 
777
779
  var children = this.get('childViews'), len = children.length, idx, child;
778
780
  for (idx = 0; idx < len; idx++) {
@@ -807,6 +809,8 @@ SC.FlowedLayout = {
807
809
 
808
810
  /** @private */
809
811
  destroyMixin: function() {
812
+ this.removeObserver( 'childViews.[]', this, this._scfl_childViewsDidChange );
813
+
810
814
  var isObserving = this._scfl_isObserving;
811
815
  if (!isObserving) return;
812
816
 
@@ -16,7 +16,13 @@ sc_require('mixins/collection_content');
16
16
  when trying to display the item in a hierarchy.
17
17
 
18
18
  When displaying a tree of objects, a tree item object will be nested to
19
- cover every object that might have child views.
19
+ cover every object that might have child views, ignoring those that will
20
+ definitely not. (Any node which has children or may have children should
21
+ advertise this by exposing an array at its treeItemChildrenKey property;
22
+ any node which does not do so is assumed to be permanently childless, so
23
+ we optimize by not observing it. In CS terms, nodes can implicitly
24
+ advertise whether they are *leaves-or-branches* and should be observed,
25
+ or are *permanently leaves*, and may remain unobserved.)
20
26
 
21
27
  TreeNode stores an array which contains either a number pointing to the
22
28
  next place in the array there is a child item or it contains a child item.
@@ -28,6 +34,26 @@ sc_require('mixins/collection_content');
28
34
  */
29
35
  SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
30
36
 
37
+ //@if(debug)
38
+ /* BEGIN DEBUG ONLY PROPERTIES AND METHODS */
39
+
40
+ /* @private */
41
+ toString: function () {
42
+ var item = this.get('item'),
43
+ ret = sc_super();
44
+
45
+ return item ? "%@:\n ↳ %@".fmt(ret, item) : ret;
46
+ },
47
+
48
+ /* END DEBUG ONLY PROPERTIES AND METHODS */
49
+ //@endif
50
+
51
+ /** @private */
52
+ _cachedItem: null,
53
+
54
+ /** @private */
55
+ _cachedDelegate: null,
56
+
31
57
  /**
32
58
  The node in the tree this observer will manage. Set when creating the
33
59
  object. If you are creating an observer manually, you must set this to
@@ -45,6 +71,26 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
45
71
  */
46
72
  delegate: null,
47
73
 
74
+ /**
75
+ The key used to retrieve children from the observed item. If a
76
+ delegate exists, the key will be the value of the `treeItemChildrenKey`
77
+ property of the delegate. Otherwise, the key will be `treeItemChildren`.
78
+
79
+ @type String
80
+ @default 'treeItemChildren'
81
+ */
82
+ treeItemChildrenKey: 'treeItemChildren',
83
+
84
+ /**
85
+ The key used to identify the expanded state of the observed item.
86
+ If a delegate exists, the key will be the value of the `treeItemIsExpandedKey`
87
+ property of the delegate. Otherwise, the key will be `treeItemIsExpanded`.
88
+
89
+ @type String
90
+ @default 'treeItemIsExpanded'
91
+ */
92
+ treeItemIsExpandedKey: 'treeItemIsExpanded',
93
+
48
94
  // ..........................................................
49
95
  // FOR NESTED OBSERVERS
50
96
  //
@@ -58,7 +104,7 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
58
104
  The parent item for the observer item. Computed automatically from the
59
105
  parent. If the value of this is null, then this is the root of the tree.
60
106
  */
61
- parentItem: function() {
107
+ parentItem: function () {
62
108
  var p = this.get('parentObserver');
63
109
  return p ? p.get('item') : null;
64
110
  }.property('parentObserver').cacheable(),
@@ -99,7 +145,7 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
99
145
  @property
100
146
  @type SC.IndexSet
101
147
  */
102
- branchIndexes: function() {
148
+ branchIndexes: function () {
103
149
  var item = this.get('item'),
104
150
  len, pitem, idx, children, ret;
105
151
 
@@ -109,7 +155,7 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
109
155
  // if item is treeItemContent then ask it directly
110
156
  else if (item.isTreeItemContent) {
111
157
  pitem = this.get('parentItem');
112
- idx = this.get('index') ;
158
+ idx = this.get('index');
113
159
  return item.treeItemBranchIndexes(pitem, idx);
114
160
 
115
161
  // otherwise, loop over children and determine disclosure state for each
@@ -118,17 +164,18 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
118
164
  if (!children) return null; // no children - no branches
119
165
  ret = SC.IndexSet.create();
120
166
  len = children.get('length');
121
- pitem = item ; // save parent
167
+ pitem = item; // save parent
122
168
 
123
- for(idx=0;idx<len;idx++) {
124
- if (!(item = children.objectAt(idx))) continue ;
169
+ for (idx = 0; idx < len; idx++) {
170
+ item = children.objectAt(idx);
171
+ if (!item) continue;
125
172
  if (!this._computeChildren(item, pitem, idx)) continue; // no children
126
173
  if (this._computeDisclosureState(item, pitem, idx) !== SC.LEAF_NODE) {
127
174
  ret.add(idx);
128
175
  }
129
176
  }
130
177
 
131
- return ret.get('length')>0 ? ret : null;
178
+ return ret.get('length') > 0 ? ret : null;
132
179
  }
133
180
  }.property('children').cacheable(),
134
181
 
@@ -136,7 +183,7 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
136
183
  Returns YES if the item itself should be shown, NO if only its children
137
184
  should be shown. Normally returns YES unless the parentObject is null.
138
185
  */
139
- isHeaderVisible: function() {
186
+ isHeaderVisible: function () {
140
187
  return !!this.get('parentObserver');
141
188
  }.property('parentObserver').cacheable(),
142
189
 
@@ -161,12 +208,11 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
161
208
  @param {Boolean} omitMaterializing
162
209
  @returns {Object}
163
210
  */
164
- objectAt: function(index, omitMaterializing) {
211
+ objectAt: function (index, omitMaterializing) {
165
212
  var len = this.get('length'),
166
213
  item = this.get('item'),
167
214
  cache = this._objectAtCache,
168
215
  cur = index,
169
- loc = 0,
170
216
  indexes, children;
171
217
 
172
218
  if (index >= len) return undefined;
@@ -177,35 +223,38 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
177
223
  item = null;
178
224
 
179
225
  if (!cache) cache = this._objectAtCache = [];
180
- if ((item = cache[index]) !== undefined) return item ;
226
+ if ((item = cache[index]) !== undefined) return item;
181
227
 
182
228
  children = this.get('children');
183
229
  if (!children) return undefined; // no children - nothing to get
184
230
 
185
231
  // loop through branch indexes, reducing the offset until it matches
186
232
  // something we might actually return.
187
- if (indexes = this.get('branchIndexes')) {
188
- indexes.forEach(function(i) {
189
- if (item || (i > cur)) return ; // past end - nothing to do
233
+ indexes = this.get('branchIndexes');
234
+ if (indexes) {
235
+ indexes.forEach(function (i) {
236
+ if (item || (i > cur)) return; // past end - nothing to do
190
237
 
191
238
  var observer = this.branchObserverAt(i), len;
192
- if (!observer) return ; // nothing to do
239
+ if (!observer) return; // nothing to do
193
240
 
194
241
  // if cur lands inside of this observer's length, use objectAt to get
195
242
  // otherwise, just remove len from cur.
196
- len = observer.get('length') ;
197
- if (i+len > cur) {
198
- item = observer.objectAt(cur-i, omitMaterializing);
199
- cur = -1;
200
- } else cur -= len-1 ;
243
+ len = observer.get('length');
244
+ if (i + len > cur) {
245
+ item = observer.objectAt(cur - i, omitMaterializing);
246
+ cur = -1;
247
+ } else {
248
+ cur = cur - (len - 1);
249
+ }
201
250
 
202
- },this);
251
+ }, this);
203
252
  }
204
253
 
205
- if (cur>=0) item = children.objectAt(cur, omitMaterializing); // get internal if needed
206
- cache[index] = item ; // save in cache
254
+ if (cur >= 0) item = children.objectAt(cur, omitMaterializing); // get internal if needed
255
+ cache[index] = item; // save in cache
207
256
 
208
- return item ;
257
+ return item;
209
258
  },
210
259
 
211
260
  /**
@@ -237,9 +286,9 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
237
286
  @param {Number} operation either SC.DROP_BEFORE or SC.DROP_AFTER
238
287
  @returns {SC.TreeItemObserver} receiver
239
288
  */
240
- replace: function(start, amt, objects, operation) {
289
+ replace: function (start, amt, objects, operation) {
241
290
 
242
- var cur = start,
291
+ var cur = start,
243
292
  observer = null,
244
293
  indexes, len, max;
245
294
 
@@ -252,19 +301,25 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
252
301
 
253
302
  // remove branch lengths. If the adjusted start location lands inside of
254
303
  // another branch, then just let that observer handle it.
255
- if (indexes = this.get('branchIndexes')) {
256
- indexes.forEach(function(i) {
257
- if (observer || (i>=cur)) return ; // nothing to do
258
- if (!(observer = this.branchObserverAt(i))) return; // nothing to do
304
+ indexes = this.get('branchIndexes');
305
+ if (indexes) {
306
+ indexes.forEach(function (i) {
307
+ if (observer || (i >= cur)) return; // nothing to do
308
+ observer = this.branchObserverAt(i);
309
+ if (!observer) return; // nothing to do
310
+
259
311
  len = observer.get('length');
260
312
 
261
313
  // if this branch range is before the start loc, just remove it and
262
314
  // go on. If cur is somewhere inside of the range, then save to pass
263
315
  // on. Note use of operation to determine the ambiguous end op.
264
- if ((i+len === cur) && operation === SC.DROP_AFTER) cur -= i;
265
- else if (i+len > cur) cur -= i; // put inside of nested range
266
- else {
267
- cur -= len-1; observer = null ;
316
+ if ((i + len === cur) && operation === SC.DROP_AFTER) {
317
+ cur = cur - i;
318
+ } else if (i + len > cur) {
319
+ cur = cur - i; // put inside of nested range
320
+ } else {
321
+ cur = cur - (len - 1);
322
+ observer = null;
268
323
  }
269
324
  }, this);
270
325
  }
@@ -279,25 +334,25 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
279
334
  // our own range. Now amt just needs to be adjusted to remove any
280
335
  // visible branches as well.
281
336
  max = cur + amt;
282
- if (amt>1 && indexes) { // if amt is 1 no need...
283
- indexes.forEachIn(cur, indexes.get('max')-cur, function(i) {
337
+ if (amt > 1 && indexes) { // if amt is 1 no need...
338
+ indexes.forEachIn(cur, indexes.get('max') - cur, function (i) {
284
339
  if (i > max) return; // nothing to do
285
340
  if (!(observer = this.branchObserverAt(i))) return; // nothing to do
286
341
  len = observer.get('length');
287
- max -= len-1;
342
+ max = max - (len - 1);
288
343
  }, this);
289
344
  }
290
345
 
291
346
  // get amt back out. if amt is negative, it means that the range passed
292
347
  // was not cleanly inside of this range. raise an exception.
293
- amt = max-cur;
348
+ amt = max - cur;
294
349
 
295
350
  // ok, now that we are adjusted, get the children and forward the replace
296
351
  // call on. if there are no children, bad news...
297
352
  var children = this.get('children');
298
353
  if (!children) throw new Error("cannot replace() tree item with no children");
299
354
 
300
- if ((amt < 0) || (max>children.get('length'))) {
355
+ if ((amt < 0) || (max > children.get('length'))) {
301
356
  throw new Error("replace() range must lie within a single tree item");
302
357
  }
303
358
 
@@ -316,13 +371,12 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
316
371
  The start, amt and delta params should reflect changes to the children
317
372
  array, not to the expanded range for the wrapper.
318
373
  */
319
- observerContentDidChange: function(start, amt, delta) {
374
+ observerContentDidChange: function (start, amt, delta) {
320
375
 
321
376
  // clear caches
322
377
  this.invalidateBranchObserversAt(start);
323
378
  this._objectAtCache = this._outlineLevelCache = null;
324
379
  this._disclosureStateCache = null;
325
- this._contentGroupIndexes = NO;
326
380
  this.notifyPropertyChange('branchIndexes');
327
381
 
328
382
  var oldlen = this.get('length'),
@@ -330,7 +384,9 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
330
384
  parent = this.get('parentObserver'), set;
331
385
 
332
386
  // update length if needed
333
- if (oldlen !== newlen) this.set('length', newlen);
387
+ if (oldlen !== newlen) {
388
+ this.set('length', newlen);
389
+ }
334
390
 
335
391
  // if we have a parent, notify that parent that we have changed.
336
392
  if (!this._notifyParent) return this; // nothing more to do
@@ -343,15 +399,15 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
343
399
  // to convert the passed change to reflect the computed range
344
400
  } else {
345
401
  if (oldlen === newlen) {
346
- amt = this.expandChildIndex(start+amt);
402
+ amt = this.expandChildIndex(start + amt);
347
403
  start = this.expandChildIndex(start);
348
- amt = amt - start ;
349
- delta = 0 ;
404
+ amt = amt - start;
405
+ delta = 0;
350
406
 
351
407
  } else {
352
408
  start = this.expandChildIndex(start);
353
409
  amt = newlen - start;
354
- delta = newlen - oldlen ;
410
+ delta = newlen - oldlen;
355
411
  }
356
412
 
357
413
  var removedCount = amt;
@@ -363,18 +419,18 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
363
419
  /**
364
420
  Accepts a child index and expands it to reflect any nested groups.
365
421
  */
366
- expandChildIndex: function(index) {
422
+ expandChildIndex: function (index) {
367
423
 
368
424
  var ret = index;
369
425
  if (this.get('isHeaderVisible')) index++;
370
426
 
371
427
  // fast path
372
428
  var branches = this.get('branchIndexes');
373
- if (!branches || branches.get('length')===0) return ret;
429
+ if (!branches || branches.get('length') === 0) return ret;
374
430
 
375
431
  // we have branches, adjust for their length
376
- branches.forEachIn(0, index, function(idx) {
377
- ret += this.branchObserverAt(idx).get('length')-1;
432
+ branches.forEachIn(0, index, function (idx) {
433
+ ret += this.branchObserverAt(idx).get('length') - 1;
378
434
  }, this);
379
435
 
380
436
  return ret; // add 1 for item header
@@ -384,18 +440,15 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
384
440
  // SC.COLLECTION CONTENT SUPPORT
385
441
  //
386
442
 
387
- _contentGroupIndexes: NO,
388
-
389
- /**
443
+ /** SC.CollectionContent
390
444
  Called by the collection view to return any group indexes. The default
391
445
  implementation will compute the indexes one time based on the delegate
392
446
  treeItemIsGrouped
393
447
  */
394
- contentGroupIndexes: function(view, content) {
395
- if (content !== this) return null; // only care about receiver
448
+ contentGroupIndexes: function (view, content) {
449
+ var ret;
396
450
 
397
- var ret = this._contentGroupIndexes;
398
- if (ret !== NO) return ret ;
451
+ if (content !== this) return null; // only care about receiver
399
452
 
400
453
  // If this is not the root item, never do grouping
401
454
  if (this.get('parentObserver')) return null;
@@ -416,33 +469,33 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
416
469
 
417
470
  // Padding is the difference between the tree index and array index for the current tree index
418
471
  padding = 0;
419
- indexes.forEach(function(i) {
472
+ indexes.forEach(function (i) {
420
473
  ret.add(i + padding, 1);
421
474
 
422
- var observer = this.branchObserverAt(i);
423
- if (observer) {
424
- padding += observer.get('length') - 1;
425
- cur += padding;
426
- }
427
- }, this);
475
+ var observer = this.branchObserverAt(i);
476
+ if (observer) {
477
+ padding += observer.get('length') - 1;
478
+ cur += padding;
479
+ }
480
+ }, this);
428
481
  }
429
482
  } else {
430
483
  ret = null;
431
484
  }
432
485
 
433
- this._contentGroupIndexes = ret ;
434
486
  return ret;
435
487
  },
436
488
 
437
- contentIndexIsGroup: function(view, content, idx) {
489
+ /** SC.CollectionContent */
490
+ contentIndexIsGroup: function (view, content, idx) {
438
491
  var indexes = this.contentGroupIndexes(view, content);
439
- return indexes ? indexes.contains(idx) : NO ;
492
+ return indexes ? indexes.contains(idx) : NO;
440
493
  },
441
494
 
442
495
  /**
443
496
  Returns the outline level for the specified index.
444
497
  */
445
- contentIndexOutlineLevel: function(view, content, index) {
498
+ contentIndexOutlineLevel: function (view, content, index) {
446
499
  if (content !== this) return -1; // only care about us
447
500
 
448
501
  var cache = this._outlineLevelCache;
@@ -451,46 +504,52 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
451
504
 
452
505
  var len = this.get('length'),
453
506
  cur = index,
454
- loc = 0,
455
507
  ret = null,
456
- indexes, children, observer;
508
+ indexes;
457
509
 
458
510
  if (index >= len) return -1;
459
511
 
460
512
  if (this.get('isHeaderVisible')) {
461
- if (index === 0) return cache[0] = this.get('outlineLevel')-1;
462
- else cur--;
513
+ if (index === 0) {
514
+ cache[0] = this.get('outlineLevel') - 1;
515
+ return cache[0];
516
+ } else {
517
+ cur--;
518
+ }
463
519
  }
464
520
 
465
521
  // loop through branch indexes, reducing the offset until it matches
466
522
  // something we might actually return.
467
- if (indexes = this.get('branchIndexes')) {
468
- indexes.forEach(function(i) {
469
- if ((ret!==null) || (i > cur)) return ; // past end - nothing to do
523
+ indexes = this.get('branchIndexes');
524
+ if (indexes) {
525
+ indexes.forEach(function (i) {
526
+ if ((ret !== null) || (i > cur)) return; // past end - nothing to do
470
527
 
471
528
  var observer = this.branchObserverAt(i), len;
472
- if (!observer) return ; // nothing to do
529
+ if (!observer) return; // nothing to do
473
530
 
474
531
  // if cur lands inside of this observer's length, use objectAt to get
475
532
  // otherwise, just remove len from cur.
476
- len = observer.get('length') ;
477
- if (i+len > cur) {
478
- ret = observer.contentIndexOutlineLevel(view, observer, cur-i);
479
- cur = -1;
480
- } else cur -= len-1 ;
533
+ len = observer.get('length');
534
+ if (i + len > cur) {
535
+ ret = observer.contentIndexOutlineLevel(view, observer, cur - i);
536
+ cur = -1;
537
+ } else {
538
+ cur = cur - (len - 1);
539
+ }
481
540
 
482
- },this);
541
+ }, this);
483
542
  }
484
543
 
485
- if (cur>=0) ret = this.get('outlineLevel'); // get internal if needed
486
- cache[index] = ret ; // save in cache
487
- return ret ;
544
+ if (cur >= 0) ret = this.get('outlineLevel'); // get internal if needed
545
+ cache[index] = ret; // save in cache
546
+ return ret;
488
547
  },
489
548
 
490
549
  /**
491
550
  Returns the disclosure state for the specified index.
492
551
  */
493
- contentIndexDisclosureState: function(view, content, index) {
552
+ contentIndexDisclosureState: function (view, content, index) {
494
553
  if (content !== this) return -1; // only care about us
495
554
 
496
555
  var cache = this._disclosureStateCache;
@@ -499,40 +558,46 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
499
558
 
500
559
  var len = this.get('length'),
501
560
  cur = index,
502
- loc = 0,
503
561
  ret = null,
504
- indexes, children, observer;
562
+ indexes;
505
563
 
506
564
  if (index >= len) return SC.LEAF_NODE;
507
565
 
508
566
  if (this.get('isHeaderVisible')) {
509
- if (index === 0) return cache[0] = this.get('disclosureState');
510
- else cur--;
567
+ if (index === 0) {
568
+ cache[0] = this.get('disclosureState');
569
+ return cache[0];
570
+ } else {
571
+ cur--;
572
+ }
511
573
  }
512
574
 
513
575
  // loop through branch indexes, reducing the offset until it matches
514
576
  // something we might actually return.
515
- if (indexes = this.get('branchIndexes')) {
516
- indexes.forEach(function(i) {
517
- if ((ret!==null) || (i > cur)) return ; // past end - nothing to do
577
+ indexes = this.get('branchIndexes');
578
+ if (indexes) {
579
+ indexes.forEach(function (i) {
580
+ if ((ret !== null) || (i > cur)) return; // past end - nothing to do
518
581
 
519
582
  var observer = this.branchObserverAt(i), len;
520
- if (!observer) return ; // nothing to do
583
+ if (!observer) return; // nothing to do
521
584
 
522
585
  // if cur lands inside of this observer's length, use objectAt to get
523
586
  // otherwise, just remove len from cur.
524
- len = observer.get('length') ;
525
- if (i+len > cur) {
526
- ret = observer.contentIndexDisclosureState(view, observer, cur-i);
587
+ len = observer.get('length');
588
+ if (i + len > cur) {
589
+ ret = observer.contentIndexDisclosureState(view, observer, cur - i);
527
590
  cur = -1;
528
- } else cur -= len-1 ;
591
+ } else {
592
+ cur = cur - (len - 1);
593
+ }
529
594
 
530
- },this);
595
+ }, this);
531
596
  }
532
597
 
533
- if (cur>=0) ret = SC.LEAF_NODE; // otherwise its a leaf node
534
- cache[index] = ret ; // save in cache
535
- return ret ;
598
+ if (cur >= 0) ret = SC.LEAF_NODE; // otherwise its a leaf node
599
+ cache[index] = ret; // save in cache
600
+ return ret;
536
601
  },
537
602
 
538
603
  /**
@@ -540,35 +605,39 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
540
605
  the branchObserver responsible for this item and then calls _collapse on
541
606
  it.
542
607
  */
543
- contentIndexExpand: function(view, content, idx) {
544
-
608
+ contentIndexExpand: function (view, content, idx) {
545
609
  var indexes, cur = idx, children, item;
546
610
 
547
611
  if (content !== this) return; // only care about us
548
612
  if (this.get('isHeaderVisible')) {
549
- if (idx===0) {
613
+ if (idx === 0) {
550
614
  this._expand(this.get('item'));
551
615
  return;
552
- } else cur--;
616
+ } else {
617
+ cur--;
618
+ }
553
619
  }
554
620
 
555
- if (indexes = this.get('branchIndexes')) {
556
- indexes.forEach(function(i) {
621
+ indexes = this.get('branchIndexes');
622
+ if (indexes) {
623
+ indexes.forEach(function (i) {
557
624
  if (i >= cur) return; // past end - nothing to do
558
625
  var observer = this.branchObserverAt(i), len;
559
- if (!observer) return ;
626
+ if (!observer) return;
560
627
 
561
628
  len = observer.get('length');
562
- if (i+len > cur) {
563
- observer.contentIndexExpand(view, observer, cur-i);
564
- cur = -1 ; //done
565
- } else cur -= len-1;
629
+ if (i + len > cur) {
630
+ observer.contentIndexExpand(view, observer, cur - i);
631
+ cur = -1; //done
632
+ } else {
633
+ cur = cur - (len - 1);
634
+ }
566
635
 
567
636
  }, this);
568
637
  }
569
638
 
570
639
  // if we are still inside of the range then maybe pass on to a child item
571
- if (cur>=0) {
640
+ if (cur >= 0) {
572
641
  children = this.get('children');
573
642
  item = children ? children.objectAt(cur) : null;
574
643
  if (item) this._expand(item, this.get('item'), cur);
@@ -584,36 +653,39 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
584
653
  @param {Number} idx the content index
585
654
  @returns {void}
586
655
  */
587
- contentIndexCollapse: function(view, content, idx) {
588
-
656
+ contentIndexCollapse: function (view, content, idx) {
589
657
  var indexes, children, item, cur = idx;
590
658
 
591
659
  if (content !== this) return; // only care about us
592
660
  if (this.get('isHeaderVisible')) {
593
- if (idx===0) {
661
+ if (idx === 0) {
594
662
  this._collapse(this.get('item'));
595
663
  return;
596
- } else cur--;
664
+ } else {
665
+ cur--;
666
+ }
597
667
  }
598
668
 
599
-
600
- if (indexes = this.get('branchIndexes')) {
601
- indexes.forEach(function(i) {
669
+ indexes = this.get('branchIndexes');
670
+ if (indexes) {
671
+ indexes.forEach(function (i) {
602
672
  if (i >= cur) return; // past end - nothing to do
603
673
  var observer = this.branchObserverAt(i), len;
604
- if (!observer) return ;
674
+ if (!observer) return;
605
675
 
606
676
  len = observer.get('length');
607
- if (i+len > cur) {
608
- observer.contentIndexCollapse(view, observer, cur-i);
609
- cur = -1 ; //done
610
- } else cur -= len-1;
677
+ if (i + len > cur) {
678
+ observer.contentIndexCollapse(view, observer, cur - i);
679
+ cur = -1; //done
680
+ } else {
681
+ cur = cur - (len - 1);
682
+ }
611
683
 
612
684
  }, this);
613
685
  }
614
686
 
615
687
  // if we are still inside of the range then maybe pass on to a child item
616
- if (cur>=0) {
688
+ if (cur >= 0) {
617
689
  children = this.get('children');
618
690
  item = children ? children.objectAt(cur) : null;
619
691
  if (item) this._collapse(item, this.get('item'), cur);
@@ -628,47 +700,48 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
628
700
  Returns the branch item for the specified index. If none exists yet, it
629
701
  will be created.
630
702
  */
631
- branchObserverAt: function(index) {
703
+ branchObserverAt: function (index) {
632
704
  var byIndex = this._branchObserversByIndex,
633
705
  indexes = this._branchObserverIndexes,
634
- ret, parent, pitem, item, children, guid, del ;
706
+ ret, item, children;
635
707
 
636
708
  if (!byIndex) byIndex = this._branchObserversByIndex = [];
637
709
  if (!indexes) {
638
710
  indexes = this._branchObserverIndexes = SC.IndexSet.create();
639
711
  }
640
712
 
641
- if (ret = byIndex[index]) return ret ; // use cache
713
+ ret = byIndex[index];
714
+ if (ret) return ret; // use cache
642
715
 
643
716
  // no observer for this content exists, create one
644
717
  children = this.get('children');
645
- item = children ? children.objectAt(index) : null ;
646
- if (!item) return null ; // can't create an observer for a null item
718
+ item = children ? children.objectAt(index) : null;
719
+ if (!item) return null; // can't create an observer for a null item
647
720
 
648
721
  byIndex[index] = ret = SC.TreeItemObserver.create({
649
722
  item: item,
650
723
  delegate: this.get('delegate'),
651
724
  parentObserver: this,
652
725
  index: index,
653
- outlineLevel: this.get('outlineLevel')+1
726
+ outlineLevel: this.get('outlineLevel') + 1
654
727
  });
655
728
 
656
729
  indexes.add(index); // save for later invalidation
657
- return ret ;
730
+ return ret;
658
731
  },
659
732
 
660
733
  /**
661
734
  Invalidates any branch observers on or after the specified index range.
662
735
  */
663
- invalidateBranchObserversAt: function(index) {
736
+ invalidateBranchObserversAt: function (index) {
664
737
  var byIndex = this._branchObserversByIndex,
665
738
  indexes = this._branchObserverIndexes;
666
739
 
667
- if (!byIndex || byIndex.length<=index) return this ; // nothing to do
668
- if (index < 0) index = 0 ;
740
+ if (!byIndex || byIndex.length <= index) return this; // nothing to do
741
+ if (index < 0) index = 0;
669
742
 
670
743
  // destroy any observer on or after the range
671
- indexes.forEachIn(index, indexes.get('max')-index, function(i) {
744
+ indexes.forEachIn(index, indexes.get('max') - index, function (i) {
672
745
  var observer = byIndex[i];
673
746
  if (observer) observer.destroy();
674
747
  }, this);
@@ -682,31 +755,66 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
682
755
  // INTERNAL METHODS
683
756
  //
684
757
 
685
- init: function() {
758
+ /** @private */
759
+ _cleanUpCachedDelegate: function () {
760
+ var cachedDelegate = this._cachedDelegate;
761
+
762
+ if (cachedDelegate) {
763
+ cachedDelegate.removeObserver('treeItemIsExpandedKey', this, this.treeItemIsExpandedKeyDidChange);
764
+ cachedDelegate.removeObserver('treeItemChildrenKey', this, this.treeItemChildrenKeyDidChange);
765
+ cachedDelegate.removeObserver('treeItemIsGrouped', this, this.treeItemIsGroupedDidChange);
766
+
767
+ // Remove the delegate specific key observers from the cached item.
768
+ this._cleanUpCachedItem();
769
+
770
+ // Reset the delegate specific keys.
771
+ this.set('treeItemChildrenKey', 'treeItemChildren');
772
+ this.set('treeItemIsExpandedKey', 'treeItemIsExpanded');
773
+
774
+ // Remove the cache.
775
+ this._cachedDelegate = null;
776
+ }
777
+ },
778
+
779
+ /** @private */
780
+ _cleanUpCachedItem: function () {
781
+ var cachedItem = this._cachedItem,
782
+ treeItemIsExpandedKey = this.get('treeItemIsExpandedKey'),
783
+ treeItemChildrenKey = this.get('treeItemChildrenKey');
784
+
785
+ if (cachedItem) {
786
+ cachedItem.removeObserver(treeItemIsExpandedKey, this, this._itemIsExpandedDidChange);
787
+ cachedItem.removeObserver(treeItemChildrenKey, this, this._itemChildrenDidChange);
788
+
789
+ // Remove the cache.
790
+ this._cachedItem = null;
791
+ }
792
+ },
793
+
794
+ /** SC.Object.prototype.init */
795
+ init: function () {
686
796
  sc_super();
687
797
 
688
- // begin all properties on item if there is one. This will allow us to
689
- // track important property changes.
690
- var item = this.get('item');
691
- if (!item) throw new Error("SC.TreeItemObserver.item cannot be null");
798
+ // Initialize the item and the delegate. Be sure to set up the delegate first,
799
+ // because it determines the keys to observe on the item.
800
+ this._delegateDidChange();
801
+ this._itemDidChange();
692
802
 
693
- item.addObserver('*', this, this._itemPropertyDidChange);
694
- this._itemPropertyDidChange(item, '*');
695
- this._notifyParent = YES ; // avoid infinite loops
803
+ this._notifyParent = YES; // avoid infinite loops
696
804
  },
697
805
 
698
- /**
806
+ /** SC.Object.prototype.destroy
699
807
  Called just before a branch observer is removed. Should stop any
700
808
  observing and invalidate any child observers.
701
809
  */
702
- destroy: function() {
810
+ destroy: function () {
703
811
  this.invalidateBranchObserversAt(0);
704
- this._objectAtCache = null ;
705
- this._notifyParent = NO ; // parent doesn't care anymore
812
+ this._objectAtCache = null;
813
+ this._notifyParent = NO; // parent doesn't care anymore
706
814
 
707
- // cleanup observing
708
- var item = this.get('item');
709
- if (item) item.removeObserver('*', this, this._itemPropertyDidChange);
815
+ // Cleanup the observed item and delegate.
816
+ this._cleanUpCachedItem();
817
+ this._cleanUpCachedDelegate();
710
818
 
711
819
  var children = this._children,
712
820
  ro = this._childrenRangeObserver;
@@ -717,73 +825,107 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
717
825
  sc_super();
718
826
  },
719
827
 
720
- /**
721
- Called whenever a property changes on the item. Determines if either the
722
- children array or the disclosure state has changed and then notifies as
723
- necessary..
724
- */
725
- _itemPropertyDidChange: function(target, key) {
726
- var children = this.get('children'),
727
- state = this.get('disclosureState'),
728
- item = this.get('item'),
729
- next ;
828
+ /** @private */
829
+ _itemDidChange: function () {
830
+ var item = this.get('item'),
831
+ treeItemChildrenKey,
832
+ treeItemIsExpandedKey;
833
+
834
+ treeItemIsExpandedKey = this.get('treeItemIsExpandedKey');
835
+ treeItemChildrenKey = this.get('treeItemChildrenKey');
730
836
 
837
+ // Cleanup the previous observed item.
838
+ this._cleanUpCachedItem();
839
+
840
+ //@if(debug)
841
+ // Add some developer support to prevent broken behavior.
842
+ if (!item) { throw new Error("Developer Error: SC.TreeItemObserver: Item cannot be null and must be set on create."); }
843
+
844
+ if (item.hasObserverFor(treeItemIsExpandedKey)) {
845
+ SC.warn("Developer Warning: SC.TreeItemObserver: Item '%@' appears to already be assigned to a tree item observer. This will cause strange behavior working with the item.".fmt(item));
846
+ }
847
+ //@endif
848
+
849
+ item.addObserver(treeItemIsExpandedKey, this, this._itemIsExpandedDidChange);
850
+ item.addObserver(treeItemChildrenKey, this, this._itemChildrenDidChange);
851
+
852
+ // Fire the observer functions once to initialize.
731
853
  this.beginPropertyChanges();
854
+ this._itemIsExpandedDidChange();
855
+ this._itemChildrenDidChange();
856
+ this.endPropertyChanges();
857
+
858
+ // Track the item so that when it changes we can clean-up.
859
+ this._cachedItem = item;
860
+ }.observes('item'),
861
+
862
+ /** @private */
863
+ _itemIsExpandedDidChange: function () {
864
+ var state = this.get('disclosureState'),
865
+ item = this.get('item'),
866
+ next;
732
867
 
733
868
  next = this._computeDisclosureState(item);
734
- if (state !== next) this.set('disclosureState', next);
869
+ if (state !== next) { this.set('disclosureState', next); }
870
+ },
735
871
 
736
- next = this._computeChildren(item);
737
- if (children !== next) this.set('children', next);
872
+ /** @private */
873
+ _itemChildrenDidChange: function () {
874
+ var children = this.get('children'),
875
+ item = this.get('item'),
876
+ next;
738
877
 
739
- this.endPropertyChanges();
878
+ next = this._computeChildren(item);
879
+ if (children !== next) { this.set('children', next); }
740
880
  },
741
881
 
742
- /**
882
+ /** @private
743
883
  Called whenever the children or disclosure state changes. Begins or ends
744
884
  observing on the children array so that changes can propogate outward.
745
885
  */
746
- _childrenDidChange: function() {
886
+ _childrenDidChange: function () {
747
887
  var state = this.get('disclosureState'),
748
- cur = state === SC.BRANCH_OPEN ? this.get('children') : null,
749
- last = this._children,
750
- ro = this._childrenRangeObserver;
888
+ cur = state === SC.BRANCH_OPEN ? this.get('children') : null,
889
+ last = this._children,
890
+ ro = this._childrenRangeObserver;
751
891
 
752
892
  if (last === cur) return this; //nothing to do
893
+
753
894
  if (ro) last.removeRangeObserver(ro);
895
+
754
896
  if (cur) {
755
- this._childrenRangeObserver =
756
- cur.addRangeObserver(null, this, this._childrenRangeDidChange);
757
- } else this._childrenRangeObserver = null;
897
+ this._childrenRangeObserver = cur.addRangeObserver(null, this, this._childrenRangeDidChange);
898
+ } else {
899
+ this._childrenRangeObserver = null;
900
+ }
758
901
 
759
- this._children = cur ;
902
+ this._children = cur;
760
903
  this._childrenRangeDidChange(cur, null, '[]', null);
761
-
762
904
  }.observes("children", "disclosureState"),
763
905
 
764
- /**
906
+ /** @private
765
907
  Called anytime the actual content of the children has changed. If this
766
908
  changes the length property, then notifies the parent that the content
767
909
  might have changed.
768
910
  */
769
- _childrenRangeDidChange: function(array, objects, key, indexes) {
911
+ _childrenRangeDidChange: function (array, objects, key, indexes) {
770
912
  var children = this.get('children'),
771
- len = children ? children.get('length') : 0,
772
- min = indexes ? indexes.get('min') : 0,
773
- max = indexes ? indexes.get('max') : len,
774
- old = this._childrenLen || 0;
913
+ len = children ? children.get('length') : 0,
914
+ min = indexes ? indexes.get('min') : 0,
915
+ max = indexes ? indexes.get('max') : len,
916
+ old = this._childrenLen || 0;
775
917
 
776
918
  this._childrenLen = len; // save for future calls
777
- this.observerContentDidChange(min, max-min, len-old);
919
+ this.observerContentDidChange(min, max - min, len - old);
778
920
  },
779
921
 
780
- /**
922
+ /** @private
781
923
  Computes the current disclosure state of the item by asking the item or
782
924
  the delegate. If no pitem or index is passed, the parentItem and index
783
925
  will be used.
784
926
  */
785
- _computeDisclosureState: function(item, pitem, index) {
786
- var key, del;
927
+ _computeDisclosureState: function (item, pitem, index) {
928
+ var key;
787
929
 
788
930
  // no item - assume leaf node
789
931
  if (!item || !this._computeChildren(item)) return SC.LEAF_NODE;
@@ -796,22 +938,17 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
796
938
 
797
939
  // otherwise get treeItemDisclosureStateKey from delegate
798
940
  } else {
799
- key = this._treeItemIsExpandedKey ;
800
- if (!key) {
801
- del = this.get('delegate');
802
- key = del ? del.get('treeItemIsExpandedKey') : 'treeItemIsExpanded';
803
- this._treeItemIsExpandedKey = key ;
804
- }
941
+ key = this.get('treeItemIsExpandedKey');
805
942
  return item.get(key) ? SC.BRANCH_OPEN : SC.BRANCH_CLOSED;
806
943
  }
807
944
  },
808
945
 
809
- /**
946
+ /** @private
810
947
  Collapse the item at the specified index. This will either directly
811
948
  modify the property on the item or call the treeItemCollapse() method.
812
949
  */
813
- _collapse: function(item, pitem, index) {
814
- var key, del;
950
+ _collapse: function (item, pitem, index) {
951
+ var key;
815
952
 
816
953
  // no item - assume leaf node
817
954
  if (!item || !this._computeChildren(item)) return this;
@@ -824,24 +961,44 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
824
961
 
825
962
  // otherwise get treeItemDisclosureStateKey from delegate
826
963
  } else {
827
- key = this._treeItemIsExpandedKey ;
828
- if (!key) {
829
- del = this.get('delegate');
830
- key = del ? del.get('treeItemIsExpandedKey') : 'treeItemIsExpanded';
831
- this._treeItemIsExpandedKey = key ;
832
- }
964
+ key = this.get('treeItemIsExpandedKey');
833
965
  item.setIfChanged(key, NO);
834
966
  }
835
967
 
836
- return this ;
968
+ return this;
837
969
  },
838
970
 
839
- /**
971
+ /** @private Each time the delegate changes, observe it for changes to its keys. */
972
+ _delegateDidChange: function () {
973
+ var delegate = this.get('delegate');
974
+
975
+ // Clean up the previous observed delegate.
976
+ this._cleanUpCachedDelegate();
977
+
978
+ if (delegate) {
979
+ delegate.addObserver('treeItemChildrenKey', this, this.treeItemChildrenKeyDidChange);
980
+ delegate.addObserver('treeItemIsExpandedKey', this, this.treeItemIsExpandedKeyDidChange);
981
+ delegate.addObserver('treeItemIsGrouped', this, this.treeItemIsGroupedDidChange);
982
+
983
+ // Fire the observer functions once to initialize.
984
+ this.treeItemChildrenKeyDidChange();
985
+ this.treeItemIsExpandedKeyDidChange();
986
+ this.treeItemIsGroupedDidChange();
987
+ }
988
+
989
+ // Re-initialize the item to match the new delegate.
990
+ this._itemDidChange();
991
+
992
+ // Cache the previous delegate so we can clean up.
993
+ this._cachedDelegate = delegate;
994
+ }.observes('delegate'),
995
+
996
+ /** @private
840
997
  Expand the item at the specified index. This will either directly
841
998
  modify the property on the item or call the treeItemExpand() method.
842
999
  */
843
- _expand: function(item, pitem, index) {
844
- var key, del;
1000
+ _expand: function (item, pitem, index) {
1001
+ var key;
845
1002
 
846
1003
  // no item - assume leaf node
847
1004
  if (!item || !this._computeChildren(item)) return this;
@@ -854,62 +1011,74 @@ SC.TreeItemObserver = SC.Object.extend(SC.Array, SC.CollectionContent, {
854
1011
 
855
1012
  // otherwise get treeItemDisclosureStateKey from delegate
856
1013
  } else {
857
- key = this._treeItemIsExpandedKey ;
858
- if (!key) {
859
- del = this.get('delegate');
860
- key = del ? del.get('treeItemIsExpandedKey') : 'treeItemIsExpanded';
861
- this._treeItemIsExpandedKey = key ;
862
- }
1014
+ key = this.get('treeItemIsExpandedKey');
863
1015
  item.setIfChanged(key, YES);
864
1016
  }
865
1017
 
866
- return this ;
1018
+ return this;
867
1019
  },
868
1020
 
869
- /**
1021
+ /** @private
870
1022
  Computes the children for the passed item.
871
1023
  */
872
- _computeChildren: function(item) {
873
- var del, key;
874
-
875
- // no item - no children
876
- if (!item) return null;
877
-
878
- // item implement TreeItemContent - call directly
879
- else if (item.isTreeItemContent) return item.get('treeItemChildren');
880
-
881
- // otherwise get treeItemChildrenKey from delegate
882
- else {
883
- key = this._treeItemChildrenKey ;
884
- if (!key) {
885
- del = this.get('delegate');
886
- key = del ? del.get('treeItemChildrenKey') : 'treeItemChildren';
887
- this._treeItemChildrenKey = key ;
888
- }
1024
+ _computeChildren: function (item) {
1025
+ var key;
1026
+
1027
+ if (!item) { // no item - no children
1028
+ return null;
1029
+ } else if (item.isTreeItemContent) { // item implements TreeItemContent - call directly
1030
+ return item.get('treeItemChildren');
1031
+ } else { // otherwise get treeItemChildrenKey from delegate
1032
+ key = this.get('treeItemChildrenKey');
889
1033
  return item.get(key);
890
1034
  }
891
1035
  },
892
1036
 
893
- /**
1037
+ /** @private
894
1038
  Computes the length of the array by looking at children.
895
1039
  */
896
- _computeLength: function() {
1040
+ _computeLength: function () {
897
1041
  var ret = this.get('isHeaderVisible') ? 1 : 0,
898
1042
  state = this.get('disclosureState'),
899
1043
  children = this.get('children'),
900
- indexes ;
1044
+ indexes;
901
1045
 
902
1046
  // if disclosure is open, add children count + length of branch observers.
903
1047
  if ((state === SC.BRANCH_OPEN) && children) {
904
1048
  ret += children.get('length');
905
- if (indexes = this.get('branchIndexes')) {
906
- indexes.forEach(function(idx) {
1049
+
1050
+ indexes = this.get('branchIndexes');
1051
+ if (indexes) {
1052
+ indexes.forEach(function (idx) {
907
1053
  var observer = this.branchObserverAt(idx);
908
- ret += observer.get('length')-1;
1054
+ ret += observer.get('length') - 1;
909
1055
  }, this);
910
1056
  }
911
1057
  }
912
- return ret ;
1058
+ return ret;
1059
+ },
1060
+
1061
+ /** @private */
1062
+ treeItemChildrenKeyDidChange: function () {
1063
+ var del = this.get('delegate'),
1064
+ key;
1065
+
1066
+ key = del ? del.get('treeItemChildrenKey') : 'treeItemChildren';
1067
+ this.set('treeItemChildrenKey', key ? key : 'treeItemChildren');
1068
+ },
1069
+
1070
+ /** @private */
1071
+ treeItemIsExpandedKeyDidChange: function () {
1072
+ var del = this.get('delegate'),
1073
+ key;
1074
+
1075
+ key = del ? del.get('treeItemIsExpandedKey') : 'treeItemIsExpanded';
1076
+ this.set('treeItemIsExpandedKey', key ? key : 'treeItemIsExpanded');
1077
+ },
1078
+
1079
+ /** @private */
1080
+ treeItemIsGroupedDidChange: function () {
1081
+ this.notifyPropertyChange('branchIndexes');
913
1082
  }
914
1083
 
915
1084
  });