sproutcore 0.9.1 → 0.9.2

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