sproutcore 1.5.0.pre.4.1 → 1.5.0.pre.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/CHANGELOG +7 -0
  2. data/VERSION.yml +1 -1
  3. data/lib/buildtasks/manifest.rake +4 -3
  4. data/lib/frameworks/sproutcore/Buildfile +1 -2
  5. data/lib/frameworks/sproutcore/CHANGELOG.md +8 -3
  6. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/app-selector.css +19 -23
  7. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/button.css +139 -135
  8. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/dock.css +5 -0
  9. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/general.css +0 -1
  10. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/menu.css +10 -13
  11. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/modal.css +9 -8
  12. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/picker.css +19 -12
  13. data/lib/frameworks/sproutcore/apps/greenhouse/models/design.js +2 -2
  14. data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +1 -1
  15. data/lib/frameworks/sproutcore/apps/greenhouse/theme.js +2 -2
  16. data/lib/frameworks/sproutcore/apps/greenhouse/views/plist_item.js +3 -1
  17. data/lib/frameworks/sproutcore/frameworks/animation/core.js +1 -1
  18. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +31 -20
  19. data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +15 -9
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +5 -5
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +1 -1
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +23 -45
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +1 -1
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +60 -5
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/ready.js +1 -1
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +2 -2
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +4 -4
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/ready/done.js +32 -0
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +5 -2
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/append_remove.js +8 -3
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/layout.js +4 -4
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/collection.js +51 -5
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/core.js +18 -0
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/handlebars.js +261 -0
  35. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/animation.js +55 -0
  36. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +2 -19
  37. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/convertFrames.js +3 -1
  38. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/insertBefore.js +17 -0
  39. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +96 -1
  40. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/prepareContext.js +15 -0
  41. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/updateLayerLocation.js +19 -0
  42. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +8 -1
  43. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +179 -4
  44. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +8 -14
  45. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +7 -0
  46. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +4 -4
  47. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +51 -114
  48. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +84 -36
  49. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +4 -67
  50. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +244 -1
  51. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +1 -1
  52. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +1 -1
  53. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +7 -1
  54. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +1 -1
  55. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +2 -2
  56. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +23 -1
  57. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +4 -2
  58. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +4 -0
  59. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/discardChanges.js +4 -1
  60. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/record_type_is.js +4 -0
  61. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_comparisons.js +4 -0
  62. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_query_extensions.js +4 -0
  63. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +4 -0
  64. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/createRecord.js +5 -1
  65. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/destroyRecord.js +5 -1
  66. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/loadRecord.js +64 -0
  67. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +38 -35
  68. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/unloadRecords.js +4 -0
  69. data/lib/frameworks/sproutcore/frameworks/datetime/system/datetime.js +7 -4
  70. data/lib/frameworks/sproutcore/frameworks/datetime/tests/system/datetime.js +2 -2
  71. data/lib/frameworks/sproutcore/frameworks/debug/core.js +1 -1
  72. data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +5 -5
  73. data/lib/frameworks/sproutcore/frameworks/designer/coders/object.js +1 -1
  74. data/lib/frameworks/sproutcore/frameworks/designer/designers/view_designer.js +11 -3
  75. data/lib/frameworks/sproutcore/frameworks/designer/ext/binding.js +33 -0
  76. data/lib/frameworks/sproutcore/frameworks/designer/ext/object.js +1 -1
  77. data/lib/frameworks/sproutcore/frameworks/designer/ext/page.js +5 -33
  78. data/lib/frameworks/sproutcore/frameworks/designer/ext/view.js +0 -27
  79. data/lib/frameworks/sproutcore/frameworks/designer/tests/coders/page.js +54 -0
  80. data/lib/frameworks/sproutcore/frameworks/designer/tests/designers/view_designer.js +47 -0
  81. data/lib/frameworks/sproutcore/frameworks/designer/views/drawing.js +4 -4
  82. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +19 -6
  83. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +1 -1
  84. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/navigation_builder.js +1 -1
  85. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
  86. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +133 -39
  87. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +3 -3
  88. data/lib/frameworks/sproutcore/frameworks/desktop/tests/mixins/border.js +6 -5
  89. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +8 -2
  90. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/select_button/ui.js +10 -2
  91. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +8 -2
  92. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/ui.js +10 -2
  93. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/ui_diagram.js +15 -9
  94. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +8 -2
  95. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +8 -2
  96. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +10 -2
  97. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/ui.js +10 -2
  98. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +31 -0
  99. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +10 -3
  100. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/separator.js +10 -3
  101. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/ui.js +10 -3
  102. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +15 -8
  103. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +10 -3
  104. data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +1 -1
  105. data/lib/frameworks/sproutcore/frameworks/desktop/views/file.js +1 -1
  106. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +1 -7
  107. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +10 -0
  108. data/lib/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +3 -3
  109. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/collection_content.js +2 -2
  110. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +17 -5
  111. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +60 -27
  112. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
  113. data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +4 -4
  114. data/lib/frameworks/sproutcore/frameworks/foundation/system/cookie.js +29 -18
  115. data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +18 -18
  116. data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +5 -5
  117. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +62 -1
  118. data/lib/frameworks/sproutcore/frameworks/foundation/tests/integration/creating_views.js +8 -3
  119. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/ui.js +4 -3
  120. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/editable/ui.js +5 -3
  121. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/ui.js +5 -3
  122. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/cookie.js +20 -4
  123. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/utils/pointInElement.js +235 -0
  124. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +5 -0
  125. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +0 -2
  126. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +8 -3
  127. data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +2 -2
  128. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +19 -11
  129. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +6 -13
  130. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions.js +23 -117
  131. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/bind.js +136 -0
  132. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/collection.js +75 -0
  133. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/localization.js +5 -0
  134. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/view.js +115 -0
  135. data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +143 -80
  136. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +1 -1
  137. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +4 -4
  138. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +5 -5
  139. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array.js +14 -0
  140. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
  141. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +13 -13
  142. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +4 -4
  143. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +3 -3
  144. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +1 -1
  145. data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +25 -17
  146. data/lib/frameworks/sproutcore/themes/ace/designs/psds/panel/pointers.psd +0 -0
  147. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +18 -12
  148. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/button.css +30 -16
  149. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/button.css +27 -15
  150. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +5 -0
  151. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/button.css +8 -0
  152. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/button.css +25 -16
  153. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/button.css +21 -15
  154. data/lib/frameworks/sproutcore/themes/ace/resources/imagebutton/ace/imagebutton.css +11 -0
  155. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/panel.png +0 -0
  156. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/picker.css +41 -0
  157. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/pointers.png +0 -0
  158. data/lib/sproutcore.rb +2 -0
  159. data/lib/sproutcore/buildfile.rb +17 -17
  160. data/lib/sproutcore/buildfile/task.rb +4 -12
  161. data/lib/sproutcore/buildfile/task_manager.rb +13 -4
  162. data/lib/sproutcore/models/manifest.rb +3 -3
  163. data/lib/sproutcore/models/target.rb +1 -1
  164. data/spec/fixtures/real_world/Buildfile +1 -1
  165. data/vendor/chance/lib/chance/imagers/data_url.rb +38 -19
  166. data/vendor/chance/lib/chance/instance.rb +4 -7
  167. data/vendor/chance/lib/chance/slicing.rb +6 -10
  168. metadata +18 -5
  169. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/tabbed.css +0 -68
  170. data/lib/frameworks/sproutcore/frameworks/designer/coders/localization.js +0 -19
  171. data/lib/sproutcore/buildfile/cloneable.rb +0 -34
@@ -171,6 +171,35 @@ if (SC.platform.supportsCSSTransitions) {
171
171
  SC.RunLoop.end();
172
172
  });
173
173
 
174
+ test("should not cancel callback when value hasn't changed", function() {
175
+ var callbacks = 0, wasCancelled = NO, check = 0;
176
+ stop(2000);
177
+
178
+ SC.RunLoop.begin();
179
+ view.invokeLater(function() {
180
+ // this triggers the initial layoutStyle code
181
+ view.animate('left', 79, 0.500, function(data) {
182
+ callbacks++;
183
+ wasCancelled = data.isCancelled;
184
+ });
185
+ // this triggers a re-render, re-running the layoutStyle code
186
+ view.displayDidChange();
187
+ }, 1);
188
+ SC.RunLoop.end();
189
+
190
+ setTimeout(function() {
191
+ // capture the callbacks value
192
+ check = callbacks;
193
+ }, 250);
194
+
195
+ setTimeout(function() {
196
+ start();
197
+ equals(check, 0, "the callback should not have been cancelled initially");
198
+ equals(callbacks, 1, "the callback should have been fired");
199
+ equals(wasCancelled, NO, "the callback should not have been cancelled");
200
+ }, 1000);
201
+ });
202
+
174
203
  test("should handle transform attributes", function(){
175
204
  SC.RunLoop.begin();
176
205
  view.animate('rotateX', 45, { duration: 1 });
@@ -289,6 +318,32 @@ if (SC.platform.supportsCSSTransitions) {
289
318
  SC.RunLoop.end();
290
319
  });
291
320
 
321
+ test("should not add animation for properties that have the same value as existing layout", function() {
322
+ var callbacks = 0;
323
+
324
+ SC.RunLoop.begin();
325
+ // we set width to the same value, but we change height
326
+ view.invokeLater('animate', 1, {width: 100, height: 50}, 0.5, function() { callbacks++; });
327
+ SC.RunLoop.end();
328
+
329
+ ok(callbacks === 0, "precond - callback should not have been run yet");
330
+
331
+ stop(2000);
332
+
333
+ // we need to test changing the width at a later time
334
+ setTimeout(function() {
335
+ start();
336
+
337
+ equals(callbacks, 1, "callback should have been run once, for height change");
338
+
339
+ SC.RunLoop.begin();
340
+ view.animate('width', 50, 0.5);
341
+ SC.RunLoop.end();
342
+
343
+ equals(callbacks, 1, "callback should still have only been called once, even though width has now been animated");
344
+ }, 1000);
345
+ });
346
+
292
347
  test("should warn if multiple callbacks for transitions");
293
348
 
294
349
  }
@@ -5,11 +5,11 @@
5
5
  // ==========================================================================
6
6
 
7
7
  /*global module test equals context ok same Q$ htmlbody */
8
- htmlbody('<style> .sc-view { border: 1px blue solid; position: absolute; overflow: hidden; }</style>');
9
8
 
10
9
  var pane, a, aa ;
11
10
  module("SC.View#clippingFrame", {
12
11
  setup: function() {
12
+ htmlbody('<style> .sc-view { border: 1px blue solid; position: absolute; overflow: hidden; }</style>');
13
13
  SC.RunLoop.begin();
14
14
  pane = SC.Pane.design()
15
15
  .layout({ top: 0, left: 0, width: 200, height: 200 })
@@ -27,6 +27,7 @@ module("SC.View#clippingFrame", {
27
27
  pane.remove();
28
28
  pane = a = aa = null ;
29
29
  SC.RunLoop.end();
30
+ clearHtmlbody();
30
31
  }
31
32
  });
32
33
 
@@ -114,21 +115,3 @@ test("notifies receiver and each child if parent clipping frame changes", functi
114
115
  // number.
115
116
  equals(callCount, 2, 'should invoke observer on child and nested child');
116
117
  });
117
-
118
-
119
- test("does not notify child views of clippingFrame changes if child view has useStaticLayout: YES", function() {
120
- var callCount = 0;
121
-
122
- aa.set('useStaticLayout', YES);
123
-
124
- // setup observers
125
- function observer() { callCount++; }
126
- a.addObserver('clippingFrame', observer);
127
- aa.addObserver('clippingFrame', observer);
128
-
129
- // now, adjust layout of child so that clipping frame will change...
130
- a.adjust('top', -50);
131
-
132
- equals(callCount, 1, 'should invoke observer on child only');
133
- });
134
-
@@ -6,7 +6,6 @@
6
6
 
7
7
  /*global module test equals context ok same Q$ htmlbody */
8
8
 
9
- htmlbody('<style> .sc-view { border: 1px blue solid; position: absolute; }</style>');
10
9
 
11
10
  // ..........................................................
12
11
  // COMMON SETUP CODE
@@ -15,6 +14,8 @@ var pane, a, b, aa, aaa, bb, f ;
15
14
  var A_LEFT = 10, A_TOP = 10, B_LEFT = 100, B_TOP = 100;
16
15
 
17
16
  function setupFrameViews() {
17
+ htmlbody('<style> .sc-view { border: 1px blue solid; position: absolute; }</style>');
18
+
18
19
  pane = SC.Pane.design()
19
20
  .layout({ top: 0, left: 0, width: 400, height: 300 })
20
21
  .childView(SC.View.design()
@@ -43,6 +44,7 @@ function setupFrameViews() {
43
44
  function teardownFrameViews() {
44
45
  pane.remove() ;
45
46
  pane = a = aa = aaa = b = bb = null ;
47
+ clearHtmlbody();
46
48
  }
47
49
 
48
50
  // ..........................................................
@@ -157,8 +157,25 @@ test("invokes parentViewDidChange() on child view. this is used by the view int
157
157
 
158
158
  parent.insertBefore(child, null);
159
159
  equals(callCount, 1, 'invoked parentViewDidChange');
160
+
161
+ var coreView = SC.CoreView.create();
162
+ parent.insertBefore(coreView, null);
163
+ equals(parent.get('childViews').lastObject(), coreView, "inserts SC.CoreView");
160
164
  });
161
165
 
166
+ test("invokes layoutDidChange() on child view", function() {
167
+
168
+ // monkey patch to test
169
+ var callCount = 0;
170
+ child.layoutDidChange = function() { callCount++; };
171
+
172
+ parent.insertBefore(child, null);
173
+ equals(callCount, 1, 'invoked layoutDidChange');
174
+
175
+ var coreView = SC.CoreView.create();
176
+ parent.insertBefore(coreView, null);
177
+ equals(parent.get('childViews').lastObject(), coreView, "inserts SC.CoreView");
178
+ });
162
179
  // VERIFY LAYER CHANGES ARE DEFERRED
163
180
  test("should not move layer immediately", function() {
164
181
 
@@ -25,7 +25,8 @@
25
25
  */
26
26
  function performLayoutTest(layout, no_f, no_s, with_f, with_s) {
27
27
  // make sure we add null properties and convert numbers to 'XXpx' to style layout.
28
- var layoutKeys = 'width height top bottom marginLeft marginTop left right zIndex minWidth maxWidth minHeight maxHeight'.w();
28
+ var layoutKeys = ('width height top bottom marginLeft marginTop left right zIndex minWidth maxWidth minHeight maxHeight ' +
29
+ 'borderTopWidth borderBottomWidth borderLeftWidth borderRightWidth').w();
29
30
  if (SC.platform.supportsCSSTransforms) { layoutKeys.push('transform'); }
30
31
 
31
32
  var frameKeys = 'x y width height'.w();
@@ -539,6 +540,100 @@
539
540
 
540
541
  }) ;
541
542
 
543
+
544
+ // ..........................................................
545
+ // TEST BORDER
546
+ //
547
+
548
+ module('BORDER LAYOUT VARIATIONS', commonSetup);
549
+
550
+ test("layout {top, left, width, height, border}", function() {
551
+ var layout = { top: 10, left: 10, width: 50, height: 50, border: 2 };
552
+ var s = { top: 10, left: 10, width: 46, height: 46,
553
+ borderTopWidth: 2, borderRightWidth: 2, borderBottomWidth: 2, borderLeftWidth: 2 } ;
554
+ var no_f = { x: 12, y: 12, width: 46, height: 46 } ;
555
+ var with_f = { x: 12, y: 12, width: 46, height: 46 } ;
556
+
557
+ performLayoutTest(layout, no_f, s, with_f, s) ;
558
+ }) ;
559
+
560
+ test("layout {top, left, bottom, right, border}", function() {
561
+ var layout = { top: 10, left: 10, bottom: 10, right: 10, border: 2 };
562
+ var no_f = { x: 12, y: 12, width: 0, height: 0 } ;
563
+ var with_f = { x: 12, y: 12, width: 176, height: 176 } ;
564
+ var s = { top: 10, left: 10, bottom: 10, right: 10,
565
+ borderTopWidth: 2, borderRightWidth: 2, borderBottomWidth: 2, borderLeftWidth: 2 } ;
566
+
567
+ performLayoutTest(layout, no_f, s, with_f, s) ;
568
+ }) ;
569
+
570
+ test("layout {top, left, bottom, right, borderTop, borderLeft, borderRight, borderBottom}", function() {
571
+ var layout = { top: 10, left: 10, bottom: 10, right: 10, borderTop: 1, borderRight: 2, borderBottom: 3, borderLeft: 4 };
572
+ var no_f = { x: 14, y: 11, width: 0, height: 0 } ;
573
+ var with_f = { x: 14, y: 11, width: 174, height: 176 } ;
574
+ var s = { top: 10, left: 10, bottom: 10, right: 10,
575
+ borderTopWidth: 1, borderRightWidth: 2, borderBottomWidth: 3, borderLeftWidth: 4 } ;
576
+
577
+ performLayoutTest(layout, no_f, s, with_f, s) ;
578
+ }) ;
579
+
580
+ test("layout {top, left, bottom, right, border, borderTop, borderLeft}", function() {
581
+ var layout = { top: 10, left: 10, bottom: 10, right: 10, border: 5, borderTop: 1, borderRight: 2 };
582
+ var no_f = { x: 15, y: 11, width: 0, height: 0 } ;
583
+ var with_f = { x: 15, y: 11, width: 173, height: 174 } ;
584
+ var s = { top: 10, left: 10, bottom: 10, right: 10,
585
+ borderTopWidth: 1, borderRightWidth: 2, borderBottomWidth: 5, borderLeftWidth: 5 } ;
586
+
587
+ performLayoutTest(layout, no_f, s, with_f, s) ;
588
+ }) ;
589
+
590
+ test("layout {bottom, right, width, height, border}", function() {
591
+
592
+ var layout = { bottom: 10, right: 10, width: 50, height: 50, border: 2 };
593
+ var no_f = { x: 2, y: 2, width: 46, height: 46 } ;
594
+ var with_f = { x: 142, y: 142, width: 46, height: 46 } ;
595
+ var s = { bottom: 10, right: 10, width: 46, height: 46,
596
+ borderTopWidth: 2, borderRightWidth: 2, borderBottomWidth: 2, borderLeftWidth: 2 } ;
597
+
598
+ performLayoutTest(layout, no_f, s, with_f, s) ;
599
+ }) ;
600
+
601
+ test("layout {centerX, centerY, width, height, border}", function() {
602
+
603
+ var layout = { centerX: 10, centerY: 10, width: 60, height: 60, border: 2 };
604
+ var no_f = { x: 12, y: 12, width: 56, height: 56 } ;
605
+ var with_f = { x: 82, y: 82, width: 56, height: 56 } ;
606
+ var s = { marginLeft: -18, marginTop: -18, width: 56, height: 56, top: "50%", left: "50%",
607
+ borderTopWidth: 2, borderRightWidth: 2, borderBottomWidth: 2, borderLeftWidth: 2 } ;
608
+
609
+ performLayoutTest(layout, no_f, s, with_f, s) ;
610
+ }) ;
611
+
612
+ test("layout {top, left, width: auto, height: auto}", function() {
613
+ child = SC.View.create({
614
+ useStaticLayout: YES,
615
+ render: function(context) {
616
+ // needed for auto
617
+ context.push('<div style="padding: 10px"></div>');
618
+ }
619
+ });
620
+
621
+ // parent MUST have a layer.
622
+ parent.createLayer();
623
+ var layer = parent.get('layer');
624
+ document.body.appendChild(layer);
625
+
626
+ var layout = { top: 0, left: 0, width: 'auto', height: 'auto', border: 2 };
627
+ var no_f = null;
628
+ var with_f = undefined; //{ x: 2, y: 2, width: 196, height: 196 };
629
+ var s = { top: 0, left: 0, width: 'auto', height: 'auto',
630
+ borderTopWidth: 2, borderRightWidth: 2, borderBottomWidth: 2, borderLeftWidth: 2 };
631
+
632
+ performLayoutTest(layout, no_f, s, with_f, s);
633
+
634
+ layer.parentNode.removeChild(layer);
635
+ });
636
+
542
637
 
543
638
  // ..........................................................
544
639
  // TEST FRAME/STYLEFRAME WHEN PARENT VIEW IS RESIZED
@@ -96,6 +96,21 @@ test("adds disabled class if view isEnabled = NO", function() {
96
96
 
97
97
  });
98
98
 
99
+ test("adds aria-disabled attribute if view isEnabled = NO", function() {
100
+ var view = SC.View.create(),
101
+ context = view.renderContext();
102
+
103
+ context = view.renderContext();
104
+ view.set('isEnabled', NO);
105
+ view.prepareContext(context, YES);
106
+ ok(context.attr('aria-disabled'), 'should have the aria-disabled attribute');
107
+
108
+ view.set('isEnabled', YES);
109
+ view.prepareContext(context, YES);
110
+ ok(context.attr('aria-disabled') === null, 'should NOT have the aria-disabled attribute');
111
+
112
+ });
113
+
99
114
  test("adds hidden class if view isVisible = NO", function() {
100
115
 
101
116
  var view = SC.View.create() ;
@@ -150,6 +150,25 @@ test("CASE 5b: insert child w/ layer before a sibling w/ NO layer - should creat
150
150
  ok(parentHasChild(newParentLayer, childLayer), 'newParentLayer should have childLayer');
151
151
  });
152
152
 
153
+ test("should insert a CoreView without layer before a sibling with layer", function() {
154
+ var newParent = SC.View.create().createLayer();
155
+ var newParentLayer = newParent.get('layer');
156
+
157
+ var sibling = SC.View.create().createLayer();
158
+ var siblingLayer = sibling.get('layer');
159
+
160
+ ok(newParentLayer, 'precond - newParent has a layer');
161
+ ok(sibling.get('layer'), 'precond - sibling has a layer');
162
+
163
+ child = SC.CoreView.create();
164
+
165
+ newParent.appendChild(sibling);
166
+ newParent.insertBefore(child, sibling);
167
+
168
+ ok(parentHasChild(newParentLayer, child.get('layer')), "child layer should belong to parent layer");
169
+ equals(child.get('layer').nextSibling, siblingLayer, "child layer should be inserted before sibling layer");
170
+ });
171
+
153
172
  // .......................................................
154
173
  // updateLayerLocationIfNeeded()
155
174
  //
@@ -79,6 +79,8 @@ SC.TemplateCollectionView = SC.TemplateView.extend({
79
79
  view.createLayer().$().appendTo(this.$());
80
80
  }
81
81
 
82
+ var itemOptions = this.itemViewOptions || {};
83
+
82
84
  // Add items, using previous if possible
83
85
  for (i=0, length=array.get('length'); i < length; i++) {
84
86
  item = array.objectAt(i);
@@ -86,7 +88,12 @@ SC.TemplateCollectionView = SC.TemplateView.extend({
86
88
  if (!view) {
87
89
  view = this.createChildView(itemViewClass.extend({
88
90
  content: item,
89
- tagName: 'li'
91
+ tagName: 'li',
92
+
93
+ render: function(context) {
94
+ sc_super();
95
+ SC.Handlebars.ViewHelper.applyAttributes(itemOptions, this, context);
96
+ }
90
97
  }));
91
98
  view.createLayer().$().appendTo(this.$());
92
99
  }
@@ -129,6 +129,17 @@ SC.CoreView.reopen(
129
129
  isVisible: YES,
130
130
  isVisibleBindingDefault: SC.Binding.bool(),
131
131
 
132
+ /**
133
+ Whether the view should be displayed. This is always YES,
134
+ unless the visibility module is added to SC.View.
135
+
136
+ If the visibility module is added, this property will be used to
137
+ optimize certain behaviors on the view. For example, updates to the
138
+ view layer will not be performed until the view becomes visible
139
+ in the window.
140
+ */
141
+ isVisibleInWindow: YES,
142
+
132
143
  // ..........................................................
133
144
  // CHILD VIEW SUPPORT
134
145
  //
@@ -257,6 +268,17 @@ SC.CoreView.reopen(
257
268
  return this;
258
269
  },
259
270
 
271
+ /**
272
+ Marks the view as needing a display update if the isVisible property changes.
273
+
274
+ Note that this behavior is identical to a display property. It is broken out
275
+ into its own observer so that it can be overridden with additional
276
+ functionality if the visibility module is applied to SC.View.
277
+ */
278
+ _sc_isVisibleDidChange: function() {
279
+ this.displayDidChange();
280
+ }.observes('isVisible'),
281
+
260
282
  /**
261
283
  Setting this property to YES will cause the updateLayerIfNeeded method to
262
284
  be invoked at the end of the runloop. You can also force a view to update
@@ -500,6 +522,78 @@ SC.CoreView.reopen(
500
522
  this.invokeOnce(this.updateLayerLocation) ;
501
523
  },
502
524
 
525
+ /**
526
+ If the parent view has changed, we need to insert this
527
+ view's layer into the layer of the new parent view.
528
+ */
529
+ parentViewDidChange: function() {
530
+ this.updateLayerLocation();
531
+ },
532
+
533
+ /**
534
+ This method is called when a view changes its location in the view
535
+ hierarchy. This method will update the underlying DOM-location of the
536
+ layer so that it reflects the new location.
537
+
538
+ @returns {SC.View} receiver
539
+ */
540
+ updateLayerLocation: function() {
541
+ // collect some useful value
542
+ // if there is no node for some reason, just exit
543
+ var node = this.get('layer'),
544
+ parentView = this.get('parentView'),
545
+ parentNode = parentView ? parentView.get('containerLayer') : null ;
546
+
547
+ // remove node from current parentNode if the node does not match the new
548
+ // parent node.
549
+ if (node && node.parentNode && node.parentNode !== parentNode) {
550
+ node.parentNode.removeChild(node);
551
+ }
552
+
553
+ // CASE 1: no new parentView. just remove from parent (above).
554
+ if (!parentView) {
555
+ if (node && node.parentNode) { node.parentNode.removeChild(node); }
556
+
557
+ // CASE 2: parentView has no layer, view has layer. destroy layer
558
+ // CASE 3: parentView has no layer, view has no layer, nothing to do
559
+ } else if (!parentNode) {
560
+ if (node) {
561
+ if (node.parentNode) { node.parentNode.removeChild(node); }
562
+ this.destroyLayer();
563
+ }
564
+
565
+ // CASE 4: parentView has layer, view has no layer. create layer & add
566
+ // CASE 5: parentView has layer, view has layer. move layer
567
+ } else {
568
+ if (!node) {
569
+ this.createLayer() ;
570
+ node = this.get('layer') ;
571
+ if (!node) { return; } // can't do anything without a node.
572
+ }
573
+
574
+ var siblings = parentView.get('childViews'),
575
+ nextView = siblings.objectAt(siblings.indexOf(this)+1),
576
+ nextNode = (nextView) ? nextView.get('layer') : null ;
577
+
578
+ // before we add to parent node, make sure that the nextNode exists...
579
+ if (nextView && (!nextNode || nextNode.parentNode!==parentNode)) {
580
+ nextView.updateLayerLocationIfNeeded() ;
581
+ nextNode = nextView.get('layer') ;
582
+ }
583
+
584
+ // add to parentNode if needed.
585
+ if ((node.parentNode!==parentNode) || (node.nextSibling!==nextNode)) {
586
+ parentNode.insertBefore(node, nextNode) ;
587
+ }
588
+ }
589
+
590
+ parentNode = parentView = node = nextNode = null ; // avoid memory leaks
591
+
592
+ this.set('layerLocationNeedsUpdate', NO) ;
593
+
594
+ return this ;
595
+ },
596
+
503
597
  /** @private -
504
598
  Invokes willDestroyLayer() on view and child views. Then sets layer to
505
599
  null for receiver.
@@ -585,9 +679,6 @@ SC.CoreView.reopen(
585
679
  applyAttributesToContext: function(context) {
586
680
  context.addClass(this.get('classNames'));
587
681
 
588
- var cursor = this.get('cursor');
589
- if (cursor) { context.addClass(cursor.get('className')); }
590
-
591
682
  if (this.get('isTextSelectable')) { context.addClass('allow-select'); }
592
683
  if (!this.get('isVisible')) { context.addClass('hidden'); }
593
684
  if (this.get('isFirstResponder')) { context.addClass('focus'); }
@@ -844,6 +935,90 @@ SC.CoreView.reopen(
844
935
  }
845
936
  },
846
937
 
938
+ /**
939
+ Frame describes the current bounding rect for your view. This is always
940
+ measured from the top-left corner of the parent view.
941
+
942
+ @property {Rect}
943
+ @test in layoutStyle
944
+ */
945
+ frame: function() {
946
+ return this.computeFrameWithParentFrame(null) ;
947
+ }.property('useStaticLayout').cacheable(), // We depend on the layout, but layoutDidChange will call viewDidResize to check the frame for us
948
+
949
+ /**
950
+ Computes the frame of the view by examining the view's DOM representation.
951
+ If no representation exists, returns null.
952
+
953
+ If a parent view is passed, its bounds will be taken into account when
954
+ calculating the frame.
955
+
956
+ @param {Rect} pdim the parent view's dimensions
957
+ @returns {Rect} the computed frame
958
+ */
959
+ computeFrameWithParentFrame: function(pdim) {
960
+ var layer;
961
+ var pv = this.get('parentView');
962
+
963
+ // need layer to be able to compute rect
964
+ if (layer = this.get('layer')) {
965
+ f = SC.viewportOffset(layer); // x,y
966
+ if (pv) { f = pv.convertFrameFromView(f, null); }
967
+
968
+ /*
969
+ TODO Can probably have some better width/height values - CC
970
+ FIXME This will probably not work right with borders - PW
971
+ */
972
+ f.width = layer.offsetWidth;
973
+ f.height = layer.offsetHeight;
974
+ return f;
975
+ }
976
+ return null; // can't compute
977
+ },
978
+
979
+ /**
980
+ The clipping frame returns the visible portion of the view, taking into
981
+ account the clippingFrame of the parent view. Keep in mind that
982
+ the clippingFrame is in the context of the view itself, not it's parent
983
+ view.
984
+
985
+ Normally this will be calculated based on the intersection of your own
986
+ clippingFrame and your parentView's clippingFrame.
987
+
988
+ @property {Rect}
989
+ */
990
+ clippingFrame: function() {
991
+ var f = this.get('frame'),
992
+ ret = f,
993
+ pv, cf;
994
+
995
+ if (!f) return null;
996
+ pv = this.get('parentView');
997
+ if (pv) {
998
+ cf = pv.get('clippingFrame');
999
+ if (!cf) return f;
1000
+ ret = SC.intersectRects(cf, f);
1001
+ }
1002
+ ret.x -= f.x;
1003
+ ret.y -= f.y;
1004
+
1005
+ return ret;
1006
+ }.property('parentView', 'frame').cacheable(),
1007
+
1008
+ /** @private
1009
+ This method is invoked whenever the clippingFrame changes, notifying
1010
+ each child view that its clippingFrame has also changed.
1011
+ */
1012
+ _sc_view_clippingFrameDidChange: function() {
1013
+ var cvs = this.get('childViews'), len = cvs.length, idx, cv ;
1014
+ for (idx=0; idx<len; ++idx) {
1015
+ cv = cvs[idx] ;
1016
+
1017
+ cv.notifyPropertyChange('clippingFrame') ;
1018
+ cv._sc_view_clippingFrameDidChange();
1019
+ }
1020
+ },
1021
+
847
1022
  /**
848
1023
  Removes the child view from the parent view.
849
1024
 
@@ -967,7 +1142,7 @@ SC.CoreView.reopen(
967
1142
  }
968
1143
 
969
1144
  if (!view) {
970
- console.error ("No view with name "+key+" has been found in "+this.toString());
1145
+ SC.Logger.error ("No view with name "+key+" has been found in "+this.toString());
971
1146
  // skip this one.
972
1147
  continue;
973
1148
  }