sproutcore 1.8.2.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (274) hide show
  1. data/VERSION.yml +2 -2
  2. data/lib/buildtasks/helpers/file_rule_list.rb +3 -3
  3. data/lib/frameworks/sproutcore/Buildfile +1 -1
  4. data/lib/frameworks/sproutcore/CHANGELOG.md +235 -16
  5. data/lib/frameworks/sproutcore/apps/media_examples/Buildfile +13 -0
  6. data/lib/frameworks/sproutcore/apps/media_examples/core.js +35 -0
  7. data/lib/frameworks/sproutcore/apps/media_examples/resources/loading.rhtml +3 -0
  8. data/lib/frameworks/sproutcore/apps/media_examples/resources/main_page.js +53 -0
  9. data/lib/frameworks/sproutcore/apps/media_examples/views/audio_view.js +100 -0
  10. data/lib/frameworks/sproutcore/apps/media_examples/views/camera_view.js +39 -0
  11. data/lib/frameworks/sproutcore/apps/media_examples/views/capabilities_view.js +116 -0
  12. data/lib/frameworks/sproutcore/apps/media_examples/views/microphone_view.js +40 -0
  13. data/lib/frameworks/sproutcore/apps/media_examples/views/video_view.js +107 -0
  14. data/lib/frameworks/sproutcore/apps/showcase/Buildfile +11 -0
  15. data/lib/frameworks/sproutcore/apps/showcase/README +15 -0
  16. data/lib/frameworks/sproutcore/apps/showcase/controllers/source_controller.js +15 -0
  17. data/lib/frameworks/sproutcore/apps/showcase/controllers/source_tree_controller.js +212 -0
  18. data/lib/frameworks/sproutcore/apps/showcase/core.js +170 -0
  19. data/lib/frameworks/sproutcore/apps/showcase/main.js +27 -0
  20. data/lib/frameworks/sproutcore/apps/showcase/resources/_theme.css +18 -0
  21. data/lib/frameworks/sproutcore/apps/showcase/resources/api.css +80 -0
  22. data/lib/frameworks/sproutcore/apps/showcase/resources/favicon.ico +0 -0
  23. data/lib/frameworks/sproutcore/apps/showcase/resources/images/alarm-clock.png +0 -0
  24. data/lib/frameworks/sproutcore/apps/showcase/resources/images/balloon-facebook.png +0 -0
  25. data/lib/frameworks/sproutcore/apps/showcase/resources/images/balloon-twitter.png +0 -0
  26. data/lib/frameworks/sproutcore/apps/showcase/resources/images/balloon.png +0 -0
  27. data/lib/frameworks/sproutcore/apps/showcase/resources/images/bullet.png +0 -0
  28. data/lib/frameworks/sproutcore/apps/showcase/resources/images/calendar-insert.png +0 -0
  29. data/lib/frameworks/sproutcore/apps/showcase/resources/images/cross.png +0 -0
  30. data/lib/frameworks/sproutcore/apps/showcase/resources/images/example-box-bg.png +0 -0
  31. data/lib/frameworks/sproutcore/apps/showcase/resources/images/fruit-grape.png +0 -0
  32. data/lib/frameworks/sproutcore/apps/showcase/resources/images/fruit-lime.png +0 -0
  33. data/lib/frameworks/sproutcore/apps/showcase/resources/images/fruit-orange.png +0 -0
  34. data/lib/frameworks/sproutcore/apps/showcase/resources/images/fruit.png +0 -0
  35. data/lib/frameworks/sproutcore/apps/showcase/resources/images/glow.png +0 -0
  36. data/lib/frameworks/sproutcore/apps/showcase/resources/images/green-dot.png +0 -0
  37. data/lib/frameworks/sproutcore/apps/showcase/resources/images/grey-dot.png +0 -0
  38. data/lib/frameworks/sproutcore/apps/showcase/resources/images/logo.png +0 -0
  39. data/lib/frameworks/sproutcore/apps/showcase/resources/images/pixels.png +0 -0
  40. data/lib/frameworks/sproutcore/apps/showcase/resources/images/red-dot.png +0 -0
  41. data/lib/frameworks/sproutcore/apps/showcase/resources/images/sproutcore-logo.png +0 -0
  42. data/lib/frameworks/sproutcore/apps/showcase/resources/images/sproutcore-startup-landscape.jpg +0 -0
  43. data/lib/frameworks/sproutcore/apps/{test_controls → showcase}/resources/loading.rhtml +1 -1
  44. data/lib/frameworks/sproutcore/apps/showcase/resources/main_page.js +61 -0
  45. data/lib/frameworks/sproutcore/apps/showcase/resources/stylesheet.css +365 -0
  46. data/lib/frameworks/sproutcore/apps/showcase/resources/views_page.js +64 -0
  47. data/lib/frameworks/sproutcore/apps/showcase/system/views_item_content.js +59 -0
  48. data/lib/frameworks/sproutcore/apps/showcase/theme.js +27 -0
  49. data/lib/frameworks/sproutcore/apps/showcase/views/button_views.js +55 -0
  50. data/lib/frameworks/sproutcore/apps/showcase/views/checkbox_views.js +34 -0
  51. data/lib/frameworks/sproutcore/apps/showcase/views/container_views.js +29 -0
  52. data/lib/frameworks/sproutcore/apps/showcase/views/date_field_views.js +30 -0
  53. data/lib/frameworks/sproutcore/apps/showcase/views/disclosure_views.js +22 -0
  54. data/lib/frameworks/sproutcore/apps/showcase/views/grid_views.js +28 -0
  55. data/lib/frameworks/sproutcore/apps/showcase/views/image_button_views.js +22 -0
  56. data/lib/frameworks/sproutcore/apps/showcase/views/image_views.js +51 -0
  57. data/lib/frameworks/sproutcore/apps/showcase/views/label_views.js +53 -0
  58. data/lib/frameworks/sproutcore/apps/showcase/views/list_views.js +31 -0
  59. data/lib/frameworks/sproutcore/apps/showcase/views/popup_button_views.js +24 -0
  60. data/lib/frameworks/sproutcore/apps/showcase/views/progress_views.js +26 -0
  61. data/lib/frameworks/sproutcore/apps/showcase/views/radio_views.js +30 -0
  62. data/lib/frameworks/sproutcore/apps/showcase/views/scroll_views.js +40 -0
  63. data/lib/frameworks/sproutcore/apps/showcase/views/segmented_views.js +90 -0
  64. data/lib/frameworks/sproutcore/apps/showcase/views/select_views.js +64 -0
  65. data/lib/frameworks/sproutcore/apps/showcase/views/slider_views.js +46 -0
  66. data/lib/frameworks/sproutcore/apps/showcase/views/source_list_views.js +23 -0
  67. data/lib/frameworks/sproutcore/apps/showcase/views/split_views.js +22 -0
  68. data/lib/frameworks/sproutcore/apps/showcase/views/stacked_views.js +23 -0
  69. data/lib/frameworks/sproutcore/apps/showcase/views/static_content_views.js +23 -0
  70. data/lib/frameworks/sproutcore/apps/showcase/views/tab_views.js +51 -0
  71. data/lib/frameworks/sproutcore/apps/showcase/views/text_field_views.js +52 -0
  72. data/lib/frameworks/sproutcore/apps/showcase/views/toolbar_views.js +23 -0
  73. data/lib/frameworks/sproutcore/apps/showcase/views/views_item_view.js +91 -0
  74. data/lib/frameworks/sproutcore/apps/showcase/views/views_list_view.js +67 -0
  75. data/lib/frameworks/sproutcore/apps/showcase/views/web_views.js +32 -0
  76. data/lib/frameworks/sproutcore/apps/showcase/views/well_views.js +29 -0
  77. data/lib/frameworks/sproutcore/apps/showcase/views/workspace_views.js +23 -0
  78. data/lib/frameworks/sproutcore/apps/tests/english.lproj/strings.js +2 -1
  79. data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +91 -51
  80. data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +93 -27
  81. data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +196 -15
  82. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +1 -1
  83. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +26 -10
  84. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/object.js +90 -92
  85. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/object.js +69 -39
  86. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/selection_support.js +1 -1
  87. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +769 -0
  88. data/lib/frameworks/sproutcore/frameworks/{desktop → core_foundation}/system/key_bindings.js +0 -0
  89. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +4 -4
  90. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/req_anim_frame.js +31 -0
  91. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +7 -1
  92. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +8 -6
  93. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/array_case.js +49 -0
  94. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/array/selection_support.js +1 -1
  95. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/ext/object_test.js +106 -0
  96. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/color.js +448 -0
  97. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/render_context/escape_html.js +8 -1
  98. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/timer/invokeLater.js +24 -24
  99. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +5 -5
  100. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/animation.js +90 -30
  101. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +14 -6
  102. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/touch.js +113 -0
  103. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +64 -8
  104. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +20 -4
  105. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +58 -38
  106. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/touch.js +32 -39
  107. data/lib/frameworks/sproutcore/frameworks/core_tools/models/target.js +20 -15
  108. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +19 -15
  109. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +1 -1
  110. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +16 -16
  111. data/lib/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +32 -32
  112. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +53 -38
  113. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +9 -8
  114. data/lib/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +26 -26
  115. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +1 -3
  116. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +4 -3
  117. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +0 -4
  118. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +96 -8
  119. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/datetime_recordattribute.js +22 -4
  120. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/data_store.js +24 -24
  121. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +376 -37
  122. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array.js +51 -53
  123. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +108 -66
  124. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +33 -35
  125. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +6 -4
  126. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/compare.js +33 -3
  127. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/createRecord.js +181 -15
  128. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +6 -0
  129. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +3 -1
  130. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_fast_path.js +2 -1
  131. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +153 -6
  132. data/lib/frameworks/sproutcore/frameworks/desktop/panes/modal.js +39 -18
  133. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +2 -1
  134. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +6 -7
  135. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +139 -50
  136. data/lib/frameworks/sproutcore/frameworks/{foundation → desktop}/resources/button_view.css +3 -3
  137. data/lib/frameworks/sproutcore/frameworks/{foundation → desktop}/resources/checkbox_view.css +4 -0
  138. data/lib/frameworks/sproutcore/frameworks/desktop/resources/disclosure.css +2 -2
  139. data/lib/frameworks/sproutcore/frameworks/{foundation → desktop}/resources/radio_view.css +0 -0
  140. data/lib/frameworks/sproutcore/frameworks/desktop/resources/segmented.css +23 -17
  141. data/lib/frameworks/sproutcore/frameworks/desktop/resources/web.css +5 -0
  142. data/lib/frameworks/sproutcore/frameworks/desktop/tests/integration/dialog.js +4 -5
  143. data/lib/frameworks/sproutcore/frameworks/desktop/tests/mixins/border.js +3 -12
  144. data/lib/frameworks/sproutcore/frameworks/desktop/tests/mixins/collection_fast_path.js +58 -0
  145. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/methods.js +2 -2
  146. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +79 -12
  147. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +13 -0
  148. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/ui.js +2 -2
  149. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/drag_and_drop.js +147 -0
  150. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/methods.js +123 -2
  151. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/drag_and_drop.js +150 -0
  152. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list_item.js +58 -44
  153. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/methods.js +9 -80
  154. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +54 -130
  155. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/observers.js +78 -0
  156. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +64 -9
  157. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +11 -11
  158. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/ui.js +28 -2
  159. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/slider/methods.js +74 -0
  160. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/slider/ui.js +141 -0
  161. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +4 -1
  162. data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +69 -36
  163. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +27 -11
  164. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +41 -25
  165. data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +51 -89
  166. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +59 -34
  167. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +59 -49
  168. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +1 -1
  169. data/lib/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +4 -1
  170. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +14 -14
  171. data/lib/frameworks/sproutcore/frameworks/foundation/resources/label.css +8 -8
  172. data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +13 -1
  173. data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +4 -1
  174. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/colors.js +21 -22
  175. data/lib/frameworks/sproutcore/frameworks/foundation/tests/controllers/tree/selection_support.js +26 -0
  176. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +4 -5
  177. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/image_queue.js +68 -44
  178. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/user_defaults.js +10 -0
  179. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +0 -10
  180. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +24 -59
  181. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +47 -34
  182. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +96 -12
  183. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +38 -0
  184. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +38 -50
  185. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +6 -2
  186. data/lib/frameworks/sproutcore/frameworks/media/media_capabilities.js +211 -0
  187. data/lib/frameworks/sproutcore/frameworks/media/render_delegates/media_slider.js +77 -0
  188. data/lib/frameworks/sproutcore/frameworks/media/resources/playeras3.fla +0 -0
  189. data/lib/frameworks/sproutcore/frameworks/media/resources/video.css +129 -115
  190. data/lib/frameworks/sproutcore/frameworks/media/resources/videoCanvas.swf +0 -0
  191. data/lib/frameworks/sproutcore/frameworks/media/tests/media_capabilities.js +194 -0
  192. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +56 -173
  193. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +15 -18
  194. data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +63 -219
  195. data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +4 -2
  196. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +4 -8
  197. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +51 -160
  198. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +138 -102
  199. data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +8 -0
  200. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  201. data/lib/frameworks/sproutcore/frameworks/runtime/ext/array.js +8 -2
  202. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +32 -12
  203. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +28 -24
  204. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +0 -2
  205. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +111 -12
  206. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/compare.js +9 -7
  207. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +8 -2
  208. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/enumerable/enumerable.js +160 -115
  209. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +64 -19
  210. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/mixin.js +83 -0
  211. data/lib/frameworks/sproutcore/frameworks/template_view/ext/handlebars/bind.js +3 -0
  212. data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/collection.js +13 -0
  213. data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/handlebars.js +4 -2
  214. data/lib/frameworks/sproutcore/frameworks/template_view/views/template_collection.js +5 -5
  215. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +5 -1
  216. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +13 -12
  217. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +9 -2
  218. data/lib/frameworks/sproutcore/themes/ace/resources/progress/ace/progress.css +105 -5
  219. data/lib/frameworks/sproutcore/themes/ace/resources/progress/ace/progress_view_indeterminate_content.png +0 -0
  220. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +19 -15
  221. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +93 -21
  222. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_vertical_active.png +0 -0
  223. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_vertical_normal.png +0 -0
  224. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_vertical_selected.png +0 -0
  225. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented_vertical_selected_active.png +0 -0
  226. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +91 -15
  227. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_vertical_active.png +0 -0
  228. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_vertical_normal.png +0 -0
  229. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_vertical_selected.png +0 -0
  230. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented_vertical_selected_active.png +0 -0
  231. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +21 -17
  232. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +26 -25
  233. data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/menu_item_view.css +2 -4
  234. data/lib/sproutcore/helpers/minifier.rb +5 -5
  235. data/lib/sproutcore/tools/build.rb +1 -1
  236. data/sproutcore.gemspec +6 -1
  237. data/vendor/chance/lib/chance/instance/slicing.rb +2 -2
  238. metadata +143 -60
  239. data/lib/frameworks/sproutcore/apps/test_controls/Buildfile +0 -0
  240. data/lib/frameworks/sproutcore/apps/test_controls/controllers/alert.js +0 -39
  241. data/lib/frameworks/sproutcore/apps/test_controls/controllers/buttons.js +0 -21
  242. data/lib/frameworks/sproutcore/apps/test_controls/controllers/categories.js +0 -125
  243. data/lib/frameworks/sproutcore/apps/test_controls/controllers/category.js +0 -36
  244. data/lib/frameworks/sproutcore/apps/test_controls/controllers/select.js +0 -12
  245. data/lib/frameworks/sproutcore/apps/test_controls/controllers/split.js +0 -74
  246. data/lib/frameworks/sproutcore/apps/test_controls/core.js +0 -29
  247. data/lib/frameworks/sproutcore/apps/test_controls/main.js +0 -14
  248. data/lib/frameworks/sproutcore/apps/test_controls/resources/buttons_page.js +0 -158
  249. data/lib/frameworks/sproutcore/apps/test_controls/resources/checkboxes_page.js +0 -53
  250. data/lib/frameworks/sproutcore/apps/test_controls/resources/flow_layout_page.js +0 -85
  251. data/lib/frameworks/sproutcore/apps/test_controls/resources/list_page.js +0 -40
  252. data/lib/frameworks/sproutcore/apps/test_controls/resources/main_page.css +0 -60
  253. data/lib/frameworks/sproutcore/apps/test_controls/resources/main_page.js +0 -151
  254. data/lib/frameworks/sproutcore/apps/test_controls/resources/panels_page.js +0 -62
  255. data/lib/frameworks/sproutcore/apps/test_controls/resources/progress_page.js +0 -33
  256. data/lib/frameworks/sproutcore/apps/test_controls/resources/radio_page.js +0 -55
  257. data/lib/frameworks/sproutcore/apps/test_controls/resources/scroll_page.js +0 -77
  258. data/lib/frameworks/sproutcore/apps/test_controls/resources/segmented_page.js +0 -99
  259. data/lib/frameworks/sproutcore/apps/test_controls/resources/select_page.js +0 -75
  260. data/lib/frameworks/sproutcore/apps/test_controls/resources/sliders_page.js +0 -54
  261. data/lib/frameworks/sproutcore/apps/test_controls/resources/split_page.js +0 -141
  262. data/lib/frameworks/sproutcore/apps/test_controls/resources/strings.js +0 -50
  263. data/lib/frameworks/sproutcore/apps/test_controls/resources/tab_page.js +0 -53
  264. data/lib/frameworks/sproutcore/apps/test_controls/resources/text_field_page.js +0 -65
  265. data/lib/frameworks/sproutcore/apps/test_controls/theme.js +0 -34
  266. data/lib/frameworks/sproutcore/apps/tests/tests/controllers/detail.js +0 -15
  267. data/lib/frameworks/sproutcore/apps/tests/tests/controllers/source.js +0 -15
  268. data/lib/frameworks/sproutcore/apps/tests/tests/controllers/target.js +0 -15
  269. data/lib/frameworks/sproutcore/apps/tests/tests/controllers/targets.js +0 -15
  270. data/lib/frameworks/sproutcore/apps/tests/tests/controllers/tests.js +0 -15
  271. data/lib/frameworks/sproutcore/apps/tests/tests/models/target.js +0 -15
  272. data/lib/frameworks/sproutcore/apps/tests/tests/models/test.js +0 -15
  273. data/lib/frameworks/sproutcore/apps/tests/tests/views/offset_checkbox.js +0 -15
  274. data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/console.js +0 -21
@@ -5,7 +5,7 @@
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
7
 
8
- /*global module test htmlbody ok equals same stop start Q$ */
8
+ /*globals module, test, htmlbody, ok, equals, same, stop, start, Q$ */
9
9
 
10
10
 
11
11
  // note: need to test interaction with Validators here
@@ -35,16 +35,16 @@ module("SC.TextFieldView",{
35
35
  });
36
36
  pane.append(); // make sure there is a layer...
37
37
  SC.RunLoop.end();
38
-
38
+
39
39
  view = pane.childViews[0];
40
40
  view1 = pane.childViews[1];
41
41
  view2 = pane.childViews[2];
42
42
  },
43
-
43
+
44
44
  teardown: function() {
45
45
  pane.remove();
46
46
  pane = view = null ;
47
- }
47
+ }
48
48
  });
49
49
 
50
50
  test("renders an text field input tag with appropriate attributes", function() {
@@ -57,7 +57,7 @@ test("renders an text field input tag with appropriate attributes", function() {
57
57
  equals(q.attr('name'), view.get('layerId'), 'should have name as view_layerid');
58
58
  });
59
59
 
60
- test("renders an text field with a custom layerId with correct id and name html attributes", function() {
60
+ test("renders an text field with a custom layerId with correct id and name html attributes", function() {
61
61
  equals(view2.$().attr('id'), 'fieldWithCustomId', 'label html element should have the custom id');
62
62
  equals(view2.$input().attr('name'), 'fieldWithCustomId', 'input html element should have the custom name');
63
63
  });
@@ -65,7 +65,7 @@ test("renders an text field with a custom layerId with correct id and name html
65
65
  test("isEnabled=NO should add disabled class", function() {
66
66
  SC.RunLoop.begin();
67
67
  view.set('isEnabled', NO);
68
- SC.RunLoop.end();
68
+ SC.RunLoop.end();
69
69
  ok(view.$().hasClass('disabled'), 'should have disabled class');
70
70
  });
71
71
 
@@ -73,7 +73,7 @@ test("isEnabled=NO isEditable=NO should add disabled attribute", function() {
73
73
  SC.RunLoop.begin();
74
74
  view.set('isEnabled', NO);
75
75
  view.set('isEditable', NO);
76
- SC.RunLoop.end();
76
+ SC.RunLoop.end();
77
77
  ok(view.$input().attr('disabled'), 'should have disabled attribute');
78
78
  ok(!view.$input().attr('readOnly'), 'should not have readOnly attribute');
79
79
  });
@@ -82,7 +82,7 @@ test("isEnabled=NO isEditable=YES should add disabled attribute", function() {
82
82
  SC.RunLoop.begin();
83
83
  view.set('isEnabled', NO);
84
84
  view.set('isEditable', YES);
85
- SC.RunLoop.end();
85
+ SC.RunLoop.end();
86
86
  ok(view.$input().attr('disabled'), 'should have disabled attribute');
87
87
  ok(!view.$input().attr('readOnly'), 'should not have readOnly attribute');
88
88
  });
@@ -91,7 +91,7 @@ test("isEnabled=YES isEditable=NO should add readOnly attribute", function() {
91
91
  SC.RunLoop.begin();
92
92
  view.set('isEnabled', YES);
93
93
  view.set('isEditable', NO);
94
- SC.RunLoop.end();
94
+ SC.RunLoop.end();
95
95
  ok(!view.$input().attr('disabled'), 'should not have disabled attribute');
96
96
  ok(view.$input().attr('readOnly'), 'should have readOnly attribute');
97
97
  });
@@ -100,7 +100,7 @@ test("isEnabled=YES isEditable=YES should not add disable or readOnly attribute"
100
100
  SC.RunLoop.begin();
101
101
  view.set('isEnabled', YES);
102
102
  view.set('isEditable', YES);
103
- SC.RunLoop.end();
103
+ SC.RunLoop.end();
104
104
  ok(!view.$input().attr('disabled'), 'should not have disabled attribute');
105
105
  ok(!view.$input().attr('readOnly'), 'should not have readOnly attribute');
106
106
  });
@@ -153,11 +153,95 @@ test("autoCorrect=null should not add autocorrect", function() {
153
153
  ok(!view.$input().attr('autocorrect'), 'should not have an autocorrect attribute set');
154
154
  });
155
155
 
156
+ /**
157
+ SC.TextFieldView was extended to make use of interpretKeyEvents, which
158
+ allows easy actions to be implemented based off of several key "keys". This
159
+ test checks that the expected actions are being captured.
160
+ */
161
+ test("interpretKeyEvents should allow key command methods to be implemented.", function() {
162
+ var evt,
163
+ layer,
164
+ cancelFlag = NO,
165
+ deleteBackwardFlag = NO,
166
+ deleteForwardFlag = NO,
167
+ insertNewlineFlag = NO,
168
+ insertTabFlag = NO,
169
+ moveLeftFlag = NO,
170
+ moveRightFlag = NO,
171
+ moveUpFlag = NO,
172
+ moveDownFlag = NO,
173
+ moveToBeginningOfDocumentFlag = NO,
174
+ moveToEndOfDocumentFlag = NO,
175
+ pageDownFlag = NO,
176
+ pageUpFlag = NO;
177
+
178
+ view1.cancel = function() { cancelFlag = YES; return YES; };
179
+ view1.deleteBackward = function() { deleteBackwardFlag = YES; return YES; };
180
+ view1.deleteForward = function() { deleteForwardFlag = YES; return YES; };
181
+ view1.insertNewline = function() { insertNewlineFlag = YES; return YES; };
182
+ view1.insertTab = function() { insertTabFlag = YES; return YES; };
183
+ view1.moveLeft = function() { moveLeftFlag = YES; return YES; };
184
+ view1.moveRight = function() { moveRightFlag = YES; return YES; };
185
+ view1.moveUp = function() { moveUpFlag = YES; return YES; };
186
+ view1.moveDown = function() { moveDownFlag = YES; return YES; };
187
+ view1.moveToBeginningOfDocument = function() { moveToBeginningOfDocumentFlag = YES; return YES; };
188
+ view1.moveToEndOfDocument = function() { moveToEndOfDocumentFlag = YES; return YES; };
189
+ view1.pageUp = function() { pageUpFlag = YES; return YES; };
190
+ view1.pageDown = function() { pageDownFlag = YES; return YES; };
191
+
192
+ SC.RunLoop.begin();
193
+ layer = view1.get('layer');
194
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_BACKSPACE, keyCode: SC.Event.KEY_BACKSPACE });
195
+ view1.keyDown(evt);
196
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_TAB, keyCode: SC.Event.KEY_TAB });
197
+ view1.keyDown(evt);
198
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_RETURN, keyCode: SC.Event.KEY_RETURN });
199
+ view1.keyDown(evt);
200
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_ESC, keyCode: SC.Event.KEY_ESC });
201
+ view1.keyDown(evt);
202
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_LEFT, keyCode: SC.Event.KEY_LEFT });
203
+ view1.keyDown(evt);
204
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_UP, keyCode: SC.Event.KEY_UP });
205
+ view1.keyDown(evt);
206
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_DOWN, keyCode: SC.Event.KEY_DOWN });
207
+ view1.keyDown(evt);
208
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_RIGHT, keyCode: SC.Event.KEY_RIGHT });
209
+ view1.keyDown(evt);
210
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_DELETE, keyCode: SC.Event.KEY_DELETE });
211
+ view1.keyDown(evt);
212
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_HOME, keyCode: SC.Event.KEY_HOME });
213
+ view1.keyDown(evt);
214
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_END, keyCode: SC.Event.KEY_END });
215
+ view1.keyDown(evt);
216
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_PAGEUP, keyCode: SC.Event.KEY_PAGEUP });
217
+ view1.keyDown(evt);
218
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_PAGEDOWN, keyCode: SC.Event.KEY_PAGEDOWN });
219
+ view1.keyDown(evt);
220
+ evt = SC.Event.simulateEvent(layer, 'keydown', { which: SC.Event.KEY_INSERT, keyCode: SC.Event.KEY_INSERT });
221
+ view1.keyDown(evt);
222
+ SC.RunLoop.end();
223
+
224
+ // Test.
225
+ ok(deleteBackwardFlag, 'deleteBackward should have been triggered.');
226
+ ok(insertTabFlag, 'insertTab should have been triggered.');
227
+ ok(insertNewlineFlag, 'insertNewline should have been triggered.');
228
+ ok(cancelFlag, 'cancel should have been triggered.');
229
+ ok(moveLeftFlag, 'moveLeft should have been triggered.');
230
+ ok(moveUpFlag, 'moveUp should have been triggered.');
231
+ ok(moveDownFlag, 'moveDown should have been triggered.');
232
+ ok(moveRightFlag, 'moveRight should have been triggered.');
233
+ ok(deleteForwardFlag, 'deleteForward should have been triggered.');
234
+ ok(moveToBeginningOfDocumentFlag, 'moveToBeginningOfDocument should have been triggered.');
235
+ ok(moveToEndOfDocumentFlag, 'moveToEndOfDocument should have been triggered.');
236
+ ok(pageUpFlag, 'pageUp should have been triggered.');
237
+ ok(pageDownFlag, 'pageDown should have been triggered.');
238
+ });
239
+
156
240
  // test("isEnabled=NO should add disabled attr to input", function() {
157
241
  // SC.RunLoop.begin();
158
242
  // view1.set('isEnabled', NO);
159
- // SC.RunLoop.end();
160
- // ok(view1.$input().attr('disabled'), 'should have disabled attr');
243
+ // SC.RunLoop.end();
244
+ // ok(view1.$input().attr('disabled'), 'should have disabled attr');
161
245
  // view1.set('isEditing',YES);
162
246
  // ok(view1.get('value') === 'SproutCore', 'value cannot be changed');
163
247
  // });
@@ -590,6 +590,44 @@ test("Adding both left and right accessory views changes style -- using design()
590
590
  ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
591
591
  });
592
592
 
593
+ test("Accessory views should only be instantiated once", function() {
594
+ var view = pane.view('with value');
595
+
596
+ // Test the left accessory view
597
+ SC.RunLoop.begin();
598
+ var leftAccessoryViewInitCount = 0;
599
+ var leftAccessoryView = SC.View.design({
600
+ layout: { top:1, left:2, width:16, height:16 },
601
+ init: function() {
602
+ sc_super();
603
+ leftAccessoryViewInitCount++;
604
+ }
605
+ });
606
+ view.set('leftAccessoryView', leftAccessoryView);
607
+ SC.RunLoop.end();
608
+
609
+ // Check it
610
+ equals(leftAccessoryViewInitCount, 1, 'the left accessory view should only be initialized once');
611
+
612
+ // Reset to null so it isn't created a second time when rightAccessoryView is set
613
+ view.set('leftAccessoryView', null);
614
+
615
+ // Test the right accessory view
616
+ SC.RunLoop.begin();
617
+ var rightAccessoryViewInitCount = 0;
618
+ var rightAccessoryView = SC.View.design({
619
+ layout: { top:1, right:3, width:17, height:16 },
620
+ init: function() {
621
+ sc_super();
622
+ rightAccessoryViewInitCount++;
623
+ }
624
+ });
625
+ view.set('rightAccessoryView', rightAccessoryView);
626
+ SC.RunLoop.end();
627
+
628
+ // Check it
629
+ equals(rightAccessoryViewInitCount, 1, 'the right accessory view should only be initialized once');
630
+ });
593
631
 
594
632
 
595
633
  // ..........................................................
@@ -92,7 +92,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
92
92
  hint: '',
93
93
 
94
94
  /**
95
- The hint to display while the field is not active.
95
+ The type attribute of the input.
96
96
 
97
97
  @type String
98
98
  @default "text"
@@ -114,7 +114,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
114
114
  isBrowserFocusable: YES,
115
115
 
116
116
  /**
117
- Whether the browser should automatically correct the input.
117
+ Whether the browser should automatically correct the input.
118
118
 
119
119
  When `autoCorrect` is set to `null`, the browser will use
120
120
  the system defaults.
@@ -806,28 +806,19 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
806
806
  position, accessoryView, frames, width, layout, offset, frame;
807
807
  for (i = 0; i < numberOfAccessoryViewPositions; i++) {
808
808
  position = accessoryViewPositions[i];
809
- accessoryView = this.get(position + 'AccessoryView');
810
- if (accessoryView) {
811
- // need acessoryView as an instance, not class...
812
- if (accessoryView.isClass) {
813
- accessoryView = accessoryView.create({
814
- layoutView: this
815
- });
816
- }
817
- // sanity check
818
- if (accessoryView.get) {
819
- frame = accessoryView.get('frame');
820
- if (frame) {
821
- width = frame.width;
822
- if (width) {
823
- // Also account for the accessory view's inset.
824
- layout = accessoryView.get('layout');
825
- if (layout) {
826
- offset = layout[position];
827
- width += offset;
828
- }
829
- widths[position] = width;
809
+ accessoryView = this['_' + position + 'AccessoryView'];
810
+ if (accessoryView && accessoryView.isObservable) {
811
+ frame = accessoryView.get('frame');
812
+ if (frame) {
813
+ width = frame.width;
814
+ if (width) {
815
+ // Also account for the accessory view's inset.
816
+ layout = accessoryView.get('layout');
817
+ if (layout) {
818
+ offset = layout[position];
819
+ width += offset;
830
820
  }
821
+ widths[position] = width;
831
822
  }
832
823
  }
833
824
  }
@@ -913,7 +904,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
913
904
  // our key/mouse down/up handlers (such as the user choosing Select All
914
905
  // from a menu).
915
906
  SC.Event.add(input, 'select', this, this._textField_selectionDidChange);
916
-
907
+
917
908
  // handle a "paste" from app menu and context menu
918
909
  SC.Event.add(input, 'input', this, this._textField_inputDidChange);
919
910
  },
@@ -1008,11 +999,11 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1008
999
  }
1009
1000
  this.updateHintOnFocus();
1010
1001
  },
1011
-
1002
+
1012
1003
  /** @private
1013
1004
  Context-menu paste does not trigger fieldValueDidChange normally. To do so, we'll capture the
1014
1005
  input event and avoid duplicating the "fieldValueDidChange" call if it was already issued elsewhere.
1015
-
1006
+
1016
1007
  I welcome someone else to find a better solution to this problem. However, please make sure that it
1017
1008
  works with pasting via shortcut, context menu and the application menu on *All Browsers*.
1018
1009
  */
@@ -1138,30 +1129,16 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1138
1129
  }
1139
1130
  },
1140
1131
 
1141
- /**
1142
- Simply allow keyDown & keyUp to pass through to the default web browser
1143
- implementation.
1144
- */
1132
+ /** @private */
1145
1133
  keyDown: function (evt) {
1134
+ return this.interpretKeyEvents(evt) || NO;
1135
+ },
1136
+
1137
+ /** @private */
1138
+ insertText: function(chr, evt) {
1146
1139
  var which = evt.which,
1147
1140
  keyCode = evt.keyCode,
1148
- maxLengthReached = false,
1149
- value, view;
1150
-
1151
- // Handle return and escape. this way they can be passed on to the
1152
- // responder chain.
1153
- // If the event is triggered by a return while entering IME input,
1154
- // don't got through this path.
1155
- if ((which === SC.Event.KEY_RETURN && !evt.isIMEInput) && !this.get('isTextArea')) { return NO; }
1156
- if (which === SC.Event.KEY_ESC) { return NO; }
1157
-
1158
- // handle tab key
1159
- if ((which === SC.Event.KEY_TAB || keyCode === SC.Event.KEY_TAB) && this.get('defaultTabbingEnabled')) {
1160
- view = evt.shiftKey ? this.get('previousValidKeyView') : this.get('nextValidKeyView');
1161
- if (view) view.becomeFirstResponder();
1162
- else evt.allowDefault();
1163
- return YES ; // handled
1164
- }
1141
+ maxLengthReached = false;
1165
1142
 
1166
1143
  // maxlength for textareas
1167
1144
  if (!SC.platform.input.maxlength && this.get('isTextArea')) {
@@ -1185,7 +1162,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1185
1162
 
1186
1163
  if (this.get('applyImmediately')) {
1187
1164
  // This has gone back and forth several times between invokeLater and setTimeout.
1188
- // Now we're back to invokeLater, please read the code comment above
1165
+ // Now we're back to invokeLater, please read the code comment above
1189
1166
  // this._textField_inputDidChange before changing it again.
1190
1167
  this._fieldValueDidChangeTimer = this.invokeLater(this.fieldValueDidChange, 10);
1191
1168
  }
@@ -1193,6 +1170,17 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1193
1170
  return YES;
1194
1171
  },
1195
1172
 
1173
+ /** @private */
1174
+ insertTab: function(evt) {
1175
+ // Don't handle if default tabbing hasn't been enabled.
1176
+ if (!this.get('defaultTabbingEnabled')) return NO;
1177
+ // Otherwise, handle.
1178
+ var view = evt.shiftKey ? this.get('previousValidKeyView') : this.get('nextValidKeyView');
1179
+ if (view) view.becomeFirstResponder();
1180
+ else evt.allowDefault();
1181
+ return YES ; // handled
1182
+ },
1183
+
1196
1184
  keyUp: function (evt) {
1197
1185
  if (SC.browser.isMozilla &&
1198
1186
  evt.keyCode === SC.Event.KEY_RETURN) { this.fieldValueDidChange(); }
@@ -1259,7 +1247,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1259
1247
  },
1260
1248
 
1261
1249
  /** @private
1262
- Overridden from SC.FieldView. Provides correct tag name based on the
1250
+ Overridden from SC.FieldView. Provides correct tag name based on the
1263
1251
  `isTextArea` property.
1264
1252
  */
1265
1253
  _inputElementTagName: function () {
@@ -1269,7 +1257,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
1269
1257
  return 'input';
1270
1258
  }
1271
1259
  },
1272
-
1260
+
1273
1261
  /** @private
1274
1262
  This observer makes sure to hide the hint when a value is entered, or
1275
1263
  show it if it becomes empty.
@@ -361,8 +361,12 @@ jQuery.Buffer = function() {
361
361
 
362
362
  Buffer.prototype.removeClass = function(value) {
363
363
  var context = this.bufferedCommand("flushClassNames");
364
- if (!context.classNames) context.classNames = this._hashFromClassNames(this._el.className);
365
- context.classNames[value] = false;
364
+ if (value === undefined) {
365
+ context.classNames = {};
366
+ } else {
367
+ if (!context.classNames) context.classNames = this._hashFromClassNames(this._el.className);
368
+ context.classNames[value] = false;
369
+ }
366
370
  };
367
371
 
368
372
  Buffer.prototype.resetClassNames = function(value) {
@@ -0,0 +1,211 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2012 Michael Krotscheck and contributors.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+
7
+ /**
8
+ * @class
9
+ *
10
+ * An easy-to-reference list of media capabilities which the current running
11
+ * browser supports such as HTML5 and Plugin detection. It is modeled after
12
+ * Flash Player's browser capabilities class, with all the non-media related
13
+ * properties removed. Rather than performing specific browser checks, we
14
+ * instead test by creating some basic DOM elements. It's both more reliable and
15
+ * easier to maintain than browser version checks.
16
+ *
17
+ * To see whether your target browser will support what you're trying to do,
18
+ * check http://caniuse.com/
19
+ *
20
+ * @see http://caniuse.com/
21
+ * @since SproutCore 1.8.1
22
+ * @author Michael Krotscheck
23
+ */
24
+ SC.mediaCapabilities = SC.Object.create({});
25
+
26
+ /**
27
+ * Automatic detection of various browser media capabilities.
28
+ */
29
+ (function() {
30
+ /**
31
+ * Specifies whether the browser supports the HTML5 <audio> tag.
32
+ *
33
+ * @name SC.mediaCapabilities.isHTML5AudioSupported
34
+ * @type Boolean
35
+ */
36
+ SC.mediaCapabilities.isHTML5AudioSupported = NO;
37
+ try {
38
+ // Firefox 3.6 doesn't support the W3C API. Disable support.
39
+ if(SC.browser.isMozilla && SC.browser.compare(SC.browser.mozilla, "3.6") <= 0) {
40
+ throw new Error('Browser not supported');
41
+ }
42
+
43
+ var doc = document.createElement('audio');
44
+ isAudioSupported = !!doc.canPlayType;
45
+ delete doc;
46
+ SC.mediaCapabilities.isHTML5AudioSupported = YES;
47
+
48
+ } catch(e) {
49
+ }
50
+
51
+ /**
52
+ * Specifies whether the browser supports the HTML5 <video> tag.
53
+ *
54
+ * @name SC.mediaCapabilities.isHTML5AudioSupported
55
+ * @type Boolean
56
+ */
57
+ SC.mediaCapabilities.isHTML5VideoSupported = NO;
58
+ try {
59
+ // Firefox 3.6 doesn't support the W3C API. Disable support.
60
+ if(SC.browser.isMozilla && SC.browser.compare(SC.browser.mozilla, "3.6") <= 0) {
61
+ throw new Error('Browser not supported');
62
+ }
63
+
64
+ var doc = document.createElement('video');
65
+ isVideoSupported = !!doc.canPlayType;
66
+ delete doc;
67
+ SC.mediaCapabilities.isHTML5VideoSupported = YES;
68
+ } catch(e) {
69
+ }
70
+
71
+ /**
72
+ * Specifies whether the browser supports the Adobe Flash plugin.
73
+ *
74
+ * @name SC.mediaCapabilities.isHTML5AudioSupported
75
+ * @type Boolean
76
+ */
77
+ SC.mediaCapabilities.isFlashSupported = NO;
78
+ // Non-IE detection
79
+ if(navigator.plugins) {
80
+ for( var i = 0; i < navigator.plugins.length; i++) {
81
+ if(navigator.plugins[i].name.indexOf("Shockwave Flash") >= 0) {
82
+ SC.mediaCapabilities.isFlashSupported = YES;
83
+ }
84
+ }
85
+ }
86
+ // IE ActiveX detection
87
+ if(window.ActiveXObject) {
88
+ try {
89
+ var control = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
90
+ delete control;
91
+ SC.mediaCapabilities.isFlashSupported = YES;
92
+ } catch(e) {
93
+ // Do nothing- The ActiveX object isn't available.
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Specifies whether the browser supports quicktime media playback.
99
+ *
100
+ * @type Boolean
101
+ */
102
+ SC.mediaCapabilities.isQuicktimeSupported = NO;
103
+
104
+ // Non-IE detection
105
+ if(navigator.plugins) {
106
+ for( var i = 0; i < navigator.plugins.length; i++) {
107
+ if(navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
108
+ SC.mediaCapabilities.isQuicktimeSupported = YES;
109
+ }
110
+ }
111
+ }
112
+ // IE ActiveX detection
113
+ if(window.ActiveXObject) {
114
+ var control = null;
115
+ try {
116
+ control = new ActiveXObject('QuickTime.QuickTime');
117
+ delete control;
118
+ SC.mediaCapabilities.isQuicktimeSupported = YES;
119
+ } catch(e) {
120
+ // Do nothing- the ActiveX object isn't available.
121
+ }
122
+
123
+ try {
124
+ // This generates a user prompt in Internet Explorer 7
125
+ control = new ActiveXObject('QuickTimeCheckObject.QuickTimeCheck');
126
+ delete control;
127
+ SC.mediaCapabilities.isQuicktimeSupported = YES;
128
+ } catch(e) {
129
+ // Do nothing- The ActiveX object isn't available.
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Specifies whether the browser supports the HTML5 getUserMedia/Stream API.
135
+ *
136
+ * NOTE: As of February 2012, this feature is still in Draft status and is
137
+ * likely to change frequently. It's included here for the sake of
138
+ * completeness, however concrete implementations don't yet exist.
139
+ *
140
+ * @name SC.mediaCapabilities.isHTML5StreamApiSupported
141
+ * @type Boolean
142
+ */
143
+ SC.mediaCapabilities.isHTML5StreamApiSupported = !!navigator.getUserMedia;
144
+
145
+ /**
146
+ * Specifies whether the browser supports audio recording via the HTML5 stream
147
+ * API or the Adobe Flash plugin.
148
+ *
149
+ * @name SC.mediaCapabilities.hasMicrophone
150
+ * @type Boolean
151
+ */
152
+ SC.mediaCapabilities.hasMicrophone = SC.mediaCapabilities.isHTML5StreamApiSupported || SC.mediaCapabilities.isFlashSupported;
153
+
154
+ /**
155
+ * Specifies whether the browser supports video recording via the HTML5 stream
156
+ * API or the Adobe Flash Plugin.
157
+ *
158
+ * @name SC.mediaCapabilities.hasMicrophone
159
+ * @type Boolean
160
+ */
161
+ SC.mediaCapabilities.hasVideoCamera = SC.mediaCapabilities.isHTML5StreamApiSupported || SC.mediaCapabilities.isFlashSupported;
162
+
163
+ /**
164
+ * Specifies whether the browser has audio playback capabilities.
165
+ *
166
+ * @name SC.mediaCapabilities.hasAudioPlayback
167
+ * @type Boolean
168
+ */
169
+ SC.mediaCapabilities.hasAudioPlayback = SC.mediaCapabilities.isHTML5AudioSupported || SC.mediaCapabilities.isQuicktimeSupported || SC.mediaCapabilities.isFlashSupported;
170
+
171
+ /**
172
+ * Specifies whether the browser has video playback capabilities.
173
+ *
174
+ * @name SC.mediaCapabilities.hasVideoPlayback
175
+ * @type Boolean
176
+ */
177
+ SC.mediaCapabilities.hasVideoPlayback = SC.mediaCapabilities.isHTML5VideoSupported || SC.mediaCapabilities.isQuicktimeSupported || SC.mediaCapabilities.isFlashSupported;
178
+
179
+ /**
180
+ * Specifies whether the browser supports Ogg Vorbis.
181
+ *
182
+ * @name SC.mediaCapabilities.isOggSupported
183
+ * @type Boolean
184
+ */
185
+ SC.mediaCapabilities.isOggSupported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isMozilla || SC.browser.isChrome || SC.browser.isOpera);
186
+
187
+ /**
188
+ * Specifies whether the browser supports the WebM/VP8 Video format.
189
+ *
190
+ * @name SC.mediaCapabilities.isWebMSupported
191
+ * @type Boolean
192
+ */
193
+ SC.mediaCapabilities.isWebMSupported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isMozilla || SC.browser.isChrome || SC.browser.isOpera);
194
+
195
+ /**
196
+ * Specifies whether the browser supports the Adobe FLV compression format.
197
+ *
198
+ * @name isFLVSupported
199
+ * @type Boolean
200
+ */
201
+ SC.mediaCapabilities.isFLVSupported = SC.mediaCapabilities.isFlashSupported;
202
+
203
+ /**
204
+ * Specifies whether the browser supports the MPEG-4/H.264 Video format
205
+ *
206
+ * @name isMP4Supported
207
+ * @type Boolean
208
+ */
209
+ SC.mediaCapabilities.isMP4Supported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isIE || SC.browser.isChrome || SC.browser.isSafari);
210
+
211
+ })();