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
@@ -17,13 +17,18 @@ SC.Pane.reopen({
17
17
  var responder = (this.rootResponder = SC.RootResponder.responder);
18
18
  responder.panes.add(this);
19
19
 
20
+ // Update the currentWindowSize cache.
21
+ this.set('currentWindowSize', responder.currentWindowSize);
22
+
20
23
  // Legacy.
21
24
  this.set('isPaneAttached', YES);
22
25
  this.paneDidAttach();
23
26
 
24
27
  // Legacy?
25
28
  this.recomputeDependentProperties();
26
- this.set('currentWindowSize', responder.currentWindowSize);
29
+
30
+ // Set the initial design mode. The responder will update this if it changes.
31
+ this.updateDesignMode(this.get('designMode'), responder.get('currentDesignMode'));
27
32
 
28
33
  // handle intercept if needed
29
34
  this._addIntercept();
@@ -0,0 +1,59 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore
3
+ // Copyright: @2013 7x7 Software, Inc.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+
7
+ /**
8
+ The SC.ChildViewLayoutProtocol defines the expected and optional properties
9
+ and methods to implement in your own child view layout plugin.
10
+ */
11
+ SC.ChildViewLayoutProtocol = {
12
+
13
+ /**
14
+ An *optional* array of properties that should be observed on the child views in order
15
+ to re-lay out the child views when changes occur. For example, most child
16
+ view layout plugins will want to adjust the layout of the views whenever
17
+ any view is hidden or becomes visible. Therefore, the parent view should
18
+ re-run the child view layout whenever any child view's `isVisible` property
19
+ changes and thus, `childLayoutProperties` should include at least the
20
+ `isVisible` property name.
21
+
22
+ For another example, the included stack child layout plugins both have the
23
+ same `childLayoutProperties` defined:
24
+
25
+ childLayoutProperties: ['marginBefore', 'marginAfter', 'isVisible']
26
+
27
+ @type Array
28
+ */
29
+ childLayoutProperties: null,
30
+
31
+ /**
32
+ This *optional* method will be called when the view initializes itself. By
33
+ returning `true` from this call, we would be indicating that whenever the
34
+ view's size changes, it should re-lay out the child views.
35
+
36
+ For instance, if the layout of the child views depends on the parent view's
37
+ size, we should return `true`. If the layout of the child views is
38
+ independent of the parent view's size, we can return false to improve
39
+ performance.
40
+
41
+ @param {SC.View} view The view that is using this plugin.
42
+ @returns {Boolean} `true` if the view's size should be observed in order to re-lay out the child views.
43
+ */
44
+ layoutDependsOnSize: function (view) {},
45
+
46
+ /**
47
+ This *required* method will be called by the view each time that it needs
48
+ to re-lay out its child views. The plugin should then as efficiently as
49
+ possible, calculate each child views' new layout and call adjust on the
50
+ child views.
51
+
52
+ For code examples, see SC.View.VERTICAL_STACK and SC.View.HORIZONTAL_STACK
53
+ in the core foundation framework.
54
+
55
+ @param {SC.View} view The view that is using this plugin.
56
+ */
57
+ layoutChildViews: function (view) {}
58
+
59
+ };
@@ -43,6 +43,23 @@ SC.ViewTransitionProtocol = {
43
43
  @param {Object} finalLayout The final layout of the view, which may be different than the starting layout of the view if a previous transition was cancelled in place.
44
44
  @param {Object} finalFrame The final frame of the view, which may be different than the starting frame of the view if a previous transition was cancelled in place.
45
45
  */
46
- run: function (view, options, finalLayout, finalFrame) {}
46
+ run: function (view, options, finalLayout, finalFrame) {},
47
+
48
+
49
+ /**
50
+ This optional property exposes a list of layout properties involved in the
51
+ transition. This allows the view to more intelligently reset its layout when
52
+ the transition is complete.
53
+
54
+ If unspecified, the transition will cache and reset the entire layout hash. This
55
+ can cause problems when spearately adjusting or animating those properties during
56
+ a transition. (Note that you should not adjust or animate the layout properties
57
+ that are involved in a transition while the transition is under way.)
58
+
59
+ @field
60
+ @type Array
61
+ @default All layout properties
62
+ */
63
+ layoutProperties: []
47
64
 
48
65
  };
@@ -4,6 +4,8 @@
4
4
  // Portions ©2008-2011 Apple Inc. All rights reserved.
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
+ sc_require('system/root_responder');
8
+
7
9
 
8
10
  /** @class
9
11
 
@@ -25,4 +27,194 @@
25
27
  SC.Application = SC.Responder.extend(SC.ResponderContext,
26
28
  /** SC.Application.prototype */ {
27
29
 
30
+ /** @private UNUSED
31
+ The current design mode of the application and its views.
32
+
33
+ If the application has designModes specified, this property will be set
34
+ automatically as the window size changes across the design mode boundaries.
35
+
36
+ @property {String}
37
+ @default null
38
+ */
39
+ // designMode: null,
40
+
41
+ /**
42
+ A hash of the design mode thresholds for this application.
43
+
44
+ While a "design" (the manner views are positioned, shaped and styled) may be
45
+ flexible enough to stretch up for a large display and to compress down
46
+ for a medium sized display, at a certain point it often makes more sense
47
+ to stop stretching and compressing and just implement an additional new design
48
+ specific to the much different display size. In order to make this possible
49
+ and with as much ease as possible, SproutCore includes support for "design
50
+ modes". Design modes are based on the current display size and orientation.
51
+
52
+ SproutCore supports three size-based design modes by default: 's' for small,
53
+ 'm' for medium and 'l' for large. Smartphones and handheld devices like the
54
+ iPod Touch fall within the small category, tablets and normal desktop displays
55
+ fall within the medium category and retina desktops or 4K displays fall
56
+ into the large category.
57
+
58
+ When the display size crosses a threshold between one size category to
59
+ another, SproutCore will update the design mode of each view in the
60
+ application, giving you a chance to provide overrides for that specific
61
+ size via the special `modeAdjust` property.
62
+
63
+ For example, if you wanted to hide a view completely when in the small (s)
64
+ mode you could add:
65
+
66
+ //...
67
+
68
+ mediumPlusView: SC.View.extend({
69
+
70
+ // Design mode overrides.
71
+ modeAdjust: { s: { isVisible: false } } // Hide the view in 's' or 'small' mode.
72
+
73
+ }),
74
+
75
+ //...
76
+
77
+ As you can see, we simply indicate the property overrides that we want
78
+ for the specific mode. To adjust the height for medium mode, you could add:
79
+
80
+ //...
81
+
82
+ myView: SC.View.extend({
83
+
84
+ // The normal layout always applies.
85
+ layout: { height: 24 },
86
+
87
+ // Design mode overrides.
88
+ modeAdjust: { m: { layout: { height: 30 } } // Adjust the height in 'm' or 'medium' mode.
89
+
90
+ }),
91
+
92
+ //...
93
+
94
+ Note that the values in `modeAdjust` are overrides for that mode and the
95
+ values will be *reset* to their original values when leaving that mode.
96
+
97
+ The second component to design modes is orientation. Each of the size
98
+ categories can have two different orientations: 'l' for landscape or 'p' for
99
+ portrait. Therefore, you may want to alter the design to account for the
100
+ device orientation as well using `modeAdjust`. To do this, you simply
101
+ specify orientation specific designs with the `_l` or `_p` suffix
102
+ accordingly.
103
+
104
+ For example, you can provide a configuration for a size category with
105
+ slight deviations for orientations of that size all in just a few lines
106
+ of code,
107
+
108
+ //...
109
+
110
+ customView: SC.View.extend({
111
+
112
+ // The default alignment for this custom view's contents.
113
+ alignment: SC.ALIGN_LEFT,
114
+
115
+ // The default line height for this custom view's contents.
116
+ lineHeight: 40,
117
+
118
+ // Design mode overrides.
119
+ modeAdjust: {
120
+ m: { lineHeight: 50 }, // Overrides for medium mode regardless of orientation.
121
+ m_p: { alignment: SC.ALIGN_CENTER }, // Overrides for medium - portrait mode.
122
+ m_l: { layout: { top: 20 } } // Overrides for medium - landscape mode.
123
+ }
124
+
125
+ }),
126
+
127
+ //...
128
+
129
+ ### A note on styling for design modes
130
+
131
+ Class names are automatically applied to each view depending on the mode
132
+ as found in the SC.DESIGN_MODE_CLASS_NAMES hash. By default, your
133
+ views will have one of three class names added:
134
+
135
+ > 'sc-small' in small mode
136
+ > 'sc-medium' in medium mode
137
+ > 'sc-large' in large mode
138
+
139
+ As well, the `body` element is given an orientation class name that you
140
+ can use as well:
141
+
142
+ > 'sc-landscape' in landscape orientation
143
+ > 'sc-portrait' in portrait orientation
144
+
145
+ ### A note on overriding layouts
146
+
147
+ Layout overrides work slightly differently than regular property overrides,
148
+ because they are set via `adjust`. This means they apply on *top* of the
149
+ default layout, they don't replace the default layout. For example,
150
+ the default layout is `{ left: 0, right: 0, top: 0, bottom: 0 }` and if
151
+ we provide a design mode like,
152
+
153
+ modeAdjust: { l: { layout: { top: 50 } } }
154
+
155
+ The layout becomes `{ left: 0, right: 0, top: 50, bottom: 0 }`. If we had
156
+ a default layout like `{ centerX: 0, centerY: 0, height: 100, width: 100 }`
157
+ and we wanted to change it to a left positioned layout, we would need to
158
+ null out the centerX value like so,
159
+
160
+ modeAdjust: { l: { layout: { centerX: null, left: 0 } } } // Convert to left positioned layout.
161
+
162
+ ### A note on the medium category
163
+
164
+ The medium category covers tablets *and* non-retina desktops and laptops.
165
+ While we could try to further differentiate between these two categories,
166
+ there is no safe way to do this and to do so would cause more harm than good.
167
+ Tablets can be connected to mice and keyboards, desktops can have touch
168
+ screens and there is no way to know whether a mouse, touch or pointer is
169
+ going to be used from one event to the next. Therefore the message should
170
+ be clear, *you should always design for touch*. This means that a medium
171
+ sized design should be expected to work well on a laptop and a tablet.
172
+
173
+ ### A note on customizing the design mode categories
174
+
175
+ Design mode thresholds are determined by the area of the display divided by
176
+ the device pixel ratio. In this manner a 1024 x 768 display on a
177
+ handheld device can be differentiated from a 1024 x 768 display on a
178
+ desktop. Through testing and research, the three categories of 'small',
179
+ 'medium' and 'large' were chosen with thresholds between them of
180
+ 500,000 sq.px and 2,000,000 sq.px.
181
+
182
+ Therefore, any display area divided by device pixel ratio that is less
183
+ than 500,000 will be considered 'small' and likewise a calculated area
184
+ of over 2,000,000 will be considered 'large'. This should be sufficient
185
+ for almost all device specific designs and as is mentioned earlier,
186
+ trying to get even more fine-grained is a dangerous endeavor. However,
187
+ you can set your own thresholds easily enough by overriding this property.
188
+
189
+ @readonly
190
+ @property {Object}
191
+ @default { s: 500000, m: 2000000, l: Infinity }
192
+ */
193
+ designModes: {
194
+ 's': 500000, // ex. smart phone display
195
+ 'm': 2000000, // ex. tablet & non-retina desktop display
196
+ 'l': Infinity // ex. retina desktop display and TV
197
+ },
198
+
199
+ /** @private */
200
+ init: function () {
201
+ sc_super();
202
+
203
+ // Initialize the value on the RootResponder when it is ready.
204
+ SC.ready(this, '_setDesignModes');
205
+ },
206
+
207
+ /** @private */
208
+ _setDesignModes: function () {
209
+ var designModes = this.get('designModes'),
210
+ responder = SC.RootResponder.responder;
211
+
212
+ if (designModes) {
213
+ // All we do is pass the value to the root responder for convenience.
214
+ responder.set('designModes', designModes);
215
+ // UNUSED.
216
+ // this.bind('designMode', SC.Binding.from('SC.RootResponder.responder.currentDesignMode'));
217
+ }
218
+ }
219
+
28
220
  });
@@ -0,0 +1,52 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2014 7x7 Software Inc. All rights reserved.
4
+ // Portions ©2008-2011 Apple Inc. All rights reserved.
5
+ // License: Licensed under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+ /** @private Kept private until fully fleshed out.
9
+ A cubic bezier equation. Used by the SC.easingCurve function.
10
+ */
11
+ SC.CubicBezierEquation = function (C1, C2, C3, C4) {
12
+
13
+ var B1 = function (t) { return (1 - t) * (1 - t) * (1 - t); };
14
+ var B2 = function (t) { return 3 * t * (1 - t) * (1 - t); };
15
+ var B3 = function (t) { return 3 * t * t * (1 - t); };
16
+ var B4 = function (t) { return t * t * t; };
17
+
18
+ this.position = function (percent) {
19
+ var pos = {};
20
+
21
+ pos.x = C1.x * B1(percent) + C2.x * B2(percent) + C3.x * B3(percent) + C4.x * B4(percent);
22
+ pos.y = C1.y * B1(percent) + C2.y * B2(percent) + C3.y * B3(percent) + C4.y * B4(percent);
23
+
24
+ return pos;
25
+ };
26
+
27
+ };
28
+
29
+ /** @private Kept private until fully fleshed out (name change?).
30
+ A specialized bezier curve with fixed start at 0,0 and fixed end at 1,1.
31
+
32
+ */
33
+ SC.easingCurve = function (C2x, C2y, C3x, C3y) {
34
+
35
+ var C1 = { x: 0, y: 0 },
36
+ C2 = { x: C2x, y: C2y },
37
+ C3 = { x: C3x, y: C3y },
38
+ C4 = { x: 1, y: 1 };
39
+
40
+ var equation = new SC.CubicBezierEquation(C1, C2, C3, C4);
41
+
42
+ equation.value = function (percent) {
43
+ percent = Math.max(0, Math.min(percent, 1));
44
+ return this.position(percent).y;
45
+ };
46
+
47
+ equation.toString = function () {
48
+ return "cubic-bezier(%@, %@, %@, %@)".fmt(C2x, C2y, C3x, C3y);
49
+ };
50
+
51
+ return equation;
52
+ };
@@ -6,19 +6,137 @@
6
6
  // ==========================================================================
7
7
 
8
8
  /** @class
9
- Provides colorspace conversions between rgb and hsl.
10
-
11
- This object can be instantiated by using `create`
12
- if it's a simple RGB color, or through `SC.Color.from`,
13
- which will turn any valid CSS color into it's
14
- appropriate SC.Color.
15
-
16
- To get the CSS value of the color, call `toCSS`,
17
- which will provide the best CSS color to use
18
- according to browser support. This means that
19
- in IE, colors with an alpha channel will fall
20
- back to use ARGB, which requires the following
21
- hack to use:
9
+ Represents a color, and provides methods for manipulating it. Maintains underlying
10
+ rgba values, and includes support for colorspace conversions between rgb and hsl.
11
+
12
+ For instructions on using SC.Color to color a view, see "SC.Color and SC.View"
13
+ below.
14
+
15
+ ### Basic Use
16
+
17
+ You can create a color from red, green, blue and alpha values, with:
18
+
19
+ SC.Color.create({
20
+ r: 255,
21
+ g: 255,
22
+ b: 255,
23
+ a: 0.5
24
+ });
25
+
26
+ All values are optional; the default is black. You can also create a color from any
27
+ valid CSS string, with:
28
+
29
+ SC.Color.from('rgba(255, 255, 255, 0.5)');
30
+
31
+ The best CSS value for the given color in the current browser is available at the
32
+ bindable property `cssText`. (This will provide deprecated ARGB values for older
33
+ versions of IE; see "Edge Case: Supporting Alpha in IE" below.) (Calling
34
+ `SC.Color.from` with an undefined or null value is equivalent to calling it with
35
+ `'transparent'`.)
36
+
37
+ Once created, you can manipulate a color by settings its a, r, g or b values,
38
+ or setting its cssText value (though be careful of invalid values; see "Error
39
+ State" below).
40
+
41
+ ### Math
42
+
43
+ `SC.Color` provides three methods for performing basic math: `sub` for subtraction,
44
+ `add` for addition, and `mult` for scaling a number via multiplication.
45
+
46
+ Note that these methods do not perform any validation to ensure that the underlying
47
+ rgba values stay within the device's gamut (0 to 255 on a normal screen, and 0 to 1
48
+ for alpha). For example, adding white to white will result in r, g and b values of
49
+ 510, a nonsensical value. (The `cssText` property will, however, correctly clamp the
50
+ component values, and the color will output `#FFFFFF`.) This behavior is required
51
+ for operations such as interpolating between colors (see "SC.Color and SC.View"
52
+ below); it also gives SC.Color more predictable math, where A + B - B = A, even if
53
+ the intermediate (A + B) operation results in underlying values outside of the normal
54
+ gamut.
55
+
56
+ (The class method `SC.Color.clampToDeviceGamut` is used to clamp r, g and b values to the
57
+ standard 0 - 255 range. If your application is displaying on a screen with non-standard
58
+ ranges, you may need to override this method.)
59
+
60
+ ### SC.Color and SC.View
61
+
62
+ Hooking up an instance of SC.Color to SC.View#backgroundColor is simple, but like all
63
+ uses of backgroundColor, it comes with moderate performance implications, and should
64
+ be avoided in cases where regular CSS is sufficient, or where bindings are unduly
65
+ expensive, such as in rapidly-scrolling ListViews.
66
+
67
+ Use the following code to tie a view's background color to an instance of SC.Color. Note
68
+ that you must add backgroundColor to displayProperties in order for your view to update
69
+ when the it changes; for performance reasons it is not included by default.
70
+
71
+ SC.View.extend({
72
+ color: SC.Color.from({'burlywood'}),
73
+ backgroundColorBinding: SC.Binding.oneWay('*color.cssText'),
74
+ displayProperties: ['backgroundColor']
75
+ })
76
+
77
+ You can use this to implement a simple cross-fade between two colors. Here's a basic
78
+ example (again, note that when possible, pure CSS transitions will be substantially
79
+ more performant):
80
+
81
+ SC.View.extend({
82
+ displayProperties: ['backgroundColor'],
83
+ backgroundColor: 'cadetblue',
84
+ fromColor: SC.Color.from('cadetblue'),
85
+ toColor: SC.Color.from('springgreen'),
86
+ click: function() {
87
+ // Cancel previous timer.
88
+ if (this._timer) this._timer.invalidate();
89
+ // Figure out whether we're coming or going.
90
+ this._forward = !this._forward;
91
+ // Calculate the difference between the two colors.
92
+ var fromColor = this._forward ? this.fromColor : this.toColor,
93
+ toColor = this._forward ? this.toColor : this.fromColor;
94
+ this._deltaColor = toColor.sub(fromColor);
95
+ // Set the timer.
96
+ this._timer = SC.Timer.schedule({
97
+ target: this,
98
+ action: '_tick',
99
+ interval: 15,
100
+ repeats: YES,
101
+ until: Date.now() + 500
102
+ });
103
+ },
104
+ _tick: function() {
105
+ // Calculate percent of time elapsed.
106
+ var started = this._timer.startTime,
107
+ now = Date.now(),
108
+ until = this._timer.until,
109
+ pct = (now - started) / (until - started);
110
+ // Constrain pct.
111
+ pct = Math.min(pct, 1);
112
+ // Calculate color.
113
+ var fromColor = this._forward ? this.fromColor : this.toColor,
114
+ toColor = this._forward ? this.toColor : this.fromColor,
115
+ deltaColor = this._deltaColor,
116
+ currentColor = fromColor.add(deltaColor.mult(pct));
117
+ // Set.
118
+ this.set('backgroundColor', currentColor.get('cssText'));
119
+ }
120
+ })
121
+
122
+ ### Error State
123
+
124
+ If you call `SC.Color.from` with an invalid value, or set `cssText` to an invalid
125
+ value, the color object will go into error mode, with `isError` set to YES and
126
+ `errorValue` containing the invalid value that triggered it. A color in error mode
127
+ will become transparent, and you will be unable to modify its r, g, b or a values.
128
+
129
+ To reset a color to its last-good values (or, if none, to black), call its `reset`
130
+ method. Setting `cssText` to a valid value will also recover the color object to a
131
+ non-error state.
132
+
133
+ ### Edge Case: Supporting Alpha in IE
134
+
135
+ Supporting the alpha channel in older versions of IE requires a little extra work.
136
+ The bindable `cssText` property will return valid ARGB (e.g. `#99FFFFFF`) when it
137
+ detects that it's in an older version of IE which requires it, but unfortunately you
138
+ can't simply plug that value into `background-color`. The following code will detect
139
+ this case and provide the correct CSS snippet:
22
140
 
23
141
  // This hack disables ClearType on IE!
24
142
  var color = SC.Color.from('rgba(0, 0, 0, .5)').get('cssText'),
@@ -32,36 +150,18 @@
32
150
  css = "background-color:" + color;
33
151
  }
34
152
 
35
- You may want to use the `sub`, `add`, and `mult`
36
- functions to tween colors between a start and
37
- end color.
38
-
39
- For instance, if we wanted to tween between
40
- the color "blue" and "teal", we would to the following:
41
-
42
- var blue = SC.Color.from("blue"),
43
- teal = SC.Color.from("teal"),
44
- delta = blue.sub(teal);
45
-
46
- // Tick is called using a percent
47
- // between 0 and 1
48
- function tick (t) {
49
- return blue.add(delta.mult(t)).get('cssText');
50
- }
51
-
52
153
  @extends SC.Object
53
154
  @extends SC.Copyable
155
+ @extends SC.Error
54
156
  */
55
157
  SC.Color = SC.Object.extend(
56
158
  SC.Copyable,
57
159
  /** @scope SC.Color.prototype */{
58
160
 
59
161
  /**
60
- The original color string that
61
- this object was created from.
162
+ The original color string from which this object was created.
62
163
 
63
- For example, if you color was
64
- created via `SC.Color.from("burlywood")`,
164
+ For example, if your color was created via `SC.Color.from("burlywood")`,
65
165
  then this would be set to `"burlywood"`.
66
166
 
67
167
  @type String
@@ -69,14 +169,48 @@ SC.Color = SC.Object.extend(
69
169
  */
70
170
  original: null,
71
171
 
172
+ /**
173
+ Whether the color is valid. Attempting to set `cssText` or call `from` with invalid input
174
+ will put the color into an error state until updated with a valid string or reset.
175
+
176
+ @type Boolean
177
+ @default NO
178
+ @see SC.Error
179
+ */
180
+ isError: NO,
181
+
182
+ /**
183
+ In the case of an invalid color, this contains the invalid string that was used to create or
184
+ update it.
185
+
186
+ @type String
187
+ @default null
188
+ @see SC.Error
189
+ */
190
+ errorValue: null,
191
+
72
192
  /**
73
193
  The alpha channel (opacity).
74
- `a` is a percent between 0 and 1.
194
+ `a` is a decimal value between 0 and 1.
75
195
 
76
196
  @type Number
77
197
  @default 1
78
198
  */
79
- a: 1,
199
+ a: function (key, value) {
200
+ // Getter.
201
+ if (value === undefined) {
202
+ return this._a;
203
+ }
204
+ // Setter.
205
+ else {
206
+ if (this.get('isError')) value = this._a;
207
+ this._a = value;
208
+ return value;
209
+ }
210
+ }.property().cacheable(),
211
+
212
+ /** @private */
213
+ _a: 1,
80
214
 
81
215
  /**
82
216
  The red value.
@@ -85,7 +219,21 @@ SC.Color = SC.Object.extend(
85
219
  @type Number
86
220
  @default 0
87
221
  */
88
- r: 0,
222
+ r: function (key, value) {
223
+ // Getter.
224
+ if (value === undefined) {
225
+ return this._r;
226
+ }
227
+ // Setter.
228
+ else {
229
+ if (this.get('isError')) value = this._r;
230
+ this._r = value;
231
+ return value;
232
+ }
233
+ }.property().cacheable(),
234
+
235
+ /** @private */
236
+ _r: 0,
89
237
 
90
238
  /**
91
239
  The green value.
@@ -94,7 +242,21 @@ SC.Color = SC.Object.extend(
94
242
  @type Number
95
243
  @default 0
96
244
  */
97
- g: 0,
245
+ g: function (key, value) {
246
+ // Getter.
247
+ if (value === undefined) {
248
+ return this._g;
249
+ }
250
+ // Setter.
251
+ else {
252
+ if (this.get('isError')) value = this._g;
253
+ this._g = value;
254
+ return value;
255
+ }
256
+ }.property().cacheable(),
257
+
258
+ /** @private */
259
+ _g: 0,
98
260
 
99
261
  /**
100
262
  The blue value.
@@ -103,7 +265,21 @@ SC.Color = SC.Object.extend(
103
265
  @type Number
104
266
  @default 0
105
267
  */
106
- b: 0,
268
+ b: function (key, value) {
269
+ // Getter.
270
+ if (value === undefined) {
271
+ return this._b;
272
+ }
273
+ // Setter.
274
+ else {
275
+ if (this.get('isError')) value = this._b;
276
+ this._b = value;
277
+ return value;
278
+ }
279
+ }.property().cacheable(),
280
+
281
+ /** @private */
282
+ _b: 0,
107
283
 
108
284
  /**
109
285
  The current hue of this color.
@@ -304,16 +480,86 @@ SC.Color = SC.Object.extend(
304
480
  @field
305
481
  @type String
306
482
  */
307
- cssText: function () {
308
- var supportsAlphaChannel = SC.Color.supportsRgba ||
309
- SC.Color.supportsArgb;
310
- return (this.a === 1 || !supportsAlphaChannel)
311
- ? this.toHex()
312
- : SC.Color.supportsRgba
313
- ? this.toRgba()
314
- : this.toArgb();
483
+ cssText: function (key, value) {
484
+ // Getter.
485
+ if (value === undefined) {
486
+ // FAST PATH: Error.
487
+ if (this.get('isError')) return this.get('errorValue');
488
+
489
+ // FAST PATH: transparent.
490
+ if (this.get('a') === 0) return 'transparent';
491
+
492
+ var supportsAlphaChannel = SC.Color.supportsRgba ||
493
+ SC.Color.supportsArgb;
494
+ return (this.get('a') === 1 || !supportsAlphaChannel)
495
+ ? this.toHex()
496
+ : SC.Color.supportsRgba
497
+ ? this.toRgba()
498
+ : this.toArgb();
499
+ }
500
+ // Setter.
501
+ else {
502
+ var hash = SC.Color._parse(value);
503
+ this.beginPropertyChanges();
504
+ // Error state
505
+ if (!hash) {
506
+ // Cache current value for recovery.
507
+ this._lastValidHash = { r: this._r, g: this._g, b: this._b, a: this._a };
508
+ this.set('r', 0);
509
+ this.set('g', 0);
510
+ this.set('b', 0);
511
+ this.set('a', 0);
512
+ this.set('errorValue', value);
513
+ this.set('isError', YES);
514
+ }
515
+ // Happy state
516
+ else {
517
+ this.setIfChanged('isError', NO);
518
+ this.setIfChanged('errorValue', null);
519
+ this.set('r', hash.r);
520
+ this.set('g', hash.g);
521
+ this.set('b', hash.b);
522
+ this.set('a', hash.a);
523
+ }
524
+ this.endPropertyChanges();
525
+ return value;
526
+ }
315
527
  }.property('r', 'g', 'b', 'a').cacheable(),
316
528
 
529
+ /**
530
+ A read-only property which always returns a valid CSS property. If the color is in
531
+ an error state, it returns 'transparent'.
532
+
533
+ @field
534
+ @type String
535
+ */
536
+ validCssText: function() {
537
+ if (this.get('isError')) return 'transparent';
538
+ else return this.get('cssText');
539
+ }.property('cssText', 'isError').cacheable(),
540
+
541
+ /**
542
+ Resets an errored color to its last valid color. If the color has never been valid,
543
+ it resets to black.
544
+
545
+ @returns {SC.Color} receiver
546
+ */
547
+ reset: function() {
548
+ // Gatekeep: not in error mode.
549
+ if (!this.get('isError')) return this;
550
+ // Reset the value to the last valid hash, or default black.
551
+ var lastValidHash = this._lastValidHash || { r: 0, g: 0, b: 0, a: 1 };
552
+ this.beginPropertyChanges();
553
+ this.set('isError', NO);
554
+ this.set('errorValue', null);
555
+ this.set('r', lastValidHash.r);
556
+ this.set('g', lastValidHash.g);
557
+ this.set('b', lastValidHash.b);
558
+ this.set('a', lastValidHash.a);
559
+ this.endPropertyChanges();
560
+ return this;
561
+ },
562
+
317
563
  /**
318
564
  Returns a clone of this color.
319
565
  This will always a deep clone.
@@ -326,7 +572,9 @@ SC.Color = SC.Object.extend(
326
572
  r: this.get('r'),
327
573
  g: this.get('g'),
328
574
  b: this.get('b'),
329
- a: this.get('a')
575
+ a: this.get('a'),
576
+ isError: this.get('isError'),
577
+ errorValue: this.get('errorValue')
330
578
  });
331
579
  },
332
580
 
@@ -343,14 +591,16 @@ SC.Color = SC.Object.extend(
343
591
  r: this.get('r') - color.get('r'),
344
592
  g: this.get('g') - color.get('g'),
345
593
  b: this.get('b') - color.get('b'),
346
- a: this.get('a') - color.get('a')
594
+ a: this.get('a') - color.get('a'),
595
+ isError: this.get('isError') || color.get('isError')
347
596
  });
348
597
  },
349
598
 
350
599
  /**
351
- Returns a color that's the addition of two colors.
600
+ Returns a new color that's the addition of two colors.
352
601
 
353
- Note that the result might not be a valid CSS color.
602
+ Note that the resulting a, r, g and b values are not clamped to within valid
603
+ ranges.
354
604
 
355
605
  @param {SC.Color} color The color to add to this one.
356
606
  @returns {SC.Color} The addition of the two colors.
@@ -360,7 +610,8 @@ SC.Color = SC.Object.extend(
360
610
  r: this.get('r') + color.get('r'),
361
611
  g: this.get('g') + color.get('g'),
362
612
  b: this.get('b') + color.get('b'),
363
- a: this.get('a') + color.get('a')
613
+ a: this.get('a') + color.get('a'),
614
+ isError: this.get('isError')
364
615
  });
365
616
  },
366
617
 
@@ -379,7 +630,8 @@ SC.Color = SC.Object.extend(
379
630
  r: round(this.get('r') * multiplier),
380
631
  g: round(this.get('g') * multiplier),
381
632
  b: round(this.get('b') * multiplier),
382
- a: this.get('a') * multiplier
633
+ a: this.get('a') * multiplier,
634
+ isError: this.get('isError')
383
635
  });
384
636
  }
385
637
  });
@@ -387,6 +639,38 @@ SC.Color = SC.Object.extend(
387
639
  SC.Color.mixin(
388
640
  /** @scope SC.Color */{
389
641
 
642
+ /** @private Overrides create to support creation with {a, r, g, b} hash. */
643
+ create: function() {
644
+ var args = SC.A(arguments),
645
+ len = args.length,
646
+ vals = {},
647
+ hasVals = NO,
648
+ keys = ['a', 'r', 'g', 'b'],
649
+ hash, i, k, key;
650
+ // Loop through all arguments. If any of them contain numeric a, r, g or b arguments,
651
+ // clone the hash and move the value from (e.g.) a to _a.
652
+ for (i = 0; i < len; i++) {
653
+ hash = args[i];
654
+ if (SC.typeOf(hash.a) === SC.T_NUMBER
655
+ || SC.typeOf(hash.r) === SC.T_NUMBER
656
+ || SC.typeOf(hash.g) === SC.T_NUMBER
657
+ || SC.typeOf(hash.b) === SC.T_NUMBER
658
+ ) {
659
+ hasVals = YES;
660
+ hash = args[i] = SC.clone(hash);
661
+ for (k = 0; k < 4; k++) {
662
+ key = keys[k];
663
+ if (SC.typeOf(hash[key]) === SC.T_NUMBER) {
664
+ vals['_' + key] = hash[key];
665
+ delete hash[key];
666
+ }
667
+ }
668
+ }
669
+ }
670
+ if (hasVals) args.push(vals);
671
+ return SC.Object.create.apply(this, args);
672
+ },
673
+
390
674
  /**
391
675
  Whether this browser supports the rgba color model.
392
676
  Check courtesy of Modernizr.
@@ -668,13 +952,48 @@ SC.Color.mixin(
668
952
  KEYWORDS: {"aliceblue":"#F0F8FF","antiquewhite":"#FAEBD7","aqua":"#00FFFF","aquamarine":"#7FFFD4","azure":"#F0FFFF","beige":"#F5F5DC","bisque":"#FFE4C4","black":"#000000","blanchedalmond":"#FFEBCD","blue":"#0000FF","blueviolet":"#8A2BE2","brown":"#A52A2A","burlywood":"#DEB887","cadetblue":"#5F9EA0","chartreuse":"#7FFF00","chocolate":"#D2691E","coral":"#FF7F50","cornflowerblue":"#6495ED","cornsilk":"#FFF8DC","crimson":"#DC143C","cyan":"#00FFFF","darkblue":"#00008B","darkcyan":"#008B8B","darkgoldenrod":"#B8860B","darkgray":"#A9A9A9","darkgreen":"#006400","darkgrey":"#A9A9A9","darkkhaki":"#BDB76B","darkmagenta":"#8B008B","darkolivegreen":"#556B2F","darkorange":"#FF8C00","darkorchid":"#9932CC","darkred":"#8B0000","darksalmon":"#E9967A","darkseagreen":"#8FBC8F","darkslateblue":"#483D8B","darkslategray":"#2F4F4F","darkslategrey":"#2F4F4F","darkturquoise":"#00CED1","darkviolet":"#9400D3","deeppink":"#FF1493","deepskyblue":"#00BFFF","dimgray":"#696969","dimgrey":"#696969","dodgerblue":"#1E90FF","firebrick":"#B22222","floralwhite":"#FFFAF0","forestgreen":"#228B22","fuchsia":"#FF00FF","gainsboro":"#DCDCDC","ghostwhite":"#F8F8FF","gold":"#FFD700","goldenrod":"#DAA520","gray":"#808080","green":"#008000","greenyellow":"#ADFF2F","grey":"#808080","honeydew":"#F0FFF0","hotpink":"#FF69B4","indianred":"#CD5C5C","indigo":"#4B0082","ivory":"#FFFFF0","khaki":"#F0E68C","lavender":"#E6E6FA","lavenderblush":"#FFF0F5","lawngreen":"#7CFC00","lemonchiffon":"#FFFACD","lightblue":"#ADD8E6","lightcoral":"#F08080","lightcyan":"#E0FFFF","lightgoldenrodyellow":"#FAFAD2","lightgray":"#D3D3D3","lightgreen":"#90EE90","lightgrey":"#D3D3D3","lightpink":"#FFB6C1","lightsalmon":"#FFA07A","lightseagreen":"#20B2AA","lightskyblue":"#87CEFA","lightslategray":"#778899","lightslategrey":"#778899","lightsteelblue":"#B0C4DE","lightyellow":"#FFFFE0","lime":"#00FF00","limegreen":"#32CD32","linen":"#FAF0E6","magenta":"#FF00FF","maroon":"#800000","mediumaquamarine":"#66CDAA","mediumblue":"#0000CD","mediumorchid":"#BA55D3","mediumpurple":"#9370DB","mediumseagreen":"#3CB371","mediumslateblue":"#7B68EE","mediumspringgreen":"#00FA9A","mediumturquoise":"#48D1CC","mediumvioletred":"#C71585","midnightblue":"#191970","mintcream":"#F5FFFA","mistyrose":"#FFE4E1","moccasin":"#FFE4B5","navajowhite":"#FFDEAD","navy":"#000080","oldlace":"#FDF5E6","olive":"#808000","olivedrab":"#6B8E23","orange":"#FFA500","orangered":"#FF4500","orchid":"#DA70D6","palegoldenrod":"#EEE8AA","palegreen":"#98FB98","paleturquoise":"#AFEEEE","palevioletred":"#DB7093","papayawhip":"#FFEFD5","peachpuff":"#FFDAB9","peru":"#CD853F","pink":"#FFC0CB","plum":"#DDA0DD","powderblue":"#B0E0E6","purple":"#800080","red":"#FF0000","rosybrown":"#BC8F8F","royalblue":"#4169E1","saddlebrown":"#8B4513","salmon":"#FA8072","sandybrown":"#F4A460","seagreen":"#2E8B57","seashell":"#FFF5EE","sienna":"#A0522D","silver":"#C0C0C0","skyblue":"#87CEEB","slateblue":"#6A5ACD","slategray":"#708090","slategrey":"#708090","snow":"#FFFAFA","springgreen":"#00FF7F","steelblue":"#4682B4","tan":"#D2B48C","teal":"#008080","thistle":"#D8BFD8","tomato":"#FF6347","turquoise":"#40E0D0","violet":"#EE82EE","wheat":"#F5DEB3","white":"#FFFFFF","whitesmoke":"#F5F5F5","yellow":"#FFFF00","yellowgreen":"#9ACD32"},
669
953
 
670
954
  /**
671
- Parses a CSS color into a `SC.Color` object.
672
- Any valid CSS color should work here.
955
+ Parses any valid CSS color into a `SC.Color` object. Given invalid input, will return a
956
+ `SC.Color` object in an error state (with isError: YES).
673
957
 
674
- @param {String} color The color to parse into a `SC.Color` object.
958
+ @param {String} color The CSS color value to parse.
675
959
  @returns {SC.Color} The color object representing the color passed in.
676
960
  */
677
961
  from: function (color) {
962
+ // Fast path: clone another color.
963
+ if (SC.kindOf(color, SC.Color)) {
964
+ return color.copy();
965
+ }
966
+
967
+ // Slow path: string
968
+ var hash = SC.Color._parse(color),
969
+ C = SC.Color;
970
+
971
+ // Gatekeep: bad input.
972
+ if (!hash) {
973
+ return SC.Color.create({
974
+ original: color,
975
+ isError: YES
976
+ });
977
+ }
978
+
979
+ return C.create({
980
+ original: color,
981
+ r: C.clampInt(hash.r, 0, 255),
982
+ g: C.clampInt(hash.g, 0, 255),
983
+ b: C.clampInt(hash.b, 0, 255),
984
+ a: C.clamp(hash.a, 0, 1)
985
+ });
986
+ },
987
+
988
+ /** @private
989
+ Parses any valid CSS color into r, g, b and a values. Returns null for invalid inputs.
990
+
991
+ For internal use only. External code should call `SC.Color.from` or `SC.Color#cssText`.
992
+
993
+ @param {String} color The CSS color value to parse.
994
+ @returns {Hash || null} A hash of r, g, b, and a values.
995
+ */
996
+ _parse: function (color) {
678
997
  var C = SC.Color,
679
998
  oColor = color,
680
999
  r, g, b, a = 1,
@@ -687,6 +1006,8 @@ SC.Color.mixin(
687
1006
 
688
1007
  if (C.KEYWORDS.hasOwnProperty(color)) {
689
1008
  color = C.KEYWORDS[color];
1009
+ } else if (SC.none(color) || color === '') {
1010
+ color = 'transparent';
690
1011
  }
691
1012
 
692
1013
  if (C.PARSE_RGB.test(color)) {
@@ -755,15 +1076,14 @@ SC.Color.mixin(
755
1076
  a = 0;
756
1077
 
757
1078
  } else {
758
- return NO;
1079
+ return null;
759
1080
  }
760
1081
 
761
- return SC.Color.create({
762
- original: oColor,
763
- r: C.clampInt(r, 0, 255),
764
- g: C.clampInt(g, 0, 255),
765
- b: C.clampInt(b, 0, 255),
766
- a: C.clamp(a, 0, 1)
767
- });
1082
+ return {
1083
+ r: r,
1084
+ g: g,
1085
+ b: b,
1086
+ a: a
1087
+ };
768
1088
  }
769
1089
  });