sproutit-sproutcore 1.0.0.20090407205609 → 1.0.0.20090408130025

Sign up to get free protection for your applications and to get access to all the features.
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) ;