sproutit-sproutcore 1.0.20090721145236 → 1.0.20090721145251

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 (933) hide show
  1. data/Rakefile +189 -54
  2. data/VERSION.yml +5 -0
  3. data/frameworks/sproutcore/Buildfile +64 -0
  4. data/frameworks/sproutcore/HISTORY +682 -0
  5. data/frameworks/sproutcore/README +23 -0
  6. data/frameworks/sproutcore/apps/docs/core.js +27 -0
  7. data/frameworks/sproutcore/apps/docs/english.lproj/loading.rhtml +9 -0
  8. data/frameworks/sproutcore/apps/docs/english.lproj/main_page.js +22 -0
  9. data/frameworks/sproutcore/apps/docs/english.lproj/strings.js +15 -0
  10. data/frameworks/sproutcore/apps/docs/main.js +30 -0
  11. data/frameworks/sproutcore/apps/tests/controllers/detail.js +16 -0
  12. data/frameworks/sproutcore/apps/tests/controllers/source.js +29 -0
  13. data/frameworks/sproutcore/apps/tests/controllers/target.js +26 -0
  14. data/frameworks/sproutcore/apps/tests/controllers/targets.js +86 -0
  15. data/frameworks/sproutcore/apps/tests/controllers/tests.js +33 -0
  16. data/frameworks/sproutcore/apps/tests/core.js +133 -0
  17. data/frameworks/sproutcore/apps/tests/data_source.js +96 -0
  18. data/frameworks/sproutcore/apps/tests/english.lproj/loading.rhtml +9 -0
  19. data/frameworks/sproutcore/apps/tests/english.lproj/main_page.css +39 -0
  20. data/frameworks/sproutcore/apps/tests/english.lproj/main_page.js +232 -0
  21. data/frameworks/sproutcore/apps/tests/english.lproj/strings.js +26 -0
  22. data/frameworks/sproutcore/apps/tests/fixtures/target.js +87 -0
  23. data/frameworks/sproutcore/apps/tests/fixtures/test.js +44 -0
  24. data/frameworks/sproutcore/apps/tests/main.js +28 -0
  25. data/frameworks/sproutcore/apps/tests/models/target.js +92 -0
  26. data/frameworks/sproutcore/apps/tests/models/test.js +48 -0
  27. data/frameworks/sproutcore/apps/tests/states/no_targets.js +26 -0
  28. data/frameworks/sproutcore/apps/tests/states/ready.js +56 -0
  29. data/frameworks/sproutcore/apps/tests/states/ready_detail.js +41 -0
  30. data/frameworks/sproutcore/apps/tests/states/ready_empty.js +48 -0
  31. data/frameworks/sproutcore/apps/tests/states/ready_list.js +41 -0
  32. data/frameworks/sproutcore/apps/tests/states/ready_loading.js +44 -0
  33. data/frameworks/sproutcore/apps/tests/states/ready_no_tests.js +31 -0
  34. data/frameworks/sproutcore/apps/tests/states/start.js +39 -0
  35. data/frameworks/sproutcore/apps/tests/tests/controllers/detail.js +15 -0
  36. data/frameworks/sproutcore/apps/tests/tests/controllers/source.js +15 -0
  37. data/frameworks/sproutcore/apps/tests/tests/controllers/target.js +15 -0
  38. data/frameworks/sproutcore/apps/tests/tests/controllers/targets.js +15 -0
  39. data/frameworks/sproutcore/apps/tests/tests/controllers/tests.js +15 -0
  40. data/frameworks/sproutcore/apps/tests/tests/models/target.js +15 -0
  41. data/frameworks/sproutcore/apps/tests/tests/models/test.js +15 -0
  42. data/frameworks/sproutcore/apps/tests/tests/views/offset_checkbox.js +15 -0
  43. data/frameworks/sproutcore/apps/tests/views/offset_checkbox.js +26 -0
  44. data/frameworks/sproutcore/apps/welcome/core.js +23 -0
  45. data/frameworks/sproutcore/apps/welcome/english.lproj/loading.rhtml +8 -0
  46. data/frameworks/sproutcore/apps/welcome/english.lproj/main_page.js +43 -0
  47. data/frameworks/sproutcore/apps/welcome/english.lproj/strings.js +15 -0
  48. data/frameworks/sproutcore/apps/welcome/main.js +36 -0
  49. data/frameworks/sproutcore/design/Record State Table.numbers +0 -0
  50. data/frameworks/sproutcore/frameworks/datastore/core.js +14 -0
  51. data/frameworks/sproutcore/frameworks/datastore/data_sources/cascade.js +113 -0
  52. data/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +273 -0
  53. data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +311 -0
  54. data/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures_with_queries.js +238 -0
  55. data/frameworks/sproutcore/frameworks/datastore/debug/json.js +71 -0
  56. data/frameworks/sproutcore/frameworks/datastore/debug/standard_setup.js +96 -0
  57. data/frameworks/sproutcore/frameworks/datastore/fixtures/author_fixtures.js +2503 -0
  58. data/frameworks/sproutcore/frameworks/datastore/fixtures/sample.js +17 -0
  59. data/frameworks/sproutcore/frameworks/datastore/models/fetched_attribute.js +92 -0
  60. data/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +54 -0
  61. data/frameworks/sproutcore/frameworks/datastore/models/record.js +561 -0
  62. data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +423 -0
  63. data/frameworks/sproutcore/frameworks/datastore/system/many_array.js +158 -0
  64. data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +488 -0
  65. data/frameworks/sproutcore/frameworks/datastore/system/query.js +979 -0
  66. data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +287 -0
  67. data/frameworks/sproutcore/frameworks/datastore/system/store.js +2007 -0
  68. data/frameworks/sproutcore/frameworks/datastore/tests/data_sources/fixtures.js +121 -0
  69. data/frameworks/sproutcore/frameworks/datastore/tests/integration/contact_model.js +114 -0
  70. data/frameworks/sproutcore/frameworks/datastore/tests/integration/mail_model.js +91 -0
  71. data/frameworks/sproutcore/frameworks/datastore/tests/integration/test_runner_model.js +56 -0
  72. data/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +94 -0
  73. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +30 -0
  74. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +73 -0
  75. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +238 -0
  76. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/readAttribute.js +48 -0
  77. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/refresh.js +42 -0
  78. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/storeDidChangeProperties.js +138 -0
  79. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/unknownProperty.js +46 -0
  80. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +71 -0
  81. data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +204 -0
  82. data/frameworks/sproutcore/frameworks/datastore/tests/system/many_array/core_methods.js +178 -0
  83. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +40 -0
  84. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +117 -0
  85. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +135 -0
  86. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/dataHashDidChange.js +110 -0
  87. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/discardChanges.js +99 -0
  88. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readDataHash.js +180 -0
  89. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/readEditableDataHash.js +126 -0
  90. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/removeDataHash.js +163 -0
  91. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/writeDataHash.js +166 -0
  92. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/compare_records.js +126 -0
  93. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/evaluation.js +165 -0
  94. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/evaluation_of_records.js +82 -0
  95. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/find_all.js +362 -0
  96. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/parsing.js +170 -0
  97. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/record_type_is.js +43 -0
  98. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_comparisons.js +60 -0
  99. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_query_extensions.js +67 -0
  100. data/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/core_methods.js +164 -0
  101. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/cancelRecord.js +54 -0
  102. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +126 -0
  103. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +126 -0
  104. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +73 -0
  105. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/createRecord.js +72 -0
  106. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataHashDidChange.js +78 -0
  107. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataSourceCallbacks.js +249 -0
  108. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/destroyRecord.js +106 -0
  109. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/init.js +21 -0
  110. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushChanges.js +61 -0
  111. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/readDataHash.js +74 -0
  112. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/readEditableDataHash.js +74 -0
  113. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +74 -0
  114. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/removeDataHash.js +144 -0
  115. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/retrieveRecord.js +137 -0
  116. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/writeDataHash.js +130 -0
  117. data/frameworks/sproutcore/frameworks/debug/core.js +61 -0
  118. data/frameworks/sproutcore/frameworks/deprecated/core.js +59 -0
  119. data/frameworks/sproutcore/frameworks/deprecated/lib/button_views.rb +330 -0
  120. data/frameworks/sproutcore/frameworks/deprecated/lib/collection_view.rb +83 -0
  121. data/frameworks/sproutcore/frameworks/deprecated/lib/core_views.rb +326 -0
  122. data/frameworks/sproutcore/frameworks/deprecated/lib/form_views.rb +253 -0
  123. data/frameworks/sproutcore/frameworks/deprecated/lib/index.rhtml +75 -0
  124. data/frameworks/sproutcore/frameworks/deprecated/lib/menu_views.rb +93 -0
  125. data/frameworks/sproutcore/frameworks/deprecated/server/rails_server.js +80 -0
  126. data/frameworks/sproutcore/frameworks/deprecated/server/rest_server.js +178 -0
  127. data/frameworks/sproutcore/frameworks/deprecated/server/server.js +673 -0
  128. data/frameworks/sproutcore/frameworks/deprecated/system/animator.js +679 -0
  129. data/frameworks/sproutcore/frameworks/deprecated/system/binding.js +36 -0
  130. data/frameworks/sproutcore/frameworks/deprecated/system/browser.js +75 -0
  131. data/frameworks/sproutcore/frameworks/deprecated/system/classic_responder.js +312 -0
  132. data/frameworks/sproutcore/frameworks/deprecated/system/event.js +58 -0
  133. data/frameworks/sproutcore/frameworks/deprecated/system/globals.js +20 -0
  134. data/frameworks/sproutcore/frameworks/deprecated/system/misc.js +58 -0
  135. data/frameworks/sproutcore/frameworks/deprecated/system/node_descriptor.js +72 -0
  136. data/frameworks/sproutcore/frameworks/deprecated/system/object.js +122 -0
  137. data/frameworks/sproutcore/frameworks/deprecated/system/path_module.js +432 -0
  138. data/frameworks/sproutcore/frameworks/deprecated/system/string.js +107 -0
  139. data/frameworks/sproutcore/frameworks/deprecated/tests/application/application.rhtml +125 -0
  140. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/clippingFrame.rhtml +401 -0
  141. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/frame.rhtml +357 -0
  142. data/frameworks/sproutcore/frameworks/deprecated/tests/views/classic_view/isVisibleInWindow.rhtml +147 -0
  143. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/base.rhtml +298 -0
  144. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/incremental_rendering.rhtml +260 -0
  145. data/frameworks/sproutcore/frameworks/deprecated/tests/views/collection/source_list_rendering.rhtml +143 -0
  146. data/frameworks/sproutcore/frameworks/deprecated/tests/views/popup_button.rhtml +128 -0
  147. data/frameworks/sproutcore/frameworks/deprecated/tests/views/text_field.rhtml +37 -0
  148. data/frameworks/sproutcore/frameworks/deprecated/views/collection.js +24 -0
  149. data/frameworks/sproutcore/frameworks/designer/coders/design.js +29 -0
  150. data/frameworks/sproutcore/frameworks/designer/coders/localization.js +27 -0
  151. data/frameworks/sproutcore/frameworks/designer/coders/object.js +347 -0
  152. data/frameworks/sproutcore/frameworks/designer/controllers/page_design.js +102 -0
  153. data/frameworks/sproutcore/frameworks/designer/css/css_rule.js +22 -0
  154. data/frameworks/sproutcore/frameworks/designer/css/css_style.js +29 -0
  155. data/frameworks/sproutcore/frameworks/designer/css/css_style_sheet.js +201 -0
  156. data/frameworks/sproutcore/frameworks/designer/ext/page.js +86 -0
  157. data/frameworks/sproutcore/frameworks/designer/ext/view.js +38 -0
  158. data/frameworks/sproutcore/frameworks/designer/views/controls/button.js +17 -0
  159. data/frameworks/sproutcore/frameworks/designer/views/designer.js +569 -0
  160. data/frameworks/sproutcore/frameworks/designer/views/label.js +16 -0
  161. data/frameworks/sproutcore/frameworks/designer/views/mixins/button.js +11 -0
  162. data/frameworks/sproutcore/frameworks/designer/views/tab.js +16 -0
  163. data/frameworks/sproutcore/frameworks/desktop/core.js +6 -0
  164. data/frameworks/sproutcore/frameworks/desktop/debug/drag.js +41 -0
  165. data/frameworks/sproutcore/frameworks/desktop/english.lproj/alert.css +56 -0
  166. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/a_sample_image.jpg +0 -0
  167. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/apple-logo1.jpeg +0 -0
  168. data/frameworks/sproutcore/frameworks/desktop/english.lproj/debug/iframe.html +23 -0
  169. data/frameworks/sproutcore/frameworks/desktop/english.lproj/disclosure.css +71 -0
  170. data/frameworks/sproutcore/frameworks/desktop/english.lproj/drag.css +6 -0
  171. data/frameworks/sproutcore/frameworks/desktop/english.lproj/icons.css +943 -0
  172. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_222222.png +0 -0
  173. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_454545.png +0 -0
  174. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_888888.png +0 -0
  175. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/mini_ffffff.png +0 -0
  176. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/icons/shared.png +0 -0
  177. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/indicator.gif +0 -0
  178. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/panels/sprite-x.png +0 -0
  179. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/panels/sprite-y.png +0 -0
  180. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sc-theme-sprite.png +0 -0
  181. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/standard_fade/000000.png +0 -0
  182. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/standard_fade/ffffff.png +0 -0
  183. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sticky-note.png +0 -0
  184. data/frameworks/sproutcore/frameworks/desktop/english.lproj/list_item.css +209 -0
  185. data/frameworks/sproutcore/frameworks/desktop/english.lproj/menu_item_view.css +100 -0
  186. data/frameworks/sproutcore/frameworks/desktop/english.lproj/modal.css +5 -0
  187. data/frameworks/sproutcore/frameworks/desktop/english.lproj/panel.css +95 -0
  188. data/frameworks/sproutcore/frameworks/desktop/english.lproj/picker.css +39 -0
  189. data/frameworks/sproutcore/frameworks/desktop/english.lproj/progress.css +31 -0
  190. data/frameworks/sproutcore/frameworks/desktop/english.lproj/radio.css +10 -0
  191. data/frameworks/sproutcore/frameworks/desktop/english.lproj/scroller.css +26 -0
  192. data/frameworks/sproutcore/frameworks/desktop/english.lproj/segmented.css +141 -0
  193. data/frameworks/sproutcore/frameworks/desktop/english.lproj/separator.css +19 -0
  194. data/frameworks/sproutcore/frameworks/desktop/english.lproj/slider.css +62 -0
  195. data/frameworks/sproutcore/frameworks/desktop/english.lproj/split.css +70 -0
  196. data/frameworks/sproutcore/frameworks/desktop/english.lproj/split_divider.css +9 -0
  197. data/frameworks/sproutcore/frameworks/desktop/english.lproj/strings.js +14 -0
  198. data/frameworks/sproutcore/frameworks/desktop/english.lproj/tab.css +12 -0
  199. data/frameworks/sproutcore/frameworks/desktop/english.lproj/toolbar.css +6 -0
  200. data/frameworks/sproutcore/frameworks/desktop/mixins/border.js +53 -0
  201. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_group.js +22 -0
  202. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_row_delegate.js +61 -0
  203. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +283 -0
  204. data/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +247 -0
  205. data/frameworks/sproutcore/frameworks/desktop/panes/alert.js +408 -0
  206. data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +651 -0
  207. data/frameworks/sproutcore/frameworks/desktop/panes/modal.js +68 -0
  208. data/frameworks/sproutcore/frameworks/desktop/panes/palette.js +63 -0
  209. data/frameworks/sproutcore/frameworks/desktop/panes/panel.js +184 -0
  210. data/frameworks/sproutcore/frameworks/desktop/panes/picker.js +400 -0
  211. data/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +46 -0
  212. data/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +39 -0
  213. data/frameworks/sproutcore/frameworks/desktop/protocols/drag_source.js +81 -0
  214. data/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +175 -0
  215. data/frameworks/sproutcore/frameworks/desktop/protocols/responder.js +280 -0
  216. data/frameworks/sproutcore/frameworks/desktop/system/drag.js +827 -0
  217. data/frameworks/sproutcore/frameworks/desktop/system/key_bindings.js +40 -0
  218. data/frameworks/sproutcore/frameworks/desktop/system/root_responder.js +641 -0
  219. data/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +187 -0
  220. data/frameworks/sproutcore/frameworks/desktop/tests/integration/dialog.js +43 -0
  221. data/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/methods.js +10 -0
  222. data/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +152 -0
  223. data/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/methods.js +55 -0
  224. data/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +59 -0
  225. data/frameworks/sproutcore/frameworks/desktop/tests/panes/palette/methods.js +10 -0
  226. data/frameworks/sproutcore/frameworks/desktop/tests/panes/palette/ui.js +35 -0
  227. data/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +10 -0
  228. data/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +40 -0
  229. data/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/methods.js +10 -0
  230. data/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +84 -0
  231. data/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/methods.js +10 -0
  232. data/frameworks/sproutcore/frameworks/desktop/tests/panes/sheet/ui.js +38 -0
  233. data/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +45 -0
  234. data/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +159 -0
  235. data/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +144 -0
  236. data/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/ui.js +99 -0
  237. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/content.js +249 -0
  238. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/deleteSelection.js +82 -0
  239. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/deselect.js +199 -0
  240. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/itemViewForContentIndex.js +288 -0
  241. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/layerIdFor.js +65 -0
  242. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/length.js +88 -0
  243. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +165 -0
  244. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/nowShowing.js +121 -0
  245. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/reload.js +177 -0
  246. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/select.js +240 -0
  247. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selectNextItem.js +191 -0
  248. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selectPreviousItem.js +197 -0
  249. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selection.js +141 -0
  250. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/ui_diagram.js +182 -0
  251. data/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/methods.js +10 -0
  252. data/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/ui.js +64 -0
  253. data/frameworks/sproutcore/frameworks/desktop/tests/views/grid/methods.js +10 -0
  254. data/frameworks/sproutcore/frameworks/desktop/tests/views/grid/ui.js +10 -0
  255. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowDelegate.js +183 -0
  256. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowHeightForContentIndex.js +133 -0
  257. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowOffsetForContentIndex.js +132 -0
  258. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_outline.js +56 -0
  259. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_row_heights.js +167 -0
  260. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_simple.js +127 -0
  261. data/frameworks/sproutcore/frameworks/desktop/tests/views/list_item.js +284 -0
  262. data/frameworks/sproutcore/frameworks/desktop/tests/views/menu_item/methods.js +10 -0
  263. data/frameworks/sproutcore/frameworks/desktop/tests/views/menu_item/ui.js +44 -0
  264. data/frameworks/sproutcore/frameworks/desktop/tests/views/progress/methods.js +128 -0
  265. data/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +240 -0
  266. data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +113 -0
  267. data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +202 -0
  268. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +139 -0
  269. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +111 -0
  270. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroller/methods.js +102 -0
  271. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroller/ui.js +70 -0
  272. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +95 -0
  273. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +222 -0
  274. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +81 -0
  275. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +100 -0
  276. data/frameworks/sproutcore/frameworks/desktop/tests/views/separator.js +37 -0
  277. data/frameworks/sproutcore/frameworks/desktop/tests/views/source_list/methods.js +10 -0
  278. data/frameworks/sproutcore/frameworks/desktop/tests/views/source_list/ui.js +10 -0
  279. data/frameworks/sproutcore/frameworks/desktop/tests/views/split/methods.js +50 -0
  280. data/frameworks/sproutcore/frameworks/desktop/tests/views/split/ui.js +52 -0
  281. data/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +231 -0
  282. data/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +54 -0
  283. data/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +88 -0
  284. data/frameworks/sproutcore/frameworks/desktop/tests/views/web/methods.js +10 -0
  285. data/frameworks/sproutcore/frameworks/desktop/tests/views/web/ui.js +110 -0
  286. data/frameworks/sproutcore/frameworks/desktop/views/button.js +331 -0
  287. data/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +105 -0
  288. data/frameworks/sproutcore/frameworks/desktop/views/collection.js +2757 -0
  289. data/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +44 -0
  290. data/frameworks/sproutcore/frameworks/desktop/views/form.js +594 -0
  291. data/frameworks/sproutcore/frameworks/desktop/views/grid.js +201 -0
  292. data/frameworks/sproutcore/frameworks/desktop/views/list.js +540 -0
  293. data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +660 -0
  294. data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +587 -0
  295. data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +68 -0
  296. data/frameworks/sproutcore/frameworks/desktop/views/progress.js +207 -0
  297. data/frameworks/sproutcore/frameworks/desktop/views/radio.js +332 -0
  298. data/frameworks/sproutcore/frameworks/desktop/views/scene.js +204 -0
  299. data/frameworks/sproutcore/frameworks/desktop/views/scroll.js +690 -0
  300. data/frameworks/sproutcore/frameworks/desktop/views/scroller.js +226 -0
  301. data/frameworks/sproutcore/frameworks/desktop/views/segmented.js +525 -0
  302. data/frameworks/sproutcore/frameworks/desktop/views/select_field.js +331 -0
  303. data/frameworks/sproutcore/frameworks/desktop/views/separator.js +37 -0
  304. data/frameworks/sproutcore/frameworks/desktop/views/slider.js +180 -0
  305. data/frameworks/sproutcore/frameworks/desktop/views/source_list.js +47 -0
  306. data/frameworks/sproutcore/frameworks/desktop/views/source_list_group.js +169 -0
  307. data/frameworks/sproutcore/frameworks/desktop/views/split.js +677 -0
  308. data/frameworks/sproutcore/frameworks/desktop/views/split_divider.js +55 -0
  309. data/frameworks/sproutcore/frameworks/desktop/views/stacked.js +101 -0
  310. data/frameworks/sproutcore/frameworks/desktop/views/tab.js +191 -0
  311. data/frameworks/sproutcore/frameworks/desktop/views/thumb.js +49 -0
  312. data/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +49 -0
  313. data/frameworks/sproutcore/frameworks/desktop/views/web.js +86 -0
  314. data/frameworks/sproutcore/frameworks/foundation/TESTING +46 -0
  315. data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +509 -0
  316. data/frameworks/sproutcore/frameworks/foundation/controllers/controller.js +45 -0
  317. data/frameworks/sproutcore/frameworks/foundation/controllers/object.js +323 -0
  318. data/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +109 -0
  319. data/frameworks/sproutcore/frameworks/foundation/core.js +136 -0
  320. data/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +194 -0
  321. data/frameworks/sproutcore/frameworks/foundation/english.lproj/blank.gif +0 -0
  322. data/frameworks/sproutcore/frameworks/foundation/english.lproj/bootstrap.rhtml +68 -0
  323. data/frameworks/sproutcore/frameworks/foundation/english.lproj/button_view.css +55 -0
  324. data/frameworks/sproutcore/frameworks/foundation/english.lproj/core.css +221 -0
  325. data/frameworks/sproutcore/frameworks/foundation/english.lproj/debug/control-test-pane.css +9 -0
  326. data/frameworks/sproutcore/frameworks/foundation/english.lproj/images/sproutcore-logo.png +0 -0
  327. data/frameworks/sproutcore/frameworks/foundation/english.lproj/label.css +30 -0
  328. data/frameworks/sproutcore/frameworks/foundation/english.lproj/static_layout.css +5 -0
  329. data/frameworks/sproutcore/frameworks/foundation/english.lproj/strings.js +15 -0
  330. data/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +45 -0
  331. data/frameworks/sproutcore/frameworks/foundation/english.lproj/view.css +45 -0
  332. data/frameworks/sproutcore/frameworks/foundation/ext/object.js +81 -0
  333. data/frameworks/sproutcore/frameworks/foundation/ext/run_loop.js +158 -0
  334. data/frameworks/sproutcore/frameworks/foundation/fixtures/file_exists.json +1 -0
  335. data/frameworks/sproutcore/frameworks/foundation/license.js +19 -0
  336. data/frameworks/sproutcore/frameworks/foundation/mixins/button.js +299 -0
  337. data/frameworks/sproutcore/frameworks/foundation/mixins/collection_content.js +171 -0
  338. data/frameworks/sproutcore/frameworks/foundation/mixins/content_display.js +88 -0
  339. data/frameworks/sproutcore/frameworks/foundation/mixins/control.js +352 -0
  340. data/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +146 -0
  341. data/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +462 -0
  342. data/frameworks/sproutcore/frameworks/foundation/mixins/selection_support.js +232 -0
  343. data/frameworks/sproutcore/frameworks/foundation/mixins/static_layout.js +132 -0
  344. data/frameworks/sproutcore/frameworks/foundation/mixins/string.js +251 -0
  345. data/frameworks/sproutcore/frameworks/foundation/mixins/tree_item_content.js +159 -0
  346. data/frameworks/sproutcore/frameworks/foundation/mixins/validatable.js +176 -0
  347. data/frameworks/sproutcore/frameworks/foundation/panes/main.js +47 -0
  348. data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +584 -0
  349. data/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +887 -0
  350. data/frameworks/sproutcore/frameworks/foundation/protocols/inline_editor_delegate.js +84 -0
  351. data/frameworks/sproutcore/frameworks/foundation/system/application.js +36 -0
  352. data/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +492 -0
  353. data/frameworks/sproutcore/frameworks/foundation/system/browser.js +64 -0
  354. data/frameworks/sproutcore/frameworks/foundation/system/builder.js +210 -0
  355. data/frameworks/sproutcore/frameworks/foundation/system/core_query.js +2015 -0
  356. data/frameworks/sproutcore/frameworks/foundation/system/cursor.js +129 -0
  357. data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +729 -0
  358. data/frameworks/sproutcore/frameworks/foundation/system/error.js +93 -0
  359. data/frameworks/sproutcore/frameworks/foundation/system/event.js +853 -0
  360. data/frameworks/sproutcore/frameworks/foundation/system/image_cache.js +433 -0
  361. data/frameworks/sproutcore/frameworks/foundation/system/json.js +440 -0
  362. data/frameworks/sproutcore/frameworks/foundation/system/locale.js +288 -0
  363. data/frameworks/sproutcore/frameworks/foundation/system/page.js +106 -0
  364. data/frameworks/sproutcore/frameworks/foundation/system/ready.js +195 -0
  365. data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +904 -0
  366. data/frameworks/sproutcore/frameworks/foundation/system/request.js +380 -0
  367. data/frameworks/sproutcore/frameworks/foundation/system/responder.js +120 -0
  368. data/frameworks/sproutcore/frameworks/foundation/system/responder_context.js +243 -0
  369. data/frameworks/sproutcore/frameworks/foundation/system/root_responder.js +391 -0
  370. data/frameworks/sproutcore/frameworks/foundation/system/routes.js +487 -0
  371. data/frameworks/sproutcore/frameworks/foundation/system/time.js +478 -0
  372. data/frameworks/sproutcore/frameworks/foundation/system/timer.js +549 -0
  373. data/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +165 -0
  374. data/frameworks/sproutcore/frameworks/foundation/system/utils.js +425 -0
  375. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/array_case.js +182 -0
  376. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/enum_case.js +193 -0
  377. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/null_case.js +64 -0
  378. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/single_case.js +136 -0
  379. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/object/empty_case.js +82 -0
  380. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/object/multiple_case.js +111 -0
  381. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/object/single_case.js +193 -0
  382. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/object/single_enumerable_case.js +179 -0
  383. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/tree/outline_case.js +108 -0
  384. data/frameworks/sproutcore/frameworks/foundation/tests/debug/control_test_pane/methods.js +10 -0
  385. data/frameworks/sproutcore/frameworks/foundation/tests/debug/control_test_pane/ui.js +113 -0
  386. data/frameworks/sproutcore/frameworks/foundation/tests/integration/creating_views.js +113 -0
  387. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/content.js +195 -0
  388. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/displayProperties.js +89 -0
  389. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/keyEquivalents.js +35 -0
  390. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/control/content.js +168 -0
  391. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/control/displayProperties.js +89 -0
  392. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/staticLayout.js +128 -0
  393. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/string.js +17 -0
  394. data/frameworks/sproutcore/frameworks/foundation/tests/private/tree_item_observer/flat_case.js +325 -0
  395. data/frameworks/sproutcore/frameworks/foundation/tests/private/tree_item_observer/group_case.js +718 -0
  396. data/frameworks/sproutcore/frameworks/foundation/tests/private/tree_item_observer/outline_case.js +484 -0
  397. data/frameworks/sproutcore/frameworks/foundation/tests/system/builder.js +42 -0
  398. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_core.js +1323 -0
  399. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_dimensions.js +387 -0
  400. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_selector.js +405 -0
  401. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/setClass.js +49 -0
  402. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/within.js +66 -0
  403. data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +151 -0
  404. data/frameworks/sproutcore/frameworks/foundation/tests/system/error.js +41 -0
  405. data/frameworks/sproutcore/frameworks/foundation/tests/system/json.js +14 -0
  406. data/frameworks/sproutcore/frameworks/foundation/tests/system/locale.js +128 -0
  407. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/begin.js +47 -0
  408. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/element.js +44 -0
  409. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/end.js +119 -0
  410. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/get.js +51 -0
  411. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_attr.js +50 -0
  412. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_basic.js +28 -0
  413. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_className.js +179 -0
  414. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/helpers_style.js +100 -0
  415. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/init.js +55 -0
  416. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/join.js +28 -0
  417. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/push_text.js +74 -0
  418. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/tag.js +45 -0
  419. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/update.js +205 -0
  420. data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +127 -0
  421. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/makeKeyPane.js +124 -0
  422. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/makeMainPane.js +68 -0
  423. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/root_responder.js +101 -0
  424. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/targetForAction.js +238 -0
  425. data/frameworks/sproutcore/frameworks/foundation/tests/system/routes.js +33 -0
  426. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/invalidate.js +38 -0
  427. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/invokeLater.js +201 -0
  428. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/isPaused.js +71 -0
  429. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/performAction.js +67 -0
  430. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/schedule.js +170 -0
  431. data/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +27 -0
  432. data/frameworks/sproutcore/frameworks/foundation/tests/system/utils/normalizeURL.js +18 -0
  433. data/frameworks/sproutcore/frameworks/foundation/tests/system/utils/range.js +62 -0
  434. data/frameworks/sproutcore/frameworks/foundation/tests/validators/credit_card.js +35 -0
  435. data/frameworks/sproutcore/frameworks/foundation/tests/validators/date.js +23 -0
  436. data/frameworks/sproutcore/frameworks/foundation/tests/validators/number.js +47 -0
  437. data/frameworks/sproutcore/frameworks/foundation/tests/validators/password.js +13 -0
  438. data/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +10 -0
  439. data/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +83 -0
  440. data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +39 -0
  441. data/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +148 -0
  442. data/frameworks/sproutcore/frameworks/foundation/tests/views/main_pane.js +31 -0
  443. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/append_remove.js +89 -0
  444. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/firstResponder.js +148 -0
  445. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/keyPane.js +133 -0
  446. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/sendEvent.js +165 -0
  447. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +76 -0
  448. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +250 -0
  449. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/clippingFrame.js +133 -0
  450. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/convertFrames.js +246 -0
  451. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/createChildViews.js +122 -0
  452. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/createLayer.js +97 -0
  453. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/destroyLayer.js +85 -0
  454. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/findLayerInParentLayer.js +52 -0
  455. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/init.js +50 -0
  456. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/insertBefore.js +200 -0
  457. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisible.js +51 -0
  458. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/isVisibleInWindow.js +113 -0
  459. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layer.js +150 -0
  460. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutChildViews.js +162 -0
  461. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutDidChange.js +127 -0
  462. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutStyle.js +328 -0
  463. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/parentViewDidChange.js +67 -0
  464. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/prepareContext.js +166 -0
  465. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/removeChild.js +189 -0
  466. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/render.js +83 -0
  467. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/replaceChild.js +29 -0
  468. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/updateLayer.js +146 -0
  469. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/updateLayerLocation.js +194 -0
  470. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/viewDidResize.js +185 -0
  471. data/frameworks/sproutcore/frameworks/foundation/validators/credit_card.js +125 -0
  472. data/frameworks/sproutcore/frameworks/foundation/validators/date.js +52 -0
  473. data/frameworks/sproutcore/frameworks/foundation/validators/email.js +45 -0
  474. data/frameworks/sproutcore/frameworks/foundation/validators/not_empty.js +33 -0
  475. data/frameworks/sproutcore/frameworks/foundation/validators/number.js +82 -0
  476. data/frameworks/sproutcore/frameworks/foundation/validators/password.js +86 -0
  477. data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +311 -0
  478. data/frameworks/sproutcore/frameworks/foundation/views/container.js +136 -0
  479. data/frameworks/sproutcore/frameworks/foundation/views/field.js +287 -0
  480. data/frameworks/sproutcore/frameworks/foundation/views/image.js +161 -0
  481. data/frameworks/sproutcore/frameworks/foundation/views/label.js +271 -0
  482. data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +257 -0
  483. data/frameworks/sproutcore/frameworks/foundation/views/view.js +2405 -0
  484. data/frameworks/sproutcore/frameworks/mobile/english.lproj/core.css +12 -0
  485. data/frameworks/sproutcore/frameworks/mobile/lib/index.rhtml +126 -0
  486. data/frameworks/sproutcore/frameworks/mobile/system/root_responder.js +109 -0
  487. data/frameworks/sproutcore/frameworks/mobile/tests/views/button/ui.js +9 -0
  488. data/frameworks/sproutcore/frameworks/mobile/views/button.js +190 -0
  489. data/frameworks/sproutcore/frameworks/runtime/README +12 -0
  490. data/frameworks/sproutcore/frameworks/runtime/core.js +856 -0
  491. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/base.js +238 -0
  492. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/indexOf.js +33 -0
  493. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/insertAt.js +121 -0
  494. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/objectAt.js +34 -0
  495. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/popObject.js +50 -0
  496. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/pushObject.js +46 -0
  497. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/rangeObserver.js +371 -0
  498. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/removeAt.js +100 -0
  499. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/removeObject.js +49 -0
  500. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +94 -0
  501. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/shiftObject.js +50 -0
  502. data/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/unshiftObject.js +47 -0
  503. data/frameworks/sproutcore/frameworks/runtime/license.js +28 -0
  504. data/frameworks/sproutcore/frameworks/runtime/mixins/array.js +613 -0
  505. data/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +64 -0
  506. data/frameworks/sproutcore/frameworks/runtime/mixins/delegate_support.js +108 -0
  507. data/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1258 -0
  508. data/frameworks/sproutcore/frameworks/runtime/mixins/freezable.js +104 -0
  509. data/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1305 -0
  510. data/frameworks/sproutcore/frameworks/runtime/private/chain_observer.js +141 -0
  511. data/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +148 -0
  512. data/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +152 -0
  513. data/frameworks/sproutcore/frameworks/runtime/protocols/observable_protocol.js +40 -0
  514. data/frameworks/sproutcore/frameworks/runtime/protocols/sparse_array_delegate.js +131 -0
  515. data/frameworks/sproutcore/frameworks/runtime/system/binding.js +915 -0
  516. data/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +107 -0
  517. data/frameworks/sproutcore/frameworks/runtime/system/index_set.js +1166 -0
  518. data/frameworks/sproutcore/frameworks/runtime/system/object.js +801 -0
  519. data/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +265 -0
  520. data/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +241 -0
  521. data/frameworks/sproutcore/frameworks/runtime/system/selection_set.js +649 -0
  522. data/frameworks/sproutcore/frameworks/runtime/system/set.js +375 -0
  523. data/frameworks/sproutcore/frameworks/runtime/system/sparse_array.js +295 -0
  524. data/frameworks/sproutcore/frameworks/runtime/tests/core/IsEqual.js +56 -0
  525. data/frameworks/sproutcore/frameworks/runtime/tests/core/beget.js +23 -0
  526. data/frameworks/sproutcore/frameworks/runtime/tests/core/clone.js +66 -0
  527. data/frameworks/sproutcore/frameworks/runtime/tests/core/compare.js +44 -0
  528. data/frameworks/sproutcore/frameworks/runtime/tests/core/console.js +16 -0
  529. data/frameworks/sproutcore/frameworks/runtime/tests/core/guidFor.js +147 -0
  530. data/frameworks/sproutcore/frameworks/runtime/tests/core/isArray.js +25 -0
  531. data/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +38 -0
  532. data/frameworks/sproutcore/frameworks/runtime/tests/core/keys.js +20 -0
  533. data/frameworks/sproutcore/frameworks/runtime/tests/core/makeArray.js +30 -0
  534. data/frameworks/sproutcore/frameworks/runtime/tests/core/objectForPropertyPath.js +19 -0
  535. data/frameworks/sproutcore/frameworks/runtime/tests/core/tupleForPropertyPath.js +37 -0
  536. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +57 -0
  537. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable.js +611 -0
  538. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +587 -0
  539. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/propertyChanges.js +132 -0
  540. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/registerDependentKeys.js +79 -0
  541. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/propertyChanges.js +80 -0
  542. data/frameworks/sproutcore/frameworks/runtime/tests/private/observer_queue/isObservingSuspended.js +55 -0
  543. data/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +265 -0
  544. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/add.js +195 -0
  545. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/clone.js +43 -0
  546. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/contains.js +74 -0
  547. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/create.js +42 -0
  548. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/indexAfter.js +38 -0
  549. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/indexBefore.js +38 -0
  550. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/intersects.js +74 -0
  551. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/max.js +40 -0
  552. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/min.js +40 -0
  553. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/rangeStartForIndex.js +36 -0
  554. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/remove.js +189 -0
  555. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/without.js +89 -0
  556. data/frameworks/sproutcore/frameworks/runtime/tests/system/object/base.js +135 -0
  557. data/frameworks/sproutcore/frameworks/runtime/tests/system/object/bindings.js +339 -0
  558. data/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/create.js +59 -0
  559. data/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/destroy.js +75 -0
  560. data/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/objectPropertyDidChange.js +117 -0
  561. data/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/rangeDidChange.js +110 -0
  562. data/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/update.js +65 -0
  563. data/frameworks/sproutcore/frameworks/runtime/tests/system/run_loop.js +120 -0
  564. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/add.js +92 -0
  565. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/copy.js +17 -0
  566. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/indexSetForSource.js +85 -0
  567. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/isEqual.js +60 -0
  568. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/remove.js +87 -0
  569. data/frameworks/sproutcore/frameworks/runtime/tests/system/set.js +292 -0
  570. data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +122 -0
  571. data/frameworks/sproutcore/frameworks/testing/core.js +196 -0
  572. data/frameworks/sproutcore/frameworks/testing/english.lproj/additions.css +8 -0
  573. data/frameworks/sproutcore/frameworks/testing/english.lproj/runner.css +126 -0
  574. data/frameworks/sproutcore/frameworks/testing/english.lproj/testsuite.css +131 -0
  575. data/frameworks/sproutcore/frameworks/testing/extras.js +17 -0
  576. data/frameworks/sproutcore/frameworks/testing/jquery.js +3559 -0
  577. data/frameworks/sproutcore/frameworks/testing/qunit.js +827 -0
  578. data/frameworks/sproutcore/frameworks/testing/system/dump.js +205 -0
  579. data/frameworks/sproutcore/frameworks/testing/system/equiv.js +201 -0
  580. data/frameworks/sproutcore/frameworks/testing/system/plan.js +691 -0
  581. data/frameworks/sproutcore/frameworks/testing/system/runner.js +209 -0
  582. data/frameworks/sproutcore/frameworks/testing/system/suite.js +228 -0
  583. data/frameworks/sproutcore/frameworks/testing/utils.js +62 -0
  584. data/frameworks/sproutcore/lib/index.rhtml +121 -0
  585. data/frameworks/sproutcore/license.js +28 -0
  586. data/frameworks/sproutcore/themes/empty_theme/tests/mini_icons.rhtml +69 -0
  587. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/button.css +41 -0
  588. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/core.css +8 -0
  589. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/backButton.png +0 -0
  590. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/blueButton.png +0 -0
  591. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/cancel.png +0 -0
  592. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/grayButton.png +0 -0
  593. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/leftButton.png +0 -0
  594. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listArrow.png +0 -0
  595. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listArrowSel.png +0 -0
  596. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/listGroup.png +0 -0
  597. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/loading.gif +0 -0
  598. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/pinstripes.png +0 -0
  599. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/rightButton.png +0 -0
  600. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/selection.png +0 -0
  601. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/thumb.png +0 -0
  602. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toggle.png +0 -0
  603. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toggleOn.png +0 -0
  604. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toolButton.png +0 -0
  605. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/toolbar.png +0 -0
  606. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/images/whiteButton.png +0 -0
  607. data/frameworks/sproutcore/themes/iphone_theme/english.lproj/strings.js +15 -0
  608. data/frameworks/sproutcore/themes/standard_theme/english.lproj/button.css +331 -0
  609. data/frameworks/sproutcore/themes/standard_theme/english.lproj/checkbox.css +91 -0
  610. data/frameworks/sproutcore/themes/standard_theme/english.lproj/collection.css +134 -0
  611. data/frameworks/sproutcore/themes/standard_theme/english.lproj/core.css +60 -0
  612. data/frameworks/sproutcore/themes/standard_theme/english.lproj/disclosure.css +55 -0
  613. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-repeat-x.png +0 -0
  614. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-sprite.png +0 -0
  615. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-ysprite.png +0 -0
  616. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-toolbar-view.png +0 -0
  617. data/frameworks/sproutcore/themes/standard_theme/english.lproj/label.css +11 -0
  618. data/frameworks/sproutcore/themes/standard_theme/english.lproj/list_item.css +30 -0
  619. data/frameworks/sproutcore/themes/standard_theme/english.lproj/pane.css +8 -0
  620. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-fat.jpg +0 -0
  621. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/background-thin.jpg +0 -0
  622. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-edge.png +0 -0
  623. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-left-corner.png +0 -0
  624. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/bottom-right-corner.png +0 -0
  625. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/left-edge.png +0 -0
  626. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/overlay.png +0 -0
  627. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/right-edge.png +0 -0
  628. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-edge.png +0 -0
  629. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-left-corner.png +0 -0
  630. data/frameworks/sproutcore/themes/standard_theme/english.lproj/panels/top-right-corner.png +0 -0
  631. data/frameworks/sproutcore/themes/standard_theme/english.lproj/progress.css +26 -0
  632. data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +122 -0
  633. data/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +279 -0
  634. data/frameworks/sproutcore/themes/standard_theme/english.lproj/slider.css +94 -0
  635. data/frameworks/sproutcore/themes/standard_theme/english.lproj/split_view.css +27 -0
  636. data/frameworks/sproutcore/themes/standard_theme/english.lproj/tab.css +18 -0
  637. data/frameworks/sproutcore/themes/standard_theme/english.lproj/text_field.css +10 -0
  638. data/frameworks/sproutcore/themes/standard_theme/english.lproj/toolbar.css +7 -0
  639. data/lib/sproutcore.rb +9 -1
  640. data/lib/sproutcore/tools/build.rb +1 -1
  641. data/lib/thor/CHANGELOG.rdoc +52 -0
  642. data/lib/thor/LICENSE +20 -0
  643. data/lib/thor/README.markdown +76 -0
  644. data/lib/thor/Rakefile +6 -0
  645. data/lib/thor/Thorfile +45 -0
  646. data/lib/thor/bin/rake2thor +83 -0
  647. data/lib/thor/bin/thor +7 -0
  648. data/lib/thor/lib/thor.rb +170 -0
  649. data/lib/thor/lib/thor/error.rb +3 -0
  650. data/lib/thor/lib/thor/options.rb +267 -0
  651. data/lib/thor/lib/thor/ordered_hash.rb +64 -0
  652. data/lib/thor/lib/thor/runner.rb +305 -0
  653. data/lib/thor/lib/thor/task.rb +83 -0
  654. data/lib/thor/lib/thor/task_hash.rb +22 -0
  655. data/lib/thor/lib/thor/tasks.rb +77 -0
  656. data/lib/thor/lib/thor/tasks/package.rb +18 -0
  657. data/lib/thor/lib/thor/util.rb +75 -0
  658. data/lib/thor/script/destroy +14 -0
  659. data/lib/thor/script/generate +14 -0
  660. data/lib/thor/task.thor +15 -0
  661. metadata +664 -351
  662. data/VERSION +0 -1
  663. data/spec/buildtasks/build/copy_spec.rb +0 -60
  664. data/spec/buildtasks/build/spec_helper.rb +0 -36
  665. data/spec/buildtasks/manifest/catalog_spec.rb +0 -48
  666. data/spec/buildtasks/manifest/hide_buildfiles_spec.rb +0 -125
  667. data/spec/buildtasks/manifest/localize_spec.rb +0 -97
  668. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +0 -246
  669. data/spec/buildtasks/manifest/prepare_build_tasks/css_spec.rb +0 -87
  670. data/spec/buildtasks/manifest/prepare_build_tasks/html_spec.rb +0 -175
  671. data/spec/buildtasks/manifest/prepare_build_tasks/javascript_spec.rb +0 -65
  672. data/spec/buildtasks/manifest/prepare_build_tasks/minify_spec.rb +0 -70
  673. data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +0 -152
  674. data/spec/buildtasks/manifest/prepare_build_tasks/sass_spec.rb +0 -98
  675. data/spec/buildtasks/manifest/prepare_build_tasks/strings_spec.rb +0 -64
  676. data/spec/buildtasks/manifest/prepare_build_tasks/tests_spec.rb +0 -163
  677. data/spec/buildtasks/manifest/prepare_spec.rb +0 -43
  678. data/spec/buildtasks/manifest/spec_helper.rb +0 -35
  679. data/spec/buildtasks/target_spec.rb +0 -214
  680. data/spec/fixtures/builder_tests/Buildfile +0 -15
  681. data/spec/fixtures/builder_tests/apps/combine_test/a.js +0 -1
  682. data/spec/fixtures/builder_tests/apps/combine_test/b.js +0 -1
  683. data/spec/fixtures/builder_tests/apps/combine_test/c.js +0 -1
  684. data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/a.css +0 -1
  685. data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/b.css +0 -1
  686. data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/c.css +0 -1
  687. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/bar1_sample.rhtml +0 -2
  688. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/erb_sample.html.erb +0 -1
  689. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/icons/image.png +0 -0
  690. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/image.jpg +0 -0
  691. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/rhtml_sample.rhtml +0 -1
  692. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/strings.js +0 -4
  693. data/spec/fixtures/builder_tests/apps/html_test/english.lproj/style.css +0 -0
  694. data/spec/fixtures/builder_tests/apps/html_test/french.lproj/french-icons/fr.png +0 -0
  695. data/spec/fixtures/builder_tests/apps/html_test/french.lproj/strings.js +0 -4
  696. data/spec/fixtures/builder_tests/apps/html_test/lib/layout_template.rhtml +0 -1
  697. data/spec/fixtures/builder_tests/apps/html_test/scripts.js +0 -0
  698. data/spec/fixtures/builder_tests/apps/javascript_test/sc_static.js +0 -15
  699. data/spec/fixtures/builder_tests/apps/javascript_test/sc_super.js +0 -4
  700. data/spec/fixtures/builder_tests/apps/javascript_test/strings.js +0 -7
  701. data/spec/fixtures/builder_tests/apps/sass_test/sample.sass +0 -3
  702. data/spec/fixtures/builder_tests/apps/strings_test/lproj/strings.js +0 -8
  703. data/spec/fixtures/builder_tests/apps/stylesheet_test/build_directives.css +0 -9
  704. data/spec/fixtures/builder_tests/apps/stylesheet_test/sc_static.css +0 -12
  705. data/spec/fixtures/builder_tests/apps/test_test/lib/alt_layout.rhtml +0 -1
  706. data/spec/fixtures/builder_tests/apps/test_test/lib/test_layout.rhtml +0 -3
  707. data/spec/fixtures/builder_tests/apps/test_test/tests/qunit_test.js +0 -1
  708. data/spec/fixtures/builder_tests/apps/test_test/tests/qunit_test2.js +0 -1
  709. data/spec/fixtures/builder_tests/apps/test_test/tests/rhtml_test.rhtml +0 -4
  710. data/spec/fixtures/builder_tests/frameworks/debug/core.js +0 -0
  711. data/spec/fixtures/builder_tests/frameworks/debug/english.lproj/dummy.css +0 -0
  712. data/spec/fixtures/builder_tests/frameworks/qunit/core.js +0 -0
  713. data/spec/fixtures/builder_tests/frameworks/qunit/english.lproj/dummy.css +0 -0
  714. data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/req_style_1.css +0 -0
  715. data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/strings.js +0 -4
  716. data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/test.rhtml +0 -1
  717. data/spec/fixtures/builder_tests/frameworks/req_target_1/req_js_1.js +0 -0
  718. data/spec/fixtures/builder_tests/frameworks/req_target_2/english.lproj/req_style_2.css +0 -0
  719. data/spec/fixtures/builder_tests/frameworks/req_target_2/english.lproj/test.rhtml +0 -1
  720. data/spec/fixtures/builder_tests/frameworks/req_target_2/javascript.js +0 -1
  721. data/spec/fixtures/builder_tests/frameworks/req_target_2/lib/alt_layout.rhtml +0 -0
  722. data/spec/fixtures/builder_tests/frameworks/req_target_2/req_js_2.js +0 -0
  723. data/spec/fixtures/builder_tests/themes/sample_theme/Buildfile +0 -1
  724. data/spec/fixtures/buildfiles/basic/Buildfile +0 -16
  725. data/spec/fixtures/buildfiles/basic/task_module.rake +0 -6
  726. data/spec/fixtures/buildfiles/installed/Buildfile +0 -7
  727. data/spec/fixtures/buildfiles/installed/Buildfile2 +0 -5
  728. data/spec/fixtures/buildfiles/project_test/Buildfile +0 -4
  729. data/spec/fixtures/buildfiles/project_test/not_project/Buildfile +0 -2
  730. data/spec/fixtures/buildfiles/project_test/not_project/child/PLACEHOLDER +0 -0
  731. data/spec/fixtures/entry_for_project/Buildfile +0 -1
  732. data/spec/fixtures/entry_for_project/apps/test_app/entry.txt +0 -0
  733. data/spec/fixtures/entry_for_project/apps/test_app/frameworks/nested/PLACEHOLDER +0 -0
  734. data/spec/fixtures/entry_for_project/frameworks/shared/PLACEHOLDER +0 -0
  735. data/spec/fixtures/find_targets/custom/Buildfile +0 -8
  736. data/spec/fixtures/find_targets/custom/bars/bar1/bars/bar1/PLACEHOLDER +0 -0
  737. data/spec/fixtures/find_targets/custom/bars/bar1/bars/bar2/PLACEHOLDER +0 -0
  738. data/spec/fixtures/find_targets/custom/bars/bar1/foos/foo1/PLACEHOLDER +0 -0
  739. data/spec/fixtures/find_targets/custom/bars/bar1/foos/foo2/PLACEHOLDER +0 -0
  740. data/spec/fixtures/find_targets/custom/foos/custom_foos/Buildfile +0 -5
  741. data/spec/fixtures/find_targets/custom/foos/custom_foos/custom_foodir/foo1/PLACEHOLDER +0 -0
  742. data/spec/fixtures/find_targets/custom/foos/custom_foos/custom_foodir/foo2/PLACEHOLDER +0 -0
  743. data/spec/fixtures/find_targets/custom/foos/custom_foos/foos/not_foo1/PLACEHOLDER +0 -0
  744. data/spec/fixtures/find_targets/custom/foos/foo1/bars/bar1/PLACEHOLDER +0 -0
  745. data/spec/fixtures/find_targets/custom/foos/foo1/bars/bar2/PLACEHOLDER +0 -0
  746. data/spec/fixtures/find_targets/nested/Buildfile +0 -8
  747. data/spec/fixtures/find_targets/nested/apps/app1/Buildfile +0 -1
  748. data/spec/fixtures/find_targets/nested/apps/app1/apps/nested_app/PLACEHOLDER +0 -0
  749. data/spec/fixtures/find_targets/standard/Apps/app1/frameworks/framework1/PLACEHOLDER +0 -0
  750. data/spec/fixtures/find_targets/standard/Apps/app1/frameworks/framework2/PLACEHOLDER +0 -0
  751. data/spec/fixtures/find_targets/standard/clients/client1/PLACEHOLDER +0 -0
  752. data/spec/fixtures/find_targets/standard/frameworks/framework1/frameworks/framework1/PLACEHOLDER +0 -0
  753. data/spec/fixtures/find_targets/standard/frameworks/framework2/PLACEHOLDER +0 -0
  754. data/spec/fixtures/find_targets/standard/themes/theme1/PLACEHOLDER +0 -0
  755. data/spec/fixtures/find_targets/standard/themes/theme2/PLACEHOLDER +0 -0
  756. data/spec/fixtures/languages/apps/caps_long_names/English.lproj/PLACEHOLDER +0 -0
  757. data/spec/fixtures/languages/apps/caps_long_names/FreNCH.lproj/PLACEHOLDER +0 -0
  758. data/spec/fixtures/languages/apps/caps_long_names/UnknOWN.lproj/PLACEHOLDER +0 -0
  759. data/spec/fixtures/languages/apps/long_names/english.lproj/PLACEHOLDER +0 -0
  760. data/spec/fixtures/languages/apps/long_names/french.lproj/PLACEHOLDER +0 -0
  761. data/spec/fixtures/languages/apps/long_names/german.lproj/PLACEHOLDER +0 -0
  762. data/spec/fixtures/languages/apps/long_names/italian.lproj/PLACEHOLDER +0 -0
  763. data/spec/fixtures/languages/apps/long_names/japanese.lproj/PLACEHOLDER +0 -0
  764. data/spec/fixtures/languages/apps/long_names/spanish.lproj/PLACEHOLDER +0 -0
  765. data/spec/fixtures/languages/apps/long_names/unknown.lproj/PLACEHOLDER +0 -0
  766. data/spec/fixtures/languages/apps/no_names/PLACEHOLDER +0 -0
  767. data/spec/fixtures/languages/apps/short_names/de.lproj/PLACEHOLDER +0 -0
  768. data/spec/fixtures/languages/apps/short_names/en-CA.lproj/PLACEHOLDER +0 -0
  769. data/spec/fixtures/languages/apps/short_names/en-GB.lproj/PLACEHOLDER +0 -0
  770. data/spec/fixtures/languages/apps/short_names/en-US.lproj/PLACEHOLDER +0 -0
  771. data/spec/fixtures/languages/apps/short_names/en.lproj/PLACEHOLDER +0 -0
  772. data/spec/fixtures/languages/apps/short_names/es.lproj/PLACEHOLDER +0 -0
  773. data/spec/fixtures/languages/apps/short_names/foo.lproj/PLACEHOLDER +0 -0
  774. data/spec/fixtures/languages/apps/short_names/fr.lproj/PLACEHOLDER +0 -0
  775. data/spec/fixtures/languages/apps/short_names/it.lproj/PLACEHOLDER +0 -0
  776. data/spec/fixtures/languages/apps/short_names/ja.lproj/PLACEHOLDER +0 -0
  777. data/spec/fixtures/ordered_entries/apps/no_requires/1.js +0 -1
  778. data/spec/fixtures/ordered_entries/apps/no_requires/B.js +0 -1
  779. data/spec/fixtures/ordered_entries/apps/no_requires/a.js +0 -1
  780. data/spec/fixtures/ordered_entries/apps/no_requires/a/a.js +0 -1
  781. data/spec/fixtures/ordered_entries/apps/no_requires/a/b.js +0 -1
  782. data/spec/fixtures/ordered_entries/apps/no_requires/b/a.js +0 -1
  783. data/spec/fixtures/ordered_entries/apps/no_requires/c.js +0 -1
  784. data/spec/fixtures/ordered_entries/apps/no_requires/core.js +0 -1
  785. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/B.css +0 -0
  786. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a.css +0 -0
  787. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a/a.css +0 -0
  788. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a/b.css +0 -0
  789. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/b/a.css +0 -0
  790. data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/c.css +0 -0
  791. data/spec/fixtures/ordered_entries/apps/no_requires/lproj/strings.js +0 -1
  792. data/spec/fixtures/ordered_entries/apps/no_requires/utils.js +0 -1
  793. data/spec/fixtures/ordered_entries/apps/with_requires/a.js +0 -2
  794. data/spec/fixtures/ordered_entries/apps/with_requires/b.js +0 -3
  795. data/spec/fixtures/ordered_entries/apps/with_requires/c.js +0 -2
  796. data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/a.css +0 -2
  797. data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/b.css +0 -2
  798. data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/c.css +0 -2
  799. data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/d.js +0 -1
  800. data/spec/fixtures/real_world/Buildfile +0 -12
  801. data/spec/fixtures/real_world/apps/account/README +0 -1
  802. data/spec/fixtures/real_world/apps/calendar/README +0 -1
  803. data/spec/fixtures/real_world/apps/contacts/README_BEFORE_EDITING +0 -1
  804. data/spec/fixtures/real_world/apps/files/README +0 -1
  805. data/spec/fixtures/real_world/apps/mail/README +0 -1
  806. data/spec/fixtures/real_world/apps/mobile_photos/README +0 -1
  807. data/spec/fixtures/real_world/apps/photos/README +0 -1
  808. data/spec/fixtures/real_world/apps/uploader/README +0 -1
  809. data/spec/fixtures/real_world/frameworks/core_files/PLACEHOLDER +0 -0
  810. data/spec/fixtures/real_world/frameworks/core_photos/PLACEHOLDER +0 -0
  811. data/spec/fixtures/real_world/frameworks/shared/PLACEHOLDER +0 -0
  812. data/spec/fixtures/real_world/frameworks/sproutcore/Buildfile +0 -26
  813. data/spec/fixtures/real_world/frameworks/sproutcore/README +0 -1
  814. data/spec/fixtures/real_world/frameworks/sproutcore/apps/docs/PLACEHOLDER +0 -0
  815. data/spec/fixtures/real_world/frameworks/sproutcore/apps/test_runner/PLACEHOLDER +0 -0
  816. data/spec/fixtures/real_world/frameworks/sproutcore/core.js +0 -0
  817. data/spec/fixtures/real_world/frameworks/sproutcore/debug/debug-resource.html +0 -0
  818. data/spec/fixtures/real_world/frameworks/sproutcore/debug/sample_debug.js +0 -0
  819. data/spec/fixtures/real_world/frameworks/sproutcore/demo2.js +0 -0
  820. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/debug/sample_debug-loc.js +0 -0
  821. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo.css +0 -4
  822. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo.html +0 -1
  823. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo2.sass +0 -0
  824. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.haml +0 -0
  825. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.html.erb +0 -1
  826. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.rhtml +0 -0
  827. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/fixtures/sample_fixtures-loc.js +0 -0
  828. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/has_require.css +0 -4
  829. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/no_require.css +0 -1
  830. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/no_sc_resource.rhtml +0 -1
  831. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/protocols/sample-loc.js +0 -0
  832. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/sc_resource.css +0 -6
  833. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/sc_resource.rhtml +0 -3
  834. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/strings.js +0 -1
  835. data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/tests/sample-loc.js +0 -0
  836. data/spec/fixtures/real_world/frameworks/sproutcore/fixtures/sample-json-fixture.json +0 -1
  837. data/spec/fixtures/real_world/frameworks/sproutcore/fixtures/sample_fixtures.js +0 -0
  838. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/application/PLACEHOLDER +0 -0
  839. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/costello/core.js +0 -0
  840. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/data_store/PLACEHOLDER +0 -0
  841. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/debug/PLACEHOLDER +0 -0
  842. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/desktop/PLACEHOLDER +0 -0
  843. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/empty_theme/PLACEHOLDER +0 -0
  844. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/foundation/PLACEHOLDER +0 -0
  845. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/mobile/PLACEHOLDER +0 -0
  846. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/qunit/PLACEHOLDER +0 -0
  847. data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/uploader/PLACEHOLDER +0 -0
  848. data/spec/fixtures/real_world/frameworks/sproutcore/french.lproj/french-resource.js +0 -0
  849. data/spec/fixtures/real_world/frameworks/sproutcore/french.lproj/strings.js +0 -1
  850. data/spec/fixtures/real_world/frameworks/sproutcore/german.lproj/german-resource.js +0 -0
  851. data/spec/fixtures/real_world/frameworks/sproutcore/german.lproj/strings.js +0 -0
  852. data/spec/fixtures/real_world/frameworks/sproutcore/has_require.js +0 -4
  853. data/spec/fixtures/real_world/frameworks/sproutcore/lib/index.html +0 -1
  854. data/spec/fixtures/real_world/frameworks/sproutcore/no_require.js +0 -1
  855. data/spec/fixtures/real_world/frameworks/sproutcore/protocols/sample.js +0 -0
  856. data/spec/fixtures/real_world/frameworks/sproutcore/sc_resource.js +0 -6
  857. data/spec/fixtures/real_world/frameworks/sproutcore/tests/nested/sample1.js +0 -0
  858. data/spec/fixtures/real_world/frameworks/sproutcore/tests/nested/sample2.js +0 -0
  859. data/spec/fixtures/real_world/frameworks/sproutcore/tests/sample.js +0 -0
  860. data/spec/fixtures/real_world/frameworks/sproutcore/tests/sample.rhtml +0 -1
  861. data/spec/fixtures/real_world/frameworks/sproutcore/themes/standard_theme/README +0 -0
  862. data/spec/fixtures/real_world/frameworks/sproutcore/views/view.js +0 -1
  863. data/spec/fixtures/real_world/generators/sample_custom/Buildfile +0 -0
  864. data/spec/fixtures/recursive_project/Buildfile +0 -8
  865. data/spec/fixtures/recursive_project/frameworks/sproutcore/frameworks/costello/PLACEHOLDER +0 -0
  866. data/spec/lib/builders/combine_spec.rb +0 -67
  867. data/spec/lib/builders/html_spec.rb +0 -577
  868. data/spec/lib/builders/javascript_spec.rb +0 -81
  869. data/spec/lib/builders/sass_spec.rb +0 -43
  870. data/spec/lib/builders/spec_helper.rb +0 -30
  871. data/spec/lib/builders/strings_spec.rb +0 -52
  872. data/spec/lib/builders/stylesheet_spec.rb +0 -63
  873. data/spec/lib/builders/test_index_spec.rb +0 -44
  874. data/spec/lib/builders/test_spec.rb +0 -135
  875. data/spec/lib/buildfile/config_for_spec.rb +0 -81
  876. data/spec/lib/buildfile/define_spec.rb +0 -59
  877. data/spec/lib/buildfile/dup_spec.rb +0 -65
  878. data/spec/lib/buildfile/invoke_spec.rb +0 -130
  879. data/spec/lib/buildfile/load_spec.rb +0 -49
  880. data/spec/lib/buildfile/task/dup_spec.rb +0 -55
  881. data/spec/lib/buildfile/task_defined_spec.rb +0 -17
  882. data/spec/lib/buildfile_commands/build_task_spec.rb +0 -19
  883. data/spec/lib/buildfile_commands/config_spec.rb +0 -97
  884. data/spec/lib/buildfile_commands/import_spec.rb +0 -17
  885. data/spec/lib/buildfile_commands/namespace_spec.rb +0 -18
  886. data/spec/lib/buildfile_commands/proxies_spec.rb +0 -38
  887. data/spec/lib/buildfile_commands/replace_task_spec.rb +0 -29
  888. data/spec/lib/buildfile_commands/task_spec.rb +0 -36
  889. data/spec/lib/helpers/packing_optimizer/optimize_spec.rb +0 -26
  890. data/spec/lib/models/hash_struct/deep_clone_spec.rb +0 -27
  891. data/spec/lib/models/hash_struct/has_options_spec.rb +0 -32
  892. data/spec/lib/models/hash_struct/hash_spec.rb +0 -64
  893. data/spec/lib/models/hash_struct/merge_spec.rb +0 -26
  894. data/spec/lib/models/hash_struct/method_missing.rb +0 -41
  895. data/spec/lib/models/manifest/add_entry_spec.rb +0 -36
  896. data/spec/lib/models/manifest/add_transform_spec.rb +0 -90
  897. data/spec/lib/models/manifest/build_spec.rb +0 -78
  898. data/spec/lib/models/manifest/entry_for_spec.rb +0 -94
  899. data/spec/lib/models/manifest/find_entry.rb +0 -84
  900. data/spec/lib/models/manifest/prepare_spec.rb +0 -62
  901. data/spec/lib/models/manifest_entry/cacheable_url_spec.rb +0 -31
  902. data/spec/lib/models/manifest_entry/prepare_spec.rb +0 -54
  903. data/spec/lib/models/project/add_target_spec.rb +0 -44
  904. data/spec/lib/models/project/buildfile_spec.rb +0 -35
  905. data/spec/lib/models/project/find_targets_for_spec.rb +0 -77
  906. data/spec/lib/models/project/load_nearest_project_spec.rb +0 -23
  907. data/spec/lib/models/project/target_for_spec.rb +0 -33
  908. data/spec/lib/models/project/targets_spec.rb +0 -62
  909. data/spec/lib/models/target/compute_build_number_spec.rb +0 -125
  910. data/spec/lib/models/target/config_spec.rb +0 -30
  911. data/spec/lib/models/target/expand_required_targets_spec.rb +0 -48
  912. data/spec/lib/models/target/installed_languages_spec.rb +0 -47
  913. data/spec/lib/models/target/lproj_for_spec.rb +0 -38
  914. data/spec/lib/models/target/manifest_for_spec.rb +0 -42
  915. data/spec/lib/models/target/parent_target_spec.rb +0 -21
  916. data/spec/lib/models/target/prepare_spec.rb +0 -53
  917. data/spec/lib/models/target/required_targets_spec.rb +0 -119
  918. data/spec/lib/models/target/target_for_spec.rb +0 -56
  919. data/spec/lib/tools/build_number_spec.rb +0 -28
  920. data/spec/lib/tools/gen_spec.rb +0 -207
  921. data/spec/lib/tools/tools_spec.rb +0 -78
  922. data/spec/spec_helper.rb +0 -138
  923. data/sproutcore-abbot.gemspec +0 -640
  924. data/vendor/jsdoc/templates/jsdoc/allclasses.tmpl +0 -17
  925. data/vendor/jsdoc/templates/jsdoc/allfiles.tmpl +0 -56
  926. data/vendor/jsdoc/templates/jsdoc/class.tmpl +0 -487
  927. data/vendor/jsdoc/templates/jsdoc/index.tmpl +0 -38
  928. data/vendor/jsdoc/templates/jsdoc/symbol.tmpl +0 -35
  929. data/vendor/jsdoc/templates/sproutcore/allclasses.tmpl +0 -0
  930. data/vendor/jsdoc/templates/sproutcore/allfiles.tmpl +0 -56
  931. data/vendor/jsdoc/templates/sproutcore/class.tmpl +0 -674
  932. data/vendor/jsdoc/templates/sproutcore/index.tmpl +0 -55
  933. data/vendor/jsdoc/templates/sproutcore/symbol.tmpl +0 -35
@@ -0,0 +1,104 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore Costello - Property Observing Library
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
+
9
+ /**
10
+ Standard Error that should be raised when you try to modify a frozen object.
11
+ */
12
+ SC.FROZEN_ERROR = new Error("Cannot modify a frozen object");
13
+
14
+ /**
15
+ @namespace
16
+
17
+ The SC.Freezable mixin implements some basic methods for marking an object
18
+ as frozen. Once an object is frozen it should be read only. No changes
19
+ may be made the internal state of the object.
20
+
21
+ h2. Enforcement
22
+
23
+ To fully support freezing in your subclass, you must include this mixin and
24
+ override any method that might alter any property on the object to instead
25
+ raise an exception. You can check the state of an object by checking the
26
+ isFrozen property.
27
+
28
+ Although future versions of JavaScript may support language-level freezing
29
+ object objects, that is not the case today. Even if an object is freezable,
30
+ it is still technically possible to modify the object, even though it could
31
+ break other parts of your application that do not expect a frozen object to
32
+ change. It is, therefore, very important that you always respect the
33
+ isFrozen property on all freezable objects.
34
+
35
+ h2. Example
36
+
37
+ The example below shows a simple object that implement the SC.Freezable
38
+ protocol.
39
+
40
+ {{{
41
+ Contact = SC.Object.extend(SC.Freezable, {
42
+
43
+ firstName: null,
44
+
45
+ lastName: null,
46
+
47
+ // swaps the names
48
+ swapNames: function() {
49
+ if (this.get('isFrozen')) throw SC.FROZEN_ERROR;
50
+ var tmp = this.get('firstName');
51
+ this.set('firstName', this.get('lastName'));
52
+ this.set('lastName', tmp);
53
+ return this;
54
+ }
55
+
56
+ });
57
+
58
+ c = Context.create({ firstName: "John", lastName: "Doe" });
59
+ c.swapNames(); => returns c
60
+ c.freeze();
61
+ c.swapNames(); => EXCEPTION
62
+
63
+ }}}
64
+
65
+ h2. Copying
66
+
67
+ Usually the SC.Freezable protocol is implemented in cooperation with the
68
+ SC.Copyable protocol, which defines a frozenCopy() method that will return
69
+ a frozen object, if the object implements this method as well.
70
+
71
+ */
72
+ SC.Freezable = {
73
+
74
+ /**
75
+ Walk like a duck.
76
+ */
77
+ isFreezable: YES,
78
+
79
+ /**
80
+ Set to YES when the object is frozen. Use this property to detect whether
81
+ your object is frozen or not.
82
+ */
83
+ isFrozen: NO,
84
+
85
+ /**
86
+ Freezes the object. Once this method has been called the object should
87
+ no longer allow any properties to be edited.
88
+
89
+ @returns {Object} reciever
90
+ */
91
+ freeze: function() {
92
+ // NOTE: Once someone actually implements Object.freeze() in the browser,
93
+ // add a call to that here also.
94
+
95
+ if (this.set) this.set('isFrozen', YES);
96
+ else this.isFrozen = YES;
97
+ return this;
98
+ }
99
+
100
+ };
101
+
102
+
103
+ // Add to Array
104
+ SC.mixin(Array.prototype, SC.Freezable);
@@ -0,0 +1,1305 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore Costello - Property Observing Library
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('private/observer_set') ;
9
+
10
+ /*globals logChange */
11
+
12
+ SC.LOG_OBSERVERS = NO ;
13
+
14
+ /**
15
+ @namespace
16
+
17
+ Key-Value-Observing (KVO) simply allows one object to observe changes to a
18
+ property on another object. It is one of the fundamental ways that models,
19
+ controllers and views communicate with each other in a SproutCore
20
+ application. Any object that has this module applied to it can be used in
21
+ KVO-operations.
22
+
23
+ This module is applied automatically to all objects that inherit from
24
+ SC.Object, which includes most objects bundled with the SproutCore
25
+ framework. You will not generally apply this module to classes yourself,
26
+ but you will use the features provided by this module frequently, so it is
27
+ important to understand how to use it.
28
+
29
+ h2. Enabling Key Value Observing
30
+
31
+ With KVO, you can write functions that will be called automatically whenever
32
+ a property on a particular object changes. You can use this feature to
33
+ reduce the amount of "glue code" that you often write to tie the various
34
+ parts of your application together.
35
+
36
+ To use KVO, just use the KVO-aware methods get() and set() to access
37
+ properties instead of accessing properties directly. Instead of writing:
38
+
39
+ {{{
40
+ var aName = contact.firstName ;
41
+ contact.firstName = 'Charles' ;
42
+ }}}
43
+
44
+ use:
45
+
46
+ {{{
47
+ var aName = contact.get('firstName') ;
48
+ contact.set('firstName', 'Charles') ;
49
+ }}}
50
+
51
+ get() and set() work just like the normal "dot operators" provided by
52
+ JavaScript but they provide you with much more power, including not only
53
+ observing but computed properties as well.
54
+
55
+ h2. Observing Property Changes
56
+
57
+ You typically observe property changes simply by adding the observes()
58
+ call to the end of your method declarations in classes that you write. For
59
+ example:
60
+
61
+ {{{
62
+ SC.Object.create({
63
+ valueObserver: function() {
64
+ // Executes whenever the "Value" property changes
65
+ }.observes('value')
66
+ }) ;
67
+ }}}
68
+
69
+ Although this is the most common way to add an observer, this capability is
70
+ actually built into the SC.Object class on top of two methods defined in
71
+ this mixin called addObserver() and removeObserver(). You can use these two
72
+ methods to add and remove observers yourself if you need to do so at run
73
+ time.
74
+
75
+ To add an observer for a property, just call:
76
+
77
+ {{{
78
+ object.addObserver('propertyKey', targetObject, targetAction) ;
79
+ }}}
80
+
81
+ This will call the 'targetAction' method on the targetObject to be called
82
+ whenever the value of the propertyKey changes.
83
+
84
+ h2. Observer Parameters
85
+
86
+ An observer function typically does not need to accept any parameters,
87
+ however you can accept certain arguments when writing generic observers.
88
+ An observer function can have the following arguments:
89
+
90
+ {{{
91
+ propertyObserver(target, key, value, revision) ;
92
+ }}}
93
+
94
+ - *target* - This is the object whose value changed. Usually this.
95
+ - *key* - The key of the value that changed
96
+ - *value* - this property is no longer used. It will always be null
97
+ - *revision* - this is the revision of the target object
98
+
99
+ h2. Implementing Manual Change Notifications
100
+
101
+ Sometimes you may want to control the rate at which notifications for
102
+ a property are delivered, for example by checking first to make sure
103
+ that the value has changed.
104
+
105
+ To do this, you need to implement a computed property for the property
106
+ you want to change and override automaticallyNotifiesObserversFor().
107
+
108
+ The example below will only notify if the "balance" property value actually
109
+ changes:
110
+
111
+ {{{
112
+
113
+ automaticallyNotifiesObserversFor: function(key) {
114
+ return (key === 'balance') ? NO : sc_super() ;
115
+ },
116
+
117
+ balance: function(key, value) {
118
+ var balance = this._balance ;
119
+ if ((value !== undefined) && (balance !== value)) {
120
+ this.propertyWillChange(key) ;
121
+ balance = this._balance = value ;
122
+ this.propertyDidChange(key) ;
123
+ }
124
+ return balance ;
125
+ }
126
+
127
+ }}}
128
+
129
+ h1. Implementation Details
130
+
131
+ Internally, SproutCore keeps track of observable information by adding a
132
+ number of properties to the object adopting the observable. All of these
133
+ properties begin with "_kvo_" to separate them from the rest of your object.
134
+
135
+ @static
136
+ @since SproutCore 1.0
137
+ */
138
+ SC.Observable = {
139
+
140
+ /** walk like that ol' duck */
141
+ isObservable: YES,
142
+
143
+ /**
144
+ Determines whether observers should be automatically notified of changes
145
+ to a key.
146
+
147
+ If you are manually implementing change notifications for a property, you
148
+ can override this method to return NO for properties you do not want the
149
+ observing system to automatically notify for.
150
+
151
+ The default implementation always returns YES.
152
+
153
+ @param key {String} the key that is changing
154
+ @returns {Boolean} YES if automatic notification should occur.
155
+ */
156
+ automaticallyNotifiesObserversFor: function(key) {
157
+ return YES;
158
+ },
159
+
160
+ // ..........................................
161
+ // PROPERTIES
162
+ //
163
+ // Use these methods to get/set properties. This will handle observing
164
+ // notifications as well as allowing you to define functions that can be
165
+ // used as properties.
166
+
167
+ /**
168
+ Retrieves the value of key from the object.
169
+
170
+ This method is generally very similar to using object[key] or object.key,
171
+ however it supports both computed properties and the unknownProperty
172
+ handler.
173
+
174
+ *Computed Properties*
175
+
176
+ Computed properties are methods defined with the property() modifier
177
+ declared at the end, such as:
178
+
179
+ {{{
180
+ fullName: function() {
181
+ return this.getEach('firstName', 'lastName').compact().join(' ');
182
+ }.property('firstName', 'lastName')
183
+ }}}
184
+
185
+ When you call get() on a computed property, the property function will be
186
+ called and the return value will be returned instead of the function
187
+ itself.
188
+
189
+ *Unknown Properties*
190
+
191
+ Likewise, if you try to call get() on a property whose values is
192
+ undefined, the unknownProperty() method will be called on the object.
193
+ If this method reutrns any value other than undefined, it will be returned
194
+ instead. This allows you to implement "virtual" properties that are
195
+ not defined upfront.
196
+
197
+ @param key {String} the property to retrieve
198
+ @returns {Object} the property value or undefined.
199
+
200
+ */
201
+ get: function(key) {
202
+ var ret = this[key], cache ;
203
+ if (ret === undefined) {
204
+ return this.unknownProperty(key) ;
205
+ } else if (ret && ret.isProperty) {
206
+ if (ret.isCacheable) {
207
+ cache = this._kvo_cache ;
208
+ if (!cache) cache = this._kvo_cache = {};
209
+ return (cache[ret.cacheKey] !== undefined) ? cache[ret.cacheKey] : (cache[ret.cacheKey] = ret.call(this,key)) ;
210
+ } else return ret.call(this,key);
211
+ } else return ret ;
212
+ },
213
+
214
+ /**
215
+ Sets the key equal to value.
216
+
217
+ This method is generally very similar to calling object[key] = value or
218
+ object.key = value, except that it provides support for computed
219
+ properties, the unknownProperty() method and property observers.
220
+
221
+ *Computed Properties*
222
+
223
+ If you try to set a value on a key that has a computed property handler
224
+ defined (see the get() method for an example), then set() will call
225
+ that method, passing both the value and key instead of simply changing
226
+ the value itself. This is useful for those times when you need to
227
+ implement a property that is composed of one or more member
228
+ properties.
229
+
230
+ *Unknown Properties*
231
+
232
+ If you try to set a value on a key that is undefined in the target
233
+ object, then the unknownProperty() handler will be called instead. This
234
+ gives you an opportunity to implement complex "virtual" properties that
235
+ are not predefined on the obejct. If unknownProperty() returns
236
+ undefined, then set() will simply set the value on the object.
237
+
238
+ *Property Observers*
239
+
240
+ In addition to changing the property, set() will also register a
241
+ property change with the object. Unless you have placed this call
242
+ inside of a beginPropertyChanges() and endPropertyChanges(), any "local"
243
+ observers (i.e. observer methods declared on the same object), will be
244
+ called immediately. Any "remote" observers (i.e. observer methods
245
+ declared on another object) will be placed in a queue and called at a
246
+ later time in a coelesced manner.
247
+
248
+ *Chaining*
249
+
250
+ In addition to property changes, set() returns the value of the object
251
+ itself so you can do chaining like this:
252
+
253
+ {{{
254
+ record.set('firstName', 'Charles').set('lastName', 'Jolley');
255
+ }}}
256
+
257
+ @param key {String} the property to set
258
+ @param value {Object} the value to set or null.
259
+ @returns {this}
260
+ */
261
+ set: function(key, value) {
262
+ var func = this[key],
263
+ notify = this.automaticallyNotifiesObserversFor(key),
264
+ ret = value,
265
+ cachedep, cache, idx, dfunc ;
266
+
267
+ // if there are any dependent keys and they use caching, then clear the
268
+ // cache.
269
+ if (this._kvo_cacheable && (cache = this._kvo_cache)) {
270
+ // lookup the cached dependents for this key. if undefined, compute.
271
+ // note that if cachdep is set to null is means we figure out it has no
272
+ // cached dependencies already. this is different from undefined.
273
+ cachedep = this._kvo_cachedep;
274
+ if (!cachedep || (cachedep = cachedep[key])===undefined) {
275
+ cachedep = this._kvo_computeCachedDependentsFor(key);
276
+ }
277
+
278
+ if (cachedep) {
279
+ idx = cachedep.length;
280
+ while(--idx>=0) {
281
+ dfunc = cachedep[idx];
282
+ cache[dfunc.cacheKey] = cache[dfunc.lastSetValueKey] = undefined;
283
+ }
284
+ }
285
+ }
286
+
287
+ // set the value.
288
+ if (func && func.isProperty) {
289
+ cache = this._kvo_cache;
290
+ if (func.isVolatile || !cache || (cache[func.lastSetValueKey] !== value)) {
291
+ if (!cache) cache = this._kvo_cache = {};
292
+
293
+ cache[func.lastSetValueKey] = value ;
294
+ if (notify) this.propertyWillChange(key) ;
295
+ ret = func.call(this,key,value) ;
296
+
297
+ // update cached value
298
+ if (func.isCacheable) cache[func.cacheKey] = ret ;
299
+ if (notify) this.propertyDidChange(key, ret, YES) ;
300
+ }
301
+
302
+ } else if (func === undefined) {
303
+ if (notify) this.propertyWillChange(key) ;
304
+ this.unknownProperty(key,value) ;
305
+ if (notify) this.propertyDidChange(key, ret) ;
306
+
307
+ } else {
308
+ if (this[key] !== value) {
309
+ if (notify) this.propertyWillChange(key) ;
310
+ ret = this[key] = value ;
311
+ if (notify) this.propertyDidChange(key, ret) ;
312
+ }
313
+ }
314
+
315
+ return this ;
316
+ },
317
+
318
+ /**
319
+ Called whenever you try to get or set an undefined property.
320
+
321
+ This is a generic property handler. If you define it, it will be called
322
+ when the named property is not yet set in the object. The default does
323
+ nothing.
324
+
325
+ @param key {String} the key that was requested
326
+ @param value {Object} The value if called as a setter, undefined if called as a getter.
327
+ @returns {Object} The new value for key.
328
+ */
329
+ unknownProperty: function(key,value) {
330
+ if (!(value === undefined)) { this[key] = value; }
331
+ return value ;
332
+ },
333
+
334
+ /**
335
+ Begins a grouping of property changes.
336
+
337
+ You can use this method to group property changes so that notifications
338
+ will not be sent until the changes are finished. If you plan to make a
339
+ large number of changes to an object at one time, you should call this
340
+ method at the beginning of the changes to suspend change notifications.
341
+ When you are done making changes, all endPropertyChanges() to allow
342
+ notification to resume.
343
+
344
+ @returns {this}
345
+ */
346
+ beginPropertyChanges: function() {
347
+ this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1;
348
+ return this;
349
+ },
350
+
351
+ /**
352
+ Ends a grouping of property changes.
353
+
354
+ You can use this method to group property changes so that notifications
355
+ will not be sent until the changes are finished. If you plan to make a
356
+ large number of changes to an object at one time, you should call
357
+ beginPropertyChanges() at the beginning of the changes to suspend change
358
+ notifications. When you are done making changes, call this method to allow
359
+ notification to resume.
360
+
361
+ @returns {this}
362
+ */
363
+ endPropertyChanges: function() {
364
+ this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1 ;
365
+ var level = this._kvo_changeLevel, changes = this._kvo_changes;
366
+ if ((level<=0) && changes && (changes.length>0) && !SC.Observers.isObservingSuspended) {
367
+ this._notifyPropertyObservers() ;
368
+ }
369
+ return this ;
370
+ },
371
+
372
+ /**
373
+ Notify the observer system that a property is about to change.
374
+
375
+ Sometimes you need to change a value directly or indirectly without
376
+ actually calling get() or set() on it. In this case, you can use this
377
+ method and propertyDidChange() instead. Calling these two methods
378
+ together will notify all observers that the property has potentially
379
+ changed value.
380
+
381
+ Note that you must always call propertyWillChange and propertyDidChange as
382
+ a pair. If you do not, it may get the property change groups out of order
383
+ and cause notifications to be delivered more often than you would like.
384
+
385
+ @param key {String} The property key that is about to change.
386
+ @returns {this}
387
+ */
388
+ propertyWillChange: function(key) {
389
+ return this ;
390
+ },
391
+
392
+ /**
393
+ Notify the observer system that a property has just changed.
394
+
395
+ Sometimes you need to change a value directly or indirectly without
396
+ actually calling get() or set() on it. In this case, you can use this
397
+ method and propertyWillChange() instead. Calling these two methods
398
+ together will notify all observers that the property has potentially
399
+ changed value.
400
+
401
+ Note that you must always call propertyWillChange and propertyDidChange as
402
+ a pair. If you do not, it may get the property change groups out of order
403
+ and cause notifications to be delivered more often than you would like.
404
+
405
+ @param key {String} The property key that has just changed.
406
+ @param value {Object} The new value of the key. May be null.
407
+ @returns {this}
408
+ */
409
+ propertyDidChange: function(key,value, _keepCache) {
410
+
411
+ this._kvo_revision = (this._kvo_revision || 0) + 1;
412
+ var level = this._kvo_changeLevel || 0,
413
+ cachedep, idx, dfunc, cache, func,
414
+ log = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING===NO);
415
+
416
+ if (this._kvo_cacheable && (cache = this._kvo_cache)) {
417
+
418
+ // clear any cached value
419
+ if (!_keepCache) {
420
+ func = this[key] ;
421
+ if (func && (func instanceof Function)) {
422
+ cache[func.cacheKey] = cache[func.lastSetValueKey] = undefined ;
423
+ }
424
+ }
425
+
426
+ // if there are any dependent keys and they use caching, then clear the
427
+ // cache. This is the same code as is in set. It is inlined for perf.
428
+ cachedep = this._kvo_cachedep;
429
+ if (!cachedep || (cachedep = cachedep[key])===undefined) {
430
+ cachedep = this._kvo_computeCachedDependentsFor(key);
431
+ }
432
+
433
+ if (cachedep) {
434
+ idx = cachedep.length;
435
+ while(--idx>=0) {
436
+ dfunc = cachedep[idx];
437
+ cache[dfunc.cacheKey] = cache[dfunc.lastSetValueKey] = undefined;
438
+ }
439
+ }
440
+ }
441
+
442
+ // save in the change set if queuing changes
443
+ var suspended = SC.Observers.isObservingSuspended;
444
+ if ((level > 0) || suspended) {
445
+ var changes = this._kvo_changes ;
446
+ if (!changes) changes = this._kvo_changes = SC.CoreSet.create() ;
447
+ changes.add(key) ;
448
+
449
+ if (suspended) {
450
+ if (log) console.log("%@%@: will not notify observers because observing is suspended".fmt(SC.KVO_SPACES,this));
451
+ SC.Observers.objectHasPendingChanges(this) ;
452
+ }
453
+
454
+ // otherwise notify property observers immediately
455
+ } else this._notifyPropertyObservers(key) ;
456
+
457
+ return this ;
458
+ },
459
+
460
+ // ..........................................
461
+ // DEPENDENT KEYS
462
+ //
463
+
464
+ /**
465
+ Use this to indicate that one key changes if other keys it depends on
466
+ change. Pass the key that is dependent and additional keys it depends
467
+ upon. You can either pass the additional keys inline as arguments or
468
+ in a single array.
469
+
470
+ You generally do not call this method, but instead pass dependent keys to
471
+ your property() method when you declare a computed property.
472
+
473
+ You can call this method during your init to register the keys that should
474
+ trigger a change notification for your computed properties.
475
+
476
+ @param {String} key the dependent key
477
+ @param {Array|String} dependentKeys one or more dependent keys
478
+ @returns {Object} this
479
+ */
480
+ registerDependentKey: function(key, dependentKeys) {
481
+ var dependents = this._kvo_dependents,
482
+ func = this[key],
483
+ keys, idx, lim, dep, queue;
484
+
485
+ // normalize input.
486
+ if (SC.typeOf(dependentKeys) === SC.T_ARRAY) {
487
+ keys = dependentKeys;
488
+ lim = 0;
489
+ } else {
490
+ keys = arguments;
491
+ lim = 1;
492
+ }
493
+ idx = keys.length;
494
+
495
+ // define dependents if not defined already.
496
+ if (!dependents) this._kvo_dependents = dependents = {} ;
497
+
498
+ // for each key, build array of dependents, add this key...
499
+ // note that we ignore the first argument since it is the key...
500
+ while(--idx >= lim) {
501
+ dep = keys[idx] ;
502
+
503
+ // add dependent key to dependents array of key it depends on
504
+ queue = dependents[dep] ;
505
+ if (!queue) queue = dependents[dep] = [] ;
506
+ queue.push(key) ;
507
+ }
508
+ },
509
+
510
+ /** @private
511
+
512
+ Helper method used by computeCachedDependents. Just loops over the
513
+ array of dependent keys. If the passed function is cacheable, it will
514
+ be added to the queue. Also, recursively call on each keys dependent
515
+ keys.
516
+
517
+ @param {Array} queue the queue to add functions to
518
+ @param {Array} keys the array of dependent keys for this key
519
+ @param {Hash} dependents the _kvo_dependents cache
520
+ @param {SC.Set} seen already seen keys
521
+ @returns {void}
522
+ */
523
+ _kvo_addCachedDependents: function(queue, keys, dependents, seen) {
524
+ var idx = keys.length,
525
+ func, key, deps ;
526
+
527
+ while(--idx >= 0) {
528
+ key = keys[idx];
529
+ seen.add(key);
530
+
531
+ // if the value for this key is a computed property, then add it to the
532
+ // set if it is cacheable, and process any of its dependent keys also.
533
+ func = this[key];
534
+ if (func && (func instanceof Function) && func.isProperty) {
535
+ if (func.isCacheable) queue.push(func); // handle this func
536
+ if ((deps = dependents[key]) && deps.length>0) { // and any dependents
537
+ this._kvo_addCachedDependents(queue, deps, dependents, seen);
538
+ }
539
+ }
540
+ }
541
+
542
+ },
543
+
544
+ /** @private
545
+
546
+ Called by set() whenever it needs to determine which cached dependent
547
+ keys to clear. Recursively searches dependent keys to determine all
548
+ cached property direcly or indirectly affected.
549
+
550
+ The return value is also saved for future reference
551
+
552
+ @param {String} key the key to compute
553
+ @returns {Array}
554
+ */
555
+ _kvo_computeCachedDependentsFor: function(key) {
556
+ var cached = this._kvo_cachedep,
557
+ dependents = this._kvo_dependents,
558
+ keys = dependents ? dependents[key] : null,
559
+ queue, seen ;
560
+ if (!cached) cached = this._kvo_cachedep = {};
561
+
562
+ // if there are no dependent keys, then just set and return null to avoid
563
+ // this mess again.
564
+ if (!keys || keys.length===0) return cached[key] = null;
565
+
566
+ // there are dependent keys, so we need to do the work to find out if
567
+ // any of them or their dependent keys are cached.
568
+ queue = cached[key] = [];
569
+ seen = SC._TMP_SEEN_SET = (SC._TMP_SEEN_SET || SC.CoreSet.create());
570
+ seen.add(key);
571
+ this._kvo_addCachedDependents(queue, keys, dependents, seen);
572
+ seen.clear(); // reset
573
+
574
+ if (queue.length === 0) queue = cached[key] = null ; // turns out nothing
575
+ return queue ;
576
+ },
577
+
578
+ // ..........................................
579
+ // OBSERVERS
580
+ //
581
+
582
+ _kvo_for: function(kvoKey, type) {
583
+ var ret = this[kvoKey] ;
584
+
585
+ if (!this._kvo_cloned) this._kvo_cloned = {} ;
586
+
587
+ // if the item does not exist, create it. Unless type is passed,
588
+ // assume array.
589
+ if (!ret) {
590
+ ret = this[kvoKey] = (type === undefined) ? [] : type.create();
591
+ this._kvo_cloned[kvoKey] = YES ;
592
+
593
+ // if item does exist but has not been cloned, then clone it. Note
594
+ // that all types must implement copy().0
595
+ } else if (!this._kvo_cloned[kvoKey]) {
596
+ ret = this[kvoKey] = ret.copy();
597
+ this._kvo_cloned[kvoKey] = YES;
598
+ }
599
+
600
+ return ret ;
601
+ },
602
+
603
+ /**
604
+ Adds an observer on a property.
605
+
606
+ This is the core method used to register an observer for a property.
607
+
608
+ Once you call this method, anytime the key's value is set, your observer
609
+ will be notified. Note that the observers are triggered anytime the
610
+ value is set, regardless of whether it has actually changed. Your
611
+ observer should be prepared to handle that.
612
+
613
+ You can also pass an optional context parameter to this method. The
614
+ context will be passed to your observer method whenever it is triggered.
615
+ Note that if you add the same target/method pair on a key multiple times
616
+ with different context parameters, your observer will only be called once
617
+ with the last context you passed.
618
+
619
+ h2. Observer Methods
620
+
621
+ Observer methods you pass should generally have the following signature if
622
+ you do not pass a "context" parameter:
623
+
624
+ {{{
625
+ fooDidChange: function(sender, key, value, rev);
626
+ }}}
627
+
628
+ The sender is the object that changed. The key is the property that
629
+ changes. The value property is currently reserved and unused. The rev
630
+ is the last property revision of the object when it changed, which you can
631
+ use to detect if the key value has really changed or not.
632
+
633
+ If you pass a "context" parameter, the context will be passed before the
634
+ revision like so:
635
+
636
+ {{{
637
+ fooDidChange: function(sender, key, value, context, rev);
638
+ }}}
639
+
640
+ Usually you will not need the value, context or revision parameters at
641
+ the end. In this case, it is common to write observer methods that take
642
+ only a sender and key value as parameters or, if you aren't interested in
643
+ any of these values, to write an observer that has no parameters at all.
644
+
645
+ @param key {String} the key to observer
646
+ @param target {Object} the target object to invoke
647
+ @param method {String|Function} the method to invoke.
648
+ @param context {Object} optional context
649
+ @returns {SC.Object} self
650
+ */
651
+ addObserver: function(key, target, method, context) {
652
+
653
+ var kvoKey, chain, chains, observers;
654
+
655
+ // normalize. if a function is passed to target, make it the method.
656
+ if (method === undefined) {
657
+ method = target; target = this ;
658
+ }
659
+ if (!target) target = this ;
660
+ if (SC.typeOf(method) === SC.T_STRING) method = target[method] ;
661
+ if (!method) throw "You must pass a method to addObserver()" ;
662
+
663
+ // Normalize key...
664
+ key = key.toString() ;
665
+ if (key.indexOf('.') >= 0) {
666
+
667
+ // create the chain and save it for later so we can tear it down if
668
+ // needed.
669
+ chain = SC._ChainObserver.createChain(this, key, target, method, context);
670
+ chain.masterTarget = target;
671
+ chain.masterMethod = method ;
672
+
673
+ // Save in set for chain observers.
674
+ this._kvo_for(SC.keyFor('_kvo_chains', key)).push(chain);
675
+
676
+ // Create observers if needed...
677
+ } else {
678
+
679
+ // Special case to support reduced properties. If the property
680
+ // key begins with '@' and its value is unknown, then try to get its
681
+ // value. This will configure the dependent keys if needed.
682
+ if ((this[key] === undefined) && (key.indexOf('@') === 0)) {
683
+ this.get(key) ;
684
+ }
685
+
686
+ if (target === this) target = null ; // use null for observers only.
687
+ kvoKey = SC.keyFor('_kvo_observers', key);
688
+ this._kvo_for(kvoKey, SC._ObserverSet).add(target, method, context);
689
+ this._kvo_for('_kvo_observed_keys', SC.CoreSet).add(key) ;
690
+ }
691
+
692
+ if (this.didAddObserver) this.didAddObserver(key, target, method);
693
+ return this;
694
+ },
695
+
696
+ /**
697
+ Remove an observer you have previously registered on this object. Pass
698
+ the same key, target, and method you passed to addObserver() and your
699
+ target will no longer receive notifications.
700
+
701
+ @returns {SC.Observable} reciever
702
+ */
703
+ removeObserver: function(key, target, method) {
704
+
705
+ var kvoKey, chains, chain, observers, idx ;
706
+
707
+ // normalize. if a function is passed to target, make it the method.
708
+ if (method === undefined) {
709
+ method = target; target = this ;
710
+ }
711
+ if (!target) target = this ;
712
+ if (SC.typeOf(method) === SC.T_STRING) method = target[method] ;
713
+ if (!method) throw "You must pass a method to addObserver()" ;
714
+
715
+ // if the key contains a '.', this is a chained observer.
716
+ key = key.toString() ;
717
+ if (key.indexOf('.') >= 0) {
718
+
719
+ // try to find matching chains
720
+ kvoKey = SC.keyFor('_kvo_chains', key);
721
+ if (chains = this[kvoKey]) {
722
+
723
+ // if chains have not been cloned yet, do so now.
724
+ chains = this._kvo_for(kvoKey) ;
725
+
726
+ // remove any chains
727
+ idx = chains.length;
728
+ while(--idx >= 0) {
729
+ chain = chains[idx];
730
+ if (chain && (chain.masterTarget===target) && (chain.masterMethod===method)) {
731
+ chains[idx] = chain.destroyChain() ;
732
+ }
733
+ }
734
+ }
735
+
736
+ // otherwise, just like a normal observer.
737
+ } else {
738
+ if (target === this) target = null ; // use null for observers only.
739
+ kvoKey = SC.keyFor('_kvo_observers', key) ;
740
+ if (observers = this[kvoKey]) {
741
+ // if observers have not been cloned yet, do so now
742
+ observers = this._kvo_for(kvoKey) ;
743
+ observers.remove(target, method) ;
744
+ if (observers.targets <= 0) {
745
+ this._kvo_for('_kvo_observed_keys', SC.CoreSet).remove(key);
746
+ }
747
+ }
748
+ }
749
+
750
+ if (this.didRemoveObserver) this.didRemoveObserver(key, target, method);
751
+ return this;
752
+ },
753
+
754
+ /**
755
+ Returns YES if the object currently has observers registered for a
756
+ particular key. You can use this method to potentially defer performing
757
+ an expensive action until someone begins observing a particular property
758
+ on the object.
759
+
760
+ @param {String} key key to check
761
+ @returns {Boolean}
762
+ */
763
+ hasObserverFor: function(key) {
764
+ SC.Observers.flush(this) ; // hookup as many observers as possible.
765
+
766
+ var observers = this[SC.keyFor('_kvo_observers', key)],
767
+ locals = this[SC.keyFor('_kvo_local', key)],
768
+ members ;
769
+
770
+ if (locals && locals.length>0) return YES ;
771
+ if (observers && observers.getMembers().length>0) return YES ;
772
+ return NO ;
773
+ },
774
+
775
+ /**
776
+ This method will register any observers and computed properties saved on
777
+ the object. Normally you do not need to call this method youself. It
778
+ is invoked automatically just before property notifications are sent and
779
+ from the init() method of SC.Object. You may choose to call this
780
+ from your own initialization method if you are using SC.Observable in
781
+ a non-SC.Object-based object.
782
+
783
+ This method looks for several private variables, which you can setup,
784
+ to initialize:
785
+
786
+ - _observers: this should contain an array of key names for observers
787
+ you need to configure.
788
+
789
+ - _bindings: this should contain an array of key names that configure
790
+ bindings.
791
+
792
+ - _properties: this should contain an array of key names for computed
793
+ properties.
794
+
795
+ @returns {Object} this
796
+ */
797
+ initObservable: function() {
798
+ if (this._observableInited) return ;
799
+ this._observableInited = YES ;
800
+
801
+ var loc, keys, key, value, observer, propertyPaths, propertyPathsLength ;
802
+
803
+ // Loop through observer functions and register them
804
+ if (keys = this._observers) {
805
+ var len = keys.length ;
806
+ for(loc=0;loc<len;loc++) {
807
+ key = keys[loc]; observer = this[key] ;
808
+ propertyPaths = observer.propertyPaths ;
809
+ propertyPathsLength = (propertyPaths) ? propertyPaths.length : 0 ;
810
+ for(var ploc=0;ploc<propertyPathsLength;ploc++) {
811
+ var path = propertyPaths[ploc] ;
812
+ var dotIndex = path.indexOf('.') ;
813
+ // handle most common case, observing a local property
814
+ if (dotIndex < 0) {
815
+ this.addObserver(path, this, observer) ;
816
+
817
+ // next most common case, use a chained observer
818
+ } else if (path.indexOf('*') === 0) {
819
+ this.addObserver(path.slice(1), this, observer) ;
820
+
821
+ // otherwise register the observer in the observers queue. This
822
+ // will add the observer now or later when the named path becomes
823
+ // available.
824
+ } else {
825
+ var root = null ;
826
+
827
+ // handle special cases for observers that look to the local root
828
+ if (dotIndex === 0) {
829
+ root = this; path = path.slice(1) ;
830
+ } else if (dotIndex===4 && path.slice(0,5) === 'this.') {
831
+ root = this; path = path.slice(5) ;
832
+ } else if (dotIndex<0 && path.length===4 && path === 'this') {
833
+ root = this; path = '';
834
+ }
835
+
836
+ SC.Observers.addObserver(path, this, observer, root);
837
+ }
838
+ }
839
+ }
840
+ }
841
+
842
+ // Add Bindings
843
+ this.bindings = []; // will be filled in by the bind() method.
844
+ if (keys = this._bindings) {
845
+ for(loc=0;loc<keys.length;loc++) {
846
+ // get propertyKey
847
+ key = keys[loc] ; value = this[key] ;
848
+ var propertyKey = key.slice(0,-7) ; // contentBinding => content
849
+ this[key] = this.bind(propertyKey, value) ;
850
+ }
851
+ }
852
+
853
+ // Add Properties
854
+ if (keys = this._properties) {
855
+ for(loc=0;loc<keys.length;loc++) {
856
+ key = keys[loc];
857
+ if (value = this[key]) {
858
+
859
+ // activate cacheable only if needed for perf reasons
860
+ if (value.isCacheable) this._kvo_cacheable = YES;
861
+
862
+ // register dependent keys
863
+ if (value.dependentKeys && (value.dependentKeys.length>0)) {
864
+ this.registerDependentKey(key, value.dependentKeys) ;
865
+ }
866
+ }
867
+ }
868
+ }
869
+
870
+ },
871
+
872
+ // ..........................................
873
+ // NOTIFICATION
874
+ //
875
+
876
+ /**
877
+ Returns an array with all of the observers registered for the specified
878
+ key. This is intended for debugging purposes only. You generally do not
879
+ want to rely on this method for production code.
880
+
881
+ @params key {String} the key to evaluate
882
+ @returns {Array} array of Observer objects, describing the observer.
883
+ */
884
+ observersForKey: function(key) {
885
+ var observers = this._kvo_for('_kvo_observers', key) ;
886
+ return observers.getMembers() || [] ;
887
+ },
888
+
889
+ // this private method actually notifies the observers for any keys in the
890
+ // observer queue. If you pass a key it will be added to the queue.
891
+ _notifyPropertyObservers: function(key) {
892
+
893
+ if (!this._observableInited) this.initObservable() ;
894
+
895
+ SC.Observers.flush(this) ; // hookup as many observers as possible.
896
+
897
+ var log = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING===NO) ;
898
+ var observers, changes, dependents, starObservers, idx, keys, rev ;
899
+ var members, membersLength, member, memberLoc, target, method, loc, func ;
900
+ var context, spaces, cache ;
901
+
902
+ if (log) {
903
+ spaces = SC.KVO_SPACES = (SC.KVO_SPACES || '') + ' ';
904
+ console.log('%@%@: notifying observers after change to key "%@"'.fmt(spaces, this, key));
905
+ }
906
+
907
+ // Get any starObservers -- they will be notified of all changes.
908
+ starObservers = this['_kvo_observers_*'] ;
909
+
910
+ // prevent notifications from being sent until complete
911
+ this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1;
912
+
913
+ // keep sending notifications as long as there are changes
914
+ while(((changes = this._kvo_changes) && (changes.length > 0)) || key) {
915
+
916
+ // increment revision
917
+ rev = ++this.propertyRevision ;
918
+
919
+ // save the current set of changes and swap out the kvo_changes so that
920
+ // any set() calls by observers will be saved in a new set.
921
+ if (!changes) changes = SC.CoreSet.create() ;
922
+ this._kvo_changes = null ;
923
+
924
+ // Add the passed key to the changes set. If a '*' was passed, then
925
+ // add all keys in the observers to the set...
926
+ // once finished, clear the key so the loop will end.
927
+ if (key === '*') {
928
+ changes.add('*') ;
929
+ changes.addEach(this._kvo_for('_kvo_observed_keys', SC.CoreSet));
930
+
931
+ } else if (key) changes.add(key) ;
932
+
933
+ // Now go through the set and add all dependent keys...
934
+ if (dependents = this._kvo_dependents) {
935
+
936
+ // NOTE: each time we loop, we check the changes length, this
937
+ // way any dependent keys added to the set will also be evaluated...
938
+ for(idx=0;idx<changes.length;idx++) {
939
+ key = changes[idx] ;
940
+ keys = dependents[key] ;
941
+
942
+ // for each dependent key, add to set of changes. Also, if key
943
+ // value is a cacheable property, clear the cached value...
944
+ if (keys && (loc = keys.length)) {
945
+ if (log) {
946
+ console.log("%@...including dependent keys for %@: %@".fmt(spaces, key, keys));
947
+ }
948
+ cache = this._kvo_cache;
949
+ if (!cache) cache = this._kvo_cache = {};
950
+ while(--loc >= 0) {
951
+ changes.add(key = keys[loc]);
952
+ if (func = this[key]) {
953
+ this[func.cacheKey] = undefined;
954
+ cache[func.cacheKey] = cache[func.lastSetValueKey] = undefined;
955
+ } // if (func=)
956
+ } // while (--loc)
957
+ } // if (keys &&
958
+ } // for(idx...
959
+ } // if (dependents...)
960
+
961
+ // now iterate through all changed keys and notify observers.
962
+ while(changes.length > 0) {
963
+ key = changes.pop() ; // the changed key
964
+
965
+ // find any observers and notify them...
966
+ observers = this[SC.keyFor('_kvo_observers', key)];
967
+ if (observers) {
968
+ members = observers.getMembers() ;
969
+ membersLength = members.length ;
970
+ for(memberLoc=0;memberLoc < membersLength; memberLoc++) {
971
+ member = members[memberLoc] ;
972
+ if (member[3] === rev) continue ; // skip notified items.
973
+
974
+ target = member[0] || this;
975
+ method = member[1] ;
976
+ context = member[2];
977
+ member[3] = rev;
978
+
979
+ if (log) console.log('%@...firing observer on %@ for key "%@"'.fmt(spaces, target, key));
980
+ if (context !== undefined) {
981
+ method.call(target, this, key, null, context, rev);
982
+ } else {
983
+ method.call(target, this, key, null, rev) ;
984
+ }
985
+ }
986
+ }
987
+
988
+ // look for local observers. Local observers are added by SC.Object
989
+ // as an optimization to avoid having to add observers for every
990
+ // instance when you are just observing your local object.
991
+ members = this[SC.keyFor('_kvo_local', key)];
992
+ if (members) {
993
+ membersLength = members.length ;
994
+ for(memberLoc=0;memberLoc<membersLength;memberLoc++) {
995
+ member = members[memberLoc];
996
+ method = this[member] ; // try to find observer function
997
+ if (method) {
998
+ if (log) console.log('%@...firing local observer %@.%@ for key "%@"'.fmt(spaces, this, member, key));
999
+ method.call(this, this, key, null, rev);
1000
+ }
1001
+ }
1002
+ }
1003
+
1004
+ // if there are starObservers, do the same thing for them
1005
+ if (starObservers && key !== '*') {
1006
+ members = starObservers.getMembers() ;
1007
+ membersLength = members.length ;
1008
+ for(memberLoc=0;memberLoc < membersLength; memberLoc++) {
1009
+ member = members[memberLoc] ;
1010
+ target = member[0] || this;
1011
+ method = member[1] ;
1012
+ context = member[2] ;
1013
+
1014
+ if (log) console.log('%@...firing * observer on %@ for key "%@"'.fmt(spaces, target, key));
1015
+ if (context !== undefined) {
1016
+ method.call(target, this, key, null, context, rev);
1017
+ } else {
1018
+ method.call(target, this, key, null, rev) ;
1019
+ }
1020
+ }
1021
+ }
1022
+
1023
+ // if there is a default property observer, call that also
1024
+ if (this.propertyObserver) {
1025
+ if (log) console.log('%@...firing %@.propertyObserver for key "%@"'.fmt(spaces, this, key));
1026
+ this.propertyObserver(this, key, null, rev);
1027
+ }
1028
+ } // while(changes.length>0)
1029
+
1030
+ // changes set should be empty. release it for reuse
1031
+ if (changes) changes.destroy() ;
1032
+
1033
+ // key is no longer needed; clear it to avoid infinite loops
1034
+ key = null ;
1035
+
1036
+ } // while (changes)
1037
+
1038
+ // done with loop, reduce change level so that future sets can resume
1039
+ this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1;
1040
+
1041
+ if (log) SC.KVO_SPACES = spaces.slice(0, -2);
1042
+
1043
+ return YES ; // finished successfully
1044
+ },
1045
+
1046
+ // ..........................................
1047
+ // BINDINGS
1048
+ //
1049
+
1050
+ /**
1051
+ Manually add a new binding to an object. This is the same as doing
1052
+ the more familiar propertyBinding: 'property.path' approach.
1053
+
1054
+ @param {String} toKey the key to bind to
1055
+ @param {Object} target target or property path to bind from
1056
+ @param {String|Function} method method for target to bind from
1057
+ @returns {SC.Binding} new binding instance
1058
+ */
1059
+ bind: function(toKey, target, method) {
1060
+
1061
+ var binding ;
1062
+
1063
+ // normalize...
1064
+ if (method !== undefined) target = [target, method];
1065
+
1066
+ // if a string or array (i.e. tuple) is passed, convert this into a
1067
+ // binding. If a binding default was provided, use that.
1068
+ var pathType = SC.typeOf(target) ;
1069
+ if (pathType === SC.T_STRING || pathType === SC.T_ARRAY) {
1070
+ binding = this[toKey + 'BindingDefault'] || SC.Binding;
1071
+ binding = binding.beget().from(target) ;
1072
+ } else binding = target ;
1073
+
1074
+ // finish configuring the binding and then connect it.
1075
+ binding = binding.to(toKey, this).connect() ;
1076
+ this.bindings.push(binding) ;
1077
+
1078
+ return binding ;
1079
+ },
1080
+
1081
+ /**
1082
+ didChangeFor makes it easy for you to verify that you haven't seen any
1083
+ changed values. You need to use this if your method observes multiple
1084
+ properties. To use this, call it like this:
1085
+
1086
+ if (this.didChangeFor('render','height','width')) {
1087
+ // DO SOMETHING HERE IF CHANGED.
1088
+ }
1089
+ */
1090
+ didChangeFor: function(context) {
1091
+
1092
+ context = SC.hashFor(context) ; // get a hash key we can use in caches.
1093
+
1094
+ // setup caches...
1095
+ var valueCache = this._kvo_didChange_valueCache ;
1096
+ if (!valueCache) valueCache = this._kvo_didChange_valueCache = {};
1097
+ var revisionCache = this._kvo_didChange_revisionCache;
1098
+ if (!revisionCache) revisionCache=this._kvo_didChange_revisionCache={};
1099
+
1100
+ // get the cache of values and revisions already seen in this context
1101
+ var seenValues = valueCache[context] || {} ;
1102
+ var seenRevisions = revisionCache[context] || {} ;
1103
+
1104
+ // prepare too loop!
1105
+ var ret = false ;
1106
+ var currentRevision = this._kvo_revision || 0 ;
1107
+ var idx = arguments.length ;
1108
+ while(--idx >= 1) { // NB: loop only to 1 to ignore context arg.
1109
+ var key = arguments[idx];
1110
+
1111
+ // has the kvo revision changed since the last time we did this?
1112
+ if (seenRevisions[key] != currentRevision) {
1113
+ // yes, check the value with the last seen value
1114
+ var value = this.get(key) ;
1115
+ if (seenValues[key] !== value) ret = true ; // did change!
1116
+ }
1117
+ seenRevisions[key] = currentRevision;
1118
+ }
1119
+
1120
+ valueCache[context] = seenValues ;
1121
+ revisionCache[context] = seenRevisions ;
1122
+ return ret ;
1123
+ },
1124
+
1125
+
1126
+
1127
+ /**
1128
+ Sets the property only if the passed value is different from the
1129
+ current value. Depending on how expensive a get() is on this property,
1130
+ this may be more efficient.
1131
+
1132
+ @param key {String} the key to change
1133
+ @param value {Object} the value to change
1134
+ @returns {this}
1135
+ */
1136
+ setIfChanged: function(key, value) {
1137
+ return (this.get(key) !== value) ? this.set(key, value) : this ;
1138
+ },
1139
+
1140
+ /**
1141
+ Navigates the property path, returning the value at that point.
1142
+
1143
+ If any object in the path is undefined, returns undefined.
1144
+ */
1145
+ getPath: function(path) {
1146
+ var tuple = SC.tupleForPropertyPath(path, this) ;
1147
+ if (tuple === null || tuple[0] === null) return undefined ;
1148
+ return tuple[0].get(tuple[1]) ;
1149
+ },
1150
+
1151
+ /**
1152
+ Navigates the property path, finally setting the value.
1153
+
1154
+ @param path {String} the property path to set
1155
+ @param value {Object} the value to set
1156
+ @returns {this}
1157
+ */
1158
+ setPath: function(path, value) {
1159
+ if (path.indexOf('.') >= 0) {
1160
+ var tuple = SC.tupleForPropertyPath(path, this) ;
1161
+ if (!tuple || !tuple[0]) return null ;
1162
+ tuple[0].set(tuple[1], value) ;
1163
+ } else this.set(path, value) ; // shortcut
1164
+ return this;
1165
+ },
1166
+
1167
+ /**
1168
+ Navigates the property path, finally setting the value but only if
1169
+ the value does not match the current value. This will avoid sending
1170
+ unecessary change notifications.
1171
+
1172
+ @param path {String} the property path to set
1173
+ @param value {Object} the value to set
1174
+ @returns {Object} this
1175
+ */
1176
+ setPathIfChanged: function(path, value) {
1177
+ if (path.indexOf('.') >= 0) {
1178
+ var tuple = SC.tupleForPropertyPath(path, this) ;
1179
+ if (!tuple || !tuple[0]) return null ;
1180
+ if (tuple[0].get(tuple[1]) !== value) {
1181
+ tuple[0].set(tuple[1], value) ;
1182
+ }
1183
+ } else this.setIfChanged(path, value) ; // shortcut
1184
+ return this;
1185
+ },
1186
+
1187
+ /**
1188
+ Convenience method to get an array of properties.
1189
+
1190
+ Pass in multiple property keys or an array of property keys. This
1191
+ method uses getPath() so you can also pass key paths.
1192
+
1193
+ @returns {Array} Values of property keys.
1194
+ */
1195
+ getEach: function() {
1196
+ var keys = SC.A(arguments) ;
1197
+ var ret = [];
1198
+ for(var idx=0; idx<keys.length;idx++) {
1199
+ ret[ret.length] = this.getPath(keys[idx]);
1200
+ }
1201
+ return ret ;
1202
+ },
1203
+
1204
+
1205
+ /**
1206
+ Increments the value of a property.
1207
+
1208
+ @param key {String} property name
1209
+ @returns {Number} new value of property
1210
+ */
1211
+ incrementProperty: function(key) {
1212
+ this.set(key,(this.get(key) || 0)+1);
1213
+ return this.get(key) ;
1214
+ },
1215
+
1216
+ /**
1217
+ decrements a property
1218
+
1219
+ @param key {String} property name
1220
+ @returns {Number} new value of property
1221
+ */
1222
+ decrementProperty: function(key) {
1223
+ this.set(key,(this.get(key) || 0) - 1 ) ;
1224
+ return this.get(key) ;
1225
+ },
1226
+
1227
+ /**
1228
+ Inverts a property. Property should be a bool.
1229
+
1230
+ @param key {String} property name
1231
+ @param value {Object} optional parameter for "true" value
1232
+ @param alt {Object} optional parameter for "false" value
1233
+ @returns {Object} new value
1234
+ */
1235
+ toggleProperty: function(key,value,alt) {
1236
+ if (value === undefined) value = true ;
1237
+ if (alt === undefined) alt = false ;
1238
+ value = (this.get(key) == value) ? alt : value ;
1239
+ this.set(key,value);
1240
+ return this.get(key) ;
1241
+ },
1242
+
1243
+ /**
1244
+ Convenience method to call propertyWillChange/propertyDidChange.
1245
+
1246
+ Sometimes you need to notify observers that a property has changed value
1247
+ without actually changing this value. In those cases, you can use this
1248
+ method as a convenience instead of calling propertyWillChange() and
1249
+ propertyDidChange().
1250
+
1251
+ @param key {String} The property key that has just changed.
1252
+ @param value {Object} The new value of the key. May be null.
1253
+ @returns {this}
1254
+ */
1255
+ notifyPropertyChange: function(key, value) {
1256
+ this.propertyWillChange(key) ;
1257
+ this.propertyDidChange(key, value) ;
1258
+ return this;
1259
+ },
1260
+
1261
+ /**
1262
+ Notifies all of observers of a property changes.
1263
+
1264
+ Sometimes when you make a major update to your object, it is cheaper to
1265
+ simply notify all observers that their property might have changed than
1266
+ to figure out specifically which properties actually did change.
1267
+
1268
+ In those cases, you can simply call this method to notify all property
1269
+ observers immediately. Note that this ignores property groups.
1270
+
1271
+ @returns {this}
1272
+ */
1273
+ allPropertiesDidChange: function() {
1274
+ this._kvo_cache = null; //clear cached props
1275
+ this._notifyPropertyObservers('*') ;
1276
+ return this ;
1277
+ },
1278
+
1279
+ addProbe: function(key) { this.addObserver(key,SC.logChange); },
1280
+ removeProbe: function(key) { this.removeObserver(key,SC.logChange); },
1281
+
1282
+ /**
1283
+ Logs the named properties to the console.
1284
+
1285
+ @param propertyNames one or more property names
1286
+ */
1287
+ logProperty: function() {
1288
+ var props = SC.$A(arguments) ;
1289
+ for(var idx=0;idx<props.length; idx++) {
1290
+ var prop = props[idx] ;
1291
+ console.log('%@:%@: '.fmt(SC.guidFor(this), prop), this.get(prop)) ;
1292
+ }
1293
+ },
1294
+
1295
+ propertyRevision: 1
1296
+
1297
+ } ;
1298
+
1299
+ /** @private used by addProbe/removeProbe */
1300
+ SC.logChange = function logChange(target, key, value) {
1301
+ console.log("CHANGE: %@[%@] => %@".fmt(target, key, target.get(key))) ;
1302
+ };
1303
+
1304
+ // Make all Array's observable
1305
+ SC.mixin(Array.prototype, SC.Observable) ;