sproutcore 1.4.5 → 1.5.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (792) hide show
  1. data/CHANGELOG +35 -0
  2. data/VERSION.yml +2 -2
  3. data/lib/Buildfile +13 -4
  4. data/lib/buildtasks/build.rake +20 -17
  5. data/lib/buildtasks/manifest.rake +143 -78
  6. data/lib/buildtasks/target.rake +1 -0
  7. data/lib/doc_templates/sproutcore/index.tmpl +18 -4
  8. data/lib/doc_templates/sproutcore/publish.js +1 -1
  9. data/lib/frameworks/sproutcore/Buildfile +24 -13
  10. data/lib/frameworks/sproutcore/{CHANGELOG-1.4.md → CHANGELOG.md} +0 -0
  11. data/lib/frameworks/sproutcore/apps/greenhouse/controllers/file.js +8 -48
  12. data/lib/frameworks/sproutcore/apps/greenhouse/core.js +3 -5
  13. data/lib/frameworks/sproutcore/apps/greenhouse/data_source.js +1 -1
  14. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/app_page.js +26 -4
  15. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/strings.js +7 -1
  16. data/lib/frameworks/sproutcore/apps/greenhouse/main.js +1 -1
  17. data/lib/frameworks/sproutcore/apps/greenhouse/models/design.js +6 -2
  18. data/lib/frameworks/sproutcore/apps/greenhouse/models/dir.js +8 -7
  19. data/lib/frameworks/sproutcore/apps/greenhouse/models/file.js +2 -2
  20. data/lib/frameworks/sproutcore/apps/greenhouse/states/inspector.js +133 -125
  21. data/lib/frameworks/sproutcore/apps/greenhouse/states/library.js +121 -112
  22. data/lib/frameworks/sproutcore/apps/greenhouse/states/main.js +233 -191
  23. data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +265 -258
  24. data/lib/frameworks/sproutcore/apps/greenhouse/states/ready.js +153 -141
  25. data/lib/frameworks/sproutcore/apps/test_controls/Buildfile +0 -0
  26. data/lib/frameworks/sproutcore/apps/test_controls/controllers/buttons.js +21 -0
  27. data/lib/frameworks/sproutcore/apps/test_controls/controllers/categories.js +108 -0
  28. data/lib/frameworks/sproutcore/apps/test_controls/controllers/category.js +36 -0
  29. data/lib/frameworks/sproutcore/apps/test_controls/core.js +29 -0
  30. data/lib/frameworks/sproutcore/apps/test_controls/main.js +14 -0
  31. data/lib/frameworks/sproutcore/apps/test_controls/resources/buttons_page.js +142 -0
  32. data/lib/frameworks/sproutcore/apps/test_controls/resources/checkboxes_page.js +45 -0
  33. data/lib/frameworks/sproutcore/apps/test_controls/resources/flow_layout_page.js +84 -0
  34. data/lib/frameworks/sproutcore/apps/test_controls/resources/list_page.js +40 -0
  35. data/lib/frameworks/sproutcore/apps/test_controls/resources/loading.rhtml +9 -0
  36. data/lib/frameworks/sproutcore/apps/test_controls/resources/main_page.css +60 -0
  37. data/lib/frameworks/sproutcore/apps/test_controls/resources/main_page.js +144 -0
  38. data/lib/frameworks/sproutcore/apps/test_controls/resources/progress_page.js +42 -0
  39. data/lib/frameworks/sproutcore/apps/test_controls/resources/radio_page.js +48 -0
  40. data/lib/frameworks/sproutcore/apps/test_controls/resources/scroll_page.js +76 -0
  41. data/lib/frameworks/sproutcore/apps/test_controls/resources/segmented_page.js +98 -0
  42. data/lib/frameworks/sproutcore/apps/test_controls/resources/select_page.js +60 -0
  43. data/lib/frameworks/sproutcore/apps/test_controls/resources/sliders_page.js +53 -0
  44. data/lib/frameworks/sproutcore/apps/test_controls/resources/strings.js +50 -0
  45. data/lib/frameworks/sproutcore/apps/test_controls/resources/tab_page.js +44 -0
  46. data/lib/frameworks/sproutcore/apps/test_controls/resources/text_field_page.js +41 -0
  47. data/lib/frameworks/sproutcore/apps/test_controls/theme.js +34 -0
  48. data/lib/frameworks/sproutcore/apps/welcome/controllers/targets.js +7 -0
  49. data/lib/frameworks/sproutcore/apps/welcome/english.lproj/images/main-bg.png +0 -0
  50. data/lib/frameworks/sproutcore/apps/welcome/english.lproj/main_page.css +24 -6
  51. data/lib/frameworks/sproutcore/apps/welcome/english.lproj/main_page.js +36 -46
  52. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/controllers/array.js +175 -195
  53. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/controllers/controller.js +0 -0
  54. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/controllers/object.js +0 -0
  55. data/lib/frameworks/sproutcore/frameworks/amber/core.js +201 -0
  56. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/ext/object.js +23 -23
  57. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/ext/run_loop.js +47 -47
  58. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/mixins/delegate_support.js +36 -36
  59. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/mixins/responder_context.js +55 -55
  60. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/mixins/selection_support.js +45 -45
  61. data/lib/frameworks/sproutcore/frameworks/amber/mixins/string.js +163 -0
  62. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/panes/main.js +4 -3
  63. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/panes/pane.js +123 -9
  64. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/protocols/observable_protocol.js +11 -11
  65. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/protocols/sparse_array_delegate.js +40 -40
  66. data/lib/frameworks/sproutcore/frameworks/{foundation/english.lproj → amber/resources}/core.css +0 -103
  67. data/lib/frameworks/sproutcore/frameworks/{foundation/english.lproj → amber/resources}/view.css +0 -0
  68. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/application.js +0 -2
  69. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/browser.js +0 -0
  70. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/builder.js +0 -0
  71. data/lib/frameworks/sproutcore/frameworks/amber/system/core_query.js +141 -0
  72. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/cursor.js +0 -0
  73. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/device.js +0 -0
  74. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/event.js +34 -14
  75. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/json.js +0 -0
  76. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/locale.js +0 -0
  77. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/page.js +0 -0
  78. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/platform.js +30 -10
  79. data/lib/frameworks/sproutcore/frameworks/amber/system/ready.js +77 -0
  80. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/render_context.js +330 -255
  81. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/responder.js +0 -0
  82. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/root_responder.js +152 -60
  83. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/system/selection_set.js +140 -145
  84. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/system/sparse_array.js +101 -87
  85. data/lib/frameworks/sproutcore/frameworks/amber/system/theme.js +316 -0
  86. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/system/timer.js +149 -147
  87. data/lib/frameworks/sproutcore/frameworks/amber/system/utils.js +174 -0
  88. data/lib/frameworks/sproutcore/frameworks/amber/system/utils/rect.js +98 -0
  89. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/array/array_case.js +41 -41
  90. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/array/enum_case.js +0 -0
  91. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/array/null_case.js +0 -0
  92. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/array/selection_support.js +0 -0
  93. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/array/single_case.js +9 -9
  94. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/object/empty_case.js +0 -0
  95. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/object/multiple_case.js +0 -0
  96. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/object/single_case.js +0 -0
  97. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/controllers/object/single_enumerable_case.js +0 -0
  98. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/mixins/responder_context.js +0 -0
  99. data/lib/frameworks/sproutcore/frameworks/amber/tests/mixins/string.js +55 -0
  100. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/builder.js +0 -0
  101. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/core_query/within.js +7 -8
  102. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/json.js +0 -0
  103. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/locale.js +0 -0
  104. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/begin.js +0 -0
  105. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/element.js +0 -0
  106. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/end.js +1 -1
  107. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/get.js +0 -0
  108. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/helpers_attr.js +0 -0
  109. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/helpers_basic.js +0 -0
  110. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/helpers_className.js +0 -2
  111. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/helpers_style.js +11 -3
  112. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/init.js +0 -0
  113. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/join.js +0 -0
  114. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/push_text.js +0 -0
  115. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/tag.js +0 -0
  116. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/render_context/update.js +0 -0
  117. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/root_responder/makeKeyPane.js +0 -0
  118. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/root_responder/makeMainPane.js +0 -0
  119. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/root_responder/makeMenuPane.js +0 -0
  120. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/root_responder/root_responder.js +0 -0
  121. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/root_responder/targetForAction.js +46 -9
  122. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/selection_set/add.js +0 -0
  123. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/selection_set/copy.js +0 -0
  124. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/selection_set/indexSetForSource.js +0 -0
  125. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/selection_set/isEqual.js +0 -0
  126. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/selection_set/remove.js +0 -0
  127. data/lib/frameworks/sproutcore/frameworks/{runtime → amber}/tests/system/sparse_array.js +0 -0
  128. data/lib/frameworks/sproutcore/frameworks/amber/tests/system/theme.js +77 -0
  129. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/timer/invalidate.js +0 -0
  130. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/timer/invokeLater.js +7 -5
  131. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/timer/isPaused.js +0 -0
  132. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/timer/performAction.js +0 -0
  133. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/timer/schedule.js +0 -0
  134. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/utils/normalizeURL.js +0 -0
  135. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/system/utils/rect.js +0 -0
  136. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/main_pane.js +0 -0
  137. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/pane/append_remove.js +0 -0
  138. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/pane/firstResponder.js +0 -0
  139. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/pane/keyPane.js +0 -0
  140. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/pane/layout.js +0 -0
  141. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/pane/sendEvent.js +0 -0
  142. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/pane/sendTouchEvent.js +267 -0
  143. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/animation.js +320 -0
  144. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/build.js +85 -0
  145. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/build_children.js +89 -0
  146. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/clippingFrame.js +3 -2
  147. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/convertFrames.js +0 -0
  148. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/convertLayouts.js +0 -0
  149. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/createChildViews.js +0 -0
  150. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/createLayer.js +2 -2
  151. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/destroyLayer.js +0 -0
  152. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/didAppendToDocument.js +0 -0
  153. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/findLayerInParentLayer.js +0 -0
  154. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/init.js +0 -0
  155. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/insertBefore.js +0 -0
  156. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/isVisible.js +0 -0
  157. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/isVisibleInWindow.js +0 -0
  158. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/layer.js +0 -0
  159. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/layoutChildViews.js +0 -0
  160. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/layoutDidChange.js +22 -0
  161. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/layoutStyle.js +135 -64
  162. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/parentViewDidChange.js +0 -0
  163. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/prepareContext.js +16 -8
  164. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/removeChild.js +0 -0
  165. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/render.js +37 -5
  166. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/render_delegate_support.js +163 -0
  167. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/replaceChild.js +0 -0
  168. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/theme.js +43 -0
  169. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/updateLayer.js +12 -10
  170. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/updateLayerLocation.js +0 -0
  171. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/view.js +64 -0
  172. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/tests/views/view/viewDidResize.js +0 -0
  173. data/lib/frameworks/sproutcore/frameworks/amber/views/base.js +1 -0
  174. data/lib/frameworks/sproutcore/frameworks/amber/views/layout_style.js +478 -0
  175. data/lib/frameworks/sproutcore/frameworks/{foundation → amber}/views/view.js +1719 -1029
  176. data/lib/frameworks/sproutcore/frameworks/animation/core.js +32 -18
  177. data/lib/frameworks/sproutcore/frameworks/animation/tests/core.js +10 -5
  178. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/bench.js +14 -0
  179. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +24 -17
  180. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +1 -13
  181. data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +72 -0
  182. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +2 -2
  183. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +7 -3
  184. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +66 -4
  185. data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +4 -1
  186. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +58 -10
  187. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +5 -14
  188. data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +4 -5
  189. data/lib/frameworks/sproutcore/frameworks/desktop/english.lproj/list_item.css +27 -3
  190. data/lib/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +5 -8
  191. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_fast_path.js +1 -1
  192. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +30 -4
  193. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/navigation_builder.js +130 -0
  194. data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +2 -0
  195. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +20 -2
  196. data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +9 -27
  197. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +32 -26
  198. data/lib/frameworks/sproutcore/frameworks/desktop/panes/select_button.js +57 -11
  199. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +2 -2
  200. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +78 -0
  201. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/checkbox.js +74 -0
  202. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +24 -0
  203. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +41 -0
  204. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/helpers/slicing.js +34 -0
  205. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +30 -0
  206. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/master_detail.js +28 -0
  207. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/menu.js +47 -0
  208. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +28 -0
  209. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/picker.js +43 -0
  210. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +175 -0
  211. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio.js +74 -0
  212. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio_group.js +109 -0
  213. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +70 -0
  214. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +58 -0
  215. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +39 -0
  216. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/source_list.js +8 -0
  217. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/toolbar.js +18 -0
  218. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/well.js +29 -0
  219. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/workspace.js +18 -0
  220. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +79 -53
  221. data/lib/frameworks/sproutcore/frameworks/desktop/tests/integration/dialog.js +7 -2
  222. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +1 -1
  223. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +45 -3
  224. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +33 -13
  225. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +11 -17
  226. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/image_button/ui.js +25 -0
  227. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list_item.js +128 -20
  228. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +10 -10
  229. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +35 -15
  230. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +162 -0
  231. data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +153 -208
  232. data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +18 -48
  233. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +26 -25
  234. data/lib/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +3 -20
  235. data/lib/frameworks/sproutcore/frameworks/desktop/views/file.js +112 -0
  236. data/lib/frameworks/sproutcore/frameworks/desktop/views/image_button.js +74 -0
  237. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +3 -1
  238. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +388 -309
  239. data/lib/frameworks/sproutcore/frameworks/desktop/views/master_detail.js +257 -0
  240. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +8 -3
  241. data/lib/frameworks/sproutcore/frameworks/desktop/views/navigation.js +237 -0
  242. data/lib/frameworks/sproutcore/frameworks/desktop/views/navigation_bar.js +181 -0
  243. data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +3 -2
  244. data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +14 -76
  245. data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +59 -164
  246. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +80 -47
  247. data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +84 -0
  248. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +320 -289
  249. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +212 -76
  250. data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +33 -36
  251. data/lib/frameworks/sproutcore/frameworks/desktop/views/source_list.js +2 -0
  252. data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +347 -248
  253. data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +1 -1
  254. data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +1 -1
  255. data/lib/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +41 -9
  256. data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +1 -1
  257. data/lib/frameworks/sproutcore/frameworks/desktop/views/well.js +2 -21
  258. data/lib/frameworks/sproutcore/frameworks/desktop/views/workspace.js +251 -0
  259. data/lib/frameworks/sproutcore/frameworks/documentation/core.js +0 -0
  260. data/lib/frameworks/sproutcore/frameworks/forms/english.lproj/default_styles.css +5 -0
  261. data/lib/frameworks/sproutcore/frameworks/forms/english.lproj/strings.js +15 -0
  262. data/lib/frameworks/sproutcore/frameworks/forms/mixins/edit_mode.js +43 -0
  263. data/lib/frameworks/sproutcore/frameworks/forms/mixins/emptiness.js +95 -0
  264. data/lib/frameworks/sproutcore/frameworks/forms/renderer_delegates/form.js +22 -0
  265. data/lib/frameworks/sproutcore/frameworks/forms/renderer_delegates/form_row.js +21 -0
  266. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form.js +15 -0
  267. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_checkbox_field.js +15 -0
  268. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_field.js +15 -0
  269. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_label.js +15 -0
  270. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_radio_field.js +15 -0
  271. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_row.js +15 -0
  272. data/lib/frameworks/sproutcore/frameworks/forms/tests/views/form_text_field.js +15 -0
  273. data/lib/frameworks/sproutcore/frameworks/forms/views/form.js +280 -0
  274. data/lib/frameworks/sproutcore/frameworks/forms/views/form_row.js +183 -0
  275. data/lib/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +5 -2
  276. data/lib/frameworks/sproutcore/frameworks/foundation/core.js +0 -150
  277. data/lib/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +0 -2
  278. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/benchmark.css +146 -0
  279. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/bootstrap.rhtml +2 -14
  280. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/images/favicon.ico +0 -0
  281. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/images/sproutcore.png +0 -0
  282. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/strings.js +0 -2
  283. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +4 -6
  284. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/pinch.js +81 -0
  285. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/swipe.js +144 -0
  286. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/tap.js +113 -0
  287. data/lib/frameworks/sproutcore/frameworks/foundation/license.js +24 -26
  288. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_mixin.js +39 -0
  289. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +244 -0
  290. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/control.js +68 -23
  291. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +8 -2
  292. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +626 -0
  293. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/gestureable.js +214 -0
  294. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +89 -0
  295. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor_delegate.js +139 -0
  296. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +25 -33
  297. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/string.js +57 -209
  298. data/lib/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +7 -3
  299. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +100 -0
  300. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/container.js +18 -0
  301. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/image.js +97 -0
  302. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +111 -0
  303. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +17 -0
  304. data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +360 -156
  305. data/lib/frameworks/sproutcore/frameworks/{runtime → foundation}/system/cookie.js +35 -35
  306. data/lib/frameworks/sproutcore/frameworks/foundation/system/core_query.js +19 -2012
  307. data/lib/frameworks/sproutcore/frameworks/foundation/system/exception_handler.js +3 -0
  308. data/lib/frameworks/sproutcore/frameworks/foundation/system/gesture.js +363 -0
  309. data/lib/frameworks/sproutcore/frameworks/foundation/system/{image_cache.js → image_queue.js} +19 -22
  310. data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +576 -0
  311. data/lib/frameworks/sproutcore/frameworks/foundation/system/request.js +19 -22
  312. data/lib/frameworks/sproutcore/frameworks/foundation/system/response.js +73 -61
  313. data/lib/frameworks/sproutcore/frameworks/foundation/system/routes.js +122 -23
  314. data/lib/frameworks/sproutcore/frameworks/foundation/system/staticqueue.js +53 -0
  315. data/lib/frameworks/sproutcore/frameworks/foundation/system/task_queue.js +18 -15
  316. data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +82 -90
  317. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/colors.js +80 -0
  318. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +76 -0
  319. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/range.js +64 -0
  320. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +247 -0
  321. data/lib/frameworks/sproutcore/frameworks/foundation/tasks/preload_bundle.js +3 -3
  322. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +2 -2
  323. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/staticLayout.js +2 -0
  324. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/string.js +2 -57
  325. data/lib/frameworks/sproutcore/frameworks/{runtime → foundation}/tests/system/cookie.js +0 -0
  326. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/setClass.js +13 -3
  327. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +99 -49
  328. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/routes.js +24 -20
  329. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +9 -1
  330. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +31 -6
  331. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +454 -44
  332. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +10 -1
  333. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/{view → text_field}/nextValidKeyView.js +0 -0
  334. data/lib/frameworks/sproutcore/frameworks/foundation/validators/number.js +1 -0
  335. data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +9 -8
  336. data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +1 -3
  337. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +381 -105
  338. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +44 -171
  339. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +69 -16
  340. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +376 -0
  341. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffered.js +205 -0
  342. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-sc.js +7 -0
  343. data/lib/frameworks/sproutcore/frameworks/jquery/jquery.js +7179 -0
  344. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +4 -2
  345. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +1 -3
  346. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +1 -2
  347. data/lib/frameworks/sproutcore/frameworks/mini/license.js +29 -28
  348. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +366 -333
  349. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/rangeObserver.js +73 -73
  350. data/lib/frameworks/sproutcore/frameworks/runtime/license.js +29 -28
  351. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +160 -150
  352. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/comparable.js +9 -9
  353. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +15 -15
  354. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +228 -220
  355. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/freezable.js +27 -27
  356. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +355 -305
  357. data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +32 -32
  358. data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +53 -51
  359. data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +49 -106
  360. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +252 -252
  361. data/lib/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +22 -22
  362. data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +31 -31
  363. data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +234 -234
  364. data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +4 -4
  365. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +167 -157
  366. data/lib/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +84 -85
  367. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +104 -91
  368. data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +102 -98
  369. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/IsEqual.js +19 -49
  370. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/guidFor.js +53 -126
  371. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +62 -33
  372. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +41 -5
  373. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +133 -98
  374. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/observer_set.js +50 -0
  375. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/create.js +11 -11
  376. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/set.js +71 -45
  377. data/lib/frameworks/sproutcore/frameworks/statechart/core.js +3 -9
  378. data/lib/frameworks/sproutcore/frameworks/statechart/debug/monitor.js +136 -0
  379. data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +636 -99
  380. data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +951 -0
  381. data/lib/frameworks/sproutcore/frameworks/statechart/tests/async.js +94 -0
  382. data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/advanced_event_handling.js +310 -0
  383. data/lib/frameworks/sproutcore/frameworks/statechart/tests/namespace/access_substates.js +252 -0
  384. data/lib/frameworks/sproutcore/frameworks/statechart/tests/state/is_current_state.js +64 -0
  385. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/goto_history_state.js +88 -0
  386. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/goto_state_advanced.js +234 -0
  387. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/goto_state_async.js +123 -0
  388. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/goto_state_basic.js +139 -0
  389. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/goto_state_intermediate.js +119 -0
  390. data/lib/frameworks/sproutcore/frameworks/statechart/tests/with_concurrent_states/send_event.js +183 -0
  391. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/default_responder.js +90 -0
  392. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/goto_history_state.js +200 -0
  393. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/goto_state.js +256 -0
  394. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/goto_state_async.js +187 -0
  395. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/send_event.js +122 -0
  396. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/state_plugin.js +99 -0
  397. data/lib/frameworks/sproutcore/frameworks/statechart/tests/without_concurrent_states/transient.js +162 -0
  398. data/lib/frameworks/sproutcore/frameworks/table/views/table_cell.js +2 -1
  399. data/lib/frameworks/sproutcore/frameworks/table/views/table_head.js +1 -1
  400. data/lib/frameworks/sproutcore/frameworks/table/views/table_row.js +1 -1
  401. data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +2 -1
  402. data/lib/frameworks/sproutcore/lib/index.rhtml +24 -1
  403. data/lib/frameworks/sproutcore/license.js +31 -30
  404. data/lib/frameworks/sproutcore/themes/ace/designs/dark.png +0 -0
  405. data/lib/frameworks/sproutcore/themes/ace/designs/dark.psd +0 -0
  406. data/lib/frameworks/sproutcore/themes/ace/designs/light.png +0 -0
  407. data/lib/frameworks/sproutcore/themes/ace/designs/light.psd +0 -0
  408. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/18px/active_button.psd +0 -0
  409. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/18px/normal_button.psd +0 -0
  410. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/18px/selected_active_button.psd +0 -0
  411. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/18px/selected_button.psd +0 -0
  412. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/active_button.psd +0 -0
  413. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/active_button_capsule.psd +0 -0
  414. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/active_button_pointer.psd +0 -0
  415. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/normal_button.psd +0 -0
  416. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/normal_button_capsule.psd +0 -0
  417. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/normal_button_pointer.psd +0 -0
  418. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_active_button.psd +0 -0
  419. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_active_button_capsule.psd +0 -0
  420. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_active_button_pointer.psd +0 -0
  421. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_button.psd +0 -0
  422. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_button_capsule.psd +0 -0
  423. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/24px/selected_button_pointer.psd +0 -0
  424. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/active_button.psd +0 -0
  425. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/active_button_pointer.psd +0 -0
  426. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/normal_button.psd +0 -0
  427. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/normal_button_pointer.psd +0 -0
  428. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/selected_active_button.psd +0 -0
  429. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/selected_active_button_pointer.psd +0 -0
  430. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/selected_button.psd +0 -0
  431. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/30px/selected_button_pointer.psd +0 -0
  432. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/44px/active_button.psd +0 -0
  433. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/44px/normal_button.psd +0 -0
  434. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/44px/selected_active_button.psd +0 -0
  435. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/ace/44px/selected_button.psd +0 -0
  436. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/active_button.psd +0 -0
  437. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/active_button_capsule.psd +0 -0
  438. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/active_button_pointer.psd +0 -0
  439. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/normal_button.psd +0 -0
  440. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/normal_button_capsule.psd +0 -0
  441. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/normal_button_pointer.psd +0 -0
  442. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_active_button.psd +0 -0
  443. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_active_button_capsule.psd +0 -0
  444. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_active_button_pointer.psd +0 -0
  445. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_button.psd +0 -0
  446. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_button_capsule.psd +0 -0
  447. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/24px/selected_button_pointer.psd +0 -0
  448. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/active_button.psd +0 -0
  449. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/active_button_pointer.psd +0 -0
  450. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/normal_button.psd +0 -0
  451. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/normal_button_pointer.psd +0 -0
  452. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/selected_active_button.psd +0 -0
  453. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/selected_active_button_pointer.psd +0 -0
  454. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/selected_button.psd +0 -0
  455. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/dark/30px/selected_button_pointer.psd +0 -0
  456. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/popup/active_select.psd +0 -0
  457. data/lib/frameworks/sproutcore/themes/ace/designs/psds/button/popup/normal_select.psd +0 -0
  458. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_checked.psd +0 -0
  459. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_checked_active.psd +0 -0
  460. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_mixed.psd +0 -0
  461. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_mixed_active.psd +0 -0
  462. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_unchecked.psd +0 -0
  463. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/14px/checkbox_unchecked_active.psd +0 -0
  464. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_checked.psd +0 -0
  465. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_checked_active.psd +0 -0
  466. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_mixed.psd +0 -0
  467. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_mixed_active.psd +0 -0
  468. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_unchecked.psd +0 -0
  469. data/lib/frameworks/sproutcore/themes/ace/designs/psds/checkbox/ace/16px/checkbox_unchecked_active.psd +0 -0
  470. data/lib/frameworks/sproutcore/themes/ace/designs/psds/collection/source-list/selection.psd +0 -0
  471. data/lib/frameworks/sproutcore/themes/ace/designs/psds/disclosure/ace/disclosure_closed.psd +0 -0
  472. data/lib/frameworks/sproutcore/themes/ace/designs/psds/disclosure/ace/disclosure_closed_active.psd +0 -0
  473. data/lib/frameworks/sproutcore/themes/ace/designs/psds/disclosure/ace/disclosure_open.psd +0 -0
  474. data/lib/frameworks/sproutcore/themes/ace/designs/psds/disclosure/ace/disclosure_open_active.psd +0 -0
  475. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/checkmark.psd +0 -0
  476. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/checkmark_active.psd +0 -0
  477. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/down.psd +0 -0
  478. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/menu.psd +0 -0
  479. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/menu_item.psd +0 -0
  480. data/lib/frameworks/sproutcore/themes/ace/designs/psds/menu/up.psd +0 -0
  481. data/lib/frameworks/sproutcore/themes/ace/designs/psds/panel/panel.psd +0 -0
  482. data/lib/frameworks/sproutcore/themes/ace/designs/psds/picker/popover/popover.psd +0 -0
  483. data/lib/frameworks/sproutcore/themes/ace/designs/psds/picker/popover/popover_empty.psd +0 -0
  484. data/lib/frameworks/sproutcore/themes/ace/designs/psds/picker/popover/popover_notoolbar.psd +0 -0
  485. data/lib/frameworks/sproutcore/themes/ace/designs/psds/picker/popover/popover_pointers.psd +0 -0
  486. data/lib/frameworks/sproutcore/themes/ace/designs/psds/picker/popover/popover_pointers_notoolbar.psd +0 -0
  487. data/lib/frameworks/sproutcore/themes/ace/designs/psds/progress/ace/progress_view_content.psd +0 -0
  488. data/lib/frameworks/sproutcore/themes/ace/designs/psds/progress/ace/progress_view_indeterminate_content.psd +0 -0
  489. data/lib/frameworks/sproutcore/themes/ace/designs/psds/progress/ace/progress_view_track.psd +0 -0
  490. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_active.psd +0 -0
  491. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_mixed.psd +0 -0
  492. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_mixed_active.psd +0 -0
  493. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_selected.psd +0 -0
  494. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_selected_active.psd +0 -0
  495. data/lib/frameworks/sproutcore/themes/ace/designs/psds/radio/radio_unselected.psd +0 -0
  496. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/horizontal/thumb.psd +0 -0
  497. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/horizontal/track_and_arrows.psd +0 -0
  498. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/horizontal/track_and_arrows_active.psd +0 -0
  499. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/vertical/thumb.psd +0 -0
  500. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/vertical/track_and_arrows.psd +0 -0
  501. data/lib/frameworks/sproutcore/themes/ace/designs/psds/scroller/vertical/track_and_arrows_active.psd +0 -0
  502. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/18px/segmented_active.psd +0 -0
  503. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/18px/segmented_normal.psd +0 -0
  504. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/18px/segmented_selected.psd +0 -0
  505. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/18px/segmented_selected_active.psd +0 -0
  506. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/24px/segmented_active.psd +0 -0
  507. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/24px/segmented_normal.psd +0 -0
  508. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/24px/segmented_selected.psd +0 -0
  509. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/24px/segmented_selected_active.psd +0 -0
  510. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/30px/segmented_active.psd +0 -0
  511. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/30px/segmented_normal.psd +0 -0
  512. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/30px/segmented_selected.psd +0 -0
  513. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/30px/segmented_selected_active.psd +0 -0
  514. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/44px/segmented_active.psd +0 -0
  515. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/44px/segmented_normal.psd +0 -0
  516. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/44px/segmented_selected.psd +0 -0
  517. data/lib/frameworks/sproutcore/themes/ace/designs/psds/segmented/44px/segmented_selected_active.psd +0 -0
  518. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/14px/knob.psd +0 -0
  519. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/14px/knob_active.psd +0 -0
  520. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/16px/knob.psd +0 -0
  521. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/16px/knob_active.psd +0 -0
  522. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/22px/knob.psd +0 -0
  523. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/22px/knob_active.psd +0 -0
  524. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/22px/track.psd +0 -0
  525. data/lib/frameworks/sproutcore/themes/ace/designs/psds/slider/ace/track.psd +0 -0
  526. data/lib/frameworks/sproutcore/themes/ace/designs/psds/toolbar/toolbar.psd +0 -0
  527. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch.psd +0 -0
  528. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_handle.png +0 -0
  529. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_handle.psd +0 -0
  530. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_off.png +0 -0
  531. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_off.psd +0 -0
  532. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_on.png +0 -0
  533. data/lib/frameworks/sproutcore/themes/ace/designs/switch/switch_on.psd +0 -0
  534. data/lib/frameworks/sproutcore/themes/ace/resources/body.css +13 -0
  535. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/active_button.png +0 -0
  536. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +27 -0
  537. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/normal_button.png +0 -0
  538. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/selected_active_button.png +0 -0
  539. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/selected_button.png +0 -0
  540. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/active_button.png +0 -0
  541. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/active_button_capsule.png +0 -0
  542. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/active_button_pointer.png +0 -0
  543. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/button.css +84 -0
  544. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/normal_button.png +0 -0
  545. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/normal_button_capsule.png +0 -0
  546. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/normal_button_pointer.png +0 -0
  547. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_active_button.png +0 -0
  548. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_active_button_capsule.png +0 -0
  549. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_active_button_pointer.png +0 -0
  550. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_button.png +0 -0
  551. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_button_capsule.png +0 -0
  552. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/selected_button_pointer.png +0 -0
  553. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/active_button.png +0 -0
  554. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/active_button_pointer.png +0 -0
  555. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/button.css +66 -0
  556. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/normal_button.png +0 -0
  557. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/normal_button_pointer.png +0 -0
  558. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/selected_active_button.png +0 -0
  559. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/selected_active_button_pointer.png +0 -0
  560. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/selected_button.png +0 -0
  561. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/selected_button_pointer.png +0 -0
  562. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/active_button.png +0 -0
  563. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +34 -0
  564. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/normal_button.png +0 -0
  565. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/selected_active_button.png +0 -0
  566. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/selected_button.png +0 -0
  567. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/button.css +28 -0
  568. data/lib/frameworks/sproutcore/themes/ace/resources/button/button.js +69 -0
  569. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/active_button.png +0 -0
  570. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/active_button_capsule.png +0 -0
  571. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/active_button_pointer.png +0 -0
  572. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/button.css +84 -0
  573. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/normal_button.png +0 -0
  574. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/normal_button_capsule.png +0 -0
  575. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/normal_button_pointer.png +0 -0
  576. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_active_button.png +0 -0
  577. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_active_button_capsule.png +0 -0
  578. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_active_button_pointer.png +0 -0
  579. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_button.png +0 -0
  580. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_button_capsule.png +0 -0
  581. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/selected_button_pointer.png +0 -0
  582. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/active_button.png +0 -0
  583. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/active_button_pointer.png +0 -0
  584. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/button.css +66 -0
  585. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/normal_button.png +0 -0
  586. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/normal_button_pointer.png +0 -0
  587. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/selected_active_button.png +0 -0
  588. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/selected_active_button_pointer.png +0 -0
  589. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/selected_button.png +0 -0
  590. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/selected_button_pointer.png +0 -0
  591. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/button.css +17 -0
  592. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/button.js +3 -0
  593. data/lib/frameworks/sproutcore/themes/ace/resources/button/popup/active_select.png +0 -0
  594. data/lib/frameworks/sproutcore/themes/ace/resources/button/popup/normal_select.png +0 -0
  595. data/lib/frameworks/sproutcore/themes/ace/resources/button/popup/select.css +20 -0
  596. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox.css +40 -0
  597. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_checked.png +0 -0
  598. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_checked_active.png +0 -0
  599. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_mixed.png +0 -0
  600. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_mixed_active.png +0 -0
  601. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_unchecked.png +0 -0
  602. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/14px/checkbox_unchecked_active.png +0 -0
  603. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox.css +40 -0
  604. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_checked.png +0 -0
  605. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_checked_active.png +0 -0
  606. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_mixed.png +0 -0
  607. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_mixed_active.png +0 -0
  608. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_unchecked.png +0 -0
  609. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/16px/checkbox_unchecked_active.png +0 -0
  610. data/lib/frameworks/sproutcore/themes/ace/resources/checkbox/ace/checkbox.css +7 -0
  611. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +4 -0
  612. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +17 -0
  613. data/lib/frameworks/sproutcore/themes/ace/resources/collection/source-list/selection.png +0 -0
  614. data/lib/frameworks/sproutcore/themes/ace/resources/collection/source-list/source-list.js +3 -0
  615. data/lib/frameworks/sproutcore/themes/ace/resources/collection/source-list/source_list_view.css +36 -0
  616. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure.css +24 -0
  617. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure_closed.png +0 -0
  618. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure_closed_active.png +0 -0
  619. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure_open.png +0 -0
  620. data/lib/frameworks/sproutcore/themes/ace/resources/disclosure/ace/disclosure_open_active.png +0 -0
  621. data/lib/frameworks/sproutcore/themes/ace/resources/loading.css +50 -0
  622. data/lib/frameworks/sproutcore/themes/ace/resources/master-detail/master-detail.css +27 -0
  623. data/lib/frameworks/sproutcore/themes/ace/resources/menu/checkmark.png +0 -0
  624. data/lib/frameworks/sproutcore/themes/ace/resources/menu/checkmark_active.png +0 -0
  625. data/lib/frameworks/sproutcore/themes/ace/resources/menu/down.png +0 -0
  626. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +76 -0
  627. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.png +0 -0
  628. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu_item.png +0 -0
  629. data/lib/frameworks/sproutcore/themes/ace/resources/menu/up.png +0 -0
  630. data/lib/frameworks/sproutcore/themes/ace/resources/pane/pane.css +3 -0
  631. data/lib/frameworks/sproutcore/themes/ace/resources/panel/panel.css +13 -0
  632. data/lib/frameworks/sproutcore/themes/ace/resources/panel/panel.js +20 -0
  633. data/lib/frameworks/sproutcore/themes/ace/resources/panel/panel.png +0 -0
  634. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/picker.js +0 -0
  635. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/picker.js +32 -0
  636. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.css +111 -0
  637. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.js +12 -0
  638. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.png +0 -0
  639. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover_empty.png +0 -0
  640. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover_notoolbar.png +0 -0
  641. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover_pointers.png +0 -0
  642. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover_pointers_notoolbar.png +0 -0
  643. data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/workspace.js +28 -0
  644. data/lib/frameworks/sproutcore/themes/ace/resources/progress/ace/progress.css +27 -0
  645. data/lib/frameworks/sproutcore/themes/ace/resources/progress/ace/progress_view_content.png +0 -0
  646. data/lib/frameworks/sproutcore/themes/ace/resources/progress/ace/progress_view_track.png +0 -0
  647. data/lib/frameworks/sproutcore/themes/ace/resources/progress/progress.js +78 -0
  648. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio.css +63 -0
  649. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_active.png +0 -0
  650. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_mixed.png +0 -0
  651. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_mixed_active.png +0 -0
  652. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_selected.png +0 -0
  653. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_selected_active.png +0 -0
  654. data/lib/frameworks/sproutcore/themes/ace/resources/radio/radio_unselected.png +0 -0
  655. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/horizontal.css +78 -0
  656. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/horizontal_touch.css +91 -0
  657. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/thumb.png +0 -0
  658. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/track_and_arrows.png +0 -0
  659. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/horizontal/track_and_arrows_active.png +0 -0
  660. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/thumb.png +0 -0
  661. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/track_and_arrows.png +0 -0
  662. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/track_and_arrows_active.png +0 -0
  663. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/vertical.css +80 -0
  664. data/lib/frameworks/sproutcore/themes/ace/resources/scroller/vertical/vertical_touch.css +92 -0
  665. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +91 -0
  666. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented_active.png +0 -0
  667. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented_normal.png +0 -0
  668. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented_selected.png +0 -0
  669. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented_selected_active.png +0 -0
  670. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +91 -0
  671. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_active.png +0 -0
  672. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_normal.png +0 -0
  673. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_selected.png +0 -0
  674. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_selected_active.png +0 -0
  675. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +91 -0
  676. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_active.png +0 -0
  677. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_normal.png +0 -0
  678. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_selected.png +0 -0
  679. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_selected_active.png +0 -0
  680. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +95 -0
  681. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented_active.png +0 -0
  682. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented_normal.png +0 -0
  683. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented_selected.png +0 -0
  684. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented_selected_active.png +0 -0
  685. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +79 -0
  686. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/knob.png +0 -0
  687. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/knob_active.png +0 -0
  688. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/14px/slider.css +27 -0
  689. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/knob.png +0 -0
  690. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/knob_active.png +0 -0
  691. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/16px/slider.css +27 -0
  692. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/knob.png +0 -0
  693. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/knob_active.png +0 -0
  694. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/slider.css +27 -0
  695. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/22px/track.png +0 -0
  696. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/slider.css +3 -0
  697. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/slider.js +48 -0
  698. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/track.png +0 -0
  699. data/lib/frameworks/sproutcore/themes/ace/resources/split/split.css +5 -0
  700. data/lib/frameworks/sproutcore/themes/ace/resources/tab/tab.css +3 -0
  701. data/lib/frameworks/sproutcore/themes/ace/resources/toolbar/toolbar.css +8 -0
  702. data/lib/frameworks/sproutcore/themes/ace/resources/toolbar/toolbar.png +0 -0
  703. data/lib/frameworks/sproutcore/themes/ace/resources/well/well.css +8 -0
  704. data/lib/frameworks/sproutcore/themes/ace/resources/well/well.js +19 -0
  705. data/lib/frameworks/sproutcore/themes/ace/theme.js +14 -0
  706. data/lib/frameworks/sproutcore/themes/empty_theme/theme.js +16 -0
  707. data/lib/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +16 -21
  708. data/lib/sproutcore.rb +9 -2
  709. data/lib/sproutcore/builders.rb +2 -1
  710. data/lib/sproutcore/builders/base.rb +7 -2
  711. data/lib/sproutcore/builders/combine.rb +49 -1
  712. data/lib/sproutcore/builders/html.rb +2 -0
  713. data/lib/sproutcore/builders/javascript.rb +1 -1
  714. data/lib/sproutcore/builders/minify.rb +12 -12
  715. data/lib/sproutcore/builders/module.rb +72 -0
  716. data/lib/sproutcore/builders/string_wrapper.rb +43 -0
  717. data/lib/sproutcore/helpers/entry_sorter.rb +5 -9
  718. data/lib/sproutcore/helpers/static_helper.rb +13 -9
  719. data/lib/sproutcore/models/manifest_entry.rb +2 -2
  720. data/lib/sproutcore/models/target.rb +25 -11
  721. data/lib/sproutcore/rack/dev.rb +3 -3
  722. data/lib/sproutcore/tools.rb +51 -2
  723. data/lib/sproutcore/tools/build.rb +35 -7
  724. data/lib/sproutcore/version.rb +1 -0
  725. data/spec/buildtasks/manifest/prepare_build_tasks/bundle_spec.rb +5 -5
  726. data/spec/fixtures/builder_tests/Buildfile +2 -2
  727. data/spec/lib/builders/bundle_spec.rb +8 -8
  728. data/spec/lib/builders/strings_spec.rb +1 -0
  729. data/sproutcore.gemspec +9 -2
  730. data/vendor/chance/.gitignore +5 -0
  731. data/vendor/chance/Gemfile +4 -0
  732. data/vendor/chance/Rakefile +2 -0
  733. data/vendor/chance/bin/chance +72 -0
  734. data/vendor/chance/chance.gemspec +28 -0
  735. data/vendor/chance/lib/chance.rb +139 -0
  736. data/vendor/chance/lib/chance/imager.rb +13 -0
  737. data/vendor/chance/lib/chance/imagers/data_url.rb +34 -0
  738. data/vendor/chance/lib/chance/importer.rb +64 -0
  739. data/vendor/chance/lib/chance/instance.rb +225 -0
  740. data/vendor/chance/lib/chance/parser.rb +831 -0
  741. data/vendor/chance/lib/chance/perf.rb +17 -0
  742. data/vendor/chance/lib/chance/sass_extensions.rb +24 -0
  743. data/vendor/chance/lib/chance/slicing.rb +104 -0
  744. data/vendor/chance/lib/chance/version.rb +3 -0
  745. data/vendor/chance/test/case/abc.png +0 -0
  746. data/vendor/chance/test/case/more/abc.png +0 -0
  747. data/vendor/chance/test/case/more/another.css +4 -0
  748. data/vendor/chance/test/case/test1.css +22 -0
  749. data/vendor/chance/test/case/test2.css +6 -0
  750. data/vendor/sproutcore/SCCompiler.jar +0 -0
  751. data/vendor/sproutcore/lib/args4j-2.0.12.jar +0 -0
  752. data/vendor/sproutcore/lib/htmlcompressor-0.9.3.jar +0 -0
  753. data/{lib/sproutcore/vendor/yui-compressor → vendor/sproutcore/lib}/yuicompressor-2.4.2.jar +0 -0
  754. data/vendor/sproutcore/src/SCCompiler/build.xml +74 -0
  755. data/vendor/sproutcore/src/SCCompiler/lib/args4j-2.0.12.jar +0 -0
  756. data/vendor/sproutcore/src/SCCompiler/lib/htmlcompressor-0.9.3.jar +0 -0
  757. data/{lib/sproutcore/vendor/yui-compressor/SCyuicompressor-2.4.2.jar → vendor/sproutcore/src/SCCompiler/lib/yuicompressor-2.4.2.jar} +0 -0
  758. data/vendor/sproutcore/src/SCCompiler/lib/yuicompressor-2.4.4.jar +0 -0
  759. data/vendor/sproutcore/src/SCCompiler/manifest.mf +3 -0
  760. data/vendor/sproutcore/src/SCCompiler/nbproject/build-impl.xml +894 -0
  761. data/vendor/sproutcore/src/SCCompiler/nbproject/genfiles.properties +8 -0
  762. data/vendor/sproutcore/src/SCCompiler/nbproject/private/config.properties +0 -0
  763. data/vendor/sproutcore/src/SCCompiler/nbproject/private/private.properties +10 -0
  764. data/vendor/sproutcore/src/SCCompiler/nbproject/private/private.xml +4 -0
  765. data/vendor/sproutcore/src/SCCompiler/nbproject/project.properties +90 -0
  766. data/vendor/sproutcore/src/SCCompiler/nbproject/project.xml +15 -0
  767. data/vendor/sproutcore/src/SCCompiler/src/com/sproutcore/Main.java +348 -0
  768. metadata +686 -177
  769. data/lib/frameworks/sproutcore/CHANGELOG +0 -93
  770. data/lib/frameworks/sproutcore/frameworks/datejs/core.js +0 -865
  771. data/lib/frameworks/sproutcore/frameworks/datejs/english.lproj/en-US.js +0 -186
  772. data/lib/frameworks/sproutcore/frameworks/datejs/extras.js +0 -332
  773. data/lib/frameworks/sproutcore/frameworks/datejs/license.js +0 -25
  774. data/lib/frameworks/sproutcore/frameworks/datejs/parser.js +0 -1116
  775. data/lib/frameworks/sproutcore/frameworks/datejs/spanish.lproj/es-CO.js +0 -186
  776. data/lib/frameworks/sproutcore/frameworks/datejs/sugarpak.js +0 -475
  777. data/lib/frameworks/sproutcore/frameworks/datejs/time.js +0 -269
  778. data/lib/frameworks/sproutcore/frameworks/datejs/validators/datejs.js +0 -34
  779. data/lib/frameworks/sproutcore/frameworks/foundation/protocols/inline_editor_delegate.js +0 -84
  780. data/lib/frameworks/sproutcore/frameworks/foundation/system/bundle.js +0 -337
  781. data/lib/frameworks/sproutcore/frameworks/foundation/system/ready.js +0 -197
  782. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils.js +0 -710
  783. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_core.js +0 -1334
  784. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_dimensions.js +0 -387
  785. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +0 -405
  786. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/isArray.js +0 -25
  787. data/lib/frameworks/sproutcore/frameworks/statechart/mixins/statechart.js +0 -336
  788. data/lib/frameworks/sproutcore/frameworks/statechart/tests/basic.js +0 -90
  789. data/lib/frameworks/sproutcore/frameworks/statechart/tests/history.js +0 -71
  790. data/lib/frameworks/sproutcore/frameworks/statechart/tests/nested.js +0 -59
  791. data/lib/frameworks/sproutcore/frameworks/statechart/tests/transient.js +0 -148
  792. data/lib/sproutcore/builders/bundle.rb +0 -63
@@ -9,10 +9,11 @@ sc_require('system/browser');
9
9
  sc_require('system/event');
10
10
  sc_require('system/cursor');
11
11
  sc_require('system/responder') ;
12
+ sc_require('system/theme');
12
13
 
13
14
  sc_require('mixins/string') ;
14
-
15
- SC.viewKey = SC.guidKey + "_view" ;
15
+ sc_require('views/base') ;
16
+ sc_require('views/layout_style') ;
16
17
 
17
18
  /** Select a horizontal layout for various views.*/
18
19
  SC.LAYOUT_HORIZONTAL = 'sc-layout-horizontal';
@@ -23,36 +24,6 @@ SC.LAYOUT_VERTICAL = 'sc-layout-vertical';
23
24
  /** @private */
24
25
  SC._VIEW_DEFAULT_DIMS = 'marginTop marginLeft'.w();
25
26
 
26
- /**
27
- Layout properties needed to anchor a view to the top.
28
- */
29
- SC.ANCHOR_TOP = { top: 0 };
30
-
31
- /**
32
- Layout properties needed to anchor a view to the left.
33
- */
34
- SC.ANCHOR_LEFT = { left: 0 };
35
-
36
- /*
37
- Layout properties to anchor a view to the top left
38
- */
39
- SC.ANCHOR_TOP_LEFT = { top: 0, left: 0 };
40
-
41
- /**
42
- Layout properties to anchoe view to the bottom.
43
- */
44
- SC.ANCHOR_BOTTOM = { bottom: 0 };
45
-
46
- /**
47
- Layout properties to anchor a view to the right.
48
- */
49
- SC.ANCHOR_RIGHT = { right: 0 } ;
50
-
51
- /**
52
- Layout properties to anchor a view to the bottom right.
53
- */
54
- SC.ANCHOR_BOTTOM_RIGHT = { bottom: 0, right: 0 };
55
-
56
27
  /**
57
28
  Layout properties to take up the full width of a parent view.
58
29
  */
@@ -86,146 +57,318 @@ SC.CONTEXT_MENU_ENABLED = YES;
86
57
  */
87
58
  SC.TABBING_ONLY_INSIDE_DOCUMENT = YES;
88
59
 
60
+ /**
61
+ Tells the property (when fetched with themed()) to get its value from the renderer (if any).
62
+ */
63
+ SC.FROM_THEME = "__FROM_THEME__"; // doesn't really matter what it is, so long as it is unique. Readability is a plus.
64
+
89
65
  /** @private - custom array used for child views */
90
66
  SC.EMPTY_CHILD_VIEWS_ARRAY = [];
91
67
  SC.EMPTY_CHILD_VIEWS_ARRAY.needsClone = YES;
92
68
 
93
- /**
69
+ /**
70
+ Map to CSS Transforms
71
+ */
72
+
73
+ SC.CSS_TRANSFORM_MAP = {
74
+ rotate: function(val){
75
+ return null;
76
+ },
77
+
78
+ rotateX: function(val){
79
+ if (SC.typeOf(val) === SC.T_NUMBER) val += 'deg';
80
+ return 'rotateX('+val+')';
81
+ },
82
+
83
+ rotateY: function(val){
84
+ if (SC.typeOf(val) === SC.T_NUMBER) val += 'deg';
85
+ return 'rotateY('+val+')';
86
+ },
87
+
88
+ rotateZ: function(val){
89
+ if (SC.typeOf(val) === SC.T_NUMBER) val += 'deg';
90
+ return 'rotateZ('+val+')';
91
+ },
92
+
93
+ scale: function(val){
94
+ if (SC.typeOf(val) === SC.T_ARRAY) val = val.join(', ');
95
+ return 'scale('+val+')';
96
+ }
97
+ };
98
+
99
+
100
+
101
+ /**
102
+ Properties that can be animated
103
+ (Hash for faster lookup)
104
+ */
105
+ SC.ANIMATABLE_PROPERTIES = {
106
+ top: YES,
107
+ left: YES,
108
+ bottom: YES,
109
+ right: YES,
110
+ width: YES,
111
+ height: YES,
112
+ centerX: YES,
113
+ centerY: YES,
114
+ opacity: YES,
115
+ scale: YES,
116
+ rotate: YES,
117
+ rotateX: YES,
118
+ rotateY: YES,
119
+ rotateZ: YES
120
+ };
121
+
122
+
123
+
124
+ /**
94
125
  @class
95
-
126
+
96
127
  Base class for managing a view. Views provide two functions:
97
-
98
- 1. They translate state and events into drawing instructions for the
128
+
129
+ 1. They translate state and events into drawing instructions for the
99
130
  web browser and
100
-
101
- 2. They act as first responders for incoming keyboard, mouse, and
131
+
132
+ 2. They act as first responders for incoming keyboard, mouse, and
102
133
  touch events.
103
-
134
+
104
135
  h2. View Initialization
105
-
106
- When a view is setup, there are several methods you can override that
136
+
137
+ When a view is setup, there are several methods you can override that
107
138
  will be called at different times depending on how your view is created.
108
139
  Here is a guide to which method you want to override and when:
109
-
110
- - *init:* override this method for any general object setup (such as
111
- observers, starting timers and animations, etc) that you need to happen
112
- everytime the view is created, regardless of whether or not its layer
140
+
141
+ - *init:* override this method for any general object setup (such as
142
+ observers, starting timers and animations, etc) that you need to happen
143
+ everytime the view is created, regardless of whether or not its layer
113
144
  exists yet.
114
-
145
+
115
146
  - *render:* override this method to generate or update your HTML to reflect
116
147
  the current state of your view. This method is called both when your view
117
148
  is first created and later anytime it needs to be updated.
118
149
 
119
- - *didCreateLayer:* the render() method is used to generate new HTML.
150
+ - *didCreateLayer:* the render() method is used to generate new HTML.
120
151
  Override this method to perform any additional setup on the DOM you might
121
152
  need to do after creating the view. For example, if you need to listen
122
153
  for events.
123
-
124
- - *willDestroyLayer:* if you implement didCreateLayer() to setup event
125
- listeners, you should implement this method as well to remove the same
154
+
155
+ - *willDestroyLayer:* if you implement didCreateLayer() to setup event
156
+ listeners, you should implement this method as well to remove the same
126
157
  just before the DOM for your view is destroyed.
127
-
158
+
128
159
  - *updateLayer:* Normally, when a view needs to update its content, it will
129
- re-render the view using the render() method. If you would like to
130
- override this behavior with your own custom updating code, you can
160
+ re-render the view using the render() method. If you would like to
161
+ override this behavior with your own custom updating code, you can
131
162
  replace updateLayer() with your own implementation instead.
132
-
163
+
133
164
  - *didAppendToDocument:* in theory all DOM setup could be done
134
- in didCreateLayer() as you already have a DOM element instantiated.
165
+ in didCreateLayer() as you already have a DOM element instantiated.
135
166
  However there is cases where the element has to be first appended to the
136
- Document because there is either a bug on the browser or you are using
167
+ Document because there is either a bug on the browser or you are using
137
168
  plugins which objects are not instantiated until you actually append the
138
- element to the DOM. This will allow you to do things like registering
169
+ element to the DOM. This will allow you to do things like registering
139
170
  DOM events on flash or quicktime objects.
140
-
171
+
141
172
  @extends SC.Responder
142
173
  @extends SC.DelegateSupport
143
174
  @since SproutCore 1.0
144
175
  */
145
- SC.View = SC.Responder.extend(SC.DelegateSupport,
176
+ SC.View.reopen(
146
177
  /** @scope SC.View.prototype */ {
147
-
178
+
148
179
  concatenatedProperties: 'outlets displayProperties layoutProperties classNames renderMixin didCreateLayerMixin willDestroyLayerMixin'.w(),
149
-
150
- /**
151
- The current pane.
180
+
181
+ /**
182
+ The current pane.
152
183
  @property {SC.Pane}
153
184
  */
154
185
  pane: function() {
155
186
  var view = this ;
156
- while (view && !view.isPane) view = view.get('parentView') ;
187
+ while (view && !view.isPane) { view = view.get('parentView') ; }
157
188
  return view ;
158
189
  }.property('parentView').cacheable(),
159
-
190
+
160
191
  /**
161
192
  The page this view was instantiated from. This is set by the page object
162
193
  during instantiation.
163
-
194
+
164
195
  @property {SC.Page}
165
196
  */
166
197
  page: null,
167
-
168
- /**
169
- The current split view this view is embedded in (may be null).
170
- @property {SC.SplitView}
171
- */
172
- splitView: function() {
173
- var view = this ;
174
- while (view && !view.isSplitView) view = view.get('parentView') ;
175
- return view ;
176
- }.property('parentView').cacheable(),
177
-
198
+
178
199
  /**
179
200
  If the view is currently inserted into the DOM of a parent view, this
180
201
  property will point to the parent of the view.
181
202
  */
182
203
  parentView: null,
183
-
204
+
184
205
  /**
185
- Optional background color. Will be applied to the view's element if
206
+ Optional background color. Will be applied to the view's element if
186
207
  set. This property is intended for one-off views that need a background
187
208
  element. If you plan to create many view instances it is probably better
188
209
  to use CSS.
189
-
210
+
190
211
  @property {String}
191
212
  */
192
213
  backgroundColor: null,
193
-
214
+
194
215
  /**
195
- Activates use of brower's static layout. You can apply this mixin and
196
- still use absolute positioning. To activate static positioning, set this
216
+ Activates use of brower's static layout. To activate, set this
197
217
  property to YES.
198
218
 
199
219
  @property {Boolean}
200
220
  */
201
- useStaticLayout: NO,
202
-
221
+ useStaticLayout: NO,
222
+
223
+ // ..........................................................
224
+ // THEME SUPPORT
225
+ //
226
+
227
+ /**
228
+ Names which theme this view should use; the theme named by this property
229
+ will be set to the view's 'theme' property.
230
+
231
+ Themes are identified by their name. In addition to looking for the
232
+ theme globally, SproutCore will look for the theme inside 'baseTheme',
233
+ which is almost always the parent view's theme.
234
+
235
+ If null (the default), the view will set its 'theme' property to
236
+ be equal to 'baseTheme'.
237
+
238
+ Example: themeName: 'ace'
239
+
240
+ @property {String}
241
+ */
242
+ themeName: null,
243
+
244
+ /**
245
+ Selects which theme to use as a 'base theme'. If null, the 'baseTheme'
246
+ property will be set to the parent's theme. If there is no parent, the theme
247
+ named by SC.defaultTheme is used.
248
+
249
+ This property is private for the time being.
250
+
251
+ @private
252
+ @property {String}
253
+ */
254
+ baseThemeName: null,
255
+
256
+ /**
257
+ The SC.Theme instance which this view should use to render.
258
+
259
+ Note: the actual code for this function is in _themeProperty for backwards-compatibility:
260
+ some older views specify a string value for 'theme', which would override this property,
261
+ breaking it.
262
+
263
+ @property {SC.Theme}
264
+ */
265
+ theme: function() {
266
+ var base = this.get('baseTheme'), themeName = this.get('themeName');
267
+
268
+ // find theme, if possible
269
+ if (themeName) {
270
+ // Note: theme instance "find" function will search every parent
271
+ // _except_ global (which is not a parent)
272
+ var theme;
273
+ if (base) {
274
+ theme = base.find(themeName);
275
+ if (theme) return theme;
276
+ }
277
+
278
+ theme = SC.Theme.find(themeName);
279
+ if (theme) return theme;
280
+
281
+ // Create a new invisible subtheme. This will cause the themeName to
282
+ // be applied as a class name.
283
+ return base.invisibleSubtheme(themeName);
284
+ }
285
+
286
+ // can't find anything, return base.
287
+ return base;
288
+ }.property('baseTheme', 'themeName').cacheable(),
289
+
290
+ /**
291
+ Detects when the theme changes. Replaces the layer if necessary.
292
+
293
+ Also, because
294
+ */
295
+ _sc_view_themeDidChange: function() {
296
+ if (this._lastTheme === this.get('theme')) return;
297
+ this._lastTheme = this.get('theme');
298
+
299
+ // invalidate child view base themes, if present
300
+ var childViews = this.childViews, len = childViews.length, idx;
301
+ for (idx = 0; idx < len; idx++) {
302
+ childViews[idx].notifyPropertyChange('baseTheme');
303
+ }
304
+
305
+ if (this.get('layer')) this.replaceLayer();
306
+ }.observes('theme'),
307
+
308
+ /**
309
+ The SC.Theme instance in which the 'theme' property should look for the theme
310
+ named by 'themeName'.
311
+
312
+ For example, if 'baseTheme' is SC.AceTheme, and 'themeName' is 'popover',
313
+ it will look to see if SC.AceTheme has a child theme named 'popover',
314
+ and _then_, if it is not found, look globally.
315
+
316
+ @private
317
+ @property {SC.Theme}
318
+ */
319
+ baseTheme: function() {
320
+ var parent;
321
+ var baseThemeName = this.get('baseThemeName');
322
+ if (baseThemeName) {
323
+ return SC.Theme.find(baseThemeName);
324
+ } else {
325
+ parent = this.get('parentView');
326
+ var theme = parent && parent.get('theme');
327
+ return theme || SC.Theme.find(SC.defaultTheme);
328
+ }
329
+ }.property('baseThemeName', 'parentView').cacheable(),
330
+
331
+ /**
332
+ * Returns the named property if it is specified on the view, and
333
+ * otherwise returns the named constant from the view's theme.
334
+ *
335
+ * @param {String} property The property on the view.
336
+ * @param {String} constantName The name of the constant on the theme.
337
+ */
338
+ getThemedProperty: function(property, constantName){
339
+ var value = this.get(property);
340
+ if (value !== undefined) return value;
341
+
342
+ var theme = this.get('theme');
343
+ if (!theme) return undefined;
344
+
345
+ return theme[constantName];
346
+ },
347
+
203
348
  // ..........................................................
204
349
  // IS ENABLED SUPPORT
205
- //
206
-
207
- /**
350
+ //
351
+
352
+ /**
208
353
  Set to true when the item is enabled. Note that changing this value
209
- will also alter the isVisibleInWindow property for this view and any
210
- child views.
211
-
212
- Note that if you apply the SC.Control mixin, changing this property will
213
- also automatically add or remove a 'disabled' CSS class name as well.
214
-
354
+ will alter the isVisibleInWindow property for this view and any
355
+ child views as well as to automatically add or remove a 'disabled' CSS
356
+ class name.
357
+
215
358
  This property is observable and bindable.
216
-
359
+
217
360
  @property {Boolean}
218
361
  */
219
362
  isEnabled: YES,
220
363
  isEnabledBindingDefault: SC.Binding.oneWay().bool(),
221
-
364
+
222
365
  /**
223
366
  Computed property returns YES if the view and all of its parent views
224
- are enabled in the pane. You should use this property when deciding
367
+ are enabled in the pane. You should use this property when deciding
225
368
  whether to respond to an incoming event or not.
226
-
369
+
227
370
  This property is not observable.
228
-
371
+
229
372
  @property {Boolean}
230
373
  */
231
374
  isEnabledInPane: function() {
@@ -247,32 +390,46 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
247
390
  }
248
391
  }.observes('isEnabled'),
249
392
 
393
+ // ..........................................................
394
+ // MULTITOUCH SUPPORT
395
+ //
396
+ /**
397
+ Set to YES if you want to receive touch events for each distinct touch (rather than only
398
+ the first touch start and last touch end).
399
+ */
400
+ acceptsMultitouch: NO,
401
+
402
+ /**
403
+ Is YES if the view is currently being touched. NO otherwise.
404
+ */
405
+ hasTouch: NO,
406
+
250
407
  // ..........................................................
251
408
  // IS VISIBLE IN WINDOW SUPPORT
252
- //
253
-
409
+ //
410
+
254
411
  /**
255
- The isVisible property determines if the view is shown in the view
412
+ The isVisible property determines if the view is shown in the view
256
413
  hierarchy it is a part of. A view can have isVisible == YES and still have
257
414
  isVisibleInWindow == NO. This occurs, for instance, when a parent view has
258
415
  isVisible == NO. Default is YES.
259
-
416
+
260
417
  The isVisible property is considered part of the layout and so changing it
261
418
  will trigger a layout update.
262
-
419
+
263
420
  @property {Boolean}
264
421
  */
265
422
  isVisible: YES,
266
423
  isVisibleBindingDefault: SC.Binding.bool(),
267
-
424
+
268
425
  /**
269
426
  YES only if the view and all of its parent views are currently visible
270
427
  in the window. This property is used to optimize certain behaviors in
271
- the view. For example, updates to the view layer are not performed
428
+ the view. For example, updates to the view layer are not performed
272
429
  if the view until the view becomes visible in the window.
273
430
  */
274
431
  isVisibleInWindow: NO,
275
-
432
+
276
433
  /**
277
434
  By default we don't disable the context menu. Overriding this property
278
435
  can enable/disable the context menu per view.
@@ -280,27 +437,27 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
280
437
  isContextMenuEnabled: function() {
281
438
  return SC.CONTEXT_MENU_ENABLED;
282
439
  }.property(),
283
-
440
+
284
441
  /**
285
- Recomputes the isVisibleInWindow property based on the visibility of the
286
- view and its parent. If the recomputed value differs from the current
287
- isVisibleInWindow state, this method will also call
288
- recomputIsVisibleInWindow() on its child views as well. As an optional
289
- optimization, you can pass the isVisibleInWindow state of the parentView
442
+ Recomputes the isVisibleInWindow property based on the visibility of the
443
+ view and its parent. If the recomputed value differs from the current
444
+ isVisibleInWindow state, this method will also call
445
+ recomputIsVisibleInWindow() on its child views as well. As an optional
446
+ optimization, you can pass the isVisibleInWindow state of the parentView
290
447
  if you already know it.
291
-
292
- You will not generally need to call or override this method yourself. It
293
- is used by the SC.View hierarchy to relay window visibility changes up
448
+
449
+ You will not generally need to call or override this method yourself. It
450
+ is used by the SC.View hierarchy to relay window visibility changes up
294
451
  and down the chain.
295
-
452
+
296
453
  @property {Boolean} parentViewIsVisible
297
- @returns {SC.View} receiver
454
+ @returns {SC.View} receiver
298
455
  */
299
456
  recomputeIsVisibleInWindow: function(parentViewIsVisible) {
300
457
  var previous = this.get('isVisibleInWindow'),
301
458
  current = this.get('isVisible'),
302
459
  parentView;
303
-
460
+
304
461
  // isVisibleInWindow = isVisible && parentView.isVisibleInWindow
305
462
  // this approach only goes up to the parentView if necessary.
306
463
  if (current) {
@@ -373,54 +530,54 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
373
530
  }.observes('isVisible'),
374
531
 
375
532
 
376
-
533
+
377
534
  // ..........................................................
378
535
  // CHILD VIEW SUPPORT
379
- //
380
-
381
- /**
536
+ //
537
+
538
+ /**
382
539
  Array of child views. You should never edit this array directly unless
383
540
  you are implementing createChildViews(). Most of the time, you should
384
- use the accessor methods such as appendChild(), insertBefore() and
541
+ use the accessor methods such as appendChild(), insertBefore() and
385
542
  removeChild().
386
-
387
- @property {Array}
543
+
544
+ @property {Array}
388
545
  */
389
546
  childViews: SC.EMPTY_CHILD_VIEWS_ARRAY,
390
-
547
+
391
548
  /**
392
549
  Insert the view into the the receiver's childNodes array.
393
-
394
- The view will be added to the childNodes array before the beforeView. If
395
- beforeView is null, then the view will be added to the end of the array.
396
- This will also add the view's rootElement DOM node to the receivers
550
+
551
+ The view will be added to the childNodes array before the beforeView. If
552
+ beforeView is null, then the view will be added to the end of the array.
553
+ This will also add the view's rootElement DOM node to the receivers
397
554
  containerElement DOM node as a child.
398
-
399
- If the specified view already belongs to another parent, it will be
555
+
556
+ If the specified view already belongs to another parent, it will be
400
557
  removed from that view first.
401
-
558
+
402
559
  @param {SC.View} view
403
560
  @param {SC.View} beforeView
404
561
  @returns {SC.View} the receiver
405
562
  */
406
- insertBefore: function(view, beforeView) {
563
+ insertBefore: function(view, beforeView) {
407
564
  view.beginPropertyChanges(); // limit notifications
408
-
565
+
409
566
  // remove view from old parent if needed. Also notify views.
410
567
  if (view.get('parentView')) view.removeFromParent() ;
411
568
  if (this.willAddChild) this.willAddChild(view, beforeView) ;
412
569
  if (view.willAddToParent) view.willAddToParent(this, beforeView) ;
413
-
570
+
414
571
  // set parentView of child
415
572
  view.set('parentView', this);
416
-
573
+
417
574
  // add to childView's array.
418
575
  var idx, childViews = this.get('childViews') ;
419
576
  if (childViews.needsClone) this.set(childViews = []);
420
577
  idx = (beforeView) ? childViews.indexOf(beforeView) : childViews.length;
421
578
  if (idx<0) idx = childViews.length ;
422
579
  childViews.insertAt(idx, view) ;
423
-
580
+
424
581
  // The DOM will need some fixing up, note this on the view.
425
582
  view.parentViewDidChange() ;
426
583
  view.layoutDidChange() ;
@@ -428,19 +585,19 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
428
585
  if(pane && pane.get('isPaneAttached')) {
429
586
  view._notifyDidAppendToDocument();
430
587
  }
431
-
588
+
432
589
  // notify views
433
590
  if (this.didAddChild) this.didAddChild(view, beforeView) ;
434
591
  if (view.didAddToParent) view.didAddToParent(this, beforeView) ;
435
-
592
+
436
593
  view.endPropertyChanges();
437
-
594
+
438
595
  return this ;
439
596
  },
440
-
597
+
441
598
  /**
442
- Removes the child view from the parent view.
443
-
599
+ Removes the child view from the parent view.
600
+
444
601
  @param {SC.View} view
445
602
  @returns {SC.View} receiver
446
603
  */
@@ -452,29 +609,29 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
452
609
  // notify views
453
610
  if (view.willRemoveFromParent) view.willRemoveFromParent() ;
454
611
  if (this.willRemoveChild) this.willRemoveChild(view) ;
455
-
612
+
456
613
  // update parent node
457
614
  view.set('parentView', null) ;
458
-
615
+
459
616
  // remove view from childViews array.
460
617
  var childViews = this.get('childViews'),
461
618
  idx = childViews.indexOf(view) ;
462
619
  if (idx>=0) childViews.removeAt(idx);
463
-
620
+
464
621
  // The DOM will need some fixing up, note this on the view.
465
622
  view.parentViewDidChange() ;
466
-
623
+
467
624
  // notify views
468
625
  if (this.didRemoveChild) this.didRemoveChild(view);
469
626
  if (view.didRemoveFromParent) view.didRemoveFromParent(this) ;
470
-
627
+
471
628
  return this ;
472
629
  },
473
-
630
+
474
631
  /**
475
632
  Removes all children from the parentView.
476
-
477
- @returns {SC.View} receiver
633
+
634
+ @returns {SC.View} receiver
478
635
  */
479
636
  removeAllChildren: function() {
480
637
  var childViews = this.get('childViews'), view ;
@@ -483,11 +640,11 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
483
640
  }
484
641
  return this ;
485
642
  },
486
-
487
- /**
643
+
644
+ /**
488
645
  Removes the view from its parentView, if one is found. Otherwise
489
646
  does nothing.
490
-
647
+
491
648
  @returns {SC.View} receiver
492
649
  */
493
650
  removeFromParent: function() {
@@ -495,15 +652,15 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
495
652
  if (parent) parent.removeChild(this) ;
496
653
  return this ;
497
654
  },
498
-
655
+
499
656
  /**
500
- Replace the oldView with the specified view in the receivers childNodes
501
- array. This will also replace the DOM node of the oldView with the DOM
657
+ Replace the oldView with the specified view in the receivers childNodes
658
+ array. This will also replace the DOM node of the oldView with the DOM
502
659
  node of the new view in the receivers DOM.
503
-
504
- If the specified view already belongs to another parent, it will be
660
+
661
+ If the specified view already belongs to another parent, it will be
505
662
  removed from that view first.
506
-
663
+
507
664
  @param view {SC.View} the view to insert in the DOM
508
665
  @param view {SC.View} the view to remove from the DOM.
509
666
  @returns {SC.View} the receiver
@@ -513,76 +670,77 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
513
670
  view.beginPropertyChanges();
514
671
  oldView.beginPropertyChanges();
515
672
  this.beginPropertyChanges();
516
-
673
+
517
674
  this.insertBefore(view,oldView).removeChild(oldView) ;
518
-
675
+
519
676
  // resume notifications
520
677
  this.endPropertyChanges();
521
678
  oldView.endPropertyChanges();
522
- view.endPropertyChanges();
523
-
679
+ view.endPropertyChanges();
680
+
524
681
  return this;
525
682
  },
526
-
683
+
527
684
  /**
528
- Replaces the current array of child views with the new array of child
685
+ Replaces the current array of child views with the new array of child
529
686
  views.
530
-
687
+
531
688
  @param {Array} views views you want to add
532
689
  @returns {SC.View} receiver
533
690
  */
534
691
  replaceAllChildren: function(views) {
535
692
  var len = views.get('length'), idx;
536
-
693
+
537
694
  this.beginPropertyChanges();
538
695
  this.destroyLayer().removeAllChildren();
539
696
  for(idx=0;idx<len;idx++) this.appendChild(views.objectAt(idx));
540
697
  this.replaceLayer();
541
698
  this.endPropertyChanges();
542
-
699
+
543
700
  return this ;
544
701
  },
545
-
702
+
546
703
  /**
547
- Appends the specified view to the end of the receivers childViews array.
704
+ Appends the specified view to the end of the receivers childViews array.
548
705
  This is equivalent to calling insertBefore(view, null);
549
-
706
+
550
707
  @param view {SC.View} the view to insert
551
- @returns {SC.View} the receiver
708
+ @returns {SC.View} the receiver
552
709
  */
553
710
  appendChild: function(view) {
554
711
  return this.insertBefore(view, null);
555
712
  },
556
-
557
- /**
558
- This method is called whenever the receiver's parentView has changed.
559
- The default implementation of this method marks the view's display
713
+
714
+ /**
715
+ This method is called whenever the receiver's parentView has changed.
716
+ The default implementation of this method marks the view's display
560
717
  location as dirty so that it will update at the end of the run loop.
561
-
718
+
562
719
  You will not usually need to override or call this method yourself, though
563
720
  if you manually patch the parentView hierarchy for some reason, you should
564
721
  call this method to notify the view that it's parentView has changed.
565
-
722
+
566
723
  @returns {SC.View} receiver
567
724
  */
568
725
  parentViewDidChange: function() {
569
726
  this.recomputeIsVisibleInWindow() ;
570
-
727
+
728
+ this.resetBuildState();
571
729
  this.set('layerLocationNeedsUpdate', YES) ;
572
730
  this.invokeOnce(this.updateLayerLocationIfNeeded) ;
573
-
731
+
574
732
  // We also need to iterate down through the view hierarchy and invalidate
575
733
  // all our child view's caches for 'pane', since it could have changed.
576
734
  //
577
735
  // Note: In theory we could try to avoid this invalidation if we
578
736
  // do this only in cases where we "know" the 'pane' value might
579
737
  // have changed, but those cases are few and far between.
580
-
738
+
581
739
  this._invalidatePaneCacheForSelfAndAllChildViews();
582
-
740
+
583
741
  return this ;
584
742
  },
585
-
743
+
586
744
  /** @private
587
745
  We want to cache the 'pane' property, but it's impossible for us to
588
746
  declare a dependence on all properties that can affect the value. (For
@@ -594,38 +752,38 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
594
752
  _invalidatePaneCacheForSelfAndAllChildViews: function () {
595
753
  var childView, childViews = this.get('childViews'),
596
754
  len = childViews.length, idx ;
597
-
755
+
598
756
  this.notifyPropertyChange('pane');
599
-
757
+
600
758
  for (idx=0; idx<len; ++idx) {
601
759
  childView = childViews[idx];
602
760
  if (childView._invalidatePaneCacheForSelfAndAllChildViews) {
603
761
  childView._invalidatePaneCacheForSelfAndAllChildViews();
604
- }
762
+ }
605
763
  }
606
764
  },
607
-
765
+
608
766
  // ..........................................................
609
767
  // LAYER SUPPORT
610
- //
611
-
768
+ //
769
+
612
770
  /**
613
- Returns the current layer for the view. The layer for a view is only
614
- generated when the view first becomes visible in the window and even
771
+ Returns the current layer for the view. The layer for a view is only
772
+ generated when the view first becomes visible in the window and even
615
773
  then it will not be computed until you request this layer property.
616
-
774
+
617
775
  If the layer is not actually set on the view itself, then the layer will
618
776
  be found by calling this.findLayerInParentLayer().
619
-
777
+
620
778
  You can also set the layer by calling set on this property.
621
-
779
+
622
780
  @property {DOMElement} the layer
623
781
  */
624
782
  layer: function(key, value) {
625
783
  if (value !== undefined) {
626
784
  this._view_layer = value ;
627
-
628
- // no layer...attempt to discover it...
785
+
786
+ // no layer...attempt to discover it...
629
787
  } else {
630
788
  value = this._view_layer;
631
789
  if (!value) {
@@ -639,40 +797,40 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
639
797
  }
640
798
  return value ;
641
799
  }.property('isVisibleInWindow').cacheable(),
642
-
800
+
643
801
  /**
644
802
  Get a CoreQuery object for this view's layer, or pass in a selector string
645
803
  to get a CoreQuery object for a DOM node nested within this layer.
646
-
804
+
647
805
  @param {String} sel a CoreQuery-compatible selector string
648
806
  @returns {SC.CoreQuery} the CoreQuery object for the DOM node
649
807
  */
650
808
  $: function(sel) {
651
809
  var ret, layer = this.get('layer') ;
652
- // note: SC.$([]) returns an empty CoreQuery object. SC.$() would
810
+ // note: SC.$([]) returns an empty CoreQuery object. SC.$() would
653
811
  // return an object selecting the document.
654
812
  ret = !layer ? SC.$([]) : (sel === undefined) ? SC.$(layer) : SC.$(sel, layer) ;
655
813
  layer = null ; // avoid memory leak
656
814
  return ret ;
657
815
  },
658
-
816
+
659
817
  /**
660
818
  Returns the DOM element that should be used to hold child views when they
661
819
  are added/remove via DOM manipulation. The default implementation simply
662
820
  returns the layer itself. You can override this to return a DOM element
663
821
  within the layer.
664
-
822
+
665
823
  @property {DOMElement} the container layer
666
824
  */
667
825
  containerLayer: function() {
668
826
  return this.get('layer') ;
669
- }.property('layer').cacheable(),
670
-
827
+ }.property('layer').cacheable(),
828
+
671
829
  /**
672
830
  The ID to use when trying to locate the layer in the DOM. If you do not
673
831
  set the layerId explicitly, then the view's GUID will be used instead.
674
832
  This ID must be set at the time the view is created.
675
-
833
+
676
834
  @property {String}
677
835
  @readOnly
678
836
  */
@@ -681,7 +839,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
681
839
  if (this._layerId) return this._layerId;
682
840
  return SC.guidFor(this) ;
683
841
  }.property().cacheable(),
684
-
842
+
685
843
  _lastLayerId: null,
686
844
 
687
845
  /**
@@ -696,42 +854,42 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
696
854
  if (lastId && SC.View.views[lastId] === this) {
697
855
  delete SC.View.views[lastId];
698
856
  }
699
-
857
+
700
858
  // set the current one as the new old one
701
859
  this._lastLayerId = lid;
702
-
860
+
703
861
  // and add the new one
704
862
  SC.View.views[lid] = this;
705
-
863
+
706
864
  // and finally, set the actual layer id.
707
865
  if (layer) layer.id = lid;
708
866
  }
709
867
  }.observes("layerId"),
710
-
868
+
711
869
  /**
712
- Attempts to discover the layer in the parent layer. The default
870
+ Attempts to discover the layer in the parent layer. The default
713
871
  implementation looks for an element with an ID of layerId (or the view's
714
872
  guid if layerId is null). You can override this method to provide your
715
873
  own form of lookup. For example, if you want to discover your layer using
716
874
  a CSS class name instead of an ID.
717
-
875
+
718
876
  @param {DOMElement} parentLayer the parent's DOM layer
719
877
  @returns {DOMElement} the discovered layer
720
878
  */
721
879
  findLayerInParentLayer: function(parentLayer) {
722
880
  var layerId = this.get('layerId'),
723
881
  node, i, ilen, childNodes, elem, usedQuerySelector;
724
-
882
+
725
883
  // first, let's try the fast path...
726
884
  elem = document.getElementById(layerId) ;
727
-
885
+
728
886
  // TODO: use code generation to only really do this check on IE
729
887
  if (SC.browser.msie && elem && elem.id !== layerId) elem = null;
730
-
888
+
731
889
  // if no element was found the fast way, search down the parentLayer for
732
890
  // the element. This code should not be invoked very often. Usually a
733
891
  // DOM element will be discovered by the first method above.
734
- // This code uses a BFS algorithm as is expected to find the layer right
892
+ // This code uses a BFS algorithm as is expected to find the layer right
735
893
  // below the parent.
736
894
  if (!elem) {
737
895
  elem = parentLayer.firstChild ;
@@ -747,73 +905,73 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
747
905
  q.push(childNodes[i]);
748
906
  }
749
907
  }
750
- elem = null;
908
+ elem = null;
751
909
  }
752
-
910
+
753
911
  return elem;
754
912
  },
755
-
913
+
756
914
  /**
757
- Returns YES if the receiver is a subview of a given view or if it’s
915
+ Returns YES if the receiver is a subview of a given view or if it’s
758
916
  identical to that view. Otherwise, it returns NO.
759
-
917
+
760
918
  @property {SC.View} view
761
919
  */
762
920
  isDescendantOf: function(view) {
763
921
  var parentView = this.get('parentView');
764
-
922
+
765
923
  if(this===view) return YES;
766
924
  else if(parentView) return parentView.isDescendantOf(view);
767
925
  else return NO;
768
926
  },
769
-
927
+
770
928
  /**
771
- This method is invoked whenever a display property changes. It will set
929
+ This method is invoked whenever a display property changes. It will set
772
930
  the layerNeedsUpdate method to YES. If you need to perform additional
773
931
  setup whenever the display changes, you can override this method as well.
774
-
932
+
775
933
  @returns {SC.View} receiver
776
934
  */
777
935
  displayDidChange: function() {
778
936
  this.set('layerNeedsUpdate', YES) ;
779
937
  return this;
780
938
  },
781
-
939
+
782
940
  /**
783
- Setting this property to YES will cause the updateLayerIfNeeded method to
941
+ Setting this property to YES will cause the updateLayerIfNeeded method to
784
942
  be invoked at the end of the runloop. You can also force a view to update
785
- sooner by calling updateLayerIfNeeded() directly. The method will update
943
+ sooner by calling updateLayerIfNeeded() directly. The method will update
786
944
  the layer only if this property is YES.
787
-
945
+
788
946
  @property {Boolean}
789
947
  @test in updateLayer
790
948
  */
791
949
  layerNeedsUpdate: NO,
792
-
950
+
793
951
  /** @private
794
952
  Schedules the updateLayerIfNeeded method to run at the end of the runloop
795
953
  if layerNeedsUpdate is set to YES.
796
- */
954
+ */
797
955
  _view_layerNeedsUpdateDidChange: function() {
798
956
  if (this.get('layerNeedsUpdate')) {
799
957
  this.invokeOnce(this.updateLayerIfNeeded) ;
800
958
  }
801
959
  }.observes('layerNeedsUpdate'),
802
-
960
+
803
961
  /**
804
- Updates the layer only if the view is visible onscreen and if
962
+ Updates the layer only if the view is visible onscreen and if
805
963
  layerNeedsUpdate is set to YES. Normally you will not invoke this method
806
964
  directly. Instead you set the layerNeedsUpdate property to YES and this
807
965
  method will be called once at the end of the runloop.
808
-
966
+
809
967
  If you need to update view's layer sooner than the end of the runloop, you
810
968
  can call this method directly. If your view is not visible in the window
811
969
  but you want it to update anyway, then call this method, passing YES for
812
970
  the 'skipIsVisibleInWindowCheck' parameter.
813
-
971
+
814
972
  You should not override this method. Instead override updateLayer() or
815
973
  render().
816
-
974
+
817
975
  @returns {SC.View} receiver
818
976
  @test in updateLayer
819
977
  */
@@ -832,27 +990,51 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
832
990
 
833
991
  return this ;
834
992
  },
835
-
993
+
836
994
  /**
837
- This is the core method invoked to update a view layer whenever it has
838
- changed. This method simply creates a render context focused on the
995
+ This is the core method invoked to update a view layer whenever it has
996
+ changed. This method simply creates a render context focused on the
839
997
  layer element and then calls your render() method.
840
-
998
+
841
999
  You will not usually call or override this method directly. Instead you
842
1000
  should set the layerNeedsUpdate property to YES to cause this method to
843
1001
  run at the end of the run loop, or you can call updateLayerIfNeeded()
844
- to force the layer to update immediately.
845
-
1002
+ to force the layer to update immediately.
1003
+
846
1004
  Instead of overriding this method, consider overidding the render() method
847
1005
  instead, which is called both when creating and updating a layer. If you
848
1006
  do not want your render() method called when updating a layer, then you
849
1007
  should override this method instead.
850
-
851
- @returns {SC.View} receiver
1008
+
1009
+ @param optionalContext provided only for backwards-compatibility.
1010
+
1011
+ @returns {SC.View} receiver
852
1012
  */
853
- updateLayer: function() {
854
- var context = this.renderContext(this.get('layer')) ;
855
- this.prepareContext(context, NO) ;
1013
+ updateLayer: function(optionalContext) {
1014
+ var mixins, idx, len, hasLegacyRenderMethod;
1015
+
1016
+ var context = optionalContext || this.renderContext(this.get('layer')) ;
1017
+ this._renderLayerSettings(context, NO);
1018
+
1019
+ // If the render method takes two parameters, we assume that it is a
1020
+ // legacy implementation that takes context and firstTime. If it has only
1021
+ // one parameter, we assume it is the render delegates style that requires
1022
+ // only context. Note that, for backwards compatibility, the default
1023
+ // SC.View implementation of render uses the old style.
1024
+ hasLegacyRenderMethod = !this.update;
1025
+ // Call render with firstTime set to NO to indicate an update, rather than
1026
+ // full re-render, should be performed.
1027
+ if (hasLegacyRenderMethod) {
1028
+ this.render(context, NO);
1029
+ }
1030
+ else {
1031
+ this.update(context.$());
1032
+ }
1033
+ if (mixins = this.renderMixin) {
1034
+ len = mixins.length;
1035
+ for(idx=0; idx<len; ++idx) mixins[idx].call(this, context, NO) ;
1036
+ }
1037
+
856
1038
  context.update() ;
857
1039
  if (context._innerHTMLReplaced) {
858
1040
  var pane = this.get('pane');
@@ -871,51 +1053,57 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
871
1053
  }
872
1054
  return this ;
873
1055
  },
874
-
1056
+
875
1057
  /**
876
1058
  Creates a new renderContext with the passed tagName or element. You
877
1059
  can override this method to provide further customization to the context
878
1060
  if needed. Normally you will not need to call or override this method.
879
-
1061
+
880
1062
  @returns {SC.RenderContext}
881
1063
  */
882
1064
  renderContext: function(tagNameOrElement) {
883
1065
  return SC.RenderContext(tagNameOrElement) ;
884
1066
  },
885
-
1067
+
886
1068
  /**
887
1069
  Creates the layer by creating a renderContext and invoking the view's
888
1070
  render() method. This will only create the layer if the layer does not
889
1071
  already exist.
890
-
1072
+
891
1073
  When you create a layer, it is expected that your render() method will
892
- also render the HTML for all child views as well. This method will
1074
+ also render the HTML for all child views as well. This method will
893
1075
  notify the view along with any of its childViews that its layer has been
894
1076
  created.
895
-
1077
+
896
1078
  @returns {SC.View} receiver
897
1079
  */
898
1080
  createLayer: function() {
899
1081
  if (this.get('layer')) return this ; // nothing to do
900
-
1082
+
901
1083
  var context = this.renderContext(this.get('tagName')) ;
902
-
1084
+
903
1085
  // now prepare the content like normal.
904
- this.prepareContext(context, YES) ;
1086
+ this.renderToContext(context) ;
905
1087
  this.set('layer', context.element()) ;
906
-
1088
+
907
1089
  // now notify the view and its child views..
908
1090
  this._notifyDidCreateLayer() ;
909
-
1091
+
910
1092
  return this ;
911
1093
  },
912
-
913
- /** @private -
1094
+
1095
+ /** @private -
914
1096
  Invokes the receivers didCreateLayer() method if it exists and then
915
1097
  invokes the same on all child views.
916
1098
  */
917
1099
  _notifyDidCreateLayer: function() {
1100
+ this.notifyPropertyChange("layer");
918
1101
  if (this.didCreateLayer) this.didCreateLayer() ;
1102
+
1103
+ // Animation prep
1104
+ if (SC.platform.supportsCSSTransitions) this.resetAnimation();
1105
+
1106
+ // and notify others
919
1107
  var mixins = this.didCreateLayerMixin, len, idx,
920
1108
  childViews = this.get('childViews'),
921
1109
  childView;
@@ -923,7 +1111,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
923
1111
  len = mixins.length ;
924
1112
  for (idx=0; idx<len; ++idx) mixins[idx].call(this) ;
925
1113
  }
926
-
1114
+
927
1115
  len = childViews.length ;
928
1116
  for (idx=0; idx<len; ++idx) {
929
1117
  childView = childViews[idx];
@@ -939,52 +1127,53 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
939
1127
  childView._notifyDidCreateLayer() ;
940
1128
  }
941
1129
  },
942
-
1130
+
943
1131
  /**
944
- Destroys any existing layer along with the layer for any child views as
1132
+ Destroys any existing layer along with the layer for any child views as
945
1133
  well. If the view does not currently have a layer, then this method will
946
1134
  do nothing.
947
-
948
- If you implement willDestroyLayer() on your view or if any mixins
1135
+
1136
+ If you implement willDestroyLayer() on your view or if any mixins
949
1137
  implement willDestroLayerMixin(), then this method will be invoked on your
950
1138
  view before your layer is destroyed to give you a chance to clean up any
951
1139
  event handlers, etc.
952
-
953
- If you write a willDestroyLayer() handler, you can assume that your
1140
+
1141
+ If you write a willDestroyLayer() handler, you can assume that your
954
1142
  didCreateLayer() handler was called earlier for the same layer.
955
-
1143
+
956
1144
  Normally you will not call or override this method yourself, but you may
957
1145
  want to implement the above callbacks when it is run.
958
-
1146
+
959
1147
  @returns {SC.View} receiver
960
1148
  */
961
1149
  destroyLayer: function() {
962
1150
  var layer = this.get('layer') ;
963
1151
  if (layer) {
1152
+
964
1153
  // Now notify the view and its child views. It will also set the
965
1154
  // layer property to null.
966
1155
  this._notifyWillDestroyLayer() ;
967
-
1156
+
968
1157
  // do final cleanup
969
1158
  if (layer.parentNode) layer.parentNode.removeChild(layer) ;
970
1159
  layer = null ;
971
1160
  }
972
1161
  return this ;
973
1162
  },
974
-
1163
+
975
1164
  /**
976
1165
  Destroys and recreates the current layer. This can be more efficient than
977
1166
  modifying individual child views.
978
-
1167
+
979
1168
  @returns {SC.View} receiver
980
1169
  */
981
1170
  replaceLayer: function() {
982
1171
  this.destroyLayer();
983
- this.set('layerLocationNeedsUpdate', YES) ;
984
- this.invokeOnce(this.updateLayerLocationIfNeeded) ;
1172
+ //this.set('layerLocationNeedsUpdate', YES) ;
1173
+ this.invokeOnce(this.updateLayerLocation) ;
985
1174
  },
986
-
987
- /** @private -
1175
+
1176
+ /** @private -
988
1177
  Invokes willDestroyLayer() on view and child views. Then sets layer to
989
1178
  null for receiver.
990
1179
  */
@@ -996,88 +1185,150 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
996
1185
  len = mixins.length ;
997
1186
  for (idx=0; idx<len; ++idx) mixins[idx].call(this) ;
998
1187
  }
999
-
1188
+
1000
1189
  len = childViews.length ;
1001
1190
  for (idx=0; idx<len; ++idx) childViews[idx]._notifyWillDestroyLayer() ;
1002
-
1191
+
1003
1192
  this.set('layer', null) ;
1004
1193
  },
1005
-
1194
+
1195
+
1196
+
1197
+ /**
1198
+ @private
1199
+
1200
+ Renders to a context.
1201
+ Rendering only happens for the initial rendering. Further updates happen in updateLayer,
1202
+ and are not done to contexts, but to layers.
1203
+ Note: You should not generally override nor directly call this method. This method is only
1204
+ called by createLayer to set up the layer initially, and by renderChildViews, to write to
1205
+ a context.
1206
+
1207
+ @param {SC.RenderContext} context the render context.
1208
+ @param {Boolean} firstTime Provided for compatibility when rendering legacy views only.
1209
+ */
1210
+ renderToContext: function(context, firstTime) {
1211
+ var hasLegacyRenderMethod, mixins, idx, len;
1212
+
1213
+ this.beginPropertyChanges() ;
1214
+ this.set('layerNeedsUpdate', NO) ;
1215
+
1216
+ if (SC.none(firstTime)) firstTime = YES;
1217
+
1218
+ this._renderLayerSettings(context, firstTime);
1219
+
1220
+ // If the render method takes two parameters, we assume that it is a
1221
+ // legacy implementation that takes context and firstTime. If it has only
1222
+ // one parameter, we assume it is the render delegates style that requires
1223
+ // only context. Note that, for backwards compatibility, the default
1224
+ // SC.View implementation of render uses the old style.
1225
+ hasLegacyRenderMethod = !this.update;
1226
+
1227
+ // Let the render method handle rendering. If we have a render delegate
1228
+ // object set, it will be used there.
1229
+ if (hasLegacyRenderMethod) {
1230
+ this.render(context, firstTime);
1231
+ }
1232
+ // This view implements the render delegate protocol.
1233
+ else {
1234
+ if (firstTime) {
1235
+ this.render(context);
1236
+ } else {
1237
+ this.update(context.$());
1238
+ }
1239
+ }
1240
+
1241
+ if (mixins = this.renderMixin) {
1242
+ len = mixins.length;
1243
+ for(idx=0; idx<len; ++idx) mixins[idx].call(this, context, firstTime) ;
1244
+ }
1245
+
1246
+ this.endPropertyChanges() ;
1247
+ },
1248
+
1249
+ _renderLayerSettings: function(context, firstTime) {
1250
+ context.resetClassNames();
1251
+ context.resetStyles();
1252
+
1253
+ var theme = this.get('theme');
1254
+ var themeClassNames = theme.classNames, idx, len = themeClassNames.length;
1255
+
1256
+ for (idx = 0; idx < len; idx++) {
1257
+ context.addClass(themeClassNames[idx]);
1258
+ }
1259
+
1260
+ var renderDelegate = this.get('renderDelegate');
1261
+ if (renderDelegate && renderDelegate.name) {
1262
+ context.addClass(renderDelegate.name);
1263
+ }
1264
+
1265
+ context.addClass(this.get('classNames'));
1266
+
1267
+ var cursor = this.get('cursor');
1268
+ if (cursor) context.addClass(cursor.get('className'));
1269
+
1270
+ if (this.get('isTextSelectable')) context.addClass('allow-select');
1271
+ if (!this.get('isEnabled')) context.addClass('disabled');
1272
+ if (!this.get('isVisible')) context.addClass('hidden');
1273
+ if (this.get('isFirstResponder')) context.addClass('focus');
1274
+ if (this.get('useStaticLayout')) context.addClass('sc-static-layout');
1275
+
1276
+ context.id(this.get('layerId'));
1277
+ context.attr('role', this.get('ariaRole'));
1278
+ if (!this.get('isEnabled')) context.attr('aria-disabled', 'true');
1279
+ if (this.get('backgroundColor')) {
1280
+ context.css('backgroundColor', this.get('backgroundColor'));
1281
+ }
1282
+
1283
+ this.renderLayout(context, firstTime);
1284
+ },
1285
+
1006
1286
  /**
1287
+ @private
1288
+
1007
1289
  Invoked by createLayer() and updateLayer() to actually render a context.
1008
- This method calls the render() method on your view along with any
1290
+ This method calls the render() method on your view along with any
1009
1291
  renderMixin() methods supplied by mixins you might have added.
1010
-
1011
- You should not override this method directly. However, you might call
1012
- this method if you choose to override updateLayer() or createLayer().
1013
-
1292
+
1293
+ You should not override this method directly. Nor should you call it. It is OLD.
1294
+
1014
1295
  @param {SC.RenderContext} context the render context
1015
1296
  @param {Boolean} firstTime YES if this is creating a layer
1016
1297
  @returns {void}
1017
1298
  */
1018
1299
  prepareContext: function(context, firstTime) {
1019
- var mixins, len, idx, layerId, bgcolor, cursor, classNames;
1020
-
1021
- // do some initial setup only needed at create time.
1300
+ // eventually, firstTime will be removed because it is ugly.
1301
+ // for now, we will sense whether we are doing things the ugly way or not.
1302
+ // if ugly, we will allow updates through.
1303
+ if (SC.none(firstTime)) firstTime = YES; // the GOOD code path :)
1022
1304
  if (firstTime) {
1023
- // TODO: seems like things will break later if SC.guidFor(this) is used
1024
-
1025
- layerId = this.layerId ? this.get('layerId') : SC.guidFor(this) ;
1026
- context.id(layerId).classNames(this.get('classNames'), YES) ;
1027
- this.renderLayout(context, firstTime) ;
1028
- }else{
1029
- context.resetClassNames();
1030
- context.classNames(this.get('classNames'), YES);
1031
- }
1032
-
1033
- // do some standard setup...
1034
- classNames = [];
1035
- if (this.get('isTextSelectable')) classNames.push('allow-select') ;
1036
- if (!this.get('isEnabled')) classNames.push('disabled') ;
1037
- if (!this.get('isVisible')) classNames.push('hidden') ;
1038
- if (this.get('isFirstResponder')) classNames.push('focus');
1039
- if (this.get('useStaticLayout')) classNames.push('sc-static-layout');
1040
-
1041
- bgcolor = this.get('backgroundColor');
1042
- if (bgcolor) context.addStyle('backgroundColor', bgcolor);
1043
-
1044
- // Sets cursor class, if present.
1045
- cursor = this.get('cursor');
1046
- if (!cursor && this.get('shouldInheritCursor')) {
1047
- // If this view has no cursor and should inherit it from the parent,
1048
- // then it sets its own cursor view. This sets the cursor rather than
1049
- // simply using the parent's cursor object so that its cursorless
1050
- // childViews can also inherit it.
1051
- cursor = this.getPath('parentView.cursor');
1052
- }
1053
-
1054
- if (SC.typeOf(cursor) === SC.T_STRING) {
1055
- cursor = SC.objectForPropertyPath(cursor);
1056
- }
1057
-
1058
- if (cursor instanceof SC.Cursor) {
1059
- classNames.push(cursor.get('className')) ;
1060
- }
1061
-
1062
- // Doing a single call to 'addClass' is faster than multiple.
1063
- context.addClass(classNames);
1064
-
1065
- this.beginPropertyChanges() ;
1066
- this.set('layerNeedsUpdate', NO) ;
1067
- this.render(context, firstTime) ;
1068
- if (mixins = this.renderMixin) {
1069
- len = mixins.length;
1070
- for(idx=0; idx<len; ++idx) mixins[idx].call(this, context, firstTime) ;
1305
+ this.renderToContext(context);
1306
+ } else {
1307
+ this.updateLayer(context);
1071
1308
  }
1072
- this.endPropertyChanges() ;
1073
1309
  },
1074
-
1310
+
1311
+ /**
1312
+ [RO] Pass this object as the data source for render delegates. This proxy object
1313
+ for the view relays requests for properties like 'title' to 'displayTitle'
1314
+ as necessary.
1315
+
1316
+ If you ever communicate with your view's render delegate, you should pass this
1317
+ object as the data source.
1318
+
1319
+ The proxy that forwards RenderDelegate requests for properties to the view,
1320
+ handling display*, keeps track of the delegate's state, etc.
1321
+ */
1322
+ renderDelegateProxy: function() {
1323
+ return SC.View._RenderDelegateProxy.createForView(this);
1324
+ }.property('renderDelegate').cacheable(),
1325
+
1075
1326
  /**
1076
1327
  Your render method should invoke this method to render any child views,
1077
1328
  especially if this is the first time the view will be rendered. This will
1078
1329
  walk down the childView chain, rendering all of the children in a nested
1079
1330
  way.
1080
-
1331
+
1081
1332
  @param {SC.RenderContext} context the context
1082
1333
  @param {Boolean} firstName true if the layer is being created
1083
1334
  @returns {SC.RenderContext} the render context
@@ -1089,42 +1340,114 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1089
1340
  view = cv[idx] ;
1090
1341
  if (!view) continue;
1091
1342
  context = context.begin(view.get('tagName')) ;
1092
- view.prepareContext(context, firstTime) ;
1343
+ view.renderToContext(context, firstTime);
1093
1344
  context = context.end() ;
1094
1345
  }
1095
- return context ;
1346
+ return context;
1096
1347
  },
1097
-
1348
+
1349
+ /**
1350
+ The object to which rendering and updating the HTML representation of this
1351
+ view should be delegated.
1352
+
1353
+ By default, views are responsible for creating their own HTML
1354
+ representation. In some cases, however, you may want to create an object
1355
+ that is responsible for rendering all views of a certain type. For example,
1356
+ you may want rendering of SC.ButtonView to be controlled by an object that
1357
+ is specific to the current theme.
1358
+
1359
+ By setting a render delegate, the render and update methods will be called
1360
+ on that object instead of the view itself.
1361
+
1362
+ For your convenience, the view will provide its displayProperties to the
1363
+ RenderDelegate. In some cases, you may have a conflict between the RenderDelegate's
1364
+ API and your view's. For instance, you may have a 'value' property that is
1365
+ any number, but the render delegate expects a percentage. Make a 'displayValue'
1366
+ property, add _it_ to displayProperties instead of 'value', and the Render Delegate
1367
+ will automatically use that when it wants to find 'value.'
1368
+
1369
+ You can also set the render delegate by using the 'renderDelegateName' property.
1370
+
1371
+ @property {Object}
1372
+ */
1373
+ renderDelegate: function(key, value) {
1374
+ if (value) this._setRenderDelegate = value;
1375
+ if (this._setRenderDelegate) return this._setRenderDelegate;
1376
+
1377
+ // If this view does not have a render delegate but has
1378
+ // renderDelegateName set, try to retrieve the render delegate from the
1379
+ // theme.
1380
+ var renderDelegateName = this.get('renderDelegateName'), renderDelegate;
1381
+
1382
+ if (renderDelegateName) {
1383
+ renderDelegate = this.get('theme')[renderDelegateName];
1384
+ if (!renderDelegate) {
1385
+ throw "%@: Unable to locate render delegate \"%@\" in theme.".fmt(this, renderDelegateName);
1386
+ }
1387
+
1388
+ return renderDelegate;
1389
+ }
1390
+
1391
+ return null;
1392
+ }.property('renderDelegateName', 'theme'),
1393
+
1394
+ /**
1395
+ The name of the property of the current theme that contains the render
1396
+ delegate to use for this view.
1397
+
1398
+ By default, views are responsible for creating their own HTML
1399
+ representation. You can tell the view to instead delegate rendering to the
1400
+ theme by setting this property to the name of the corresponding property
1401
+ of the theme.
1402
+
1403
+ For example, to tell the view that it should render using the
1404
+ SC.ButtonView render delegate, set this property to
1405
+ 'buttonRenderDelegate'. When the view is created, it will retrieve the
1406
+ buttonRenderDelegate property from its theme and set the renderDelegate
1407
+ property to that object.
1408
+ */
1409
+ renderDelegateName: null,
1410
+
1098
1411
  /**
1099
- Invoked whenever your view needs to be rendered, including when the view's
1100
- layer is first created and any time in the future when it needs to be
1101
- updated.
1102
-
1103
- You will normally override this method in your subclassed views to
1104
- provide whatever drawing functionality you will need in order to
1412
+ Invoked whenever your view needs to create its HTML representation.
1413
+
1414
+ You will normally override this method in your subclassed views to
1415
+ provide whatever drawing functionality you will need in order to
1105
1416
  render your content.
1106
-
1107
- You can use the passed firstTime property to determine whether or not
1108
- you need to completely re-render the view or only update the surrounding
1109
- HTML.
1110
-
1111
- The default implementation of this method simply calls renderChildViews()
1112
- if this is the first time you are rendering, or null otherwise.
1113
-
1417
+
1418
+ This method is usually only called once per view. After that, the update
1419
+ method will be called to allow you to update the existing HTML
1420
+ representation.
1421
+
1422
+
1423
+ The default implementation of this method calls renderChildViews().
1424
+
1425
+ For backwards compatibility, this method will also call the appropriate
1426
+ method on a render delegate object, if your view has one.
1427
+
1114
1428
  @param {SC.RenderContext} context the render context
1115
- @param {Boolean} firstTime YES if this is creating a layer
1116
1429
  @returns {void}
1117
1430
  */
1118
1431
  render: function(context, firstTime) {
1119
- if (firstTime) this.renderChildViews(context, firstTime) ;
1432
+ var renderDelegate = this.get('renderDelegate');
1433
+
1434
+ if (renderDelegate) {
1435
+ if (firstTime) {
1436
+ renderDelegate.render(this.get('renderDelegateProxy'), context);
1437
+ } else {
1438
+ renderDelegate.update(this.get('renderDelegateProxy'), context.$());
1439
+ }
1440
+ }
1441
+
1442
+ if (firstTime) this.renderChildViews(context, firstTime);
1120
1443
  },
1121
-
1122
-
1123
- /** @private -
1444
+
1445
+
1446
+ /** @private -
1124
1447
  Invokes the receivers didAppendLayerToDocument() method if it exists and
1125
- then invokes the same on all child views.
1448
+ then invokes the same on all child views.
1126
1449
  */
1127
-
1450
+
1128
1451
  _notifyDidAppendToDocument: function() {
1129
1452
  if (this.didAppendToDocument) this.didAppendToDocument();
1130
1453
 
@@ -1136,7 +1459,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1136
1459
  }
1137
1460
  }
1138
1461
  },
1139
-
1462
+
1140
1463
  childViewsObserver: function(){
1141
1464
  var childViews = this.get('childViews'), i, iLen, child;
1142
1465
  for(i=0, iLen = childViews.length; i<iLen; i++){
@@ -1144,56 +1467,91 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1144
1467
  if(child._notifyDidAppendToDocument){
1145
1468
  child._notifyDidAppendToDocument();
1146
1469
  }
1147
- }
1470
+ }
1148
1471
  }.observes('childViews'),
1149
-
1472
+
1150
1473
  // ..........................................................
1151
1474
  // STANDARD RENDER PROPERTIES
1152
- //
1153
-
1154
- /**
1475
+ //
1476
+
1477
+ /**
1155
1478
  Tag name for the view's outer element. The tag name is only used when
1156
1479
  a layer is first created. If you change the tagName for an element, you
1157
1480
  must destroy and recreate the view layer.
1158
-
1481
+
1159
1482
  @property {String}
1160
1483
  */
1161
1484
  tagName: 'div',
1162
-
1485
+
1486
+ /**
1487
+ The WAI-ARIA role of the control represented by this view. For example, a
1488
+ button may have a role of type 'button', or a pane may have a role of
1489
+ type 'alertdialog'. This property is used by assistive software to help
1490
+ visually challenged users navigate rich web applications.
1491
+
1492
+ The full list of valid WAI-ARIA roles is available at:
1493
+ http://www.w3.org/TR/wai-aria/roles#roles_categorization
1494
+
1495
+ @property {String}
1496
+ */
1497
+ ariaRole: null,
1498
+
1163
1499
  /**
1164
- Standard CSS class names to apply to the view's outer element. This
1500
+ Standard CSS class names to apply to the view's outer element. This
1165
1501
  property automatically inherits any class names defined by the view's
1166
- superclasses as well.
1167
-
1502
+ superclasses as well.
1503
+
1168
1504
  @property {Array}
1169
1505
  */
1170
1506
  classNames: ['sc-view'],
1171
-
1507
+
1172
1508
  /**
1173
- Tool tip property that will be set to the title attribute on the HTML
1509
+ Tool tip property that will be set to the title attribute on the HTML
1174
1510
  rendered element.
1175
-
1511
+
1176
1512
  @property {String}
1177
1513
  */
1178
1514
  toolTip: null,
1179
1515
 
1516
+ /**
1517
+ The computed tooltip. This is generated by localizing the toolTip
1518
+ property if necessary.
1519
+
1520
+ @property {String}
1521
+ */
1522
+ displayToolTip: function() {
1523
+ var ret = this.get('toolTip');
1524
+ return (ret && this.get('localize')) ? ret.loc() : (ret || '');
1525
+ }.property('toolTip','localize').cacheable(),
1526
+
1180
1527
  /**
1181
1528
  Determines if the user can select text within the view. Normally this is
1182
1529
  set to NO to disable text selection. You should set this to YES if you
1183
1530
  are creating a view that includes editable text. Otherwise, settings this
1184
- to YES will probably make your controls harder to use and it is not
1531
+ to YES will probably make your controls harder to use and it is not
1185
1532
  recommended.
1186
-
1533
+
1187
1534
  @property {Boolean}
1188
1535
  @readOnly
1189
1536
  */
1190
1537
  isTextSelectable: NO,
1191
-
1192
- /**
1538
+
1539
+ /**
1193
1540
  You can set this array to include any properties that should immediately
1194
1541
  invalidate the display. The display will be automatically invalidated
1195
1542
  when one of these properties change.
1196
1543
 
1544
+ These are the properties that will be visible to any Render Delegate.
1545
+ When the RenderDelegate asks for a property it needs, the view checks the
1546
+ displayProperties array. It first looks for the property name prefixed
1547
+ by 'display'; for instance, if the render delegate needs a 'title',
1548
+ the view will attempt to find 'displayTitle'. If there is no 'displayTitle'
1549
+ in displayProperties, the view will then try 'title'. If 'title' is not
1550
+ in displayProperties either, an error will be thrown.
1551
+
1552
+ This allows you to avoid collisions between your view's API and the Render
1553
+ Delegate's API.
1554
+
1197
1555
  Implementation note: 'isVisible' is also effectively a display property,
1198
1556
  but it is not declared as such because the same effect is implemented
1199
1557
  inside _sc_isVisibleDidChange(). This avoids having two observers on
@@ -1205,49 +1563,62 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1205
1563
  @readOnly
1206
1564
  */
1207
1565
  displayProperties: ['isFirstResponder'],
1208
-
1209
- /**
1210
- You can set this to an SC.Cursor instance; its class name will
1211
- automatically be added to the layer's classNames, allowing you
1212
- to efficiently change the cursor for a large group of views with
1213
- just one change to the SC.Cursor object. The cursor property
1214
- is only used when the layer is created, so if you need to change
1215
- it to a different cursor object, you will have to destroy and
1216
- recreate the view layer. (In this case you might investigate
1217
- setting cursors using CSS directly instead of SC.Cursor.)
1218
-
1566
+
1567
+ /**
1568
+ You can set this to an SC.Cursor instance; whenever that SC.Cursor's
1569
+ 'cursorStyle' changes, the cursor for this view will automatically
1570
+ be updated to match. This allows you to coordinate the cursors of
1571
+ many views by making them all share the same cursor instance.
1572
+
1573
+ For example, SC.SplitView uses this ensure that it and all of its
1574
+ children have the same cursor while dragging, so that whether you are
1575
+ hovering over the divider or another child of the split view, the
1576
+ proper cursor is visible.
1577
+
1219
1578
  @property {SC.Cursor String}
1220
1579
  */
1221
- cursor: null,
1222
-
1580
+ cursor: function(key, value) {
1581
+ var parent;
1582
+
1583
+ if (value) this._setCursor = value;
1584
+ if (this._setCursor !== undefined) return this._setCursor;
1585
+
1586
+ parent = this.get('parentView');
1587
+ if (this.get('shouldInheritCursor') && parent) {
1588
+ return parent.get('cursor');
1589
+ }
1590
+
1591
+ return null;
1592
+ }.property('parentView', 'shouldInheritCursor').cacheable(),
1593
+
1223
1594
  /**
1224
1595
  A child view without a cursor of its own inherits its parent's cursor by
1225
1596
  default. Set this to NO to prevent this behavior.
1226
-
1597
+
1227
1598
  @property {Boolean}
1228
1599
  */
1229
1600
  shouldInheritCursor: YES,
1230
-
1601
+
1231
1602
  // ..........................................................
1232
1603
  // LAYER LOCATION
1233
- //
1234
-
1604
+ //
1605
+
1235
1606
  /**
1236
- Set to YES when the view's layer location is dirty. You can call
1607
+ Set to YES when the view's layer location is dirty. You can call
1237
1608
  updateLayerLocationIfNeeded() to clear this flag if it is set.
1238
-
1609
+
1239
1610
  @property {Boolean}
1240
1611
  */
1241
1612
  layerLocationNeedsUpdate: NO,
1242
-
1613
+
1243
1614
  /**
1244
1615
  Calls updateLayerLocation(), but only if the view's layer location
1245
- currently needs to be updated. This method is called automatically at
1616
+ currently needs to be updated. This method is called automatically at
1246
1617
  the end of a run loop if you have called parentViewDidChange() at some
1247
1618
  point.
1248
-
1619
+
1249
1620
  @property {Boolean} force This property is ignored.
1250
- @returns {SC.View} receiver
1621
+ @returns {SC.View} receiver
1251
1622
  @test in updateLayerLocation
1252
1623
  */
1253
1624
  updateLayerLocationIfNeeded: function(force) {
@@ -1256,12 +1627,12 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1256
1627
  }
1257
1628
  return this ;
1258
1629
  },
1259
-
1630
+
1260
1631
  /**
1261
- This method is called when a view changes its location in the view
1262
- hierarchy. This method will update the underlying DOM-location of the
1632
+ This method is called when a view changes its location in the view
1633
+ hierarchy. This method will update the underlying DOM-location of the
1263
1634
  layer so that it reflects the new location.
1264
-
1635
+
1265
1636
  @returns {SC.View} receiver
1266
1637
  */
1267
1638
  updateLayerLocation: function() {
@@ -1270,17 +1641,17 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1270
1641
  var node = this.get('layer'),
1271
1642
  parentView = this.get('parentView'),
1272
1643
  parentNode = parentView ? parentView.get('containerLayer') : null ;
1273
-
1274
- // remove node from current parentNode if the node does not match the new
1644
+
1645
+ // remove node from current parentNode if the node does not match the new
1275
1646
  // parent node.
1276
1647
  if (node && node.parentNode && node.parentNode !== parentNode) {
1277
1648
  node.parentNode.removeChild(node);
1278
1649
  }
1279
-
1650
+
1280
1651
  // CASE 1: no new parentView. just remove from parent (above).
1281
1652
  if (!parentView) {
1282
1653
  if (node && node.parentNode) node.parentNode.removeChild(node);
1283
-
1654
+
1284
1655
  // CASE 2: parentView has no layer, view has layer. destroy layer
1285
1656
  // CASE 3: parentView has no layer, view has no layer, nothing to do
1286
1657
  } else if (!parentNode) {
@@ -1288,7 +1659,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1288
1659
  if (node.parentNode) node.parentNode.removeChild(node);
1289
1660
  this.destroyLayer();
1290
1661
  }
1291
-
1662
+
1292
1663
  // CASE 4: parentView has layer, view has no layer. create layer & add
1293
1664
  // CASE 5: parentView has layer, view has layer. move layer
1294
1665
  } else {
@@ -1297,34 +1668,34 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1297
1668
  node = this.get('layer') ;
1298
1669
  if (!node) return; // can't do anything without a node.
1299
1670
  }
1300
-
1671
+
1301
1672
  var siblings = parentView.get('childViews'),
1302
1673
  nextView = siblings.objectAt(siblings.indexOf(this)+1),
1303
1674
  nextNode = (nextView) ? nextView.get('layer') : null ;
1304
-
1675
+
1305
1676
  // before we add to parent node, make sure that the nextNode exists...
1306
1677
  if (nextView && (!nextNode || nextNode.parentNode!==parentNode)) {
1307
1678
  nextView.updateLayerLocationIfNeeded() ;
1308
1679
  nextNode = nextView.get('layer') ;
1309
1680
  }
1310
-
1681
+
1311
1682
  // add to parentNode if needed.
1312
1683
  if ((node.parentNode!==parentNode) || (node.nextSibling!==nextNode)) {
1313
1684
  parentNode.insertBefore(node, nextNode) ;
1314
1685
  }
1315
1686
  }
1316
-
1687
+
1317
1688
  parentNode = parentView = node = nextNode = null ; // avoid memory leaks
1318
1689
 
1319
1690
  this.set('layerLocationNeedsUpdate', NO) ;
1320
1691
 
1321
- return this ;
1692
+ return this ;
1322
1693
  },
1323
-
1694
+
1324
1695
  // .......................................................
1325
1696
  // SC.RESPONDER SUPPORT
1326
1697
  //
1327
-
1698
+
1328
1699
  /** @property
1329
1700
  The nextResponder is usually the parentView.
1330
1701
  */
@@ -1332,65 +1703,65 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1332
1703
  return this.get('parentView') ;
1333
1704
  }.property('parentView').cacheable(),
1334
1705
 
1335
-
1706
+
1336
1707
  /** @property
1337
- Set to YES if your view is willing to accept first responder status. This
1708
+ Set to YES if your view is willing to accept first responder status. This
1338
1709
  is used when calculcating key responder loop.
1339
1710
  */
1340
1711
  acceptsFirstResponder: NO,
1341
1712
 
1342
1713
  // ..........................................................
1343
1714
  // KEY RESPONDER
1344
- //
1345
-
1715
+ //
1716
+
1346
1717
  /** @property
1347
- YES if the view is currently first responder and the pane the view belongs
1348
- to is also key pane. While this property is set, you should expect to
1718
+ YES if the view is currently first responder and the pane the view belongs
1719
+ to is also key pane. While this property is set, you should expect to
1349
1720
  receive keyboard events.
1350
1721
  */
1351
1722
  isKeyResponder: NO,
1352
1723
 
1353
1724
  /**
1354
- This method is invoked just before you lost the key responder status.
1355
- The passed view is the view that is about to gain keyResponder status.
1356
- This gives you a chance to do any early setup. Remember that you can
1357
- gain/lose key responder status either because another view in the same
1358
- pane is becoming first responder or because another pane is about to
1725
+ This method is invoked just before you lost the key responder status.
1726
+ The passed view is the view that is about to gain keyResponder status.
1727
+ This gives you a chance to do any early setup. Remember that you can
1728
+ gain/lose key responder status either because another view in the same
1729
+ pane is becoming first responder or because another pane is about to
1359
1730
  become key.
1360
-
1731
+
1361
1732
  @param {SC.Responder} responder
1362
1733
  */
1363
1734
  willLoseKeyResponderTo: function(responder) {},
1364
-
1735
+
1365
1736
  /**
1366
- This method is invoked just before you become the key responder. The
1367
- passed view is the view that is about to lose keyResponder status. You
1737
+ This method is invoked just before you become the key responder. The
1738
+ passed view is the view that is about to lose keyResponder status. You
1368
1739
  can use this to do any setup before the view changes.
1369
- Remember that you can gain/lose key responder status either because
1370
- another view in the same pane is becoming first responder or because
1740
+ Remember that you can gain/lose key responder status either because
1741
+ another view in the same pane is becoming first responder or because
1371
1742
  another pane is about to become key.
1372
-
1743
+
1373
1744
  @param {SC.Responder} responder
1374
1745
  */
1375
1746
  willBecomeKeyResponderFrom: function(responder) {},
1376
-
1747
+
1377
1748
  /**
1378
1749
  Invokved just after the responder loses key responder status.
1379
1750
  */
1380
1751
  didLoseKeyResponderTo: function(responder) {},
1381
-
1752
+
1382
1753
  /**
1383
1754
  Invoked just after the responder gains key responder status.
1384
1755
  */
1385
1756
  didBecomeKeyResponderFrom: function(responder) {},
1386
-
1757
+
1387
1758
  /**
1388
- This method will process a key input event, attempting to convert it to
1389
- an appropriate action method and sending it up the responder chain. The
1390
- event is converted using the SC.KEY_BINDINGS hash, which maps key events
1391
- into method names. If no key binding is found, then the key event will
1759
+ This method will process a key input event, attempting to convert it to
1760
+ an appropriate action method and sending it up the responder chain. The
1761
+ event is converted using the SC.KEY_BINDINGS hash, which maps key events
1762
+ into method names. If no key binding is found, then the key event will
1392
1763
  be passed along using an insertText() method.
1393
-
1764
+
1394
1765
  @param {SC.Event} event
1395
1766
  @returns {Object} object that handled event, if any
1396
1767
  */
@@ -1409,11 +1780,11 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1409
1780
  }
1410
1781
  return handler ;
1411
1782
  }
1412
- }
1783
+ }
1413
1784
 
1414
1785
  if (chr && this.respondsTo('insertText')) {
1415
- // if we haven't returned yet and there is plain text, then do an insert
1416
- // of the text. Since this is not an action, do not send it up the
1786
+ // if we haven't returned yet and there is plain text, then do an insert
1787
+ // of the text. Since this is not an action, do not send it up the
1417
1788
  // responder chain.
1418
1789
  ret = this.insertText(chr, event);
1419
1790
  return ret ? (ret===YES ? this : ret) : null ; // map YES|NO => this|nil
@@ -1421,29 +1792,29 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1421
1792
 
1422
1793
  return null ; //nothing to do.
1423
1794
  },
1424
-
1795
+
1425
1796
  /**
1426
- This method is invoked by interpretKeyEvents() when you receive a key
1427
- event matching some plain text. You can use this to actually insert the
1797
+ This method is invoked by interpretKeyEvents() when you receive a key
1798
+ event matching some plain text. You can use this to actually insert the
1428
1799
  text into your application, if needed.
1429
-
1800
+
1430
1801
  @param {SC.Event} event
1431
1802
  @returns {Object} receiver or object that handled event
1432
1803
  */
1433
1804
  insertText: function(chr) {
1434
1805
  return NO ;
1435
1806
  },
1436
-
1807
+
1437
1808
  /**
1438
- Recursively travels down the view hierarchy looking for a view that
1439
- implements the key equivalent (returning to YES to indicate it handled
1440
- the event). You can override this method to handle specific key
1809
+ Recursively travels down the view hierarchy looking for a view that
1810
+ implements the key equivalent (returning to YES to indicate it handled
1811
+ the event). You can override this method to handle specific key
1441
1812
  equivalents yourself.
1442
-
1813
+
1443
1814
  The keystring is a string description of the key combination pressed.
1444
1815
  The evt is the event itself. If you handle the equivalent, return YES.
1445
1816
  Otherwise, you should just return sc_super.
1446
-
1817
+
1447
1818
  @param {String} keystring
1448
1819
  @param {SC.Event} evt
1449
1820
  @returns {Boolean}
@@ -1458,43 +1829,43 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1458
1829
  }
1459
1830
  return ret ;
1460
1831
  },
1461
-
1832
+
1462
1833
  /**
1463
1834
  Optionally points to the next key view that should gain focus when tabbing
1464
1835
  through an interface. If this is not set, then the next key view will
1465
1836
  be set automatically to the next child.
1466
1837
  */
1467
1838
  nextKeyView: null,
1468
-
1839
+
1469
1840
  /**
1470
1841
  Computes the next valid key view, possibly returning the receiver or null.
1471
1842
  This is the next key view that acceptsFirstResponder.
1472
-
1843
+
1473
1844
  @property
1474
1845
  @type SC.View
1475
1846
  */
1476
1847
  nextValidKeyView: function() {
1477
- var seen = [],
1848
+ var seen = [],
1478
1849
  rootView = this.get('pane'), ret = this.get('nextKeyView');
1479
-
1850
+
1480
1851
  if(!ret) ret = rootView._computeNextValidKeyView(this, seen);
1481
-
1852
+
1482
1853
  if(SC.TABBING_ONLY_INSIDE_DOCUMENT && !ret) {
1483
1854
  ret = rootView._computeNextValidKeyView(rootView, seen);
1484
1855
  }
1485
-
1856
+
1486
1857
  return ret ;
1487
1858
  }.property('nextKeyView'),
1488
-
1859
+
1489
1860
  _computeNextValidKeyView: function(currentView, seen) {
1490
1861
  var ret = this.get('nextKeyView'),
1491
1862
  children, i, childLen, child;
1492
- if(this !== currentView && seen.indexOf(currentView)!=-1 &&
1863
+ if(this !== currentView && seen.indexOf(currentView)!=-1 &&
1493
1864
  this.get('acceptsFirstResponder') && this.get('isVisibleInWindow')){
1494
1865
  return this;
1495
1866
  }
1496
1867
  seen.push(this); // avoid cycles
1497
-
1868
+
1498
1869
  // find next sibling
1499
1870
  if (!ret) {
1500
1871
  children = this.get('childViews');
@@ -1509,33 +1880,33 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1509
1880
  }
1510
1881
  return ret ;
1511
1882
  },
1512
-
1883
+
1513
1884
  /**
1514
1885
  Optionally points to the previous key view that should gain focus when
1515
- tabbing through the interface. If this is not set then the previous
1886
+ tabbing through the interface. If this is not set then the previous
1516
1887
  key view will be set automatically to the previous child.
1517
1888
  */
1518
1889
  previousKeyView: null,
1519
1890
 
1520
1891
  /**
1521
- Computes the previous valid key view, possibly returning the receiver or
1892
+ Computes the previous valid key view, possibly returning the receiver or
1522
1893
  null. This is the previous key view that acceptsFirstResponder.
1523
-
1894
+
1524
1895
  @property
1525
1896
  @type SC.View
1526
1897
  */
1527
1898
  previousValidKeyView: function() {
1528
1899
  var seen = [],
1529
- rootView = this.pane(), ret = this.get('previousKeyView');
1900
+ rootView = this.pane(), ret = this.get('previousKeyView');
1530
1901
  if(!ret) ret = rootView._computePreviousValidKeyView(this, seen);
1531
1902
  return ret ;
1532
1903
  }.property('previousKeyView'),
1533
-
1534
- _computePreviousValidKeyView: function(currentView, seen) {
1904
+
1905
+ _computePreviousValidKeyView: function(currentView, seen) {
1535
1906
  var ret = this.get('previousKeyView'),
1536
1907
  children, i, child;
1537
-
1538
- if(this !== currentView && seen.indexOf(currentView)!=-1 &&
1908
+
1909
+ if(this !== currentView && seen.indexOf(currentView)!=-1 &&
1539
1910
  this.get('acceptsFirstResponder') && this.get('isVisibleInWindow')){
1540
1911
  return this;
1541
1912
  }
@@ -1559,52 +1930,64 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1559
1930
  // .......................................................
1560
1931
  // CORE DISPLAY METHODS
1561
1932
  //
1562
-
1563
- /** @private
1564
- Setup a view, but do not finish waking it up.
1933
+
1934
+ /** @private
1935
+ Setup a view, but do not finish waking it up.
1565
1936
  - configure childViews
1566
- - generate DOM + plug in outlets/childViews unless rootElement is defined
1567
- - register the view with the global views hash, which is used for mgmt
1937
+ - Determine the view's theme
1938
+ - Fetch a render delegate from the theme, if necessary
1939
+ - register the view with the global views hash, which is used for event
1940
+ dispatch
1568
1941
  */
1569
1942
  init: function() {
1570
- var parentView, path, root, idx, len, lp, dp ;
1571
-
1572
- sc_super() ;
1943
+ var parentView = this.get('parentView'),
1944
+ theme = this.get('theme'),
1945
+ path, root, idx, len, lp, dp ;
1946
+
1947
+ sc_super();
1948
+
1949
+ // TODO: This makes it impossible to override
1950
+ this.layoutStyleCalculator = SC.View.LayoutStyleCalculator.create({ view: this });
1573
1951
 
1574
- // Register this view for event handling
1575
- SC.View.views[this.get('layerId')] = this ;
1952
+ // Register the view for event handling. This hash is used by
1953
+ // SC.RootResponder to dispatch incoming events.
1954
+ SC.View.views[this.get('layerId')] = this;
1576
1955
 
1577
1956
  var childViews = this.get('childViews');
1578
-
1957
+
1579
1958
  // setup child views. be sure to clone the child views array first
1580
1959
  this.childViews = childViews ? childViews.slice() : [] ;
1581
1960
  this.createChildViews() ; // setup child Views
1582
-
1961
+ this._hasCreatedChildViews = YES;
1962
+
1583
1963
  // register display property observers ..
1584
- // TODO: Optimize into class setup
1585
- dp = this.get('displayProperties') ;
1964
+ // TODO: Optimize into class setup
1965
+ dp = this.get('displayProperties') ;
1586
1966
  idx = dp.length ;
1587
1967
  while (--idx >= 0) {
1588
- this.addObserver(dp[idx], this, this.displayDidChange) ;
1968
+ this.addObserver(dp[idx], this, this.displayDidChange);
1589
1969
  }
1590
-
1970
+
1591
1971
  // register for drags
1592
1972
  if (this.get('isDropTarget')) SC.Drag.addDropTarget(this) ;
1593
-
1973
+
1594
1974
  // register scroll views for autoscroll during drags
1595
1975
  if (this.get('isScrollable')) SC.Drag.addScrollableView(this) ;
1976
+
1977
+ this._previousLayout = this.get('layout');
1978
+ this._lastTheme = this.get('theme');
1596
1979
  },
1597
-
1980
+
1598
1981
  /**
1599
- Wakes up the view. The default implementation immediately syncs any
1600
- bindings, which may cause the view to need its display updated. You
1601
- can override this method to perform any additional setup. Be sure to
1982
+ Wakes up the view. The default implementation immediately syncs any
1983
+ bindings, which may cause the view to need its display updated. You
1984
+ can override this method to perform any additional setup. Be sure to
1602
1985
  call sc_super to setup bindings and to call awake on childViews.
1603
-
1986
+
1604
1987
  It is best to awake a view before you add it to the DOM. This way when
1605
1988
  the DOM is generated, it will have the correct initial values and will
1606
1989
  not require any additional setup.
1607
-
1990
+
1608
1991
  @returns {void}
1609
1992
  */
1610
1993
  awake: function() {
@@ -1613,83 +1996,83 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1613
1996
  for (idx=0; idx<len; ++idx) {
1614
1997
  if (!childViews[idx]) continue ;
1615
1998
  childViews[idx].awake() ;
1616
- }
1999
+ }
1617
2000
  },
1618
-
1619
- /**
1620
- You must call this method on a view to destroy the view (and all of its
1621
- child views). This will remove the view from any parent node, then make
1622
- sure that the DOM element managed by the view can be released by the
2001
+
2002
+ /**
2003
+ You must call this method on a view to destroy the view (and all of its
2004
+ child views). This will remove the view from any parent node, then make
2005
+ sure that the DOM element managed by the view can be released by the
1623
2006
  memory manager.
1624
2007
  */
1625
2008
  destroy: function() {
1626
2009
  if (this.get('isDestroyed')) return this; // nothing to do
1627
-
2010
+
1628
2011
  this._destroy(); // core destroy method
1629
-
2012
+
1630
2013
  // remove from parent if found
1631
2014
  this.removeFromParent() ;
1632
-
2015
+
1633
2016
  // unregister for drags
1634
2017
  if (this.get('isDropTarget')) SC.Drag.removeDropTarget(this) ;
1635
-
2018
+
1636
2019
  // unregister for autoscroll during drags
1637
2020
  if (this.get('isScrollable')) SC.Drag.removeScrollableView(this) ;
1638
-
2021
+
1639
2022
  //Do generic destroy. It takes care of mixins and sets isDestroyed to YES.
1640
2023
  sc_super();
1641
2024
  return this; // done with cleanup
1642
2025
  },
1643
-
2026
+
1644
2027
  _destroy: function() {
1645
2028
  if (this.get('isDestroyed')) return this ; // nothing to do
1646
-
1647
- // destroy the layer -- this will avoid each child view destroying
2029
+
2030
+ // destroy the layer -- this will avoid each child view destroying
1648
2031
  // the layer over and over again...
1649
- this.destroyLayer() ;
1650
-
2032
+ this.destroyLayer() ;
2033
+
1651
2034
  // first destroy any children.
1652
2035
  var childViews = this.get('childViews'), len = childViews.length, idx ;
1653
2036
  if (len) {
1654
2037
  childViews = childViews.slice() ;
1655
2038
  for (idx=0; idx<len; ++idx) childViews[idx].destroy() ;
1656
2039
  }
1657
-
2040
+
1658
2041
  // next remove view from global hash
1659
2042
  delete SC.View.views[this.get('layerId')] ;
1660
- delete this._CQ ;
2043
+ delete this._CQ ;
1661
2044
  delete this.page ;
1662
-
2045
+
1663
2046
  return this ;
1664
2047
  },
1665
-
1666
- /**
1667
- This method is called when your view is first created to setup any child
1668
- views that are already defined on your class. If any are found, it will
2048
+
2049
+ /**
2050
+ This method is called when your view is first created to setup any child
2051
+ views that are already defined on your class. If any are found, it will
1669
2052
  instantiate them for you.
1670
-
1671
- The default implementation of this method simply steps through your
1672
- childViews array, which is expects to either be empty or to contain View
2053
+
2054
+ The default implementation of this method simply steps through your
2055
+ childViews array, which is expects to either be empty or to contain View
1673
2056
  designs that can be instantiated
1674
-
1675
- Alternatively, you can implement this method yourself in your own
2057
+
2058
+ Alternatively, you can implement this method yourself in your own
1676
2059
  subclasses to look for views defined on specific properties and then build
1677
2060
  a childViews array yourself.
1678
-
1679
- Note that when you implement this method yourself, you should never
1680
- instantiate views directly. Instead, you should use
1681
- this.createChildView() method instead. This method can be much faster in
2061
+
2062
+ Note that when you implement this method yourself, you should never
2063
+ instantiate views directly. Instead, you should use
2064
+ this.createChildView() method instead. This method can be much faster in
1682
2065
  a production environment than creating views yourself.
1683
-
2066
+
1684
2067
  @returns {SC.View} receiver
1685
2068
  */
1686
2069
  createChildViews: function() {
1687
- var childViews = this.get('childViews'),
1688
- len = childViews.length,
2070
+ var childViews = this.get('childViews'),
2071
+ len = childViews.length,
1689
2072
  idx, key, views, view ;
1690
-
2073
+
1691
2074
  this.beginPropertyChanges() ;
1692
-
2075
+
1693
2076
  // swap the array
1694
2077
  for (idx=0; idx<len; ++idx) {
1695
2078
  if (key = (view = childViews[idx])) {
@@ -1698,32 +2081,32 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1698
2081
  if (typeof key === SC.T_STRING) {
1699
2082
  view = this[key];
1700
2083
  } else key = null ;
1701
-
2084
+
1702
2085
  if (!view) {
1703
2086
  console.error ("No view with name "+key+" has been found in "+this.toString());
1704
2087
  // skip this one.
1705
2088
  continue;
1706
2089
  }
1707
-
2090
+
1708
2091
  if (view.isClass) {
1709
2092
  view = this.createChildView(view) ; // instantiate if needed
1710
2093
  if (key) this[key] = view ; // save on key name if passed
1711
- }
2094
+ }
1712
2095
  }
1713
2096
  childViews[idx] = view;
1714
2097
  }
1715
-
2098
+
1716
2099
  this.endPropertyChanges() ;
1717
2100
  return this ;
1718
2101
  },
1719
-
2102
+
1720
2103
  /**
1721
- Instantiates a view to be added to the childViews array during view
1722
- initialization. You generally will not call this method directly unless
1723
- you are overriding createChildViews(). Note that this method will
1724
- automatically configure the correct settings on the new view instance to
2104
+ Instantiates a view to be added to the childViews array during view
2105
+ initialization. You generally will not call this method directly unless
2106
+ you are overriding createChildViews(). Note that this method will
2107
+ automatically configure the correct settings on the new view instance to
1725
2108
  act as a child of the parent.
1726
-
2109
+
1727
2110
  @param {Class} viewClass
1728
2111
  @param {Hash} attrs optional attributes to add
1729
2112
  @returns {SC.View} new instance
@@ -1732,15 +2115,18 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1732
2115
  createChildView: function(view, attrs) {
1733
2116
  // attrs should always exist...
1734
2117
  if (!attrs) attrs = {} ;
2118
+ // clone the hash that was given so we dont pollute it if it's being reused
2119
+ else attrs = SC.clone(attrs);
2120
+
1735
2121
  attrs.owner = attrs.parentView = this ;
1736
2122
  attrs.isVisibleInWindow = this.get('isVisibleInWindow');
1737
2123
  if (!attrs.page) attrs.page = this.page ;
1738
-
2124
+
1739
2125
  // Now add this to the attributes and create.
1740
2126
  view = view.create(attrs) ;
1741
2127
  return view ;
1742
2128
  },
1743
-
2129
+
1744
2130
  // ...........................................
1745
2131
  // LAYOUT
1746
2132
  //
@@ -1751,7 +2137,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1751
2137
  we need to invalidate the cache whenever 'layout' changes. However,
1752
2138
  observing 'layout' does not guarantee that; the observer might not be run
1753
2139
  immediately.
1754
-
2140
+
1755
2141
  In order to avoid any window of opportunity where the cached frame could
1756
2142
  be invalid, we need to force layoutDidChange() to always immediately run
1757
2143
  whenever 'layout' is set.
@@ -1760,10 +2146,10 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1760
2146
  // If the key is 'layout', we need to call layoutDidChange() immediately
1761
2147
  // so that if the frame has changed any cached values (for both this view
1762
2148
  // and any child views) can be appropriately invalidated.
1763
-
1764
- // To allow layout to be a computed property, we check if any property has
1765
- // changed and if layout is dependent on the property.
1766
- // If it is we call layoutDidChange.
2149
+
2150
+ // To allow layout to be a computed property, we check if any property has
2151
+ // changed and if layout is dependent on the property.
2152
+ // If it is we call layoutDidChange.
1767
2153
  var layoutChange=false;
1768
2154
  if(typeof this.layout === "function" && this._kvo_dependents) {
1769
2155
  var dependents = this._kvo_dependents[key];
@@ -1775,26 +2161,26 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1775
2161
  },
1776
2162
 
1777
2163
 
1778
- /**
2164
+ /**
1779
2165
  This convenience method will take the current layout, apply any changes
1780
2166
  you pass and set it again. It is more convenient than having to do this
1781
2167
  yourself sometimes.
1782
-
2168
+
1783
2169
  You can pass just a key/value pair or a hash with several pairs. You can
1784
2170
  also pass a null value to delete a property.
1785
-
2171
+
1786
2172
  This method will avoid actually setting the layout if the value you pass
1787
2173
  does not edit the layout.
1788
-
2174
+
1789
2175
  @param {String|Hash} key
1790
2176
  @param {Object} value
1791
2177
  @returns {SC.View} receiver
1792
2178
  */
1793
2179
  adjust: function(key, value) {
1794
2180
  var layout = SC.clone(this.get('layout')), didChange = NO, cur ;
1795
-
2181
+
1796
2182
  if (key === undefined) return this ; // nothing to do.
1797
-
2183
+
1798
2184
  // handle string case
1799
2185
  if (SC.typeOf(key) === SC.T_STRING) {
1800
2186
  cur = layout[key] ;
@@ -1805,7 +2191,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1805
2191
  if (cur !== value) didChange = YES ;
1806
2192
  layout[key] = value ;
1807
2193
  }
1808
-
2194
+
1809
2195
  // handle hash -- do it this way to avoid creating memory unless needed
1810
2196
  } else {
1811
2197
  var hash = key;
@@ -1813,7 +2199,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1813
2199
  if (!hash.hasOwnProperty(key)) continue;
1814
2200
  value = hash[key] ;
1815
2201
  cur = layout[key] ;
1816
-
2202
+
1817
2203
  if (value === null) {
1818
2204
  if (cur !== undefined) didChange = YES ;
1819
2205
  delete layout[key] ;
@@ -1825,56 +2211,171 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1825
2211
  }
1826
2212
  // now set adjusted layout
1827
2213
  if (didChange) this.set('layout', layout) ;
1828
-
2214
+
1829
2215
  return this ;
1830
2216
  },
1831
-
1832
- /**
1833
- The layout describes how you want your view to be positions on the
2217
+
2218
+
2219
+ /**
2220
+ Animate a given property using CSS animations.
2221
+
2222
+ Takes a key, value and either a duration, or a hash of options.
2223
+ The options hash has the following parameters
2224
+ - duration: Duration of animation in seconds
2225
+ - callback: Callback method to run when animation completes
2226
+ - timing: Animation timing function
2227
+
2228
+ @param {String|Hash} key
2229
+ @param {Object} value
2230
+ @params {Number|Hash} duration or options
2231
+ @returns {SC.View} receiver
2232
+ */
2233
+ animate: function(keyOrHash, valueOrOptions, optionsOrCallback, callback) {
2234
+ var hash, options;
2235
+
2236
+ if (typeof keyOrHash === SC.T_STRING) {
2237
+ hash = {};
2238
+ hash[keyOrHash] = valueOrOptions;
2239
+ options = optionsOrCallback;
2240
+ } else {
2241
+ hash = keyOrHash;
2242
+ options = valueOrOptions;
2243
+ callback = optionsOrCallback;
2244
+ }
2245
+
2246
+ var optionsType = SC.typeOf(options);
2247
+ if (optionsType === SC.T_NUMBER) {
2248
+ options = { duration: options };
2249
+ } else if (optionsType !== SC.T_HASH) {
2250
+ throw "Must provide options hash or duration!";
2251
+ }
2252
+
2253
+ if (callback) options.callback = callback;
2254
+
2255
+ var timing = options.timing;
2256
+ if (timing) {
2257
+ if (typeof timing !== SC.T_STRING) {
2258
+ options.timing = "cubic-bezier("+timing[0]+", "+timing[1]+", "+
2259
+ timing[2]+", "+timing[3]+")";
2260
+ }
2261
+ } else {
2262
+ options.timing = 'linear';
2263
+ }
2264
+
2265
+ var layout = SC.clone(this.get('layout')), didChange = NO, value, cur, animValue, curAnim, key;
2266
+
2267
+ if (!layout.animate) layout.animate = {};
2268
+
2269
+ // Very similar to #adjust
2270
+ for(key in hash) {
2271
+ if (!hash.hasOwnProperty(key)) continue;
2272
+ value = hash[key];
2273
+ cur = layout[key];
2274
+
2275
+ if (cur !== value) { didChange = YES; }
2276
+
2277
+ if (SC.ANIMATABLE_PROPERTIES[key]) {
2278
+ curAnim = layout.animate[key];
2279
+
2280
+ // loose comparison used instead of (value === null || value === undefined)
2281
+ if (value == null) { throw "Can only animate to an actual value!"; }
2282
+
2283
+ // FIXME: We should check more than duration
2284
+ if (curAnim && curAnim.duration !== options.duration) { didChange = YES; }
2285
+
2286
+ layout.animate[key] = options;
2287
+ }
2288
+
2289
+ layout[key] = value;
2290
+
2291
+ }
2292
+
2293
+ // now set adjusted layout
2294
+ if (didChange) this.set('layout', layout) ;
2295
+
2296
+ return this ;
2297
+ },
2298
+
2299
+ /**
2300
+ Resets animation, stopping all existing animations.
2301
+ */
2302
+ resetAnimation: function() {
2303
+ var layout = this.get('layout'),
2304
+ animations = layout.animate,
2305
+ didChange = NO, key;
2306
+
2307
+ if (!animations) return;
2308
+
2309
+ var hasAnimations;
2310
+
2311
+ for (key in animations) {
2312
+ didChange = YES;
2313
+ delete animations[key];
2314
+ }
2315
+
2316
+ if (didChange) {
2317
+ this.set('layout', layout);
2318
+ this.notifyPropertyChange('layout');
2319
+ }
2320
+
2321
+ return this;
2322
+ },
2323
+
2324
+ /**
2325
+ Called when animation ends, should not usually be called manually
2326
+ */
2327
+ transitionDidEnd: function(evt){
2328
+ // WARNING: Sometimes this will get called more than once for a property. Not sure why.
2329
+ this.get('layoutStyleCalculator').transitionDidEnd(evt);
2330
+ },
2331
+
2332
+
2333
+ /**
2334
+ The layout describes how you want your view to be positions on the
1834
2335
  screen. You can define the following properties:
1835
-
2336
+
1836
2337
  - left: the left edge
1837
2338
  - top: the top edge
1838
2339
  - right: the right edge
1839
2340
  - bottom: the bottom edge
1840
2341
  - height: the height
1841
2342
  - width: the width
1842
- - centerX: an offset from center X
2343
+ - centerX: an offset from center X
1843
2344
  - centerY: an offset from center Y
1844
2345
  - minWidth: a minimum width
1845
2346
  - minHeight: a minimum height
1846
2347
  - maxWidth: a maximum width
1847
2348
  - maxHeight: a maximum height
1848
-
1849
- Note that you can only use certain combinations to set layout. For
2349
+
2350
+ Note that you can only use certain combinations to set layout. For
1850
2351
  example, you may set left/right or left/width, but not left/width/right,
1851
2352
  since that combination doesn't make sense.
1852
-
2353
+
1853
2354
  Likewise, you may set a minWidth/minHeight, or maxWidth/maxHeight, but
1854
2355
  if you also set the width/height explicitly, then those constraints won't
1855
2356
  matter as much.
1856
-
1857
- Layout is designed to maximize reliance on the browser's rendering
2357
+
2358
+ Layout is designed to maximize reliance on the browser's rendering
1858
2359
  engine to keep your app up to date.
1859
-
2360
+
1860
2361
  @test in layoutStyle
1861
2362
  */
1862
2363
  layout: { top: 0, left: 0, bottom: 0, right: 0 },
1863
-
2364
+
1864
2365
  /**
1865
2366
  Converts a frame from the receiver's offset to the target offset. Both
1866
2367
  the receiver and the target must belong to the same pane. If you pass
1867
2368
  null, the conversion will be to the pane level.
1868
-
2369
+
1869
2370
  Note that the context of a view's frame is the view's parent frame. In
1870
2371
  other words, if you want to convert the frame of your view to the global
1871
2372
  frame, then you should do:
1872
-
2373
+
1873
2374
  {{{
1874
2375
  var pv = this.get('parentView'), frame = this.get('frame');
1875
2376
  var newFrame = pv ? pv.convertFrameToView(frame, null) : frame;
1876
2377
  }}}
1877
-
2378
+
1878
2379
  @param {Rect} frame the source frame
1879
2380
  @param {SC.View} targetView the target view to convert to
1880
2381
  @returns {Rect} converted frame
@@ -1882,41 +2383,41 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1882
2383
  */
1883
2384
  convertFrameToView: function(frame, targetView) {
1884
2385
  var myX=0, myY=0, targetX=0, targetY=0, view = this, f ;
1885
-
2386
+
1886
2387
  // walk up this side
1887
2388
  while (view) {
1888
2389
  f = view.get('frame'); myX += f.x; myY += f.y ;
1889
- view = view.get('layoutView') ;
2390
+ view = view.get('layoutView') ;
1890
2391
  }
1891
-
2392
+
1892
2393
  // walk up other size
1893
2394
  if (targetView) {
1894
2395
  view = targetView ;
1895
2396
  while (view) {
1896
2397
  f = view.get('frame'); targetX += f.x; targetY += f.y ;
1897
- view = view.get('layoutView') ;
2398
+ view = view.get('layoutView') ;
1898
2399
  }
1899
2400
  }
1900
-
2401
+
1901
2402
  // now we can figure how to translate the origin.
1902
2403
  myX = frame.x + myX - targetX ;
1903
2404
  myY = frame.y + myY - targetY ;
1904
2405
  return { x: myX, y: myY, width: frame.width, height: frame.height } ;
1905
2406
  },
1906
-
2407
+
1907
2408
  /**
1908
- Converts a frame offset in the coordinates of another view system to the
2409
+ Converts a frame offset in the coordinates of another view system to the
1909
2410
  receiver's view.
1910
-
1911
- Note that the convext of a view's frame is relative to the view's
2411
+
2412
+ Note that the convext of a view's frame is relative to the view's
1912
2413
  parentFrame. For example, if you want to convert the frame of view that
1913
2414
  belongs to another view to the receiver's frame you would do:
1914
-
2415
+
1915
2416
  {{{
1916
2417
  var frame = view.get('frame');
1917
2418
  var newFrame = this.convertFrameFromView(frame, view.get('parentView'));
1918
2419
  }}}
1919
-
2420
+
1920
2421
  @param {Rect} frame the source frame
1921
2422
  @param {SC.View} targetView the target view to convert to
1922
2423
  @returns {Rect} converted frame
@@ -1924,72 +2425,72 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
1924
2425
  */
1925
2426
  convertFrameFromView: function(frame, targetView) {
1926
2427
  var myX=0, myY=0, targetX=0, targetY=0, view = this, f ;
1927
-
2428
+
1928
2429
  // walk up this side
1929
2430
  //Note: Intentional assignment of variable f
1930
2431
  while (view && (f = view.get('frame'))) {
1931
2432
  myX += f.x; myY += f.y ;
1932
- view = view.get('parentView') ;
2433
+ view = view.get('parentView') ;
1933
2434
  }
1934
-
2435
+
1935
2436
  // walk up other size
1936
2437
  if (targetView) {
1937
2438
  view = targetView ;
1938
2439
  while(view) {
1939
2440
  f = view.get('frame'); targetX += f.x; targetY += f.y ;
1940
- view = view.get('parentView') ;
2441
+ view = view.get('parentView') ;
1941
2442
  }
1942
2443
  }
1943
-
2444
+
1944
2445
  // now we can figure how to translate the origin.
1945
2446
  myX = frame.x - myX + targetX ;
1946
2447
  myY = frame.y - myY + targetY ;
1947
2448
  return { x: myX, y: myY, width: frame.width, height: frame.height } ;
1948
2449
  },
1949
-
2450
+
1950
2451
  /**
1951
2452
  Attempt to scroll the view to visible. This will walk up the parent
1952
- view hierarchy looking looking for a scrollable view. It will then
2453
+ view hierarchy looking looking for a scrollable view. It will then
1953
2454
  call scrollToVisible() on it.
1954
-
2455
+
1955
2456
  Returns YES if an actual scroll took place, no otherwise.
1956
-
1957
- @returns {Boolean}
2457
+
2458
+ @returns {Boolean}
1958
2459
  */
1959
2460
  scrollToVisible: function() {
1960
2461
  var pv = this.get('parentView');
1961
2462
  while(pv && !pv.get('isScrollable')) pv = pv.get('parentView');
1962
-
2463
+
1963
2464
  // found view, first make it scroll itself visible then scroll this.
1964
2465
  if (pv) {
1965
2466
  pv.scrollToVisible();
1966
2467
  return pv.scrollToVisible(this);
1967
2468
  } else return NO ;
1968
2469
  },
1969
-
2470
+
1970
2471
  /**
1971
2472
  Frame describes the current bounding rect for your view. This is always
1972
2473
  measured from the top-left corner of the parent view.
1973
-
2474
+
1974
2475
  @property {Rect}
1975
2476
  @test in layoutStyle
1976
2477
  */
1977
2478
  frame: function() {
1978
2479
  return this.computeFrameWithParentFrame(null) ;
1979
2480
  }.property('useStaticLayout').cacheable(), // We depend on the layout, but layoutDidChange will call viewDidChange to check the frame for us
1980
-
2481
+
1981
2482
  /**
1982
2483
  Computes what the frame of this view would be if the parent were resized
1983
2484
  to the passed dimensions. You can use this method to project the size of
1984
2485
  a frame based on the resize behavior of the parent.
1985
-
1986
- This method is used especially by the scroll view to automatically
2486
+
2487
+ This method is used especially by the scroll view to automatically
1987
2488
  calculate when scrollviews should be visible.
1988
-
1989
- Passing null for the parent dimensions will use the actual current
2489
+
2490
+ Passing null for the parent dimensions will use the actual current
1990
2491
  parent dimensions. This is the same method used to calculate the current
1991
2492
  frame when it changes.
1992
-
2493
+
1993
2494
  @param {Rect} pdim the projected parent dimensions
1994
2495
  @returns {Rect} the computed frame
1995
2496
  */
@@ -2000,13 +2501,13 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2000
2501
  pv = this.get('parentView'),
2001
2502
  dH, dW, //shortHand for parentDimensions
2002
2503
  borderTop, borderLeft,
2003
- lR = layout.right,
2004
- lL = layout.left,
2005
- lT = layout.top,
2006
- lB = layout.bottom,
2007
- lW = layout.width,
2008
- lH = layout.height,
2009
- lcX = layout.centerX,
2504
+ lR = layout.right,
2505
+ lL = layout.left,
2506
+ lT = layout.top,
2507
+ lB = layout.bottom,
2508
+ lW = layout.width,
2509
+ lH = layout.height,
2510
+ lcX = layout.centerX,
2010
2511
  lcY = layout.centerY;
2011
2512
 
2012
2513
  if (lW !== undefined &&
@@ -2017,7 +2518,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2017
2518
  console.error(error.toString()) ;
2018
2519
  throw error ;
2019
2520
  }
2020
-
2521
+
2021
2522
  if (lH !== undefined &&
2022
2523
  lH === SC.LAYOUT_AUTO &&
2023
2524
  stLayout !== undefined && !stLayout) {
@@ -2026,13 +2527,13 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2026
2527
  console.error(error.toString()) ;
2027
2528
  throw error ;
2028
2529
  }
2029
-
2530
+
2030
2531
  if (stLayout) {
2031
2532
  // need layer to be able to compute rect
2032
2533
  if (layer = this.get('layer')) {
2033
2534
  f = SC.viewportOffset(layer); // x,y
2034
2535
  if (pv) f = pv.convertFrameFromView(f, null);
2035
-
2536
+
2036
2537
  /*
2037
2538
  TODO Can probably have some better width/height values - CC
2038
2539
  */
@@ -2042,14 +2543,13 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2042
2543
  }
2043
2544
  return null; // can't compute
2044
2545
  }
2045
-
2546
+
2046
2547
 
2047
2548
  if (!pdim) pdim = this.computeParentDimensions(layout) ;
2048
2549
  dH = pdim.height;
2049
2550
  dW = pdim.width;
2050
-
2051
-
2052
- // handle left aligned and left/right
2551
+
2552
+ // handle left aligned and left/right
2053
2553
  if (!SC.none(lL)) {
2054
2554
  if(SC.isPercentage(lL)){
2055
2555
  f.x = dW*lL;
@@ -2080,7 +2580,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2080
2580
  if (SC.isPercentage(lW)) f.x = dW - (lR*dW) - f.width ;
2081
2581
  else f.x = dW - lR - f.width ;
2082
2582
  }
2083
-
2583
+
2084
2584
  // handle centered
2085
2585
  } else if (!SC.none(lcX)) {
2086
2586
  if(lW === AUTO) f.width = AUTO ;
@@ -2098,8 +2598,8 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2098
2598
  else f.width = (lW || 0) ;
2099
2599
  }
2100
2600
  }
2101
-
2102
- // handle top aligned and top/bottom
2601
+
2602
+ // handle top aligned and top/bottom
2103
2603
  if (!SC.none(lT)) {
2104
2604
  if(SC.isPercentage(lT)) f.y = lT*dH ;
2105
2605
  else f.y = lT ;
@@ -2111,7 +2611,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2111
2611
  if(lB && SC.isPercentage(lB)) f.height = dH - f.y - (lB*dH) ;
2112
2612
  else f.height = dH - f.y - (lB || 0) ;
2113
2613
  }
2114
-
2614
+
2115
2615
  // handle bottom aligned
2116
2616
  } else if (!SC.none(lB)) {
2117
2617
  if (SC.none(lH)) {
@@ -2125,7 +2625,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2125
2625
  if (SC.isPercentage(lB)) f.y = dH - (lB*dH) - f.height ;
2126
2626
  else f.y = dH - lB - f.height ;
2127
2627
  }
2128
-
2628
+
2129
2629
  // handle centered
2130
2630
  } else if (!SC.none(lcY)) {
2131
2631
  if(lH === AUTO) f.height = AUTO ;
@@ -2133,7 +2633,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2133
2633
  else f.height = (lH || 0) ;
2134
2634
  if (SC.isPercentage(lcY)) f.y = (dH - f.height)/2 + (lcY*dH) ;
2135
2635
  else f.y = (dH - f.height)/2 + lcY ;
2136
-
2636
+
2137
2637
  // fallback
2138
2638
  } else {
2139
2639
  f.y = 0 ; // fallback
@@ -2145,26 +2645,26 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2145
2645
  else f.height = lH || 0 ;
2146
2646
  }
2147
2647
  }
2148
-
2648
+
2149
2649
  f.x = Math.floor(f.x);
2150
2650
  f.y = Math.floor(f.y);
2151
2651
  if(f.height !== AUTO) f.height = Math.floor(f.height);
2152
2652
  if(f.width !== AUTO) f.width = Math.floor(f.width);
2153
-
2653
+
2154
2654
  // if width or height were set to auto and we have a layer, try lookup
2155
2655
  if (f.height === AUTO || f.width === AUTO) {
2156
2656
  layer = this.get('layer');
2157
2657
  if (f.height === AUTO) f.height = layer ? layer.clientHeight : 0;
2158
2658
  if (f.width === AUTO) f.width = layer ? layer.clientWidth : 0;
2159
2659
  }
2160
-
2660
+
2161
2661
  // views with SC.Border mixin applied applied
2162
2662
  if (this.get('hasBorder')) {
2163
- borderTop = this.get('borderTop');
2164
- borderLeft = this.get('borderLeft');
2165
- f.height -= borderTop+this.get('borderBottom');
2663
+ borderTop = this.get('borderTop') || 0;
2664
+ borderLeft = this.get('borderLeft') || 0;
2665
+ f.height -= borderTop+ (this.get('borderBottom') || 0);
2166
2666
  f.y += borderTop;
2167
- f.width -= borderLeft+this.get('borderRight');
2667
+ f.width -= borderLeft + (this.get('borderRight') || 0);
2168
2668
  f.x += borderLeft;
2169
2669
  }
2170
2670
 
@@ -2188,21 +2688,21 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2188
2688
  if (!SC.none(layout.maxWidth) && (f.width > layout.maxWidth)) {
2189
2689
  f.width = layout.maxWidth ;
2190
2690
  }
2191
-
2691
+
2192
2692
  if (!SC.none(layout.minWidth) && (f.width < layout.minWidth)) {
2193
2693
  f.width = layout.minWidth ;
2194
2694
  }
2195
-
2695
+
2196
2696
  // make sure width/height are never < 0
2197
2697
  if (f.height < 0) f.height = 0 ;
2198
2698
  if (f.width < 0) f.width = 0 ;
2199
-
2699
+
2200
2700
  return f;
2201
2701
  },
2202
-
2702
+
2203
2703
  computeParentDimensions: function(frame) {
2204
2704
  var ret, pv = this.get('parentView'), pf = (pv) ? pv.get('frame') : null ;
2205
-
2705
+
2206
2706
  if (pf) {
2207
2707
  ret = { width: pf.width, height: pf.height };
2208
2708
  } else {
@@ -2214,15 +2714,15 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2214
2714
  }
2215
2715
  return ret ;
2216
2716
  },
2217
-
2717
+
2218
2718
  /**
2219
2719
  The clipping frame returns the visible portion of the view, taking into
2220
- account the contentClippingFrame of the parent view. Keep in mind that
2221
- the clippingFrame is in the context of the view itself, not it's parent
2720
+ account the contentClippingFrame of the parent view. Keep in mind that
2721
+ the clippingFrame is in the context of the view itself, not it's parent
2222
2722
  view.
2223
-
2224
- Normally this will be calculated based on the intersection of your own
2225
- clippingFrame and your parentView's contentClippingFrame.
2723
+
2724
+ Normally this will be calculated based on the intersection of your own
2725
+ clippingFrame and your parentView's contentClippingFrame.
2226
2726
 
2227
2727
  @property {Rect}
2228
2728
  */
@@ -2230,29 +2730,29 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2230
2730
  var f = this.get('frame'),
2231
2731
  ret = f,
2232
2732
  pv, cf;
2233
-
2733
+
2234
2734
  if (!f) return null;
2235
2735
  pv = this.get('parentView');
2236
2736
  if (pv) {
2237
2737
  cf = pv.get('contentClippingFrame');
2238
2738
  if (!cf) return f;
2239
2739
  ret = SC.intersectRects(cf, f);
2240
- }
2740
+ }
2241
2741
  ret.x -= f.x;
2242
2742
  ret.y -= f.y;
2243
-
2743
+
2244
2744
  return ret;
2245
2745
  }.property('parentView', 'frame').cacheable(),
2246
-
2746
+
2247
2747
  /**
2248
- The clipping frame child views should intersect with. Normally this is
2249
- the same as the regular clippingFrame. However, you may override this
2748
+ The clipping frame child views should intersect with. Normally this is
2749
+ the same as the regular clippingFrame. However, you may override this
2250
2750
  method if you want the child views to actually draw more or less content
2251
2751
  than is actually visible for some reason.
2252
-
2752
+
2253
2753
  Usually this is only used by the ScrollView to optimize drawing on touch
2254
2754
  devices.
2255
-
2755
+
2256
2756
  @property {Rect}
2257
2757
  */
2258
2758
  contentClippingFrame: function() {
@@ -2267,30 +2767,30 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2267
2767
  var cvs = this.get('childViews'), len = cvs.length, idx, cv ;
2268
2768
  for (idx=0; idx<len; ++idx) {
2269
2769
  cv = cvs[idx] ;
2270
-
2271
- // In SC 1.0 views with static layout did not receive notifications
2770
+
2771
+ // In SC 1.0 views with static layout did not receive notifications
2272
2772
  // of frame changes because they didn't support frames. In SC 1.1 they
2273
2773
  // do support frames, so they should receive notifications. Also in
2274
- // SC 1.1 SC.StaticLayout is merged into SC.View. The mixin is only
2275
- // for compatibility. This property is defined on the mixin.
2774
+ // SC 1.1 SC.StaticLayout is merged into SC.View. The mixin is only
2775
+ // for compatibility. This property is defined on the mixin.
2276
2776
  //
2277
- // frame changes should be sent all the time unless this property is
2777
+ // frame changes should be sent all the time unless this property is
2278
2778
  // present to indicate that we want the old 1.0 API behavior instead.
2279
- //
2280
- if (!cv.hasStaticLayout) {
2779
+ //
2780
+ if (!cv.useStaticLayout) {
2281
2781
  cv.notifyPropertyChange('clippingFrame') ;
2282
2782
  cv._sc_view_clippingFrameDidChange();
2283
2783
  }
2284
2784
  }
2285
2785
  },
2286
-
2287
- /**
2786
+
2787
+ /**
2288
2788
  This method may be called on your view whenever the parent view resizes.
2289
-
2290
- The default version of this method will reset the frame and then call
2789
+
2790
+ The default version of this method will reset the frame and then call
2291
2791
  viewDidResize(). You will not usually override this method, but you may
2292
2792
  override the viewDidResize() method.
2293
-
2793
+
2294
2794
  @returns {void}
2295
2795
  @test in viewDidResize
2296
2796
  */
@@ -2305,7 +2805,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2305
2805
  }
2306
2806
  else {
2307
2807
  layout = this.get('layout');
2308
-
2808
+
2309
2809
  // only resizes if the layout does something other than left/top - fixed
2310
2810
  // size.
2311
2811
  isFixed = (
@@ -2318,11 +2818,11 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2318
2818
  // percentage of the parent.
2319
2819
  if (isFixed) {
2320
2820
  isPercentageFunc = SC.isPercentage;
2321
- isPercentage = (isPercentageFunc(layout.left) ||
2821
+ isPercentage = (isPercentageFunc(layout.left) ||
2322
2822
  isPercentageFunc(layout.top) ||
2323
- isPercentageFunc(layout.width) ||
2823
+ isPercentageFunc(layout.width) ||
2324
2824
  isPercentageFunc(layout.right) ||
2325
- isPercentageFunc(layout.centerX) ||
2825
+ isPercentageFunc(layout.centerX) ||
2326
2826
  isPercentageFunc(layout.centerY));
2327
2827
  }
2328
2828
 
@@ -2344,20 +2844,20 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2344
2844
  This method is invoked on your view when the view resizes due to a layout
2345
2845
  change or potentially due to the parent view resizing (if your view’s size
2346
2846
  depends on the size of your parent view). You can override this method
2347
- to implement your own layout if you like, such as performing a grid
2847
+ to implement your own layout if you like, such as performing a grid
2348
2848
  layout.
2349
-
2849
+
2350
2850
  The default implementation simply notifies about the change to 'frame' and
2351
2851
  then calls parentViewDidResize on all of your children.
2352
-
2852
+
2353
2853
  @returns {void}
2354
2854
  */
2355
2855
  viewDidResize: function() {
2356
2856
  this._viewFrameDidChange();
2357
2857
 
2358
2858
  // Also notify our children.
2359
- var cv = this.childViews, len = cv.length, idx, view ;
2360
- for (idx=0; idx<len; ++idx) {
2859
+ var cv = this.childViews, len, idx, view ;
2860
+ for (idx=0; idx<(len= cv.length); ++idx) {
2361
2861
  view = cv[idx];
2362
2862
  view.parentViewDidResize();
2363
2863
  }
@@ -2374,9 +2874,9 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2374
2874
  this._sc_view_clippingFrameDidChange();
2375
2875
  },
2376
2876
 
2377
- // Implementation note: As a general rule, paired method calls, such as
2877
+ // Implementation note: As a general rule, paired method calls, such as
2378
2878
  // beginLiveResize/endLiveResize that are called recursively on the tree
2379
- // should reverse the order when doing the final half of the call. This
2879
+ // should reverse the order when doing the final half of the call. This
2380
2880
  // ensures that the calls are propertly nested for any cleanup routines.
2381
2881
  //
2382
2882
  // -> View A.beginXXX()
@@ -2392,19 +2892,19 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2392
2892
  // <- View A.endXXX()
2393
2893
  //
2394
2894
  // See the two methods below for an example implementation.
2395
-
2895
+
2396
2896
  /**
2397
- Call this method when you plan to begin a live resize. This will
2897
+ Call this method when you plan to begin a live resize. This will
2398
2898
  notify the receiver view and any of its children that are interested
2399
2899
  that the resize is about to begin.
2400
-
2900
+
2401
2901
  @returns {SC.View} receiver
2402
2902
  @test in viewDidResize
2403
2903
  */
2404
2904
  beginLiveResize: function() {
2405
2905
  // call before children have been notified...
2406
2906
  if (this.willBeginLiveResize) this.willBeginLiveResize() ;
2407
-
2907
+
2408
2908
  // notify children in order
2409
2909
  var ary = this.get('childViews'), len = ary.length, idx, view ;
2410
2910
  for (idx=0; idx<len; ++idx) {
@@ -2413,12 +2913,12 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2413
2913
  }
2414
2914
  return this ;
2415
2915
  },
2416
-
2916
+
2417
2917
  /**
2418
2918
  Call this method when you are finished with a live resize. This will
2419
2919
  notify the receiver view and any of its children that are interested
2420
2920
  that the live resize has ended.
2421
-
2921
+
2422
2922
  @returns {SC.View} receiver
2423
2923
  @test in viewDidResize
2424
2924
  */
@@ -2429,272 +2929,93 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2429
2929
  view = ary[idx] ;
2430
2930
  if (view.endLiveResize) view.endLiveResize() ;
2431
2931
  }
2432
-
2932
+
2433
2933
  // call *after* all children have been notified...
2434
2934
  if (this.didEndLiveResize) this.didEndLiveResize() ;
2435
2935
  return this ;
2436
2936
  },
2437
2937
 
2438
2938
  /**
2439
- Setting wantsAcceleratedLayer to YES will use 3d transforms to move the
2440
- layer when available.
2939
+ Setting wantsAcceleratedLayer to YES will use transforms to move the
2940
+ layer when available. On some platforms transforms are hardware accelerated.
2441
2941
  */
2442
2942
  wantsAcceleratedLayer: NO,
2443
2943
 
2444
2944
  /**
2445
- Specifies whether 3d transforms can be used to move the layer.
2945
+ Specifies whether transforms can be used to move the layer.
2446
2946
  */
2447
2947
  hasAcceleratedLayer: function(){
2448
- return this.get('wantsAcceleratedLayer') && SC.platform.supportsAcceleratedLayers;
2948
+ if (this.get('wantsAcceleratedLayer') && SC.platform.supportsAcceleratedLayers) {
2949
+ var layout = this.get('layout'),
2950
+ animations = layout.animate,
2951
+ AUTO = SC.LAYOUT_AUTO,
2952
+ key;
2953
+
2954
+ if (animations && (animations['top'] || animations['left'])) {
2955
+ for (key in animations) {
2956
+ // If we're animating other transforms at different speeds, don't use acceleratedLayer
2957
+ if (
2958
+ SC.CSS_TRANSFORM_MAP[key] &&
2959
+ ((animations['top'] && animations['top'].duration !== animations[key].duration) ||
2960
+ (animations['left'] && animations['left'].duration !== animations[key].duration))
2961
+ ) {
2962
+ return NO;
2963
+ }
2964
+ }
2965
+ }
2966
+
2967
+ // loose comparison used instead of (layout.X === null || layout.X === undefined)
2968
+ if (
2969
+ layout.left != null && !SC.isPercentage(layout.left) && layout.left !== AUTO &&
2970
+ layout.top != null && !SC.isPercentage(layout.top) && layout.top !== AUTO &&
2971
+ layout.width != null && !SC.isPercentage(layout.width) && layout.width !== AUTO &&
2972
+ layout.height != null && !SC.isPercentage(layout.height) && layout.height !== AUTO
2973
+ ) {
2974
+ return YES;
2975
+ }
2976
+ }
2977
+ return NO;
2449
2978
  }.property('wantsAcceleratedLayer').cacheable(),
2450
2979
 
2451
2980
 
2981
+ layoutStyleCalculator: null,
2982
+
2452
2983
  /**
2453
2984
  layoutStyle describes the current styles to be written to your element
2454
2985
  based on the layout you defined. Both layoutStyle and frame reset when
2455
2986
  you edit the layout property. Both are read only.
2456
-
2987
+
2457
2988
  Computes the layout style settings needed for the current anchor.
2458
-
2989
+
2459
2990
  @property {Hash}
2460
2991
  @readOnly
2461
2992
  */
2462
-
2463
-
2464
2993
  layoutStyle: function() {
2465
- var layout = this.get('layout'), ret = {}, pdim = null, error,
2466
- AUTO = SC.LAYOUT_AUTO,
2467
- dims = SC._VIEW_DEFAULT_DIMS, loc = dims.length, x, value, key,
2468
- stLayout = this.get('useStaticLayout'),
2469
- lR = layout.right,
2470
- lL = layout.left,
2471
- lT = layout.top,
2472
- lB = layout.bottom,
2473
- lW = layout.width,
2474
- lH = layout.height,
2475
- lMW = layout.maxWidth,
2476
- lMH = layout.maxHeight,
2477
- lcX = layout.centerX,
2478
- lcY = layout.centerY,
2479
- hasAcceleratedLayer = this.get('hasAcceleratedLayer'),
2480
- translateTop = 0,
2481
- translateLeft = 0;
2482
- if (lW !== undefined && lW === SC.LAYOUT_AUTO && !stLayout) {
2483
- error= SC.Error.desc("%@.layout() you cannot use width:auto if "+
2484
- "staticLayout is disabled".fmt(this),"%@".fmt(this),-1);
2485
- console.error(error.toString()) ;
2486
- throw error ;
2487
- }
2488
-
2489
- if (lH !== undefined && lH === SC.LAYOUT_AUTO && !stLayout) {
2490
- error = SC.Error.desc("%@.layout() you cannot use height:auto if "+
2491
- "staticLayout is disabled".fmt(this),"%@".fmt(this),-1);
2492
- console.error(error.toString()) ;
2493
- throw error ;
2494
- }
2994
+ var props = {
2995
+ layout: this.get('layout'),
2996
+ turbo: this.get('hasAcceleratedLayer'),
2997
+ staticLayout: this.get('useStaticLayout')
2998
+ };
2495
2999
 
2496
- // X DIRECTION
2497
-
2498
- // handle left aligned and left/right
2499
- if (!SC.none(lL)) {
2500
- if(SC.isPercentage(lL)) {
2501
- ret.left = (lL*100)+"%"; //percentage left
2502
- } else if (hasAcceleratedLayer && !SC.empty(lW)) {
2503
- translateLeft = Math.floor(lL);
2504
- ret.left = 0;
2505
- } else {
2506
- ret.left = Math.floor(lL); //px left
2507
- }
2508
- ret.marginLeft = 0 ;
2509
-
2510
- if (lW !== undefined) {
2511
- if(lW === SC.LAYOUT_AUTO) ret.width = SC.LAYOUT_AUTO ;
2512
- else if(SC.isPercentage(lW)) ret.width = (lW*100)+"%"; //percentage width
2513
- else ret.width = Math.floor(lW) ; //px width
2514
- ret.right = null ;
2515
- } else {
2516
- ret.width = null ;
2517
- if(lR && SC.isPercentage(lR)) ret.right = (lR*100)+"%"; //percentage right
2518
- else ret.right = Math.floor(lR || 0) ; //px right
2519
- }
2520
-
2521
- // handle right aligned
2522
- } else if (!SC.none(lR)) {
2523
- if(SC.isPercentage(lR)) {
2524
- ret.right = Math.floor(lR*100)+"%"; //percentage left
2525
- }else{
2526
- ret.right = Math.floor(lR) ;
2527
- }
2528
- ret.marginLeft = 0 ;
2529
-
2530
- if (SC.none(lW)) {
2531
- if (SC.none(lMW)) ret.left = 0;
2532
- ret.width = null;
2533
- } else {
2534
- ret.left = null ;
2535
- if(lW === SC.LAYOUT_AUTO) ret.width = SC.LAYOUT_AUTO ;
2536
- else if(lW && SC.isPercentage(lW)) ret.width = (lW*100)+"%" ; //percentage width
2537
- else ret.width = Math.floor(lW || 0) ; //px width
2538
- }
2539
-
2540
- // handle centered
2541
- } else if (!SC.none(lcX)) {
2542
- ret.left = "50%";
2543
- if(lW && SC.isPercentage(lW)) ret.width = (lW*100)+"%" ; //percentage width
2544
- else ret.width = Math.floor(lW || 0) ;
2545
- if(lW && SC.isPercentage(lW) && (SC.isPercentage(lcX) || SC.isPercentage(lcX*-1))){
2546
- ret.marginLeft = Math.floor((lcX - lW/2)*100)+"%" ;
2547
- }else if(lW && lW >= 1 && !SC.isPercentage(lcX)){
2548
- ret.marginLeft = Math.floor(lcX - ret.width/2) ;
2549
- }else {
2550
- // This error message happens whenever width is not set.
2551
- console.warn("You have to set width and centerX usign both percentages or pixels");
2552
- ret.marginLeft = "50%";
2553
- }
2554
- ret.right = null ;
2555
-
2556
- // if width defined, assume top/left of zero
2557
- } else if (!SC.none(lW)) {
2558
- ret.left = 0;
2559
- ret.right = null;
2560
- if(lW === SC.LAYOUT_AUTO) ret.width = SC.LAYOUT_AUTO ;
2561
- else if(SC.isPercentage(lW)) ret.width = (lW*100)+"%";
2562
- else ret.width = Math.floor(lW);
2563
- ret.marginLeft = 0;
2564
-
2565
- // fallback, full width.
2566
- } else {
2567
- ret.left = 0;
2568
- ret.right = 0;
2569
- ret.width = null ;
2570
- ret.marginLeft= 0;
2571
- }
2572
-
2573
-
2574
- // handle min/max
2575
- ret.minWidth = (layout.minWidth === undefined) ? null : layout.minWidth ;
2576
- ret.maxWidth = (layout.maxWidth === undefined) ? null : layout.maxWidth ;
2577
-
2578
- // Y DIRECTION
2579
-
2580
- // handle top aligned and left/right
2581
- if (!SC.none(lT)) {
2582
- if(SC.isPercentage(lT)) {
2583
- ret.top = (lT*100)+"%";
2584
- } else if (hasAcceleratedLayer && !SC.empty(lH)) {
2585
- translateTop = Math.floor(lT);
2586
- ret.top = 0;
2587
- } else {
2588
- ret.top = Math.floor(lT);
2589
- }
2590
- if (lH !== undefined) {
2591
- if(lH === SC.LAYOUT_AUTO) ret.height = SC.LAYOUT_AUTO ;
2592
- else if(SC.isPercentage(lH)) ret.height = (lH*100)+"%" ;
2593
- else ret.height = Math.floor(lH) ;
2594
- ret.bottom = null ;
2595
- } else {
2596
- ret.height = null ;
2597
- if(lB && SC.isPercentage(lB)) ret.bottom = (lB*100)+"%" ;
2598
- else ret.bottom = Math.floor(lB || 0) ;
2599
- }
2600
- ret.marginTop = 0 ;
2601
-
2602
- // handle bottom aligned
2603
- } else if (!SC.none(lB)) {
2604
- ret.marginTop = 0 ;
2605
- if(SC.isPercentage(lB)) ret.bottom = (lB*100)+"%";
2606
- else ret.bottom = Math.floor(lB) ;
2607
- if (SC.none(lH)) {
2608
- if (SC.none(lMH)) ret.top = 0;
2609
- ret.height = null ;
2610
- } else {
2611
- ret.top = null ;
2612
- if(lH === SC.LAYOUT_AUTO) ret.height = SC.LAYOUT_AUTO ;
2613
- else if(lH && SC.isPercentage(lH)) ret.height = (lH*100)+"%" ;
2614
- else ret.height = Math.floor(lH || 0) ;
2615
- }
2616
-
2617
- // handle centered
2618
- } else if (!SC.none(lcY)) {
2619
- ret.top = "50%";
2620
- ret.bottom = null ;
2621
-
2622
- if(lH && SC.isPercentage(lH)) ret.height = (lH*100)+ "%" ;
2623
- else ret.height = Math.floor(lH || 0) ;
2624
-
2625
- if(lH && SC.isPercentage(lH) && (SC.isPercentage(lcY) || SC.isPercentage(lcY*-1))){ //height is percentage and lcy too
2626
- ret.marginTop = Math.floor((lcY - lH/2)*100)+"%" ;
2627
- }else if(lH && lH >= 1 && !SC.isPercentage(lcY)){
2628
- ret.marginTop = Math.floor(lcY - ret.height/2) ;
2629
- }else {
2630
- console.warn("You have to set height and centerY to use both percentages or pixels");
2631
- ret.marginTop = "50%";
2632
- }
2633
- } else if (!SC.none(lH)) {
2634
- ret.top = 0;
2635
- ret.bottom = null;
2636
- if(lH === SC.LAYOUT_AUTO) ret.height = SC.LAYOUT_AUTO ;
2637
- else if(lH && SC.isPercentage(lH)) ret.height = (lH*100)+"%" ;
2638
- else ret.height = Math.floor(lH || 0) ;
2639
- ret.marginTop = 0;
2640
-
2641
- // fallback, full width.
2642
- } else {
2643
- ret.top = 0;
2644
- ret.bottom = 0;
2645
- ret.height = null ;
2646
- ret.marginTop= 0;
2647
- }
2648
-
2649
- // handle min/max
2650
- ret.minHeight = (layout.minHeight === undefined) ?
2651
- null :
2652
- layout.minHeight ;
2653
- ret.maxHeight = (layout.maxHeight === undefined) ?
2654
- null :
2655
- layout.maxHeight ;
2656
-
2657
- // if zIndex is set, use it. otherwise let default shine through
2658
- ret.zIndex = SC.none(layout.zIndex) ? null : layout.zIndex.toString();
2659
-
2660
- // if backgroundPosition is set, use it.
2661
- // otherwise let default shine through
2662
- ret.backgroundPosition = SC.none(layout.backgroundPosition) ?
2663
- null :
2664
- layout.backgroundPosition.toString() ;
2665
-
2666
- // set default values to null to allow built-in CSS to shine through
2667
- // currently applies only to marginLeft & marginTop
2668
- while(--loc >=0) {
2669
- x = dims[loc];
2670
- if (ret[x]===0) ret[x]=null;
2671
- }
2672
-
2673
- if (hasAcceleratedLayer) {
2674
- var transform = 'translateX('+translateLeft+'px) translateY('+translateTop+'px)';
2675
- if (SC.platform.supportsCSS3DTransforms) transform += ' translateZ(0px)'
2676
- ret[SC.platform.domCSSPrefix+'Transform'] = transform;
2677
- }
2678
-
2679
- // convert any numbers into a number + "px".
2680
- for(key in ret) {
2681
- value = ret[key];
2682
- if (typeof value === SC.T_NUMBER) ret[key] = (value + "px");
2683
- }
2684
- return ret ;
3000
+ var calculator = this.get('layoutStyleCalculator');
3001
+ calculator.set(props);
3002
+
3003
+ return calculator.calculate();
2685
3004
  }.property().cacheable(),
2686
-
3005
+
3006
+
3007
+
2687
3008
  /**
2688
- The view responsible for laying out this view. The default version
3009
+ The view responsible for laying out this view. The default version
2689
3010
  returns the current parent view.
2690
3011
  */
2691
3012
  layoutView: function() {
2692
3013
  return this.get('parentView') ;
2693
3014
  }.property('parentView').cacheable(),
2694
-
3015
+
2695
3016
  /**
2696
- This method is called whenever a property changes that invalidates the
2697
- layout of the view. Changing the layout will do this automatically, but
3017
+ This method is called whenever a property changes that invalidates the
3018
+ layout of the view. Changing the layout will do this automatically, but
2698
3019
  you can add others if you want.
2699
3020
 
2700
3021
  Implementation Note: In a traditional setup, we would simply observe
@@ -2702,7 +3023,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2702
3023
  implementation of propertyDidChange(), this method must always run
2703
3024
  immediately after 'layout' is updated to avoid the potential for stale
2704
3025
  (incorrect) cached 'frame' values.
2705
-
3026
+
2706
3027
  @returns {SC.View} receiver
2707
3028
  */
2708
3029
  layoutDidChange: function() {
@@ -2713,6 +3034,35 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2713
3034
  didResize = YES,
2714
3035
  previousWidth, previousHeight, currentWidth, currentHeight;
2715
3036
 
3037
+
3038
+ // Handle old style rotation
3039
+ if (!SC.none(currentLayout.rotate)) {
3040
+ if (SC.none(currentLayout.rotateX)) {
3041
+ currentLayout.rotateX = currentLayout.rotate;
3042
+ console.warn('Please set rotateX instead of rotate');
3043
+ }
3044
+ }
3045
+ if (!SC.none(currentLayout.rotateX)) {
3046
+ currentLayout.rotate = currentLayout.rotateX;
3047
+ } else {
3048
+ delete currentLayout.rotate;
3049
+ }
3050
+
3051
+ var animations = currentLayout.animations;
3052
+ if (animations) {
3053
+ if (!SC.none(animations.rotate)) {
3054
+ if (SC.none(animations.rotateX)) {
3055
+ animations.rotateX = animations.rotate;
3056
+ console.warn('Please animate rotateX instead of rotate');
3057
+ }
3058
+ }
3059
+ if (!SC.none(animations.rotateX)) {
3060
+ animations.rotate = animations.rotateX;
3061
+ } else {
3062
+ delete animations.rotate;
3063
+ }
3064
+ }
3065
+
2716
3066
  if (previousLayout && previousLayout !== currentLayout) {
2717
3067
  // This is a simple check to see whether we think the view may have
2718
3068
  // resized. We could look for a number of cases, but for now we'll
@@ -2732,6 +3082,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2732
3082
  }
2733
3083
 
2734
3084
  this.beginPropertyChanges() ;
3085
+ this.notifyPropertyChange('hasAcceleratedLayer');
2735
3086
  this.notifyPropertyChange('layoutStyle') ;
2736
3087
  if (didResize) {
2737
3088
  this.viewDidResize();
@@ -2742,7 +3093,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2742
3093
  this._viewFrameDidChange();
2743
3094
  }
2744
3095
  this.endPropertyChanges() ;
2745
-
3096
+
2746
3097
  // notify layoutView...
2747
3098
  var layoutView = this.get('layoutView');
2748
3099
  if (layoutView) {
@@ -2752,35 +3103,37 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2752
3103
  layoutView.invokeOnce(layoutView.layoutChildViewsIfNeeded);
2753
3104
  }
2754
3105
  }
2755
-
3106
+
3107
+ this._previousLayout = currentLayout;
3108
+
2756
3109
  return this ;
2757
3110
  },
2758
-
3111
+
2759
3112
  /**
2760
3113
  This this property to YES whenever the view needs to layout its child
2761
3114
  views. Normally this property is set automatically whenever the layout
2762
3115
  property for a child view changes.
2763
-
3116
+
2764
3117
  @property {Boolean}
2765
3118
  */
2766
3119
  childViewsNeedLayout: NO,
2767
-
3120
+
2768
3121
  /**
2769
- One of two methods that are invoked whenever one of your childViews
3122
+ One of two methods that are invoked whenever one of your childViews
2770
3123
  layout changes. This method is invoked everytime a child view's layout
2771
3124
  changes to give you a chance to record the information about the view.
2772
-
3125
+
2773
3126
  Since this method may be called many times during a single run loop, you
2774
3127
  should keep this method pretty short. The other method called when layout
2775
- changes, layoutChildViews(), is invoked only once at the end of
3128
+ changes, layoutChildViews(), is invoked only once at the end of
2776
3129
  the run loop. You should do any expensive operations (including changing
2777
3130
  a childView's actual layer) in this other method.
2778
-
3131
+
2779
3132
  Note that if as a result of running this method you decide that you do not
2780
- need your layoutChildViews() method run later, you can set the
2781
- childViewsNeedsLayout property to NO from this method and the layout
3133
+ need your layoutChildViews() method run later, you can set the
3134
+ childViewsNeedsLayout property to NO from this method and the layout
2782
3135
  method will not be called layer.
2783
-
3136
+
2784
3137
  @param {SC.View} childView the view whose layout has changed.
2785
3138
  @returns {void}
2786
3139
  */
@@ -2789,11 +3142,11 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2789
3142
  if (!set) set = this._needLayoutViews = SC.CoreSet.create();
2790
3143
  set.add(childView);
2791
3144
  },
2792
-
3145
+
2793
3146
  /**
2794
3147
  Called your layout method if the view currently needs to layout some
2795
3148
  child views.
2796
-
3149
+
2797
3150
  @param {Boolean} isVisible if true assume view is visible even if it is not.
2798
3151
  @returns {SC.View} receiver
2799
3152
  @test in layoutChildViews
@@ -2806,16 +3159,16 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2806
3159
  }
2807
3160
  return this ;
2808
3161
  },
2809
-
3162
+
2810
3163
  /**
2811
3164
  Applies the current layout to the layer. This method is usually only
2812
- called once per runloop. You can override this method to provide your
3165
+ called once per runloop. You can override this method to provide your
2813
3166
  own layout updating method if you want, though usually the better option
2814
3167
  is to override the layout method from the parent view.
2815
-
3168
+
2816
3169
  The default implementation of this method simply calls the renderLayout()
2817
3170
  method on the views that need layout.
2818
-
3171
+
2819
3172
  @returns {void}
2820
3173
  */
2821
3174
  layoutChildViews: function() {
@@ -2827,16 +3180,16 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2827
3180
  }
2828
3181
  set.clear(); // reset & reuse
2829
3182
  },
2830
-
3183
+
2831
3184
  /**
2832
- Invoked by the layoutChildViews method to update the layout on a
2833
- particular view. This method creates a render context and calls the
2834
- renderLayout() method, which is probably what you want to override instead
3185
+ Invoked by the layoutChildViews method to update the layout on a
3186
+ particular view. This method creates a render context and calls the
3187
+ renderLayout() method, which is probably what you want to override instead
2835
3188
  of this.
2836
-
2837
- You will not usually override this method, but you may call it if you
3189
+
3190
+ You will not usually override this method, but you may call it if you
2838
3191
  implement layoutChildViews() in a view yourself.
2839
-
3192
+
2840
3193
  @returns {SC.View} receiver
2841
3194
  @test in layoutChildViews
2842
3195
  */
@@ -2844,7 +3197,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2844
3197
  var layer = this.get('layer'), context;
2845
3198
  if (layer) {
2846
3199
  context = this.renderContext(layer);
2847
- this.renderLayout(context);
3200
+ this.renderLayout(context, NO);
2848
3201
  context.update();
2849
3202
 
2850
3203
  // If this view uses static layout, then notify if the frame changed.
@@ -2854,48 +3207,50 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2854
3207
  layer = null ;
2855
3208
  return this ;
2856
3209
  },
2857
-
3210
+
2858
3211
  /**
2859
3212
  Default method called by the layout view to actually apply the current
2860
- layout to the layer. The default implementation simply assigns the
3213
+ layout to the layer. The default implementation simply assigns the
2861
3214
  current layoutStyle to the layer. This method is also called whenever
2862
3215
  the layer is first created.
2863
-
3216
+
2864
3217
  @param {SC.RenderContext} the render context
2865
3218
  @returns {void}
2866
3219
  @test in layoutChildViews
2867
3220
  */
2868
3221
  renderLayout: function(context, firstTime) {
3222
+ this.get('layoutStyleCalculator').willRenderAnimations();
2869
3223
  context.addStyle(this.get('layoutStyle'));
3224
+ this.get('layoutStyleCalculator').didRenderAnimations();
2870
3225
  },
2871
-
3226
+
2872
3227
  /** walk like a duck */
2873
3228
  isView: YES,
2874
-
3229
+
2875
3230
  /**
2876
- Default method called when a selectstart event is triggered. This event is
2877
- only supported by IE. Used in sproutcore to disable text selection and
2878
- IE8 accelerators. The accelerators will be enabled only in
3231
+ Default method called when a selectstart event is triggered. This event is
3232
+ only supported by IE. Used in sproutcore to disable text selection and
3233
+ IE8 accelerators. The accelerators will be enabled only in
2879
3234
  text selectable views. In FF and Safari we use the css style 'allow-select'.
2880
-
3235
+
2881
3236
  If you want to enable text selection in certain controls is recommended
2882
- to override this function to always return YES , instead of setting
2883
- isTextSelectable to true.
2884
-
3237
+ to override this function to always return YES , instead of setting
3238
+ isTextSelectable to true.
3239
+
2885
3240
  For example in textfield you dont want to enable textSelection on the text
2886
3241
  hint only on the actual text you are entering. You can achieve that by
2887
3242
  only overriding this method.
2888
-
3243
+
2889
3244
  @param evt {SC.Event} the selectstart event
2890
3245
  @returns YES if selectable
2891
3246
  */
2892
3247
  selectStart: function(evt) {
2893
3248
  return this.get('isTextSelectable');
2894
3249
  },
2895
-
3250
+
2896
3251
  /**
2897
3252
  Used to block the contextMenu per view.
2898
-
3253
+
2899
3254
  @param evt {SC.Event} the contextmenu event
2900
3255
  @returns YES if the contextmenu can show up
2901
3256
  */
@@ -2903,14 +3258,14 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2903
3258
  if(!this.get('isContextMenuEnabled')) evt.stop();
2904
3259
  return true;
2905
3260
  },
2906
-
3261
+
2907
3262
  /**
2908
3263
  A boundary set of distances outside which the touch will not be considered "inside" the view anymore.
2909
-
3264
+
2910
3265
  By default, up to 50px on each side.
2911
3266
  */
2912
3267
  touchBoundary: { left: 50, right: 50, top: 50, bottom: 50 },
2913
-
3268
+
2914
3269
  /**
2915
3270
  @private
2916
3271
  A computed property based on frame.
@@ -2918,14 +3273,14 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2918
3273
  _touchBoundaryFrame: function (){
2919
3274
  return this.get("parentView").convertFrameToView(this.get('frame'), null);
2920
3275
  }.property("frame", "parentView").cacheable(),
2921
-
3276
+
2922
3277
  /**
2923
3278
  Returns YES if the provided touch is within the boundary.
2924
3279
  */
2925
3280
  touchIsInBoundary: function(touch) {
2926
3281
  var f = this.get("_touchBoundaryFrame"), maxX = 0, maxY = 0, boundary = this.get("touchBoundary");
2927
3282
  var x = touch.pageX, y = touch.pageY;
2928
-
3283
+
2929
3284
  if (x < f.x) {
2930
3285
  x = f.x - x;
2931
3286
  maxX = boundary.left;
@@ -2936,7 +3291,7 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2936
3291
  x = 0;
2937
3292
  maxX = 1;
2938
3293
  }
2939
-
3294
+
2940
3295
  if (y < f.y) {
2941
3296
  y = f.y - y;
2942
3297
  maxY = boundary.top;
@@ -2947,26 +3302,208 @@ SC.View = SC.Responder.extend(SC.DelegateSupport,
2947
3302
  y = 0;
2948
3303
  maxY = 1;
2949
3304
  }
2950
-
3305
+
2951
3306
  if (x > 100 || y > 100) return NO;
2952
3307
  return YES;
3308
+ },
3309
+
3310
+ ///
3311
+ /// BUILDING IN/OUT
3312
+ ///
3313
+
3314
+ /**
3315
+ Call this to append a child while building it in. If the child is not
3316
+ buildable, this is the same as calling appendChild.
3317
+ */
3318
+ buildInChild: function(view) {
3319
+ view.willBuildInToView(this);
3320
+ this.appendChild(view);
3321
+ view.buildInToView(this);
3322
+ },
3323
+
3324
+ /**
3325
+ Call to remove a child after building it out. If the child is not buildable,
3326
+ this will simply call removeChild.
3327
+ */
3328
+ buildOutChild: function(view) {
3329
+ view.buildOutFromView(this);
3330
+ },
3331
+
3332
+ /**
3333
+ Called by child view when build in finishes. By default, does nothing.
3334
+
3335
+ */
3336
+ buildInDidFinishFor: function(child) {
3337
+ },
3338
+
3339
+ /**
3340
+ @private
3341
+ Called by child view when build out finishes. By default removes the child view.
3342
+ */
3343
+ buildOutDidFinishFor: function(child) {
3344
+ this.removeChild(child);
3345
+ },
3346
+
3347
+ /**
3348
+ Whether the view is currently building in.
3349
+ */
3350
+ isBuildingIn: NO,
3351
+
3352
+ /**
3353
+ Whether the view is currently building out.
3354
+ */
3355
+ isBuildingOut: NO,
3356
+
3357
+ /**
3358
+ Implement this, and call didFinishBuildIn when you are done.
3359
+ */
3360
+ buildIn: function() {
3361
+ this.buildInDidFinish();
3362
+ },
3363
+
3364
+ /**
3365
+ Implement this, and call didFinsihBuildOut when you are done.
3366
+ */
3367
+ buildOut: function() {
3368
+ this.buildOutDidFinish();
3369
+ },
3370
+
3371
+ /**
3372
+ This should reset (without animation) any internal states; sometimes called before.
3373
+
3374
+ It is usually called before a build in, by the parent view.
3375
+ */
3376
+ resetBuild: function() {
3377
+
3378
+ },
3379
+
3380
+ /**
3381
+ Implement this if you need to do anything special when cancelling build out;
3382
+ note that buildIn will subsequently be called, so you usually won't need to do
3383
+ anything.
3384
+
3385
+ This is basically called whenever build in happens.
3386
+ */
3387
+ buildOutDidCancel: function() {
3388
+
3389
+ },
3390
+
3391
+ /**
3392
+ Implement this if you need to do anything special when cancelling build in.
3393
+ You probably won't be able to do anything. I mean, what are you gonna do?
3394
+
3395
+ If build in was cancelled, it means build out is probably happening.
3396
+ So, any timers or anything you had going, you can cancel.
3397
+ Then buildOut will happen.
3398
+ */
3399
+ buildInDidCancel: function() {
3400
+
3401
+ },
3402
+
3403
+ /**
3404
+ Call this when you have built in.
3405
+ */
3406
+ buildInDidFinish: function() {
3407
+ this.isBuildingIn = NO;
3408
+ this._buildingInTo.buildInDidFinishFor(this);
3409
+ this._buildingInTo = null;
3410
+ },
3411
+
3412
+ /**
3413
+ Call this when you have finished building out.
3414
+ */
3415
+ buildOutDidFinish: function() {
3416
+ this.isBuildingOut = NO;
3417
+ this._buildingOutFrom.buildOutDidFinishFor(this);
3418
+ this._buildingOutFrom = null;
3419
+ },
3420
+
3421
+ /**
3422
+ Usually called by parentViewDidChange, this resets the build state (calling resetBuild in the process).
3423
+ */
3424
+ resetBuildState: function() {
3425
+ if (this.isBuildingIn) {
3426
+ this.buildInDidCancel();
3427
+ this.isBuildingIn = NO;
3428
+ }
3429
+ if (this.isBuildingOut) {
3430
+ this.buildOutDidCancel();
3431
+ this.isBuildingOut = NO;
3432
+ }
3433
+
3434
+ // finish cleaning up
3435
+ this.buildingInTo = null;
3436
+ this.buildingOutFrom = null;
3437
+
3438
+ this.resetBuild();
3439
+ },
3440
+
3441
+ /**
3442
+ @private (semi)
3443
+ Called by building parent view's buildInChild method. This prepares
3444
+ to build in, but unlike buildInToView, this is called _before_ the child
3445
+ is appended.
3446
+
3447
+ Mostly, this cancels any build out _before_ the view is removed through parent change.
3448
+ */
3449
+ willBuildInToView: function(view) {
3450
+ // stop any current build outs (and if we need to, we also need to build in again)
3451
+ if (this.isBuildingOut) {
3452
+ this.buildOutDidCancel();
3453
+ }
3454
+ },
3455
+
3456
+ /**
3457
+ @private (semi)
3458
+ Called by building parent view's buildInChild method.
3459
+ */
3460
+ buildInToView: function(view) {
3461
+ // if we are already building in, do nothing.
3462
+ if (this.isBuildingIn) return;
3463
+
3464
+ this._buildingInTo = view;
3465
+ this.isBuildingOut = NO;
3466
+ this.isBuildingIn = YES;
3467
+ this.buildIn();
3468
+ },
3469
+
3470
+ /**
3471
+ @private (semi)
3472
+ Called by building parent view's buildOutChild method.
3473
+
3474
+ The supplied view should always be the parent view.
3475
+ */
3476
+ buildOutFromView: function(view) {
3477
+ // if we are already building out, do nothing.
3478
+ if (this.isBuildingOut) return;
3479
+
3480
+ // cancel any build ins
3481
+ if (this.isBuildingIn) {
3482
+ this.buildInDidCancel();
3483
+ }
3484
+
3485
+ // in any case, we need to build out
3486
+ this.isBuildingOut = YES;
3487
+ this.isBuildingIn = NO;
3488
+ this._buildingOutFrom = view;
3489
+ this.buildOut();
2953
3490
  }
2954
3491
  });
2955
3492
 
2956
3493
  SC.View.mixin(/** @scope SC.View */ {
2957
-
3494
+
2958
3495
  /** @private walk like a duck -- used by SC.Page */
2959
3496
  isViewClass: YES,
2960
-
3497
+
2961
3498
  /**
2962
3499
  This method works just like extend() except that it will also preserve
2963
- the passed attributes in case you want to use a view builder later, if
3500
+ the passed attributes in case you want to use a view builder later, if
2964
3501
  needed.
2965
-
3502
+
2966
3503
  @param {Hash} attrs Attributes to add to view
2967
3504
  @returns {Class} SC.View subclass to create
2968
3505
  @function
2969
- */
3506
+ */
2970
3507
  design: function() {
2971
3508
  if (this.isDesign) return this; // only run design one time
2972
3509
  var ret = this.extend.apply(this, arguments);
@@ -2976,30 +3513,41 @@ SC.View.mixin(/** @scope SC.View */ {
2976
3513
  }
2977
3514
  return ret ;
2978
3515
  },
2979
-
3516
+
3517
+ extend: function() {
3518
+ var last = arguments[arguments.length - 1];
3519
+
3520
+ if (last && !SC.none(last.theme)) {
3521
+ last.themeName = last.theme;
3522
+ delete last.theme;
3523
+ }
3524
+
3525
+ return SC.Object.extend.apply(this, arguments);
3526
+ },
3527
+
2980
3528
  /**
2981
- Helper applies the layout to the prototype.
3529
+ Helper applies the layout to the prototype.
2982
3530
  */
2983
3531
  layout: function(layout) {
2984
3532
  this.prototype.layout = layout ;
2985
3533
  return this ;
2986
3534
  },
2987
-
3535
+
2988
3536
  /**
2989
3537
  Convert any layout to a Top, Left, Width, Height layout
2990
3538
  */
2991
3539
  convertLayoutToAnchoredLayout: function(layout, parentFrame){
2992
3540
  var ret = {top: 0, left: 0, width: parentFrame.width, height: parentFrame.height},
2993
3541
  pFW = parentFrame.width, pFH = parentFrame.height, //shortHand for parentDimensions
2994
- lR = layout.right,
2995
- lL = layout.left,
2996
- lT = layout.top,
2997
- lB = layout.bottom,
2998
- lW = layout.width,
2999
- lH = layout.height,
3000
- lcX = layout.centerX,
3542
+ lR = layout.right,
3543
+ lL = layout.left,
3544
+ lT = layout.top,
3545
+ lB = layout.bottom,
3546
+ lW = layout.width,
3547
+ lH = layout.height,
3548
+ lcX = layout.centerX,
3001
3549
  lcY = layout.centerY;
3002
-
3550
+
3003
3551
  // X Conversion
3004
3552
  // handle left aligned and left/right
3005
3553
  if (!SC.none(lL)) {
@@ -3016,21 +3564,21 @@ SC.View.mixin(/** @scope SC.View */ {
3016
3564
 
3017
3565
  // handle right aligned
3018
3566
  } else if (!SC.none(lR)) {
3019
-
3567
+
3020
3568
  // if no width, calculate it from the parent frame
3021
3569
  if (SC.none(lW)) {
3022
3570
  ret.left = 0;
3023
3571
  if(lR && SC.isPercentage(lR)) ret.width = pFW - (lR*pFW);
3024
3572
  else ret.width = pFW - (lR || 0);
3025
-
3573
+
3026
3574
  // If has width, calculate the left anchor from the width and right and parent frame
3027
3575
  } else {
3028
3576
  if(lW === SC.LAYOUT_AUTO) ret.width = SC.LAYOUT_AUTO ;
3029
- else {
3577
+ else {
3030
3578
  if (SC.isPercentage(lW)) ret.width = lW*pFW;
3031
3579
  else ret.width = lW;
3032
3580
  if (SC.isPercentage(lR)) ret.left = pFW - (ret.width + lR);
3033
- else ret.left = pFW - (ret.width + lR);
3581
+ else ret.left = pFW - (ret.width + lR);
3034
3582
  }
3035
3583
  }
3036
3584
 
@@ -3041,7 +3589,7 @@ SC.View.mixin(/** @scope SC.View */ {
3041
3589
  ret.left = ((pFW - ret.width)/2);
3042
3590
  if (SC.isPercentage(lcX)) ret.left = ret.left + lcX*pFW;
3043
3591
  else ret.left = ret.left + lcX;
3044
-
3592
+
3045
3593
  // if width defined, assume left of zero
3046
3594
  } else if (!SC.none(lW)) {
3047
3595
  ret.left = 0;
@@ -3059,8 +3607,8 @@ SC.View.mixin(/** @scope SC.View */ {
3059
3607
 
3060
3608
  // handle min/max
3061
3609
  if (layout.minWidth !== undefined) ret.minWidth = layout.minWidth ;
3062
- if (layout.maxWidth !== undefined) ret.maxWidth = layout.maxWidth ;
3063
-
3610
+ if (layout.maxWidth !== undefined) ret.maxWidth = layout.maxWidth ;
3611
+
3064
3612
  // Y Conversion
3065
3613
  // handle left aligned and top/bottom
3066
3614
  if (!SC.none(lT)) {
@@ -3078,22 +3626,22 @@ SC.View.mixin(/** @scope SC.View */ {
3078
3626
 
3079
3627
  // handle bottom aligned
3080
3628
  } else if (!SC.none(lB)) {
3081
-
3629
+
3082
3630
  // if no height, calculate it from the parent frame
3083
3631
  if (SC.none(lH)) {
3084
3632
  ret.top = 0;
3085
3633
  if (lB && SC.isPercentage(lB)) ret.height = pFH - (lB*pFH);
3086
3634
  else ret.height = pFH - (lB || 0);
3087
-
3635
+
3088
3636
  // If has height, calculate the top anchor from the height and bottom and parent frame
3089
3637
  } else {
3090
3638
  if(lH === SC.LAYOUT_AUTO) ret.height = SC.LAYOUT_AUTO ;
3091
- else {
3639
+ else {
3092
3640
  if (SC.isPercentage(lH)) ret.height = lH*pFH;
3093
3641
  else ret.height = lH;
3094
3642
  ret.top = pFH - ret.height;
3095
3643
  if (SC.isPercentage(lB)) ret.top = ret.top - (lB*pFH);
3096
- else ret.top = ret.top - lB;
3644
+ else ret.top = ret.top - lB;
3097
3645
  }
3098
3646
  }
3099
3647
 
@@ -3104,7 +3652,7 @@ SC.View.mixin(/** @scope SC.View */ {
3104
3652
  ret.top = ((pFH - ret.height)/2);
3105
3653
  if(SC.isPercentage(lcY)) ret.top = ret.top + lcY*pFH;
3106
3654
  else ret.top = ret.top + lcY;
3107
-
3655
+
3108
3656
  // if height defined, assume top of zero
3109
3657
  } else if (!SC.none(lH)) {
3110
3658
  ret.top = 0;
@@ -3117,7 +3665,7 @@ SC.View.mixin(/** @scope SC.View */ {
3117
3665
  ret.top = 0;
3118
3666
  ret.height = 0;
3119
3667
  }
3120
-
3668
+
3121
3669
  if(ret.top) ret.top = Math.floor(ret.top);
3122
3670
  if(ret.bottom) ret.bottom = Math.floor(ret.bottom);
3123
3671
  if(ret.left) ret.left = Math.floor(ret.left);
@@ -3128,17 +3676,17 @@ SC.View.mixin(/** @scope SC.View */ {
3128
3676
  // handle min/max
3129
3677
  if (layout.minHeight !== undefined) ret.minHeight = layout.minHeight ;
3130
3678
  if (layout.maxHeight !== undefined) ret.maxHeight = layout.maxHeight ;
3131
-
3679
+
3132
3680
  return ret;
3133
3681
  },
3134
-
3682
+
3135
3683
  /**
3136
3684
  For now can only convert Top/Left/Width/Height to a Custom Layout
3137
3685
  */
3138
3686
  convertLayoutToCustomLayout: function(layout, layoutParams, parentFrame){
3139
3687
  // TODO: [EG] Create Top/Left/Width/Height to a Custom Layout conversion
3140
3688
  },
3141
-
3689
+
3142
3690
  /**
3143
3691
  Helper applies the classNames to the prototype
3144
3692
  */
@@ -3147,7 +3695,7 @@ SC.View.mixin(/** @scope SC.View */ {
3147
3695
  this.prototype.classNames = sc;
3148
3696
  return this ;
3149
3697
  },
3150
-
3698
+
3151
3699
  /**
3152
3700
  Help applies the tagName
3153
3701
  */
@@ -3155,7 +3703,7 @@ SC.View.mixin(/** @scope SC.View */ {
3155
3703
  this.prototype.tagName = tg;
3156
3704
  return this ;
3157
3705
  },
3158
-
3706
+
3159
3707
  /**
3160
3708
  Helper adds the childView
3161
3709
  */
@@ -3168,7 +3716,7 @@ SC.View.mixin(/** @scope SC.View */ {
3168
3716
  this.prototype.childViews = childViews;
3169
3717
  return this ;
3170
3718
  },
3171
-
3719
+
3172
3720
  /**
3173
3721
  Helper adds a binding to a design
3174
3722
  */
@@ -3177,12 +3725,12 @@ SC.View.mixin(/** @scope SC.View */ {
3177
3725
  var bindings = p._bindings ;
3178
3726
  if (!bindings || bindings === s._bindings) {
3179
3727
  bindings = p._bindings = (bindings || []).slice() ;
3180
- }
3181
-
3728
+ }
3729
+
3182
3730
  keyName = keyName + "Binding";
3183
3731
  p[keyName] = path ;
3184
3732
  bindings.push(keyName);
3185
-
3733
+
3186
3734
  return this ;
3187
3735
  },
3188
3736
 
@@ -3193,23 +3741,23 @@ SC.View.mixin(/** @scope SC.View */ {
3193
3741
  this.prototype[keyName] = value;
3194
3742
  return this ;
3195
3743
  },
3196
-
3744
+
3197
3745
  /**
3198
3746
  Used to construct a localization for a view. The default implementation
3199
3747
  will simply return the passed attributes.
3200
3748
  */
3201
- localization: function(attrs, rootElement) {
3749
+ localization: function(attrs, rootElement) {
3202
3750
  // add rootElement
3203
3751
  if (rootElement) attrs.rootElement = SC.$(rootElement)[0];
3204
- return attrs;
3752
+ return attrs;
3205
3753
  },
3206
-
3754
+
3207
3755
  /**
3208
3756
  Creates a view instance, first finding the DOM element you name and then
3209
- using that as the root element. You should not use this method very
3210
- often, but it is sometimes useful if you want to attach to already
3757
+ using that as the root element. You should not use this method very
3758
+ often, but it is sometimes useful if you want to attach to already
3211
3759
  existing HTML.
3212
-
3760
+
3213
3761
  @param {String|Element} element
3214
3762
  @param {Hash} attrs
3215
3763
  @returns {SC.View} instance
@@ -3223,39 +3771,46 @@ SC.View.mixin(/** @scope SC.View */ {
3223
3771
  args = args[0] = null;
3224
3772
  return ret ;
3225
3773
  },
3226
-
3774
+
3227
3775
  /**
3228
- Create a new view with the passed attributes hash. If you have the
3776
+ Create a new view with the passed attributes hash. If you have the
3229
3777
  Designer module loaded, this will also create a peer designer if needed.
3230
3778
  */
3231
3779
  create: function() {
3232
- var C=this, ret = new C(arguments);
3780
+ var last = arguments[arguments.length - 1];
3781
+
3782
+ if (last && last.theme) {
3783
+ last.themeName = last.theme;
3784
+ delete last.theme;
3785
+ }
3786
+
3787
+ var C=this, ret = new C(arguments);
3233
3788
  if (SC.ViewDesigner) {
3234
3789
  SC.ViewDesigner.didCreateView(ret, SC.$A(arguments));
3235
3790
  }
3236
- return ret ;
3791
+ return ret ;
3237
3792
  },
3238
-
3793
+
3239
3794
  /**
3240
3795
  Applies the passed localization hash to the component views. Call this
3241
3796
  method before you call create(). Returns the receiver. Typically you
3242
3797
  will do something like this:
3243
-
3798
+
3244
3799
  view = SC.View.design({...}).loc(localizationHash).create();
3245
-
3246
- @param {Hash} loc
3800
+
3801
+ @param {Hash} loc
3247
3802
  @param rootElement {String} optional rootElement with prepped HTML
3248
3803
  @returns {SC.View} receiver
3249
3804
  */
3250
3805
  loc: function(loc) {
3251
3806
  var childLocs = loc.childViews;
3252
3807
  delete loc.childViews; // clear out child views before applying to attrs
3253
-
3808
+
3254
3809
  this.applyLocalizedAttributes(loc) ;
3255
3810
  if (SC.ViewDesigner) {
3256
3811
  SC.ViewDesigner.didLoadLocalization(this, SC.$A(arguments));
3257
3812
  }
3258
-
3813
+
3259
3814
  // apply localization recursively to childViews
3260
3815
  var childViews = this.prototype.childViews, idx = childViews.length,
3261
3816
  viewClass;
@@ -3264,10 +3819,10 @@ SC.View.mixin(/** @scope SC.View */ {
3264
3819
  loc = childLocs[idx];
3265
3820
  if (loc && viewClass && viewClass.loc) viewClass.loc(loc) ;
3266
3821
  }
3267
-
3822
+
3268
3823
  return this; // done!
3269
3824
  },
3270
-
3825
+
3271
3826
  /**
3272
3827
  Internal method actually updates the localizated attributes on the view
3273
3828
  class. This is overloaded in design mode to also save the attributes.
@@ -3275,18 +3830,18 @@ SC.View.mixin(/** @scope SC.View */ {
3275
3830
  applyLocalizedAttributes: function(loc) {
3276
3831
  SC.mixin(this.prototype, loc) ;
3277
3832
  },
3278
-
3833
+
3279
3834
  views: {}
3280
-
3835
+
3281
3836
  }) ;
3282
3837
 
3283
3838
  // .......................................................
3284
3839
  // OUTLET BUILDER
3285
3840
  //
3286
3841
 
3287
- /**
3842
+ /**
3288
3843
  Generates a computed property that will look up the passed property path
3289
- the first time you try to get the value. Use this whenever you want to
3844
+ the first time you try to get the value. Use this whenever you want to
3290
3845
  define an outlet that points to another view or object. The root object
3291
3846
  used for the path will be the receiver.
3292
3847
  */
@@ -3306,8 +3861,143 @@ SC.View.unload = function() {
3306
3861
  if (!views.hasOwnProperty(key)) continue ;
3307
3862
  delete views[key];
3308
3863
  }
3309
- }
3864
+ }
3310
3865
  } ;
3311
3866
 
3867
+ SC.View.runCallback = function(callback){
3868
+ var additionalArgs = SC.$A(arguments).slice(1),
3869
+ typeOfAction = SC.typeOf(callback.action);
3870
+
3871
+ // if the action is a function, just try to call it.
3872
+ if (typeOfAction == SC.T_FUNCTION) {
3873
+ callback.action.apply(callback.target, additionalArgs);
3874
+
3875
+ // otherwise, action should be a string. If it has a period, treat it
3876
+ // like a property path.
3877
+ } else if (typeOfAction === SC.T_STRING) {
3878
+ if (callback.action.indexOf('.') >= 0) {
3879
+ var path = callback.action.split('.') ;
3880
+ var property = path.pop() ;
3881
+
3882
+ var target = SC.objectForPropertyPath(path, window) ;
3883
+ var action = target.get ? target.get(property) : target[property];
3884
+ if (action && SC.typeOf(action) == SC.T_FUNCTION) {
3885
+ action.apply(target, additionalArgs);
3886
+ } else {
3887
+ throw 'SC.runCallback could not find a function at %@'.fmt(callback.action) ;
3888
+ }
3889
+
3890
+ // otherwise, try to execute action direction on target or send down
3891
+ // responder chain.
3892
+ // FIXME: Add support for additionalArgs to this
3893
+ // } else {
3894
+ // SC.RootResponder.responder.sendAction(callback.action, callback.target, callback.source, callback.source.get("pane"), null, callback.source);
3895
+ }
3896
+ }
3897
+ };
3898
+
3899
+ /**
3900
+ @class
3901
+ @private
3902
+ View Render Delegate Proxies are tool SC.Views use to:
3903
+
3904
+ a) limit properties the render delegate can access to the displayProperties
3905
+ b) look up 'display*' ('displayTitle' instead of 'title') to help deal with
3906
+ differences between the render delegate's API and the view's.
3907
+
3908
+ RenderDelegateProxies are fully valid data sources for render delegates. They
3909
+ act as proxies to the view, interpreting the .get and .didChangeFor commands
3910
+ based on the view's displayProperties.
3911
+
3912
+ This tool is not useful outside of SC.View itself, and as such, is private.
3913
+ */
3914
+ SC.View._RenderDelegateProxy = {
3915
+
3916
+ // for testing:
3917
+ isViewRenderDelegateProxy: YES,
3918
+
3919
+ /**
3920
+ * Creates a View Render Delegate Proxy for the specified view.
3921
+ *
3922
+ * Implementation note: this creates a hash of the view's displayProperties
3923
+ * array so that the proxy may quickly determine whether a property is a
3924
+ * displayProperty or not. This could cause issues if the view's displayProperties
3925
+ * array is modified after instantiation.
3926
+ *
3927
+ * @param {SC.View} view The view this proxy should proxy to.
3928
+ * @returns SC.View._RenderDelegateProxy
3929
+ */
3930
+ createForView: function(view) {
3931
+ var ret = SC.beget(this);
3932
+
3933
+ // set up displayProperty lookup for performance
3934
+ var dp = view.get('displayProperties'), lookup = {};
3935
+ for (var idx = 0, len = dp.length; idx < len; idx++) {
3936
+ lookup[dp[idx]] = YES;
3937
+ }
3938
+
3939
+ // also allow the few special properties through
3940
+ lookup['theme'] = YES;
3941
+
3942
+ ret._displayPropertiesLookup = lookup;
3943
+ ret.renderState = {};
3944
+
3945
+ ret.view = view;
3946
+ return ret;
3947
+ },
3948
+
3949
+
3950
+ /**
3951
+ * Provides the render delegate with any property it needs.
3952
+ *
3953
+ * This first looks up whether the property exists in the view's
3954
+ * displayProperties, and whether it exists prefixed with 'display';
3955
+ * for instance, if the render delegate asks for 'title', this will
3956
+ * look for 'displayTitle' in the view's displayProperties array.
3957
+ *
3958
+ * @param {String} property The name of the property the render delegate needs.
3959
+ * @returns The value.
3960
+ */
3961
+ get: function(property) {
3962
+ if (this[property] !== undefined) return this[property];
3963
+
3964
+ var displayProperty = 'display' + property.capitalize();
3965
+
3966
+ if (this._displayPropertiesLookup[displayProperty]) {
3967
+ return this.view.get(displayProperty);
3968
+ } else if (this._displayPropertiesLookup[property]) {
3969
+ return this.view.get(property);
3970
+ }
3971
+
3972
+ return undefined;
3973
+ },
3974
+
3975
+ /**
3976
+ * Checks if any of the specified properties have changed.
3977
+ *
3978
+ * For each property passed, this first determines whether to use the
3979
+ * 'display' prefix. Then, it calls view.didChangeFor with context and that
3980
+ * property name.
3981
+ *
3982
+ */
3983
+ didChangeFor: function(context) {
3984
+ var len = arguments.length, idx;
3985
+ for (idx = 1; idx < len; idx++) {
3986
+ var property = arguments[idx],
3987
+ displayProperty = 'display' + property.capitalize();
3988
+
3989
+ if (this._displayPropertiesLookup[displayProperty]) {
3990
+ if (this.view.didChangeFor(context, displayProperty)) return YES;
3991
+ } else if (this._displayPropertiesLookup[property]) {
3992
+ if (this.view.didChangeFor(context, property)) return YES;
3993
+ }
3994
+ }
3995
+
3996
+ return NO;
3997
+ }
3998
+ };
3999
+
3312
4000
  //unload views for IE, trying to collect memory.
3313
4001
  if(SC.browser.msie) SC.Event.add(window, 'unload', SC.View, SC.View.unload) ;
4002
+
4003
+