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,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 %>