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
@@ -10,15 +10,19 @@ sc_require('panes/panel');
10
10
  /** @class
11
11
  Displays a non-modal, default positioned, drag&drop-able palette pane.
12
12
 
13
- The default way to use the palette pane is to simply add it to your page like this:
13
+ The simplest way to use the palette pane is to define it in an SC.Page like this:
14
14
 
15
- SC.PalettePane.create({
16
- layout: { width: 400, height: 200, right: 0, top: 0 },
17
- contentView: SC.View.extend({
15
+ myPalettePane: SC.PalettePane.create({
16
+ layout: { width: 400, height: 200, right: 0, top: 0 },
17
+ contentView: SC.View.extend({
18
+ })
18
19
  })
19
- }).append();
20
20
 
21
- This will cause your palette pane to display.
21
+ Then get it from your page and append like this:
22
+
23
+ MyApp.myPage.get('myPalettePane').append();
24
+
25
+ This will cause your palette pane to instantiate lazily and display.
22
26
 
23
27
  Palette pane is a simple way to provide non-modal messaging that won't
24
28
  blocks the user's interaction with your application. Palette panes are
@@ -26,9 +30,10 @@ sc_require('panes/panel');
26
30
  They provide a better user experience than modal panel.
27
31
 
28
32
  @extends SC.PanelPane
33
+ @extends SC.DraggablePaneSupport
29
34
  @since SproutCore 1.0
30
35
  */
31
- SC.PalettePane = SC.PanelPane.extend(
36
+ SC.PalettePane = SC.PanelPane.extend(SC.DraggablePaneSupport,
32
37
  /** @scope SC.PalettePane.prototype */ {
33
38
 
34
39
  /**
@@ -50,47 +55,6 @@ SC.PalettePane = SC.PanelPane.extend(
50
55
  @type SC.View
51
56
  @default SC.ModalPane
52
57
  */
53
- modalPane: SC.ModalPane,
54
-
55
- /**
56
- @type Boolean
57
- @default NO
58
- */
59
- isAnchored: NO,
60
-
61
- /** @private */
62
- _mouseOffsetX: null,
63
-
64
- /** @private */
65
- _mouseOffsetY: null,
66
-
67
- /** @private
68
- Drag & drop palette to new position.
69
- */
70
- mouseDown: function(evt) {
71
- var f=this.get('frame');
72
- this._mouseOffsetX = f ? (f.x - evt.pageX) : 0;
73
- this._mouseOffsetY = f ? (f.y - evt.pageY) : 0;
74
- return YES;
75
- },
76
-
77
- /** @private */
78
- mouseDragged: function(evt) {
79
- if(!this.isAnchored) {
80
- this.set('layout', { width: this.layout.width, height: this.layout.height, left: this._mouseOffsetX + evt.pageX, top: this._mouseOffsetY + evt.pageY });
81
- this.updateLayout();
82
- }
83
- return YES;
84
- },
85
-
86
- /** @private */
87
- touchStart: function(evt){
88
- return this.mouseDown(evt);
89
- },
90
-
91
- /** @private */
92
- touchesDragged: function(evt){
93
- return this.mouseDragged(evt);
94
- }
95
58
 
59
+ modalPane: SC.ModalPane
96
60
  });
@@ -51,14 +51,6 @@ SC.PICKER_POINTER = 'pointer';
51
51
  */
52
52
  SC.PICKER_MENU_POINTER = 'menu-pointer';
53
53
 
54
- /**
55
- Pointer layout for perfect right/left/top/bottom.
56
-
57
- @constant
58
- @static
59
- */
60
- SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom"];
61
-
62
54
  /**
63
55
  @class
64
56
 
@@ -95,10 +87,10 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
95
87
  When `preferType` is unspecified, `SC.PICKER_MENU` or `SC.PICKER_FIXED`, then
96
88
  the `preferMatrix` array describes the offset that is used to position the
97
89
  pane below the anchor. The offset is described by an array of three values,
98
- defaulting to `[1, 4, 3]`. The first value controls the x offset and the second
99
- value the y offset. The third value can be `0` (right) or `3` (bottom),
90
+ defaulting to `[1, 4, SC.POSITION_BOTTOM]`. The first value controls the x offset and the second
91
+ value the y offset. The third value can be `SC.POSITION_RIGHT` (0) or `SC.POSITION_BOTTOM` (3),
100
92
  controlling whether the origin of the pane is further offset by the width
101
- (in the case of 0) or the height (in the case of 3) of the anchor.
93
+ (in the case of SC.POSITION_RIGHT) or the height (in the case of SC.POSITION_BOTTOM) of the anchor.
102
94
 
103
95
  ### Position-based
104
96
 
@@ -109,14 +101,27 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
109
101
  `SC.PickerPane` should display on when there isn't enough space around any
110
102
  of the preferred sides.
111
103
 
112
- Anchor sides are defined by their index in `SC.POINTER_LAYOUT`, where right
113
- is `0`, left is `1`, top is `2`, and bottom is `3`.
104
+ The sides may be one of:
105
+
106
+ * SC.POSITION_RIGHT (i.e. 0) - to the right of the anchor
107
+ * SC.POSITION_LEFT (i.e. 1)- to the left of the anchor
108
+ * SC.POSITION_TOP (i.e. 2) - above the anchor
109
+ * SC.POSITION_BOTTOM (i.e. 3) - below the anchor
110
+
111
+ For example, the `preferMatrix` of,
114
112
 
115
- For example, the `preferMatrix` of `[3, 0, 1, 2, 2]` says: "Display below the
116
- anchor (3); if there isn't enough space then display to the right of the anchor (0).
113
+ [SC.POSITION_BOTTOM, SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_TOP],
114
+
115
+ indicates: Display below the anchor (SC.POSITION_BOTTOM); if there isn't enough
116
+ space then display to the right of the anchor (SC.POSITION_RIGHT).
117
117
  If there isn't enough space either below or to the right of the anchor, then appear
118
- to the left (1), unless there is also no space on the left, in which case display
119
- above the anchor (2)."
118
+ to the left (SC.POSITION_LEFT), unless there is also no space on the left, in which case display
119
+ above the anchor (SC.POSITION_TOP).
120
+
121
+ Note: The position constants are simply the integers 0 to 3, so a short form
122
+ of the example above would read,
123
+
124
+ [3, 0, 1, 2, 2]
120
125
 
121
126
  ## Position Rules
122
127
 
@@ -131,30 +136,29 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
131
136
 
132
137
  ### `SC.PICKER_MENU`
133
138
 
134
- Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, 3]`.
139
+ Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, SC.POSITION_BOTTOM]`.
135
140
  Furthermore, a minimum left and right padding to window, of 7px and 8px, respectively,
136
141
  is enforced.
137
142
 
138
143
 
139
144
  ### `SC.PICKER_FIXED`
140
145
 
141
- Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, 3]` and
146
+ Positioning is offset-based, with `preferMatrix` defaulting to `[1, 4, SC.POSITION_BOTTOM]` and
142
147
  skipping `fitPositionToScreen`.
143
148
 
144
149
 
145
150
  ### `SC.PICKER_POINTER`
146
151
 
147
- Positioning is position-based, with `preferMatrix` defaulting to `[0, 1, 2, 3, 2]`,
152
+ Positioning is position-based, with `preferMatrix` defaulting to `[SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM, SC.POSITION_TOP]` or `[0, 1, 2, 3, 2]` for short,
148
153
  i.e. right > left > top > bottom; fallback to top.
149
154
 
150
155
 
151
156
  ### `SC.PICKER_MENU_POINTER`
152
157
 
153
- Positioning is position-based, with `preferMatrix` defaulting to `[3, 0, 1, 2, 3]`,
158
+ Positioning is position-based, with `preferMatrix` defaulting to `[SC.POSITION_BOTTOM, SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM]` or `[3, 0, 1, 2, 3]` for short,
154
159
  i.e. bottom, right, left, top; fallback to bottom.
155
160
 
156
161
 
157
-
158
162
  ## Examples
159
163
 
160
164
  Examples for applying popular customized picker position rules:
@@ -166,60 +170,60 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
166
170
  contentView: SC.View.extend({})
167
171
  }).popup(anchor);
168
172
 
169
- ### menu below the anchor with default `preferMatrix` of `[1, 4, 3]`:
173
+ ### menu below the anchor with default `preferMatrix` of `[1, 4, SC.POSITION_BOTTOM]`:
170
174
 
171
175
  SC.PickerPane.create({
172
176
  layout: { width: 400, height: 200 },
173
177
  contentView: SC.View.extend({})
174
178
  }).popup(anchor, SC.PICKER_MENU);
175
179
 
176
- ### menu on the right side of anchor with custom `preferMatrix` of `[2, 6, 0]`:
180
+ ### menu on the right side of anchor with custom `preferMatrix` of `[2, 6, SC.POSITION_RIGHT]`:
177
181
 
178
182
  SC.PickerPane.create({
179
183
  layout: { width: 400, height: 200 },
180
184
  contentView: SC.View.extend({})
181
- }).popup(anchor, SC.PICKER_MENU, [2, 6, 0]);
185
+ }).popup(anchor, SC.PICKER_MENU, [2, 6, SC.POSITION_RIGHT]);
182
186
 
183
- ### fixed below the anchor with default `preferMatrix` of `[1, 4, 3]`:
187
+ ### fixed below the anchor with default `preferMatrix` of `[1, 4, SC.POSITION_BOTTOM]`:
184
188
 
185
189
  SC.PickerPane.create({
186
190
  layout: { width: 400, height: 200 },
187
191
  contentView: SC.View.extend({})
188
192
  }).popup(anchor, SC.PICKER_FIXED);
189
193
 
190
- ### fixed on the right side of anchor with `preferMatrix` of `[-22,-17, 0]`:
194
+ ### fixed on the right side of anchor with `preferMatrix` of `[-22,-17, SC.POSITION_RIGHT]`:
191
195
 
192
196
  SC.PickerPane.create({
193
197
  layout: { width: 400, height: 200 },
194
198
  contentView: SC.View.extend({})
195
- }).popup(anchor, SC.PICKER_FIXED, [-22,-17, 0]);
199
+ }).popup(anchor, SC.PICKER_FIXED, [-22,-17, SC.POSITION_RIGHT]);
196
200
 
197
- ### pointer with default `preferMatrix` of `[0, 1, 2, 3, 2]`:
201
+ ### pointer with default `preferMatrix` of `[SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM, SC.POSITION_TOP]` or `[0, 1, 2, 3, 2]`:
198
202
 
199
203
  SC.PickerPane.create({
200
204
  layout: { width: 400, height: 200 },
201
205
  contentView: SC.View.extend({})
202
206
  }).popup(anchor, SC.PICKER_POINTER);
203
207
 
204
- Positioning: right (0) > left (1) > top (2) > bottom (3). Fallback to top (2).
208
+ Positioning: SC.POSITION_RIGHT (0) > SC.POSITION_LEFT (1) > SC.POSITION_TOP (2) > SC.POSITION_BOTTOM (3). Fallback to SC.POSITION_TOP (2).
205
209
 
206
- ### pointer with custom `preferMatrix` of `[3, 0, 1, 2, 2]`:
210
+ ### pointer with custom `preferMatrix` of `[SC.POSITION_BOTTOM, SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_TOP]` or `[3, 0, 1, 2, 2]`:
207
211
 
208
212
  SC.PickerPane.create({
209
213
  layout: { width: 400, height: 200 },
210
214
  contentView: SC.View.extend({})
211
215
  }).popup(anchor, SC.PICKER_POINTER, [3, 0, 1, 2, 2]);
212
216
 
213
- Positioning: bottom (3) > right (0) > left (1) > top (2). Fallback to top (2).
217
+ Positioning: SC.POSITION_BOTTOM (3) > SC.POSITION_RIGHT (0) > SC.POSITION_LEFT (1) > SC.POSITION_TOP (2). Fallback to SC.POSITION_TOP (2).
214
218
 
215
- ### menu-pointer with default `preferMatrix` of `[3, 0, 1, 2, 3]`:
219
+ ### menu-pointer with default `preferMatrix` of `[SC.POSITION_BOTTOM, SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM]` or `[3, 0, 1, 2, 3]`:
216
220
 
217
221
  SC.PickerPane.create({
218
222
  layout: { width: 400, height: 200 },
219
223
  contentView: SC.View.extend({})
220
224
  }).popup(anchor, SC.PICKER_MENU_POINTER);
221
225
 
222
- Positioning: bottom (3) > right (0) > left (1) > top (2). Fallback to bottom (3).
226
+ Positioning: SC.POSITION_BOTTOM (3) > SC.POSITION_RIGHT (0) > SC.POSITION_LEFT (1) > SC.POSITION_TOP (2). Fallback to SC.POSITION_BOTTOM (3).
223
227
 
224
228
  @extends SC.PalettePane
225
229
  @since SproutCore 1.0
@@ -227,6 +231,11 @@ SC.POINTER_LAYOUT = ["perfectRight", "perfectLeft", "perfectTop", "perfectBottom
227
231
  SC.PickerPane = SC.PalettePane.extend(
228
232
  /** @scope SC.PickerPane.prototype */ {
229
233
 
234
+ //@if(debug)
235
+ /** @private Debug-mode only flag for ensuring that the pane is appended via `popup`. */
236
+ _sc_didUsePopup: false,
237
+ //@endif
238
+
230
239
  /**
231
240
  @type Array
232
241
  @default ['sc-picker']
@@ -246,6 +255,12 @@ SC.PickerPane = SC.PalettePane.extend(
246
255
  */
247
256
  isModal: YES,
248
257
 
258
+ /**
259
+ @private
260
+ TODO: Remove SC.POINTER_LAYOUT backward compatibility.
261
+ */
262
+ _sc_pointerLayout: SC.POINTER_LAYOUT || ['perfectRight', 'perfectLeft', 'perfectTop', 'perfectBottom'],
263
+
249
264
  /** @private
250
265
  @type String
251
266
  @default 'perfectRight'
@@ -265,37 +280,48 @@ SC.PickerPane = SC.PalettePane.extend(
265
280
  pointerPosY: 0,
266
281
 
267
282
  /** @private
268
- This property will be set to the element (or view.get('layer')) that
269
- triggered your picker to show. You can use this to properly position your
270
- picker.
283
+ When calling `popup`, you pass a view or element to anchor the pane. This
284
+ property returns the anchor element. (If you've anchored to a view, this
285
+ is its layer.) You can use this to properly position your view.
271
286
 
272
287
  @type HTMLElement
273
288
  @default null
274
289
  */
275
290
  anchorElement: function (key, value) {
276
- var anchorView;
277
-
291
+ // Getter
278
292
  if (value === undefined) {
279
- // Getting the value.
280
- anchorView = this._anchorView;
281
- return anchorView ? anchorView.get('layer') : this._anchorHTMLElement;
282
- } else {
283
- // Setting the value.
293
+ if (this._anchorView) return this._anchorView.get('layer');
294
+ else return this._anchorHTMLElement;
295
+ }
296
+ // Setter
297
+ else {
298
+ // Strip jQuery objects. (We do this first in case an empty one is passed in.)
299
+ if (value && value.isCoreQuery) value = value[0];
300
+
301
+ // Throw an error if a null or empty value is set. You're not allowed to go anchorless.
302
+ // (TODO: why can't we go anchorless? positionPane happily centers an unmoored pane.)
284
303
  if (!value) {
285
304
  throw "You must set 'anchorElement' to either a view or a DOM element";
286
305
  }
287
- else if (value.isView) {
306
+
307
+ // Clean up any previous anchor elements.
308
+ this._removeScrollObservers();
309
+
310
+ if (value.isView) {
311
+ this._setupScrollObservers(value);
288
312
  this._anchorView = value;
289
313
  this._anchorHTMLElement = null;
314
+ return value.get('layer');
290
315
  }
291
316
  else {
317
+ // TODO: We could setupScrollObservers on passed elements too, but it would
318
+ // be a bit more complicated.
292
319
  this._anchorView = null;
293
320
  this._anchorHTMLElement = value;
321
+ return value;
294
322
  }
295
-
296
- return value;
297
323
  }
298
- }.property('layer').cacheable(),
324
+ }.property().cacheable(),
299
325
 
300
326
  /** @private
301
327
  anchor rect calculated by computeAnchorRect from init popup
@@ -306,7 +332,34 @@ SC.PickerPane = SC.PalettePane.extend(
306
332
  anchorCached: null,
307
333
 
308
334
  /**
309
- popular customized picker position rule
335
+ The type of picker pane.
336
+
337
+ Picker panes can behave and appear in slightly differing ways
338
+ depending on the value of `preferType`. By default, with no `preferType`
339
+ specified, the pane will appear directly below the anchor element with
340
+ its left side aligned to the anchor's left side.
341
+
342
+ However, if you wish to position the pane by a specified offset to the
343
+ right or below the anchor using the values of `preferMatrix` as an offset
344
+ configuration, you can set `preferType` to one of `SC.PICKER_MENU` or
345
+ `SC.PICKER_FIXED`. These two picker types both use the `preferMatrix` to
346
+ adjust the position of the pane below or to the right of the anchor.
347
+
348
+ The difference is that `SC.PICKER_MENU` also uses the `windowPadding`
349
+ value to ensure that the pane doesn't go outside the bounds of the visible
350
+ window.
351
+
352
+ If you wish to position the pane on whichever side it will best fit and include
353
+ a pointer, then you can use one of `SC.PICKER_POINTER` or `SC.PICKER_MENU_POINTER`
354
+ for `preferType`. With this setting the pane will use the values of
355
+ `preferMatrix` to indicate the preferred side of the anchor for the picker
356
+ to appear.
357
+
358
+ The difference between these two is that `SC.PICKER_MENU_POINTER` prefers
359
+ to position below the anchor by default and `SC.PICKER_POINTER` prefers to
360
+ position to the right of the anchor by default. As well, the `SC.PICKER_MENU_POINTER`
361
+ type will resize itself if its height extends outside the visible window
362
+ (which is useful for long menus that can scroll).
310
363
 
311
364
  @type String
312
365
  @default null
@@ -314,18 +367,80 @@ SC.PickerPane = SC.PalettePane.extend(
314
367
  preferType: null,
315
368
 
316
369
  /**
317
- default/custom offset or position pref matrix for specific preferType
370
+ The configuration value for the current type of picker pane.
318
371
 
319
- @type String
372
+ This dual-purpose property controls the positioning of the pane depending
373
+ on what the value of `preferType` is.
374
+
375
+ ## Offset based use of `preferMatrix`
376
+
377
+ For `preferType` of `SC.PICKER_MENU` or `SC.PICKER_FIXED`, `preferMatrix`
378
+ determines the x and y offset of the pane from either the right or bottom
379
+ side of the anchor. In this case, the `preferMatrix` should be an array of,
380
+
381
+ [*x offset*, *y offset*, *offset position*]
382
+
383
+ For example, to position the pane 10px directly below the anchor, we would
384
+ use,
385
+
386
+ preferMatrix: [0, 10, SC.POSITION_BOTTOM]
387
+
388
+ To position the pane 10px down and 5px right of the anchor's right side,
389
+ we would use,
390
+
391
+ preferMatrix: [5, 10, SC.POSITION_RIGHT]
392
+
393
+ ## Position based use of `preferMatrix`
394
+
395
+ For `preferType` of `SC.PICKER_POINTER` or `SC.PICKER_MENU_POINTER`, `preferMatrix`
396
+ determines the side of the anchor to appear on in order of preference.
397
+ In this case, the `preferMatrix` should be an array of,
398
+
399
+ [*preferred side*, *2nd preferred side*, *3rd preferred side*, *4th preferred side*, *fallback side if none fit*]
400
+
401
+ Note that if the pane can't fit within the window bounds (including `windowPadding`)
402
+ on any of the sides, then the last side is used as a fallback.
403
+
404
+ @type Array
405
+ @default preferType == SC.PICKER_MENU || preferType == SC.PICKER_FIXED ? [1, 4, SC.POSITION_BOTTOM] (i.e. [1, 4, 3])
406
+ @default preferType == SC.PICKER_POINTER ? [SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM, SC.POSITION_TOP] (i.e. [0, 1, 2, 3, 2])
407
+ @default preferType == SC.PICKER_MENU_POINTER ? [SC.POSITION_BOTTOM, SC.POSITION_RIGHT, SC.POSITION_LEFT, SC.POSITION_TOP, SC.POSITION_BOTTOM] (i.e. [3, 0, 1, 2, 3])
320
408
  @default null
321
409
  */
322
410
  preferMatrix: null,
323
411
 
324
412
  /**
325
- default/custom offset of pointer for picker-pointer or pointer-menu
413
+ The offset of the pane from its target when positioned with `preferType` of
414
+ `SC.PICKER_POINTER` or `SC.PICKER_MENU_POINTER`.
415
+
416
+ When using `SC.PICKER_POINTER` or `SC.PICKER_MENU_POINTER` as the `preferType`,
417
+ the pane will include a pointer element (ex. a small triangle on the side of
418
+ the pane). This also means that the pane will be offset by an additional
419
+ distance in order to make space for the pointer. The offset distance of each
420
+ side is specified by `pointerOffset`.
421
+
422
+ Therefore, if you are using a custom picker pane style or you would just
423
+ like to change the default offsets, you should specify your own value like
424
+ so:
425
+
426
+ pointerOffset: [*right offset*, *left offset*, *top offset*, *bottom offset*]
427
+
428
+ For example,
429
+
430
+ // If the pane is to the right of the target, offset 15px further right for a left-side pointer.
431
+ // If the pane is to the left of the target, offset -15px further left for a right-side pointer.
432
+ // If the pane is above the target, offset -30px up for a bottom pointer.
433
+ // If the pane is below the target, offset 20px down for a top pointer.
434
+ pointerOffset: [15, -15, -30, 20]
326
435
 
327
436
  @type Array
328
- @default null
437
+ @default preferType == SC.PICKER_POINTER ? SC.PickerPane.PICKER_POINTER_OFFSET (i.e. [9, -9, -18, 18])
438
+ @default preferType == SC.PICKER_MENU_POINTER && controlSize == SC.TINY_CONTROL_SIZE ? SC.PickerPane.TINY_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -18, 18])
439
+ @default preferType == SC.PICKER_MENU_POINTER && controlSize == SC.SMALL_CONTROL_SIZE ? SC.PickerPane.SMALL_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -8, 8])
440
+ @default preferType == SC.PICKER_MENU_POINTER && controlSize == SC.REGULAR_CONTROL_SIZE ? SC.PickerPane.REGULAR_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -12, 12])
441
+ @default preferType == SC.PICKER_MENU_POINTER && controlSize == SC.LARGE_CONTROL_SIZE ? SC.PickerPane.LARGE_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -16, 16])
442
+ @default preferType == SC.PICKER_MENU_POINTER && controlSize == SC.HUGE_CONTROL_SIZE ? SC.PickerPane.HUGE_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -18, 18])
443
+ @default preferType == SC.PICKER_MENU_POINTER ? SC.PickerPane.REGULAR_PICKER_MENU_POINTER_OFFSET (i.e [9, -9, -12, 12])
329
444
  */
330
445
  pointerOffset: null,
331
446
 
@@ -405,9 +520,28 @@ SC.PickerPane = SC.PalettePane.extend(
405
520
  */
406
521
  windowPadding: null,
407
522
 
408
- /* @private Observe the frame for changes so that we can reposition if necessary. */
409
- borderFrameDidChange: function () {
523
+ //@if(debug)
524
+ // Provide some developer support. People have occasionally been misled by calling `append`
525
+ // on PickerPanes, which fails to position the pane properly. Hopefully, we can give
526
+ // them a clue to speed up finding the problem.
527
+ /** @private SC.Pane */
528
+ append: function () {
529
+ if (!this._sc_didUsePopup) {
530
+ SC.warn("Developer Warning: You should not use .append() with SC.PickerPane. Instead use .popup() and pass in an anchor view or element.");
531
+ }
532
+
533
+ this._sc_didUsePopup = false;
534
+
535
+ return sc_super();
536
+ },
537
+ //@endif
538
+
539
+ /* @private If the pane changes size, reposition as necessary. */
540
+ viewDidResize: function () {
410
541
  this.positionPane(true);
542
+
543
+ // Don't forget to call the superclass method.
544
+ sc_super();
411
545
  },
412
546
 
413
547
  /**
@@ -420,15 +554,8 @@ SC.PickerPane = SC.PalettePane.extend(
420
554
  @returns {SC.PickerPane} receiver
421
555
  */
422
556
  popup: function (anchorViewOrElement, preferType, preferMatrix, pointerOffset) {
423
- if (anchorViewOrElement) {
424
- if (anchorViewOrElement.isView) {
425
- this._anchorView = anchorViewOrElement;
426
- this._setupScrollObservers(anchorViewOrElement);
427
- } else {
428
- this._anchorHTMLElement = anchorViewOrElement;
429
- }
430
- }
431
557
  this.beginPropertyChanges();
558
+ this.setIfChanged('anchorElement', anchorViewOrElement);
432
559
  if (preferType) { this.set('preferType', preferType); }
433
560
  if (preferMatrix) { this.set('preferMatrix', preferMatrix); }
434
561
  if (pointerOffset) { this.set('pointerOffset', pointerOffset); }
@@ -436,8 +563,10 @@ SC.PickerPane = SC.PalettePane.extend(
436
563
  this.positionPane();
437
564
  this._hideOverflow();
438
565
 
439
- // Start observing the frame for changes.
440
- this.addObserver('borderFrame', this.borderFrameDidChange);
566
+ //@if(debug)
567
+ // A debug-mode only flag to indicate that the popup method was called (see override of append).
568
+ this._sc_didUsePopup = true;
569
+ //@endif
441
570
 
442
571
  return this.append();
443
572
  },
@@ -449,74 +578,73 @@ SC.PickerPane = SC.PalettePane.extend(
449
578
  fallback to center.
450
579
  */
451
580
  positionPane: function (useAnchorCached) {
452
- useAnchorCached = useAnchorCached && this.get('anchorCached');
453
-
454
- var anchor = useAnchorCached ? this.get('anchorCached') : this.get('anchorElement'),
455
- frame = this.get('borderFrame'),
456
- preferType = this.get('preferType'),
581
+ var frame = this.get('borderFrame'),
582
+ preferType = this.get('preferType'),
457
583
  preferMatrix = this.get('preferMatrix'),
458
- layout = this.get('layout'),
459
- origin;
584
+ origin, adjustHash,
585
+ anchor, anchorCached, anchorElement;
460
586
 
461
587
  // usually an anchorElement will be passed. The ideal position is just
462
588
  // below the anchor + default or custom offset according to preferType.
463
589
  // If that is not possible, fitPositionToScreen will take care of that for
464
590
  // other alternative and fallback position.
591
+ anchorCached = this.get('anchorCached');
592
+ anchorElement = this.get('anchorElement');
593
+ if (useAnchorCached && anchorCached) {
594
+ anchor = anchorCached;
595
+ } else if (anchorElement) {
596
+ anchor = this.computeAnchorRect(anchorElement);
597
+ this.set('anchorCached', anchor);
598
+ } // else no anchor to use
465
599
 
466
600
  if (anchor) {
467
- if (!useAnchorCached) {
468
- anchor = this.computeAnchorRect(anchor);
469
- this.set('anchorCached', anchor);
470
- }
471
-
472
601
  origin = SC.cloneRect(anchor);
473
602
 
474
- if (preferType) {
475
- switch (preferType) {
476
- case SC.PICKER_MENU:
477
- case SC.PICKER_FIXED:
478
- if (!preferMatrix || preferMatrix.length !== 3) {
479
- // default below the anchor with fine-tuned visual alignment
480
- // for Menu to appear just below the anchorElement.
481
- this.set('preferMatrix', [1, 4, 3]);
482
- }
483
-
484
- // fine-tuned visual alignment from preferMatrix
485
- origin.x += ((this.preferMatrix[2] === 0) ? origin.width : 0) + this.preferMatrix[0];
486
- origin.y += ((this.preferMatrix[2] === 3) ? origin.height : 0) + this.preferMatrix[1];
487
- break;
488
- default:
489
- origin.y += origin.height;
490
- break;
603
+ // Adjust the origin for offset based positioning.
604
+ switch (preferType) {
605
+ case SC.PICKER_MENU:
606
+ case SC.PICKER_FIXED:
607
+ if (!preferMatrix || preferMatrix.length !== 3) {
608
+ // default below the anchor with fine-tuned visual alignment
609
+ // for Menu to appear just below the anchorElement.
610
+ this.set('preferMatrix', [1, 4, 3]);
611
+ preferMatrix = this.get('preferMatrix');
491
612
  }
492
- } else {
613
+
614
+ // fine-tuned visual alignment from preferMatrix
615
+ origin.x += ((preferMatrix[2] === 0) ? origin.width : 0) + preferMatrix[0];
616
+ origin.y += ((preferMatrix[2] === 3) ? origin.height : 0) + preferMatrix[1];
617
+ break;
618
+ default:
493
619
  origin.y += origin.height;
620
+ break;
494
621
  }
495
622
 
496
623
  // Since we repeatedly need to know the half-width and half-height of the
497
624
  // frames, add those properties.
498
625
  anchor.halfWidth = parseInt(anchor.width * 0.5, 0);
499
626
  anchor.halfHeight = parseInt(anchor.height * 0.5, 0);
500
- frame.halfWidth = parseInt(frame.width * 0.5, 0);
501
- frame.halfHeight = parseInt(frame.height * 0.5, 0);
627
+ frame.halfWidth = parseInt(frame.originalWidth * 0.5, 0);
628
+ frame.halfHeight = parseInt(frame.originalHeight * 0.5, 0);
629
+
630
+ frame = this.fitPositionToScreen(origin, frame, anchor);
631
+ adjustHash = {
632
+ left: frame.x,
633
+ top: frame.y,
634
+ width: frame.width,
635
+ height: frame.height
636
+ };
502
637
 
503
- origin = this.fitPositionToScreen(origin, frame, anchor);
504
- this.adjust({
505
- width: origin.width,
506
- height: origin.height,
507
- left: origin.x,
508
- top: origin.y
509
- });
638
+ // Adjust.
639
+ this.adjust(adjustHash);
640
+ }
510
641
  // if no anchor view has been set for some reason, just center.
511
- } else {
642
+ else {
512
643
  this.adjust({
513
- width: layout.width,
514
- height: layout.height,
515
644
  centerX: 0,
516
645
  centerY: 0
517
646
  });
518
647
  }
519
- this.updateLayout();
520
648
 
521
649
  return this;
522
650
  },
@@ -570,11 +698,11 @@ SC.PickerPane = SC.PalettePane.extend(
570
698
  },
571
699
 
572
700
  /** @private
573
- This method will dispatch to the right re-position rule according to preferType
701
+ This method will dispatch to the correct re-position rule according to preferType
574
702
  */
575
- fitPositionToScreen: function (preferredPosition, picker, anchor) {
576
- var wsize = SC.RootResponder.responder.computeWindowSize(),
577
- wret = { x: 0, y: 0, width: wsize.width, height: wsize.height };
703
+ fitPositionToScreen: function (preferredPosition, frame, anchorFrame) {
704
+ var windowSize = SC.RootResponder.responder.computeWindowSize(),
705
+ windowFrame = { x: 0, y: 0, width: windowSize.width, height: windowSize.height };
578
706
 
579
707
  // if window size is smaller than the minimum size of app, use minimum size.
580
708
  var mainPane = SC.RootResponder.responder.mainPane;
@@ -582,32 +710,33 @@ SC.PickerPane = SC.PalettePane.extend(
582
710
  var minWidth = mainPane.layout.minWidth,
583
711
  minHeight = mainPane.layout.minHeight;
584
712
 
585
- if (minWidth && wret.width < minWidth) {
586
- wret.width = mainPane.layout.minWidth;
713
+ if (minWidth && windowFrame.width < minWidth) {
714
+ windowFrame.width = mainPane.layout.minWidth;
587
715
  }
588
716
 
589
- if (minHeight && wret.height < minHeight) {
590
- wret.height = mainPane.layout.minHeight;
717
+ if (minHeight && windowFrame.height < minHeight) {
718
+ windowFrame.height = mainPane.layout.minHeight;
591
719
  }
592
720
  }
593
721
 
594
- picker.x = preferredPosition.x;
595
- picker.y = preferredPosition.y;
722
+ frame.x = preferredPosition.x;
723
+ frame.y = preferredPosition.y;
596
724
 
597
- if (this.preferType) {
598
- switch (this.preferType) {
725
+ var preferType = this.get('preferType');
726
+ if (preferType) {
727
+ switch (preferType) {
599
728
  case SC.PICKER_MENU:
600
729
  // apply menu re-position rule
601
- picker = this.fitPositionToScreenMenu(wret, picker, this.get('isSubMenu'));
730
+ frame = this.fitPositionToScreenMenu(windowFrame, frame, this.get('isSubMenu'));
602
731
  break;
603
732
  case SC.PICKER_MENU_POINTER:
604
- this.setupPointer(anchor);
605
- picker = this.fitPositionToScreenMenuPointer(wret, picker, anchor);
733
+ this.setupPointer(anchorFrame);
734
+ frame = this.fitPositionToScreenMenuPointer(windowFrame, frame, anchorFrame);
606
735
  break;
607
736
  case SC.PICKER_POINTER:
608
737
  // apply pointer re-position rule
609
- this.setupPointer(anchor);
610
- picker = this.fitPositionToScreenPointer(wret, picker, anchor);
738
+ this.setupPointer(anchorFrame);
739
+ frame = this.fitPositionToScreenPointer(windowFrame, frame, anchorFrame);
611
740
  break;
612
741
  case SC.PICKER_FIXED:
613
742
  // skip fitPositionToScreen
@@ -617,52 +746,53 @@ SC.PickerPane = SC.PalettePane.extend(
617
746
  }
618
747
  } else {
619
748
  // apply default re-position rule
620
- picker = this.fitPositionToScreenDefault(wret, picker, anchor);
749
+ frame = this.fitPositionToScreenDefault(windowFrame, frame, anchorFrame);
621
750
  }
622
- // this.displayDidChange();
623
- return picker;
751
+
752
+ return frame;
624
753
  },
625
754
 
626
755
  /** @private
627
756
  re-position rule migrated from old SC.OverlayPaneView.
628
757
  shift x, y to optimized picker visibility and make sure top-left corner is always visible.
629
758
  */
630
- fitPositionToScreenDefault: function (w, f, a) {
631
- var mx;
759
+ fitPositionToScreenDefault: function (windowFrame, frame, anchorFrame) {
760
+ var maximum;
632
761
 
633
762
  // make sure the right edge fits on the screen. If not, anchor to
634
763
  // right edge of anchor or right edge of window, whichever is closer.
635
- if (SC.maxX(f) > w.width) {
636
- mx = Math.max(SC.maxX(a), f.width);
637
- f.x = Math.min(mx, w.width) - f.width;
764
+ if (SC.maxX(frame) > windowFrame.width) {
765
+ maximum = Math.max(SC.maxX(anchorFrame), frame.width);
766
+ frame.x = Math.min(maximum, windowFrame.width) - frame.width;
638
767
  }
639
768
 
640
769
  // if the left edge is off of the screen, try to position at left edge
641
770
  // of anchor. If that pushes right edge off screen, shift back until
642
771
  // right is on screen or left = 0
643
- if (SC.minX(f) < 0) {
644
- f.x = SC.minX(Math.max(a, 0));
645
- if (SC.maxX(f) > w.width) {
646
- f.x = Math.max(0, w.width - f.width);
772
+ if (SC.minX(frame) < 0) {
773
+ frame.x = SC.minX(Math.max(anchorFrame, 0));
774
+ if (SC.maxX(frame) > windowFrame.width) {
775
+ frame.x = Math.max(0, windowFrame.width - frame.width);
647
776
  }
648
777
  }
649
778
 
650
779
  // make sure bottom edge fits on screen. If not, try to anchor to top
651
780
  // of anchor or bottom edge of screen.
652
- if (SC.maxY(f) > w.height) {
653
- mx = Math.max((a.y - f.height), 0);
654
- if (mx > w.height) {
655
- f.y = Math.max(0, w.height - f.height);
656
- } else { f.y = mx; }
781
+ if (SC.maxY(frame) > windowFrame.height) {
782
+ maximum = Math.max((anchorFrame.y - frame.height), 0);
783
+ if (maximum > windowFrame.height) {
784
+ frame.y = Math.max(0, windowFrame.height - frame.height);
785
+ } else { frame.y = maximum; }
657
786
  }
658
787
 
659
- // if Top edge is off screen, try to anchor to bottom of anchor. If that
788
+ // if top edge is off screen, try to anchor to bottom of anchor. If that
660
789
  // pushes off bottom edge, shift up until it is back on screen or top =0
661
- if (SC.minY(f) < 0) {
662
- mx = Math.min(SC.maxY(a), (w.height - a.height));
663
- f.y = Math.max(mx, 0);
790
+ if (SC.minY(frame) < 0) {
791
+ maximum = Math.min(SC.maxY(anchorFrame), (windowFrame.height - anchorFrame.height));
792
+ frame.y = Math.max(maximum, 0);
664
793
  }
665
- return f;
794
+
795
+ return frame;
666
796
  },
667
797
 
668
798
  /** @private
@@ -674,44 +804,48 @@ SC.PickerPane = SC.PalettePane.extend(
674
804
  If the menu is a submenu, we also want to reposition the pane to the left
675
805
  of the parent menu if it would otherwise exceed the width of the viewport.
676
806
  */
677
- fitPositionToScreenMenu: function (windowFrame, paneFrame, subMenu) {
807
+ fitPositionToScreenMenu: function (windowFrame, frame, subMenu) {
808
+ var windowPadding = this.get('windowPadding');
809
+
678
810
  // Set up init location for submenu
679
811
  if (subMenu) {
680
- paneFrame.x -= this.get('submenuOffsetX');
681
- paneFrame.y -= Math.floor(this.get('menuHeightPadding') / 2);
812
+ frame.x -= this.get('submenuOffsetX');
813
+ frame.y -= Math.floor(this.get('menuHeightPadding') / 2);
814
+ }
815
+
816
+ // Make sure we are at least the window padding from the left edge of the screen to start.
817
+ if (frame.x < windowPadding) {
818
+ frame.x = windowPadding;
682
819
  }
683
820
 
684
- // If the right edge of the pane is within 20 pixels of the right edge
821
+ // If the right edge of the pane is within the window padding of the right edge
685
822
  // of the window, we need to reposition it.
686
- if ((paneFrame.x + paneFrame.width) > (windowFrame.width - 20)) {
823
+ if ((frame.x + frame.width + windowPadding) > windowFrame.width) {
687
824
  if (subMenu) {
688
825
  // Submenus should be re-anchored to the left of the parent menu
689
- paneFrame.x = paneFrame.x - (paneFrame.width * 2);
826
+ frame.x = frame.x - (frame.width * 2);
690
827
  } else {
691
- // Otherwise, just position the pane 20 pixels from the right edge
692
- paneFrame.x = windowFrame.width - paneFrame.width - 20;
828
+ // Otherwise, just shift the pane windowPadding pixels from the right edge
829
+ frame.x = windowFrame.width - frame.width - windowPadding;
693
830
  }
694
831
  }
695
832
 
696
- // Make sure we are at least 7 pixels from the left edge of the screen.
697
- if (paneFrame.x < 7) { paneFrame.x = 7; }
833
+ // Make sure we are at least the window padding from the top edge of the screen to start.
834
+ if (frame.y < windowPadding) {
835
+ frame.y = windowPadding;
836
+ }
698
837
 
699
- if (paneFrame.y < 7) {
700
- paneFrame.height += paneFrame.y;
701
- paneFrame.y = 7;
838
+ // If the height of the menu is bigger than the window height, shift it upward.
839
+ if (frame.y + frame.height + windowPadding > windowFrame.height) {
840
+ frame.y = Math.max(windowPadding, windowFrame.height - frame.height - windowPadding);
702
841
  }
703
842
 
704
- // If the height of the menu is bigger than the window height, resize it.
705
- if (paneFrame.height + paneFrame.y + 35 >= windowFrame.height) {
706
- if (paneFrame.height + 50 >= windowFrame.height) {
707
- paneFrame.y = SC.MenuPane.VERTICAL_OFFSET;
708
- paneFrame.height = windowFrame.height - (SC.MenuPane.VERTICAL_OFFSET * 2);
709
- } else {
710
- paneFrame.y += (windowFrame.height - (paneFrame.height + paneFrame.y + 35));
711
- }
843
+ // If the height of the menu is still bigger than the window height, resize it.
844
+ if (frame.y + frame.height + windowPadding > windowFrame.height) {
845
+ frame.height = windowFrame.height - (2 * windowPadding);
712
846
  }
713
847
 
714
- return paneFrame;
848
+ return frame;
715
849
  },
716
850
 
717
851
  /** @private
@@ -723,25 +857,25 @@ SC.PickerPane = SC.PalettePane.extend(
723
857
 
724
858
  @returns {Rect}
725
859
  */
726
- fitPositionToScreenMenuPointer: function (w, f, a) {
727
- f = this.fitPositionToScreenPointer(w, f, a);
860
+ fitPositionToScreenMenuPointer: function (windowFrame, frame, anchorFrame) {
861
+ frame = this.fitPositionToScreenPointer(windowFrame, frame, anchorFrame);
728
862
 
729
863
  // If the height of the menu is bigger than the window height, resize it.
730
- if (f.height + f.y + 35 >= w.height) {
731
- f.height = w.height - f.y - (SC.MenuPane.VERTICAL_OFFSET * 2);
864
+ if (frame.height + frame.y + 35 >= windowFrame.height) {
865
+ frame.height = windowFrame.height - frame.y - (SC.MenuPane.VERTICAL_OFFSET * 2);
732
866
  }
733
867
 
734
- return f;
868
+ return frame;
735
869
  },
736
870
 
737
871
  /** @private
738
872
  re-position rule for triangle pointer picker.
739
873
  */
740
- fitPositionToScreenPointer: function (w, f, a) {
874
+ fitPositionToScreenPointer: function (windowFrame, frame, anchorFrame) {
741
875
  var curType,
742
876
  deltas,
743
- matrix = this.preferMatrix,
744
- offset = this.pointerOffset,
877
+ matrix = this.get('preferMatrix'),
878
+ offset = this.get('pointerOffset'),
745
879
  topLefts, botRights,
746
880
  windowPadding = this.get('windowPadding');
747
881
 
@@ -749,37 +883,37 @@ SC.PickerPane = SC.PalettePane.extend(
749
883
  // frames, while taking the pointer offset into account.
750
884
  topLefts = [
751
885
  // Top left [x, y] if positioned evenly to the right of the anchor
752
- [a.x + a.width + offset[0], a.y + a.halfHeight - f.halfHeight],
886
+ [anchorFrame.x + anchorFrame.width + offset[0], anchorFrame.y + anchorFrame.halfHeight - frame.halfHeight],
753
887
 
754
888
  // Top left [x, y] if positioned evenly to the left of the anchor
755
- [a.x - f.width + offset[1], a.y + a.halfHeight - f.halfHeight],
889
+ [anchorFrame.x - frame.originalWidth + offset[1], anchorFrame.y + anchorFrame.halfHeight - frame.halfHeight],
756
890
 
757
891
  // Top left [x, y] if positioned evenly above the anchor
758
- [a.x + a.halfWidth - f.halfWidth, a.y - f.height + offset[2]],
892
+ [anchorFrame.x + anchorFrame.halfWidth - frame.halfWidth, anchorFrame.y - frame.originalHeight + offset[2]],
759
893
 
760
894
  // Top left [x, y] if positioned evenly below the anchor
761
- [a.x + a.halfWidth - f.halfWidth, a.y + a.height + offset[3]]
895
+ [anchorFrame.x + anchorFrame.halfWidth - frame.halfWidth, anchorFrame.y + anchorFrame.height + offset[3]]
762
896
  ];
763
897
 
764
898
  // Determine the bottom-right corner of each of the 4 perfectly positioned
765
899
  // frames, while taking the pointer offset into account.
766
900
  botRights = [
767
901
  // Bottom right [x, y] if positioned evenly to the right of the anchor
768
- [a.x + a.width + f.width + offset[0], a.y + a.halfHeight + f.halfHeight],
902
+ [anchorFrame.x + anchorFrame.width + frame.width + offset[0], anchorFrame.y + anchorFrame.halfHeight + frame.halfHeight],
769
903
 
770
904
  // Bottom right [x, y] if positioned evenly to the left of the anchor
771
- [a.x + offset[1], a.y + a.halfHeight + f.halfHeight],
905
+ [anchorFrame.x + offset[1], anchorFrame.y + anchorFrame.halfHeight + frame.halfHeight],
772
906
 
773
907
  // Bottom right [x, y] if positioned evenly above the anchor
774
- [a.x + a.halfWidth + f.halfWidth, a.y + offset[2]],
908
+ [anchorFrame.x + anchorFrame.halfWidth + frame.halfWidth, anchorFrame.y + offset[2]],
775
909
 
776
910
  // Bottom right [x, y] if positioned evenly below the anchor
777
- [a.x + a.halfWidth + f.halfWidth, a.y + a.height + f.height + offset[3]]
911
+ [anchorFrame.x + anchorFrame.halfWidth + frame.halfWidth, anchorFrame.y + anchorFrame.height + frame.height + offset[3]]
778
912
  ];
779
913
 
780
914
  // Loop through the preferred matrix, hopefully finding one that will fit
781
915
  // perfectly.
782
- for (var i = 0, pointerLen = SC.POINTER_LAYOUT.length; i < pointerLen; i++) {
916
+ for (var i = 0, pointerLen = this._sc_pointerLayout.length; i < pointerLen; i++) {
783
917
  // The current preferred side.
784
918
  curType = matrix[i];
785
919
 
@@ -793,8 +927,8 @@ SC.PickerPane = SC.PalettePane.extend(
793
927
  // option for positioning.
794
928
  deltas = {
795
929
  top: topLefts[curType][1] - windowPadding,
796
- right: w.width - windowPadding - botRights[curType][0],
797
- bottom: w.height - windowPadding - botRights[curType][1],
930
+ right: windowFrame.width - windowPadding - botRights[curType][0],
931
+ bottom: windowFrame.height - windowPadding - botRights[curType][1],
798
932
  left: topLefts[curType][0] - windowPadding
799
933
  };
800
934
 
@@ -810,12 +944,12 @@ SC.PickerPane = SC.PalettePane.extend(
810
944
  deltas.bottom >= 0 &&
811
945
  deltas.left >= 0) {
812
946
 
813
- f.x = topLefts[curType][0];
814
- f.y = topLefts[curType][1];
947
+ frame.x = topLefts[curType][0];
948
+ frame.y = topLefts[curType][1];
815
949
 
816
950
  this.set('pointerPosX', 0);
817
951
  this.set('pointerPosY', 0);
818
- this.set('pointerPos', SC.POINTER_LAYOUT[curType]);
952
+ this.set('pointerPos', this._sc_pointerLayout[curType]);
819
953
 
820
954
  break;
821
955
 
@@ -826,17 +960,17 @@ SC.PickerPane = SC.PalettePane.extend(
826
960
  } else if (((curType === 0 && deltas.right >= 0) || // Right fits for preferred right
827
961
  (curType === 1 && deltas.left >= 0)) && // or left fits for preferred left,
828
962
  deltas.top < 0 && // but top doesn't fit,
829
- deltas.top + f.halfHeight >= 0) { // yet it could.
963
+ deltas.top + frame.halfHeight >= 0) { // yet it could.
830
964
 
831
965
  // Adjust the pane position by the amount of downward shifting.
832
- f.x = topLefts[curType][0];
833
- f.y = topLefts[curType][1] - deltas.top;
966
+ frame.x = topLefts[curType][0];
967
+ frame.y = topLefts[curType][1] - deltas.top;
834
968
 
835
969
  // Offset the pointer position by the opposite amount of downward
836
970
  // shifting (minus half the height of the pointer).
837
971
  this.set('pointerPosX', 0);
838
972
  this.set('pointerPosY', deltas.top);
839
- this.set('pointerPos', SC.POINTER_LAYOUT[curType]);
973
+ this.set('pointerPos', this._sc_pointerLayout[curType]);
840
974
  break;
841
975
 
842
976
  // If we prefer right or left and can fit right or left respectively, but
@@ -846,17 +980,17 @@ SC.PickerPane = SC.PalettePane.extend(
846
980
  } else if (((curType === 0 && deltas.right >= 0) || // Right fits for preferred right
847
981
  (curType === 1 && deltas.left >= 0)) && // or left fits for preferred left,
848
982
  deltas.bottom < 0 && // but bottom doesn't fit,
849
- deltas.bottom + f.halfHeight >= 0) { // yet it could.
983
+ deltas.bottom + frame.halfHeight >= 0) { // yet it could.
850
984
 
851
985
  // Adjust the pane position by the amount of upward shifting.
852
- f.x = topLefts[curType][0];
853
- f.y = topLefts[curType][1] + deltas.bottom;
986
+ frame.x = topLefts[curType][0];
987
+ frame.y = topLefts[curType][1] + deltas.bottom;
854
988
 
855
989
  // Offset the pointer position by the opposite amount of upward
856
990
  // shifting (minus half the height of the pointer).
857
991
  this.set('pointerPosX', 0);
858
992
  this.set('pointerPosY', Math.abs(deltas.bottom));
859
- this.set('pointerPos', SC.POINTER_LAYOUT[curType]);
993
+ this.set('pointerPos', this._sc_pointerLayout[curType]);
860
994
  break;
861
995
 
862
996
  // If we prefer top or bottom and can fit top or bottom respectively, but
@@ -867,17 +1001,17 @@ SC.PickerPane = SC.PalettePane.extend(
867
1001
  } else if (((curType === 2 && deltas.top >= 0) || // Top fits for preferred top
868
1002
  (curType === 3 && deltas.bottom >= 0)) && // or bottom fits for preferred bottom,
869
1003
  deltas.right < 0 && // but right doesn't fit,
870
- deltas.right + f.halfWidth >= 0) { // yet it could.
1004
+ deltas.right + frame.halfWidth >= 0) { // yet it could.
871
1005
 
872
1006
  // Adjust the pane position by the amount of leftward shifting.
873
- f.x = topLefts[curType][0] + deltas.right;
874
- f.y = topLefts[curType][1];
1007
+ frame.x = topLefts[curType][0] + deltas.right;
1008
+ frame.y = topLefts[curType][1];
875
1009
 
876
1010
  // Offset the pointer position by the opposite amount of leftward
877
1011
  // shifting (minus half the width of the pointer).
878
1012
  this.set('pointerPosX', Math.abs(deltas.right));
879
1013
  this.set('pointerPosY', 0);
880
- this.set('pointerPos', SC.POINTER_LAYOUT[curType]);
1014
+ this.set('pointerPos', this._sc_pointerLayout[curType]);
881
1015
  break;
882
1016
 
883
1017
  // If we prefer top or bottom and can fit top or bottom respectively, but
@@ -888,17 +1022,17 @@ SC.PickerPane = SC.PalettePane.extend(
888
1022
  } else if (((curType === 2 && deltas.top >= 0) || // Top fits for preferred top
889
1023
  (curType === 3 && deltas.bottom >= 0)) && // or bottom fits for preferred bottom,
890
1024
  deltas.left < 0 && // but left doesn't fit,
891
- deltas.left + f.halfWidth >= 0) { // yet it could.
1025
+ deltas.left + frame.halfWidth >= 0) { // yet it could.
892
1026
 
893
1027
  // Adjust the pane position by the amount of leftward shifting.
894
- f.x = topLefts[curType][0] - deltas.left;
895
- f.y = topLefts[curType][1];
1028
+ frame.x = topLefts[curType][0] - deltas.left;
1029
+ frame.y = topLefts[curType][1];
896
1030
 
897
1031
  // Offset the pointer position by the opposite amount of leftward
898
1032
  // shifting (minus half the width of the pointer).
899
1033
  this.set('pointerPosX', deltas.left);
900
1034
  this.set('pointerPosY', 0);
901
- this.set('pointerPos', SC.POINTER_LAYOUT[curType]);
1035
+ this.set('pointerPos', this._sc_pointerLayout[curType]);
902
1036
  break;
903
1037
  }
904
1038
 
@@ -908,17 +1042,16 @@ SC.PickerPane = SC.PalettePane.extend(
908
1042
  // type.
909
1043
  if (i === pointerLen) {
910
1044
  if (matrix[4] === -1) {
911
- //f.x = a.x > 0 ? a.x + 23 : 0; // another alternative align to left
912
- f.x = a.x + a.halfWidth;
913
- f.y = a.y + a.halfHeight - f.halfHeight;
1045
+ frame.x = anchorFrame.x + anchorFrame.halfWidth;
1046
+ frame.y = anchorFrame.y + anchorFrame.halfHeight - frame.halfHeight;
914
1047
 
915
- this.set('pointerPos', SC.POINTER_LAYOUT[0] + ' fallback');
916
- this.set('pointerPosY', f.halfHeight - 40);
1048
+ this.set('pointerPos', this._sc_pointerLayout[0] + ' fallback');
1049
+ this.set('pointerPosY', frame.halfHeight - 40);
917
1050
  } else {
918
- f.x = topLefts[matrix[4]][0];
919
- f.y = topLefts[matrix[4]][1];
1051
+ frame.x = topLefts[matrix[4]][0];
1052
+ frame.y = topLefts[matrix[4]][1];
920
1053
 
921
- this.set('pointerPos', SC.POINTER_LAYOUT[matrix[4]]);
1054
+ this.set('pointerPos', this._sc_pointerLayout[matrix[4]]);
922
1055
  this.set('pointerPosY', 0);
923
1056
  }
924
1057
 
@@ -927,7 +1060,7 @@ SC.PickerPane = SC.PalettePane.extend(
927
1060
 
928
1061
  this.invokeLast(this._adjustPointerPosition);
929
1062
 
930
- return f;
1063
+ return frame;
931
1064
  },
932
1065
 
933
1066
  /** @private Measure the pointer element and adjust it by the determined offset. */
@@ -958,12 +1091,12 @@ SC.PickerPane = SC.PalettePane.extend(
958
1091
  and size if not provided explicitly.
959
1092
  */
960
1093
  setupPointer: function (a) {
961
- var pointerOffset = this.pointerOffset,
962
- K = SC.PickerPane;
1094
+ var pointerOffset = this.get('pointerOffset'),
1095
+ K = SC.PickerPane;
963
1096
 
964
- // set up pointerOffset according to type and size if not provided explicitly
1097
+ // Set windowPadding and pointerOffset (SC.PICKER_MENU_POINTER only).
965
1098
  if (!pointerOffset || pointerOffset.length !== 4) {
966
- if (this.get('preferType') == SC.PICKER_MENU_POINTER) {
1099
+ if (this.get('preferType') === SC.PICKER_MENU || this.get('preferType') === SC.PICKER_MENU_POINTER) {
967
1100
  switch (this.get('controlSize')) {
968
1101
  case SC.TINY_CONTROL_SIZE:
969
1102
  this.set('pointerOffset', K.TINY_PICKER_MENU_POINTER_OFFSET);
@@ -1003,22 +1136,14 @@ SC.PickerPane = SC.PalettePane.extend(
1003
1136
  offsetKey[3] + overlapTuningY];
1004
1137
 
1005
1138
  this.set('pointerOffset', offset);
1006
- // TODO: What to do about this?
1007
- if (SC.none(this.get('windowPadding'))) {
1008
- this.set('windowPadding', K.WINDOW_PADDING);
1009
- }
1010
- }
1011
- } else {
1012
- // TODO: What to do about this?
1013
- if (SC.none(this.get('windowPadding'))) {
1014
- this.set('windowPadding', K.WINDOW_PADDING);
1015
1139
  }
1016
1140
  }
1017
1141
 
1018
1142
  // set up preferMatrix according to type if not provided explicitly:
1019
1143
  // take default [0, 1, 2, 3, 2] for picker, [3, 0, 1, 2, 3] for menu picker if
1020
1144
  // custom matrix not provided explicitly
1021
- if (!this.preferMatrix || this.preferMatrix.length !== 5) {
1145
+ var preferMatrix = this.get('preferMatrix');
1146
+ if (!preferMatrix || preferMatrix.length !== 5) {
1022
1147
  // menu-picker default re-position rule :
1023
1148
  // perfect bottom (3) > perfect right (0) > perfect left (1) > perfect top (2)
1024
1149
  // fallback to perfect bottom (3)
@@ -1083,7 +1208,11 @@ SC.PickerPane = SC.PalettePane.extend(
1083
1208
  windowSizeDidChange: function (oldSize, newSize) {
1084
1209
  sc_super();
1085
1210
 
1086
- if (this.repositionOnWindowResize) { this.positionPane(); }
1211
+ if (this.repositionOnWindowResize) {
1212
+ // Do this in the next run loop. This ensures that positionPane is only called once even if scroll view
1213
+ // offsets are changing at the same time as the window is resizing (see _scrollOffsetDidChange below).
1214
+ this.invokeNext(this.positionPane);
1215
+ }
1087
1216
  },
1088
1217
 
1089
1218
  remove: function () {
@@ -1092,9 +1221,6 @@ SC.PickerPane = SC.PalettePane.extend(
1092
1221
  }
1093
1222
  this._removeScrollObservers();
1094
1223
 
1095
- // Stop observing the frame for changes.
1096
- this.removeObserver('borderFrame', this.borderFrameDidChange);
1097
-
1098
1224
  return sc_super();
1099
1225
  },
1100
1226
 
@@ -1144,109 +1270,144 @@ SC.PickerPane = SC.PalettePane.extend(
1144
1270
  _setupScrollObservers: function (anchorView) {
1145
1271
  var scrollView = this._getScrollViewOfView(anchorView);
1146
1272
  if (scrollView) {
1273
+ scrollView.addObserver('canScrollHorizontal', this, this._scrollCanScrollHorizontalDidChange);
1274
+ scrollView.addObserver('canScrollVertical', this, this._scrollCanScrollVerticalDidChange);
1275
+
1276
+ // Fire the observers once to initialize them.
1277
+ this._scrollCanScrollHorizontalDidChange(scrollView);
1278
+ this._scrollCanScrollVerticalDidChange(scrollView);
1279
+
1280
+ this._scrollView = scrollView;
1281
+ }
1282
+ },
1283
+
1284
+ /** @private Modify horizontalScrollOffset observer. */
1285
+ _scrollCanScrollHorizontalDidChange: function (scrollView) {
1286
+ if (scrollView.get('canScrollHorizontal')) {
1147
1287
  scrollView.addObserver('horizontalScrollOffset', this, this._scrollOffsetDidChange);
1288
+ } else {
1289
+ scrollView.removeObserver('horizontalScrollOffset', this, this._scrollOffsetDidChange);
1290
+ }
1291
+ },
1292
+
1293
+ /** @private Modify verticalScrollOffset observer. */
1294
+ _scrollCanScrollVerticalDidChange: function (scrollView) {
1295
+ if (scrollView.get('canScrollVertical')) {
1148
1296
  scrollView.addObserver('verticalScrollOffset', this, this._scrollOffsetDidChange);
1149
- this._scrollView = scrollView;
1297
+ } else {
1298
+ scrollView.removeObserver('verticalScrollOffset', this, this._scrollOffsetDidChange);
1150
1299
  }
1151
1300
  },
1152
1301
 
1153
- /** @private
1154
- Teardown observers setup in _setupScrollObservers.
1155
- */
1302
+ /** @private Teardown observers setup in _setupScrollObservers. */
1156
1303
  _removeScrollObservers: function () {
1157
1304
  var scrollView = this._scrollView;
1158
1305
  if (scrollView) {
1306
+ scrollView.removeObserver('canScrollHorizontal', this, this._scrollCanScrollHorizontalDidChange);
1307
+ scrollView.removeObserver('canScrollVertical', this, this._scrollCanScrollVerticalDidChange);
1159
1308
  scrollView.removeObserver('horizontalScrollOffset', this, this._scrollOffsetDidChange);
1160
1309
  scrollView.removeObserver('verticalScrollOffset', this, this._scrollOffsetDidChange);
1161
1310
  }
1162
1311
  },
1163
1312
 
1164
- /** @private
1165
- Reposition pane whenever scroll offsets change.
1166
- */
1313
+ /** @private Reposition pane whenever scroll offsets change. */
1167
1314
  _scrollOffsetDidChange: function () {
1168
- this.positionPane();
1315
+ // Filter the observer firing. We don't want to reposition multiple times if both horizontal and vertical
1316
+ // scroll offsets are updating.
1317
+ // Note: do this *after* the current run loop finishes. This allows the scroll view to scroll to
1318
+ // actually move so that the anchor's position is correct before we reposition.
1319
+ this.invokeNext(this.positionPane);
1320
+ },
1321
+
1322
+ /** @private SC.Object */
1323
+ init: function () {
1324
+ sc_super();
1325
+
1326
+ // Set defaults that can only be configured on initialization.
1327
+ if (!this.windowPadding) { this.windowPadding = SC.PickerPane.WINDOW_PADDING; }
1328
+ },
1329
+
1330
+ /** @private SC.Object */
1331
+ destroy: function () {
1332
+ this._scrollView = null;
1333
+ this._anchorView = null;
1334
+ this._anchorHTMLElement = null;
1335
+ return sc_super();
1169
1336
  }
1170
1337
  });
1171
1338
 
1172
- /**
1173
- Default metrics for the different control sizes.
1174
- */
1175
1339
 
1176
- /** @static */
1177
- SC.PickerPane.WINDOW_PADDING = 20;
1340
+ /** Class methods. */
1341
+ SC.PickerPane.mixin( /** @scope SC.PickerPane */ {
1178
1342
 
1179
- /** @static */
1180
- SC.PickerPane.TINY_MENU_WINDOW_PADDING = 12;
1343
+ //---------------------------------------------------------------------------
1344
+ // Constants
1345
+ //
1181
1346
 
1182
- /** @static */
1183
- SC.PickerPane.SMALL_MENU_WINDOW_PADDING = 11;
1347
+ /** @static */
1348
+ WINDOW_PADDING: 20,
1184
1349
 
1185
- /** @static */
1186
- SC.PickerPane.REGULAR_MENU_WINDOW_PADDING = 12;
1350
+ /** @static */
1351
+ TINY_MENU_WINDOW_PADDING: 12,
1187
1352
 
1188
- /** @static */
1189
- SC.PickerPane.LARGE_MENU_WINDOW_PADDING = 17;
1353
+ /** @static */
1354
+ SMALL_MENU_WINDOW_PADDING: 11,
1190
1355
 
1191
- /** @static */
1192
- SC.PickerPane.HUGE_MENU_WINDOW_PADDING = 12;
1356
+ /** @static */
1357
+ REGULAR_MENU_WINDOW_PADDING: 12,
1193
1358
 
1194
- /** @deprecated Version 1.10. Use SC.PickerPane.WINDOW_PADDING.
1195
- @static
1196
- */
1197
- SC.PickerPane.PICKER_EXTRA_RIGHT_OFFSET = 20;
1359
+ /** @static */
1360
+ LARGE_MENU_WINDOW_PADDING: 17,
1198
1361
 
1199
- /** @deprecated Version 1.10. Use SC.PickerPane.TINY_MENU_WINDOW_PADDING.
1200
- @static
1201
- */
1202
- SC.PickerPane.TINY_PICKER_MENU_EXTRA_RIGHT_OFFSET = 12;
1362
+ /** @static */
1363
+ HUGE_MENU_WINDOW_PADDING: 12,
1203
1364
 
1204
- /** @deprecated Version 1.10. Use SC.PickerPane.SMALL_MENU_WINDOW_PADDING.
1205
- @static
1206
- */
1207
- SC.PickerPane.SMALL_PICKER_MENU_EXTRA_RIGHT_OFFSET = 11;
1365
+ /** @static */
1366
+ PICKER_POINTER_OFFSET: [9, -9, -18, 18],
1208
1367
 
1209
- /** @deprecated Version 1.10. Use SC.PickerPane.REGULAR_MENU_WINDOW_PADDING.
1210
- @static
1211
- */
1212
- SC.PickerPane.REGULAR_PICKER_MENU_EXTRA_RIGHT_OFFSET = 12;
1368
+ /** @static */
1369
+ TINY_PICKER_MENU_POINTER_OFFSET: [9, -9, -18, 18],
1213
1370
 
1214
- /** @deprecated Version 1.10. Use SC.PickerPane.LARGE_MENU_WINDOW_PADDING.
1215
- @static
1216
- */
1217
- SC.PickerPane.LARGE_PICKER_MENU_EXTRA_RIGHT_OFFSET = 17;
1371
+ /** @static */
1372
+ SMALL_PICKER_MENU_POINTER_OFFSET: [9, -9, -8, 8],
1218
1373
 
1219
- /** @deprecated Version 1.10. Use SC.PickerPane.HUGE_MENU_WINDOW_PADDING.
1220
- @static
1221
- */
1222
- SC.PickerPane.HUGE_PICKER_MENU_EXTRA_RIGHT_OFFSET = 12;
1374
+ /** @static */
1375
+ REGULAR_PICKER_MENU_POINTER_OFFSET: [9, -9, -12, 12],
1223
1376
 
1224
- /**
1225
- @static
1226
- */
1227
- SC.PickerPane.PICKER_POINTER_OFFSET = [9, -9, -18, 18];
1377
+ /** @static */
1378
+ LARGE_PICKER_MENU_POINTER_OFFSET: [9, -9, -16, 16],
1228
1379
 
1229
- /**
1230
- @static
1231
- */
1232
- SC.PickerPane.TINY_PICKER_MENU_POINTER_OFFSET = [9, -9, -18, 18];
1380
+ /** @static */
1381
+ HUGE_PICKER_MENU_POINTER_OFFSET: [9, -9, -18, 18],
1233
1382
 
1234
- /**
1235
- @static
1236
- */
1237
- SC.PickerPane.SMALL_PICKER_MENU_POINTER_OFFSET = [9, -9, -8, 8];
1383
+ /** @deprecated Version 1.10. Use SC.PickerPane.WINDOW_PADDING.
1384
+ @static
1385
+ */
1386
+ PICKER_EXTRA_RIGHT_OFFSET: 20,
1238
1387
 
1239
- /**
1240
- @static
1241
- */
1242
- SC.PickerPane.REGULAR_PICKER_MENU_POINTER_OFFSET = [9, -9, -12, 12];
1388
+ /** @deprecated Version 1.10. Use SC.PickerPane.TINY_MENU_WINDOW_PADDING.
1389
+ @static
1390
+ */
1391
+ TINY_PICKER_MENU_EXTRA_RIGHT_OFFSET: 12,
1243
1392
 
1244
- /**
1245
- @static
1246
- */
1247
- SC.PickerPane.LARGE_PICKER_MENU_POINTER_OFFSET = [9, -9, -16, 16];
1393
+ /** @deprecated Version 1.10. Use SC.PickerPane.SMALL_MENU_WINDOW_PADDING.
1394
+ @static
1395
+ */
1396
+ SMALL_PICKER_MENU_EXTRA_RIGHT_OFFSET: 11,
1248
1397
 
1249
- /**
1250
- @static
1251
- */
1252
- SC.PickerPane.HUGE_PICKER_MENU_POINTER_OFFSET = [9, -9, -18, 18];
1398
+ /** @deprecated Version 1.10. Use SC.PickerPane.REGULAR_MENU_WINDOW_PADDING.
1399
+ @static
1400
+ */
1401
+ REGULAR_PICKER_MENU_EXTRA_RIGHT_OFFSET: 12,
1402
+
1403
+ /** @deprecated Version 1.10. Use SC.PickerPane.LARGE_MENU_WINDOW_PADDING.
1404
+ @static
1405
+ */
1406
+ LARGE_PICKER_MENU_EXTRA_RIGHT_OFFSET: 17,
1407
+
1408
+ /** @deprecated Version 1.10. Use SC.PickerPane.HUGE_MENU_WINDOW_PADDING.
1409
+ @static
1410
+ */
1411
+ HUGE_PICKER_MENU_EXTRA_RIGHT_OFFSET: 12
1412
+
1413
+ });