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,353 @@
1
+ <% # ========================================================================
2
+ # SC.View Frame/Rects Unit Test
3
+ #
4
+ # This test validates the various frame properties for a view given
5
+ # different configurations.
6
+ #
7
+ # ========================================================================
8
+ %>
9
+ <% content_for('final') do %>
10
+
11
+ <script>
12
+
13
+ Test.context("CASE 1: Auto-layout view with no padding & no border", {
14
+
15
+ "frame should reflect current offset settings": function() {
16
+ var el = this.v.rootElement ;
17
+ var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
18
+ console.log(this.v.get('frame').x) ;
19
+ console.log('this.frame', this.v.get('frame')) ;
20
+ SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
21
+ },
22
+
23
+ "frame should change when CSS changed": function() {
24
+ var origFrame = this.v.get('frame') ;
25
+
26
+ this.v.addClassName('half') ;
27
+ this.v.viewFrameDidChange() ;
28
+
29
+ SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
30
+
31
+ // remove the class. make sure we have restored the frame
32
+ this.v.removeClassName('half') ; //reset
33
+ this.v.viewFrameDidChange() ;
34
+ SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(true) ;
35
+ },
36
+
37
+ "setting frame should change style, even if it does not impact actual value": function() {
38
+ var f = this.v.get('frame') ;
39
+ var ret = this.v.set('frame', { x: 10, y: 10 }) ;
40
+
41
+ // it should change the style though
42
+ this.v.getStyle('left').shouldEqual('10px');
43
+ this.v.getStyle('top').shouldEqual('10px');
44
+
45
+ // change the top & left. Since the layout is static here, this should not actually
46
+ // change anything.
47
+ SC.rectsEqual(ret, f).shouldEqual(true) ;
48
+ },
49
+
50
+ setup: function() { this.v = SC.page.get('case1'); }
51
+
52
+ });
53
+ //
54
+ // CASE 2: Manual-layout of view
55
+ Test.context("CASE 2: Manual-layout of view", {
56
+
57
+ "frame should reflect current offset settings at first": function() {
58
+ var el = this.v.rootElement ;
59
+ var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
60
+ SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
61
+ },
62
+
63
+ "should get absolute positioning": function() {
64
+ this.v.getStyle('position').shouldEqual('absolute') ;
65
+ },
66
+
67
+ "frame should reflect set values exactly": function() {
68
+ var f = { x: 10, y: 10, width: 20, height: 20 } ;
69
+ var ret = this.v.set('frame', f);
70
+ SC.rectsEqual(f,ret).shouldEqual(true) ;
71
+ SC.rectsEqual(this.v.get('frame'), f).shouldEqual(true) ;
72
+ },
73
+
74
+ "actual offset should reflect set values exactly": function() {
75
+ var f = { x: 10, y: 10, width: 20, height: 20 } ;
76
+ var ret = this.v.set('frame', f);
77
+ var el = this.v.rootElement;
78
+ el.offsetLeft.shouldEqual(10) ;
79
+ el.offsetTop.shouldEqual(10) ;
80
+ el.offsetWidth.shouldEqual(20) ;
81
+ el.offsetHeight.shouldEqual(20) ;
82
+ },
83
+
84
+ "applying CSS class should not change frame": function() {
85
+ var f = this.v.get('frame') ;
86
+ this.v.addClassName('half') ;
87
+ SC.rectsEqual(this.v.get('frame'),f).shouldEqual(true) ;
88
+ },
89
+
90
+ "getting frame should cache the value": function() {
91
+ f = this.v.get('frame') ;
92
+ this.assertNotNull(this.v._frame) ;
93
+ },
94
+
95
+ setup: function() { this.v = SC.page.get('case2'); }
96
+
97
+ });
98
+
99
+ // CASE 3: Manual-layout View with padding & border
100
+ Test.context("CASE 3: Manual-layout of view with padding & border", {
101
+
102
+ "frame size should include padding and border": function() {
103
+ var f = this.v.get('frame') ;
104
+ var el = this.v.rootElement ;
105
+ Math.round(parseFloat(el.getStyle('width'),0)).shouldEqual(f.width - 24) ;
106
+ Math.round(parseFloat(el.getStyle('height'),0)).shouldEqual(f.height - 24) ;
107
+ },
108
+
109
+ "changing frame size should subtract padding and border": function() {
110
+ this.v.set('frame', { width: 50, height: 50 }) ;
111
+ var f = this.v.get('frame') ;
112
+ f.width.shouldEqual(50) ;
113
+ f.height.shouldEqual(50);
114
+
115
+ var el = this.v.rootElement ;
116
+ Math.round(parseFloat(el.getStyle('width'),0)).shouldEqual(f.width - 24) ;
117
+ Math.round(parseFloat(el.getStyle('height'),0)).shouldEqual(f.height - 24) ;
118
+ },
119
+
120
+ setup: function() { this.v = SC.page.get('case3'); }
121
+
122
+ }) ;
123
+
124
+ // CASE 4: Child view inside of view with overflow = hidden
125
+ // NOTE: Cases 4,5 & 6 test a specific bug in FireFox.
126
+ Test.context("CASE 4: Absolute positioned Child view inside of view with overflow = hidden", {
127
+
128
+ "frame origin should be 0,0 & size should match owner's innerFrame": function() {
129
+ var vf = this.v.get('innerFrame') ;
130
+ var f = this.v.child.get('frame') ;
131
+ f.x.shouldEqual(0) ;
132
+ f.y.shouldEqual(0) ;
133
+ f.width.shouldEqual(62) ;
134
+ },
135
+
136
+ "nested frame origin should be 0,0 inside of parent": function() {
137
+ var f = this.v.child.nestedChild.get('frame') ;
138
+ f.x.shouldEqual(0) ;
139
+ f.y.shouldEqual(0) ;
140
+ },
141
+
142
+ "setting child frame should reflect in new frame value": function() {
143
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
144
+ var f = this.v.child.get('frame') ;
145
+ f.x.shouldEqual(10) ;
146
+ f.y.shouldEqual(10) ;
147
+ },
148
+
149
+ setup: function() { this.v = SC.page.get('case4'); }
150
+
151
+ }) ;
152
+
153
+ // CASE 5: Child view inside of view with overflow = hidden
154
+ Test.context("CASE 5: Non-positioned Child view inside of view with overflow = hidden", {
155
+
156
+ "frame origin should be 0,0 & size should match owner's innerFrame": function() {
157
+ var vf = this.v.get('innerFrame') ;
158
+ var f = this.v.child.get('frame') ;
159
+ f.x.shouldEqual(0) ;
160
+ f.y.shouldEqual(0) ;
161
+ f.width.shouldEqual(vf.width) ;
162
+ },
163
+
164
+ "nested frame origin should be 1,1 to account for border offset of parent": function() {
165
+ var f = this.v.child.nestedChild.get('frame') ;
166
+ f.x.shouldEqual(1) ;
167
+ f.y.shouldEqual(1) ;
168
+ },
169
+
170
+ "setting child frame should not move child frame": function() {
171
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
172
+ var f = this.v.child.get('frame') ;
173
+ f.x.shouldEqual(0) ;
174
+ f.y.shouldEqual(0) ;
175
+ },
176
+
177
+ setup: function() { this.v = SC.page.get('case5'); }
178
+
179
+ }) ;
180
+
181
+ Test.context("CASE 6: Relative positioned Child view inside of view with overflow = hidden", {
182
+
183
+ "frame origin should be 0,0 & size should match owner's innerFrame": function() {
184
+ var vf = this.v.get('innerFrame') ;
185
+ var f = this.v.child.get('frame') ;
186
+ f.x.shouldEqual(0) ;
187
+ f.y.shouldEqual(0) ;
188
+ f.width.shouldEqual(62) ;
189
+ },
190
+
191
+ "nested frame origin should be 0,0 inside of parent": function() {
192
+ var f = this.v.child.nestedChild.get('frame') ;
193
+ f.x.shouldEqual(0) ;
194
+ f.y.shouldEqual(0) ;
195
+ },
196
+
197
+ "setting child frame should reflect in new frame value that includes borders": function() {
198
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
199
+ var f = this.v.child.get('frame') ;
200
+ f.x.shouldEqual(10) ;
201
+ f.y.shouldEqual(10) ;
202
+ },
203
+
204
+ setup: function() { this.v = SC.page.get('case6'); }
205
+
206
+ }) ;
207
+
208
+ Test.context("CASE 7: Create view (not in the window)", {
209
+
210
+ "frame should be 10,10,30,30 even though it is not on screen": function() {
211
+ var f = { x: 10, y: 10, width: 30, height: 30 };
212
+ var vf = this.v.get('frame') ;
213
+ SC.rectsEqual(f,vf).shouldEqual(true) ;
214
+ },
215
+
216
+ "resizing frame should update frame": function() {
217
+ var f = { x: 20, y: 20, width: 40, height: 40 } ;
218
+ this.v.set('frame', f) ;
219
+ var vf = this.v.get('frame') ;
220
+ SC.rectsEqual(f,vf).shouldEqual(true) ;
221
+ },
222
+
223
+ setup: function() { this.v = SC.View.extend({
224
+ emptyElement: '<div style="width: 30px; height: 30px; left: 10px; top: 10px; position: absolute;"></div>'
225
+ }).create(); }
226
+
227
+ }) ;
228
+
229
+ main = function() { SC.page.awake(); };
230
+
231
+ </script>
232
+
233
+ <% end %>
234
+
235
+ <% # Create the views for the various use cases. %>
236
+ <% content_for('page_javascript') do %>
237
+ <script>
238
+ </script>
239
+ <% end %>
240
+
241
+ <% content_for('body') do %>
242
+
243
+ <style>
244
+
245
+ .case { background-color: white; }
246
+ .case .child { border: 1px red solid; }
247
+
248
+ .base {
249
+ float: left;
250
+ width: 200px;
251
+ height: 100px;
252
+ border: 1px #aaa solid;
253
+ position: relative;
254
+ margin: 2px;
255
+ }
256
+
257
+ .cases { position: absolute; bottom: 0 ; left: 0; right: 0; border-top: 1px #ccc solid; }
258
+
259
+ .base label {
260
+ position: absolute;
261
+ bottom: 4px;
262
+ left: 4px;
263
+ }
264
+
265
+ .half { width: 50%; }
266
+
267
+ .case2, .case3 { position: absolute; }
268
+
269
+ .case3 {
270
+ border: 2px red solid ;
271
+ padding: 10px;
272
+ }
273
+
274
+ .case4 {
275
+ overflow: hidden;
276
+ position: relative;
277
+ border-left: 5px blue solid;
278
+ height: 60px;
279
+ }
280
+
281
+ .case5 {
282
+ overflow: auto;
283
+ position: relative;
284
+ border-left: 5px blue solid;
285
+ height: 60px;
286
+ }
287
+
288
+ .case4 .child {
289
+ position: absolute;
290
+ width: 60px;
291
+ }
292
+
293
+ .case6 .child {
294
+ position: relative;
295
+ width: 60px;
296
+ }
297
+
298
+ .nested_child { border: 1px green solid; }
299
+
300
+ </style>
301
+
302
+ <div class="cases">
303
+ <div class="base">
304
+ <label>Case 1</label>
305
+ <% view :case1, :class => 'case' do %>
306
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
307
+ <% end %>
308
+ </div>
309
+
310
+ <div class="base">
311
+ <label>Case 2</label>
312
+ <% view :case2, :class => 'case' do %>
313
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
314
+ <% end %>
315
+ </div>
316
+
317
+ <div class="base">
318
+ <label>Case 3</label>
319
+ <% view :case3, :class => 'case' do %>
320
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
321
+ <% end %>
322
+ </div>
323
+
324
+ <div class="base">
325
+ <label>Case 4</label>
326
+ <% view :case4, :class => 'case' do %>
327
+ <% view :child, :outlet => true do %>
328
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
329
+ <% end %>
330
+ <% end %>
331
+ </div>
332
+
333
+ <div class="base">
334
+ <label>Case 5</label>
335
+ <% view :case5, :class => 'case' do %>
336
+ <% view :child, :outlet => true do %>
337
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
338
+ <% end %>
339
+ <% end %>
340
+ </div>
341
+
342
+ <div class="base">
343
+ <label>Case 6</label>
344
+ <% view :case6, :class => 'case' do %>
345
+ <% view :child, :outlet => true do %>
346
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
347
+ <% end %>
348
+ <% end %>
349
+ </div>
350
+
351
+ </div>
352
+
353
+ <% end %>
@@ -0,0 +1,347 @@
1
+ <% # ========================================================================
2
+ # SC.View innerFrame Unit Test
3
+ #
4
+ # The innerFrame represents the frame less any padding or scroll bars.
5
+ # It should update whenever the frame updates. Verify this.
6
+ #
7
+ # ========================================================================
8
+ %>
9
+ <% content_for('final') do %>
10
+
11
+ <script>
12
+
13
+ Test.context("CASE 1: Auto-layout view with no padding & no border", {
14
+
15
+ "frame should == innerFrame": function() {
16
+ SC.rectsEqual(this.v.get('frame'), this.v.get('innerFrame')).shouldEqual(true) ;
17
+ },
18
+
19
+ "frame & innerFrame should change when CSS changed and viewFrameDidChange() is called": function() {
20
+ var origFrame = this.v.get('frame') ;
21
+ var origInnerFrame = this.v.get('innerFrame') ;
22
+
23
+ this.v.addClassName('half') ;
24
+ this.v.viewFrameDidChange() ;
25
+
26
+ SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
27
+ SC.rectsEqual(this.v.get('innerFrame'), origInnerFrame).shouldEqual(false) ;
28
+
29
+ this.v.removeClassName('half') ; //reset
30
+ },
31
+
32
+ setup: function() { this.v = SC.page.get('case1'); }
33
+
34
+ });
35
+
36
+ // CASE 2: Auto-layout of view with padding
37
+ // - same as Case 1, except innerFrame = frame less padding
38
+ CASE2_OFFSET = 2;
39
+ Test.context("CASE 2: Auto-layout view with padding & border", {
40
+
41
+ "innerFrame should == frame less border": function() {
42
+ var f = this.v.get('frame') ;
43
+ f.x += CASE2_OFFSET; f.y += CASE2_OFFSET;
44
+ f.width -= (CASE2_OFFSET*2); f.height -= (CASE2_OFFSET*2) ;
45
+ //console.log('f: %@ if: %@'.fmt($H(f).inspect(), $H(this.v.get('innerFrame')).inspect()));
46
+
47
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
48
+ },
49
+
50
+ "frame & innerFrame should change when CSS changed and viewFrameDidChange is called.; innerFrame should maintain proportion": function() {
51
+ var origFrame = this.v.get('frame') ;
52
+ var origInnerFrame = this.v.get('innerFrame') ;
53
+
54
+ // verify that frames change
55
+ this.v.addClassName('half') ;
56
+ this.v.viewFrameDidChange() ;
57
+
58
+ SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
59
+ SC.rectsEqual(this.v.get('innerFrame'), origInnerFrame).shouldEqual(false) ;
60
+
61
+ // verify that innerFrame changes correctly.
62
+ var f = this.v.get('frame') ;
63
+ f.x += CASE2_OFFSET; f.y += CASE2_OFFSET;
64
+ f.width -= (CASE2_OFFSET*2); f.height -= (CASE2_OFFSET*2) ;
65
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
66
+
67
+ this.v.removeClassName('half') ; //reset
68
+ },
69
+
70
+ "changing border should change innerFrame": function() {
71
+ this.v.setStyle({ border: '5px red solid' }) ;
72
+ this.v.viewFrameDidChange() ;
73
+ var f = this.v.get('frame') ;
74
+ f.x += 5; f.y += 5;
75
+ f.width -= 10; f.height -= 10 ;
76
+
77
+ var got = this.v.get('innerFrame') ;
78
+ console.log('expected: %@ got: %@'.fmt($H(f).inspect(), $H(got).inspect()));
79
+ SC.rectsEqual(f, got).shouldEqual(true) ;
80
+ },
81
+
82
+ setup: function() { this.v = SC.page.get('case2'); }
83
+
84
+ });
85
+
86
+ // CASE 3: Manual-layout view with some padding and border
87
+ // - innerFrame should update at frame is changed.
88
+ CASE3_OFFSET = 2;
89
+ CASE3_OFFSET_THICK = 5 ;
90
+
91
+ Test.context("CASE 3: manual-layout view with some padding and no border", {
92
+
93
+ "innerFrame should == frame less border": function() {
94
+ var f = this.v.get('frame') ;
95
+ f.x += CASE3_OFFSET; f.y += CASE3_OFFSET;
96
+ f.width -= (CASE3_OFFSET*2); f.height -= (CASE3_OFFSET*2) ;
97
+
98
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
99
+ },
100
+
101
+ "after frame change, innerFrame should == frame less border, viewFrameDidChange is not required.": function() {
102
+ var f = this.v.set('frame', { width: 50, x: 10, y: 10, height: 50 }) ;
103
+ f.x += CASE3_OFFSET; f.y += CASE3_OFFSET;
104
+ f.width -= (CASE3_OFFSET*2); f.height -= (CASE3_OFFSET*2) ;
105
+ //console.log('f: %@ if: %@'.fmt($H(f).inspect(), $H(this.v.get('innerFrame')).inspect()));
106
+
107
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
108
+ },
109
+
110
+ "changing CSS to change width should not impact innerFrame if viewFrameDidChange is called": function() {
111
+ var f = this.v.get('frame') ;
112
+ f.x += CASE3_OFFSET; f.y += CASE3_OFFSET;
113
+ f.width -= (CASE3_OFFSET*2); f.height -= (CASE3_OFFSET*2) ;
114
+
115
+ this.v.addClassName('half') ;
116
+ this.v.viewFrameDidChange() ;
117
+
118
+ //console.log('f: %@ if: %@'.fmt($H(f).inspect(), $H(this.v.get('innerFrame')).inspect()));
119
+
120
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
121
+ },
122
+
123
+ "changing CSS to change border width should impact innerFrame if viewFrameDidChange() is called": function() {
124
+
125
+ this.v.get('frame') ;
126
+ this.v.get('innerFrame'); // make sure the old value is cached.
127
+
128
+ this.v.addClassName('thick-border') ;
129
+ this.v.viewFrameDidChange() ;
130
+
131
+ // calculate the expected new value
132
+ var f = this.v.get('frame') ;
133
+ f.x += CASE3_OFFSET_THICK; f.y += CASE3_OFFSET_THICK;
134
+ f.width -= (CASE3_OFFSET_THICK*2); f.height -= (CASE3_OFFSET_THICK*2) ;
135
+
136
+ console.log('f: %@ if: %@'.fmt($H(f).inspect(), $H(this.v.get('innerFrame')).inspect()));
137
+
138
+ SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
139
+ },
140
+
141
+ setup: function() { this.v = SC.page.get('case3'); }
142
+
143
+ });
144
+
145
+ // CASE 4: Child view inside of view with overflow = hidden
146
+ // NOTE: This test case deals with a specific bug in FireFox.
147
+ Test.context("CASE 4: Positioned Child view inside of view with overflow = hidden", {
148
+
149
+ "inner frame origin should be 1,1 & size should match width less border": function() {
150
+ var f = this.v.child.get('innerFrame') ;
151
+ f.x.shouldEqual(1) ;
152
+ f.y.shouldEqual(1) ;
153
+ f.width.shouldEqual(60) ;
154
+ },
155
+
156
+ "nested innerframe origin should be 1,1 inside of parent": function() {
157
+ var f = this.v.child.nestedChild.get('innerFrame') ;
158
+ f.x.shouldEqual(1) ;
159
+ f.y.shouldEqual(1) ;
160
+ },
161
+
162
+ "setting child frame should reflect in new frame value + border offset": function() {
163
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
164
+ var f = this.v.child.get('innerFrame') ;
165
+ f.x.shouldEqual(11) ;
166
+ f.y.shouldEqual(11) ;
167
+ },
168
+
169
+ setup: function() { this.v = SC.page.get('case4'); }
170
+
171
+ }) ;
172
+
173
+ // CASE 5: Child view inside of view with overflow = hidden
174
+ Test.context("CASE 5: Non-positioned Child view inside of view with overflow = hidden", {
175
+
176
+ "inner frame origin should be 1,1 & size should match width less border": function() {
177
+ var f = this.v.child.get('innerFrame') ;
178
+ f.x.shouldEqual(1) ;
179
+ f.y.shouldEqual(1) ;
180
+ },
181
+
182
+ "nested innerframe origin should be offset from case root.": function() {
183
+ var f = this.v.child.nestedChild.get('innerFrame') ;
184
+ f.x.shouldEqual(2) ;
185
+ f.y.shouldEqual(2) ;
186
+ },
187
+
188
+ "setting child frame should not move child frame or effect innerFrame": function() {
189
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
190
+ var f = this.v.child.get('innerFrame') ;
191
+ f.x.shouldEqual(1) ;
192
+ f.y.shouldEqual(1) ;
193
+ },
194
+
195
+ setup: function() { this.v = SC.page.get('case5'); }
196
+
197
+ }) ;
198
+
199
+ Test.context("CASE 6: Relative positioned Child view inside of view with overflow = hidden", {
200
+
201
+ "inner frame origin should be 1,1 & size should match width less border": function() {
202
+ var f = this.v.child.get('innerFrame') ;
203
+ f.x.shouldEqual(1) ;
204
+ f.y.shouldEqual(1) ;
205
+ f.width.shouldEqual(60) ;
206
+ },
207
+
208
+ "nested innerframe origin should be 1,1 inside of parent": function() {
209
+ var f = this.v.child.nestedChild.get('innerFrame') ;
210
+ f.x.shouldEqual(1) ;
211
+ f.y.shouldEqual(1) ;
212
+ },
213
+
214
+ "setting child frame should reflect in new frame value + border offset": function() {
215
+ this.v.child.set('frame', { x: 10, y: 10 }) ;
216
+ var f = this.v.child.get('innerFrame') ;
217
+ f.x.shouldEqual(11) ;
218
+ f.y.shouldEqual(11) ;
219
+ },
220
+
221
+ setup: function() { this.v = SC.page.get('case6'); }
222
+
223
+ }) ;
224
+
225
+ main = function() { SC.page.awake(); };
226
+
227
+ </script>
228
+
229
+ <% end %>
230
+
231
+ <% # Create the views for the various use cases. %>
232
+ <% content_for('page_javascript') do %>
233
+ <script>
234
+ </script>
235
+ <% end %>
236
+
237
+ <% content_for('body') do %>
238
+
239
+ <style>
240
+
241
+ .case { background-color: white; }
242
+ .case .child { border: 1px red solid; }
243
+
244
+ .base {
245
+ float: left;
246
+ width: 200px;
247
+ height: 100px;
248
+ border: 1px #aaa solid;
249
+ position: relative;
250
+ margin: 2px;
251
+ }
252
+
253
+ .cases { position: absolute; bottom: 0 ; left: 0; right: 0; border-top: 1px #ccc solid; }
254
+
255
+ .base label {
256
+ position: absolute;
257
+ bottom: 4px;
258
+ left: 4px;
259
+ }
260
+
261
+ .half { width: 50%; }
262
+
263
+ .case2, .case3 { padding: 10px; border: 2px blue solid; }
264
+
265
+ .case.thick-border { border: 5px green solid; }
266
+
267
+ .case4 {
268
+ overflow: hidden;
269
+ position: relative;
270
+ border-left: 5px blue solid;
271
+ height: 60px;
272
+ }
273
+
274
+ .case5 {
275
+ overflow: auto;
276
+ position: relative;
277
+ border-left: 5px blue solid;
278
+ height: 60px;
279
+ }
280
+
281
+ .case4 .child {
282
+ position: absolute;
283
+ width: 60px;
284
+ }
285
+
286
+ .case6 .child {
287
+ position: relative;
288
+ width: 60px;
289
+ }
290
+
291
+
292
+ .nested_child { border: 1px green solid; }
293
+
294
+ </style>
295
+
296
+ <div class="cases">
297
+ <div class="base">
298
+ <label>Case 1</label>
299
+ <% view :case1, :class => 'case' do %>
300
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
301
+ <% end %>
302
+ </div>
303
+
304
+ <div class="base">
305
+ <label>Case 2</label>
306
+ <% view :case2, :class => 'case' do %>
307
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
308
+ <% end %>
309
+ </div>
310
+
311
+ <div class="base">
312
+ <label>Case 3</label>
313
+ <% view :case3, :class => 'case' do %>
314
+ <%= view :child, :outlet => true, :inner_html => 'Child' %>
315
+ <% end %>
316
+ </div>
317
+
318
+ <div class="base">
319
+ <label>Case 4</label>
320
+ <% view :case4, :class => 'case' do %>
321
+ <% view :child, :outlet => true do %>
322
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
323
+ <% end %>
324
+ <% end %>
325
+ </div>
326
+
327
+ <div class="base">
328
+ <label>Case 5</label>
329
+ <% view :case5, :class => 'case' do %>
330
+ <% view :child, :outlet => true do %>
331
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
332
+ <% end %>
333
+ <% end %>
334
+ </div>
335
+
336
+ <div class="base">
337
+ <label>Case 6</label>
338
+ <% view :case6, :class => 'case' do %>
339
+ <% view :child, :outlet => true do %>
340
+ <%= view :nested_child, :outlet => true, :inner_html => 'Nested' %>
341
+ <% end %>
342
+ <% end %>
343
+ </div>
344
+
345
+ </div>
346
+
347
+ <% end %>