sproutit-sproutcore 1.0.0.20090407205609 → 1.0.0.20090408130025

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (574) hide show
  1. data/frameworks/sproutcore/Buildfile +63 -0
  2. data/frameworks/sproutcore/HISTORY +682 -0
  3. data/frameworks/sproutcore/README +22 -0
  4. data/frameworks/sproutcore/apps/sc_jsdoc/controllers/docs.js +149 -0
  5. data/frameworks/sproutcore/apps/sc_jsdoc/core.js +16 -0
  6. data/frameworks/sproutcore/apps/sc_jsdoc/english.lproj/body.css +17 -0
  7. data/frameworks/sproutcore/apps/sc_jsdoc/english.lproj/body.js +99 -0
  8. data/frameworks/sproutcore/apps/sc_jsdoc/english.lproj/images/sproutcore-logo.png +0 -0
  9. data/frameworks/sproutcore/apps/sc_jsdoc/english.lproj/strings.js +15 -0
  10. data/frameworks/sproutcore/apps/sc_jsdoc/main.js +27 -0
  11. data/frameworks/sproutcore/apps/sc_jsdoc/models/doc.js +21 -0
  12. data/frameworks/sproutcore/apps/sc_qunit/controllers/runner.js +209 -0
  13. data/frameworks/sproutcore/apps/sc_qunit/core.js +16 -0
  14. data/frameworks/sproutcore/apps/sc_qunit/english.lproj/body.css +17 -0
  15. data/frameworks/sproutcore/apps/sc_qunit/english.lproj/body.js +107 -0
  16. data/frameworks/sproutcore/apps/sc_qunit/english.lproj/images/sproutcore-logo.png +0 -0
  17. data/frameworks/sproutcore/apps/sc_qunit/english.lproj/strings.js +15 -0
  18. data/frameworks/sproutcore/apps/sc_qunit/main.js +18 -0
  19. data/frameworks/sproutcore/apps/sc_qunit/models/test.js +24 -0
  20. data/frameworks/sproutcore/apps/sc_qunit/views/test_iframe.js +52 -0
  21. data/frameworks/sproutcore/apps/tests/controllers/targets.js +47 -0
  22. data/frameworks/sproutcore/apps/tests/controllers/test.js +20 -0
  23. data/frameworks/sproutcore/apps/tests/controllers/tests.js +38 -0
  24. data/frameworks/sproutcore/apps/tests/core.js +35 -0
  25. data/frameworks/sproutcore/apps/tests/english.lproj/loading.rhtml +9 -0
  26. data/frameworks/sproutcore/apps/tests/english.lproj/main_page.css +19 -0
  27. data/frameworks/sproutcore/apps/tests/english.lproj/main_page.js +86 -0
  28. data/frameworks/sproutcore/apps/tests/english.lproj/strings.js +17 -0
  29. data/frameworks/sproutcore/apps/tests/fixtures/target.js +43 -0
  30. data/frameworks/sproutcore/apps/tests/fixtures/test.js +43 -0
  31. data/frameworks/sproutcore/apps/tests/main.js +39 -0
  32. data/frameworks/sproutcore/apps/tests/models/target.js +49 -0
  33. data/frameworks/sproutcore/apps/tests/models/test.js +20 -0
  34. data/frameworks/sproutcore/apps/tests/tests/controllers/targets.js +15 -0
  35. data/frameworks/sproutcore/apps/tests/tests/controllers/test.js +15 -0
  36. data/frameworks/sproutcore/apps/tests/tests/controllers/tests.js +15 -0
  37. data/frameworks/sproutcore/apps/tests/tests/models/target.js +15 -0
  38. data/frameworks/sproutcore/apps/tests/tests/models/test.js +15 -0
  39. data/frameworks/sproutcore/apps/welcome/core.js +23 -0
  40. data/frameworks/sproutcore/apps/welcome/english.lproj/loading.rhtml +8 -0
  41. data/frameworks/sproutcore/apps/welcome/english.lproj/main_page.js +43 -0
  42. data/frameworks/sproutcore/apps/welcome/english.lproj/strings.js +15 -0
  43. data/frameworks/sproutcore/apps/welcome/main.js +36 -0
  44. data/frameworks/sproutcore/design/Design Charts.graffle +15819 -0
  45. data/frameworks/sproutcore/design/Record State Table.numbers +0 -0
  46. data/frameworks/sproutcore/frameworks/datastore/core.js +14 -0
  47. data/frameworks/sproutcore/frameworks/datastore/data_sources/cascade.js +113 -0
  48. data/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +256 -0
  49. data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +196 -0
  50. data/frameworks/sproutcore/frameworks/datastore/debug/json.js +71 -0
  51. data/frameworks/sproutcore/frameworks/datastore/debug/standard_setup.js +96 -0
  52. data/frameworks/sproutcore/frameworks/datastore/fixtures/author_fixtures.js +2503 -0
  53. data/frameworks/sproutcore/frameworks/datastore/fixtures/sample.js +17 -0
  54. data/frameworks/sproutcore/frameworks/datastore/models/fetched_attribute.js +92 -0
  55. data/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +38 -0
  56. data/frameworks/sproutcore/frameworks/datastore/models/record.js +430 -0
  57. data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +361 -0
  58. data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +305 -0
  59. data/frameworks/sproutcore/frameworks/datastore/system/query.js +128 -0
  60. data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +149 -0
  61. data/frameworks/sproutcore/frameworks/datastore/system/store.js +1689 -0
  62. data/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +86 -0
  63. data/frameworks/sproutcore/frameworks/datastore/tests/integration/contact_model.js +114 -0
  64. data/frameworks/sproutcore/frameworks/datastore/tests/integration/mail_model.js +91 -0
  65. data/frameworks/sproutcore/frameworks/datastore/tests/integration/test_runner_model.js +56 -0
  66. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +73 -0
  67. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/readAttribute.js +48 -0
  68. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/refresh.js +42 -0
  69. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +138 -0
  70. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/unknownProperty.js +46 -0
  71. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +71 -0
  72. data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +115 -0
  73. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +40 -0
  74. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +116 -0
  75. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +135 -0
  76. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/dataHashDidChange.js +110 -0
  77. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/discardChanges.js +99 -0
  78. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readDataHash.js +180 -0
  79. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readEditableDataHash.js +126 -0
  80. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/removeDataHash.js +163 -0
  81. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/writeDataHash.js +166 -0
  82. data/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/core_methods.js +175 -0
  83. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/cancelRecord.js +54 -0
  84. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +126 -0
  85. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +127 -0
  86. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/createRecord.js +57 -0
  87. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataHashDidChange.js +78 -0
  88. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataSourceCallbacks.js +247 -0
  89. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/destroyRecord.js +106 -0
  90. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/init.js +21 -0
  91. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushChanges.js +61 -0
  92. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/readDataHash.js +74 -0
  93. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/readEditableDataHash.js +74 -0
  94. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +74 -0
  95. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/removeDataHash.js +144 -0
  96. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/retrieveRecord.js +137 -0
  97. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/writeDataHash.js +130 -0
  98. data/frameworks/sproutcore/frameworks/debug/core.js +1 -0
  99. data/frameworks/sproutcore/frameworks/deprecated/core.js +61 -0
  100. data/frameworks/sproutcore/frameworks/deprecated/lib/button_views.rb +330 -0
  101. data/frameworks/sproutcore/frameworks/deprecated/lib/collection_view.rb +83 -0
  102. data/frameworks/sproutcore/frameworks/deprecated/lib/core_views.rb +326 -0
  103. data/frameworks/sproutcore/frameworks/deprecated/lib/form_views.rb +253 -0
  104. data/frameworks/sproutcore/frameworks/deprecated/lib/index.rhtml +75 -0
  105. data/frameworks/sproutcore/frameworks/deprecated/lib/menu_views.rb +93 -0
  106. data/frameworks/sproutcore/frameworks/deprecated/server/rails_server.js +80 -0
  107. data/frameworks/sproutcore/frameworks/deprecated/server/rest_server.js +178 -0
  108. data/frameworks/sproutcore/frameworks/deprecated/server/server.js +674 -0
  109. data/frameworks/sproutcore/frameworks/deprecated/system/animator.js +679 -0
  110. data/frameworks/sproutcore/frameworks/deprecated/system/binding.js +36 -0
  111. data/frameworks/sproutcore/frameworks/deprecated/system/browser.js +77 -0
  112. data/frameworks/sproutcore/frameworks/deprecated/system/classic_responder.js +314 -0
  113. data/frameworks/sproutcore/frameworks/deprecated/system/event.js +60 -0
  114. data/frameworks/sproutcore/frameworks/deprecated/system/globals.js +20 -0
  115. data/frameworks/sproutcore/frameworks/deprecated/system/misc.js +60 -0
  116. data/frameworks/sproutcore/frameworks/deprecated/system/node_descriptor.js +72 -0
  117. data/frameworks/sproutcore/frameworks/deprecated/system/object.js +124 -0
  118. data/frameworks/sproutcore/frameworks/deprecated/system/path_module.js +433 -0
  119. data/frameworks/sproutcore/frameworks/deprecated/system/string.js +109 -0
  120. data/frameworks/sproutcore/frameworks/deprecated/tests/application/application.rhtml +125 -0
  121. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/clippingFrame.rhtml +401 -0
  122. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/frame.rhtml +357 -0
  123. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/isVisibleInWindow.rhtml +147 -0
  124. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/base.rhtml +298 -0
  125. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/incremental_rendering.rhtml +260 -0
  126. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/source_list_rendering.rhtml +143 -0
  127. data/frameworks/sproutcore/frameworks/deprecated/tests/views/popup_button.rhtml +128 -0
  128. data/frameworks/sproutcore/frameworks/deprecated/tests/views/text_field.rhtml +37 -0
  129. data/frameworks/sproutcore/frameworks/deprecated/views/collection.js +24 -0
  130. data/frameworks/sproutcore/frameworks/designer/coders/design.js +30 -0
  131. data/frameworks/sproutcore/frameworks/designer/coders/localization.js +28 -0
  132. data/frameworks/sproutcore/frameworks/designer/coders/object.js +347 -0
  133. data/frameworks/sproutcore/frameworks/designer/controllers/page_design.js +102 -0
  134. data/frameworks/sproutcore/frameworks/designer/css/css_rule.js +22 -0
  135. data/frameworks/sproutcore/frameworks/designer/css/css_style.js +29 -0
  136. data/frameworks/sproutcore/frameworks/designer/css/css_style_sheet.js +201 -0
  137. data/frameworks/sproutcore/frameworks/designer/ext/page.js +88 -0
  138. data/frameworks/sproutcore/frameworks/designer/ext/view.js +40 -0
  139. data/frameworks/sproutcore/frameworks/designer/views/controls/button.js +18 -0
  140. data/frameworks/sproutcore/frameworks/designer/views/designer.js +553 -0
  141. data/frameworks/sproutcore/frameworks/designer/views/label.js +17 -0
  142. data/frameworks/sproutcore/frameworks/designer/views/mixins/button.js +13 -0
  143. data/frameworks/sproutcore/frameworks/designer/views/tab.js +17 -0
  144. data/frameworks/sproutcore/frameworks/desktop/core.js +6 -0
  145. data/frameworks/sproutcore/frameworks/desktop/debug/drag.js +41 -0
  146. data/frameworks/sproutcore/frameworks/desktop/english.lproj/alert.css +56 -0
  147. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/a_sample_image.jpg +0 -0
  148. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/apple-logo1.jpeg +0 -0
  149. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/iframe.html +23 -0
  150. data/frameworks/sproutcore/frameworks/desktop/english.lproj/disclosure.css +71 -0
  151. data/frameworks/sproutcore/frameworks/desktop/english.lproj/icons.css +943 -0
  152. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/blank.gif +0 -0
  153. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_222222.png +0 -0
  154. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_454545.png +0 -0
  155. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_888888.png +0 -0
  156. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_ffffff.png +0 -0
  157. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/shared.png +0 -0
  158. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/indicator.gif +0 -0
  159. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/panels/sprite-x.png +0 -0
  160. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/panels/sprite-y.png +0 -0
  161. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sc-theme-sprite.png +0 -0
  162. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/standard_fade/000000.png +0 -0
  163. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/standard_fade/ffffff.png +0 -0
  164. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sticky-note.png +0 -0
  165. data/frameworks/sproutcore/frameworks/desktop/english.lproj/list_item.css +156 -0
  166. data/frameworks/sproutcore/frameworks/desktop/english.lproj/menu.css +83 -0
  167. data/frameworks/sproutcore/frameworks/desktop/english.lproj/menu_item_view.css +99 -0
  168. data/frameworks/sproutcore/frameworks/desktop/english.lproj/palette.css +3 -0
  169. data/frameworks/sproutcore/frameworks/desktop/english.lproj/panel.css +94 -0
  170. data/frameworks/sproutcore/frameworks/desktop/english.lproj/picker.css +39 -0
  171. data/frameworks/sproutcore/frameworks/desktop/english.lproj/progress.css +31 -0
  172. data/frameworks/sproutcore/frameworks/desktop/english.lproj/radio.css +10 -0
  173. data/frameworks/sproutcore/frameworks/desktop/english.lproj/scroller.css +26 -0
  174. data/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +141 -0
  175. data/frameworks/sproutcore/frameworks/desktop/english.lproj/separator.css +19 -0
  176. data/frameworks/sproutcore/frameworks/desktop/english.lproj/slider.css +57 -0
  177. data/frameworks/sproutcore/frameworks/desktop/english.lproj/split.css +70 -0
  178. data/frameworks/sproutcore/frameworks/desktop/english.lproj/split_divider.css +8 -0
  179. data/frameworks/sproutcore/frameworks/desktop/english.lproj/strings.js +14 -0
  180. data/frameworks/sproutcore/frameworks/desktop/english.lproj/tab.css +12 -0
  181. data/frameworks/sproutcore/frameworks/desktop/english.lproj/text_field.css +29 -0
  182. data/frameworks/sproutcore/frameworks/desktop/english.lproj/toolbar.css +6 -0
  183. data/frameworks/sproutcore/frameworks/desktop/mixins/border.js +53 -0
  184. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_group.js +22 -0
  185. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_item.js +22 -0
  186. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +226 -0
  187. data/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +247 -0
  188. data/frameworks/sproutcore/frameworks/desktop/panes/alert.js +377 -0
  189. data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +504 -0
  190. data/frameworks/sproutcore/frameworks/desktop/panes/modal.js +68 -0
  191. data/frameworks/sproutcore/frameworks/desktop/panes/palette.js +63 -0
  192. data/frameworks/sproutcore/frameworks/desktop/panes/panel.js +184 -0
  193. data/frameworks/sproutcore/frameworks/desktop/panes/picker.js +402 -0
  194. data/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +46 -0
  195. data/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +39 -0
  196. data/frameworks/sproutcore/frameworks/desktop/protocols/drag_source.js +81 -0
  197. data/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +175 -0
  198. data/frameworks/sproutcore/frameworks/desktop/protocols/responder.js +280 -0
  199. data/frameworks/sproutcore/frameworks/desktop/system/drag.js +721 -0
  200. data/frameworks/sproutcore/frameworks/desktop/system/key_bindings.js +40 -0
  201. data/frameworks/sproutcore/frameworks/desktop/system/root_responder.js +641 -0
  202. data/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +187 -0
  203. data/frameworks/sproutcore/frameworks/desktop/tests/integration/dialog.js +43 -0
  204. data/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/methods.js +10 -0
  205. data/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +152 -0
  206. data/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/methods.js +10 -0
  207. data/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +57 -0
  208. data/frameworks/sproutcore/frameworks/desktop/tests/panes/palette/methods.js +10 -0
  209. data/frameworks/sproutcore/frameworks/desktop/tests/panes/palette/ui.js +36 -0
  210. data/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +10 -0
  211. data/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +40 -0
  212. data/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/methods.js +10 -0
  213. data/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +80 -0
  214. data/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/methods.js +10 -0
  215. data/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/ui.js +38 -0
  216. data/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +45 -0
  217. data/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +140 -0
  218. data/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +145 -0
  219. data/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/ui.js +99 -0
  220. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/methods.js +10 -0
  221. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selectPreviousItem.js +39 -0
  222. data/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/methods.js +10 -0
  223. data/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/ui.js +64 -0
  224. data/frameworks/sproutcore/frameworks/desktop/tests/views/grid/methods.js +10 -0
  225. data/frameworks/sproutcore/frameworks/desktop/tests/views/grid/ui.js +10 -0
  226. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/methods.js +10 -0
  227. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui.js +110 -0
  228. data/frameworks/sproutcore/frameworks/desktop/tests/views/list_item.js +255 -0
  229. data/frameworks/sproutcore/frameworks/desktop/tests/views/menu_item/methods.js +10 -0
  230. data/frameworks/sproutcore/frameworks/desktop/tests/views/menu_item/ui.js +44 -0
  231. data/frameworks/sproutcore/frameworks/desktop/tests/views/progress/methods.js +128 -0
  232. data/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +240 -0
  233. data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +113 -0
  234. data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +202 -0
  235. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +139 -0
  236. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +111 -0
  237. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroller/methods.js +63 -0
  238. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroller/ui.js +70 -0
  239. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +94 -0
  240. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +206 -0
  241. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +81 -0
  242. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +85 -0
  243. data/frameworks/sproutcore/frameworks/desktop/tests/views/separator.js +37 -0
  244. data/frameworks/sproutcore/frameworks/desktop/tests/views/source_list/methods.js +10 -0
  245. data/frameworks/sproutcore/frameworks/desktop/tests/views/source_list/ui.js +10 -0
  246. data/frameworks/sproutcore/frameworks/desktop/tests/views/split/methods.js +50 -0
  247. data/frameworks/sproutcore/frameworks/desktop/tests/views/split/ui.js +52 -0
  248. data/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +54 -0
  249. data/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +88 -0
  250. data/frameworks/sproutcore/frameworks/desktop/tests/views/text_field/methods.js +76 -0
  251. data/frameworks/sproutcore/frameworks/desktop/tests/views/text_field/ui.js +198 -0
  252. data/frameworks/sproutcore/frameworks/desktop/tests/views/web/methods.js +10 -0
  253. data/frameworks/sproutcore/frameworks/desktop/tests/views/web/ui.js +110 -0
  254. data/frameworks/sproutcore/frameworks/desktop/views/button.js +320 -0
  255. data/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +98 -0
  256. data/frameworks/sproutcore/frameworks/desktop/views/collection.js +2141 -0
  257. data/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +44 -0
  258. data/frameworks/sproutcore/frameworks/desktop/views/form.js +595 -0
  259. data/frameworks/sproutcore/frameworks/desktop/views/grid.js +199 -0
  260. data/frameworks/sproutcore/frameworks/desktop/views/list.js +706 -0
  261. data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +523 -0
  262. data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +437 -0
  263. data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +62 -0
  264. data/frameworks/sproutcore/frameworks/desktop/views/progress.js +207 -0
  265. data/frameworks/sproutcore/frameworks/desktop/views/radio.js +332 -0
  266. data/frameworks/sproutcore/frameworks/desktop/views/scene.js +56 -0
  267. data/frameworks/sproutcore/frameworks/desktop/views/scroll.js +648 -0
  268. data/frameworks/sproutcore/frameworks/desktop/views/scroller.js +203 -0
  269. data/frameworks/sproutcore/frameworks/desktop/views/segmented.js +509 -0
  270. data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +292 -0
  271. data/frameworks/sproutcore/frameworks/desktop/views/separator.js +37 -0
  272. data/frameworks/sproutcore/frameworks/desktop/views/slider.js +178 -0
  273. data/frameworks/sproutcore/frameworks/desktop/views/source_list.js +1117 -0
  274. data/frameworks/sproutcore/frameworks/desktop/views/source_list_group.js +169 -0
  275. data/frameworks/sproutcore/frameworks/desktop/views/split.js +651 -0
  276. data/frameworks/sproutcore/frameworks/desktop/views/split_divider.js +55 -0
  277. data/frameworks/sproutcore/frameworks/desktop/views/tab.js +190 -0
  278. data/frameworks/sproutcore/frameworks/desktop/views/text_field.js +233 -0
  279. data/frameworks/sproutcore/frameworks/desktop/views/thumb.js +49 -0
  280. data/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +49 -0
  281. data/frameworks/sproutcore/frameworks/desktop/views/web.js +86 -0
  282. data/frameworks/sproutcore/frameworks/foundation/TESTING +46 -0
  283. data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +490 -0
  284. data/frameworks/sproutcore/frameworks/foundation/controllers/controller.js +317 -0
  285. data/frameworks/sproutcore/frameworks/foundation/controllers/object.js +421 -0
  286. data/frameworks/sproutcore/frameworks/foundation/core.js +111 -0
  287. data/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +172 -0
  288. data/frameworks/sproutcore/frameworks/foundation/english.lproj/blank.gif +0 -0
  289. data/frameworks/sproutcore/frameworks/foundation/english.lproj/bootstrap.rhtml +53 -0
  290. data/frameworks/sproutcore/frameworks/foundation/english.lproj/button_view.css +55 -0
  291. data/frameworks/sproutcore/frameworks/foundation/english.lproj/core.css +5 -0
  292. data/frameworks/sproutcore/frameworks/foundation/english.lproj/debug/control-test-pane.css +8 -0
  293. data/frameworks/sproutcore/frameworks/foundation/english.lproj/images/sproutcore-logo.png +0 -0
  294. data/frameworks/sproutcore/frameworks/foundation/english.lproj/static_layout.css +5 -0
  295. data/frameworks/sproutcore/frameworks/foundation/english.lproj/view.css +40 -0
  296. data/frameworks/sproutcore/frameworks/foundation/ext/object.js +81 -0
  297. data/frameworks/sproutcore/frameworks/foundation/ext/run_loop.js +158 -0
  298. data/frameworks/sproutcore/frameworks/foundation/fixtures/file_exists.json +1 -0
  299. data/frameworks/sproutcore/frameworks/foundation/mixins/button.js +291 -0
  300. data/frameworks/sproutcore/frameworks/foundation/mixins/content_display.js +88 -0
  301. data/frameworks/sproutcore/frameworks/foundation/mixins/control.js +352 -0
  302. data/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +146 -0
  303. data/frameworks/sproutcore/frameworks/foundation/mixins/responder.js +156 -0
  304. data/frameworks/sproutcore/frameworks/foundation/mixins/selection_support.js +154 -0
  305. data/frameworks/sproutcore/frameworks/foundation/mixins/static_layout.js +101 -0
  306. data/frameworks/sproutcore/frameworks/foundation/mixins/string.js +237 -0
  307. data/frameworks/sproutcore/frameworks/foundation/mixins/validatable.js +176 -0
  308. data/frameworks/sproutcore/frameworks/foundation/panes/main.js +47 -0
  309. data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +555 -0
  310. data/frameworks/sproutcore/frameworks/foundation/protocols/inline_editor_delegate.js +84 -0
  311. data/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +244 -0
  312. data/frameworks/sproutcore/frameworks/foundation/system/browser.js +64 -0
  313. data/frameworks/sproutcore/frameworks/foundation/system/builder.js +210 -0
  314. data/frameworks/sproutcore/frameworks/foundation/system/core_query.js +2015 -0
  315. data/frameworks/sproutcore/frameworks/foundation/system/cursor.js +129 -0
  316. data/frameworks/sproutcore/frameworks/foundation/system/error.js +93 -0
  317. data/frameworks/sproutcore/frameworks/foundation/system/event.js +817 -0
  318. data/frameworks/sproutcore/frameworks/foundation/system/image_cache.js +433 -0
  319. data/frameworks/sproutcore/frameworks/foundation/system/json.js +440 -0
  320. data/frameworks/sproutcore/frameworks/foundation/system/locale.js +288 -0
  321. data/frameworks/sproutcore/frameworks/foundation/system/page.js +106 -0
  322. data/frameworks/sproutcore/frameworks/foundation/system/ready.js +189 -0
  323. data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +865 -0
  324. data/frameworks/sproutcore/frameworks/foundation/system/request.js +255 -0
  325. data/frameworks/sproutcore/frameworks/foundation/system/root_responder.js +368 -0
  326. data/frameworks/sproutcore/frameworks/foundation/system/routes.js +446 -0
  327. data/frameworks/sproutcore/frameworks/foundation/system/time.js +478 -0
  328. data/frameworks/sproutcore/frameworks/foundation/system/timer.js +549 -0
  329. data/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +158 -0
  330. data/frameworks/sproutcore/frameworks/foundation/system/utils.js +330 -0
  331. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array.js +118 -0
  332. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/controller.js +268 -0
  333. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/object.js +433 -0
  334. data/frameworks/sproutcore/frameworks/foundation/tests/debug/control_test_pane/methods.js +10 -0
  335. data/frameworks/sproutcore/frameworks/foundation/tests/debug/control_test_pane/ui.js +113 -0
  336. data/frameworks/sproutcore/frameworks/foundation/tests/integration/creating_views.js +113 -0
  337. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/content.js +195 -0
  338. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/displayProperties.js +89 -0
  339. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/control/content.js +168 -0
  340. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/control/displayProperties.js +89 -0
  341. data/frameworks/sproutcore/frameworks/foundation/tests/system/builder.js +42 -0
  342. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_core.js +1323 -0
  343. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_dimensions.js +387 -0
  344. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +405 -0
  345. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/setClass.js +49 -0
  346. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/within.js +66 -0
  347. data/frameworks/sproutcore/frameworks/foundation/tests/system/error.js +41 -0
  348. data/frameworks/sproutcore/frameworks/foundation/tests/system/json.js +14 -0
  349. data/frameworks/sproutcore/frameworks/foundation/tests/system/locale.js +128 -0
  350. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/begin.js +47 -0
  351. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/element.js +44 -0
  352. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/end.js +119 -0
  353. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/get.js +51 -0
  354. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_attr.js +50 -0
  355. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_basic.js +28 -0
  356. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_className.js +179 -0
  357. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_style.js +100 -0
  358. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/init.js +55 -0
  359. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/join.js +28 -0
  360. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/push_text.js +74 -0
  361. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/tag.js +45 -0
  362. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/update.js +205 -0
  363. data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +89 -0
  364. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/makeKeyPane.js +124 -0
  365. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/makeMainPane.js +68 -0
  366. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/root_responder.js +97 -0
  367. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/targetForAction.js +238 -0
  368. data/frameworks/sproutcore/frameworks/foundation/tests/system/routes.js +33 -0
  369. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/invalidate.js +38 -0
  370. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/invokeLater.js +201 -0
  371. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/isPaused.js +71 -0
  372. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/performAction.js +67 -0
  373. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/schedule.js +170 -0
  374. data/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +27 -0
  375. data/frameworks/sproutcore/frameworks/foundation/tests/system/utils/normalizeURL.js +18 -0
  376. data/frameworks/sproutcore/frameworks/foundation/tests/system/utils/range.js +62 -0
  377. data/frameworks/sproutcore/frameworks/foundation/tests/validators/credit_card.js +35 -0
  378. data/frameworks/sproutcore/frameworks/foundation/tests/validators/date.js +21 -0
  379. data/frameworks/sproutcore/frameworks/foundation/tests/validators/number.js +47 -0
  380. data/frameworks/sproutcore/frameworks/foundation/tests/validators/password.js +13 -0
  381. data/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +10 -0
  382. data/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +83 -0
  383. data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +39 -0
  384. data/frameworks/sproutcore/frameworks/foundation/tests/views/main_pane.js +31 -0
  385. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/append_remove.js +89 -0
  386. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/firstResponder.js +148 -0
  387. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/keyPane.js +133 -0
  388. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/sendEvent.js +165 -0
  389. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/clippingFrame.js +132 -0
  390. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/convertFrames.js +246 -0
  391. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/createChildViews.js +87 -0
  392. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/createLayer.js +97 -0
  393. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/destroyLayer.js +85 -0
  394. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/findLayerInParentLayer.js +52 -0
  395. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/init.js +50 -0
  396. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/insertBefore.js +200 -0
  397. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisibleInWindow.js +102 -0
  398. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layer.js +150 -0
  399. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutChildViews.js +162 -0
  400. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutDidChange.js +127 -0
  401. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutStyle.js +248 -0
  402. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/parentViewDidChange.js +67 -0
  403. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/prepareContext.js +166 -0
  404. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/removeChild.js +189 -0
  405. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/render.js +83 -0
  406. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/replaceChild.js +29 -0
  407. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/updateLayer.js +142 -0
  408. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/updateLayerLocation.js +194 -0
  409. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/viewDidResize.js +185 -0
  410. data/frameworks/sproutcore/frameworks/foundation/validators/credit_card.js +125 -0
  411. data/frameworks/sproutcore/frameworks/foundation/validators/date.js +52 -0
  412. data/frameworks/sproutcore/frameworks/foundation/validators/email.js +45 -0
  413. data/frameworks/sproutcore/frameworks/foundation/validators/not_empty.js +33 -0
  414. data/frameworks/sproutcore/frameworks/foundation/validators/number.js +82 -0
  415. data/frameworks/sproutcore/frameworks/foundation/validators/password.js +86 -0
  416. data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +311 -0
  417. data/frameworks/sproutcore/frameworks/foundation/views/container.js +136 -0
  418. data/frameworks/sproutcore/frameworks/foundation/views/field.js +276 -0
  419. data/frameworks/sproutcore/frameworks/foundation/views/image.js +158 -0
  420. data/frameworks/sproutcore/frameworks/foundation/views/label.js +261 -0
  421. data/frameworks/sproutcore/frameworks/foundation/views/view.js +2160 -0
  422. data/frameworks/sproutcore/frameworks/mobile/english.lproj/core.css +12 -0
  423. data/frameworks/sproutcore/frameworks/mobile/lib/index.rhtml +126 -0
  424. data/frameworks/sproutcore/frameworks/mobile/system/root_responder.js +109 -0
  425. data/frameworks/sproutcore/frameworks/mobile/tests/views/button/ui.js +9 -0
  426. data/frameworks/sproutcore/frameworks/mobile/views/button.js +190 -0
  427. data/frameworks/sproutcore/frameworks/runtime/README +11 -0
  428. data/frameworks/sproutcore/frameworks/runtime/core.js +777 -0
  429. data/frameworks/sproutcore/frameworks/runtime/license.js +28 -0
  430. data/frameworks/sproutcore/frameworks/runtime/mixins/array.js +403 -0
  431. data/frameworks/sproutcore/frameworks/runtime/mixins/delegate_support.js +70 -0
  432. data/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1193 -0
  433. data/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1149 -0
  434. data/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +135 -0
  435. data/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +108 -0
  436. data/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +128 -0
  437. data/frameworks/sproutcore/frameworks/runtime/protocols/sparse_array_delegate.js +131 -0
  438. data/frameworks/sproutcore/frameworks/runtime/system/binding.js +891 -0
  439. data/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +107 -0
  440. data/frameworks/sproutcore/frameworks/runtime/system/object.js +783 -0
  441. data/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +99 -0
  442. data/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +214 -0
  443. data/frameworks/sproutcore/frameworks/runtime/system/set.js +246 -0
  444. data/frameworks/sproutcore/frameworks/runtime/system/sparse_array.js +286 -0
  445. data/frameworks/sproutcore/frameworks/runtime/tests/core/IsEqual.js +56 -0
  446. data/frameworks/sproutcore/frameworks/runtime/tests/core/beget.js +23 -0
  447. data/frameworks/sproutcore/frameworks/runtime/tests/core/clone.js +66 -0
  448. data/frameworks/sproutcore/frameworks/runtime/tests/core/guidFor.js +147 -0
  449. data/frameworks/sproutcore/frameworks/runtime/tests/core/inspect.js +27 -0
  450. data/frameworks/sproutcore/frameworks/runtime/tests/core/isArray.js +25 -0
  451. data/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +38 -0
  452. data/frameworks/sproutcore/frameworks/runtime/tests/core/keys.js +20 -0
  453. data/frameworks/sproutcore/frameworks/runtime/tests/core/makeArray.js +30 -0
  454. data/frameworks/sproutcore/frameworks/runtime/tests/core/objectForPropertyPath.js +19 -0
  455. data/frameworks/sproutcore/frameworks/runtime/tests/core/tupleForPropertyPath.js +37 -0
  456. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +592 -0
  457. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +467 -0
  458. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/propertyChanges.js +123 -0
  459. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/registerDependentKeys.js +79 -0
  460. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/propertyChanges.js +80 -0
  461. data/frameworks/sproutcore/frameworks/runtime/tests/system/array.js +263 -0
  462. data/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +190 -0
  463. data/frameworks/sproutcore/frameworks/runtime/tests/system/object/base.js +135 -0
  464. data/frameworks/sproutcore/frameworks/runtime/tests/system/object/bindings.js +339 -0
  465. data/frameworks/sproutcore/frameworks/runtime/tests/system/run_loop.js +120 -0
  466. data/frameworks/sproutcore/frameworks/runtime/tests/system/set.js +313 -0
  467. data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +84 -0
  468. data/frameworks/sproutcore/frameworks/testing/core.js +13 -0
  469. data/frameworks/sproutcore/frameworks/testing/english.lproj/additions.css +8 -0
  470. data/frameworks/sproutcore/frameworks/testing/english.lproj/testsuite.css +131 -0
  471. data/frameworks/sproutcore/frameworks/testing/extras.js +43 -0
  472. data/frameworks/sproutcore/frameworks/testing/jquery.js +3559 -0
  473. data/frameworks/sproutcore/frameworks/testing/qunit.js +819 -0
  474. data/frameworks/sproutcore/frameworks/testing/tests/debug/qunit.js +25 -0
  475. data/frameworks/sproutcore/frameworks/testing/utils.js +55 -0
  476. data/frameworks/sproutcore/lib/index.rhtml +118 -0
  477. data/frameworks/sproutcore/license.js +28 -0
  478. data/frameworks/sproutcore/themes/empty_theme/tests/mini_icons.rhtml +69 -0
  479. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/button.css +41 -0
  480. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/core.css +8 -0
  481. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/backButton.png +0 -0
  482. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/blueButton.png +0 -0
  483. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/cancel.png +0 -0
  484. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/grayButton.png +0 -0
  485. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/leftButton.png +0 -0
  486. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listArrow.png +0 -0
  487. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listArrowSel.png +0 -0
  488. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listGroup.png +0 -0
  489. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/loading.gif +0 -0
  490. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/pinstripes.png +0 -0
  491. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/rightButton.png +0 -0
  492. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/selection.png +0 -0
  493. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/thumb.png +0 -0
  494. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toggle.png +0 -0
  495. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toggleOn.png +0 -0
  496. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toolButton.png +0 -0
  497. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toolbar.png +0 -0
  498. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/whiteButton.png +0 -0
  499. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/strings.js +15 -0
  500. data/frameworks/sproutcore/themes/standard_theme/Source/Panel.drawit/Data +0 -0
  501. data/frameworks/sproutcore/themes/standard_theme/Source/Panel.drawit/QuickLook/Preview.jpg +0 -0
  502. data/frameworks/sproutcore/themes/standard_theme/Source/Panel.drawit/QuickLook/Thumbnail.jpg +0 -0
  503. data/frameworks/sproutcore/themes/standard_theme/Source/ToolbarView Pattern.drawit/Data +0 -0
  504. data/frameworks/sproutcore/themes/standard_theme/Source/ToolbarView Pattern.drawit/QuickLook/Preview.jpg +0 -0
  505. data/frameworks/sproutcore/themes/standard_theme/Source/ToolbarView Pattern.drawit/QuickLook/Thumbnail.jpg +0 -0
  506. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-x.drawit/Data +0 -0
  507. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-x.drawit/QuickLook/Preview.jpg +0 -0
  508. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-x.drawit/QuickLook/Thumbnail.jpg +0 -0
  509. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-y.drawit/Data +0 -0
  510. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-y.drawit/QuickLook/Preview.jpg +0 -0
  511. data/frameworks/sproutcore/themes/standard_theme/Source/panel-sprite-y.drawit/QuickLook/Thumbnail.jpg +0 -0
  512. data/frameworks/sproutcore/themes/standard_theme/english.lproj/button.css +333 -0
  513. data/frameworks/sproutcore/themes/standard_theme/english.lproj/checkbox.css +90 -0
  514. data/frameworks/sproutcore/themes/standard_theme/english.lproj/collection.css +53 -0
  515. data/frameworks/sproutcore/themes/standard_theme/english.lproj/core.css +47 -0
  516. data/frameworks/sproutcore/themes/standard_theme/english.lproj/disclosure.css +55 -0
  517. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-sprite.png +0 -0
  518. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-ysprite.png +0 -0
  519. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-toolbar-view.png +0 -0
  520. data/frameworks/sproutcore/themes/standard_theme/english.lproj/label.css +37 -0
  521. data/frameworks/sproutcore/themes/standard_theme/english.lproj/pane.css +8 -0
  522. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-fat.jpg +0 -0
  523. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-thin.jpg +0 -0
  524. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-edge.png +0 -0
  525. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-left-corner.png +0 -0
  526. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-right-corner.png +0 -0
  527. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/left-edge.png +0 -0
  528. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/overlay.png +0 -0
  529. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/right-edge.png +0 -0
  530. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-edge.png +0 -0
  531. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-left-corner.png +0 -0
  532. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-right-corner.png +0 -0
  533. data/frameworks/sproutcore/themes/standard_theme/english.lproj/progress.css +23 -0
  534. data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +113 -0
  535. data/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +141 -0
  536. data/frameworks/sproutcore/themes/standard_theme/english.lproj/slider.css +62 -0
  537. data/frameworks/sproutcore/themes/standard_theme/english.lproj/split_view.css +27 -0
  538. data/frameworks/sproutcore/themes/standard_theme/english.lproj/tab.css +12 -0
  539. data/frameworks/sproutcore/themes/standard_theme/english.lproj/text_field.css +13 -0
  540. data/frameworks/sproutcore/themes/standard_theme/english.lproj/toolbar.css +4 -0
  541. data/lib/thor/.autotest +7 -0
  542. data/lib/thor/CHANGELOG.rdoc +52 -0
  543. data/lib/thor/LICENSE +20 -0
  544. data/lib/thor/README.markdown +76 -0
  545. data/lib/thor/Rakefile +6 -0
  546. data/lib/thor/Thorfile +45 -0
  547. data/lib/thor/bin/rake2thor +83 -0
  548. data/lib/thor/bin/thor +7 -0
  549. data/lib/thor/lib/thor/error.rb +3 -0
  550. data/lib/thor/lib/thor/options.rb +267 -0
  551. data/lib/thor/lib/thor/ordered_hash.rb +64 -0
  552. data/lib/thor/lib/thor/runner.rb +305 -0
  553. data/lib/thor/lib/thor/task.rb +83 -0
  554. data/lib/thor/lib/thor/task_hash.rb +22 -0
  555. data/lib/thor/lib/thor/tasks/package.rb +18 -0
  556. data/lib/thor/lib/thor/tasks.rb +77 -0
  557. data/lib/thor/lib/thor/util.rb +75 -0
  558. data/lib/thor/lib/thor.rb +170 -0
  559. data/lib/thor/script/destroy +14 -0
  560. data/lib/thor/script/generate +14 -0
  561. data/lib/thor/spec/fixtures/task.thor +10 -0
  562. data/lib/thor/spec/options_spec.rb +271 -0
  563. data/lib/thor/spec/ordered_hash_spec.rb +84 -0
  564. data/lib/thor/spec/spec.opts +1 -0
  565. data/lib/thor/spec/spec_helper.rb +30 -0
  566. data/lib/thor/spec/task_spec.rb +11 -0
  567. data/lib/thor/spec/tasks_spec.rb +28 -0
  568. data/lib/thor/spec/thor_runner_spec.rb +194 -0
  569. data/lib/thor/spec/thor_spec.rb +206 -0
  570. data/lib/thor/spec/util_spec.rb +99 -0
  571. data/lib/thor/task.thor +15 -0
  572. data/lib/thor/thor.gemspec +29 -0
  573. metadata +3 -4
  574. data/sproutcore.gemspec +0 -47
@@ -0,0 +1,2160 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
4
+ // Portions ©2008-2009 Apple, Inc. All rights reserved.
5
+ // License: Licened under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+ require('system/browser');
9
+ require('system/event');
10
+ require('system/cursor');
11
+
12
+ require('mixins/responder') ;
13
+ require('mixins/string') ;
14
+
15
+ SC.viewKey = SC.guidKey + "_view" ;
16
+
17
+ /** Select a horizontal layout for various views.*/
18
+ SC.LAYOUT_HORIZONTAL = 'sc-layout-horizontal';
19
+
20
+ /** Select a vertical layout for various views.*/
21
+ SC.LAYOUT_VERTICAL = 'sc-layout-vertical';
22
+
23
+ /** @private */
24
+ SC._VIEW_DEFAULT_DIMS = 'marginTop marginLeft'.w();
25
+
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
+ /**
57
+ Layout properties to take up the full width of a parent view.
58
+ */
59
+ SC.FULL_WIDTH = { left: 0, right: 0 };
60
+
61
+ /**
62
+ Layout properties to take up the full height of a parent view.
63
+ */
64
+ SC.FULL_HEIGHT = { top: 0, bottom: 0 };
65
+
66
+ /**
67
+ Layout properties to center. Note that you must also specify a width and
68
+ height for this to work.
69
+ */
70
+ SC.ANCHOR_CENTER = { centerX: 0, centerY: 0 };
71
+
72
+ /** @private - custom array used for child views */
73
+ SC.EMPTY_CHILD_VIEWS_ARRAY = [];
74
+ SC.EMPTY_CHILD_VIEWS_ARRAY.needsClone = YES;
75
+
76
+ /**
77
+ @class
78
+
79
+ Base class for managing a view. View's provide two functions:
80
+
81
+ 1. They translate state and events into drawing instructions for the
82
+ web browser and
83
+
84
+ 2. They act as first responders for incoming keyboard, mouse, and
85
+ touch events.
86
+
87
+ h2. View Initialization
88
+
89
+ When a view is setup, there are several methods you can override that
90
+ will be called at different times depending on how your view is created.
91
+ Here is a guide to which method you want to override and when:
92
+
93
+ - *init:* override this method for any general object setup (such as
94
+ observers, starting timers and animations, etc) that you need to happen
95
+ everytime the view is created, regardless of whether or not its layer
96
+ exists yet.
97
+
98
+ - *render:* override this method to generate or update your HTML to reflect
99
+ the current state of your view. This method is called both when your view
100
+ is first created and later anytime it needs to be updated.
101
+
102
+ - *didCreateLayer:* the render() method is used to generate new HTML.
103
+ Override this method to perform any additional setup on the DOM you might
104
+ need to do after creating the view. For example, if you need to listen
105
+ for events.
106
+
107
+ - *willDestroyLayer:* if you implement didCreateLayer() to setup event
108
+ listeners, you should implement this method as well to remove the same
109
+ just before the DOM for your view is destroyed.
110
+
111
+ - *updateLayer:* Normally, when a view needs to update its content, it will
112
+ re-render the view using the render() method. If you would like to
113
+ override this behavior with your own custom updating code, you can
114
+ replace updateLayer() with your own implementation instead.
115
+
116
+ @extends SC.Object
117
+ @extends SC.Responder
118
+ @extends SC.DelegateSupport
119
+ @since SproutCore 1.0
120
+ */
121
+ SC.View = SC.Object.extend(SC.Responder, SC.DelegateSupport,
122
+ /** @scope SC.View.prototype */ {
123
+
124
+ concatenatedProperties: 'outlets displayProperties layoutProperties classNames renderMixin didCreateLayerMixin willDestroyLayerMixin'.w(),
125
+
126
+ /**
127
+ The current pane.
128
+ @property {SC.Pane}
129
+ */
130
+ pane: function() {
131
+ var view = this ;
132
+ while (view && !view.isPane) view = view.get('parentView') ;
133
+ return view ;
134
+ }.property('parentView').cacheable(),
135
+
136
+ /**
137
+ The page this view was instantiated from. This is set by the page object
138
+ during instantiation.
139
+
140
+ @property {SC.Page}
141
+ */
142
+ page: null,
143
+
144
+ /**
145
+ The current split view this view is embedded in (may be null).
146
+ @property {SC.SplitView}
147
+ */
148
+ splitView: function() {
149
+ var view = this ;
150
+ while (view && !view.isSplitView) view = view.get('parentView') ;
151
+ return view ;
152
+ }.property('parentView').cacheable(),
153
+
154
+ /**
155
+ If the view is currently inserted into the DOM of a parent view, this
156
+ property will point to the parent of the view.
157
+ */
158
+ parentView: null,
159
+
160
+ /**
161
+ Optional background color. Will be applied to the view's element if
162
+ set. This property is intended for one-off views that need a background
163
+ element. If you plan to create many view instances it is probably better
164
+ to use CSS.
165
+
166
+ @property {String}
167
+ */
168
+ backgroundColor: null,
169
+
170
+ // ..........................................................
171
+ // IS ENABLED SUPPORT
172
+ //
173
+
174
+ /**
175
+ Set to true when the item is enabled. Note that changing this value
176
+ will also alter the isVisibleInWindow property for this view and any
177
+ child views.
178
+
179
+ Note that if you apply the SC.Control mixin, changing this property will
180
+ also automatically add or remove a 'disabled' CSS class name as well.
181
+
182
+ This property is observable and bindable.
183
+
184
+ @property {Boolean}
185
+ */
186
+ isEnabled: YES,
187
+ isEnabledBindingDefault: SC.Binding.oneWay().bool(),
188
+
189
+ /**
190
+ Computed property returns YES if the view and all of its parent views
191
+ are enabled in the pane. You should use this property when deciding
192
+ whether to respond to an incoming event or not.
193
+
194
+ This property is not observable.
195
+
196
+ @property {Boolean}
197
+ */
198
+ isEnabledInPane: function() {
199
+ var ret = this.get('isEnabled'), pv ;
200
+ if (ret && (pv = this.get('parentView'))) ret = pv.get('isEnabledInPane');
201
+ return ret ;
202
+ }.property('parentView', 'isEnabled'),
203
+
204
+ // ..........................................................
205
+ // IS VISIBLE IN WINDOW SUPPORT
206
+ //
207
+
208
+ /**
209
+ The isVisible property determines if the view is shown in the view
210
+ hierarchy it is a part of. A view can have isVisible == YES and still have
211
+ isVisibleInWindow == NO. This occurs, for instance, when a parent view has
212
+ isVisible == NO. Default is YES.
213
+
214
+ The isVisible property is considered part of the layout and so changing it
215
+ will trigger a layout update.
216
+
217
+ @property {Boolean}
218
+ */
219
+ isVisible: YES,
220
+
221
+ /**
222
+ YES only if the view and all of its parent views are currently visible
223
+ in the window. This property is used to optimize certain behaviors in
224
+ the view. For example, updates to the view layer are not performed
225
+ if the view until the view becomes visible in the window.
226
+ */
227
+ isVisibleInWindow: NO,
228
+
229
+ /**
230
+ Recomputes the isVisibleInWindow property based on the visibility of the
231
+ view and its parent. If the recomputed value differs from the current
232
+ isVisibleInWindow state, this method will also call
233
+ recomputIsVisibleInWindow() on its child views as well. As an optional
234
+ optimization, you can pass the isVisibleInWindow state of the parentView
235
+ if you already know it.
236
+
237
+ You will not generally need to call or override this method yourself. It
238
+ is used by the SC.View hierarchy to relay window visibility changes up
239
+ and down the chain.
240
+
241
+ @property {Boolean} parentViewIsVisible
242
+ @returns {SC.View} receiver
243
+ */
244
+ recomputeIsVisibleInWindow: function(parentViewIsVisible) {
245
+ var last = this.get('isVisibleInWindow') ;
246
+ var cur = this.get('isVisible'), parentView ;
247
+
248
+ // isVisibleInWindow = isVisible && parentView.isVisibleInWindow
249
+ // this approach only goes up to the parentView if necessary.
250
+ if (cur) {
251
+ cur = (parentViewIsVisible === undefined) ?
252
+ ((parentView=this.get('parentView')) ?
253
+ parentView.get('isVisibleInWindow') : NO) : parentViewIsVisible ;
254
+ }
255
+
256
+ // if the state has changed, update it and notify children
257
+ if (last !== cur) {
258
+ this.set('isVisibleInWindow', cur) ;
259
+
260
+ var childViews = this.get('childViews'), len = childViews.length, idx;
261
+ for(idx=0;idx<len;idx++) {
262
+ childViews[idx].recomputeIsVisibleInWindow(cur);
263
+ }
264
+
265
+ // if we just became visible, update layer + layout if needed...
266
+ if (cur && this.parentViewDidResize) this.parentViewDidResize();
267
+
268
+ // if we were firstResponder, resign firstResponder also if no longer
269
+ // visible.
270
+ if (!cur && this.get('isFirstResponder')) this.resignFirstResponder();
271
+
272
+ }
273
+
274
+ return this ;
275
+ },
276
+
277
+ // ..........................................................
278
+ // CHILD VIEW SUPPORT
279
+ //
280
+
281
+ /**
282
+ Array of child views. You should never edit this array directly unless
283
+ you are implementing createChildViews(). Most of the time, you should
284
+ use the accessor methods such as appendChild(), insertBefore() and
285
+ removeChild().
286
+
287
+ @property {Array}
288
+ */
289
+ childViews: SC.EMPTY_CHILD_VIEWS_ARRAY,
290
+
291
+ /**
292
+ Insert the view into the the receiver's childNodes array.
293
+
294
+ The view will be added to the childNodes array before the beforeView. If
295
+ beforeView is null, then the view will be added to the end of the array.
296
+ This will also add the view's rootElement DOM node to the receivers
297
+ containerElement DOM node as a child.
298
+
299
+ If the specified view already belongs to another parent, it will be
300
+ removed from that view first.
301
+
302
+ @param {SC.View} view
303
+ @param {SC.View} beforeView
304
+ @returns {SC.View} the receiver
305
+ */
306
+ insertBefore: function(view, beforeView) {
307
+
308
+ view.beginPropertyChanges(); // limit notifications
309
+
310
+ // remove view from old parent if needed. Also notify views.
311
+ if (view.get('parentView')) view.removeFromParent() ;
312
+ if (this.willAddChild) this.willAddChild(view, beforeView) ;
313
+ if (view.willAddToParent) view.willAddToParent(this, beforeView) ;
314
+
315
+ // set parentView of child
316
+ view.set('parentView', this);
317
+
318
+ // add to childView's array.
319
+ var idx, childViews = this.get('childViews') ;
320
+ if (childViews.needsClone) this.set(childViews = []);
321
+ idx = (beforeView) ? childViews.indexOf(beforeView) : childViews.length;
322
+ if (idx<0) idx = childViews.length ;
323
+ childViews.insertAt(idx, view) ;
324
+
325
+ // The DOM will need some fixing up, note this on the view.
326
+ view.parentViewDidChange() ;
327
+ view.layoutDidChange() ;
328
+
329
+ // notify views
330
+ if (this.didAddChild) this.didAddChild(view, beforeView) ;
331
+ if (view.didAddToParent) view.didAddToParent(this, beforeView) ;
332
+
333
+ view.endPropertyChanges();
334
+
335
+ return this ;
336
+ },
337
+
338
+ /**
339
+ Removes the child view from the parent view.
340
+
341
+ @param {SC.View} view
342
+ @returns {SC.View} receiver
343
+ */
344
+ removeChild: function(view) {
345
+ if (!view) return this; // nothing to do
346
+ if (view.parentView !== this) {
347
+ throw "%@.removeChild(%@) must belong to parent".fmt(this,view);
348
+ }
349
+
350
+ // notify views
351
+ if (view.willRemoveFromParent) view.willRemoveFromParent() ;
352
+ if (this.willRemoveChild) this.willRemoveChild(view) ;
353
+
354
+ // update parent node
355
+ view.set('parentView', null) ;
356
+
357
+ // remove view from childViews array.
358
+ var childViews = this.get('childViews') ;
359
+ var idx = childViews.indexOf(view) ;
360
+ if (idx>=0) childViews.removeAt(idx);
361
+
362
+ // The DOM will need some fixing up, note this on the view.
363
+ view.parentViewDidChange() ;
364
+
365
+ // notify views
366
+ if (this.didRemoveChild) this.didRemoveChild(view);
367
+ if (view.didRemoveFromParent) view.didRemoveFromParent(this) ;
368
+
369
+ return this ;
370
+ },
371
+
372
+ /**
373
+ Removes all children from the parentView.
374
+
375
+ @returns {SC.View} receiver
376
+ */
377
+ removeAllChildren: function() {
378
+ var childViews = this.get('childViews'), view ;
379
+ while (view = childViews.objectAt(childViews.get('length')-1)) {
380
+ this.removeChild(view) ;
381
+ }
382
+ return this ;
383
+ },
384
+
385
+ /**
386
+ Removes the view from its parentView, if one is found. Otherwise
387
+ does nothing.
388
+
389
+ @returns {SC.View} receiver
390
+ */
391
+ removeFromParent: function() {
392
+ var parent = this.get('parentView') ;
393
+ if (parent) parent.removeChild(this) ;
394
+ return this ;
395
+ },
396
+
397
+ /**
398
+ Replace the oldView with the specified view in the receivers childNodes
399
+ array. This will also replace the DOM node of the oldView with the DOM
400
+ node of the new view in the receivers DOM.
401
+
402
+ If the specified view already belongs to another parent, it will be
403
+ removed from that view first.
404
+
405
+ @param view {SC.View} the view to insert in the DOM
406
+ @param view {SC.View} the view to remove from the DOM.
407
+ @returns {SC.View} the receiver
408
+ */
409
+ replaceChild: function(view, oldView) {
410
+
411
+ // suspend notifications
412
+ view.beginPropertyChanges();
413
+ oldView.beginPropertyChanges();
414
+ this.beginPropertyChanges();
415
+
416
+ this.insertBefore(view,oldView).removeChild(oldView) ;
417
+
418
+ // resume notifications
419
+ this.endPropertyChanges();
420
+ oldView.endPropertyChanges();
421
+ view.endPropertyChanges();
422
+
423
+ return this;
424
+ },
425
+
426
+ /**
427
+ Appends the specified view to the end of the receivers childViews array.
428
+ This is equivalent to calling insertBefore(view, null);
429
+
430
+ @param view {SC.View} the view to insert
431
+ @returns {SC.View} the receiver
432
+ */
433
+ appendChild: function(view) {
434
+ return this.insertBefore(view, null);
435
+ },
436
+
437
+ /**
438
+ This method is called whenever the receiver's parentView has changed.
439
+ The default implementation of this method marks the view's display
440
+ location as dirty so that it will update at the end of the run loop.
441
+
442
+ You will not usually need to override or call this method yourself, though
443
+ if you manually patch the parentView hierarchy for some reason, you should
444
+ call this method to notify the view that it's parentView has changed.
445
+
446
+ @returns {SC.View} receiver
447
+ */
448
+ parentViewDidChange: function() {
449
+ this.recomputeIsVisibleInWindow() ;
450
+
451
+ this.set('layerLocationNeedsUpdate', YES) ;
452
+ this.invokeOnce(this.updateLayerLocationIfNeeded) ;
453
+
454
+ return this ;
455
+ }.observes('isVisible'),
456
+
457
+ // ..........................................................
458
+ // LAYER SUPPORT
459
+ //
460
+
461
+ /**
462
+ Returns the current layer for the view. The layer for a view is only
463
+ generated when the view first becomes visible in the window and even
464
+ then it will not be computed until you request this layer property.
465
+
466
+ If the layer is not actually set on the view itself, then the layer will
467
+ be found by calling this.findLayerInParentLayer().
468
+
469
+ You can also set the layer by calling set on this property.
470
+
471
+ @property {DOMElement} the layer
472
+ */
473
+ layer: function(key, value) {
474
+ if (value !== undefined) {
475
+ this._view_layer = value ;
476
+
477
+ // no layer...attempt to discover it...
478
+ } else {
479
+ value = this._view_layer;
480
+ if (!value) {
481
+ var parent = this.get('parentView');
482
+ if (parent) parent = parent.get('layer');
483
+ if (parent) {
484
+ this._view_layer = value = this.findLayerInParentLayer(parent);
485
+ }
486
+ parent = null ; // avoid memory leak
487
+ }
488
+ }
489
+ return value ;
490
+ }.property('isVisibleInWindow').cacheable(),
491
+
492
+ /**
493
+ Get a CoreQuery object for this view's layer, or pass in a selector string
494
+ to get a CoreQuery object for a DOM node nested within this layer.
495
+
496
+ @param {String} sel a CoreQuery-compatible selector string
497
+ @returns {SC.CoreQuery} the CoreQuery object for the DOM node
498
+ */
499
+ $: function(sel) {
500
+ var ret, layer = this.get('layer') ;
501
+ // note: SC.$([]) returns an empty CoreQuery object. SC.$() would
502
+ // return an object selecting hte document.
503
+ ret = !layer ? SC.$([]) : (sel === undefined) ? SC.$(layer) : SC.$(sel, layer) ;
504
+ layer = null ; // avoid memory leak
505
+ return ret ;
506
+ },
507
+
508
+ /**
509
+ Returns the DOM element that should be used to hold child views when they
510
+ are added/remove via DOM manipulation. The default implementation simply
511
+ returns the layer itself. You can override this to return a DOM element
512
+ within the layer.
513
+
514
+ @property {DOMElement} the container layer
515
+ */
516
+ containerLayer: function() {
517
+ return this.get('layer') ;
518
+ }.property('layer').cacheable(),
519
+
520
+ /**
521
+ The ID to use when trying to locate the layer in the DOM. If you do not
522
+ set the layerId explicitly, then the view's GUID will be used instead.
523
+ This ID must be set at the time the view is created.
524
+
525
+ @property {String}
526
+ @readOnly
527
+ */
528
+ layerId: function() {
529
+ return SC.guidFor(this) ;
530
+ }.property().cacheable(),
531
+
532
+ /**
533
+ Attempts to discover the layer in the parent layer. The default
534
+ implementation looks for an element with an ID of layerId (or the view's
535
+ guid if layerId is null). You can override this method to provide your
536
+ own form of lookup. For example, if you want to discover your layer using
537
+ a CSS class name instead of an ID.
538
+
539
+ @param {DOMElement} parentLayer the parent's DOM layer
540
+ @returns {DOMElement} the discovered layer
541
+ */
542
+ findLayerInParentLayer: function(parentLayer) {
543
+ var layerId = this.get('layerId') ;
544
+
545
+ // first, let's try the fast path...
546
+ var elem = document.getElementById(layerId) ;
547
+
548
+ // TODO: use code generation to only really do this check on IE
549
+ if (SC.browser.msie && elem && elem.id !== layerId) elem = null ;
550
+
551
+ // if browser supports querySelector use that.
552
+ if (!elem && parentLayer.querySelector) {
553
+ // TODO: make querySelector work on all platforms...
554
+ // elem = parentLayer.querySelector('#' + layerId)[0];
555
+ }
556
+
557
+ // if no element was found the fast way, search down the parentLayer for
558
+ // the element. This code should not be invoked very often. Usually a
559
+ // DOM element will be discovered by the first method above.
560
+ if (!elem) {
561
+ elem = parentLayer.firstChild ;
562
+ while (elem && (elem.id !== layerId)) {
563
+ // try to get first child or next sibling if no children
564
+ var next = elem.firstChild || elem.nextSibling ;
565
+
566
+ // if no next sibling, then get next sibling of parent. Walk up
567
+ // until we find parent with next sibling or find ourselves back at
568
+ // the beginning.
569
+ while (!next && elem && ((elem = elem.parentNode) !== parentLayer)) {
570
+ next = elem.nextSibling ;
571
+ }
572
+
573
+ elem = next ;
574
+ }
575
+ }
576
+
577
+ return elem;
578
+ },
579
+
580
+ /**
581
+ This method is invoked whenever a display property changes. It will set
582
+ the layerNeedsUpdate method to YES.
583
+ */
584
+ displayDidChange: function() {
585
+ this.set('layerNeedsUpdate', YES) ;
586
+ },
587
+
588
+ /**
589
+ Setting this property to YES will cause the updateLayerIfNeeded method to
590
+ be invoked at the end of the runloop. You can also force a view to update
591
+ sooner by calling updateLayerIfNeeded() directly. The method will update
592
+ the layer only if this property is YES.
593
+
594
+ @property {Boolean}
595
+ @test in updateLayer
596
+ */
597
+ layerNeedsUpdate: NO,
598
+
599
+ /** @private
600
+ Schedules the updateLayerIfNeeded method to run at the end of the runloop
601
+ if layerNeedsUpdate is set to YES.
602
+ */
603
+ _view_layerNeedsUpdateDidChange: function() {
604
+ if (this.get('layerNeedsUpdate')) {
605
+ this.invokeOnce(this.updateLayerIfNeeded) ;
606
+ }
607
+ }.observes('layerNeedsUpdate'),
608
+
609
+ /**
610
+ Updates the layer only if the view is visible onscreen and if
611
+ layerNeedsUpdate is set to YES. Normally you will not invoke this method
612
+ directly. Instead you set the layerNeedsUpdate property to YES and this
613
+ method will be called once at the end of the runloop.
614
+
615
+ If you need to update view's layer sooner than the end of the runloop, you
616
+ can call this method directly. If your view is not visible in the window
617
+ but you want it to update anyway, then call this method, passing YES for
618
+ the 'force' parameter.
619
+
620
+ You should not override this method. Instead override updateLayer() or
621
+ render().
622
+
623
+ @param {Boolean} isVisible if true assume view is visible even if it is not.
624
+ @returns {SC.View} receiver
625
+ @test in updateLayer
626
+ */
627
+ updateLayerIfNeeded: function(isVisible) {
628
+ if (!isVisible) isVisible = this.get('isVisibleInWindow') ;
629
+ if (isVisible && this.get('layerNeedsUpdate')) {
630
+ this.beginPropertyChanges() ;
631
+ this.set('layerNeedsUpdate', NO) ;
632
+ this.updateLayer() ;
633
+ this.endPropertyChanges() ;
634
+ }
635
+ return this ;
636
+ },
637
+
638
+ /**
639
+ This is the core method invoked to update a view layer whenever it has
640
+ changed. This method simply creates a render context focused on the
641
+ layer element and then calls your render() method.
642
+
643
+ You will not usually call or override this method directly. Instead you
644
+ should set the layerNeedsUpdate property to YES to cause this method to
645
+ run at the end of the run loop, or you can call updateLayerIfNeeded()
646
+ to force the layer to update immediately.
647
+
648
+ Instead of overriding this method, consider overidding the render() method
649
+ instead, which is called both when creating and updating a layer. If you
650
+ do not want your render() method called when updating a layer, then you
651
+ should override this method instead.
652
+
653
+ @returns {SC.View} receiver
654
+ */
655
+ updateLayer: function() {
656
+ var context = this.renderContext(this.get('layer')) ;
657
+ this.prepareContext(context, NO) ;
658
+ context.update() ;
659
+ return this ;
660
+ },
661
+
662
+ /**
663
+ Creates a new renderContext with the passed tagName or element. You
664
+ can override this method to provide further customization to the context
665
+ if needed. Normally you will not need to call or override this method.
666
+
667
+ @returns {SC.RenderContext}
668
+ */
669
+ renderContext: function(tagNameOrElement) {
670
+ return SC.RenderContext(tagNameOrElement) ;
671
+ },
672
+
673
+ /**
674
+ Creates the layer by creating a renderContext and invoking the view's
675
+ render() method. This will only create the layer if the layer does not
676
+ already exist.
677
+
678
+ When you create a layer, it is expected that your render() method will
679
+ also render the HTML for all child views as well. This method will
680
+ notify the view along with any of its childViews that its layer has been
681
+ created.
682
+
683
+ @returns {SC.View} receiver
684
+ */
685
+ createLayer: function() {
686
+ if (this.get('layer')) return this ; // nothing to do
687
+
688
+ var context = this.renderContext(this.get('tagName')) ;
689
+
690
+ // now prepare the contet like normal.
691
+ this.prepareContext(context, YES) ;
692
+ this.set('layer', context.element()) ;
693
+
694
+ // now notify the view and its child views..
695
+ this._notifyDidCreateLayer() ;
696
+
697
+ return this ;
698
+ },
699
+
700
+ /** @private -
701
+ Invokes the receivers didCreateLayer() method if it exists and then
702
+ invokes the same on all child views.
703
+ */
704
+ _notifyDidCreateLayer: function() {
705
+ if (this.didCreateLayer) this.didCreateLayer() ;
706
+ var mixins = this.didCreateLayerMixin, len, idx ;
707
+ if (mixins) {
708
+ len = mixins.length ;
709
+ for (idx=0; idx<len; ++idx) mixins[idx].call(this) ;
710
+ }
711
+
712
+ var childViews = this.get('childViews') ;
713
+ len = childViews.length ;
714
+ for (idx=0; idx<len; ++idx) childViews[idx]._notifyDidCreateLayer() ;
715
+ },
716
+
717
+ /**
718
+ Destroys any existing layer along with the layer for any child views as
719
+ well. If the view does not currently have a layer, then this method will
720
+ do nothing.
721
+
722
+ If you implement willDestroyLayer() on your view or if any mixins
723
+ implement willDestroLayerMixin(), then this method will be invoked on your
724
+ view before your layer is destroyed to give you a chance to clean up any
725
+ event handlers, etc.
726
+
727
+ If you write a willDestroyLayer() handler, you can assume that your
728
+ didCreateLayer() handler was called earlier for the same layer.
729
+
730
+ Normally you will not call or override this method yourself, but you may
731
+ want to implement the above callbacks when it is run.
732
+
733
+ @returns {SC.View} receiver
734
+ */
735
+ destroyLayer: function() {
736
+ var layer = this.get('layer') ;
737
+ if (layer) {
738
+ // Now notify the view and its child views. It will also set the
739
+ // layer property to null.
740
+ this._notifyWillDestroyLayer() ;
741
+
742
+ // do final cleanup
743
+ if (layer.parentNode) layer.parentNode.removeChild(layer) ;
744
+ layer = null ;
745
+ }
746
+ return this ;
747
+ },
748
+
749
+ /** @private -
750
+ Invokes willDestroyLayer() on view and child views. Then sets layer to
751
+ null for receiver.
752
+ */
753
+ _notifyWillDestroyLayer: function() {
754
+ if (this.willDestroyLayer) this.willDestroyLayer() ;
755
+ var mixins = this.willDestroyLayerMixin, len, idx ;
756
+ if (mixins) {
757
+ len = mixins.length ;
758
+ for (idx=0; idx<len; ++idx) mixins[idx].call(this) ;
759
+ }
760
+
761
+ var childViews = this.get('childViews') ;
762
+ len = childViews.length ;
763
+ for (idx=0; idx<len; ++idx) childViews[idx]._notifyWillDestroyLayer() ;
764
+
765
+ this.set('layer', null) ;
766
+ },
767
+
768
+ /**
769
+ Invoked by createLayer() and updateLayer() to actually render a context.
770
+ This method calls the render() method on your view along with any
771
+ renderMixin() methods supplied by mixins you might have added.
772
+
773
+ You should not override this method directly. However, you might call
774
+ this method if you choose to override updateLayer() or createLayer().
775
+
776
+ @param {SC.RenderContext} context the render context
777
+ @param {Boolean} firstTime YES if this is creating a layer
778
+ @returns {void}
779
+ */
780
+ prepareContext: function(context, firstTime) {
781
+ var mixins, len, idx, layerId, bgcolor, cursor ;
782
+
783
+ // do some initial setup only needed at create time.
784
+ if (firstTime) {
785
+ // TODO: seems like things will break later if SC.guidFor(this) is used
786
+ layerId = this.layerId ? this.get('layerId') : SC.guidFor(this) ;
787
+ context.id(layerId).classNames(this.get('classNames'), YES) ;
788
+ this.renderLayout(context, firstTime) ;
789
+ }
790
+
791
+ // do some standard setup...
792
+ if (this.get('isTextSelectable')) context.addClass('allow-select') ;
793
+ if (!this.get('isEnabled')) context.addClass('disabled') ;
794
+ if (!this.get('isVisible')) context.addClass('hidden') ;
795
+
796
+ bgcolor = this.get('backgroundColor');
797
+ if (bgcolor) context.addStyle('backgroundColor', bgcolor);
798
+
799
+ cursor = this.get('cursor') ;
800
+ if (cursor) context.addClass(cursor.get('className')) ;
801
+
802
+ this.render(context, firstTime) ;
803
+ if (mixins = this.renderMixin) {
804
+ len = mixins.length;
805
+ for(idx=0; idx<len; ++idx) mixins[idx].call(this, context, firstTime) ;
806
+ }
807
+ },
808
+
809
+ /**
810
+ Your render method should invoke this method to render any child views,
811
+ especially if this is the first time the view will be rendered. This will
812
+ walk down the childView chain, rendering all of the children in a nested
813
+ way.
814
+
815
+ @param {SC.RenderContext} context the context
816
+ @param {Boolean} firstName true if the layer is being created
817
+ @returns {SC.RenderContext} the render context
818
+ @test in render
819
+ */
820
+ renderChildViews: function(context, firstTime) {
821
+ var cv = this.get('childViews'), len = cv.length, idx, view ;
822
+ for (idx=0; idx<len; ++idx) {
823
+ view = cv[idx] ;
824
+ context = context.begin(view.get('tagName')) ;
825
+ view.prepareContext(context, firstTime) ;
826
+ context = context.end() ;
827
+ }
828
+ return context ;
829
+ },
830
+
831
+ /**
832
+ Invoked whenever your view needs to be rendered, including when the view's
833
+ layer is first created and any time in the future when it needs to be
834
+ updated.
835
+
836
+ You will normally override this method in your subclassed views to
837
+ provide whatever drawing functionality you will need in order to
838
+ render your content.
839
+
840
+ You can use the passed firstTime property to determine whether or not
841
+ you need to completely re-render the view or only update the surrounding
842
+ HTML.
843
+
844
+ The default implementation of this method simply calls renderChildViews()
845
+ if this is the first time you are rendering, or null otherwise.
846
+
847
+ @param {SC.RenderContext} context the render context
848
+ @param {Boolean} firstTime YES if this is creating a layer
849
+ @returns {void}
850
+ */
851
+ render: function(context, firstTime) {
852
+ if (firstTime) this.renderChildViews(context, firstTime) ;
853
+ },
854
+
855
+ // ..........................................................
856
+ // STANDARD RENDER PROPERTIES
857
+ //
858
+
859
+ /**
860
+ Tag name for the view's outer element. The tag name is only used when
861
+ a layer is first created. If you change the tagName for an element, you
862
+ must destroy and recreate the view layer.
863
+
864
+ @property {String}
865
+ */
866
+ tagName: 'div',
867
+
868
+ /**
869
+ Standard CSS class names to apply to the view's outer element. This
870
+ property automatically inherits any class names defined by the view's
871
+ superclasses as well.
872
+
873
+ @property {Array}
874
+ */
875
+ classNames: ['sc-view'],
876
+
877
+ /**
878
+ Determines if the user can select text within the view. Normally this is
879
+ set to NO to disable text selection. You should set this to YES if you
880
+ are creating a view that includes editable text. Otherwise, settings this
881
+ to YES will probably make your controls harder to use and it is not
882
+ recommended.
883
+
884
+ @property {Boolean}
885
+ @readOnly
886
+ */
887
+ isTextSelectable: NO,
888
+
889
+ /**
890
+ You can set this array to include any properties that should immediately
891
+ invalidate the display. The display will be automatically invalidated
892
+ when one of these properties change.
893
+
894
+ @property {Array}
895
+ @readOnly
896
+ */
897
+ displayProperties: [],
898
+
899
+ /**
900
+ You can set this to an SC.Cursor instance; it's className will
901
+ automatically be added to the layer's classNames. The cursor is only used
902
+ when a layer is first created. If you change the cursor for an element,
903
+ you must destroy and recreate the view layer.
904
+
905
+ @property {SC.Cursor}
906
+ */
907
+ cursor: null,
908
+
909
+ // ..........................................................
910
+ // LAYER LOCATION
911
+ //
912
+
913
+ /**
914
+ Set to YES when the view's layer location is dirty. You can call
915
+ updateLayerLocationIfNeeded() to clear this flag if it is set.
916
+
917
+ @property {Boolean}
918
+ */
919
+ layerLocationNeedsUpdate: NO,
920
+
921
+ /**
922
+ Calls updateLayerLocation(), but only if the view's layer location
923
+ currently needs to be updated. This method is called automatically at
924
+ the end of a run loop if you have called parentViewDidChange() at some
925
+ point.
926
+
927
+ @property {Boolean} force This property is ignored.
928
+ @returns {SC.View} receiver
929
+ @test in updateLayerLocation
930
+ */
931
+ updateLayerLocationIfNeeded: function(force) {
932
+ if (this.get('layerLocationNeedsUpdate')) {
933
+ this.set('layerLocationNeedsUpdate', NO) ;
934
+ this.updateLayerLocation() ;
935
+ }
936
+ return this ;
937
+ },
938
+
939
+ /**
940
+ This method is called when a view changes its location in the view
941
+ hierarchy. This method will update the underlying DOM-location of the
942
+ layer so that it reflects the new location.
943
+
944
+ @returns {SC.View} receiver
945
+ */
946
+ updateLayerLocation: function() {
947
+ // collect some useful value
948
+ // if there is no node for some reason, just exit
949
+ var node = this.get('layer') ;
950
+ var parentView = this.get('parentView') ;
951
+ var parentNode = parentView ? parentView.get('containerLayer') : null ;
952
+
953
+ // remove node from current parentNode if the node does not match the new
954
+ // parent node.
955
+ if (node && node.parentNode && node.parentNode !== parentNode) {
956
+ node.parentNode.removeChild(node);
957
+ }
958
+
959
+ // CASE 1: no new parentView. just remove from parent (above).
960
+ if (!parentView) {
961
+ if (node && node.parentNode) node.parentNode.removeChild(node);
962
+
963
+ // CASE 2: parentView has no layer, view has layer. destroy layer
964
+ // CASE 3: parentView has no layer, view has no layer, nothing to do
965
+ } else if (!parentNode) {
966
+ if (node) {
967
+ if (node.parentNode) node.parentNode.removeChild(node);
968
+ this.destroyLayer();
969
+ }
970
+
971
+ // CASE 4: parentView has layer, view has no layer. create layer & add
972
+ // CASE 5: parentView has layer, view has layer. move layer
973
+ } else {
974
+ if (!node) {
975
+ this.createLayer() ;
976
+ node = this.get('layer') ;
977
+ }
978
+
979
+ var siblings = parentView.get('childViews') ;
980
+ var nextView = siblings.objectAt(siblings.indexOf(this)+1) ;
981
+ var nextNode = (nextView) ? nextView.get('layer') : null ;
982
+
983
+ // before we add to parent node, make sure that the nextNode exists...
984
+ if (nextView && !nextNode) {
985
+ nextView.updateLayerLocationIfNeeded() ;
986
+ nextNode = nextView.get('layer') ;
987
+ }
988
+
989
+ // add to parentNode if needed. If we do add, then also notify view
990
+ // that its parentView has resized since joining a parentView has the
991
+ // same effect.
992
+ if ((node.parentNode!==parentNode) || (node.nextSibling!==nextNode)) {
993
+ parentNode.insertBefore(node, nextNode) ;
994
+ if (this.parentViewDidResize) this.parentViewDidResize() ;
995
+ }
996
+ }
997
+
998
+ parentNode = parentView = node = null ; // avoid memory leaks
999
+ return this ;
1000
+ },
1001
+
1002
+ // .......................................................
1003
+ // SC.RESPONDER SUPPORT
1004
+ //
1005
+
1006
+ /** @property
1007
+ The nextResponder is usually the parentView.
1008
+ */
1009
+ nextResponder: function() {
1010
+ return this.get('parentView');
1011
+ }.property('parentView').cacheable(),
1012
+
1013
+ /**
1014
+ Recursively travels down the view hierarchy looking for a view that
1015
+ implements the key equivalent (returning to YES to indicate it handled
1016
+ the event). You can override this method to handle specific key
1017
+ equivalents yourself.
1018
+
1019
+ The keystring is a string description of the key combination pressed.
1020
+ The evt is the event itself. If you handle the equivalent, return YES.
1021
+ Otherwise, you should just return sc_super.
1022
+
1023
+ @param {String} keystring
1024
+ @param {SC.Event} evt
1025
+ @returns {Boolean}
1026
+ */
1027
+ performKeyEquivalent: function(keystring, evt) {
1028
+ var ret = null, childViews = this.get('childViews'), len = childViews.length, idx=-1;
1029
+ while(!ret && (++idx<len)) {
1030
+ ret = childViews[idx].performKeyEquivalent(keystring, evt);
1031
+ }
1032
+ return ret ;
1033
+ },
1034
+
1035
+ // .......................................................
1036
+ // CORE DISPLAY METHODS
1037
+ //
1038
+
1039
+ /** @private
1040
+ Setup a view, but do not finish waking it up.
1041
+ - configure childViews
1042
+ - generate DOM + plug in outlets/childViews unless rootElement is defined
1043
+ - register the view with the global views hash, which is used for mgmt
1044
+ */
1045
+ init: function() {
1046
+ var parentView, path, root, idx, len, lp, dp ;
1047
+
1048
+ sc_super() ;
1049
+
1050
+ // register for event handling now if we're not a materialized view
1051
+ // (materialized views register themselves as needed)
1052
+ if (!this.get('isMaterialized')) {
1053
+ SC.View.views[this.get('layerId')] = this ;
1054
+ }
1055
+
1056
+ // setup child views. be sure to clone the child views array first
1057
+ this.childViews = this.childViews ? this.childViews.slice() : [] ;
1058
+ this.createChildViews() ; // setup child Views
1059
+
1060
+ // register display property observers ..
1061
+ // TODO: Optimize into class setup
1062
+ dp = this.get('displayProperties') ;
1063
+ idx = dp.length ;
1064
+ while(--idx >= 0) {
1065
+ this.addObserver(dp[idx], this, this.displayDidChange) ;
1066
+ }
1067
+
1068
+ // register for drags
1069
+ if (this.get('isDropTarget')) SC.Drag.addDropTarget(this) ;
1070
+
1071
+ // register scroll views for autoscroll during drags
1072
+ if (this.get('isScrollable')) SC.Drag.addScrollableView(this) ;
1073
+ },
1074
+
1075
+ /**
1076
+ Wakes up the view. The default implementation immediately syncs any
1077
+ bindings, which may cause the view to need its display updated. You
1078
+ can override this method to perform any additional setup. Be sure to
1079
+ call sc_super to setup bindings and to call awake on childViews.
1080
+
1081
+ It is best to awake a view before you add it to the DOM. This way when
1082
+ the DOM is generated, it will have the correct initial values and will
1083
+ not require any additional setup.
1084
+
1085
+ @returns {void}
1086
+ */
1087
+ awake: function() {
1088
+ sc_super();
1089
+ var childViews = this.get('childViews'), len = childViews.length, idx ;
1090
+ for (idx=0; idx<len; ++idx) childViews[idx].awake() ;
1091
+ },
1092
+
1093
+ /**
1094
+ You must call this method on a view to destroy the view (and all of its
1095
+ child views). This will remove the view from any parent node, then make
1096
+ sure that the DOM element managed by the view can be released by the
1097
+ memory manager.
1098
+ */
1099
+ destroy: function() {
1100
+ if (this.get('isDestroyed')) return this; // nothing to do
1101
+
1102
+ sc_super();
1103
+
1104
+ // remove from parent if found
1105
+ this.removeFromParent() ;
1106
+ this._destroy(); // core destroy method
1107
+
1108
+ // unregister for drags
1109
+ if (this.get('isDropTarget')) SC.Drag.removeDropTarget(this) ;
1110
+
1111
+ // unregister for autoscroll during drags
1112
+ if (this.get('isScrollable')) SC.Drag.removeScrollableView(this) ;
1113
+ return this; // done with cleanup
1114
+ },
1115
+
1116
+ _destroy: function() {
1117
+ if (this.get('isDestroyed')) return this ; // nothing to do
1118
+
1119
+ // destroy the layer -- this will avoid each child view destroying
1120
+ // the layer over and over again...
1121
+ this.destroyLayer() ;
1122
+
1123
+ // first destroy any children.
1124
+ var childViews = this.get('childViews'), len = childViews.length, idx ;
1125
+ if (len) {
1126
+ childViews = childViews.slice() ;
1127
+ for (idx=0; idx<len; ++idx) childViews[idx]._destroy() ;
1128
+ }
1129
+
1130
+ // next remove view from global hash
1131
+ delete SC.View.views[this.get('layerId')] ;
1132
+ delete this._CQ ;
1133
+ delete this.page ;
1134
+
1135
+ // mark as destroyed so we don't do this again
1136
+ this.set('isDestroyed', YES) ;
1137
+ return this ;
1138
+ },
1139
+
1140
+ /**
1141
+ This method is called when your view is first created to setup any child
1142
+ views that are already defined on your class. If any are found, it will
1143
+ instantiate them for you.
1144
+
1145
+ The default implementation of this method simply steps through your
1146
+ childViews array, which is expects to either be empty or to contain View
1147
+ designs that can be instantiated
1148
+
1149
+ Alternatively, you can implement this method yourself in your own
1150
+ subclasses to look for views defined on specific properties and then build
1151
+ a childViews array yourself.
1152
+
1153
+ Note that when you implement this method yourself, you should never
1154
+ instantiate views directly. Instead, you should use
1155
+ this.createChildView() method instead. This method can be much faster in
1156
+ a production environment than creating views yourself.
1157
+
1158
+ @returns {SC.View} receiver
1159
+ */
1160
+ createChildViews: function() {
1161
+ var childViews = this.get('childViews'),
1162
+ len = childViews.length,
1163
+ idx, key, views, view ;
1164
+
1165
+ this.beginPropertyChanges() ;
1166
+
1167
+ // swap the array
1168
+ for (idx=0; idx<len; ++idx) {
1169
+ if (key = (view = childViews[idx])) {
1170
+
1171
+ // is this is a key name, lookup view class
1172
+ if (typeof key === SC.T_STRING) {
1173
+ view = this[key];
1174
+ } else key = null ;
1175
+
1176
+ if (view.isClass) {
1177
+ view = this.createChildView(view) ; // instantiate if needed
1178
+ if (key) this[key] = view ; // save on key name if passed
1179
+ }
1180
+ }
1181
+ childViews[idx] = view;
1182
+ }
1183
+
1184
+ this.endPropertyChanges() ;
1185
+ return this ;
1186
+ },
1187
+
1188
+ /**
1189
+ Instantiates a view to be added to the childViews array during view
1190
+ initialization. You generally will not call this method directly unless
1191
+ you are overriding createChildViews(). Note that this method will
1192
+ automatically configure the correct settings on the new view instance to
1193
+ act as a child of the parent.
1194
+
1195
+ @param {Class} viewClass
1196
+ @param {Hash} attrs optional attributes to add
1197
+ @returns {SC.View} new instance
1198
+ @test in createChildViews
1199
+ */
1200
+ createChildView: function(view, attrs) {
1201
+ // attrs should always exist...
1202
+ if (!attrs) attrs = {} ;
1203
+ attrs.owner = attrs.parentView = this ;
1204
+ if (!attrs.page) attrs.page = this.page ;
1205
+
1206
+ // Now add this to the attributes and create.
1207
+ view = view.create(attrs) ;
1208
+ return view ;
1209
+ },
1210
+
1211
+ // ...........................................
1212
+ // LAYOUT
1213
+ //
1214
+
1215
+ /**
1216
+ This convenience method will take the current layout, apply any changes
1217
+ you pass and set it again. It is more convenient than having to do this
1218
+ yourself sometimes.
1219
+
1220
+ You can pass just a key/value pair or a hash with several pairs. You can
1221
+ also pass a null value to delete a property.
1222
+
1223
+ This method will avoid actually setting the layout if the value you pass
1224
+ does not edit the layout.
1225
+
1226
+ @param {String|Hash} key
1227
+ @param {Object} value
1228
+ @returns {SC.View} receiver
1229
+ */
1230
+ adjust: function(key, value) {
1231
+ var layout = SC.clone(this.get('layout')), didChange = NO, cur ;
1232
+
1233
+ if (key === undefined) return this ; // nothing to do.
1234
+
1235
+ // handle string case
1236
+ if (SC.typeOf(key) === SC.T_STRING) {
1237
+ cur = layout[key] ;
1238
+ if (SC.none(value)) {
1239
+ if (cur !== undefined) didChange = YES ;
1240
+ delete layout[key] ;
1241
+ } else {
1242
+ if (cur !== value) didChange = YES ;
1243
+ layout[key] = value ;
1244
+ }
1245
+
1246
+ // handle hash -- do it this way to avoid creating memory unless needed
1247
+ } else {
1248
+ var hash = key;
1249
+ for(key in hash) {
1250
+ if (!hash.hasOwnProperty(key)) continue;
1251
+ value = hash[key] ;
1252
+ cur = layout[key] ;
1253
+
1254
+ if (value === null) {
1255
+ if (cur !== undefined) didChange = YES ;
1256
+ delete layout[key] ;
1257
+ } else if (value !== undefined) {
1258
+ if (cur !== value) didChange = YES ;
1259
+ layout[key] = value ;
1260
+ }
1261
+ }
1262
+ }
1263
+
1264
+ // if (didChange) {
1265
+ // console.log('did change layout') ;
1266
+ // console.log(layout) ;
1267
+ // }
1268
+
1269
+ // now set adjusted layout
1270
+ if (didChange) this.set('layout', layout) ;
1271
+
1272
+ return this ;
1273
+ },
1274
+
1275
+ /**
1276
+ The layout describes how you want your view to be positions on the
1277
+ screen. You can define the following properties:
1278
+
1279
+ - left: the left edge
1280
+ - top: the top edge
1281
+ - right: the right edge
1282
+ - bottom: the bottom edge
1283
+ - height: the height
1284
+ - width: the width
1285
+ - centerX: an offset from center X
1286
+ - centerY: an offset from center Y
1287
+ - minWidth: a minimum width
1288
+ - minHeight: a minimum height
1289
+ - maxWidth: a maximum width
1290
+ - maxHeight: a maximum height
1291
+
1292
+ Note that you can only use certain combinations to set layout. For
1293
+ example, you may set left/right or left/width, but not left/width/right,
1294
+ since that combination doesn't make sense.
1295
+
1296
+ Likewise, you may set a minWidth/minHeight, or maxWidth/maxHeight, but
1297
+ if you also set the width/height explicitly, then those constraints won't
1298
+ matter as much.
1299
+
1300
+ Layout is designed to maximize reliance on the browser's rendering
1301
+ engine to keep your app up to date.
1302
+
1303
+ @test in layoutStyle
1304
+ */
1305
+ layout: { top: 0, left: 0, bottom: 0, right: 0 },
1306
+
1307
+ /**
1308
+ Converts a frame from the receiver's offset to the target offset. Both
1309
+ the receiver and the target must belong to the same pane. If you pass
1310
+ null, the conversion will be to the pane level.
1311
+
1312
+ Note that the context of a view's frame is the view's parent frame. In
1313
+ other words, if you want to convert the frame of your view to the global
1314
+ frame, then you should do:
1315
+
1316
+ {{{
1317
+ var pv = this.get('parentView'), frame = this.get('frame');
1318
+ var newFrame = pv ? pv.convertFrameToView(frame, null) : frame;
1319
+ }}}
1320
+
1321
+ @param {Rect} frame the source frame
1322
+ @param {SC.View} targetView the target view to convert to
1323
+ @returns {Rect} converted frame
1324
+ @test in converFrames
1325
+ */
1326
+ convertFrameToView: function(frame, targetView) {
1327
+ var myX=0, myY=0, targetX=0, targetY=0, view = this, f ;
1328
+
1329
+ // walk up this side
1330
+ while (view) {
1331
+ f = view.get('frame'); myX += f.x; myY += f.y ;
1332
+ view = view.get('parentView') ;
1333
+ }
1334
+
1335
+ // walk up other size
1336
+ if (targetView) {
1337
+ view = targetView ;
1338
+ while (view) {
1339
+ f = view.get('frame'); targetX += f.x; targetY += f.y ;
1340
+ view = view.get('parentView') ;
1341
+ }
1342
+ }
1343
+
1344
+ // now we can figure how to translate the origin.
1345
+ myX = frame.x + myX - targetX ;
1346
+ myY = frame.y + myY - targetY ;
1347
+ return { x: myX, y: myY, width: frame.width, height: frame.height } ;
1348
+ },
1349
+
1350
+ /**
1351
+ Converts a frame offset in the coordinates of another view system to the
1352
+ reciever's view.
1353
+
1354
+ Note that the convext of a view's frame is relative to the view's
1355
+ parentFrame. For example, if you want to convert the frame of view that
1356
+ belongs to another view to the receiver's frame you would do:
1357
+
1358
+ {{{
1359
+ var frame = view.get('frame');
1360
+ var newFrame = this.convertFrameFromView(frame, view.get('parentView'));
1361
+ }}}
1362
+
1363
+ @param {Rect} frame the source frame
1364
+ @param {SC.View} targetView the target view to convert to
1365
+ @returns {Rect} converted frame
1366
+ @test in converFrames
1367
+ */
1368
+ convertFrameFromView: function(frame, targetView) {
1369
+ var myX=0, myY=0, targetX=0, targetY=0, view = this, next, f ;
1370
+
1371
+ // walk up this side
1372
+ while (view) {
1373
+ f = view.get('frame'); myX += f.x; myY += f.y ;
1374
+ view = view.get('parentView') ;
1375
+ }
1376
+
1377
+ // walk up other size
1378
+ if (targetView) {
1379
+ view = targetView ;
1380
+ while(view) {
1381
+ f = view.get('frame'); targetX += f.x; targetY += f.y ;
1382
+ view = view.get('parentView') ;
1383
+ }
1384
+ }
1385
+
1386
+ // now we can figure how to translate the origin.
1387
+ myX = frame.x - myX + targetX ;
1388
+ myY = frame.y - myY + targetY ;
1389
+ return { x: myX, y: myY, width: frame.width, height: frame.height } ;
1390
+ },
1391
+
1392
+ /**
1393
+ Frame describes the current bounding rect for your view. This is always
1394
+ measured from the top-left corner of the parent view.
1395
+
1396
+ @property {Rect}
1397
+ @test in layoutStyle
1398
+ */
1399
+ frame: function() {
1400
+ return this.computeFrameWithParentFrame(null) ;
1401
+ }.property().cacheable(),
1402
+
1403
+ /**
1404
+ Computes what the frame of this view would be if the parent were resized
1405
+ to the passed dimensions. You can use this method to project the size of
1406
+ a frame based on the resize behavior of the parent.
1407
+
1408
+ This method is used especially by the scroll view to automatically
1409
+ calculate when scrollviews should be visible.
1410
+
1411
+ Passing null for the parent dimensions will use the actual current
1412
+ parent dimensions. This is the same method used to calculate the current
1413
+ frame when it changes.
1414
+
1415
+ @param {Rect} pdim the projected parent dimensions
1416
+ @returns {Rect} the computed frame
1417
+ */
1418
+ computeFrameWithParentFrame: function(pdim) {
1419
+ var layout = this.get('layout') ;
1420
+ var f = {} ;
1421
+
1422
+ // handle left aligned and left/right
1423
+ if (!SC.none(layout.left)) {
1424
+ f.x = Math.floor(layout.left) ;
1425
+ if (layout.width !== undefined) {
1426
+ f.width = Math.floor(layout.width) ;
1427
+ } else { // better have layout.right!
1428
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1429
+ f.width = Math.floor(pdim.width - f.x - (layout.right || 0)) ;
1430
+ }
1431
+
1432
+ // handle right aligned
1433
+ } else if (!SC.none(layout.right)) {
1434
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1435
+ if (SC.none(layout.width)) {
1436
+ f.width = pdim.width - layout.right ;
1437
+ f.x = 0 ;
1438
+ } else {
1439
+ f.width = Math.floor(layout.width || 0) ;
1440
+ f.x = Math.floor(pdim.width - layout.right - f.width) ;
1441
+ }
1442
+
1443
+ // handle centered
1444
+ } else if (!SC.none(layout.centerX)) {
1445
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1446
+ f.width = Math.floor(layout.width || 0) ;
1447
+ f.x = Math.floor((pdim.width - f.width)/2 + layout.centerX) ;
1448
+ } else {
1449
+ f.x = 0 ; // fallback
1450
+ if (SC.none(layout.width)) {
1451
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1452
+ f.width = Math.floor(pdim.width) ;
1453
+ } else f.width = layout.width ;
1454
+ }
1455
+
1456
+ // handle top aligned and top/bottom
1457
+ if (!SC.none(layout.top)) {
1458
+ f.y = Math.floor(layout.top) ;
1459
+ if (layout.height !== undefined) {
1460
+ f.height = Math.floor(layout.height) ;
1461
+ } else { // better have layout.bottm!
1462
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1463
+ f.height = Math.floor(pdim.height - f.y - (layout.bottom || 0)) ;
1464
+ }
1465
+
1466
+ // handle bottom aligned
1467
+ } else if (!SC.none(layout.bottom)) {
1468
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1469
+ if (SC.none(layout.height)) {
1470
+ f.height = pdim.height - layout.bottom ;
1471
+ f.y = 0 ;
1472
+ } else {
1473
+ f.height = Math.floor(layout.height || 0) ;
1474
+ f.y = Math.floor(pdim.height - layout.bottom - f.height) ;
1475
+ }
1476
+
1477
+ // handle centered
1478
+ } else if (!SC.none(layout.centerY)) {
1479
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1480
+ f.height = Math.floor(layout.height || 0) ;
1481
+ f.y = Math.floor((pdim.height - f.height)/2 + layout.centerY) ;
1482
+
1483
+ // fallback
1484
+ } else {
1485
+ f.y = 0 ; // fallback
1486
+ if (SC.none(layout.height)) {
1487
+ if (!pdim) pdim = this.computeParentDimensions(layout) ;
1488
+ f.height = Math.floor(pdim.height) ;
1489
+ } else f.height = layout.height;
1490
+ }
1491
+
1492
+ // make sure the width/height fix min/max...
1493
+ if (!SC.none(layout.maxHeight) && (f.height > layout.maxHeight)) {
1494
+ f.height = layout.maxHeight ;
1495
+ }
1496
+
1497
+ if (!SC.none(layout.minHeight) && (f.height < layout.minHeight)) {
1498
+ f.height = layout.minHeight ;
1499
+ }
1500
+
1501
+ if (!SC.none(layout.maxWidth) && (f.width > layout.maxWidth)) {
1502
+ f.width = layout.maxWidth ;
1503
+ }
1504
+
1505
+ if (!SC.none(layout.minWidth) && (f.width < layout.minWidth)) {
1506
+ f.width = layout.minWidth ;
1507
+ }
1508
+
1509
+ // make sure width/height are never < 0
1510
+ if (f.height < 0) f.height = 0 ;
1511
+ if (f.width < 0) f.width = 0 ;
1512
+
1513
+ return f;
1514
+ },
1515
+
1516
+ computeParentDimensions: function(frame) {
1517
+ var ret, pv = this.get('parentView'), pf = (pv) ? pv.get('frame') : null ;
1518
+
1519
+ if (pf) {
1520
+ ret = { width: pf.width, height: pf.height };
1521
+ } else {
1522
+ var f = frame ;
1523
+ ret = {
1524
+ width: (f.left || 0) + (f.width || 0) + (f.right || 0),
1525
+ height: (f.top || 0) + (f.height || 0) + (f.bottom || 0)
1526
+ };
1527
+ }
1528
+ return ret ;
1529
+ },
1530
+
1531
+ /**
1532
+ The clipping frame returns the visible portion of the view, taking into
1533
+ account the clippingFrame of the parent view. Keep in mind that the
1534
+ clippingFrame is in the context of the view itself, not it's parent view.
1535
+
1536
+ Normally this will be calculate based on the intersection of your own
1537
+ clippingFrame and your parentView's clippingFrame.
1538
+
1539
+ @property {Rect}
1540
+ */
1541
+ clippingFrame: function() {
1542
+ var pv= this.get('parentView'), f = this.get('frame'), ret = f ;
1543
+ if (pv) {
1544
+ pv = pv.get('clippingFrame') ;
1545
+ ret = SC.intersectRects(pv, f) ;
1546
+ }
1547
+ ret.x -= f.x ;
1548
+ ret.y -= f.y ;
1549
+ return ret ;
1550
+ }.property('parentView', 'frame').cacheable(),
1551
+
1552
+ /** @private
1553
+ Whenever the clippingFrame changes, this observer will fire, notifying
1554
+ child views that their frames have also changed.
1555
+ */
1556
+ _sc_view_clippingFrameDidChange: function() {
1557
+ var cvs = this.get('childViews'), len = cvs.length, idx, cv ;
1558
+ for (idx=0; idx<len; ++idx) {
1559
+ cv = cvs[idx] ;
1560
+ if (!cv.hasStaticLayout) cv.notifyPropertyChange('clippingFrame') ;
1561
+ }
1562
+ }.observes('clippingFrame'),
1563
+
1564
+ /**
1565
+ This method may be called on your view whenever the parent view resizes.
1566
+
1567
+ The default version of this method will reset the frame and then call
1568
+ viewDidResize(). You will not usually override this method, but you may
1569
+ override the viewDidResize() method.
1570
+
1571
+ @returns {void}
1572
+ @test in viewDidResize
1573
+ */
1574
+ parentViewDidResize: function() {
1575
+ var layout = this.get('layout') ;
1576
+
1577
+ // only resizes if the layout does something other than left/top - fixed
1578
+ // size.
1579
+ var isFixed = (
1580
+ (layout.left !== undefined) && (layout.top !== undefined) &&
1581
+ (layout.width !== undefined) && (layout.height !== undefined)
1582
+ );
1583
+
1584
+ if (!isFixed) {
1585
+ this.notifyPropertyChange('frame') ;
1586
+ this.viewDidResize() ;
1587
+ }
1588
+ },
1589
+
1590
+ /**
1591
+ This method is invoked on your view when the view resizes due to a layout
1592
+ change or due to the parent view resizing. You can override this method
1593
+ to implement your own layout if you like, such as performing a grid
1594
+ layout.
1595
+
1596
+ The default implementation simply calls parentViewDidResize on all of
1597
+ your children.
1598
+
1599
+ @returns {void}
1600
+ */
1601
+ viewDidResize: function() {
1602
+ var cv = this.childViews, len = cv.length, idx, view ;
1603
+ for (idx=0; idx<len; ++idx) {
1604
+ view = cv[idx] ;
1605
+ if (view.parentViewDidResize) view.parentViewDidResize() ;
1606
+ }
1607
+ }.observes('layout'),
1608
+
1609
+ // Implementation note: As a general rule, paired method calls, such as
1610
+ // beginLiveResize/endLiveResize that are called recursively on the tree
1611
+ // should reverse the order when doing the final half of the call. This
1612
+ // ensures that the calls are propertly nested for any cleanup routines.
1613
+ //
1614
+ // -> View A.beginXXX()
1615
+ // -> View B.beginXXX()
1616
+ // -> View C.begitXXX()
1617
+ // -> View D.beginXXX()
1618
+ //
1619
+ // ...later on, endXXX methods are called in reverse order of beginXXX...
1620
+ //
1621
+ // <- View D.endXXX()
1622
+ // <- View C.endXXX()
1623
+ // <- View B.endXXX()
1624
+ // <- View A.endXXX()
1625
+ //
1626
+ // See the two methods below for an example implementation.
1627
+
1628
+ /**
1629
+ Call this method when you plan to begin a live resize. This will
1630
+ notify the receiver view and any of its children that are interested
1631
+ that the resize is about to begin.
1632
+
1633
+ @returns {SC.View} receiver
1634
+ @test in viewDidResize
1635
+ */
1636
+ beginLiveResize: function() {
1637
+ // call before children have been notified...
1638
+ if (this.willBeginLiveResize) this.willBeginLiveResize() ;
1639
+
1640
+ // notify children in order
1641
+ var ary = this.get('childViews'), len = ary.length, idx, view ;
1642
+ for (idx=0; idx<len; ++idx) {
1643
+ view = ary[idx] ;
1644
+ if (view.beginLiveResize) view.beginLiveResize();
1645
+ }
1646
+ return this ;
1647
+ },
1648
+
1649
+ /**
1650
+ Call this method when you are finished with a live resize. This will
1651
+ notify the receiver view and any of its children that are interested
1652
+ that the live resize has ended.
1653
+
1654
+ @returns {SC.View} receiver
1655
+ @test in viewDidResize
1656
+ */
1657
+ endLiveResize: function() {
1658
+ // notify children in *reverse* order
1659
+ var ary = this.get('childViews'), len = ary.length, idx, view ;
1660
+ for (idx=len-1; idx>=0; --idx) { // loop backwards
1661
+ view = ary[idx] ;
1662
+ if (view.endLiveResize) view.endLiveResize() ;
1663
+ }
1664
+
1665
+ // call *after* all children have been notified...
1666
+ if (this.didEndLiveResize) this.didEndLiveResize() ;
1667
+ return this ;
1668
+ },
1669
+
1670
+ /**
1671
+ layoutStyle describes the current styles to be written to your element
1672
+ based on the layout you defined. Both layoutStyle and frame reset when
1673
+ you edit the layout property. Both are read only.
1674
+
1675
+ Computes the layout style settings needed for the current anchor.
1676
+
1677
+ @property {Hash}
1678
+ @readOnly
1679
+ */
1680
+ layoutStyle: function() {
1681
+ var layout = this.get('layout'), ret = {}, pdim = null;
1682
+
1683
+ // X DIRECTION
1684
+
1685
+ // handle left aligned and left/right
1686
+ if (!SC.none(layout.left)) {
1687
+ ret.left = Math.floor(layout.left);
1688
+ if (layout.width !== undefined) {
1689
+ ret.width = Math.floor(layout.width) ;
1690
+ ret.right = null ;
1691
+ } else {
1692
+ ret.width = null ;
1693
+ ret.right = Math.floor(layout.right || 0) ;
1694
+ }
1695
+ ret.marginLeft = 0 ;
1696
+
1697
+ // handle right aligned
1698
+ } else if (!SC.none(layout.right)) {
1699
+ ret.right = Math.floor(layout.right) ;
1700
+ ret.marginLeft = 0 ;
1701
+
1702
+ if (SC.none(layout.width)) {
1703
+ ret.left = 0;
1704
+ ret.width = null;
1705
+ } else {
1706
+ ret.left = null ;
1707
+ ret.width = Math.floor(layout.width || 0) ;
1708
+ }
1709
+
1710
+ // handle centered
1711
+ } else if (!SC.none(layout.centerX)) {
1712
+ ret.left = "50%";
1713
+ ret.width = Math.floor(layout.width || 0) ;
1714
+ ret.marginLeft = Math.floor(layout.centerX - ret.width/2) ;
1715
+ ret.right = null ;
1716
+
1717
+ // if width defined, assume top/left of zero
1718
+ } else if (!SC.none(layout.width)) {
1719
+ ret.left = 0;
1720
+ ret.right = null;
1721
+ ret.width = Math.floor(layout.width);
1722
+ ret.marginLeft = 0;
1723
+
1724
+ // fallback, full width.
1725
+ } else {
1726
+ ret.left = 0;
1727
+ ret.right = 0;
1728
+ ret.width = null ;
1729
+ ret.marginLeft= 0;
1730
+ }
1731
+
1732
+ // handle min/max
1733
+ ret.minWidth = (layout.minWidth === undefined) ? null : layout.minWidth;
1734
+ ret.maxWidth = (layout.maxWidth === undefined) ? null : layout.maxWidth;
1735
+
1736
+ // Y DIRECTION
1737
+
1738
+ // handle left aligned and left/right
1739
+ if (!SC.none(layout.top)) {
1740
+ ret.top = Math.floor(layout.top);
1741
+ if (layout.height !== undefined) {
1742
+ ret.height = Math.floor(layout.height) ;
1743
+ ret.bottom = null ;
1744
+ } else {
1745
+ ret.height = null ;
1746
+ ret.bottom = Math.floor(layout.bottom || 0) ;
1747
+ }
1748
+ ret.marginTop = 0 ;
1749
+
1750
+ // handle right aligned
1751
+ } else if (!SC.none(layout.bottom)) {
1752
+ ret.marginTop = 0 ;
1753
+ ret.bottom = Math.floor(layout.bottom) ;
1754
+ if (SC.none(layout.height)) {
1755
+ ret.top = 0;
1756
+ ret.height = null ;
1757
+ } else {
1758
+ ret.top = null ;
1759
+ ret.height = Math.floor(layout.height || 0) ;
1760
+ }
1761
+
1762
+ // handle centered
1763
+ } else if (!SC.none(layout.centerY)) {
1764
+ ret.top = "50%";
1765
+ ret.height = Math.floor(layout.height || 0) ;
1766
+ ret.marginTop = Math.floor(layout.centerY - ret.height/2) ;
1767
+ ret.bottom = null ;
1768
+
1769
+ } else if (!SC.none(layout.height)) {
1770
+ ret.top = 0;
1771
+ ret.bottom = null;
1772
+ ret.height = Math.floor(layout.height || 0);
1773
+ ret.marginTop = 0;
1774
+
1775
+ // fallback, full width.
1776
+ } else {
1777
+ ret.top = 0;
1778
+ ret.bottom = 0;
1779
+ ret.height = null ;
1780
+ ret.marginTop= 0;
1781
+ }
1782
+
1783
+ // handle min/max
1784
+ ret.minHeight = (layout.minHeight === undefined) ? null : layout.minHeight;
1785
+ ret.maxHeight = (layout.maxHeight === undefined) ? null : layout.maxHeight;
1786
+
1787
+ // if zIndex is set, use it. otherwise let default shine through
1788
+ ret.zIndex = SC.none(layout.zIndex) ? null : layout.zIndex.toString();
1789
+
1790
+ // if backgroundPosition is set, use it. otherwise let default shine through
1791
+ ret.backgroundPosition = SC.none(layout.backgroundPosition) ? null : layout.backgroundPosition.toString();
1792
+
1793
+ // set default values to null to allow built-in CSS to shine through
1794
+ // currently applies only to marginLeft & marginTop
1795
+ var dims = SC._VIEW_DEFAULT_DIMS, loc = dims.length, x;
1796
+ while(--loc >=0) {
1797
+ x = dims[loc];
1798
+ if (ret[x]===0) ret[x]=null;
1799
+ }
1800
+
1801
+ // convert any numbers into a number + "px".
1802
+ for(var key in ret) {
1803
+ var value = ret[key];
1804
+ if (typeof value === SC.T_NUMBER) ret[key] = (value + "px");
1805
+ }
1806
+ return ret ;
1807
+ }.property().cacheable(),
1808
+
1809
+ /**
1810
+ The view responsible for laying out this view. The default version
1811
+ returns the current parent view.
1812
+ */
1813
+ layoutView: function() {
1814
+ return this.get('parentView') ;
1815
+ }.property('parentView').cacheable(),
1816
+
1817
+ /**
1818
+ This method is called whenever a property changes that invalidates the
1819
+ layout of the view. Changing the layout will do this automatically, but
1820
+ you can add others if you want.
1821
+
1822
+ @returns {SC.View} receiver
1823
+ */
1824
+ layoutDidChange: function() {
1825
+ // console.log('%@.layoutDidChange()'.fmt(this));
1826
+ this.beginPropertyChanges() ;
1827
+ if (this.frame) this.notifyPropertyChange('frame') ;
1828
+ this.notifyPropertyChange('layoutStyle') ;
1829
+ this.endPropertyChanges() ;
1830
+
1831
+ // notify layoutView...
1832
+ var layoutView = this.get('layoutView');
1833
+ if (layoutView) {
1834
+ layoutView.set('childViewsNeedLayout', YES);
1835
+ layoutView.layoutDidChangeFor(this) ;
1836
+ if (layoutView.get('childViewsNeedLayout')) {
1837
+ layoutView.invokeOnce(layoutView.layoutChildViewsIfNeeded);
1838
+ }
1839
+ }
1840
+
1841
+ return this ;
1842
+ }.observes('layout'),
1843
+
1844
+ /**
1845
+ This this property to YES whenever the view needs to layout its child
1846
+ views. Normally this property is set automatically whenever the layout
1847
+ property for a child view changes.
1848
+
1849
+ @property {Boolean}
1850
+ */
1851
+ childViewsNeedLayout: NO,
1852
+
1853
+ /**
1854
+ One of two methods that are invoked whenever one of your childViews
1855
+ layout changes. This method is invoked everytime a child view's layout
1856
+ changes to give you a chance to record the information about the view.
1857
+
1858
+ Since this method may be called many times during a single run loop, you
1859
+ should keep this method pretty short. The other method called when layout
1860
+ changes, layoutChildViews(), is invoked only once at the end of
1861
+ the run loop. You should do any expensive operations (including changing
1862
+ a childView's actual layer) in this other method.
1863
+
1864
+ Note that if as a result of running this method you decide that you do not
1865
+ need your layoutChildViews() method run later, you can set the
1866
+ childViewsNeedsLayout property to NO from this method and the layout
1867
+ method will not be called layer.
1868
+
1869
+ @param {SC.View} childView the view whose layout has changed.
1870
+ @returns {void}
1871
+ */
1872
+ layoutDidChangeFor: function(childView) {
1873
+ var set = this._needLayoutViews ;
1874
+ if (!set) set = this._needLayoutViews = SC.Set.create();
1875
+ set.add(childView);
1876
+ },
1877
+
1878
+ /**
1879
+ Called your layout method if the view currently needs to layout some
1880
+ child views.
1881
+
1882
+ @param {Boolean} isVisible if true assume view is visible even if it is not.
1883
+ @returns {SC.View} receiver
1884
+ @test in layoutChildViews
1885
+ */
1886
+ layoutChildViewsIfNeeded: function(isVisible) {
1887
+ if (!isVisible) isVisible = this.get('isVisibleInWindow');
1888
+ if (isVisible && this.get('childViewsNeedLayout')) {
1889
+ this.set('childViewsNeedLayout', NO);
1890
+ this.layoutChildViews();
1891
+ }
1892
+ return this ;
1893
+ },
1894
+
1895
+ /**
1896
+ Applies the current layout to the layer. This method is usually only
1897
+ called once per runloop. You can override this method to provide your
1898
+ own layout updating method if you want, though usually the better option
1899
+ is to override the layout method from the parent view.
1900
+
1901
+ The default implementation of this method simply calls the renderLayout()
1902
+ method on the views that need layout.
1903
+
1904
+ @returns {void}
1905
+ */
1906
+ layoutChildViews: function() {
1907
+ var set = this._needLayoutViews, len = set ? set.length : 0, idx;
1908
+ var view, context, layer;
1909
+ for(idx=0;idx<len;idx++) {
1910
+ view = set[idx];
1911
+ view.updateLayout();
1912
+ }
1913
+ view = context = layer = null ; // cleanup
1914
+ set.clear(); // reset & reuse
1915
+ },
1916
+
1917
+ /**
1918
+ Invoked by the layoutChildViews method to update the layout on a
1919
+ particular view. This method creates a render context and calls the
1920
+ renderLayout() method, which is probably what you want to override instead
1921
+ of this.
1922
+
1923
+ You will not usually override this method, but you may call it if you
1924
+ implement layoutChildViews() in a view yourself.
1925
+
1926
+ @returns {SC.View} receiver
1927
+ @test in layoutChildViews
1928
+ */
1929
+ updateLayout: function() {
1930
+ var layer = this.get('layer'), context;
1931
+ if (layer) {
1932
+ context = this.renderContext(layer);
1933
+ this.renderLayout(context);
1934
+ context.update();
1935
+ }
1936
+ layer = null ;
1937
+ return this ;
1938
+ },
1939
+
1940
+ /**
1941
+ Default method called by the layout view to actually apply the current
1942
+ layout to the layer. The default implementation simply assigns the
1943
+ current layoutStyle to the layer. This method is also called whenever
1944
+ the layer is first created.
1945
+
1946
+ @param {SC.RenderContext} the render context
1947
+ @returns {void}
1948
+ @test in layoutChildViews
1949
+ */
1950
+ renderLayout: function(context, firstTime) {
1951
+ context.addStyle(this.get('layoutStyle'));
1952
+ }
1953
+
1954
+ /** walk like a duck */
1955
+ isView: YES
1956
+
1957
+ });
1958
+
1959
+ SC.View.mixin(/** @scope SC.View @static */ {
1960
+
1961
+ /** @private walk like a duck -- used by SC.Page */
1962
+ isViewClass: YES,
1963
+
1964
+ /**
1965
+ This method works just like extend() except that it will also preserve
1966
+ the passed attributes in case you want to use a view builder later, if
1967
+ needed.
1968
+
1969
+ @param {Hash} attrs Attributes to add to view
1970
+ @returns {Class} SC.View subclass to create
1971
+ @function
1972
+ */
1973
+ design: function() {
1974
+ if (this.isDesign) return this; // only run design one time
1975
+ var ret = this.extend.apply(this, arguments);
1976
+ ret.isDesign = YES ;
1977
+ if (SC.ViewDesigner) {
1978
+ SC.ViewDesigner.didLoadDesign(ret, this, SC.A(arguments));
1979
+ }
1980
+ return ret ;
1981
+ },
1982
+
1983
+ /**
1984
+ Helper applies the layout to the prototype.
1985
+ */
1986
+ layout: function(layout) {
1987
+ this.prototype.layout = layout ;
1988
+ return this ;
1989
+ },
1990
+
1991
+ /**
1992
+ Helper applies the classNames to the prototype
1993
+ */
1994
+ classNames: function(sc) {
1995
+ sc = (this.prototype.classNames || []).concat(sc);
1996
+ this.prototype.classNames = sc;
1997
+ return this ;
1998
+ },
1999
+
2000
+ /**
2001
+ Help applies the tagName
2002
+ */
2003
+ tagName: function(tg) {
2004
+ this.prototype.tagName = tg;
2005
+ return this ;
2006
+ },
2007
+
2008
+ /**
2009
+ Helper adds the childView
2010
+ */
2011
+ childView: function(cv) {
2012
+ var childViews = this.prototype.childViews || [];
2013
+ if (childViews === this.superclass.prototype.childViews) childViews = childViews.slice();
2014
+ childViews.push(cv) ;
2015
+ this.prototype.childViews = childViews;
2016
+ return this ;
2017
+ },
2018
+
2019
+ /**
2020
+ Helper adds a binding to a design
2021
+ */
2022
+ bind: function(keyName, path) {
2023
+ var p = this.prototype, s = this.superclass.prototype;
2024
+ var bindings = p._bindings ;
2025
+ if (!bindings || bindings === s._bindings) {
2026
+ bindings = p._bindings = (bindings || []).slice() ;
2027
+ }
2028
+
2029
+ keyName = keyName + "Binding";
2030
+ p[keyName] = path ;
2031
+ bindings.push(keyName);
2032
+
2033
+ return this ;
2034
+ },
2035
+
2036
+ /**
2037
+ Helper sets a generic property on a design.
2038
+ */
2039
+ prop: function(keyName, value) {
2040
+ this.prototype[keyName] = value;
2041
+ return this ;
2042
+ },
2043
+
2044
+ /**
2045
+ Used to construct a localization for a view. The default implementation
2046
+ will simply return the passed attributes.
2047
+ */
2048
+ localization: function(attrs, rootElement) {
2049
+ // add rootElement
2050
+ if (rootElement) attrs.rootElement = SC.$(rootElement).get(0);
2051
+ return attrs;
2052
+ },
2053
+
2054
+ /**
2055
+ Creates a view instance, first finding the DOM element you name and then
2056
+ using that as the root element. You should not use this method very
2057
+ often, but it is sometimes useful if you want to attach to already
2058
+ existing HTML.
2059
+
2060
+ @param {String|Element} element
2061
+ @param {Hash} attrs
2062
+ @returns {SC.View} instance
2063
+ */
2064
+ viewFor: function(element, attrs) {
2065
+ var args = SC.$A(arguments); // prepare to edit
2066
+ if (SC.none(element)) {
2067
+ args.shift(); // remove if no element passed
2068
+ } else args[0] = { rootElement: SC.$(element).get(0) } ;
2069
+ var ret = this.create.apply(this, arguments) ;
2070
+ args = args[0] = null;
2071
+ return ret ;
2072
+ },
2073
+
2074
+ /**
2075
+ Create a new view with the passed attributes hash. If you have the
2076
+ Designer module loaded, this will also create a peer designer if needed.
2077
+ */
2078
+ create: function() {
2079
+ var C=this, ret = new C(arguments);
2080
+ if (SC.ViewDesigner) {
2081
+ SC.ViewDesigner.didCreateView(ret, SC.$A(arguments));
2082
+ }
2083
+ return ret ;
2084
+ },
2085
+
2086
+ /**
2087
+ Applies the passed localization hash to the component views. Call this
2088
+ method before you call create(). Returns the receiver. Typically you
2089
+ will do something like this:
2090
+
2091
+ view = SC.View.design({...}).loc(localizationHash).create();
2092
+
2093
+ @param {Hash} loc
2094
+ @param rootElement {String} optional rootElement with prepped HTML
2095
+ @returns {SC.View} receiver
2096
+ */
2097
+ loc: function(loc) {
2098
+ var childLocs = loc.childViews;
2099
+ delete loc.childViews; // clear out child views before applying to attrs
2100
+
2101
+ this.applyLocalizedAttributes(loc) ;
2102
+ if (SC.ViewDesigner) {
2103
+ SC.ViewDesigner.didLoadLocalization(this, SC.$A(arguments));
2104
+ }
2105
+
2106
+ // apply localization recursively to childViews
2107
+ var childViews = this.prototype.childViews, idx = childViews.length;
2108
+ while(--idx>=0) {
2109
+ var viewClass = childViews[idx];
2110
+ loc = childLocs[idx];
2111
+ if (loc && viewClass && viewClass.loc) viewClass.loc(loc) ;
2112
+ }
2113
+
2114
+ return this; // done!
2115
+ },
2116
+
2117
+ /**
2118
+ Internal method actually updates the localizated attributes on the view
2119
+ class. This is overloaded in design mode to also save the attributes.
2120
+ */
2121
+ applyLocalizedAttributes: function(loc) {
2122
+ SC.mixin(this.prototype, loc) ;
2123
+ },
2124
+
2125
+ views: {}
2126
+
2127
+ }) ;
2128
+
2129
+ // .......................................................
2130
+ // OUTLET BUILDER
2131
+ //
2132
+
2133
+ /**
2134
+ Generates a computed property that will look up the passed property path
2135
+ the first time you try to get the value. Use this whenever you want to
2136
+ define an outlet that points to another view or object. The root object
2137
+ used for the path will be the receiver.
2138
+ */
2139
+ SC.outlet = function(path) {
2140
+ return function(key) {
2141
+ return (this[key] = SC.objectForPropertyPath(path, this)) ;
2142
+ }.property();
2143
+ };
2144
+
2145
+ /** @private on unload clear cached divs. */
2146
+ SC.View.unload = function() {
2147
+
2148
+ // delete view items this way to ensure the views are cleared. The hash
2149
+ // itself may be owned by multiple view subclasses.
2150
+ var views = SC.View.views;
2151
+ if (views) {
2152
+ for(var key in views) {
2153
+ if (!views.hasOwnProperty(key)) continue ;
2154
+ delete views[key];
2155
+ }
2156
+ }
2157
+
2158
+ } ;
2159
+
2160
+ SC.Event.add(window, 'unload', SC.View, SC.View.unload) ;