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
@@ -16,13 +16,3 @@ test("Static layout", function() {
16
16
 
17
17
  ok(view.$().is('.sc-static-layout'), "views with useStaticLayout get the sc-static-layout class");
18
18
  });
19
-
20
- test("Background color", function() {
21
- var view = SC.View.create({
22
- backgroundColor: "red"
23
- });
24
-
25
- view.createLayer();
26
-
27
- equals(view.get('layer').style.backgroundColor, "red", "backgroundColor sets the CSS background-color class");
28
- });
@@ -4,7 +4,7 @@
4
4
  // License: Licensed under MIT license (see license.js)
5
5
  // ==========================================================================
6
6
 
7
- /*global module test equals context ok same Q$ htmlbody */
7
+ /*global module, test, equals, same */
8
8
 
9
9
  // ..........................................................
10
10
  // viewDidResize()
@@ -45,8 +45,37 @@ test("parentViewDidResize should only be called when the parent's layout propert
45
45
  equals(callCount, 2, 'parentViewDidResize should invoke twice');
46
46
 
47
47
  // This is tricky, if the height increases, but the same size border is added, the effective height/width is unchanged.
48
- SC.run(function () { view.adjust({'height': 70, 'borderTop': 10 }); });
49
- equals(callCount, 2, 'parentViewDidResize should invoke twice');
48
+ /*
49
+ Testing for this type of change on every call to adjust isn't worth the computation cost. Essentially,
50
+ what we lose is that parentViewDidResize will get called still if a view happens to adjust its border and
51
+ size at the same time, such that its frame doesn't change, which has a very small chance of occurring and
52
+ isn't critical if it does occur.
53
+ */
54
+ // SC.run(function () { view.adjust({'height': 70, 'borderTop': 10 }); });
55
+ // equals(callCount, 2, 'parentViewDidResize should invoke twice');
56
+ });
57
+
58
+ /**
59
+ When a view's layout changes, _checkForResize determines whether the size has changed using a comparison of the previously
60
+ cached layout and the new (current) layout. If it seems that the view has resized, it calls `viewDidResize`. Previously
61
+ it would call viewDidResize and then update the _previousLayout cache afterward. This meant that any adjustments that
62
+ were triggered by viewDidResize (which would in turn call _checkForResize) would compare the new layout against the
63
+ previous previous layout, instead of just the previous layout.
64
+
65
+ Long story short, to ensure that _checkForResize is checking the current layout against the *last* layout, it's important
66
+ that the last layout, _previousLayout, is updated *before* continuing on.
67
+ */
68
+ test("SC.View.prototype._checkForResize() updates the _previousLayout cache before calling viewDidResize", function () {
69
+ var view1 = SC.View.create({
70
+ layout: { width: 200, height: 200 },
71
+ viewDidResize: function () {
72
+ ok(this._previousLayout !== originalPreviousLayout, "The previous layout should not be the same anymore.");
73
+ }
74
+ }),
75
+ originalPreviousLayout;
76
+
77
+ originalPreviousLayout = view1.get('layout');
78
+ SC.run(function () { view1.adjust({ width: 100 }); });
50
79
  });
51
80
 
52
81
  test("The view's frame should only notify changes when its layout changes if the effective size or position actually change.", function () {
@@ -62,25 +91,29 @@ test("The view's frame should only notify changes when its layout changes if the
62
91
  layout: { width: 200, height: 200 }
63
92
  });
64
93
 
65
- SC.run(function () { view2.set('layout', { height: 50, width: 50 }); });
94
+ // Because the view is created independently and then added to a parent, it's frame should change
95
+ // once when added to the parent.
66
96
  equals(view2.get('frameCallCount'), 1, 'frame should have notified changing once.');
67
97
 
98
+ SC.run(function () { view2.set('layout', { height: 50, width: 50 }); });
99
+ equals(view2.get('frameCallCount'), 2, 'frame should have notified changing twice.');
100
+
68
101
  SC.run(function () { view2.adjust('top', 0); });
69
- equals(view2.get('frameCallCount'), 2, 'frame should have notified changing once.');
102
+ equals(view2.get('frameCallCount'), 3, 'frame should have notified changing thrice.');
70
103
 
71
104
  SC.run(function () { view2.adjust('height', 100); });
72
- equals(view2.get('frameCallCount'), 3, 'frame should have notified changing twice.');
105
+ equals(view2.get('frameCallCount'), 4, 'frame should have notified changing four times.');
73
106
 
74
107
  // Tricky.
75
108
  SC.run(function () { view2.adjust({ 'height': 110, 'borderTop': 10, 'top': -10 }); });
76
- equals(view2.get('frameCallCount'), 4, 'frame should have notified changing twice.');
109
+ equals(view2.get('frameCallCount'), 5, 'frame should have notified changing five times.');
77
110
 
78
111
  SC.run(function () { view2.adjust('width', null); });
79
- equals(view2.get('frameCallCount'), 5, 'frame should have notified changing thrice.');
112
+ equals(view2.get('frameCallCount'), 6, 'frame should have notified changing six times.');
80
113
 
81
114
  // Tricky.
82
115
  SC.run(function () { view2.adjust('width', 200); });
83
- equals(view2.get('frameCallCount'), 6, 'frame should have notified changing thrice.');
116
+ equals(view2.get('frameCallCount'), 7, 'frame should have notified changing seven times.');
84
117
  });
85
118
 
86
119
  test("making sure that the frame value is correct inside viewDidResize()", function() {
@@ -141,51 +174,101 @@ test("When parentViewDidResize is called on a view, it should only notify on fra
141
174
  });
142
175
 
143
176
  // try with fixed layout
144
- view.set('layout', { top: 10, left: 10, height: 10, width: 10 });
177
+ SC.run(function () {
178
+ view.set('layout', { top: 10, left: 10, height: 10, width: 10 });
179
+ view.viewDidResize.reset(); view.frameCallCount = 0;
180
+ parentView.adjust({ width: 90, height: 90 });
181
+ });
182
+ view.viewDidResize.expect(0, "Should not notify view resize with fixed position and fixed size");
183
+ equals(view.frameCallCount, 0, 'Should not notify frame changed with fixed position and fixed size.');
184
+
185
+ // Try with flexible height
186
+ SC.run(function () {
187
+ view.set('layout', { top: 10, left: 10, bottom: 10, width: 10 });
188
+ // Adjust height.
189
+ view.viewDidResize.reset(); view.frameCallCount = 0;
190
+ parentView.adjust({ height: 80 });
191
+ });
192
+ view.viewDidResize.expect(1, "View with fixed width and flexible height SHOULD resize when parent's height is adjusted");
193
+ equals(view.frameCallCount, 1, "Adjusting parent's height SHOULD notify frame with fixed position, fixed width and flexible height");
194
+
195
+ // Adjust width.
145
196
  view.viewDidResize.reset(); view.frameCallCount = 0;
146
- parentView.adjust({ width: 90, height: 90 });
147
- view.viewDidResize.expect(0);
148
- equals(view.frameCallCount, 0, 'should not notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
149
197
 
150
- // try with flexible height
151
- view.set('layout', { top: 10, left: 10, bottom: 10, width: 10 });
198
+ SC.run(function () {
199
+ parentView.adjust({ width: 80 });
200
+ });
201
+ view.viewDidResize.expect(0, "View with fixed width and flexible height should NOT resize when parent's width is adjusted");
202
+ equals(view.frameCallCount, 0, "Adjusting parent's width should NOT notify frame with fixed position, fixed width and flexible height");
203
+
204
+ // Adjust both.
152
205
  view.viewDidResize.reset(); view.frameCallCount = 0;
153
- parentView.adjust({ width: 80, height: 80 });
154
- view.viewDidResize.expect(1);
155
- equals(view.frameCallCount, 1, 'should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
206
+
207
+ SC.run(function () {
208
+ parentView.adjust({ width: 90, height: 90 });
209
+ });
210
+ view.viewDidResize.expect(1, "View with fixed width and flexible height SHOULD resize when parent's height and width are adjusted");
211
+ equals(view.frameCallCount, 1, "Adjusting parent's height and width SHOULD notify frame with fixed position, fixed width and flexible height");
156
212
 
157
213
  // try with flexible width
158
- view.set('layout', { top: 10, left: 10, height: 10, right: 10 });
214
+ SC.run(function () {
215
+ view.set('layout', { top: 10, left: 10, height: 10, right: 10 });
216
+ // Adjust height.
217
+ view.viewDidResize.reset(); view.frameCallCount = 0;
218
+ parentView.adjust({ height: 80 });
219
+ });
220
+ view.viewDidResize.expect(0, "View with flexible width and fixed height should NOT resize when parent's height is adjusted");
221
+ equals(view.frameCallCount, 0, "Adjusting parent's height should NOT notify frame with fixed position, flexible width and fixed height");
222
+
223
+ // Adjust width.
224
+ view.viewDidResize.reset(); view.frameCallCount = 0;
225
+ SC.run(function () {
226
+ parentView.adjust({ width: 80 });
227
+ });
228
+ view.viewDidResize.expect(1, "View with flexible width and fixed height SHOULD resize when parent's width is adjusted");
229
+ equals(view.frameCallCount, 1, "Adjusting parent's width SHOULD notify frame with fixed position, flexible width and fixed height");
230
+
231
+ // Adjust both.
159
232
  view.viewDidResize.reset(); view.frameCallCount = 0;
160
- parentView.adjust({ width: 70, height: 70 });
161
- view.viewDidResize.expect(1);
162
- equals(view.frameCallCount, 1, 'should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
233
+ SC.run(function () {
234
+ parentView.adjust({ width: 90, height: 90 });
235
+ });
236
+ view.viewDidResize.expect(1, "View with flexible width and fixed height SHOULD resize when parent's height and width are adjusted");
237
+ equals(view.frameCallCount, 1, "Adjusting parent's height and width SHOULD notify frame with fixed position, flexible width and fixed height");
163
238
 
164
239
  // try with right align
165
- view.set('layout', { top: 10, right: 10, height: 10, width: 10 });
166
- view.viewDidResize.reset(); view.frameCallCount = 0;
167
- parentView.adjust({ width: 60, height: 60 });
240
+ SC.run(function () {
241
+ view.set('layout', { top: 10, right: 10, height: 10, width: 10 });
242
+ view.viewDidResize.reset(); view.frameCallCount = 0;
243
+ parentView.adjust({ width: 60, height: 60 });
244
+ });
168
245
  view.viewDidResize.expect(0);
169
246
  equals(view.frameCallCount, 1, 'right align: should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
170
247
 
171
248
  // try with bottom align
172
- view.set('layout', { left: 10, bottom: 10, height: 10, width: 10 });
173
- view.viewDidResize.reset(); view.frameCallCount = 0;
174
- parentView.adjust({ width: 50, height: 50 });
249
+ SC.run(function () {
250
+ view.set('layout', { left: 10, bottom: 10, height: 10, width: 10 });
251
+ view.viewDidResize.reset(); view.frameCallCount = 0;
252
+ parentView.adjust({ width: 50, height: 50 });
253
+ });
175
254
  view.viewDidResize.expect(0);
176
255
  equals(view.frameCallCount, 1, 'bottom align: should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
177
256
 
178
257
  // try with center horizontal align
179
- view.set('layout', { centerX: 10, top: 10, height: 10, width: 10 });
180
- view.viewDidResize.reset(); view.frameCallCount = 0;
181
- parentView.adjust({ width: 40, height: 40 });
258
+ SC.run(function () {
259
+ view.set('layout', { centerX: 10, top: 10, height: 10, width: 10 });
260
+ view.viewDidResize.reset(); view.frameCallCount = 0;
261
+ parentView.adjust({ width: 40, height: 40 });
262
+ });
182
263
  view.viewDidResize.expect(0);
183
264
  equals(view.frameCallCount, 1, 'centerX: should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
184
265
 
185
266
  // try with center vertical align
186
- view.set('layout', { left: 10, centerY: 10, height: 10, width: 10 });
187
- view.viewDidResize.reset(); view.frameCallCount = 0;
188
- parentView.adjust({ width: 30, height: 30 });
267
+ SC.run(function () {
268
+ view.set('layout', { left: 10, centerY: 10, height: 10, width: 10 });
269
+ view.viewDidResize.reset(); view.frameCallCount = 0;
270
+ parentView.adjust({ width: 30, height: 30 });
271
+ });
189
272
  view.viewDidResize.expect(0);
190
273
  equals(view.frameCallCount, 1, 'centerY: should notify frame changed when isFixedPosition: %@ and isFixedSize: %@'.fmt(view.get('isFixedPosition'), view.get('isFixedSize')));
191
274
  });
@@ -424,6 +424,27 @@ test("Test showing and hiding parentView updates child views.", function () {
424
424
  view.destroy();
425
425
  });
426
426
 
427
+ test("Test showing parentView with transitionShow", function () {
428
+ var parentView = SC.View.create({
429
+ isVisible: NO,
430
+ transitionShow: { run: function() {} }
431
+ });
432
+ var childView = SC.View.create();
433
+ childView._doAdopt(parentView);
434
+ parentView._doRender();
435
+ parentView._doAttach(document.body);
436
+
437
+ SC.run(function() { parentView.set('isVisible', YES) });
438
+
439
+ equals(parentView.viewState, SC.View.ATTACHED_SHOWING, "Upon being made visible, a view with a transition is in state");
440
+ equals(childView.viewState, SC.View.ATTACHED_SHOWN, "A visible view whose parent is ATTACHED_SHOWING is in state.");
441
+
442
+ parentView.destroy();
443
+ parentView = null;
444
+ childView.destroy();
445
+ childView = null;
446
+ });
447
+
427
448
  test("Test hiding with transitionHide", function () {
428
449
  var child = SC.View.create(),
429
450
  transitionHide = { run: function () {} },
@@ -454,6 +475,35 @@ test("Test hiding with transitionHide", function () {
454
475
  view.destroy();
455
476
  });
456
477
 
478
+ test("Adjusting unrelated layout property (not specified in transition's layoutProperties) during transition.", function() {
479
+ var transition = {
480
+ layoutProperties: ['opacity'],
481
+ run: function (view) {
482
+ view.adjust('opacity', 0);
483
+ view.invokeNext(view.didTransitionIn);
484
+ }
485
+ }
486
+ var view = SC.View.create({
487
+ transitionIn: transition,
488
+ layout: { height: 40 },
489
+ didTransitionIn: function() {
490
+ sc_super();
491
+ equals(this.getPath('layout.height'), 30, "height adjusted during an opacity transition is retained after the transition is complete");
492
+ start();
493
+ }
494
+ });
495
+
496
+ SC.run(function() {
497
+ view._doRender();
498
+ view._doAttach(document.body);
499
+ equals(view.getPath('layout.height'), 40, 'PRELIM: View height starts at 40');
500
+ equals(view.get('viewState'), SC.View.ATTACHED_BUILDING_IN, "PRELIM: View is building in");
501
+ view.adjust('height', 30);
502
+ stop(250);
503
+ });
504
+
505
+ });
506
+
457
507
  /** isVisible */
458
508
  var child, view;
459
509
  module("SC.View isVisible integration with shown and hidden state", {
@@ -598,10 +648,10 @@ test("Test hiding and showing a showing view in same run loop should not update
598
648
  // Hide the view using isVisible.
599
649
  SC.run(function () {
600
650
  equals(view.viewState, SC.CoreView.ATTACHED_SHOWING, "The view should be in the state");
601
- equals(child.viewState, SC.CoreView.ATTACHED_HIDDEN_BY_PARENT, "The child view should be in the state");
651
+ equals(child.viewState, SC.CoreView.ATTACHED_SHOWN, "The child view should be in the state");
602
652
 
603
653
  ok(view.get('isVisibleInWindow'), "isVisibleInWindow should be true");
604
- ok(!child.get('isVisibleInWindow'), "isVisibleInWindow of child should be false");
654
+ ok(child.get('isVisibleInWindow'), "isVisibleInWindow of child should be true");
605
655
 
606
656
  view.set('isVisible', false);
607
657
  equals(view.viewState, SC.CoreView.ATTACHED_HIDDEN, "The view should be in the state");
@@ -167,6 +167,16 @@ SC.CoreView.reopen(
167
167
  */
168
168
  childViews: SC.EMPTY_CHILD_VIEWS_ARRAY,
169
169
 
170
+ /**
171
+ Use this property to automatically mix in a collection of mixins into all
172
+ child views created by the view. This collection is applied during createChildView
173
+ @property
174
+
175
+ @type Array
176
+ @default null
177
+ */
178
+ autoMixins: null,
179
+
170
180
  // ..........................................................
171
181
  // LAYER SUPPORT
172
182
  //
@@ -251,7 +261,7 @@ SC.CoreView.reopen(
251
261
  @returns {DOMElement} the discovered layer
252
262
  */
253
263
  findLayerInParentLayer: function (parentLayer) {
254
- var id = "#" + this.get('layerId');
264
+ var id = "#" + this.get('layerId').escapeCssIdForSelector();
255
265
  return jQuery(id, parentLayer)[0] || jQuery(id)[0];
256
266
  },
257
267
 
@@ -908,6 +918,11 @@ SC.CoreView.reopen(
908
918
  // CORE DISPLAY METHODS
909
919
  //
910
920
 
921
+ /** @private
922
+ Caches the layerId to detect when it changes.
923
+ */
924
+ _lastLayerId: null,
925
+
911
926
  /** @private
912
927
  Setup a view, but do not finish waking it up.
913
928
 
@@ -918,18 +933,20 @@ SC.CoreView.reopen(
918
933
  dispatch
919
934
  */
920
935
  init: function () {
921
- var childViews;
936
+ var childViews, layerId;
922
937
 
923
938
  sc_super();
924
939
 
940
+ layerId = this._lastLayerId = this.get('layerId');
941
+
925
942
  // Register the view for event handling. This hash is used by
926
943
  // SC.RootResponder to dispatch incoming events.
927
944
  //@if (debug)
928
- if (SC.View.views[this.get('layerId')]) {
945
+ if (SC.View.views[layerId]) {
929
946
  throw new Error("Developer Error: A view with layerId, '%@', already exists. Each view must have a unique layerId.".fmt(this.get('layerId')));
930
947
  }
931
948
  //@endif
932
- SC.View.views[this.get('layerId')] = this;
949
+ SC.View.views[layerId] = this;
933
950
 
934
951
  // setup classNames
935
952
  this.classNames = this.get('classNames').slice();
@@ -961,8 +978,11 @@ SC.CoreView.reopen(
961
978
  },
962
979
 
963
980
  /**
964
- Frame describes the current bounding rect for your view. This is always
965
- measured from the top-left corner of the parent view.
981
+ Frame describes this view's current bounding rect, relative to its parent view. You
982
+ can use this, for example, to reliably access a width for a view whose layout is
983
+ defined with left and right. (Note that width and height values are calculated in
984
+ the parent view's frame of reference as well, which has consequences for scaled
985
+ views.)
966
986
 
967
987
  @type Rect
968
988
  @test in layoutStyle
@@ -993,9 +1013,12 @@ SC.CoreView.reopen(
993
1013
  /*
994
1014
  TODO Can probably have some better width/height values - CC
995
1015
  FIXME This will probably not work right with borders - PW
1016
+ FIXME This assumes and reports a scale of 1 - DCP
996
1017
  */
997
- f.width = layer.offsetWidth;
998
- f.height = layer.offsetHeight;
1018
+ f.width = f.originalWidth = layer.offsetWidth;
1019
+ f.height = f.originalHeight = layer.offsetHeight;
1020
+ f.scale = 1;
1021
+ f.transformOriginX = f.transformOriginY = 0.5;
999
1022
  return f;
1000
1023
  }
1001
1024
 
@@ -1036,9 +1059,9 @@ SC.CoreView.reopen(
1036
1059
 
1037
1060
  /**
1038
1061
  The clipping frame returns the visible portion of the view, taking into
1039
- account the clippingFrame of the parent view. Keep in mind that
1040
- the clippingFrame is in the context of the view itself, not it's parent
1041
- view.
1062
+ account the clippingFrame of the parent view. (Note that, in contrast
1063
+ to `frame`, `clippingFrame` is in the context of the view itself, not
1064
+ its parent view.)
1042
1065
 
1043
1066
  Normally this will be calculated based on the intersection of your own
1044
1067
  clippingFrame and your parentView's clippingFrame.
@@ -1046,20 +1069,48 @@ SC.CoreView.reopen(
1046
1069
  @type Rect
1047
1070
  */
1048
1071
  clippingFrame: function () {
1049
- var f = this.get('frame'),
1050
- ret = f,
1051
- pv, cf;
1072
+ var f = this.get('frame');
1052
1073
 
1074
+ // FAST PATH: No frame, no clipping frame.
1053
1075
  if (!f) return null;
1054
- pv = this.get('parentView');
1055
- if (pv) {
1056
- cf = pv.get('clippingFrame');
1057
- if (!cf) return { x: 0, y: 0, width: f.width, height: f.height};
1058
- ret = SC.intersectRects(cf, f);
1059
- }
1076
+
1077
+ var scale = (f.scale == null) ? 1 : f.scale,
1078
+ scaleIsArray = NO,
1079
+ pv = this.get('parentView'),
1080
+ pcf = pv ? pv.get('clippingFrame') : null,
1081
+ sf, spcf, originX, originY, deltaH, deltaW,
1082
+ ret;
1083
+
1084
+ // FAST PATH: No parent clipping frame, no change. (The origin and scale are reset from parent view's
1085
+ // context to our own.)
1086
+ if (!pcf) return { x: 0, y: 0, width: f.width / scale, height: f.height / scale};
1087
+
1088
+ // Get the intersection.
1089
+ ret = SC.intersectRects(pcf, f);
1090
+
1091
+ // Reorient the top-left from the parent's origin to ours.
1060
1092
  ret.x -= f.x;
1061
1093
  ret.y -= f.y;
1062
1094
 
1095
+ // If we're scaled, we have to scale the intersected rectangle from our parent's frame of reference
1096
+ // to our own.
1097
+ if (scale !== 1) {
1098
+ var scaleX, scaleY;
1099
+ // We're scaling from parent space into our space, so the scale is reversed. (Layout scale may be an array.)
1100
+ if (SC.typeOf(scale) === SC.T_ARRAY) {
1101
+ scaleX = 1 / scale[0];
1102
+ scaleY = 1 / scale[1];
1103
+ } else {
1104
+ scaleX = scaleY = 1 / scale;
1105
+ }
1106
+
1107
+ // Convert the entire rectangle into our scale.
1108
+ ret.x *= scaleX;
1109
+ ret.width *= scaleX;
1110
+ ret.y *= scaleY;
1111
+ ret.height *= scaleY;
1112
+ }
1113
+
1063
1114
  return ret;
1064
1115
  }.property('parentView', 'frame').cacheable(),
1065
1116
 
@@ -1363,31 +1414,39 @@ SC.CoreView.reopen(
1363
1414
  @test in createChildViews
1364
1415
  */
1365
1416
  createChildView: function (view, attrs) {
1366
- if (!view.isClass) {
1367
- attrs = view;
1368
- } else {
1417
+ // Create the view if it is a class.
1418
+ if (view.isClass) {
1369
1419
  // attrs should always exist...
1370
1420
  if (!attrs) { attrs = {}; }
1421
+
1371
1422
  // clone the hash that was given so we do not pollute it if it's being reused
1372
1423
  else { attrs = SC.clone(attrs); }
1373
- }
1374
1424
 
1375
- attrs.owner = attrs.parentView = this;
1425
+ // Assign the owner, parentView & page to ourself.
1426
+ attrs.owner = attrs.parentView = this;
1427
+ if (!attrs.page) { attrs.page = this.page; }
1376
1428
 
1377
- // We need to set isVisibleInWindow before the init method is called on the view
1378
- // The prototype check is a bit hackish and should be revisited - PDW
1379
- // if (view.isClass && view.prototype.hasVisibility) {
1380
- // attrs.isVisibleInWindow = this.get('isVisibleInWindow');
1381
- // }
1382
-
1383
- if (!attrs.page) { attrs.page = this.page; }
1384
-
1385
- // Now add this to the attributes and create.
1386
- if (view.isClass) {
1387
1429
  // Track that we created this view.
1388
1430
  attrs.createdByParent = true;
1389
1431
 
1390
- view = view.create(attrs);
1432
+ // Insert the autoMixins if defined
1433
+ var applyMixins = this.autoMixins;
1434
+ if (!!applyMixins) {
1435
+ applyMixins = SC.clone(applyMixins);
1436
+ applyMixins.push(attrs);
1437
+ view = view.create.apply(view, applyMixins);
1438
+ } else {
1439
+ view = view.create(attrs);
1440
+ }
1441
+ // Assign the parentView & owner if the view is an instance.
1442
+ // TODO: This should not be accepting view instances, for the purpose of lazy code elsewhere in the framework.
1443
+ // We should ensure users of `createChildViews` are using appendChild and other manipulation methods.
1444
+ } else {
1445
+ view.set('parentView', this);
1446
+ view.set('owner', this);
1447
+ view._adopted();
1448
+
1449
+ if (!view.get('page')) { view.set('page', this.page); }
1391
1450
  }
1392
1451
 
1393
1452
  return view;
@@ -1626,8 +1685,18 @@ SC.CoreView.reopen(
1626
1685
  @default null
1627
1686
  @since Version 1.10
1628
1687
  */
1629
- transitionHideOptions: null
1688
+ transitionHideOptions: null,
1689
+
1690
+ // ............................................
1691
+ // Patches
1692
+ //
1630
1693
 
1694
+ /** @private
1695
+ Override this method to apply design modes to this view and
1696
+ its children.
1697
+ @see SC.View
1698
+ */
1699
+ updateDesignMode: function (lastDesignMode, designMode) {}
1631
1700
  });
1632
1701
 
1633
1702
  SC.CoreView.mixin(
@@ -1862,10 +1931,43 @@ SC.CoreView.unload = function () {
1862
1931
 
1863
1932
  Base class for managing a view. Views provide two functions:
1864
1933
 
1865
- 1. They translate state and events into drawing instructions for the
1866
- web browser and
1867
- 2. They act as first responders for incoming keyboard, mouse, and
1868
- touch events.
1934
+ 1. They display – translating your application's state into drawing
1935
+ instructions for the web browser, and
1936
+ 2. They react – acting as responders for incoming keyboard, mouse, and touch
1937
+ events.
1938
+
1939
+ View Basics
1940
+ ====
1941
+
1942
+ SproutCore's view layer is made up of a tree of SC.View instances, nested
1943
+ using the `childViews` list – usually an array of local property names. You
1944
+ position each view by specifying a set of layout keys, like 'left', 'right',
1945
+ 'width', or 'centerX', in a hash on the layout property. (See the 'layout'
1946
+ documentation for more.)
1947
+
1948
+ Other than positioning, SproutCore relies on CSS for all your styling needs.
1949
+ Set an array of CSS classes on the `classNames` property, then style them with
1950
+ standard CSS. (SproutCore's build tools come with Sass support built in, too.)
1951
+ If you have a class that you want automatically added and removed as another
1952
+ property changes, take a look at `classNameBindings`.
1953
+
1954
+ Different view classes do different things. The so-called "Big Five" view
1955
+ classes are SC.LabelView, for displaying (optionally editable, optionally
1956
+ localizable) text; SC.ButtonView, for the user to poke; SC.CollectionView
1957
+ (most often as its subclass SC.ListView) for displaying an array of content;
1958
+ SC.ContainerView, for easily swapping child views in and out; and SC.ScrollView,
1959
+ for containing larger views and allowing them to be scrolled.
1960
+
1961
+ All views live in panes (subclasses of SC.Pane, like SC.MainPane and SC.PanelPane),
1962
+ which are parentless views that know how to append themselves directly to the document.
1963
+ Panes also serve as routers for events, like mouse, touch and keyboard events, that are
1964
+ bound for their views. (See "View Events" below for more.)
1965
+
1966
+ For best performance, you should define your view and pane instances with `extend()`
1967
+ inside an SC.Page instance, getting them as needed with `get`. As its name suggests,
1968
+ SC.Page's only job is to instantiate views once when first requested, deferring the
1969
+ expensive view creation process until each view is needed. Correctly using SC.Page is
1970
+ considered an important best practice for high-performance applications.
1869
1971
 
1870
1972
  View Initialization
1871
1973
  ====
@@ -1903,6 +2005,199 @@ SC.CoreView.unload = function () {
1903
2005
  before its layer is removed from the DOM. You can use this to reverse any
1904
2006
  setup that is performed in `didAppendToDocument`.
1905
2007
 
2008
+ View Events
2009
+ ====
2010
+
2011
+ One of SproutCore's optimizations is application-wide event delegation: SproutCore
2012
+ handles and standardizes events for you before sending them through your view layer's
2013
+ chain of responding views. You should never need to attach event listeners to elements;
2014
+ instead, just implement methods like `click`, `doubleClick`, `mouseEntered` and
2015
+ `dataDragHover` on your views.
2016
+
2017
+ Note that events generally bubble up an event's responder chain, which is made up of the
2018
+ targeted view (i.e. the view whose DOM element received the event), and its chain of
2019
+ parentViews up to its pane. (In certain rare cases, you may wish to manipulate the responder
2020
+ chain to bypass certain views; you can do so by overriding a view's `nextResponder` property.)
2021
+
2022
+ Simple mouse click events
2023
+ ----
2024
+ In many situations, all you need are clicks - in which case, just implement `click` or
2025
+ `doubleClick` on your views. Note that these events bubble up the responder chain until
2026
+ they encounter a view which implements the event method. For example, if a view and its
2027
+ parent both implement `click`, the parent will not be notified of the click. (If you want a
2028
+ view to handle the event AND allow the event to keep bubbling to its parent views, no
2029
+ problem: just be sure to return NO from the event method.)
2030
+ - `click` -- Called on a view when the user clicks the mouse on a view. (Note that the view
2031
+ on which the user lifts the mouse button will receive the `click` event, regardless of
2032
+ whether the user depressed the mouse button elsewhere. If you need finer-grained control
2033
+ than this, see "Granular mouse click events" below.)
2034
+ - `doubleClick` -- Called on a view when a user has double-clicked it. Double-clicks are
2035
+ triggered when two clicks of the same button happen within eight pixels and 250ms of each
2036
+ other. (If you need finer-grained control than this, see "Granular mouse click events"
2037
+ below.) The same view may receive both `click` and `doubleClick` events.
2038
+
2039
+ Note that defining application behavior directly in event handlers is usually a bad idea; you
2040
+ should follow the target/action pattern when possible. See SC.ButtonView and SC.ActionSupport.
2041
+ Also note that you will not need to implement event handling yourself on most built-in
2042
+ SproutCore controls.
2043
+
2044
+ Note that `click` and `doubleClick` event handlers on your views will not be notified of touch
2045
+ events; you must also implement touch handling. See "Touch events" below.
2046
+
2047
+ Mouse movement events
2048
+ ----
2049
+ SproutCore normalizes (and brings sanity to) mouse movement events by calculating when
2050
+ the mouse has entered and exited views, and sending the correct event to each view in
2051
+ the responder chain. For example, if a mouse moves within a parent view but crosses from
2052
+ one child view to another, the parent view will receive a mouseMoved event while the child
2053
+ views will receive mouseEntered and mouseExit events.
2054
+
2055
+ In contrast to mouse click events, mouse movement events are called on the entire responder
2056
+ chain regardless of how you handle it along the way - a view and its parent, both implementing
2057
+ event methods, will both be notified of the event.
2058
+
2059
+ - `mouseEntered` -- Called when the cursor first enters a view. Called on every view that has
2060
+ just entered the responder chain.
2061
+ - `mouseMoved` -- Called when the cursor moves over a view.
2062
+ - `mouseExited` -- Called when the cursor leaves a view. Called on every view that has
2063
+ just exited the responder chain.
2064
+
2065
+ Granular mouse click events
2066
+ ----
2067
+ If you need more granular handling of mouse click events than what is provided by `click`
2068
+ and `doubleClick`, you can handle their atomic components `mouseDown`, `mouseDrag` and
2069
+ `mouseUp`. Like the compound events, these events bubble up their responder chain towards
2070
+ the pane until they find an event which implements the event handler method. (Again, to
2071
+ handle an event but allow it to continue bubbling, just return NO.)
2072
+
2073
+ It bears emphasizing that `mouseDrag` and `mouseUp` events for a given mouse click sequence
2074
+ are *only ever called* on the view which successfully responded to the `mouseDown` event. This
2075
+ gives `mouseDown` control over which view responder-chain is allowed to handle the entire
2076
+ click sequence.
2077
+
2078
+ (Note that because of how events bubble up the responder chain, if a child view implements
2079
+ `mouseDown` but not `mouseDrag` or `mouseUp`, those events will bubble to its parent. This
2080
+ may cause unexpected behavior if similar events are handled at different parts of your view
2081
+ hierarchy, for example if you handle `mouseDown` in a child and a parent, and only handle
2082
+ `mouseUp` in the parent.)
2083
+
2084
+ - `mouseDown` -- Called on the target view and responder chain when the user depresses a
2085
+ button. A view must implement `mouseDown` (and not return NO) in order to be notified
2086
+ of the subsequent drag and up events.
2087
+ - `mouseDrag` -- Called on the target view if it handled mouseDown. A view must implement
2088
+ mouseDown (and not return NO) in order to receive mouseDrag; only the view which handled a
2089
+ given click sequence's mouseDown will receive `mouseDrag` events (and will continue to
2090
+ receive them even if the user drags the mouse off of it).
2091
+ - `mouseUp` -- Called on the target view when the user lifts a mouse button. A view must
2092
+ implement mouseDown (and not return NO) in order to receive mouseUp.
2093
+
2094
+ SproutCore implements a higher-level API for handling in-application dragging and dropping.
2095
+ See `SC.Drag`, `SC.DragSource`, `SC.DragDataSource`, and `SC.DropTarget` for more.
2096
+
2097
+ Data-drag events
2098
+ ----
2099
+ Browsers implement a parallel system of events for drags which bring something with them: for
2100
+ example, dragging text, an image, a URL or (in modern browsers) a file. They behave differently,
2101
+ and require different responses from the developer, so SproutCore implements them as a separate
2102
+ set of "data drag" events. These behave much like mouse events; the data-drag movement events
2103
+ bubble indiscriminately, and the data-drag drop event bubbles until it finds a view which handles
2104
+ it (and doesn't return NO).
2105
+
2106
+ By default, SproutCore cancels the default behavior of any data drag event which carries URLs
2107
+ or files, as by default these would quit the app and open the dragged item in the browser. If
2108
+ you wish to implement data drag-and-drop support in your application, you should set the event's
2109
+ dataTransfer.dropEffect property to 'copy' in a `dataDragHovered` event handler.
2110
+
2111
+ - `dataDragEntered` -- Triggered when a data drag enters a view. You can use this handler to
2112
+ update the view to visually signal that a drop is possible.
2113
+ - `dataDragHovered` -- Triggered when the browser sends a dragover event to a view. If you want
2114
+ to support dropping data on your view, you must set the event's `dataTransfer.dropEffect`
2115
+ property to 'copy' (or related). Note that `dataDragHovered` is given access to dragenter
2116
+ events as well, so you do not need to worry about this in your `dataDragEntered` methods.
2117
+ - `dataDragDropped` -- If the last hover event's dropEffect was set correctly, this event will
2118
+ give the view access to the data that was dropped. This event bubbles up the responder chain
2119
+ until it finds a view which handles it (and doesn't return NO).
2120
+ - `dataDragExited` -- Triggered when a data drag leaves a view. You can use this handler to
2121
+ update the view to remove the visual drop signal. This event is fired regardless of whether
2122
+ a drop occurred.
2123
+
2124
+
2125
+ Touch events
2126
+ ----
2127
+ Touch events can be much more complicated than mouse events: multiple touches may be in flight
2128
+ at once, and views may wish to handle average touches rather than individual touches.
2129
+
2130
+ Basic support for touch events is required to make your application touch-aware. (You will not
2131
+ need to implement touch support for built-in SproutCore controls, which are touch-aware out of
2132
+ the box.) The basic touch event handlers are `touchStart` and `touchEnd`; if all you need is
2133
+ basic support then you can simply proxy these events to their mouse counterparts.
2134
+
2135
+ The counterpart to `mouseDragged` is `touchesDragged`, which is passed two arguments: a special
2136
+ multitouch event object which includes methods for accessing information about all currently
2137
+ in-flight touches, and a list of touches active on the current view. If you need to check the
2138
+ status of touches currently being handled by other views, the special multitouch event object
2139
+ exposes the `touchesForView` method. It also exposes the convenient `averagedTouchesForView`
2140
+ method, which gives you easy access to an average touch center and distance. Unlike `mouseDragged`,
2141
+ `touchesDragged` does not bubble, being only called on views whic handled `touchStart` for touches
2142
+ which have moved.
2143
+
2144
+ To facilitate intuitive behavior in situations like scroll views with touch handlers inside them,
2145
+ you may capture a touch from part way up its responder chain before it has a chance to bubble
2146
+ up from the target. To capture a touch, expose a method on your view called `captureTouch` which
2147
+ accepts the touch as its only argument, and which returns YES if you would like to capture that
2148
+ touch. A captured touch will not bubble as normal, instead bubbling up from the capture point. Any
2149
+ child views will not have the opportunity to handle the captured event unless you implement custom
2150
+ responder swapping yourself.
2151
+
2152
+ Touch events bubble differently than mouse and keyboard events. The initial reverse `captureTouch`
2153
+ bubbling is followed by regular `touchStart` bubbling; however, once this process has found a view
2154
+ that's willing to respond to the touch, further events are applied only to that view. If a view
2155
+ wishes to assign respondership for a touch to a different view, it can call one of several methods
2156
+ on the touch object. For a fuller discussion of touch events, touch responder behavior, and the touch
2157
+ object itself, see the documentation for SC.Touch.
2158
+
2159
+ Keyboard events
2160
+ ----
2161
+ The basic key events are `keyDown` and `keyUp`. In order to be notified of keyboard events,
2162
+ a view must set `acceptsFirstResponder` to `YES`, and be on an active pane with
2163
+ `acceptsKeyPane` set to YES. (You may also need to call `becomeFirstResponder` on your view
2164
+ on a `mouseDown`, for example, to focus it. You can verify whether your view has successfully
2165
+ received first responder status by checking `isFirstResponder`.)
2166
+
2167
+ Note that key events bubble similarly to mouse click events: they will stop bubbling if they
2168
+ encounter a view which handles the event and does not return NO.
2169
+
2170
+ SproutCore implements a set of very convenient, higher-level keyboard events for action keys
2171
+ such as *tab*, *enter*, and the arrow keys. These are not triggered automatically, but you
2172
+ can gain access to them by proxying the keyboard event of your choice to `interpretKeyEvent`.
2173
+ For example:
2174
+
2175
+ // Proxy the keyboard event to SC's built-in interpreter.
2176
+ keyDown: function(evt) {
2177
+ return this.interpretKeyEvents(evt);
2178
+ },
2179
+ // The interpreter will trigger the view's `cancel` event if the escape key was pressed.
2180
+ cancel: function(evt) {
2181
+ console.log('The escape key was pressed.'');
2182
+ }
2183
+
2184
+ This will analyze the key press and fire an appropriate event. These events include, but are
2185
+ not limited to:
2186
+
2187
+ - `moveUp`, `moveDown`, `moveLeft`, `moveRight` -- The arrow keys
2188
+ - `insertNewline` -- The enter key (note the lower-case 'line')
2189
+ - `cancel` -- The escape key
2190
+ - `insertTab` -- The tab key
2191
+ - `insertBacktab` -- Shift + the tab key
2192
+ - `moveToBeginningOfDocument` -- The *home* key
2193
+ - `moveToEndOfDocument` -- The *end* key
2194
+ - `pageUp` and `pageDown`
2195
+ - `moveLeftAndModifySelection` -- Shift + the left arrow
2196
+ - `selectAll` -- Ctrl + A / Cmd + A
2197
+
2198
+ For a full list of available methods, see the key values on SC.BASE_KEY_BINDINGS and
2199
+ SC.MODIFIED_KEY_BINDINGS.
2200
+
1906
2201
  @extends SC.Responder
1907
2202
  @extends SC.DelegateSupport
1908
2203
  @since SproutCore 1.0
@@ -1911,7 +2206,326 @@ SC.CoreView.unload = function () {
1911
2206
  SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
1912
2207
  classNames: ['sc-view'],
1913
2208
 
1914
- displayProperties: []
2209
+ displayProperties: [],
2210
+
2211
+ /** @private Enhance. */
2212
+ _executeQueuedUpdates: function () {
2213
+ sc_super();
2214
+
2215
+ // Enabled
2216
+ // Update the layout style of the layer if necessary.
2217
+ if (this._enabledStyleNeedsUpdate) {
2218
+ this._doUpdateEnabledStyle();
2219
+ }
2220
+
2221
+ // Layout
2222
+ // Update the layout style of the layer if necessary.
2223
+ if (this._layoutStyleNeedsUpdate) {
2224
+ this._doUpdateLayoutStyle();
2225
+ }
2226
+ },
2227
+
2228
+ /** Apply the attributes to the context. */
2229
+ applyAttributesToContext: function (context) {
2230
+ // Cursor
2231
+ var cursor = this.get('cursor');
2232
+ if (cursor) { context.addClass(cursor.get('className')); }
2233
+
2234
+ // Enabled
2235
+ if (!this.get('isEnabled')) {
2236
+ context.addClass('disabled');
2237
+ context.setAttr('aria-disabled', 'true');
2238
+ }
2239
+
2240
+ // Layout
2241
+ // Have to pass 'true' for second argument for legacy.
2242
+ this.renderLayout(context, true);
2243
+
2244
+ if (this.get('useStaticLayout')) { context.addClass('sc-static-layout'); }
2245
+
2246
+ // Background color defaults to null; for performance reasons we should ignore it
2247
+ // unless it's ever been non-null.
2248
+ var backgroundColor = this.get('backgroundColor');
2249
+ if (!SC.none(backgroundColor) || this._scv_hasBackgroundColor) {
2250
+ this._scv_hasBackgroundColor = YES;
2251
+ if (backgroundColor) context.setStyle('backgroundColor', backgroundColor);
2252
+ else context.removeStyle('backgroundColor');
2253
+ }
2254
+
2255
+ // Theming
2256
+ var theme = this.get('theme');
2257
+ var themeClassNames = theme.classNames, idx, len = themeClassNames.length;
2258
+
2259
+ for (idx = 0; idx < len; idx++) {
2260
+ context.addClass(themeClassNames[idx]);
2261
+ }
2262
+
2263
+ sc_super();
2264
+
2265
+ var renderDelegate = this.get('renderDelegate');
2266
+ if (renderDelegate && renderDelegate.className) {
2267
+ context.addClass(renderDelegate.className);
2268
+ }
2269
+
2270
+ // @if(debug)
2271
+ if (renderDelegate && renderDelegate.name) {
2272
+ SC.Logger.error("Render delegates now use 'className' instead of 'name'.");
2273
+ SC.Logger.error("Name '%@' will be ignored.", renderDelegate.name);
2274
+ }
2275
+ // @endif
2276
+ },
2277
+
2278
+ /**
2279
+ Computes what the frame of this view would be if the parent were resized
2280
+ to the passed dimensions. You can use this method to project the size of
2281
+ a frame based on the resize behavior of the parent.
2282
+
2283
+ This method is used especially by the scroll view to automatically
2284
+ calculate when scrollviews should be visible.
2285
+
2286
+ Passing null for the parent dimensions will use the actual current
2287
+ parent dimensions. This is the same method used to calculate the current
2288
+ frame when it changes.
2289
+
2290
+ @param {Rect} pdim the projected parent dimensions (optional)
2291
+ @returns {Rect} the computed frame
2292
+ */
2293
+ computeFrameWithParentFrame: function (pdim) {
2294
+ // Layout.
2295
+ var f, layout = this.get('layout');
2296
+
2297
+ // We can't predict the frame for static layout, so just return the view's
2298
+ // current frame (see original computeFrameWithParentFrame in views/view.js)
2299
+ if (this.get('useStaticLayout')) {
2300
+ f = sc_super();
2301
+ f = f ? this._adjustForBorder(f, layout) : null;
2302
+ f = f ? this._adjustForScale(f, layout) : null;
2303
+ return f;
2304
+ }
2305
+
2306
+ f = {};
2307
+
2308
+ var error, layer, AUTO = SC.LAYOUT_AUTO,
2309
+ pv = this.get('parentView'),
2310
+ scale, oX, oY, // Used with the special case ScrollView handling below.
2311
+ dH, dW, //shortHand for parentDimensions
2312
+ lR = layout.right,
2313
+ lL = layout.left,
2314
+ lT = layout.top,
2315
+ lB = layout.bottom,
2316
+ lW = layout.width,
2317
+ lH = layout.height,
2318
+ lcX = layout.centerX,
2319
+ lcY = layout.centerY;
2320
+
2321
+ if (lW === AUTO) {
2322
+ error = SC.Error.desc(("%@.layout() cannot use width:auto if " +
2323
+ "staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2324
+ SC.Logger.error(error.toString());
2325
+ throw error;
2326
+ }
2327
+
2328
+ if (lH === AUTO) {
2329
+ error = SC.Error.desc(("%@.layout() cannot use height:auto if " +
2330
+ "staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2331
+ SC.Logger.error(error.toString());
2332
+ throw error;
2333
+ }
2334
+
2335
+ if (!pdim) { pdim = this.computeParentDimensions(layout); }
2336
+ dH = pdim.height;
2337
+ dW = pdim.width;
2338
+
2339
+ // handle left aligned and left/right
2340
+ if (!SC.none(lL)) {
2341
+ if (SC.isPercentage(lL)) {
2342
+ f.x = dW * lL;
2343
+ } else {
2344
+ f.x = lL;
2345
+ }
2346
+ if (lW !== undefined) {
2347
+ if (lW === AUTO) { f.width = AUTO; }
2348
+ else if (SC.isPercentage(lW)) { f.width = dW * lW; }
2349
+ else { f.width = lW; }
2350
+ } else { // better have lR!
2351
+ f.width = dW - f.x;
2352
+ if (lR && SC.isPercentage(lR)) { f.width = f.width - (lR * dW); }
2353
+ else { f.width = f.width - (lR || 0); }
2354
+ }
2355
+ // handle right aligned
2356
+ } else if (!SC.none(lR)) {
2357
+ if (SC.none(lW)) {
2358
+ if (SC.isPercentage(lR)) {
2359
+ f.width = dW - (dW * lR);
2360
+ }
2361
+ else f.width = dW - lR;
2362
+ f.x = 0;
2363
+ } else {
2364
+ if (lW === AUTO) f.width = AUTO;
2365
+ else if (SC.isPercentage(lW)) f.width = dW * lW;
2366
+ else f.width = (lW || 0);
2367
+ if (SC.isPercentage(lW)) f.x = dW - (lR * dW) - f.width;
2368
+ else f.x = dW - lR - f.width;
2369
+ }
2370
+
2371
+ // handle centered
2372
+ } else if (!SC.none(lcX)) {
2373
+ if (lW === AUTO) f.width = AUTO;
2374
+ else if (SC.isPercentage(lW)) f.width = lW * dW;
2375
+ else f.width = (lW || 0);
2376
+ if (SC.isPercentage(lcX)) f.x = (dW - f.width) / 2 + (lcX * dW);
2377
+ else f.x = (dW - f.width) / 2 + lcX;
2378
+ } else {
2379
+ f.x = 0; // fallback
2380
+ if (SC.none(lW)) {
2381
+ f.width = dW;
2382
+ } else {
2383
+ if (lW === AUTO) f.width = AUTO;
2384
+ if (SC.isPercentage(lW)) f.width = lW * dW;
2385
+ else f.width = (lW || 0);
2386
+ }
2387
+ }
2388
+
2389
+ // handle top aligned and top/bottom
2390
+ if (!SC.none(lT)) {
2391
+ if (SC.isPercentage(lT)) f.y = lT * dH;
2392
+ else f.y = lT;
2393
+ if (lH !== undefined) {
2394
+ if (lH === AUTO) f.height = AUTO;
2395
+ else if (SC.isPercentage(lH)) f.height = lH * dH;
2396
+ else f.height = lH;
2397
+ } else { // better have lB!
2398
+ if (lB && SC.isPercentage(lB)) f.height = dH - f.y - (lB * dH);
2399
+ else f.height = dH - f.y - (lB || 0);
2400
+ }
2401
+
2402
+ // handle bottom aligned
2403
+ } else if (!SC.none(lB)) {
2404
+ if (SC.none(lH)) {
2405
+ if (SC.isPercentage(lB)) f.height = dH - (lB * dH);
2406
+ else f.height = dH - lB;
2407
+ f.y = 0;
2408
+ } else {
2409
+ if (lH === AUTO) f.height = AUTO;
2410
+ if (lH && SC.isPercentage(lH)) f.height = lH * dH;
2411
+ else f.height = (lH || 0);
2412
+ if (SC.isPercentage(lB)) f.y = dH - (lB * dH) - f.height;
2413
+ else f.y = dH - lB - f.height;
2414
+ }
2415
+
2416
+ // handle centered
2417
+ } else if (!SC.none(lcY)) {
2418
+ if (lH === AUTO) f.height = AUTO;
2419
+ if (lH && SC.isPercentage(lH)) f.height = lH * dH;
2420
+ else f.height = (lH || 0);
2421
+ if (SC.isPercentage(lcY)) f.y = (dH - f.height) / 2 + (lcY * dH);
2422
+ else f.y = (dH - f.height) / 2 + lcY;
2423
+
2424
+ // fallback
2425
+ } else {
2426
+ f.y = 0; // fallback
2427
+ if (SC.none(lH)) {
2428
+ f.height = dH;
2429
+ } else {
2430
+ if (lH === AUTO) f.height = AUTO;
2431
+ if (SC.isPercentage(lH)) f.height = lH * dH;
2432
+ else f.height = lH || 0;
2433
+ }
2434
+ }
2435
+
2436
+ f.x = Math.floor(f.x);
2437
+ f.y = Math.floor(f.y);
2438
+ if (f.height !== AUTO) f.height = Math.floor(f.height);
2439
+ if (f.width !== AUTO) f.width = Math.floor(f.width);
2440
+
2441
+ // if width or height were set to auto and we have a layer, try lookup
2442
+ if (f.height === AUTO || f.width === AUTO) {
2443
+ layer = this.get('layer');
2444
+ if (f.height === AUTO) f.height = layer ? layer.clientHeight : 0;
2445
+ if (f.width === AUTO) f.width = layer ? layer.clientWidth : 0;
2446
+ }
2447
+
2448
+ // Okay we have all our numbers. Let's adjust them for things.
2449
+
2450
+ // First, adjust for border.
2451
+ f = this._adjustForBorder(f, layout);
2452
+
2453
+ // Make sure the width/height fix their min/max (note the inlining of SC.none for performance)...
2454
+ if ((layout.maxHeight != null) && (f.height > layout.maxHeight)) f.height = layout.maxHeight;
2455
+ if ((layout.minHeight != null) && (f.height < layout.minHeight)) f.height = layout.minHeight;
2456
+ if ((layout.maxWidth != null) && (f.width > layout.maxWidth)) f.width = layout.maxWidth;
2457
+ if ((layout.minWidth != null) && (f.width < layout.minWidth)) f.width = layout.minWidth;
2458
+
2459
+ // Finally, adjust for scale. (Scale is only defined here if we're doing special-case ScrollView stuff.)
2460
+ f = this._adjustForScale(f, layout, scale, oX, oY);
2461
+
2462
+ return f;
2463
+ },
2464
+
2465
+ init: function () {
2466
+ sc_super();
2467
+
2468
+ // Enabled.
2469
+ // If the view is pre-configured as disabled, then go to the proper initial state.
2470
+ if (!this.get('isEnabled')) { this._doDisable(); }
2471
+
2472
+ // Layout
2473
+ this._previousLayout = this.get('layout');
2474
+
2475
+ // Apply the automatic child view layout if it is defined.
2476
+ var childViewLayout = this.childViewLayout;
2477
+ if (childViewLayout) {
2478
+ // Layout the child views once.
2479
+ this.set('childViewsNeedLayout', true);
2480
+ this.layoutChildViewsIfNeeded();
2481
+
2482
+ // If the child view layout is live, start observing affecting properties.
2483
+ if (this.get('isChildViewLayoutLive')) {
2484
+ this.addObserver('childViews.[]', this, this._cvl_childViewsDidChange);
2485
+ // DISABLED. this.addObserver('childViewLayout', this, this._cvl_childViewLayoutDidChange);
2486
+ this.addObserver('childViewLayoutOptions', this, this._cvl_childViewLayoutDidChange);
2487
+
2488
+ // Initialize the child views.
2489
+ this._cvl_setupChildViewsLiveLayout();
2490
+
2491
+ // Initialize our own frame observer.
2492
+ if (!this.get('isFixedSize') && childViewLayout.layoutDependsOnSize && childViewLayout.layoutDependsOnSize(this)) {
2493
+ this.addObserver('frame', this, this._cvl_childViewLayoutDidChange);
2494
+ }
2495
+ }
2496
+ }
2497
+
2498
+ // Theming
2499
+ this._lastTheme = this.get('theme');
2500
+
2501
+ },
2502
+
2503
+ /** @private */
2504
+ destroy: function () {
2505
+ // Clean up.
2506
+ this._previousLayout = null;
2507
+
2508
+ return sc_super();
2509
+ },
2510
+
2511
+ /** SC.CoreView.prototype. */
2512
+ removeChild: function(view) {
2513
+ // Manipulation
2514
+ if (!view) { return this; } // nothing to do
2515
+ if (view.parentView !== this) {
2516
+ throw new Error("%@.removeChild(%@) must belong to parent".fmt(this, view));
2517
+ }
2518
+
2519
+ // notify views
2520
+ // TODO: Deprecate these notifications.
2521
+ if (view.willRemoveFromParent) { view.willRemoveFromParent() ; }
2522
+ if (this.willRemoveChild) { this.willRemoveChild(view) ; }
2523
+
2524
+ sc_super();
2525
+
2526
+ return this;
2527
+ }
2528
+
1915
2529
  });
1916
2530
 
1917
2531
  //unload views for IE, trying to collect memory.