sproutcore 1.10.0 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +8 -8
  2. data/VERSION.yml +1 -1
  3. data/bin/sc-phantom +13 -0
  4. data/lib/Buildfile +3 -0
  5. data/lib/buildtasks/manifest.rake +3 -0
  6. data/lib/frameworks/sproutcore/CHANGELOG.md +24 -1
  7. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +1 -0
  8. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +1 -1
  9. data/lib/frameworks/sproutcore/frameworks/designer/views/designer_drop_target.js +1 -2
  10. data/lib/frameworks/sproutcore/frameworks/designer/views/high_light.js +1 -2
  11. data/lib/frameworks/sproutcore/frameworks/designer/views/page_item_view.js +1 -2
  12. data/lib/frameworks/sproutcore/frameworks/designer/views/selection_handles.js +1 -2
  13. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +4 -3
  14. data/lib/frameworks/sproutcore/frameworks/desktop/resources/progress.css +4 -0
  15. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +44 -35
  16. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +167 -91
  17. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/touch.js +215 -0
  18. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/grid/drag_and_drop.js +7 -2
  19. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/drag_and_drop.js +7 -1
  20. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +26 -24
  21. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +9 -18
  22. data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +25 -20
  23. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +29 -29
  24. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +107 -106
  25. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +120 -134
  26. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +14 -7
  27. data/lib/frameworks/sproutcore/frameworks/desktop/views/stacked.js +2 -1
  28. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +4 -4
  29. data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +197 -196
  30. data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +7 -0
  31. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +22 -10
  32. data/lib/frameworks/sproutcore/frameworks/routing/tests/system/routes.js +43 -0
  33. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
  34. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +2 -3
  35. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +14 -14
  36. data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +90 -79
  37. data/lib/frameworks/sproutcore/frameworks/statechart/tests/event_handling/advanced/event_queuing.js +104 -0
  38. data/lib/frameworks/sproutcore/frameworks/table/views/table.js +3 -0
  39. data/lib/frameworks/sproutcore/frameworks/template_view/handlebars.js +2 -1
  40. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/grid.css +17 -0
  41. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +1 -0
  42. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.png +0 -0
  43. data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu@2x.png +0 -0
  44. data/lib/frameworks/sproutcore/themes/ace/resources/panel/panel.css +2 -2
  45. data/lib/frameworks/sproutcore/themes/empty_theme/theme.js +1 -1
  46. data/lib/sproutcore/tools.rb +2 -1
  47. data/lib/sproutcore/tools/phantom.rb +36 -0
  48. data/sproutcore.gemspec +1 -1
  49. data/vendor/chance/lib/chance/instance.rb +5 -2
  50. metadata +11 -4
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmFiZjRlOTRmZjI1ZWY4NGI4ZGVjYjNmZjgyY2MzNzY2ODlmMWFhMg==
4
+ YzI3MjhhNWFhOGZkMDQ0NmY2OWRkMjIwZTYwNGZjYjUyODA2MjhhOA==
5
5
  data.tar.gz: !binary |-
6
- MTk5ODA0ZmRiZmRmZjkwYzViZGY3OGIyNjgwMTIxMzYwMWE4NDEyZg==
6
+ ZjQ2ZjFiMWMxZTM5YWJiNDBlMTcxNzQ3NzNjYTljNmZlYWVkNTM4Yg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OGY5N2UwMWM5YmQ5ZTExOTJiYjViYjY3YWRkMWE3ZmU3ZGJhNzBhNGY2N2Vl
10
- OTlhOWVkMGFhMzBhNjFiY2EyZTExMGQ5MzdlMzIxYjBhZWZiNTI3MDY1YjAy
11
- ZmNlYzI0YzhjOTFjNWNkNmI1YWZmY2U2MDY5Y2MyMjMwMWJlMzI=
9
+ MjI5MGY5MWJmYWI5Njg1MDM2ZThjMDEwMjM1NTlmMzc3MTI4YjlkYWE3NzI5
10
+ YzFhNzc1NGQyZWYxYzcxNzZkZjExZDMxNDk4ZWYyMWU5OTQ0ZjA4NjYzNGE2
11
+ OTU5NDg3Yzc2ODhiY2FhOGM4ODYzYzU5NjQxYmM1MGFmOGNkNDE=
12
12
  data.tar.gz: !binary |-
13
- OTM5NjA3NThiYTcwNjUyODA4Yjc4YThiNmM0ZjEwYmI2NDk0ZDVlZDI4MmEy
14
- YTkzMGM3NWRlNWIzNWFhOTMwM2MyMmM2NzYxZDNkZWZlZTlkYWIxZGU3Zjk1
15
- NWRhNGZjMTdmMDcwMWM1ZmEzMThjNDEwYmYzMGZkMTNjMWEwMjU=
13
+ OWQ4NDNjMGE0MzY5MGIxOTY5NWNiMTczNWMzMTQ5Yzk2ZTY1NTM2MTMyNDFl
14
+ MjcxNzg0ZGE4N2QzMWZlMTg5ODc2YTZlYmNiOGE4M2YxNDNiYmE4MjM3NTFh
15
+ MTk1ZDAyYTQ1ZTlkYTM1ZTc1MDkxODAxZDUzYWZlYjNiMWNjMWE=
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 10
4
- :patch: 0
4
+ :patch: 1
data/bin/sc-phantom ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # ===========================================================================
3
+ # Project: Abbot - SproutCore Build Tools
4
+ # Copyright: ©2010 Apple Inc.
5
+ # portions copyright @2006-2013 Strobe Inc.
6
+ # and contributors
7
+ # ===========================================================================
8
+
9
+ require "sproutcore"
10
+
11
+ SC::Tools.invoke 'phantom'
12
+
13
+ # EOF
data/lib/Buildfile CHANGED
@@ -58,6 +58,9 @@ mode :all do
58
58
  :combine_javascript => true,
59
59
  :combine_stylesheets => true,
60
60
 
61
+ # Use @charset "UTF-8" by default
62
+ :css_charset => "UTF-8",
63
+
61
64
  # We do NOT want to pad sprites for debugging in production. This both increases filesize
62
65
  # and makes the background of the sprite an embarrassing pink.
63
66
  :pad_sprites_for_debugging => false,
@@ -467,6 +467,9 @@ namespace :manifest do
467
467
  # whether it should minify
468
468
  :minify => minify,
469
469
 
470
+ # charset for CSS files
471
+ :css_charset => CONFIG[:css_charset],
472
+
470
473
  # whether it should optimize sprites. This is opt-in, and comes from the buildfile.
471
474
  :optimize_sprites => CONFIG[:optimize_sprites],
472
475
 
@@ -1,7 +1,30 @@
1
1
  CHANGE LOG
2
2
  ==========
3
3
 
4
- 1.10.0.0
4
+ 1.10.1
5
+ -----------
6
+
7
+ ### BUG FIXES
8
+
9
+ * Clean ups for http://docs.sproutcore.com.
10
+ * Fixes memory leak in SC.ContentValueSupport.
11
+ * Fixes layout bug with inline label view editor when used with child view layout plugins.
12
+ * Fixes SC.Module loading on IE11+.
13
+ * Fixes SC.Drag to fire `dragEnded` when cancelling a drag and drop operation
14
+ using the escape key.
15
+ * Fixes missing non-retina image for SC.MenuPane.
16
+ * CollectionView: fix the selection on touchEnd. Previously when an item was touched two times, after the second touch it was no longer marked as selected even if it was (correctly) part of the collection's selection, its isSelected property was NO when it was supposed to be YES.
17
+ * Fixes the code to show an insertion point for SC.GridView using @nicolasbadia's code. Adds a default style for SC.GridView's default insertion point that matches SC.ListView's default. Also improves the positioning of SC.ListView's insertion point so that the insertion view can specify a different height/right/width layout if wanted.
18
+ * Fixes misplaced scroll view content when changing the content using touch scrolling. Reapplies the CSS transforms when touch scroll view's content frame changes. Because the CSS transforms are applied directly to the content view, if the content view's layout style changes, the transforms will be erased.
19
+ * Fixes warnings when smoothly decelerating scrolling (includes performance improvement). Removes the necessity to trigger run loops while the scroll decelerates and only triggers the run loop when actually doing an update. This also removes an invoke warning if the first time the deceleration code runs (not within run loop) and doesn't have any velocity and so updates immediately.
20
+ * Changes the theme class for SC.EmptyTheme from 'sc-empty' to 'sc-empty-theme'. This fixes the conflict with 'sc-empty' used by SC.ProgressViews that causes all progress views in apps using the empty theme to not have an inner border. This is a potentially conflicting change, but less dangerous than changing the class used by SC.ProgressView, because SC.EmptyTheme doesn't have any styles.
21
+ * Fix issue with sending statechart events while state transitioning. `sendEvent` had a typo which allowed events to be sent while in the middle of a state transition. Fixing that revealed that now events sent during state transitions would be queued but never sent (at least not until another event was sent).
22
+ * Resolved Handlebars escaping issue with ampersands.
23
+ * Fix caching issue with SC.routes.informLocation. Since location and informLocation really just represent a single property, they both need to update the cached value for the opposite property.
24
+ * Fixes regression with OS sniffing of Linux and Android in SC.browser.
25
+
26
+
27
+ 1.10.0
5
28
  -----------
6
29
 
7
30
  ### CHANGES & FEATURES
@@ -268,6 +268,7 @@ SC.detectBrowser = function (userAgent, language) {
268
268
  if (isIOSDevice) { os = SC.OS.ios; }
269
269
  else if (osAndVersion[1] === 'mac os x' || osAndVersion[1] === 'mac os') { os = SC.OS.mac; }
270
270
  else if (osAndVersion[1] === 'windows nt') { os = SC.OS.win; }
271
+ else { os = osAndVersion[1]; }
271
272
 
272
273
  // Normalize the os version.
273
274
  osAndVersion[2] = osAndVersion[2] ? osAndVersion[2].replace(/_/g, '.') : '0';
@@ -1638,7 +1638,7 @@ SC.RootResponder = SC.Object.extend(
1638
1638
  // If user presses the escape key while we are in the middle of a
1639
1639
  // drag operation, cancel the drag operation and handle the event.
1640
1640
  if (keyCode === 27 && this._drag) {
1641
- this._drag.cancelDrag();
1641
+ this._drag.cancelDrag(evt);
1642
1642
  this._drag = null;
1643
1643
  this._mouseDownView = null;
1644
1644
  return YES;
@@ -10,8 +10,7 @@
10
10
 
11
11
  @extends SC.ContainerView
12
12
  */
13
- SC.DesignerDropTarget = SC.ContainerView.extend(
14
- /** @scope SC.DesignerDropTarget.prototype */ {
13
+ SC.DesignerDropTarget = SC.ContainerView.extend({
15
14
 
16
15
  inGlobalOffset: YES,
17
16
 
@@ -6,8 +6,7 @@
6
6
  This View is used by Greenhouse when application is in design mode
7
7
  It darkens the area around the `rootDesigner`
8
8
  */
9
- SC.RootDesignerHighLightView = SC.View.extend(
10
- /** @scope SC.RootDesignerHighLight.prototype */ {
9
+ SC.RootDesignerHighLightView = SC.View.extend({
11
10
 
12
11
  /**
13
12
  The designer that owns this highlight
@@ -12,8 +12,7 @@
12
12
 
13
13
  */
14
14
 
15
- SC.pageItemView = SC.ListItemView.extend(
16
- /** @scope SC.ListItemView.prototype */ {
15
+ SC.pageItemView = SC.ListItemView.extend({
17
16
  isDropTarget: YES,
18
17
 
19
18
  dragEntered: function(drag, evt) {
@@ -9,8 +9,7 @@
9
9
  This view draws selection handles for a given designer. It will also
10
10
  forward any mouse events to the underlying designer.
11
11
  */
12
- SC.SelectionHandlesView = SC.View.extend(
13
- /** @scope SC.SelectionHandlesView.prototype */ {
12
+ SC.SelectionHandlesView = SC.View.extend({
14
13
 
15
14
  /**
16
15
  The designer that owns this selection. mouse and keyboard events are
@@ -539,7 +539,6 @@ SC.MenuPane = SC.PickerPane.extend(
539
539
  var scroll, menuView, menuItemViews;
540
540
 
541
541
  scroll = this._menuScrollView = this.createChildView(SC.MenuScrollView, {
542
- borderStyle: SC.BORDER_NONE,
543
542
  controlSize: this.get('controlSize')
544
543
  });
545
544
 
@@ -554,10 +553,12 @@ SC.MenuPane = SC.PickerPane.extend(
554
553
  });
555
554
 
556
555
  menuItemViews = this.get('menuItemViews');
557
- menuView.set('layout', { top: 0, left: 0, height : this.get('menuHeight')});
558
556
  menuView.replaceAllChildren(menuItemViews);
559
- scroll.set('contentView', menuView);
560
557
 
558
+ // Adjust our menu view's layout to fit the calculated menu height.
559
+ menuView.set('layout', { top: 0, left: 0, height : this.get('menuHeight')});
560
+
561
+ scroll.set('contentView', menuView);
561
562
 
562
563
  this.childViews = [scroll];
563
564
 
@@ -5,10 +5,12 @@
5
5
  background-color: #c8c8c8;
6
6
  -webkit-border-radius: 2px;
7
7
  border-radius: 2px;
8
+
8
9
  &.disabled {
9
10
  background-color: #e8e8e8;
10
11
  border: 1px #9a9a9a solid;
11
12
  }
13
+
12
14
  .sc-inner {
13
15
  position: absolute;
14
16
  left: 0px;
@@ -19,10 +21,12 @@
19
21
  -webkit-transition: all 0.01s linear;
20
22
  -webkit-transform: translate3d(0,0,0);
21
23
  }
24
+
22
25
  &.sc-indeterminate .sc-inner {
23
26
  background: #555555;
24
27
  border: 0;
25
28
  }
29
+
26
30
  &.sc-empty .sc-inner {
27
31
  border: none;
28
32
  }
@@ -406,32 +406,60 @@ SC.Drag = SC.Object.extend(
406
406
  /** @private
407
407
  Cancel the drag operation.
408
408
 
409
- This notifies the data source that the drag ended and removes the
410
- ghost view, but does not notify the drop target of a drop.
411
-
412
409
  This is called by RootResponder's keyup method when the user presses
413
410
  escape and a drag is in progress.
411
+
412
+ @param {Event} evt the key event
413
+ @see SC.Drag.endDrag
414
414
  */
415
- cancelDrag: function () {
415
+ cancelDrag: function (evt) {
416
416
  var target = this._lastTarget,
417
417
  loc = this.get('location');
418
418
 
419
419
  if (target && target.dragExited) target.dragExited(this, this._lastMouseDraggedEvent);
420
420
 
421
+ this.endDrag(evt, SC.DRAG_NONE);
422
+ },
423
+
424
+ /** @private
425
+ End the drag operation.
426
+
427
+ This notifies the data source that the drag ended and removes the
428
+ ghost view, but does not notify the drop target of a drop.
429
+
430
+ @param {Event} evt
431
+ @param {DragOp} op The drag operation that was performed. One of
432
+ SC.DRAG_COPY, SC.DRAG_MOVE, SC.DRAG_LINK, or SC.DRAG_NONE.
433
+ */
434
+ endDrag: function (evt, op) {
435
+ var loc = this.get('location');
436
+
437
+ // notify all drop targets that the drag ended
438
+ var ary = this._dropTargets();
439
+ for (var idx = 0, len = ary.length; idx < len; idx++) {
440
+ try {
441
+ ary[idx].tryToPerform('dragEnded', this, evt);
442
+ } catch (ex2) {
443
+ SC.Logger.error('Exception in SC.Drag.mouseUp(dragEnded on %@): %@'.fmt(ary[idx], ex2));
444
+ }
445
+ }
446
+
421
447
  if (this.get('sourceIsDraggable')) {
448
+ // destroy the ghost view
422
449
  this._destroyGhostView();
423
450
 
424
451
  if (this.get('ghost')) {
452
+ // Show the dragView if it was hidden.
425
453
  if (this._dragViewWasVisible) this._getDragView().set('isVisible', YES);
426
454
  this._dragViewWasVisible = null;
427
455
  }
428
456
  }
429
457
 
458
+ // notify the source that everything has completed
430
459
  var source = this.source;
431
- if (source && source.dragDidEnd) source.dragDidEnd(this, loc, SC.DRAG_NONE);
432
-
433
- this._lastTarget = null;
434
- this._dragInProgress = NO;
460
+ if (source && source.dragDidEnd) source.dragDidEnd(this, loc, op);
461
+
462
+ this._cleanUpDrag();
435
463
  },
436
464
 
437
465
  // ..........................................
@@ -536,33 +564,7 @@ SC.Drag = SC.Object.extend(
536
564
  SC.Logger.error('Exception in SC.Drag.mouseUp(acceptDragOperation|performDragOperation): %@'.fmt(e));
537
565
  }
538
566
 
539
- // notify all drop targets that the drag ended
540
- var ary = this._dropTargets();
541
- for (var idx = 0, len = ary.length; idx < len; idx++) {
542
- try {
543
- ary[idx].tryToPerform('dragEnded', this, evt);
544
- } catch (ex2) {
545
- SC.Logger.error('Exception in SC.Drag.mouseUp(dragEnded on %@): %@'.fmt(ary[idx], ex2));
546
- }
547
- }
548
-
549
- if (this.get('sourceIsDraggable')) {
550
- // destroy the ghost view
551
- this._destroyGhostView();
552
-
553
- if (this.get('ghost')) {
554
- // Show the dragView if it was hidden.
555
- if (this._dragViewWasVisible) this._getDragView().set('isVisible', YES);
556
- this._dragViewWasVisible = null;
557
- }
558
- }
559
-
560
- // notify the source that everything has completed
561
- var source = this.source;
562
- if (source && source.dragDidEnd) source.dragDidEnd(this, loc, op);
563
-
564
- this._lastTarget = null;
565
- this._dragInProgress = NO; // required by autoscroll (invoked by a timer)
567
+ this.endDrag(evt, op);
566
568
  },
567
569
 
568
570
  /** @private */
@@ -674,6 +676,13 @@ SC.Drag = SC.Object.extend(
674
676
  }
675
677
  },
676
678
 
679
+ /** @private */
680
+ _cleanUpDrag: function() {
681
+ this._lastTarget = null;
682
+ this._dragInProgress = NO;
683
+ this._cachedDropTargets = null;
684
+ },
685
+
677
686
  /** @private
678
687
  Return an array of drop targets, sorted with any nested drop targets
679
688
  at the top of the array. The first time this method is called during
@@ -5,7 +5,7 @@
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
7
 
8
- /*global module test htmlbody ok equals same stop start */
8
+ /*global module, test, ok, equals, stop, start */
9
9
 
10
10
  var items = [
11
11
  { title: 'Menu Item', keyEquivalent: 'ctrl_shift_n' },
@@ -30,30 +30,34 @@ var menu;
30
30
 
31
31
  module('SC.MenuPane UI', {
32
32
  setup: function () {
33
- menu = SC.MenuPane.create({
34
- layout: { width: 206 },
33
+ SC.run(function () {
34
+ menu = SC.MenuPane.create({
35
+ layout: { width: 206 },
35
36
 
36
- selectedItemChanged: function () {
37
- this._selectedItemCount = (this._selectedItemCount||0)+1;
38
- }.observes('selectedItem'),
37
+ selectedItemChanged: function () {
38
+ this._selectedItemCount = (this._selectedItemCount || 0) + 1;
39
+ }.observes('selectedItem'),
39
40
 
40
- countAction: function () {
41
- this._actionCount = (this._actionCount||0)+1;
42
- }
43
- });
41
+ countAction: function () {
42
+ this._actionCount = (this._actionCount || 0) + 1;
43
+ }
44
+ });
44
45
 
45
- items[0].target = menu;
46
- items[0].action = 'countAction';
46
+ items[0].target = menu;
47
+ items[0].action = 'countAction';
47
48
 
48
- items[1].action = function () {
49
- menu._functionActionCount = (menu._functionActionCount||0)+1;
50
- };
49
+ items[1].action = function () {
50
+ menu._functionActionCount = (menu._functionActionCount || 0) + 1;
51
+ };
51
52
 
52
- menu.set('items', items);
53
+ menu.set('items', items);
54
+ });
53
55
  },
54
56
 
55
57
  teardown: function () {
56
- menu.destroy();
58
+ SC.run(function () {
59
+ menu.destroy();
60
+ });
57
61
  menu = null;
58
62
  }
59
63
  });
@@ -78,7 +82,7 @@ function clickOn(view, shiftKey, ctrlKey) {
78
82
  ev = SC.Event.simulateEvent(layer, 'mouseup', opts);
79
83
  SC.Event.trigger(layer, 'mouseup', [ev]);
80
84
  SC.RunLoop.begin().end();
81
- layer = null ;
85
+ layer = null;
82
86
  }
83
87
 
84
88
  /**
@@ -92,14 +96,14 @@ function clickOn(view, shiftKey, ctrlKey) {
92
96
  */
93
97
  function keyPressOn(view, keyCode, isKeyPress, shiftKey, ctrlKey) {
94
98
  var layer = view.get('layer'),
95
- opts = {
96
- shiftKey: !!shiftKey,
97
- ctrlKey: !!ctrlKey,
98
- keyCode: keyCode,
99
- charCode: isKeyPress ? keyCode : 0,
100
- which: keyCode
101
- },
102
- ev;
99
+ opts = {
100
+ shiftKey: !!shiftKey,
101
+ ctrlKey: !!ctrlKey,
102
+ keyCode: keyCode,
103
+ charCode: isKeyPress ? keyCode : 0,
104
+ which: keyCode
105
+ },
106
+ ev;
103
107
 
104
108
  ok(layer, 'keyPressOn() precond - view %@ should have layer'.fmt(view.toString()));
105
109
 
@@ -114,11 +118,13 @@ function keyPressOn(view, keyCode, isKeyPress, shiftKey, ctrlKey) {
114
118
  ev = SC.Event.simulateEvent(layer, 'keyup', opts);
115
119
  SC.Event.trigger(layer, 'keyup', [ev]);
116
120
  SC.RunLoop.begin().end();
117
- layer = null ;
121
+ layer = null;
118
122
  }
119
123
 
120
124
  test('Basic UI', function () {
121
- menu.popup();
125
+ SC.run(function () {
126
+ menu.popup();
127
+ });
122
128
  ok(menu.$().hasClass('sc-menu'), 'pane should have "sc-menu" class');
123
129
  ok(menu.$().hasClass('sc-regular-size'), 'pane should have default control size class');
124
130
  ok(!menu.get('isSubMenu'), 'isSubMenu should be NO on menus that are not submenus');
@@ -133,7 +139,9 @@ test('Basic UI', function () {
133
139
  equals(selectedItem ? selectedItem.title : null, menuItem.get('content').title, 'selectedItem should be set to the content item that was clicked');
134
140
  equals(1, menu._selectedItemCount, 'selectedItem should only change once when a menu item is clicked');
135
141
  equals(1, menu._actionCount, 'action is fired once when menu item is clicked');
136
- menu.remove();
142
+ SC.run(function () {
143
+ menu.remove();
144
+ });
137
145
  ok(!menu.get('isVisibleInWindow'), 'menu should not be visible after being removed');
138
146
  equals(menu.get('currentMenuItem'), null, 'currentMenuItem should be null after being removed');
139
147
  start();
@@ -147,35 +155,48 @@ test('Control size', function () {
147
155
  { title: 'Ya better better baby' }
148
156
  ];
149
157
 
150
- smallPane = SC.MenuPane.create({
151
- controlSize: SC.SMALL_CONTROL_SIZE,
152
- items: items
158
+ SC.run(function () {
159
+ smallPane = SC.MenuPane.create({
160
+ controlSize: SC.SMALL_CONTROL_SIZE,
161
+ items: items
162
+ });
163
+
164
+ smallPane.popup();
153
165
  });
154
- smallPane.popup();
155
166
  views = smallPane.get('menuItemViews');
156
167
 
157
168
  var small_constants = SC.BaseTheme.menuRenderDelegate['sc-small-size'];
158
169
  equals(views[0].get('frame').height, small_constants.itemHeight, 'should change itemHeight');
159
170
  equals(views[1].get('frame').height, small_constants.itemSeparatorHeight, 'should change itemSeparatorHeight');
160
- equals(views[0].get('frame').y, small_constants.menuHeightPadding/2, 'should change menuHeightPadding');
161
- smallPane.remove();
171
+ equals(views[0].get('frame').y, small_constants.menuHeightPadding / 2, 'should change menuHeightPadding');
172
+ SC.run(function () {
173
+ smallPane.remove();
174
+ });
175
+
176
+ SC.run(function () {
177
+ largePane = SC.MenuPane.create({
178
+ controlSize: SC.LARGE_CONTROL_SIZE,
179
+ items: items
180
+ });
162
181
 
163
- largePane = SC.MenuPane.create({
164
- controlSize: SC.LARGE_CONTROL_SIZE,
165
- items: items
182
+ largePane.popup();
166
183
  });
167
- largePane.popup();
168
184
  views = largePane.get('menuItemViews');
169
185
 
170
186
  var large_constants = SC.BaseTheme.menuRenderDelegate['sc-large-size'];
171
187
  equals(views[0].get('frame').height, large_constants.itemHeight, 'should change itemHeight');
172
188
  equals(views[1].get('frame').height, large_constants.itemSeparatorHeight, 'should change itemSeparatorHeight');
173
- equals(views[0].get('frame').y, large_constants.menuHeightPadding/2, 'should change menuHeightPadding');
174
- largePane.remove();
189
+ equals(views[0].get('frame').y, large_constants.menuHeightPadding / 2, 'should change menuHeightPadding');
190
+
191
+ SC.run(function () {
192
+ largePane.remove();
193
+ });
175
194
  });
176
195
 
177
- test('Legacy Function Support', function (){
178
- menu.popup();
196
+ test('Legacy Function Support', function () {
197
+ SC.run(function () {
198
+ menu.popup();
199
+ });
179
200
  var menuItem = menu.get('menuItemViews')[1], selectedItem;
180
201
  menuItem.mouseEntered();
181
202
  clickOn(menuItem, NO, NO);
@@ -184,41 +205,63 @@ test('Legacy Function Support', function (){
184
205
  setTimeout(function () {
185
206
  selectedItem = menu.get('selectedItem');
186
207
  equals(1, menu._functionActionCount, 'Function should be called if it is set as the action and the menu item is clicked');
187
- menu.remove();
208
+
209
+ SC.run(function () {
210
+ menu.remove();
211
+ });
188
212
  start();
189
213
  }, 250);
190
214
  });
191
215
 
192
216
  test('Custom MenuItemView Class', function () {
193
217
  equals(menu.get('exampleView'), SC.MenuItemView, 'SC.MenuPane should generate SC.MenuItemViews by default');
194
- var menu2 = SC.MenuPane.create({
195
- exampleView: SC.MenuItemView.extend({
196
- classNames: 'custom-menu-item'.w()
197
- }),
218
+ var menu2;
198
219
 
199
- items: items
220
+ SC.run(function () {
221
+ menu2 = SC.MenuPane.create({
222
+ exampleView: SC.MenuItemView.extend({
223
+ classNames: 'custom-menu-item'.w()
224
+ }),
225
+
226
+ items: items
227
+ });
228
+
229
+ menu2.popup();
200
230
  });
201
- menu2.popup();
202
231
  ok(menu2.$('.custom-menu-item').length > 0, 'SC.MenuPane should generate instances of custom classes if exampleView is changed');
203
- menu2.remove();
232
+ SC.run(function () {
233
+ menu2.remove();
234
+ });
204
235
  });
205
236
 
206
237
 
207
238
  test('Custom MenuItemView Class on an item using itemExampleViewKey', function () {
208
239
  equals(menu.get('exampleView'), SC.MenuItemView, 'SC.MenuPane should generate SC.MenuItemViews by default');
209
- menu.popup();
240
+ SC.run(function () {
241
+ menu.popup();
242
+ });
210
243
  ok(menu.$('.custom-menu-item').length === 1, 'SC.MenuPane should generate one instance of a custom class if the item has an exampleView property');
211
- ok($($('.sc-menu-item')[11]).hasClass('custom-menu-item'), 'The last menu item should have a custom class');
212
- menu.remove();
244
+ ok(SC.$(SC.$('.sc-menu-item')[11]).hasClass('custom-menu-item'), 'The last menu item should have a custom class');
245
+
246
+ SC.run(function () {
247
+ menu.remove();
248
+ });
213
249
  });
214
250
 
215
251
  test('Basic Submenus', function () {
216
- var smallMenu = SC.MenuPane.create({
217
- controlSize: SC.SMALL_CONTROL_SIZE,
218
- items: items
252
+ var smallMenu,
253
+ menuItem, subMenu;
254
+
255
+ SC.run(function () {
256
+ smallMenu = SC.MenuPane.create({
257
+ controlSize: SC.SMALL_CONTROL_SIZE,
258
+ items: items
259
+ });
260
+ menuItem = smallMenu.get('menuItemViews')[8];
261
+
262
+ smallMenu.popup();
219
263
  });
220
- var menuItem = smallMenu.get('menuItemViews')[8], subMenu;
221
- smallMenu.popup();
264
+
222
265
  menuItem.mouseEntered();
223
266
  SC.RunLoop.begin().end();
224
267
  ok(menuItem.get('hasSubMenu'), 'precond - menu item has a submenu');
@@ -229,7 +272,9 @@ test('Basic Submenus', function () {
229
272
  ok(subMenu.get('isVisibleInWindow'), 'submenu should open after 100ms delay');
230
273
  ok(subMenu.get('isSubMenu'), 'isSubMenu should be YES on submenus');
231
274
  ok(subMenu.get('controlSize'), SC.SMALL_CONTROL_SIZE, "submenu should inherit parent's controlSize");
232
- smallMenu.remove();
275
+ SC.run(function () {
276
+ smallMenu.remove();
277
+ });
233
278
  ok(!subMenu.get('isVisibleInWindow'), 'submenus should close if their parent menu is closed');
234
279
  start();
235
280
  }, 150);
@@ -239,34 +284,52 @@ test('Menu Item Localization', function () {
239
284
  ok(menu.get('localize'), 'menu panes should be localized by default');
240
285
  var locMenu, items;
241
286
 
242
- SC.stringsFor('en', { 'Localized.Text': 'LOCALIZED TEXT' } );
287
+ SC.stringsFor('en', { 'Localized.Text': 'LOCALIZED TEXT' });
243
288
  items = [ 'Localized.Text' ];
244
289
 
245
- locMenu = SC.MenuPane.create({
246
- layout: { width: 200 },
247
- items: items,
248
- localize: NO
290
+ SC.run(function () {
291
+ locMenu = SC.MenuPane.create({
292
+ layout: { width: 200 },
293
+ items: items,
294
+ localize: NO
295
+ });
296
+
297
+ locMenu.popup();
249
298
  });
250
- locMenu.popup();
251
299
  equals('Localized.Text', locMenu.$('.sc-menu-item .value').text(), 'Menu item titles should not be localized if localize is NO');
252
- locMenu.remove();
253
300
 
254
- locMenu = SC.MenuPane.create({
255
- items: items,
256
- localize: YES
301
+ SC.run(function () {
302
+ locMenu.remove();
303
+ });
304
+
305
+ SC.run(function () {
306
+ locMenu = SC.MenuPane.create({
307
+ items: items,
308
+ localize: YES
309
+ });
310
+
311
+ locMenu.popup();
257
312
  });
258
- locMenu.popup();
259
313
  equals('LOCALIZED TEXT', locMenu.$('.sc-menu-item .value').text(), 'Menu item titles should be localized if localize is YES');
260
- locMenu.remove();
314
+ SC.run(function () {
315
+ locMenu.remove();
316
+ });
261
317
  });
262
318
 
263
319
  test('Automatic Closing', function () {
264
- menu.popup();
320
+
321
+ SC.run(function () {
322
+ menu.popup();
323
+ });
265
324
  ok(menu.get('isVisibleInWindow'), 'precond - window should be visible');
266
- menu.windowSizeDidChange();
325
+ SC.run(function () {
326
+ menu.windowSizeDidChange();
327
+ });
267
328
  ok(!menu.get('isVisibleInWindow'), 'menu should close if window resizes');
268
329
 
269
- menu.popup();
330
+ SC.run(function () {
331
+ menu.popup();
332
+ });
270
333
  clickOn(menu);
271
334
  ok(!menu.get('isVisibleInWindow'), 'menu should close if anywhere other than a menu item is clicked');
272
335
  });
@@ -278,10 +341,10 @@ test('keyEquivalents', function () {
278
341
  // keyEquivalents work
279
342
  menu.items.forEach(function (item) {
280
343
  var keyEq = item.keyEquivalent, idx, len;
281
- if(!keyEq) return;
344
+ if (!keyEq) return;
282
345
 
283
- if(SC.typeOf(keyEq)===SC.T_ARRAY) {
284
- for(idx=0,len=keyEq.length;idx<len;idx++) {
346
+ if (SC.typeOf(keyEq) === SC.T_ARRAY) {
347
+ for (idx = 0, len = keyEq.length; idx < len; idx++) {
285
348
  ok(keyEquivalents[keyEq[idx]], "keyEquivalent should map to " + keyEq[idx]);
286
349
  }
287
350
  }
@@ -294,7 +357,9 @@ test('keyEquivalents', function () {
294
357
  test('scrolling', function () {
295
358
  var currentMenuItem;
296
359
 
297
- menu.popup();
360
+ SC.run(function () {
361
+ menu.popup();
362
+ });
298
363
  menu.set('currentMenuItem', menu.get('menuItemViews')[0]);
299
364
  currentMenuItem = menu.get('currentMenuItem');
300
365
  equals(currentMenuItem.get('title'), 'Menu Item', 'menu should begin at first item');
@@ -325,12 +390,17 @@ test('scrolling', function () {
325
390
  });
326
391
 
327
392
  test('aria-role attribute', function () {
328
- var menuPane = SC.MenuPane.create({
329
- layout: { width: 200 },
330
- items: items,
331
- itemCheckboxKey: 'isChecked'
332
- }), menuItems,normalItem, itemWithCheckBox, separatorItem;
333
- menuPane.popup();
393
+ var menuPane, menuItems, normalItem, itemWithCheckBox, separatorItem;
394
+
395
+ SC.run(function () {
396
+ menuPane = SC.MenuPane.create({
397
+ layout: { width: 200 },
398
+ items: items,
399
+ itemCheckboxKey: 'isChecked'
400
+ });
401
+
402
+ menuPane.popup();
403
+ });
334
404
 
335
405
  equals(menuPane.$().attr('role'), 'menu', "menu pane should have role set");
336
406
 
@@ -346,12 +416,18 @@ test('aria-role attribute', function () {
346
416
  });
347
417
 
348
418
  test('aria-checked attribute', function () {
349
- var menuPane = SC.MenuPane.create({
350
- layout: { width: 200 },
351
- items: items,
352
- itemCheckboxKey: 'isChecked'
353
- }),itemWithCheckBox;
354
- menuPane.popup();
419
+ var menuPane,
420
+ itemWithCheckBox;
421
+
422
+ SC.run(function () {
423
+ menuPane = SC.MenuPane.create({
424
+ layout: { width: 200 },
425
+ items: items,
426
+ itemCheckboxKey: 'isChecked'
427
+ });
428
+
429
+ menuPane.popup();
430
+ });
355
431
 
356
432
  itemWithCheckBox = menuPane.get('menuItemViews')[1];
357
433