sproutcore 1.5.0.pre.3 → 1.5.0.pre.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. data/.rspec +1 -0
  2. data/CHANGELOG +42 -0
  3. data/README.txt +25 -0
  4. data/VERSION.yml +1 -1
  5. data/bin/sc-build +1 -1
  6. data/bin/sc-build-number +1 -1
  7. data/bin/sc-docs +1 -1
  8. data/bin/sc-gen +1 -1
  9. data/bin/sc-init +1 -1
  10. data/bin/sc-manifest +1 -1
  11. data/bin/sc-server +1 -1
  12. data/bin/sproutcore +1 -1
  13. data/lib/buildtasks/build.rake +5 -0
  14. data/lib/buildtasks/manifest.rake +20 -1
  15. data/lib/frameworks/sproutcore/Buildfile +12 -9
  16. data/lib/frameworks/sproutcore/CHANGELOG.md +48 -0
  17. data/lib/frameworks/sproutcore/apps/greenhouse/README +2 -9
  18. data/lib/frameworks/sproutcore/apps/greenhouse/TODO +11 -27
  19. data/lib/frameworks/sproutcore/apps/greenhouse/controllers/library.js +3 -10
  20. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/main-page.css +4 -31
  21. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/dialogs.js +5 -4
  22. data/lib/frameworks/sproutcore/apps/greenhouse/models/dir.js +3 -3
  23. data/lib/frameworks/sproutcore/apps/greenhouse/models/file.js +2 -2
  24. data/lib/frameworks/sproutcore/apps/greenhouse/states/main.js +31 -14
  25. data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +2 -1
  26. data/lib/frameworks/sproutcore/apps/greenhouse/states/ready.js +27 -1
  27. data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/list_item.js +1 -0
  28. data/lib/frameworks/sproutcore/apps/greenhouse/tests/views/plist_item.js +20 -0
  29. data/lib/frameworks/sproutcore/apps/greenhouse/theme.js +25 -0
  30. data/lib/frameworks/sproutcore/apps/greenhouse/views/plist_item.js +161 -24
  31. data/lib/frameworks/sproutcore/apps/greenhouse/views/tear_off_picker.js +1 -1
  32. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +37 -25
  33. data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +135 -26
  34. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/array.js +0 -0
  35. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/controller.js +0 -0
  36. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/controllers/object.js +1 -1
  37. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/core.js +0 -0
  38. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/object.js +0 -0
  39. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/ext/run_loop.js +1 -0
  40. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/delegate_support.js +0 -0
  41. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/responder_context.js +0 -0
  42. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/selection_support.js +0 -0
  43. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/mixins/string.js +0 -0
  44. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +68 -0
  45. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +108 -0
  46. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/main.js +2 -2
  47. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/manipulation.js +27 -0
  48. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/panes/pane.js +215 -505
  49. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +24 -0
  50. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/visibility.js +11 -0
  51. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/observable_protocol.js +0 -0
  52. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/protocols/sparse_array_delegate.js +0 -0
  53. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/core.css +0 -0
  54. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/resources/view.css +0 -0
  55. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/application.js +0 -0
  56. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/browser.js +1 -0
  57. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/builder.js +0 -0
  58. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/core_query.js +1 -1
  59. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/cursor.js +0 -0
  60. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +210 -0
  61. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/event.js +5 -5
  62. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/json.js +0 -0
  63. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/locale.js +0 -0
  64. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/page.js +0 -0
  65. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/platform.js +31 -5
  66. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/ready.js +1 -1
  67. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/render_context.js +0 -0
  68. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/responder.js +0 -0
  69. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/root_responder.js +83 -110
  70. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/selection_set.js +7 -4
  71. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/sparse_array.js +0 -0
  72. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/theme.js +0 -0
  73. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/timer.js +0 -0
  74. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/system/utils/rect.js +0 -0
  75. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +151 -0
  76. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/array_case.js +0 -0
  77. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/enum_case.js +0 -0
  78. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/null_case.js +0 -0
  79. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/selection_support.js +26 -0
  80. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/array/single_case.js +0 -0
  81. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/empty_case.js +0 -0
  82. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/multiple_case.js +0 -0
  83. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_case.js +0 -0
  84. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/controllers/object/single_enumerable_case.js +0 -0
  85. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/responder_context.js +0 -0
  86. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/mixins/string.js +0 -0
  87. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +14 -0
  88. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/builder.js +0 -0
  89. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/core_query/within.js +0 -0
  90. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/json.js +0 -0
  91. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/locale.js +0 -0
  92. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/begin.js +0 -0
  93. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/element.js +0 -0
  94. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/end.js +0 -0
  95. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/get.js +0 -0
  96. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_attr.js +0 -0
  97. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_basic.js +0 -0
  98. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_className.js +0 -0
  99. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/helpers_style.js +0 -0
  100. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/init.js +0 -0
  101. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/join.js +0 -0
  102. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/push_text.js +0 -0
  103. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/tag.js +0 -0
  104. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/render_context/update.js +0 -0
  105. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeKeyPane.js +0 -0
  106. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMainPane.js +0 -0
  107. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/makeMenuPane.js +0 -0
  108. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/root_responder.js +0 -0
  109. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/root_responder/targetForAction.js +0 -0
  110. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/add.js +0 -0
  111. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/copy.js +0 -0
  112. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/indexSetForSource.js +0 -0
  113. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/isEqual.js +0 -0
  114. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/selection_set/remove.js +0 -0
  115. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/sparse_array.js +0 -0
  116. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/theme.js +0 -0
  117. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invalidate.js +0 -0
  118. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/invokeLater.js +0 -0
  119. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/isPaused.js +0 -0
  120. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/performAction.js +0 -0
  121. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/timer/schedule.js +0 -0
  122. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/normalizeURL.js +0 -0
  123. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +268 -0
  124. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/system/utils/rect.js +0 -0
  125. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/main_pane.js +43 -0
  126. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/append_remove.js +107 -18
  127. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/child_view.js +20 -0
  128. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/firstResponder.js +0 -0
  129. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/keyPane.js +0 -0
  130. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/layout.js +0 -0
  131. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/pane/sendEvent.js +0 -0
  132. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/checkbox_support.js +32 -0
  133. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/text_field_support.js +73 -0
  134. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/collection.js +65 -0
  135. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/core.js +67 -0
  136. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/handlebars.js +295 -0
  137. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/animation.js +19 -18
  138. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build.js +0 -0
  139. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/build_children.js +0 -0
  140. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/clippingFrame.js +0 -0
  141. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertFrames.js +0 -0
  142. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/convertLayouts.js +0 -0
  143. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createChildViews.js +18 -15
  144. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/createLayer.js +0 -0
  145. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/destroyLayer.js +0 -0
  146. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/didAppendToDocument.js +11 -8
  147. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/findLayerInParentLayer.js +0 -0
  148. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/init.js +0 -0
  149. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/insertBefore.js +0 -0
  150. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisible.js +28 -0
  151. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/isVisibleInWindow.js +0 -0
  152. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +22 -0
  153. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layer.js +0 -0
  154. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/layoutChildViews.js +0 -0
  155. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +180 -0
  156. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +640 -0
  157. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/parentViewDidChange.js +0 -0
  158. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/prepareContext.js +0 -0
  159. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/removeChild.js +0 -0
  160. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/render.js +125 -0
  161. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/render_delegate_support.js +0 -0
  162. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/replaceChild.js +0 -0
  163. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/static_layout.js +21 -0
  164. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/theme.js +0 -0
  165. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayer.js +0 -0
  166. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/updateLayerLocation.js +0 -0
  167. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/view.js +0 -0
  168. data/lib/frameworks/sproutcore/frameworks/{amber → core_foundation}/tests/views/view/viewDidResize.js +0 -0
  169. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/checkbox_support.js +20 -0
  170. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +99 -0
  171. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/text_field_support.js +35 -0
  172. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template.js +77 -0
  173. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +187 -0
  174. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/base.js +1 -0
  175. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +41 -0
  176. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +57 -0
  177. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +223 -0
  178. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +1150 -0
  179. data/lib/frameworks/sproutcore/frameworks/{amber/views → core_foundation/views/view}/layout_style.js +93 -1
  180. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +489 -0
  181. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +362 -0
  182. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/touch.js +67 -0
  183. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/visibility.js +113 -0
  184. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +1280 -0
  185. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +27 -53
  186. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +13 -19
  187. data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +1 -0
  188. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +183 -71
  189. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +1 -2
  190. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +26 -46
  191. data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +25 -4
  192. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +139 -21
  193. data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +6 -1
  194. data/lib/frameworks/sproutcore/frameworks/datastore/tests/integration/cyclical_relationship.js +1 -1
  195. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/{parentless.js → data_store.js} +62 -16
  196. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +51 -17
  197. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +36 -10
  198. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +11 -11
  199. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +8 -8
  200. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +2 -2
  201. data/lib/frameworks/sproutcore/frameworks/{foundation/english.lproj → datetime/resources}/strings.js +1 -0
  202. data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/system/datetime.js +5 -37
  203. data/lib/frameworks/sproutcore/frameworks/{foundation → datetime}/tests/system/datetime.js +1 -0
  204. data/lib/frameworks/sproutcore/frameworks/debug/core.js +1 -1
  205. data/lib/frameworks/sproutcore/frameworks/designer/controllers/designs.js +1 -2
  206. data/lib/frameworks/sproutcore/frameworks/designer/designers/object_designer.js +3 -3
  207. data/lib/frameworks/sproutcore/frameworks/designer/designers/view_designer.js +3 -3
  208. data/lib/frameworks/sproutcore/frameworks/designer/views/designer_drop_target.js +9 -3
  209. data/lib/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +71 -70
  210. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +10 -2
  211. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +4 -19
  212. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +33 -14
  213. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +25 -0
  214. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +1 -1
  215. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +25 -103
  216. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +102 -92
  217. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +22 -25
  218. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +38 -25
  219. data/lib/frameworks/sproutcore/frameworks/desktop/views/date_field.js +1 -1
  220. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +1 -1
  221. data/lib/frameworks/sproutcore/frameworks/desktop/views/segment.js +42 -22
  222. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +513 -230
  223. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +0 -2
  224. data/lib/frameworks/sproutcore/frameworks/experimental/README.md +23 -0
  225. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/README.md +11 -0
  226. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/device.js +215 -0
  227. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/device_motion/platform.js +67 -0
  228. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +34 -0
  229. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/polymorphic_single_attribute.js +183 -0
  230. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +23 -0
  231. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/tests/models/polymorphic/single.js +124 -0
  232. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +0 -2
  233. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +151 -0
  234. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +27 -17
  235. data/lib/frameworks/sproutcore/frameworks/foundation/system/image_queue.js +6 -3
  236. data/lib/frameworks/sproutcore/frameworks/foundation/system/logger.js +163 -0
  237. data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +6 -3
  238. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +1 -0
  239. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/logger.js +44 -0
  240. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +200 -167
  241. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +1 -1
  242. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +52 -137
  243. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +7 -11
  244. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions.js +138 -0
  245. data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1338 -0
  246. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +32 -26
  247. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +162 -3
  248. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +10 -5
  249. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +123 -3
  250. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +12 -5
  251. data/lib/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +50 -13
  252. data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +163 -333
  253. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +58 -8
  254. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +2 -0
  255. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +9 -6
  256. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/makeArray.js +15 -1
  257. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +2 -0
  258. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/chained.js +31 -0
  259. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +18 -0
  260. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +31 -143
  261. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/concatenated_properties.js +71 -0
  262. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +177 -0
  263. data/lib/frameworks/sproutcore/frameworks/table/views/table.js +5 -4
  264. data/lib/frameworks/sproutcore/frameworks/table/views/table_header.js +5 -3
  265. data/lib/frameworks/sproutcore/themes/ace/resources/button/button.js +8 -2
  266. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +2 -3
  267. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +1 -1
  268. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +1 -1
  269. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +1 -1
  270. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +1 -1
  271. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +2 -2
  272. data/lib/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +62 -62
  273. data/lib/gen/html_app/Buildfile +36 -0
  274. data/lib/gen/html_app/README +1 -0
  275. data/lib/gen/html_app/USAGE +15 -0
  276. data/lib/gen/html_app/templates/apps/@target_name@/@target_name@.js +14 -0
  277. data/lib/gen/html_app/templates/apps/@target_name@/resources/images/.gitkeep +0 -0
  278. data/lib/gen/html_app/templates/apps/@target_name@/resources/stylesheets/@target_name@.css +0 -0
  279. data/lib/gen/html_app/templates/apps/@target_name@/resources/templates/@target_name@.handlebars +1 -0
  280. data/lib/gen/html_project/Buildfile +45 -0
  281. data/lib/gen/html_project/INIT +3 -0
  282. data/lib/gen/html_project/README +1 -0
  283. data/lib/gen/html_project/USAGE +2 -0
  284. data/lib/gen/html_project/templates/@filename@/Buildfile +8 -0
  285. data/lib/gen/html_project/templates/@filename@/README +7 -0
  286. data/lib/sproutcore/builders/handlebars.rb +30 -0
  287. data/lib/sproutcore/builders.rb +1 -1
  288. data/lib/sproutcore/helpers/static_helper.rb +3 -3
  289. data/lib/sproutcore/tools/init.rb +25 -9
  290. data/spec/buildtasks/manifest/prepare_build_tasks/handlebars_spec.rb +39 -0
  291. data/spec/fixtures/builder_tests/apps/handlebars_test/template.handlebars +5 -0
  292. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/templates/demo.handlebars +4 -0
  293. data/spec/lib/builders/handlebars_spec.rb +29 -0
  294. data/vendor/chance/lib/chance/imagers/data_url.rb +20 -7
  295. data/vendor/chance/lib/chance/instance.rb +4 -1
  296. data/vendor/chance/lib/chance/parser.rb +31 -31
  297. data/vendor/chance/lib/chance/slicing.rb +38 -8
  298. metadata +195 -225
  299. data/lib/frameworks/sproutcore/frameworks/amber/system/device.js +0 -143
  300. data/lib/frameworks/sproutcore/frameworks/amber/system/utils.js +0 -174
  301. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/main_pane.js +0 -31
  302. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/pane/sendTouchEvent.js +0 -267
  303. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutDidChange.js +0 -149
  304. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/layoutStyle.js +0 -602
  305. data/lib/frameworks/sproutcore/frameworks/amber/tests/views/view/render.js +0 -115
  306. data/lib/frameworks/sproutcore/frameworks/amber/views/base.js +0 -1
  307. data/lib/frameworks/sproutcore/frameworks/amber/views/view.js +0 -4003
  308. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +0 -105
@@ -0,0 +1,1280 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2011 Strobe Inc. and contributors.
4
+ // Portions ©2008-2010 Apple Inc. All rights reserved.
5
+ // License: Licensed under MIT license (see license.js)
6
+ // ==========================================================================
7
+
8
+ sc_require('system/browser');
9
+ sc_require('system/event');
10
+ sc_require('system/cursor');
11
+ sc_require('system/responder') ;
12
+ sc_require('system/theme');
13
+
14
+ sc_require('mixins/string') ;
15
+ sc_require('views/view/base') ;
16
+
17
+ /**
18
+ Default property to disable or enable by default the contextMenu
19
+ */
20
+ SC.CONTEXT_MENU_ENABLED = YES;
21
+
22
+ /**
23
+ Default property to disable or enable if the focus can jump to the address
24
+ bar or not.
25
+ */
26
+ SC.TABBING_ONLY_INSIDE_DOCUMENT = YES;
27
+
28
+ /**
29
+ Tells the property (when fetched with themed()) to get its value from the renderer (if any).
30
+ */
31
+ SC.FROM_THEME = "__FROM_THEME__"; // doesn't really matter what it is, so long as it is unique. Readability is a plus.
32
+
33
+ /** @private - custom array used for child views */
34
+ SC.EMPTY_CHILD_VIEWS_ARRAY = [];
35
+ SC.EMPTY_CHILD_VIEWS_ARRAY.needsClone = YES;
36
+
37
+ /**
38
+ @class
39
+
40
+ Base class for managing a view. Views provide two functions:
41
+
42
+ 1. They translate state and events into drawing instructions for the
43
+ web browser and
44
+
45
+ 2. They act as first responders for incoming keyboard, mouse, and
46
+ touch events.
47
+
48
+ h2. View Initialization
49
+
50
+ When a view is setup, there are several methods you can override that
51
+ will be called at different times depending on how your view is created.
52
+ Here is a guide to which method you want to override and when:
53
+
54
+ - *init:* override this method for any general object setup (such as
55
+ observers, starting timers and animations, etc) that you need to happen
56
+ everytime the view is created, regardless of whether or not its layer
57
+ exists yet.
58
+
59
+ - *render:* override this method to generate or update your HTML to reflect
60
+ the current state of your view. This method is called both when your view
61
+ is first created and later anytime it needs to be updated.
62
+
63
+ - *didCreateLayer:* the render() method is used to generate new HTML.
64
+ Override this method to perform any additional setup on the DOM you might
65
+ need to do after creating the view. For example, if you need to listen
66
+ for events.
67
+
68
+ - *willDestroyLayer:* if you implement didCreateLayer() to setup event
69
+ listeners, you should implement this method as well to remove the same
70
+ just before the DOM for your view is destroyed.
71
+
72
+ - *updateLayer:* Normally, when a view needs to update its content, it will
73
+ re-render the view using the render() method. If you would like to
74
+ override this behavior with your own custom updating code, you can
75
+ replace updateLayer() with your own implementation instead.
76
+
77
+ - *didAppendToDocument:* in theory all DOM setup could be done
78
+ in didCreateLayer() as you already have a DOM element instantiated.
79
+ However there is cases where the element has to be first appended to the
80
+ Document because there is either a bug on the browser or you are using
81
+ plugins which objects are not instantiated until you actually append the
82
+ element to the DOM. This will allow you to do things like registering
83
+ DOM events on flash or quicktime objects.
84
+
85
+ @extends SC.Responder
86
+ @extends SC.DelegateSupport
87
+ @since SproutCore 1.0
88
+ */
89
+ SC.CoreView.reopen(
90
+ /** @scope SC.View.prototype */ {
91
+
92
+ concatenatedProperties: 'outlets displayProperties classNames renderMixin didCreateLayerMixin willDestroyLayerMixin'.w(),
93
+
94
+ /**
95
+ The current pane.
96
+ @property {SC.Pane}
97
+ */
98
+ pane: function() {
99
+ var view = this ;
100
+ while (view && !view.isPane) { view = view.get('parentView') ; }
101
+ return view ;
102
+ }.property('parentView').cacheable(),
103
+
104
+ /**
105
+ The page this view was instantiated from. This is set by the page object
106
+ during instantiation.
107
+
108
+ @property {SC.Page}
109
+ */
110
+ page: null,
111
+
112
+ /**
113
+ If the view is currently inserted into the DOM of a parent view, this
114
+ property will point to the parent of the view.
115
+ */
116
+ parentView: null,
117
+
118
+ /**
119
+ The isVisible property determines if the view is shown in the view
120
+ hierarchy it is a part of. A view can have isVisible == YES and still have
121
+ isVisibleInWindow == NO. This occurs, for instance, when a parent view has
122
+ isVisible == NO. Default is YES.
123
+
124
+ The isVisible property is considered part of the layout and so changing it
125
+ will trigger a layout update.
126
+
127
+ @property {Boolean}
128
+ */
129
+ isVisible: YES,
130
+ isVisibleBindingDefault: SC.Binding.bool(),
131
+
132
+ // ..........................................................
133
+ // CHILD VIEW SUPPORT
134
+ //
135
+
136
+ /**
137
+ Array of child views. You should never edit this array directly unless
138
+ you are implementing createChildViews(). Most of the time, you should
139
+ use the accessor methods such as appendChild(), insertBefore() and
140
+ removeChild().
141
+
142
+ @property {Array}
143
+ */
144
+ childViews: SC.EMPTY_CHILD_VIEWS_ARRAY,
145
+
146
+ // ..........................................................
147
+ // LAYER SUPPORT
148
+ //
149
+
150
+ /**
151
+ Returns the current layer for the view. The layer for a view is only
152
+ generated when the view first becomes visible in the window and even
153
+ then it will not be computed until you request this layer property.
154
+
155
+ If the layer is not actually set on the view itself, then the layer will
156
+ be found by calling this.findLayerInParentLayer().
157
+
158
+ You can also set the layer by calling set on this property.
159
+
160
+ @property {DOMElement} the layer
161
+ */
162
+ layer: function(key, value) {
163
+ if (value !== undefined) {
164
+ this._view_layer = value ;
165
+
166
+ // no layer...attempt to discover it...
167
+ } else {
168
+ value = this._view_layer;
169
+ if (!value) {
170
+ var parent = this.get('parentView');
171
+ if (parent) { parent = parent.get('layer'); }
172
+ if (parent) { this._view_layer = value = this.findLayerInParentLayer(parent); }
173
+ }
174
+ }
175
+ return value ;
176
+ }.property('isVisibleInWindow').cacheable(),
177
+
178
+ /**
179
+ Get a CoreQuery object for this view's layer, or pass in a selector string
180
+ to get a CoreQuery object for a DOM node nested within this layer.
181
+
182
+ @param {String} sel a CoreQuery-compatible selector string
183
+ @returns {SC.CoreQuery} the CoreQuery object for the DOM node
184
+ */
185
+ $: function(sel) {
186
+ var layer = this.get('layer') ;
187
+
188
+ if(!layer) { return SC.$(); }
189
+ else if(sel === undefined) { return SC.$(layer); }
190
+ else { return SC.$(sel, layer); }
191
+ },
192
+
193
+ /**
194
+ Returns the DOM element that should be used to hold child views when they
195
+ are added/remove via DOM manipulation. The default implementation simply
196
+ returns the layer itself. You can override this to return a DOM element
197
+ within the layer.
198
+
199
+ @property {DOMElement} the container layer
200
+ */
201
+ containerLayer: function() {
202
+ return this.get('layer') ;
203
+ }.property('layer').cacheable(),
204
+
205
+ /**
206
+ The ID to use when trying to locate the layer in the DOM. If you do not
207
+ set the layerId explicitly, then the view's GUID will be used instead.
208
+ This ID must be set at the time the view is created.
209
+
210
+ @property {String}
211
+ @readOnly
212
+ */
213
+ layerId: function(key, value) {
214
+ if (value) { this._layerId = value; }
215
+ if (this._layerId) { return this._layerId; }
216
+ return SC.guidFor(this) ;
217
+ }.property().cacheable(),
218
+
219
+ /**
220
+ Attempts to discover the layer in the parent layer. The default
221
+ implementation looks for an element with an ID of layerId (or the view's
222
+ guid if layerId is null). You can override this method to provide your
223
+ own form of lookup. For example, if you want to discover your layer using
224
+ a CSS class name instead of an ID.
225
+
226
+ @param {DOMElement} parentLayer the parent's DOM layer
227
+ @returns {DOMElement} the discovered layer
228
+ */
229
+ findLayerInParentLayer: function(parentLayer) {
230
+ var id = "#" + this.get('layerId');
231
+ return jQuery(id)[0] || jQuery(id, parentLayer)[0] ;
232
+ },
233
+
234
+ /**
235
+ Returns YES if the receiver is a subview of a given view or if it's
236
+ identical to that view. Otherwise, it returns NO.
237
+
238
+ @property {SC.View} view
239
+ */
240
+ isDescendantOf: function(view) {
241
+ var parentView = this.get('parentView');
242
+
243
+ if(this === view) { return YES; }
244
+ else if(parentView) { return parentView.isDescendantOf(view); }
245
+ else { return NO; }
246
+ },
247
+
248
+ /**
249
+ This method is invoked whenever a display property changes. It will set
250
+ the layerNeedsUpdate method to YES. If you need to perform additional
251
+ setup whenever the display changes, you can override this method as well.
252
+
253
+ @returns {SC.View} receiver
254
+ */
255
+ displayDidChange: function() {
256
+ this.set('layerNeedsUpdate', YES) ;
257
+ return this;
258
+ },
259
+
260
+ /**
261
+ Setting this property to YES will cause the updateLayerIfNeeded method to
262
+ be invoked at the end of the runloop. You can also force a view to update
263
+ sooner by calling updateLayerIfNeeded() directly. The method will update
264
+ the layer only if this property is YES.
265
+
266
+ @property {Boolean}
267
+ @test in updateLayer
268
+ */
269
+ layerNeedsUpdate: NO,
270
+
271
+ /** @private
272
+ Schedules the updateLayerIfNeeded method to run at the end of the runloop
273
+ if layerNeedsUpdate is set to YES.
274
+ */
275
+ _view_layerNeedsUpdateDidChange: function() {
276
+ if (this.get('layerNeedsUpdate')) {
277
+ this.invokeOnce(this.updateLayerIfNeeded) ;
278
+ }
279
+ }.observes('layerNeedsUpdate'),
280
+
281
+ /**
282
+ Updates the layer only if the view is visible onscreen and if
283
+ layerNeedsUpdate is set to YES. Normally you will not invoke this method
284
+ directly. Instead you set the layerNeedsUpdate property to YES and this
285
+ method will be called once at the end of the runloop.
286
+
287
+ If you need to update view's layer sooner than the end of the runloop, you
288
+ can call this method directly. If your view is not visible in the window
289
+ but you want it to update anyway, then call this method, passing YES for
290
+ the 'skipIsVisibleInWindowCheck' parameter.
291
+
292
+ You should not override this method. Instead override updateLayer() or
293
+ render().
294
+
295
+ @returns {SC.View} receiver
296
+ @test in updateLayer
297
+ */
298
+ updateLayerIfNeeded: function(skipIsVisibleInWindowCheck) {
299
+ var needsUpdate = this.get('layerNeedsUpdate'),
300
+ shouldUpdate = needsUpdate && (skipIsVisibleInWindowCheck || this.get('isVisibleInWindow'));
301
+ if (shouldUpdate) {
302
+ // only update a layer if it already exists
303
+ if (this.get('layer')) {
304
+ this.beginPropertyChanges() ;
305
+ this.set('layerNeedsUpdate', NO) ;
306
+ this.updateLayer() ;
307
+ this.endPropertyChanges() ;
308
+ }
309
+ }
310
+
311
+ return this ;
312
+ },
313
+
314
+ /**
315
+ This is the core method invoked to update a view layer whenever it has
316
+ changed. This method simply creates a render context focused on the
317
+ layer element and then calls your render() method.
318
+
319
+ You will not usually call or override this method directly. Instead you
320
+ should set the layerNeedsUpdate property to YES to cause this method to
321
+ run at the end of the run loop, or you can call updateLayerIfNeeded()
322
+ to force the layer to update immediately.
323
+
324
+ Instead of overriding this method, consider overidding the render() method
325
+ instead, which is called both when creating and updating a layer. If you
326
+ do not want your render() method called when updating a layer, then you
327
+ should override this method instead.
328
+
329
+ @param optionalContext provided only for backwards-compatibility.
330
+
331
+ @returns {SC.View} receiver
332
+ */
333
+ updateLayer: function(optionalContext) {
334
+ var mixins, idx, len, hasLegacyRenderMethod;
335
+
336
+ var context = optionalContext || this.renderContext(this.get('layer')) ;
337
+ this._renderLayerSettings(context, NO);
338
+
339
+ // If the render method takes two parameters, we assume that it is a
340
+ // legacy implementation that takes context and firstTime. If it has only
341
+ // one parameter, we assume it is the render delegates style that requires
342
+ // only context. Note that, for backwards compatibility, the default
343
+ // SC.View implementation of render uses the old style.
344
+ hasLegacyRenderMethod = !this.update;
345
+ // Call render with firstTime set to NO to indicate an update, rather than
346
+ // full re-render, should be performed.
347
+ if (hasLegacyRenderMethod) {
348
+ this.render(context, NO);
349
+ }
350
+ else {
351
+ this.update(context.$());
352
+ }
353
+ if (mixins = this.renderMixin) {
354
+ len = mixins.length;
355
+ for(idx=0; idx<len; ++idx) { mixins[idx].call(this, context, NO) ; }
356
+ }
357
+
358
+ context.update() ;
359
+ if (context._innerHTMLReplaced) {
360
+ var pane = this.get('pane');
361
+ if(pane && pane.get('isPaneAttached')) {
362
+ this._notifyDidAppendToDocument();
363
+ }
364
+ }
365
+
366
+ // If this view uses static layout, then notify that the frame (likely)
367
+ // changed.
368
+ if (this.useStaticLayout) { this.viewDidResize(); }
369
+
370
+ if (this.didUpdateLayer) { this.didUpdateLayer(); } // call to update DOM
371
+ if(this.designer && this.designer.viewDidUpdateLayer) {
372
+ this.designer.viewDidUpdateLayer(); //let the designer know
373
+ }
374
+ return this ;
375
+ },
376
+
377
+ parentViewDidResize: function() {
378
+ this.viewDidResize();
379
+ },
380
+
381
+ /**
382
+ Override this in a child class to define behavior that should be invoked
383
+ when a parent's view was resized.
384
+ */
385
+ viewDidResize: function() {},
386
+
387
+ /**
388
+ Creates a new renderContext with the passed tagName or element. You
389
+ can override this method to provide further customization to the context
390
+ if needed. Normally you will not need to call or override this method.
391
+
392
+ @returns {SC.RenderContext}
393
+ */
394
+ renderContext: function(tagNameOrElement) {
395
+ return SC.RenderContext(tagNameOrElement) ;
396
+ },
397
+
398
+ /**
399
+ Creates the layer by creating a renderContext and invoking the view's
400
+ render() method. This will only create the layer if the layer does not
401
+ already exist.
402
+
403
+ When you create a layer, it is expected that your render() method will
404
+ also render the HTML for all child views as well. This method will
405
+ notify the view along with any of its childViews that its layer has been
406
+ created.
407
+
408
+ @returns {SC.View} receiver
409
+ */
410
+ createLayer: function() {
411
+ if (this.get('layer')) { return this ; } // nothing to do
412
+
413
+ var context = this.renderContext(this.get('tagName')) ;
414
+
415
+ // now prepare the content like normal.
416
+ this.renderToContext(context) ;
417
+ this.set('layer', context.element()) ;
418
+
419
+ // now notify the view and its child views..
420
+ this._notifyDidCreateLayer() ;
421
+
422
+ return this ;
423
+ },
424
+
425
+ /** @private -
426
+ Invokes the receivers didCreateLayer() method if it exists and then
427
+ invokes the same on all child views.
428
+ */
429
+ _notifyDidCreateLayer: function() {
430
+ this.notifyPropertyChange("layer");
431
+ if (this.didCreateLayer) { this.didCreateLayer() ; }
432
+
433
+ // and notify others
434
+ var mixins = this.didCreateLayerMixin, len, idx,
435
+ childViews = this.get('childViews'),
436
+ childView;
437
+ if (mixins) {
438
+ len = mixins.length ;
439
+ for (idx=0; idx<len; ++idx) { mixins[idx].call(this) ; }
440
+ }
441
+
442
+ len = childViews.length ;
443
+ for (idx=0; idx<len; ++idx) {
444
+ childView = childViews[idx];
445
+ if (!childView) { continue; }
446
+
447
+ // A parent view creating a layer might result in the creation of a
448
+ // child view's DOM node being created via a render context without
449
+ // createLayer() being invoked on the child. In such cases, if anyone
450
+ // had requested 'layer' and it was cached as null, we need to
451
+ // invalidate it.
452
+ childView.notifyPropertyChange('layer');
453
+
454
+ childView._notifyDidCreateLayer() ;
455
+ }
456
+ },
457
+
458
+ /**
459
+ Destroys any existing layer along with the layer for any child views as
460
+ well. If the view does not currently have a layer, then this method will
461
+ do nothing.
462
+
463
+ If you implement willDestroyLayer() on your view or if any mixins
464
+ implement willDestroLayerMixin(), then this method will be invoked on your
465
+ view before your layer is destroyed to give you a chance to clean up any
466
+ event handlers, etc.
467
+
468
+ If you write a willDestroyLayer() handler, you can assume that your
469
+ didCreateLayer() handler was called earlier for the same layer.
470
+
471
+ Normally you will not call or override this method yourself, but you may
472
+ want to implement the above callbacks when it is run.
473
+
474
+ @returns {SC.View} receiver
475
+ */
476
+ destroyLayer: function() {
477
+ var layer = this.get('layer') ;
478
+ if (layer) {
479
+
480
+ // Now notify the view and its child views. It will also set the
481
+ // layer property to null.
482
+ this._notifyWillDestroyLayer() ;
483
+
484
+ // do final cleanup
485
+ if (layer.parentNode) { layer.parentNode.removeChild(layer) ; }
486
+ layer = null ;
487
+ }
488
+ return this ;
489
+ },
490
+
491
+ /**
492
+ Destroys and recreates the current layer. This can be more efficient than
493
+ modifying individual child views.
494
+
495
+ @returns {SC.View} receiver
496
+ */
497
+ replaceLayer: function() {
498
+ this.destroyLayer();
499
+ //this.set('layerLocationNeedsUpdate', YES) ;
500
+ this.invokeOnce(this.updateLayerLocation) ;
501
+ },
502
+
503
+ /** @private -
504
+ Invokes willDestroyLayer() on view and child views. Then sets layer to
505
+ null for receiver.
506
+ */
507
+ _notifyWillDestroyLayer: function() {
508
+ if (this.willDestroyLayer) { this.willDestroyLayer() ; }
509
+ var mixins = this.willDestroyLayerMixin, len, idx,
510
+ childViews = this.get('childViews') ;
511
+ if (mixins) {
512
+ len = mixins.length ;
513
+ for (idx=0; idx<len; ++idx) { mixins[idx].call(this) ; }
514
+ }
515
+
516
+ len = childViews.length ;
517
+ for (idx=0; idx<len; ++idx) { childViews[idx]._notifyWillDestroyLayer() ; }
518
+
519
+ this.set('layer', null) ;
520
+ },
521
+
522
+
523
+
524
+ /**
525
+ @private
526
+
527
+ Renders to a context.
528
+ Rendering only happens for the initial rendering. Further updates happen in updateLayer,
529
+ and are not done to contexts, but to layers.
530
+ Note: You should not generally override nor directly call this method. This method is only
531
+ called by createLayer to set up the layer initially, and by renderChildViews, to write to
532
+ a context.
533
+
534
+ @param {SC.RenderContext} context the render context.
535
+ @param {Boolean} firstTime Provided for compatibility when rendering legacy views only.
536
+ */
537
+ renderToContext: function(context, firstTime) {
538
+ var hasLegacyRenderMethod, mixins, idx, len;
539
+
540
+ this.beginPropertyChanges() ;
541
+ this.set('layerNeedsUpdate', NO) ;
542
+
543
+ if (SC.none(firstTime)) { firstTime = YES; }
544
+
545
+ this._renderLayerSettings(context, firstTime);
546
+
547
+ // If the render method takes two parameters, we assume that it is a
548
+ // legacy implementation that takes context and firstTime. If it has only
549
+ // one parameter, we assume it is the render delegates style that requires
550
+ // only context. Note that, for backwards compatibility, the default
551
+ // SC.View implementation of render uses the old style.
552
+ hasLegacyRenderMethod = !this.update;
553
+
554
+ // Let the render method handle rendering. If we have a render delegate
555
+ // object set, it will be used there.
556
+ if (hasLegacyRenderMethod) {
557
+ this.render(context, firstTime);
558
+ }
559
+ // This view implements the render delegate protocol.
560
+ else {
561
+ if (firstTime) {
562
+ this.render(context);
563
+ } else {
564
+ this.update(context.$());
565
+ }
566
+ }
567
+
568
+ if (firstTime && !this._didRenderChildViews) { this.renderChildViews(context, firstTime); }
569
+
570
+ if (mixins = this.renderMixin) {
571
+ len = mixins.length;
572
+ for(idx=0; idx<len; ++idx) { mixins[idx].call(this, context, firstTime) ; }
573
+ }
574
+
575
+ this.endPropertyChanges() ;
576
+ },
577
+
578
+ _renderLayerSettings: function(context, firstTime) {
579
+ context.resetClassNames();
580
+ context.resetStyles();
581
+
582
+ this.applyAttributesToContext(context);
583
+ },
584
+
585
+ applyAttributesToContext: function(context) {
586
+ context.addClass(this.get('classNames'));
587
+
588
+ var cursor = this.get('cursor');
589
+ if (cursor) { context.addClass(cursor.get('className')); }
590
+
591
+ if (this.get('isTextSelectable')) { context.addClass('allow-select'); }
592
+ if (!this.get('isVisible')) { context.addClass('hidden'); }
593
+ if (this.get('isFirstResponder')) { context.addClass('focus'); }
594
+
595
+ context.id(this.get('layerId'));
596
+ context.attr('role', this.get('ariaRole'));
597
+ },
598
+
599
+ /**
600
+ @private
601
+
602
+ Invoked by createLayer() and updateLayer() to actually render a context.
603
+ This method calls the render() method on your view along with any
604
+ renderMixin() methods supplied by mixins you might have added.
605
+
606
+ You should not override this method directly. Nor should you call it. It is OLD.
607
+
608
+ @param {SC.RenderContext} context the render context
609
+ @param {Boolean} firstTime YES if this is creating a layer
610
+ @returns {void}
611
+ */
612
+ prepareContext: function(context, firstTime) {
613
+ // eventually, firstTime will be removed because it is ugly.
614
+ // for now, we will sense whether we are doing things the ugly way or not.
615
+ // if ugly, we will allow updates through.
616
+ if (firstTime !== false) { firstTime = YES; } // the GOOD code path :)
617
+
618
+ if (firstTime) {
619
+ this.renderToContext(context);
620
+ } else {
621
+ this.updateLayer(context);
622
+ }
623
+ },
624
+
625
+ /**
626
+ Your render method should invoke this method to render any child views,
627
+ especially if this is the first time the view will be rendered. This will
628
+ walk down the childView chain, rendering all of the children in a nested
629
+ way.
630
+
631
+ @param {SC.RenderContext} context the context
632
+ @param {Boolean} firstName true if the layer is being created
633
+ @returns {SC.RenderContext} the render context
634
+ @test in render
635
+ */
636
+ renderChildViews: function(context, firstTime) {
637
+ var cv = this.get('childViews'), len = cv.length, idx, view ;
638
+ for (idx=0; idx<len; ++idx) {
639
+ view = cv[idx] ;
640
+ if (!view) { continue; }
641
+ context = context.begin(view.get('tagName')) ;
642
+ view.renderToContext(context, firstTime);
643
+ context = context.end() ;
644
+ }
645
+ return context;
646
+ },
647
+
648
+ /** @private -
649
+ override to add support for theming or in your view
650
+ */
651
+ render: function() { },
652
+
653
+ /** @private -
654
+ Invokes the receivers didAppendLayerToDocument() method if it exists and
655
+ then invokes the same on all child views.
656
+ */
657
+
658
+ _notifyDidAppendToDocument: function() {
659
+ if (this.didAppendToDocument) { this.didAppendToDocument(); }
660
+
661
+ var i=0, child, childLen, children = this.get('childViews');
662
+ for(i=0, childLen=children.length; i<childLen; i++) {
663
+ child = children[i];
664
+ if(child._notifyDidAppendToDocument){
665
+ child._notifyDidAppendToDocument();
666
+ }
667
+ }
668
+ },
669
+
670
+ childViewsObserver: function(){
671
+ var childViews = this.get('childViews'), i, iLen, child;
672
+ for(i=0, iLen = childViews.length; i<iLen; i++){
673
+ child = childViews[i];
674
+ if(child._notifyDidAppendToDocument){
675
+ child._notifyDidAppendToDocument();
676
+ }
677
+ }
678
+ }.observes('childViews'),
679
+
680
+ // ..........................................................
681
+ // STANDARD RENDER PROPERTIES
682
+ //
683
+
684
+ /**
685
+ Tag name for the view's outer element. The tag name is only used when
686
+ a layer is first created. If you change the tagName for an element, you
687
+ must destroy and recreate the view layer.
688
+
689
+ @property {String}
690
+ */
691
+ tagName: 'div',
692
+
693
+ /**
694
+ The WAI-ARIA role of the control represented by this view. For example, a
695
+ button may have a role of type 'button', or a pane may have a role of
696
+ type 'alertdialog'. This property is used by assistive software to help
697
+ visually challenged users navigate rich web applications.
698
+
699
+ The full list of valid WAI-ARIA roles is available at:
700
+ http://www.w3.org/TR/wai-aria/roles#roles_categorization
701
+
702
+ @property {String}
703
+ */
704
+ ariaRole: null,
705
+
706
+ /**
707
+ Standard CSS class names to apply to the view's outer element. This
708
+ property automatically inherits any class names defined by the view's
709
+ superclasses as well.
710
+
711
+ @property {Array}
712
+ */
713
+ classNames: ['sc-view'],
714
+
715
+ /**
716
+ Tool tip property that will be set to the title attribute on the HTML
717
+ rendered element.
718
+
719
+ @property {String}
720
+ */
721
+ toolTip: null,
722
+
723
+ /**
724
+ The computed tooltip. This is generated by localizing the toolTip
725
+ property if necessary.
726
+
727
+ @property {String}
728
+ */
729
+ displayToolTip: function() {
730
+ var ret = this.get('toolTip');
731
+ return (ret && this.get('localize')) ? ret.loc() : (ret || '');
732
+ }.property('toolTip','localize').cacheable(),
733
+
734
+ /**
735
+ Determines if the user can select text within the view. Normally this is
736
+ set to NO to disable text selection. You should set this to YES if you
737
+ are creating a view that includes editable text. Otherwise, settings this
738
+ to YES will probably make your controls harder to use and it is not
739
+ recommended.
740
+
741
+ @property {Boolean}
742
+ @readOnly
743
+ */
744
+ isTextSelectable: NO,
745
+
746
+ /**
747
+ You can set this array to include any properties that should immediately
748
+ invalidate the display. The display will be automatically invalidated
749
+ when one of these properties change.
750
+
751
+ These are the properties that will be visible to any Render Delegate.
752
+ When the RenderDelegate asks for a property it needs, the view checks the
753
+ displayProperties array. It first looks for the property name prefixed
754
+ by 'display'; for instance, if the render delegate needs a 'title',
755
+ the view will attempt to find 'displayTitle'. If there is no 'displayTitle'
756
+ in displayProperties, the view will then try 'title'. If 'title' is not
757
+ in displayProperties either, an error will be thrown.
758
+
759
+ This allows you to avoid collisions between your view's API and the Render
760
+ Delegate's API.
761
+
762
+ Implementation note: 'isVisible' is also effectively a display property,
763
+ but it is not declared as such because the same effect is implemented
764
+ inside _sc_isVisibleDidChange(). This avoids having two observers on
765
+ 'isVisible', which is:
766
+ a. More efficient
767
+ b. More correct, because we can guarantee the order of operations
768
+
769
+ @property {Array}
770
+ @readOnly
771
+ */
772
+ displayProperties: ['isFirstResponder'],
773
+
774
+ // .......................................................
775
+ // SC.RESPONDER SUPPORT
776
+ //
777
+
778
+ /** @property
779
+ The nextResponder is usually the parentView.
780
+ */
781
+ nextResponder: function() {
782
+ return this.get('parentView') ;
783
+ }.property('parentView').cacheable(),
784
+
785
+
786
+ /** @property
787
+ Set to YES if your view is willing to accept first responder status. This
788
+ is used when calculcating key responder loop.
789
+ */
790
+ acceptsFirstResponder: NO,
791
+
792
+ // .......................................................
793
+ // CORE DISPLAY METHODS
794
+ //
795
+
796
+ /** @private
797
+ Setup a view, but do not finish waking it up.
798
+ - configure childViews
799
+ - Determine the view's theme
800
+ - Fetch a render delegate from the theme, if necessary
801
+ - register the view with the global views hash, which is used for event
802
+ dispatch
803
+ */
804
+ init: function() {
805
+ var parentView = this.get('parentView'),
806
+ path, root, lp, displayProperties ;
807
+
808
+ sc_super();
809
+
810
+ // Register the view for event handling. This hash is used by
811
+ // SC.RootResponder to dispatch incoming events.
812
+ SC.View.views[this.get('layerId')] = this;
813
+
814
+ // setup child views. be sure to clone the child views array first
815
+ this.childViews = this.get('childViews').slice() ;
816
+ this.createChildViews() ; // setup child Views
817
+
818
+ // register display property observers ..
819
+ // TODO: Optimize into class setup
820
+ displayProperties = this.get('displayProperties') ;
821
+ for(var i=0, l=displayProperties.length; i<l; i++) {
822
+ this.addObserver(displayProperties[i], this, this.displayDidChange);
823
+ }
824
+ },
825
+
826
+ /**
827
+ Wakes up the view. The default implementation immediately syncs any
828
+ bindings, which may cause the view to need its display updated. You
829
+ can override this method to perform any additional setup. Be sure to
830
+ call sc_super to setup bindings and to call awake on childViews.
831
+
832
+ It is best to awake a view before you add it to the DOM. This way when
833
+ the DOM is generated, it will have the correct initial values and will
834
+ not require any additional setup.
835
+
836
+ @returns {void}
837
+ */
838
+ awake: function() {
839
+ sc_super();
840
+ var childViews = this.get('childViews'), len = childViews.length, idx ;
841
+ for (idx=0; idx<len; ++idx) {
842
+ if (!childViews[idx]) { continue ; }
843
+ childViews[idx].awake() ;
844
+ }
845
+ },
846
+
847
+ /**
848
+ Removes the child view from the parent view.
849
+
850
+ @param {SC.View} view
851
+ @returns {SC.View} receiver
852
+ */
853
+ removeChild: function(view) {
854
+ // update parent node
855
+ view.set('parentView', null) ;
856
+
857
+ // remove view from childViews array.
858
+ var childViews = this.get('childViews'),
859
+ idx = childViews.indexOf(view) ;
860
+ if (idx>=0) { childViews.removeAt(idx); }
861
+
862
+ return this ;
863
+ },
864
+
865
+ /**
866
+ Removes all children from the parentView.
867
+
868
+ @returns {SC.View} receiver
869
+ */
870
+ removeAllChildren: function() {
871
+ var childViews = this.get('childViews'), view ;
872
+ while (view = childViews.objectAt(childViews.get('length')-1)) {
873
+ this.removeChild(view) ;
874
+ }
875
+ return this ;
876
+ },
877
+
878
+ /**
879
+ Removes the view from its parentView, if one is found. Otherwise
880
+ does nothing.
881
+
882
+ @returns {SC.View} receiver
883
+ */
884
+ removeFromParent: function() {
885
+ var parent = this.get('parentView') ;
886
+ if (parent) { parent.removeChild(this) ; }
887
+ return this ;
888
+ },
889
+
890
+ /**
891
+ You must call this method on a view to destroy the view (and all of its
892
+ child views). This will remove the view from any parent node, then make
893
+ sure that the DOM element managed by the view can be released by the
894
+ memory manager.
895
+ */
896
+ destroy: function() {
897
+ if (this.get('isDestroyed')) { return this; } // nothing to do
898
+
899
+ this._destroy(); // core destroy method
900
+
901
+ // remove from parent if found
902
+ if (this.get('parentView')) { this.removeFromParent(); }
903
+
904
+ //Do generic destroy. It takes care of mixins and sets isDestroyed to YES.
905
+ sc_super();
906
+ return this; // done with cleanup
907
+ },
908
+
909
+ _destroy: function() {
910
+ if (this.get('isDestroyed')) { return this ; } // nothing to do
911
+
912
+ // destroy the layer -- this will avoid each child view destroying
913
+ // the layer over and over again...
914
+ this.destroyLayer() ;
915
+
916
+ // first destroy any children.
917
+ var childViews = this.get('childViews'), len = childViews.length, idx ;
918
+ if (len) {
919
+ childViews = childViews.slice() ;
920
+ for (idx=0; idx<len; ++idx) { childViews[idx].destroy() ; }
921
+ }
922
+
923
+ // next remove view from global hash
924
+ delete SC.View.views[this.get('layerId')] ;
925
+ delete this._CQ ;
926
+ delete this.page ;
927
+
928
+ return this ;
929
+ },
930
+
931
+ /**
932
+ This method is called when your view is first created to setup any child
933
+ views that are already defined on your class. If any are found, it will
934
+ instantiate them for you.
935
+
936
+ The default implementation of this method simply steps through your
937
+ childViews array, which is expects to either be empty or to contain View
938
+ designs that can be instantiated
939
+
940
+ Alternatively, you can implement this method yourself in your own
941
+ subclasses to look for views defined on specific properties and then build
942
+ a childViews array yourself.
943
+
944
+ Note that when you implement this method yourself, you should never
945
+ instantiate views directly. Instead, you should use
946
+ this.createChildView() method instead. This method can be much faster in
947
+ a production environment than creating views yourself.
948
+
949
+ @returns {SC.View} receiver
950
+ */
951
+ createChildViews: function() {
952
+ var childViews = this.get('childViews'),
953
+ len = childViews.length,
954
+ idx, key, views, view ;
955
+
956
+ this.beginPropertyChanges() ;
957
+
958
+ // swap the array
959
+ for (idx=0; idx<len; ++idx) {
960
+ if (key = (view = childViews[idx])) {
961
+
962
+ // is this is a key name, lookup view class
963
+ if (typeof key === SC.T_STRING) {
964
+ view = this[key];
965
+ } else {
966
+ key = null ;
967
+ }
968
+
969
+ if (!view) {
970
+ console.error ("No view with name "+key+" has been found in "+this.toString());
971
+ // skip this one.
972
+ continue;
973
+ }
974
+
975
+ // createChildView creates the view if necessary, but also sets
976
+ // important properties, such as parentView
977
+ view = this.createChildView(view) ;
978
+ if (key) { this[key] = view ; } // save on key name if passed
979
+ }
980
+ childViews[idx] = view;
981
+ }
982
+
983
+ this.endPropertyChanges() ;
984
+ return this ;
985
+ },
986
+
987
+ /**
988
+ Instantiates a view to be added to the childViews array during view
989
+ initialization. You generally will not call this method directly unless
990
+ you are overriding createChildViews(). Note that this method will
991
+ automatically configure the correct settings on the new view instance to
992
+ act as a child of the parent.
993
+
994
+ @param {Class} viewClass
995
+ @param {Hash} attrs optional attributes to add
996
+ @returns {SC.View} new instance
997
+ @test in createChildViews
998
+ */
999
+ createChildView: function(view, attrs) {
1000
+ if (!view.isClass) {
1001
+ attrs = view;
1002
+ } else {
1003
+ // attrs should always exist...
1004
+ if (!attrs) { attrs = {} ; }
1005
+ // clone the hash that was given so we dont pollute it if it's being reused
1006
+ else { attrs = SC.clone(attrs); }
1007
+ }
1008
+
1009
+ attrs.owner = attrs.parentView = this ;
1010
+ attrs.isVisibleInWindow = this.get('isVisibleInWindow');
1011
+ if (!attrs.page) { attrs.page = this.page ; }
1012
+
1013
+ // Now add this to the attributes and create.
1014
+ if (view.isClass) { view = view.create(attrs); }
1015
+ return view ;
1016
+ },
1017
+
1018
+ /** walk like a duck */
1019
+ isView: YES,
1020
+
1021
+ /**
1022
+ Default method called when a selectstart event is triggered. This event is
1023
+ only supported by IE. Used in sproutcore to disable text selection and
1024
+ IE8 accelerators. The accelerators will be enabled only in
1025
+ text selectable views. In FF and Safari we use the css style 'allow-select'.
1026
+
1027
+ If you want to enable text selection in certain controls is recommended
1028
+ to override this function to always return YES , instead of setting
1029
+ isTextSelectable to true.
1030
+
1031
+ For example in textfield you dont want to enable textSelection on the text
1032
+ hint only on the actual text you are entering. You can achieve that by
1033
+ only overriding this method.
1034
+
1035
+ @param evt {SC.Event} the selectstart event
1036
+ @returns YES if selectable
1037
+ */
1038
+ selectStart: function(evt) {
1039
+ return this.get('isTextSelectable');
1040
+ },
1041
+
1042
+ /**
1043
+ Used to block the contextMenu per view.
1044
+
1045
+ @param evt {SC.Event} the contextmenu event
1046
+ @returns YES if the contextmenu can show up
1047
+ */
1048
+ contextMenu: function(evt) {
1049
+ if(!this.get('isContextMenuEnabled')) evt.stop();
1050
+ return true;
1051
+ }
1052
+
1053
+ });
1054
+
1055
+ SC.CoreView.mixin(/** @scope SC.CoreView */ {
1056
+
1057
+ /** @private walk like a duck -- used by SC.Page */
1058
+ isViewClass: YES,
1059
+
1060
+ /**
1061
+ This method works just like extend() except that it will also preserve
1062
+ the passed attributes in case you want to use a view builder later, if
1063
+ needed.
1064
+
1065
+ @param {Hash} attrs Attributes to add to view
1066
+ @returns {Class} SC.View subclass to create
1067
+ @function
1068
+ */
1069
+ design: function() {
1070
+ if (this.isDesign) { return this; } // only run design one time
1071
+ var ret = this.extend.apply(this, arguments);
1072
+ ret.isDesign = YES ;
1073
+ if (SC.ViewDesigner) {
1074
+ SC.ViewDesigner.didLoadDesign(ret, this, SC.A(arguments));
1075
+ }
1076
+ return ret ;
1077
+ },
1078
+
1079
+ extend: function() {
1080
+ var last = arguments[arguments.length - 1];
1081
+
1082
+ if (last && !SC.none(last.theme)) {
1083
+ last.themeName = last.theme;
1084
+ delete last.theme;
1085
+ }
1086
+
1087
+ return SC.Object.extend.apply(this, arguments);
1088
+ },
1089
+
1090
+ /**
1091
+ Helper applies the layout to the prototype.
1092
+ */
1093
+ layout: function(layout) {
1094
+ this.prototype.layout = layout ;
1095
+ return this ;
1096
+ },
1097
+
1098
+ /**
1099
+ Helper applies the classNames to the prototype
1100
+ */
1101
+ classNames: function(sc) {
1102
+ sc = (this.prototype.classNames || []).concat(sc);
1103
+ this.prototype.classNames = sc;
1104
+ return this ;
1105
+ },
1106
+
1107
+ /**
1108
+ Help applies the tagName
1109
+ */
1110
+ tagName: function(tg) {
1111
+ this.prototype.tagName = tg;
1112
+ return this ;
1113
+ },
1114
+
1115
+ /**
1116
+ Helper adds the childView
1117
+ */
1118
+ childView: function(cv) {
1119
+ var childViews = this.prototype.childViews || [];
1120
+ if (childViews === this.superclass.prototype.childViews) {
1121
+ childViews = childViews.slice();
1122
+ }
1123
+ childViews.push(cv) ;
1124
+ this.prototype.childViews = childViews;
1125
+ return this ;
1126
+ },
1127
+
1128
+ /**
1129
+ Helper adds a binding to a design
1130
+ */
1131
+ bind: function(keyName, path) {
1132
+ var p = this.prototype, s = this.superclass.prototype;
1133
+ var bindings = p._bindings ;
1134
+ if (!bindings || bindings === s._bindings) {
1135
+ bindings = p._bindings = (bindings || []).slice() ;
1136
+ }
1137
+
1138
+ keyName = keyName + "Binding";
1139
+ p[keyName] = path ;
1140
+ bindings.push(keyName);
1141
+
1142
+ return this ;
1143
+ },
1144
+
1145
+ /**
1146
+ Helper sets a generic property on a design.
1147
+ */
1148
+ prop: function(keyName, value) {
1149
+ this.prototype[keyName] = value;
1150
+ return this ;
1151
+ },
1152
+
1153
+ /**
1154
+ Used to construct a localization for a view. The default implementation
1155
+ will simply return the passed attributes.
1156
+ */
1157
+ localization: function(attrs, rootElement) {
1158
+ // add rootElement
1159
+ if (rootElement) attrs.rootElement = SC.$(rootElement)[0];
1160
+ return attrs;
1161
+ },
1162
+
1163
+ /**
1164
+ Creates a view instance, first finding the DOM element you name and then
1165
+ using that as the root element. You should not use this method very
1166
+ often, but it is sometimes useful if you want to attach to already
1167
+ existing HTML.
1168
+
1169
+ @param {String|Element} element
1170
+ @param {Hash} attrs
1171
+ @returns {SC.View} instance
1172
+ */
1173
+ viewFor: function(element, attrs) {
1174
+ var args = SC.$A(arguments); // prepare to edit
1175
+ if (SC.none(element)) {
1176
+ args.shift(); // remove if no element passed
1177
+ } else args[0] = { rootElement: SC.$(element)[0] } ;
1178
+ var ret = this.create.apply(this, arguments) ;
1179
+ args = args[0] = null;
1180
+ return ret ;
1181
+ },
1182
+
1183
+ /**
1184
+ Create a new view with the passed attributes hash. If you have the
1185
+ Designer module loaded, this will also create a peer designer if needed.
1186
+ */
1187
+ create: function() {
1188
+ var last = arguments[arguments.length - 1];
1189
+
1190
+ if (last && last.theme) {
1191
+ last.themeName = last.theme;
1192
+ delete last.theme;
1193
+ }
1194
+
1195
+ var C=this, ret = new C(arguments);
1196
+ if (SC.ViewDesigner) {
1197
+ SC.ViewDesigner.didCreateView(ret, SC.$A(arguments));
1198
+ }
1199
+ return ret ;
1200
+ },
1201
+
1202
+ /**
1203
+ Applies the passed localization hash to the component views. Call this
1204
+ method before you call create(). Returns the receiver. Typically you
1205
+ will do something like this:
1206
+
1207
+ view = SC.View.design({...}).loc(localizationHash).create();
1208
+
1209
+ @param {Hash} loc
1210
+ @param rootElement {String} optional rootElement with prepped HTML
1211
+ @returns {SC.View} receiver
1212
+ */
1213
+ loc: function(loc) {
1214
+ var childLocs = loc.childViews;
1215
+ delete loc.childViews; // clear out child views before applying to attrs
1216
+
1217
+ this.applyLocalizedAttributes(loc) ;
1218
+ if (SC.ViewDesigner) {
1219
+ SC.ViewDesigner.didLoadLocalization(this, SC.$A(arguments));
1220
+ }
1221
+
1222
+ // apply localization recursively to childViews
1223
+ var childViews = this.prototype.childViews, idx = childViews.length,
1224
+ viewClass;
1225
+ while(--idx>=0) {
1226
+ viewClass = childViews[idx];
1227
+ loc = childLocs[idx];
1228
+ if (loc && viewClass && viewClass.loc) viewClass.loc(loc) ;
1229
+ }
1230
+
1231
+ return this; // done!
1232
+ },
1233
+
1234
+ /**
1235
+ Internal method actually updates the localizated attributes on the view
1236
+ class. This is overloaded in design mode to also save the attributes.
1237
+ */
1238
+ applyLocalizedAttributes: function(loc) {
1239
+ SC.mixin(this.prototype, loc) ;
1240
+ },
1241
+
1242
+ views: {}
1243
+
1244
+ }) ;
1245
+
1246
+ // .......................................................
1247
+ // OUTLET BUILDER
1248
+ //
1249
+
1250
+ /**
1251
+ Generates a computed property that will look up the passed property path
1252
+ the first time you try to get the value. Use this whenever you want to
1253
+ define an outlet that points to another view or object. The root object
1254
+ used for the path will be the receiver.
1255
+ */
1256
+ SC.outlet = function(path, root) {
1257
+ return function(key) {
1258
+ return (this[key] = SC.objectForPropertyPath(path, (root !== undefined) ? root : this)) ;
1259
+ }.property();
1260
+ };
1261
+
1262
+ /** @private on unload clear cached divs. */
1263
+ SC.CoreView.unload = function() {
1264
+ // delete view items this way to ensure the views are cleared. The hash
1265
+ // itself may be owned by multiple view subclasses.
1266
+ var views = SC.View.views;
1267
+ if (views) {
1268
+ for(var key in views) {
1269
+ if (!views.hasOwnProperty(key)) continue ;
1270
+ delete views[key];
1271
+ }
1272
+ }
1273
+ } ;
1274
+
1275
+ SC.View = SC.CoreView.extend({});
1276
+
1277
+ //unload views for IE, trying to collect memory.
1278
+ if(SC.browser.msie) SC.Event.add(window, 'unload', SC.View, SC.View.unload) ;
1279
+
1280
+