sproutcore 0.9.1 → 0.9.2

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 (208) hide show
  1. data/History.txt +233 -0
  2. data/Manifest.txt +67 -34
  3. data/bin/sc-build +12 -1
  4. data/bin/sc-gen +1 -1
  5. data/bin/sproutcore +14 -0
  6. data/clients/sc_docs/controllers/docs.js +38 -8
  7. data/clients/sc_docs/english.lproj/body.css +80 -127
  8. data/clients/sc_docs/english.lproj/body.rhtml +43 -23
  9. data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
  10. data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
  11. data/clients/sc_docs/main.js +14 -9
  12. data/clients/sc_docs/models/doc.js +1 -1
  13. data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
  14. data/clients/sc_docs/tests/models/doc.rhtml +1 -2
  15. data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
  16. data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
  17. data/clients/sc_docs/views/doc_frame.js +1 -1
  18. data/clients/sc_test_runner/controllers/runner.js +31 -8
  19. data/clients/sc_test_runner/english.lproj/body.css +62 -122
  20. data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
  21. data/clients/sc_test_runner/main.js +1 -6
  22. data/clients/sc_test_runner/models/test.js +14 -1
  23. data/clients/sc_test_runner/views/runner_frame.js +4 -2
  24. data/clients/view_builder/builders/builder.js +339 -0
  25. data/clients/view_builder/builders/button.js +81 -0
  26. data/clients/view_builder/controllers/document.js +21 -0
  27. data/clients/view_builder/core.js +19 -0
  28. data/clients/view_builder/english.lproj/body.css +77 -0
  29. data/clients/view_builder/english.lproj/body.rhtml +41 -0
  30. data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
  31. data/clients/view_builder/english.lproj/strings.js +14 -0
  32. data/clients/view_builder/main.js +38 -0
  33. data/clients/view_builder/tests/controllers/document.rhtml +20 -0
  34. data/clients/view_builder/tests/views/builder.rhtml +20 -0
  35. data/clients/view_builder/views/builder.js +23 -0
  36. data/frameworks/prototype/prototype.js +1 -1
  37. data/frameworks/sproutcore/Core.js +32 -7
  38. data/frameworks/sproutcore/README +1 -1
  39. data/frameworks/sproutcore/animation/animation.js +411 -0
  40. data/frameworks/sproutcore/controllers/array.js +17 -9
  41. data/frameworks/sproutcore/controllers/collection.js +9 -110
  42. data/frameworks/sproutcore/controllers/controller.js +1 -1
  43. data/frameworks/sproutcore/controllers/object.js +2 -1
  44. data/frameworks/sproutcore/drag/drag.js +267 -56
  45. data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
  46. data/frameworks/sproutcore/drag/drag_source.js +53 -42
  47. data/frameworks/sproutcore/drag/drop_target.js +2 -2
  48. data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
  49. data/frameworks/sproutcore/english.lproj/core.css +115 -0
  50. data/frameworks/sproutcore/english.lproj/icons.css +227 -0
  51. data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
  52. data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
  53. data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
  54. data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
  55. data/frameworks/sproutcore/english.lproj/menu.css +1 -1
  56. data/frameworks/sproutcore/english.lproj/strings.js +1 -1
  57. data/frameworks/sproutcore/english.lproj/theme.css +405 -31
  58. data/frameworks/sproutcore/foundation/application.js +15 -11
  59. data/frameworks/sproutcore/foundation/benchmark.js +1 -1
  60. data/frameworks/sproutcore/foundation/binding.js +2 -2
  61. data/frameworks/sproutcore/foundation/date.js +1 -1
  62. data/frameworks/sproutcore/foundation/error.js +1 -1
  63. data/frameworks/sproutcore/foundation/input_manager.js +32 -21
  64. data/frameworks/sproutcore/foundation/mock.js +1 -1
  65. data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
  66. data/frameworks/sproutcore/foundation/object.js +249 -177
  67. data/frameworks/sproutcore/foundation/page.js +5 -2
  68. data/frameworks/sproutcore/foundation/path_module.js +11 -10
  69. data/frameworks/sproutcore/foundation/responder.js +5 -2
  70. data/frameworks/sproutcore/foundation/routes.js +17 -13
  71. data/frameworks/sproutcore/foundation/run_loop.js +249 -11
  72. data/frameworks/sproutcore/foundation/server.js +1 -1
  73. data/frameworks/sproutcore/foundation/set.js +3 -3
  74. data/frameworks/sproutcore/foundation/string.js +5 -3
  75. data/frameworks/sproutcore/foundation/timer.js +371 -0
  76. data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
  77. data/frameworks/sproutcore/foundation/unittest.js +3 -3
  78. data/frameworks/sproutcore/foundation/utils.js +161 -2
  79. data/frameworks/sproutcore/globals/panels.js +1 -1
  80. data/frameworks/sproutcore/globals/popups.js +4 -3
  81. data/frameworks/sproutcore/globals/window.js +44 -4
  82. data/frameworks/sproutcore/lib/button_views.rb +328 -0
  83. data/frameworks/sproutcore/lib/collection_view.rb +80 -0
  84. data/frameworks/sproutcore/lib/core_views.rb +281 -0
  85. data/frameworks/sproutcore/lib/form_views.rb +253 -0
  86. data/frameworks/sproutcore/lib/index.rhtml +2 -0
  87. data/frameworks/sproutcore/lib/menu_views.rb +88 -0
  88. data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
  89. data/frameworks/sproutcore/mixins/control.js +265 -0
  90. data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
  91. data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
  92. data/frameworks/sproutcore/mixins/scrollable.js +245 -0
  93. data/frameworks/sproutcore/mixins/selection_support.js +148 -0
  94. data/frameworks/sproutcore/mixins/validatable.js +152 -0
  95. data/frameworks/sproutcore/models/collection.js +5 -5
  96. data/frameworks/sproutcore/models/record.js +1 -1
  97. data/frameworks/sproutcore/models/store.js +1 -1
  98. data/frameworks/sproutcore/panes/dialog.js +1 -1
  99. data/frameworks/sproutcore/panes/manager.js +1 -1
  100. data/frameworks/sproutcore/panes/menu.js +1 -1
  101. data/frameworks/sproutcore/panes/overlay.js +2 -2
  102. data/frameworks/sproutcore/panes/panel.js +1 -1
  103. data/frameworks/sproutcore/panes/picker.js +1 -1
  104. data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
  105. data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
  106. data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
  107. data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
  108. data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
  109. data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
  110. data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
  111. data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
  112. data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
  113. data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
  114. data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
  115. data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
  116. data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
  117. data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
  118. data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
  119. data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
  120. data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
  121. data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
  122. data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
  123. data/frameworks/sproutcore/validators/credit_card.js +33 -13
  124. data/frameworks/sproutcore/validators/date.js +26 -6
  125. data/frameworks/sproutcore/validators/email.js +21 -3
  126. data/frameworks/sproutcore/validators/not_empty.js +11 -1
  127. data/frameworks/sproutcore/validators/number.js +18 -4
  128. data/frameworks/sproutcore/validators/password.js +12 -1
  129. data/frameworks/sproutcore/validators/validator.js +204 -194
  130. data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
  131. data/frameworks/sproutcore/views/button/checkbox.js +29 -0
  132. data/frameworks/sproutcore/views/button/disclosure.js +42 -0
  133. data/frameworks/sproutcore/views/button/radio.js +29 -0
  134. data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
  135. data/frameworks/sproutcore/views/collection/grid.js +124 -46
  136. data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
  137. data/frameworks/sproutcore/views/collection/list.js +45 -35
  138. data/frameworks/sproutcore/views/collection/source_list.js +386 -0
  139. data/frameworks/sproutcore/views/collection/table.js +118 -0
  140. data/frameworks/sproutcore/views/container.js +7 -2
  141. data/frameworks/sproutcore/views/error_explanation.js +23 -10
  142. data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
  143. data/frameworks/sproutcore/views/field/field.js +219 -0
  144. data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
  145. data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
  146. data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
  147. data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
  148. data/frameworks/sproutcore/views/filter_button.js +2 -2
  149. data/frameworks/sproutcore/views/form.js +3 -3
  150. data/frameworks/sproutcore/views/image.js +128 -21
  151. data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
  152. data/frameworks/sproutcore/views/label.js +149 -92
  153. data/frameworks/sproutcore/views/list_item.js +225 -0
  154. data/frameworks/sproutcore/views/menu_item.js +10 -4
  155. data/frameworks/sproutcore/views/pagination.js +11 -4
  156. data/frameworks/sproutcore/views/popup_button.js +25 -21
  157. data/frameworks/sproutcore/views/popup_menu.js +10 -4
  158. data/frameworks/sproutcore/views/progress.js +29 -16
  159. data/frameworks/sproutcore/views/radio_group.js +1 -1
  160. data/frameworks/sproutcore/views/scroll.js +60 -20
  161. data/frameworks/sproutcore/views/segmented.js +1 -1
  162. data/frameworks/sproutcore/views/slider.js +132 -0
  163. data/frameworks/sproutcore/views/source_list_group.js +130 -0
  164. data/frameworks/sproutcore/views/spinner.js +1 -1
  165. data/frameworks/sproutcore/views/split.js +292 -0
  166. data/frameworks/sproutcore/views/split_divider.js +109 -0
  167. data/frameworks/sproutcore/views/tab.js +1 -1
  168. data/frameworks/sproutcore/views/toolbar.js +1 -1
  169. data/frameworks/sproutcore/views/view.js +1272 -591
  170. data/generators/client/templates/english.lproj/body.css +1 -1
  171. data/generators/controller/controller_generator.rb +1 -1
  172. data/generators/controller/templates/test.rhtml +2 -1
  173. data/generators/model/templates/test.rhtml +1 -1
  174. data/generators/test/templates/test.rhtml +1 -1
  175. data/generators/view/templates/test.rhtml +1 -1
  176. data/jsdoc/templates/sproutcore/class.tmpl +241 -338
  177. data/jsdoc/templates/sproutcore/default.css +105 -155
  178. data/jsdoc/templates/sproutcore/index.tmpl +43 -8
  179. data/jsdoc/templates/sproutcore/publish.js +9 -4
  180. data/lib/sproutcore/build_tools/html_builder.rb +29 -13
  181. data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
  182. data/lib/sproutcore/bundle.rb +86 -25
  183. data/lib/sproutcore/jsdoc.rb +2 -0
  184. data/lib/sproutcore/version.rb +1 -1
  185. data/lib/sproutcore/view_helpers.rb +36 -3
  186. data/tasks/deployment.rake +1 -1
  187. metadata +69 -36
  188. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  189. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  190. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  191. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  192. data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
  193. data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
  194. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  195. data/frameworks/sproutcore/english.lproj/collections.css +0 -82
  196. data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
  197. data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
  198. data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
  199. data/frameworks/sproutcore/views/field.js +0 -214
  200. data/frameworks/sproutcore/views/workspace.js +0 -170
  201. data/generators/client/templates/english.lproj/controls.css +0 -0
  202. data/generators/framework/templates/english.lproj/body.css +0 -0
  203. data/generators/framework/templates/english.lproj/body.rhtml +0 -3
  204. data/generators/framework/templates/english.lproj/controls.css +0 -0
  205. data/lib/sproutcore/view_helpers/button_views.rb +0 -302
  206. data/lib/sproutcore/view_helpers/core_views.rb +0 -292
  207. data/lib/sproutcore/view_helpers/form_views.rb +0 -258
  208. data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
@@ -0,0 +1,148 @@
1
+ <% # ========================================================================
2
+ # SC.View isVisibleInWindow Unit Test
3
+ # ========================================================================
4
+ %>
5
+ <% content_for('final') do %>
6
+
7
+ <script>
8
+
9
+ var FRAME = { x: 10, y: 10, width: 30, height: 30 } ;
10
+
11
+ Test.context("CASE 1: View created outside of window", {
12
+
13
+ "initial isVisibleInWindow should be false": function() {
14
+ v.get('isVisibleInWindow').shouldEqual(false) ;
15
+ },
16
+
17
+ "adding to window should make it true": function() {
18
+ SC.page.get('root').get('isVisibleInWindow').shouldEqual(true) ;
19
+
20
+ SC.page.get('root').appendChild(v) ;
21
+ v.get('isVisibleInWindow').shouldEqual(true) ;
22
+ },
23
+
24
+ "removing from window should make it false again": function() {
25
+ SC.page.get('root').appendChild(v) ;
26
+ v.get('isVisibleInWindow').shouldEqual(true) ;
27
+
28
+ v.removeFromParent() ;
29
+ v.get('isVisibleInWindow').shouldEqual(false) ;
30
+ },
31
+
32
+ setup: function() {
33
+ v = SC.View.extend({
34
+ emptyElement: '<div class="case"></div>'
35
+ }).create();
36
+ }
37
+
38
+ });
39
+
40
+ Test.context("CASE 2: View in body", {
41
+
42
+ "initial isVisibleInWindow should be true": function() {
43
+ v.get('isVisibleInWindow').shouldEqual(true) ;
44
+ },
45
+
46
+ "moving to another view in window should still be true": function() {
47
+ SC.page.get('root').appendChild(v) ;
48
+ v.get('isVisibleInWindow').shouldEqual(true) ;
49
+ },
50
+
51
+ "removing from window should make it false": function() {
52
+ v.removeFromParent() ;
53
+ v.get('isVisibleInWindow').shouldEqual(false) ;
54
+
55
+ // readd to window
56
+ SC.page.get('root').appendChild(v) ;
57
+ },
58
+
59
+ "moving to a view that is offscreen should make it false": function() {
60
+ v.get('isVisibleInWindow').shouldEqual(true) ;
61
+ offscreen.appendChild(v) ;
62
+ v.get('isVisibleInWindow').shouldEqual(false) ;
63
+ },
64
+
65
+ setup: function() {
66
+ v = SC.page.get('case2');
67
+ offscreen = SC.View.create() ;
68
+ }
69
+ });
70
+
71
+ Test.context("CASE 3: View created in resources", {
72
+
73
+ "initial isVisibleInWindow should be YES": function() {
74
+ v.get('isVisibleInWindow').shouldEqual(YES) ;
75
+ },
76
+
77
+ "moving to a visible view in window should be true": function() {
78
+ SC.page.get('root').appendChild(v) ;
79
+ v.get('isVisibleInWindow').shouldEqual(true) ;
80
+ },
81
+
82
+ "removing from window should make it false": function() {
83
+ v.removeFromParent() ;
84
+ v.get('isVisibleInWindow').shouldEqual(false) ;
85
+ },
86
+
87
+ "moving to a view that is offscreen should make it false": function() {
88
+ offscreen.appendChild(v) ;
89
+ v.get('isVisibleInWindow').shouldEqual(false) ;
90
+ },
91
+
92
+ setup: function() {
93
+ v = SC.page.get('case3');
94
+ offscreen = SC.View.create() ;
95
+ }
96
+
97
+ });
98
+
99
+ main = function() { SC.page.awake(); };
100
+
101
+ </script>
102
+
103
+ <% end %>
104
+
105
+ <% content_for('body') do %>
106
+
107
+ <style>
108
+
109
+ .case { background-color: white; }
110
+ .case .child { border: 1px red solid; }
111
+
112
+ .base {
113
+ float: left;
114
+ width: 200px;
115
+ height: 100px;
116
+ border: 1px #aaa solid;
117
+ position: relative;
118
+ margin: 2px;
119
+ }
120
+
121
+ .cases { position: absolute; bottom: 0 ; left: 0; right: 0; border-top: 1px #ccc solid; }
122
+
123
+ .base label {
124
+ position: absolute;
125
+ bottom: 4px;
126
+ left: 4px;
127
+ }
128
+
129
+ .nested_child { border: 1px green solid; }
130
+
131
+ .case {
132
+ position: absolute;
133
+ left: 10px;
134
+ top: 10px;
135
+ width: 30px;
136
+ height: 30px;
137
+ }
138
+
139
+ </style>
140
+
141
+ <%= view :case2, :class => 'case', :inner_html => 'Case' %>
142
+
143
+ <%= view :root %>
144
+ </div>
145
+
146
+ <% end %>
147
+
148
+ <%= view :case3, :class => 'case', :inner_html => 'Case' %>
@@ -0,0 +1,468 @@
1
+ <% # ========================================================================
2
+ # SC.View scrollFrame Unit Test
3
+ #
4
+ # scrollFrame represents the frame within the view represented by scrollable
5
+ # content. If you view is not scrollable, the scrollFrame should always
6
+ # be eqaul to innerFrame size with a 0,0 origin.
7
+ #
8
+ # ========================================================================
9
+ %>
10
+ <% content_for('final') do %>
11
+
12
+ <script>
13
+
14
+ CHILD_HEIGHT = 152 ; // +2 since we have a border
15
+ CHILD_WIDTH = 302; // +2 since we have a border
16
+
17
+ // CASE 1: non-scrollable view
18
+ Test.context("CASE 1: Non-scrollable view - all view fits within content", {
19
+
20
+ "scrollFrame origin should == 0,0; size should == frame.size": function() {
21
+ var f = this.v.get('frame') ;
22
+ f.x = f.y = 0 ;
23
+
24
+ // console.log('----') ;
25
+ // console.log('f:' + $H(f).inspect()) ;
26
+ // console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
27
+ // console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
28
+ // console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
29
+
30
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
31
+ },
32
+
33
+ "resizing frame should change scrollFrame size": function() {
34
+ var f = this.v.get('frame') ;
35
+ f.x = f.y = 0 ;
36
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
37
+
38
+ this.v.set('frame', { width: 50, height: 50 }) ;
39
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(false) ;
40
+
41
+ var f = this.v.get('frame') ;
42
+ f.x = f.y = 0 ;
43
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
44
+ },
45
+
46
+ "resizing frame should notify change on scrollFrame": function() {
47
+ var didNotify = false ;
48
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
49
+ this.v.set('frame', { width: 55 }) ;
50
+ didNotify.shouldEqual(true) ;
51
+ },
52
+
53
+ setup: function() { this.v = SC.page.get('case1'); }
54
+
55
+ });
56
+
57
+ // CASE 2: Non-scrollable view with hidden overflow content
58
+ Test.context("CASE 2: Non-scrollable view with hidden overflow content", {
59
+
60
+ "scrollFrame origin should == 0,0; size should == innerFrame": function() {
61
+ var f = this.v.get('innerFrame') ;
62
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
63
+
64
+ console.log('CASE 2 ----') ;
65
+ console.log('f:' + $H(f).inspect()) ;
66
+ console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
67
+ console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
68
+ console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
69
+
70
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
71
+ },
72
+
73
+ "resizing frame should change scrollFrame width but not height": function() {
74
+ var f = this.v.get('innerFrame') ;
75
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
76
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
77
+
78
+ this.v.set('frame', { width: 50, height: 50 }) ;
79
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(false) ;
80
+
81
+ var f = this.v.get('innerFrame') ;
82
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
83
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
84
+ },
85
+
86
+ "resizing frame should notify change on scrollFrame": function() {
87
+ var didNotify = false ;
88
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
89
+ this.v.set('frame', { width: 55 }) ;
90
+ didNotify.shouldEqual(true) ;
91
+ },
92
+
93
+ "changing the scrollFrame should scroll": function() {
94
+ var didNotify = false ;
95
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
96
+
97
+ this.v.set('scrollFrame', { y: -20, x: -20 }) ;
98
+
99
+ this.v.get('scrollFrame').y.shouldEqual(-20) ;
100
+ this.v.get('scrollFrame').x.shouldEqual(0) ;
101
+ didNotify.shouldEqual(true) ;
102
+ },
103
+
104
+ setup: function() { this.v = SC.page.get('case2'); }
105
+
106
+ });
107
+
108
+ // CASE 3: Scrollable view with hidden overflow content
109
+ Test.context("CASE 3: Scrollable view with hidden overflow content", {
110
+
111
+ "scrollFrame origin should == 0,0; size should == innerFrame": function() {
112
+ var f = this.v.get('innerFrame') ;
113
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
114
+
115
+ console.log('CASE 3 ----') ;
116
+ console.log('f:' + $H(f).inspect()) ;
117
+ console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
118
+ console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
119
+ console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
120
+
121
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
122
+ },
123
+
124
+ "resizing frame should change scrollFrame width but not height": function() {
125
+ var f = this.v.get('innerFrame') ;
126
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
127
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
128
+
129
+ this.v.set('frame', { width: 50, height: 50 }) ;
130
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(false) ;
131
+
132
+ var f = this.v.get('innerFrame') ;
133
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
134
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
135
+ },
136
+
137
+ "resizing frame should notify change on scrollFrame": function() {
138
+ var didNotify = false ;
139
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
140
+ this.v.set('frame', { width: 55 }) ;
141
+ didNotify.shouldEqual(true) ;
142
+ },
143
+
144
+ "changing the scrollFrame should scroll": function() {
145
+ var didNotify = false ;
146
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
147
+
148
+ this.v.set('scrollFrame', { y: -20, x: -20 }) ;
149
+
150
+ this.v.get('scrollFrame').y.shouldEqual(-20) ;
151
+ this.v.get('scrollFrame').x.shouldEqual(0) ;
152
+ didNotify.shouldEqual(true) ;
153
+ },
154
+
155
+
156
+ setup: function() { this.v = SC.page.get('case3'); }
157
+
158
+ });
159
+
160
+ // CASE 4: Scrollable view with scrollbar and vertical overflow content
161
+ Test.context("CASE 4: Scrollable view with scrollbar and vertical overflow content", {
162
+
163
+ "scrollFrame origin should == 0,0; size should == innerFrame": function() {
164
+ var f = this.v.get('innerFrame') ;
165
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
166
+
167
+ console.log('CASE 4 ----') ;
168
+ console.log('f:' + $H(f).inspect()) ;
169
+ console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
170
+ console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
171
+ console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
172
+
173
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
174
+ },
175
+
176
+ "resizing frame should change scrollFrame width but not height": function() {
177
+ var f = this.v.get('innerFrame') ;
178
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
179
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
180
+
181
+ this.v.set('frame', { width: 50, height: 50 }) ;
182
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(false) ;
183
+
184
+ var f = this.v.get('innerFrame') ;
185
+ f.x = f.y = 0 ; f.height = CHILD_HEIGHT ;
186
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
187
+ },
188
+
189
+ "resizing frame should notify change on scrollFrame": function() {
190
+ var didNotify = false ;
191
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
192
+ this.v.set('frame', { width: 55 }) ;
193
+ didNotify.shouldEqual(true) ;
194
+ },
195
+
196
+ "scrolling should trigger notification and change value": function() {
197
+ var f= this.v.get('scrollFrame') ;
198
+ var didNotify = false ;
199
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
200
+
201
+ // fake a scroll
202
+ this.v.rootElement.scrollTop = 10 ;
203
+ this.v._onscroll() ;
204
+
205
+ didNotify.shouldEqual(true) ;
206
+ SC.rectsEqual(this.v.get('scrollFrame'), f).shouldEqual(false) ;
207
+ this.v.get('scrollFrame').y.shouldEqual(-10) ;
208
+ },
209
+
210
+ "changing the scrollFrame should scroll": function() {
211
+ var didNotify = false ;
212
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
213
+
214
+ this.v.set('scrollFrame', { y: -20, x: -20 }) ;
215
+
216
+ this.v.get('scrollFrame').y.shouldEqual(-20) ;
217
+ this.v.get('scrollFrame').x.shouldEqual(0) ;
218
+ didNotify.shouldEqual(true) ;
219
+ },
220
+
221
+ setup: function() { this.v = SC.page.get('case4'); }
222
+
223
+ });
224
+
225
+ Test.context("CASE 5: Scrollable view with scrollbar and horizontal overflow content", {
226
+
227
+ "scrollFrame origin should == 0,0; size should == innerFrame.height + child width": function() {
228
+ var f = this.v.get('innerFrame') ;
229
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
230
+
231
+ console.log('CASE 5 ----') ;
232
+ console.log('f:' + $H(f).inspect()) ;
233
+ console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
234
+ console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
235
+ console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
236
+
237
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
238
+ },
239
+
240
+ "resizing frame should change scrollFrame height but not width": function() {
241
+ var f = this.v.get('innerFrame') ;
242
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
243
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
244
+
245
+ this.v.set('frame', { width: 50, height: 50 }) ;
246
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(false) ;
247
+
248
+ var f = this.v.get('innerFrame') ;
249
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
250
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
251
+ },
252
+
253
+ "resizing frame should notify change on scrollFrame": function() {
254
+ var didNotify = false ;
255
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
256
+ this.v.set('frame', { width: 55 }) ;
257
+ didNotify.shouldEqual(true) ;
258
+ },
259
+
260
+
261
+ "scrolling should trigger notification and change value": function() {
262
+ var f= this.v.get('scrollFrame') ;
263
+ var didNotify = false ;
264
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
265
+
266
+ // fake a scroll
267
+ this.v.rootElement.scrollLeft = 10 ;
268
+ this.v._onscroll() ;
269
+
270
+ didNotify.shouldEqual(true) ;
271
+ SC.rectsEqual(this.v.get('scrollFrame'), f).shouldEqual(false) ;
272
+ this.v.get('scrollFrame').x.shouldEqual(-10) ;
273
+ },
274
+
275
+ "changing the scrollFrame should scroll": function() {
276
+ var didNotify = false ;
277
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
278
+
279
+ this.v.set('scrollFrame', { y: -20, x: -20 }) ;
280
+
281
+ this.v.get('scrollFrame').x.shouldEqual(-20) ;
282
+ this.v.get('scrollFrame').y.shouldEqual(0) ;
283
+ didNotify.shouldEqual(true) ;
284
+ },
285
+
286
+
287
+ setup: function() { this.v = SC.page.get('case5'); }
288
+
289
+ });
290
+
291
+ Test.context("CASE 6: Scrollable view with scrollbar and horizontal overflow content", {
292
+
293
+ "scrollFrame origin should == 0,0; size should == fix height of child": function() {
294
+ var f = this.v.get('innerFrame') ;
295
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
296
+ f.height = CHILD_HEIGHT ;
297
+
298
+ console.log('CASE 6 ----') ;
299
+ console.log('f:' + $H(f).inspect()) ;
300
+ console.log('scroll:' + $H(this.v.get('scrollFrame')).inspect()) ;
301
+ console.log('innerFrame:' + $H(this.v.get('innerFrame')).inspect()) ;
302
+ console.log('frame:' + $H(this.v.get('frame')).inspect()) ;
303
+
304
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
305
+ },
306
+
307
+ "resizing frame should change not change scrollFrame": function() {
308
+ var f = this.v.get('innerFrame') ;
309
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
310
+ f.height = CHILD_HEIGHT ;
311
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
312
+
313
+ this.v.set('frame', { width: 50, height: 50 }) ;
314
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
315
+
316
+ var f = this.v.get('innerFrame') ;
317
+ f.x = f.y = 0 ; f.width = CHILD_WIDTH ;
318
+ f.height = CHILD_HEIGHT ;
319
+ SC.rectsEqual(f, this.v.get('scrollFrame')).shouldEqual(true) ;
320
+ },
321
+
322
+ "resizing frame should notify change on scrollFrame": function() {
323
+ var didNotify = false ;
324
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
325
+ this.v.set('frame', { width: 55 }) ;
326
+ didNotify.shouldEqual(true) ;
327
+ },
328
+
329
+ "scrolling should trigger notification and change value": function() {
330
+ var f= this.v.get('scrollFrame') ;
331
+ var didNotify = false ;
332
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
333
+
334
+ // fake a scroll
335
+ this.v.rootElement.scrollTop = 10 ;
336
+ this.v.rootElement.scrollLeft = 10 ;
337
+ this.v._onscroll() ;
338
+
339
+ didNotify.shouldEqual(true) ;
340
+ SC.rectsEqual(this.v.get('scrollFrame'), f).shouldEqual(false) ;
341
+ this.v.get('scrollFrame').y.shouldEqual(-10) ;
342
+ this.v.get('scrollFrame').x.shouldEqual(-10) ;
343
+ },
344
+
345
+
346
+ "changing the scrollFrame should scroll": function() {
347
+ var didNotify = false ;
348
+ this.v.addObserver('scrollFrame', function() { didNotify = true; }) ;
349
+
350
+ this.v.set('scrollFrame', { y: -20, x: -20 }) ;
351
+
352
+ this.v.get('scrollFrame').y.shouldEqual(-20) ;
353
+ this.v.get('scrollFrame').x.shouldEqual(-20) ;
354
+ didNotify.shouldEqual(true) ;
355
+ },
356
+
357
+
358
+ setup: function() { this.v = SC.page.get('case6'); }
359
+
360
+ });
361
+
362
+ main = function() { SC.page.awake(); };
363
+
364
+ </script>
365
+
366
+ <% end %>
367
+
368
+ <% content_for('body') do %>
369
+
370
+ <style>
371
+
372
+ .case {
373
+ background-color: white;
374
+ position: absolute;
375
+ width: 190px;
376
+ height: 90px;
377
+ border: 1px blue solid;
378
+ }
379
+
380
+ .case .child { border: 1px red solid; }
381
+
382
+ .base {
383
+ float: left;
384
+ width: 200px;
385
+ height: 100px;
386
+ border: 1px #aaa solid;
387
+ position: relative;
388
+ margin: 2px;
389
+ }
390
+
391
+ .cases {
392
+ position: absolute;
393
+ bottom: 0 ;
394
+ left: 0;
395
+ right: 0;
396
+ border-top: 1px #ccc solid;
397
+ background-color: #f0f0f0;
398
+ }
399
+
400
+ .base label {
401
+ position: absolute;
402
+ bottom: 4px;
403
+ left: 4px;
404
+ }
405
+
406
+ .case2, .case3 { overflow: hidden; }
407
+ .case4, .case5, .case6 { overflow: auto; }
408
+
409
+ .case2 .child,
410
+ .case3 .child,
411
+ .case4 .child,
412
+ .case6 .child {
413
+ height: 150px;
414
+ }
415
+
416
+ .case5 .child,
417
+ .case6 .child {
418
+ width: 300px;
419
+ }
420
+
421
+ </style>
422
+
423
+ <div class="cases">
424
+ <div class="base">
425
+ <label>Case 1</label>
426
+ <% view :case1, :class => 'case' do %>
427
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
428
+ <% end %>
429
+ </div>
430
+
431
+ <div class="base">
432
+ <label>Case 2</label>
433
+ <% view :case2, :class => 'case' do %>
434
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
435
+ <% end %>
436
+ </div>
437
+
438
+ <div class="base">
439
+ <label>Case 3</label>
440
+ <% view :case3, :class => 'case', :properties => { :is_scrollable => true } do %>
441
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
442
+ <% end %>
443
+ </div>
444
+
445
+ <div class="base">
446
+ <label>Case 4</label>
447
+ <% view :case4, :class => 'case', :properties => { :is_scrollable => true } do %>
448
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
449
+ <% end %>
450
+ </div>
451
+
452
+ <div class="base">
453
+ <label>Case 5</label>
454
+ <% view :case5, :class => 'case', :properties => { :is_scrollable => true } do %>
455
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
456
+ <% end %>
457
+ </div>
458
+
459
+ <div class="base">
460
+ <label>Case 6</label>
461
+ <% view :case6, :class => 'case', :properties => { :is_scrollable => true } do %>
462
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
463
+ <% end %>
464
+ </div>
465
+
466
+ </div>
467
+
468
+ <% end %>