sproutcore 1.10.2 → 1.10.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG +11 -0
  3. data/VERSION.yml +1 -1
  4. data/lib/frameworks/sproutcore/CHANGELOG.md +34 -0
  5. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +3 -1
  6. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +3 -1
  7. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +79 -80
  8. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +115 -22
  9. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +54 -17
  10. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +76 -34
  11. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +18 -5
  12. data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +14 -5
  13. data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +42 -18
  14. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +41 -41
  15. data/lib/frameworks/sproutcore/frameworks/foundation/tests/transitions/view_transitions_test.js +235 -0
  16. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/bounce_transition.js +8 -4
  17. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/fade_transition.js +6 -2
  18. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/pop_transition.js +8 -4
  19. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/scale_transition.js +6 -2
  20. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/slide_transition.js +6 -2
  21. data/lib/frameworks/sproutcore/frameworks/foundation/transitions/spring_transition.js +8 -4
  22. data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +5 -4
  23. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
  24. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +2 -2
  25. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +124 -80
  26. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +134 -0
  27. data/lib/sproutcore.rb +1 -1
  28. data/lib/sproutcore/models/manifest.rb +12 -6
  29. data/lib/sproutcore/rack/builder.rb +20 -12
  30. data/lib/sproutcore/tools.rb +3 -3
  31. data/lib/sproutcore/tools/build.rb +22 -22
  32. data/sproutcore.gemspec +2 -5
  33. data/vendor/sproutcore/lib/yuicompressor-2.4.8.jar +0 -0
  34. metadata +10 -23
  35. data/vendor/sproutcore/lib/yuicompressor-2.4.6.jar +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmM2OWQzMTljMWNmN2U5OTczMWNkYjBlNTdkNGY1NjdiMjYyMjM0Mw==
4
+ N2VkZDQ3ZWNjMGJhZjA3ZmQ1MTFjMmM1ZjAzM2JjYThiZTQyODY1OA==
5
5
  data.tar.gz: !binary |-
6
- N2NkMmVhOGVlOTg1MjFjNDM0MTUwNzcyOTY3Mzg2MTY5ZmVkOTQyMA==
6
+ YmI0NTE1M2U0NTRlM2I5ZDE2YWJiNGJhODMyYzg1NzFlYWJkYjA0Zg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NjBjNDc3NTczZjlkNmZmZTE2ZDI0OTM0YWY2MTkzZTUyNzM1YWU4MDBlMjg5
10
- ZmUzNzM5ZmZmOGMwMTkxZGU1NjU1MWUzZTVkNzM0M2JiZmRlNTczYzNlYWM1
11
- MjZmZjE1YTY4NzU2ODhhMjg2ODA2N2ZkZTBkMjE5ZjkwODM0MjQ=
9
+ ODJhNTc0NWNkOTM2NmYwNDVjMWQ1YTZmNjljMjFiNzdjZGVhNGQyMzg0OWM1
10
+ MWRkMDBkZTRiZjg4MDViNjkyODE1NjE3MjgzYTc4MDM1ODU3NDhiMjdjMDRk
11
+ NTM0ZDNiODE5MjFkYzc0MzI1YzJjY2JhNGFmMGIyODcyMmYzZWM=
12
12
  data.tar.gz: !binary |-
13
- NzMxNDA0ZWI5OGM4YmMxZGRmZjU2ZGI4NDg0NTg1MWZmOTdiMmQyYTFhMjVh
14
- YWIxNzg5NmRhNjMwODI1NGNkM2IxYmUzOGI2Y2NlM2M2Yzc2ODY1MWFkMWE3
15
- YzRkZjBmNTA4N2QyM2EyMTM1MGVkN2JmYThkMGQ0ZDMxZTM0ZTA=
13
+ YmZlNWFlYzIyNWM2NjE3ODVjMDRiOTg3MmY0YWRiYWIwMWYyNWY2OTA5MmEw
14
+ MzQwMWQyOGExMTUzMWVkMDY2OGQ3YTFjNTM5MGE0ODAzYzExZjNmOWNjZjEz
15
+ OWIyZTU5MDk0NzgzZGI0ZTI1M2EwODQ2MDg4NWMzNjBhODlhZjk=
data/CHANGELOG CHANGED
@@ -1,8 +1,19 @@
1
+ SproutCore 1.10.3
2
+ -----------------
3
+
4
+ * Makes logging each individual path a debug level mode and moves the build path message to info level.
5
+ * Adds a bit of default messaging to the build process.
6
+ * Bumps the listen gem minimum requirement as earlier versions seem to result in not being able to kill sc-server.
7
+ * Updates YUICompressor to version 2.4.8.
8
+ * Moves some unneeded code into the polling listener block and adds all matched .git directories as an ignored path. This prevents excessive CPU usage when dealing with submodules and frameworks checked out within a project.
9
+
10
+
1
11
  SproutCore 1.10.2
2
12
  -----------------
3
13
 
4
14
  * Uses a file system change listener rather than polling.
5
15
 
16
+
6
17
  SproutCore 1.10.0
7
18
  -----------------
8
19
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 10
4
- :patch: 2
4
+ :patch: 3.1
@@ -17,6 +17,35 @@ CHANGE LOG
17
17
 
18
18
  * Some fixes for deprecated template view framework.
19
19
 
20
+
21
+ 1.10.3
22
+ -----------
23
+
24
+ ### INTERNAL CHANGES
25
+
26
+ * Adds a new state to the view statechart, SC.CoreView.ATTACHED_SHOWN_ANIMATING. This state is for views that are manually animated via a call to `animate` when in the ATTACHED_SHOWN state and is used to cancel manual animations if a view is hidden or removed, which would cause the animation callbacks to fail to trigger. Also prevents animate from running on views that are not visible in the window.
27
+ * Removes double clone of observable members array. The `getMembers` function already does a slice of the array, so SC.clone (which just does another slice of the array) is unnecessary.
28
+ * Prevents bindings that are disconnected at the moment of updating from continuing, which would throw an exception because the binding would try to resolve both sides of the connection and become connected to the window (which doesn’t support the KVC methods the binding uses).
29
+
30
+ One scenario that this has been seen in is an observer that destroys an old binding and creates a new binding to a *store query based computed property*. As the binding is about to update, it first has to get the value of the query based computed property from the target, which results in the store flushing and indicating certain records did change which in turn triggers the original observer function where the binding is replaced. In the very next step, the old binding, which is now disconnected, tries to syncronize its value, which will fail.
31
+
32
+ ### BUG FIXES
33
+
34
+ * Fixes problems with SC.GridView when its width goes to 0 (which would calculate infinite items per row).
35
+ * Fixes a bug where separator items gained the value of the previous item such that the separator item would appear selected in the menu when the previous item was actually selected.
36
+ * Fixes regression that the icon of the selected item doesn’t update the view.
37
+ Adds ability to set the value of the view and have the view’s title and icon update.
38
+ * Fixes regression with transitionIn due to animate rejecting non-visible states.
39
+ * Fixes double invokeNext call when runAnimationCallback is wrapped in an invokeNext.
40
+ * Fixes direct duplicate call to commitEditing in SC.InlineTextField when using the tab or shift-tab keys, also cleans whitespace in SC.Editable.
41
+ * Fixes cancellation of view transitions. If the transition is cancelled, the plugin should not fire the callback. Cancels show/hide transitions when the state changes before they complete.
42
+ * Fixes bugs where logic bindings (and & or) defined on classes were being serviced by a shared underlying object, causing issues when two instances wanted different values or to be destroyed at different times.
43
+ * Stacked child layout views: don't add padding or margins if none of the children are visible.
44
+ * Fixes animations failing when browser tab not visible.
45
+ * Takes a new approach to transition and animation callbacks. Instead of waiting for the exact right event name to be determined, we listen to all the possible combinations for the browser and then remove the unnecessary listeners when the test completes. This allows code to run that uses transitions and animations in the application’s main function and doesn’t require blocking the launch of the application for the tests to complete.
46
+ * Fixes animations failing when tab loaded and not visible. Because animation callbacks are paused when some browsers’ tabs are not visible, we can’t apply animations based on the browser support for CSS transitions alone. We also need to set up our animation event listeners and so any animations that occur while the page is loading should simply apply directly.
47
+ * Fixes the case that a layout observer calls adjust due to an animate layout being set. The observer would fire before the _animateLayout internal property would be cleared, leading a later adjust method to fail.
48
+
20
49
  1.10.2
21
50
  -----------
22
51
 
@@ -26,6 +55,11 @@ CHANGE LOG
26
55
  * Added a debug-mode only developer error to prevent double calls to materializeRecord from within materializeRecord. The result is duplicated objects that appear to be the same record instance but are in fact not, which can be very time-consuming to debug. Hopefully this saves developers a lot of grief.
27
56
  * Added several *debug-mode only* `toString` methods for easy debugging.
28
57
  * Added a tiny bit of debug mode only developer support. If manually connecting/disconnecting bindings it's possible to accidentally try to bind to a missing object. The normal stack trace this would produce is hard to follow so we present a more traceable error message with the stack.
58
+ * Fixed issue with property chain notifications.
59
+
60
+ Property chains would by notified during teardownEnumerablePropertyChains, but this could result in computed properties trying to access the array before it was finished mutating. This was observed with SC.ChildArray's.
61
+
62
+ Instead, wait until setupEnumerablePropertyChains to notify, and always notify with the assumption that changes were made.
29
63
 
30
64
  ### BUG FIXES
31
65
 
@@ -272,7 +272,9 @@ SC.mixin(SC.View,
272
272
  }
273
273
 
274
274
  // Adjust our frame to fit as well, this ensures that scrolling works.
275
- position += Math.max(lastMargin, paddingAfter);
275
+ // If the current size is 0 (all children are hidden), it doesn't make sense to add the padding
276
+ if (position !== 0)
277
+ position += Math.max(lastMargin, paddingAfter);
276
278
  if (resizeToFit && view.getPath('layout.width') !== position) {
277
279
  view.adjust('width', position);
278
280
  }
@@ -273,7 +273,9 @@ SC.mixin(SC.View,
273
273
  }
274
274
 
275
275
  // Adjust our frame to fit as well, this ensures that scrolling works.
276
- position += Math.max(lastMargin, paddingAfter);
276
+ // If the current size is 0 (all children are hidden), it doesn't make sense to add the padding
277
+ if (position !== 0)
278
+ position += Math.max(lastMargin, paddingAfter);
277
279
  if (resizeToFit && view.getPath('layout.height') !== position) {
278
280
  view.adjust('height', position);
279
281
  }
@@ -446,8 +446,8 @@ SC.platform = SC.Object.create({
446
446
  we would get it wrong. Instead we perform actual tests to find out the proper
447
447
  names and only add the proper listeners.
448
448
 
449
- Once the tests are completed the RootResponder is notified in order to add
450
- transition and animation event listeners for the appropriate event names.
449
+ Once the tests are completed the RootResponder is notified in order to clean up
450
+ unnecessary transition and animation event listeners.
451
451
  */
452
452
  SC.ready(function () {
453
453
  // This will add 4 different variations of the named event listener and clean
@@ -508,14 +508,13 @@ SC.ready(function () {
508
508
  // If an end event never fired, we can't really support CSS transitions in SproutCore.
509
509
  if (success) {
510
510
  // Set up the SC transition event listener.
511
- SC.RootResponder.responder.setupTransitionListener();
511
+ SC.RootResponder.responder.cleanUpTransitionListeners();
512
512
  } else {
513
513
  SC.platform.supportsCSSTransitions = NO;
514
514
  }
515
515
 
516
516
  transitionEl.parentNode.removeChild(transitionEl);
517
517
  transitionEl = null;
518
-
519
518
  });
520
519
 
521
520
  // Append the test element.
@@ -525,86 +524,86 @@ SC.ready(function () {
525
524
  setTimeout(function () {
526
525
  transitionEl.style.opacity = '0';
527
526
  });
528
- }
529
-
530
- // Set up and execute the animation event test.
531
- if (SC.platform.supportsCSSAnimations) {
532
- var animationEl = document.createElement('div'),
533
- keyframes,
534
- prefixedKeyframes;
535
-
536
- // Generate both the regular and prefixed version of the style.
537
- keyframes = '@keyframes _sc_animation_test { from { opacity: 1; } to { opacity: 0; } }';
538
- prefixedKeyframes = '@' + SC.browser.cssPrefix + 'keyframes _sc_prefixed_animation_test { from { opacity: 1; } to { opacity: 0; } }';
539
-
540
- // Add test animation styles.
541
- animationEl.innerHTML = '<style>' + keyframes + '\n' + prefixedKeyframes + '</style>';
542
527
 
543
528
  // Set up and execute the animation event test.
544
- animationEl.style.animation = '_sc_animation_test 1ms linear';
545
- animationEl.style[SC.browser.domPrefix + 'Animation'] = '_sc_prefixed_animation_test 5ms linear';
546
-
547
- // NOTE: We could test start, but it's extra work and easier just to test the end
548
- // and infer the start event name from it. Keeping this code for example.
549
- // executeTest(animationEl, 'animationstart', 'AnimationStart', function (success) {
550
- // // If an iteration start never fired, we can't really support CSS transitions in SproutCore.
551
- // if (!success) {
552
- // SC.platform.supportsCSSAnimations = NO;
553
- // }
554
- // });
555
-
556
- // NOTE: Testing iteration event support proves very problematic. Many
557
- // browsers can't iterate less than several milliseconds which means we
558
- // have to wait too long to find out this event name. Instead we test
559
- // the end only and infer the iteration event name from it. Keeping this
560
- // code for example, but it wont' work reliably unless the animation style
561
- // is something like '_sc_animation_test 30ms linear' (i.e. ~60ms wait time)
562
- // executeTest(animationEl, 'animationiteration', 'AnimationIteration', function (success) {
563
- // // If an iteration event never fired, we can't really support CSS transitions in SproutCore.
564
- // if (!success) {
565
- // SC.platform.supportsCSSAnimations = NO;
566
- // }
567
- // });
568
-
569
- // Test animation events.
570
- executeTest(animationEl, 'animationend', 'AnimationEnd', function (success) {
571
- // If an end event never fired, we can't really support CSS animations in SproutCore.
572
- if (success) {
573
- // Infer the start and iteration event names based on the success of the end event.
574
- var domPrefix = SC.browser.domPrefix,
575
- lowerDomPrefix = domPrefix.toLowerCase(),
576
- endEventName = SC.platform.animationendEventName;
577
-
578
- switch (endEventName) {
579
- case lowerDomPrefix + 'animationend':
580
- SC.platform.animationstartEventName = lowerDomPrefix + 'animationstart';
581
- SC.platform.animationiterationEventName = lowerDomPrefix + 'animationiteration';
582
- break;
583
- case lowerDomPrefix + 'AnimationEnd':
584
- SC.platform.animationstartEventName = lowerDomPrefix + 'AnimationStart';
585
- SC.platform.animationiterationEventName = lowerDomPrefix + 'AnimationIteration';
586
- break;
587
- case domPrefix + 'AnimationEnd':
588
- SC.platform.animationstartEventName = domPrefix + 'AnimationStart';
589
- SC.platform.animationiterationEventName = domPrefix + 'AnimationIteration';
590
- break;
591
- default:
592
- SC.platform.animationstartEventName = 'animationstart';
593
- SC.platform.animationiterationEventName = 'animationiteration';
529
+ if (SC.platform.supportsCSSAnimations) {
530
+ var animationEl = document.createElement('div'),
531
+ keyframes,
532
+ prefixedKeyframes;
533
+
534
+ // Generate both the regular and prefixed version of the style.
535
+ keyframes = '@keyframes _sc_animation_test { from { opacity: 1; } to { opacity: 0; } }';
536
+ prefixedKeyframes = '@' + SC.browser.cssPrefix + 'keyframes _sc_prefixed_animation_test { from { opacity: 1; } to { opacity: 0; } }';
537
+
538
+ // Add test animation styles.
539
+ animationEl.innerHTML = '<style>' + keyframes + '\n' + prefixedKeyframes + '</style>';
540
+
541
+ // Set up and execute the animation event test.
542
+ animationEl.style.animation = '_sc_animation_test 1ms linear';
543
+ animationEl.style[SC.browser.domPrefix + 'Animation'] = '_sc_prefixed_animation_test 5ms linear';
544
+
545
+ // NOTE: We could test start, but it's extra work and easier just to test the end
546
+ // and infer the start event name from it. Keeping this code for example.
547
+ // executeTest(animationEl, 'animationstart', 'AnimationStart', function (success) {
548
+ // // If an iteration start never fired, we can't really support CSS transitions in SproutCore.
549
+ // if (!success) {
550
+ // SC.platform.supportsCSSAnimations = NO;
551
+ // }
552
+ // });
553
+
554
+ // NOTE: Testing iteration event support proves very problematic. Many
555
+ // browsers can't iterate less than several milliseconds which means we
556
+ // have to wait too long to find out this event name. Instead we test
557
+ // the end only and infer the iteration event name from it. Keeping this
558
+ // code for example, but it wont' work reliably unless the animation style
559
+ // is something like '_sc_animation_test 30ms linear' (i.e. ~60ms wait time)
560
+ // executeTest(animationEl, 'animationiteration', 'AnimationIteration', function (success) {
561
+ // // If an iteration event never fired, we can't really support CSS transitions in SproutCore.
562
+ // if (!success) {
563
+ // SC.platform.supportsCSSAnimations = NO;
564
+ // }
565
+ // });
566
+
567
+ // Test animation events.
568
+ executeTest(animationEl, 'animationend', 'AnimationEnd', function (success) {
569
+ // If an end event never fired, we can't really support CSS animations in SproutCore.
570
+ if (success) {
571
+ // Infer the start and iteration event names based on the success of the end event.
572
+ var domPrefix = SC.browser.domPrefix,
573
+ lowerDomPrefix = domPrefix.toLowerCase(),
574
+ endEventName = SC.platform.animationendEventName;
575
+
576
+ switch (endEventName) {
577
+ case lowerDomPrefix + 'animationend':
578
+ SC.platform.animationstartEventName = lowerDomPrefix + 'animationstart';
579
+ SC.platform.animationiterationEventName = lowerDomPrefix + 'animationiteration';
580
+ break;
581
+ case lowerDomPrefix + 'AnimationEnd':
582
+ SC.platform.animationstartEventName = lowerDomPrefix + 'AnimationStart';
583
+ SC.platform.animationiterationEventName = lowerDomPrefix + 'AnimationIteration';
584
+ break;
585
+ case domPrefix + 'AnimationEnd':
586
+ SC.platform.animationstartEventName = domPrefix + 'AnimationStart';
587
+ SC.platform.animationiterationEventName = domPrefix + 'AnimationIteration';
588
+ break;
589
+ default:
590
+ SC.platform.animationstartEventName = 'animationstart';
591
+ SC.platform.animationiterationEventName = 'animationiteration';
592
+ }
593
+
594
+ // Set up the SC animation event listeners.
595
+ SC.RootResponder.responder.cleanUpAnimationListeners();
596
+ } else {
597
+ SC.platform.supportsCSSAnimations = NO;
594
598
  }
595
599
 
596
- // Set up the SC animation event listeners.
597
- SC.RootResponder.responder.setupAnimationListeners();
598
- } else {
599
- SC.platform.supportsCSSAnimations = NO;
600
- }
600
+ // Clean up.
601
+ animationEl.parentNode.removeChild(animationEl);
602
+ animationEl = null;
603
+ });
601
604
 
602
- // Clean up.
603
- animationEl.parentNode.removeChild(animationEl);
604
- animationEl = null;
605
- });
606
-
607
- // Break execution to allow the browser to update the DOM before altering the style.
608
- document.documentElement.appendChild(animationEl);
605
+ // Break execution to allow the browser to update the DOM before altering the style.
606
+ document.documentElement.appendChild(animationEl);
607
+ }
609
608
  }
610
609
  });
@@ -650,6 +650,57 @@ SC.RootResponder = SC.Object.extend(
650
650
  }
651
651
  }
652
652
 
653
+ // Add an array of transition listeners for immediate use (these will be cleaned up when actual testing completes).
654
+ // Because the transition test happens asynchronously and because we don't want to
655
+ // delay the launch of the application in order to a transition test (the app won't
656
+ // load if the browser tab is not visible), we start off by listening to everything
657
+ // and when the test is completed, we remove the extras to avoid double callbacks.
658
+ if (SC.platform.supportsCSSTransitions) {
659
+ var domPrefix = SC.browser.domPrefix,
660
+ lowerDomPrefix = domPrefix.toLowerCase(),
661
+ variation1 = lowerDomPrefix + 'transitionend',
662
+ variation2 = lowerDomPrefix + 'TransitionEnd',
663
+ variation3 = domPrefix + 'TransitionEnd';
664
+
665
+ // Ensure that the callback name used maps to our implemented function name.
666
+ this[variation1] = this[variation2] = this[variation3] = this.transitionend;
667
+
668
+ // ex. transitionend, webkittransitionend, webkitTransitionEnd, WebkitTransitionEnd
669
+ this.listenFor(['transitionend', variation1, variation2, variation3], document);
670
+
671
+ if (SC.platform.supportsCSSAnimations) {
672
+ variation1 = lowerDomPrefix + 'animationstart';
673
+ variation2 = lowerDomPrefix + 'AnimationStart';
674
+ variation3 = domPrefix + 'AnimationStart';
675
+
676
+ // Ensure that the callback name used maps to our implemented function name.
677
+ this[variation1] = this[variation2] = this[variation3] = this.animationstart;
678
+
679
+ // ex. animationstart, webkitanimationstart, webkitAnimationStart, WebkitAnimationStart
680
+ this.listenFor(['animationstart', variation1, variation2, variation3], document);
681
+
682
+ variation1 = lowerDomPrefix + 'animationiteration';
683
+ variation2 = lowerDomPrefix + 'AnimationIteration';
684
+ variation3 = domPrefix + 'AnimationIteration';
685
+
686
+ // Ensure that the callback name used maps to our implemented function name.
687
+ this[variation1] = this[variation2] = this[variation3] = this.animationiteration;
688
+
689
+ // ex. animationiteration, webkitanimationiteration, webkitAnimationIteration, WebkitAnimationIteration
690
+ this.listenFor(['animationiteration', variation1, variation2, variation3], document);
691
+
692
+ variation1 = lowerDomPrefix + 'animationend';
693
+ variation2 = lowerDomPrefix + 'AnimationEnd';
694
+ variation3 = domPrefix + 'AnimationEnd';
695
+
696
+ // Ensure that the callback name used maps to our implemented function name.
697
+ this[variation1] = this[variation2] = this[variation3] = this.animationend;
698
+
699
+ // ex. animationend, webkitanimationend, webkitAnimationEnd, WebkitAnimationEnd
700
+ this.listenFor(['animationend', variation1, variation2, variation3], document);
701
+ }
702
+ }
703
+
653
704
  // handle these two events specially in IE
654
705
  ['drag', 'selectstart'].forEach(function (keyName) {
655
706
  var method = this[keyName];
@@ -763,37 +814,79 @@ SC.RootResponder = SC.Object.extend(
763
814
  },
764
815
 
765
816
  /**
766
- Sets up the transition end event listener.
817
+ Cleans up the additional transition event listeners.
767
818
 
768
- NOTE: requires that SC.platform.transitionendEventName has been determined.
819
+ NOTE: requires that SC.RootResponser.responder.transitionendEventName
820
+ has been determined.
769
821
 
770
822
  @returns {void}
771
823
  */
772
- setupTransitionListener: function () {
773
- // CSS Transitions (tested asynchronously)
774
- if (SC.platform.supportsCSSTransitions) {
775
- // Ensure that the callback name used maps to our implemented function name.
776
- this[SC.platform.transitionendEventName] = this.transitionend;
777
- this.listenFor([SC.platform.transitionendEventName], document);
778
- }
824
+ cleanUpTransitionListeners: function () {
825
+ var actualEventName = SC.platform.transitionendEventName,
826
+ domPrefix = SC.browser.domPrefix,
827
+ lowerDomPrefix = domPrefix.toLowerCase(),
828
+ variation1 = lowerDomPrefix + 'transitionend',
829
+ variation2 = lowerDomPrefix + 'TransitionEnd',
830
+ variation3 = domPrefix + 'TransitionEnd';
831
+
832
+ // Once the actual event name is determined, simply remove all the extras.
833
+ // This should prevent any problems with browsers that fire multiple events.
834
+ ['transitionend', variation1, variation2, variation3].forEach(function (keyName) {
835
+ if (keyName != actualEventName) {
836
+ SC.Event.remove(document, keyName, this, this[keyName]);
837
+ this[keyName] = null;
838
+ }
839
+ });
779
840
  },
780
841
 
781
842
  /**
782
- Sets up the animation event listeners.
843
+ Cleans up the additional animation event listeners.
783
844
 
784
- NOTE: requires that SC.platform.animationstartEventName, SC.platform.animationendEventName & SC.platform.animationiterationEventName has been determined.
845
+ NOTE: requires that SC.RootResponser.responder.animationstartEventName,
846
+ SC.RootResponser.responder.animationendEventName and
847
+ SC.RootResponser.responder.animationiterationEventName have been
848
+ determined.
785
849
 
786
850
  @returns {void}
787
851
  */
788
- setupAnimationListeners: function () {
789
- // CSS Animations (tested asynchronously)
790
- if (SC.platform.supportsCSSAnimations) {
791
- // Ensure that the callback name used maps to our implemented function name.
792
- this[SC.platform.animationstartEventName] = this.animationstart;
793
- this[SC.platform.animationendEventName] = this.animationend;
794
- this[SC.platform.animationiterationEventName] = this.animationiteration;
795
- this.listenFor([SC.platform.animationstartEventName, SC.platform.animationendEventName, SC.platform.animationiterationEventName], document);
796
- }
852
+ cleanUpAnimationListeners: function () {
853
+ var domPrefix = SC.browser.domPrefix,
854
+ lowerDomPrefix = domPrefix.toLowerCase(),
855
+ actualEventName = SC.platform.animationendEventName,
856
+ variation1 = lowerDomPrefix + 'animationend',
857
+ variation2 = lowerDomPrefix + 'AnimationEnd',
858
+ variation3 = domPrefix + 'AnimationEnd';
859
+
860
+ // Once the actual event name is determined, simply remove all the extras.
861
+ // This should prevent any problems with browsers that fire multiple events.
862
+ ['animationend', variation1, variation2, variation3].forEach(function (keyName) {
863
+ if (keyName != actualEventName) {
864
+ SC.Event.remove(document, keyName, this, this[keyName]);
865
+ this[keyName] = null;
866
+ }
867
+ });
868
+
869
+ actualEventName = SC.platform.animationiterationEventName;
870
+ variation1 = lowerDomPrefix + 'animationiteration';
871
+ variation2 = lowerDomPrefix + 'AnimationIteration';
872
+ variation3 = domPrefix + 'AnimationIteration';
873
+ ['animationiteration', variation1, variation2, variation3].forEach(function (keyName) {
874
+ if (keyName != actualEventName) {
875
+ SC.Event.remove(document, keyName, this, this[keyName]);
876
+ this[keyName] = null;
877
+ }
878
+ });
879
+
880
+ actualEventName = SC.platform.animationstartEventName;
881
+ variation1 = lowerDomPrefix + 'animationstart';
882
+ variation2 = lowerDomPrefix + 'AnimationStart';
883
+ variation3 = domPrefix + 'AnimationStart';
884
+ ['animationstart', variation1, variation2, variation3].forEach(function (keyName) {
885
+ if (keyName != actualEventName) {
886
+ SC.Event.remove(document, keyName, this, this[keyName]);
887
+ this[keyName] = null;
888
+ }
889
+ });
797
890
  },
798
891
 
799
892
  // ...........................................................................
@@ -1615,7 +1708,7 @@ SC.RootResponder = SC.Object.extend(
1615
1708
  handles the event, then it will be sent as a regular keyDown event.
1616
1709
  This function is only valid when called with a keydown event.
1617
1710
  */
1618
- _isFunctionOrNonPrintableKey: function(evt) {
1711
+ _isFunctionOrNonPrintableKey: function (evt) {
1619
1712
  return !!(evt.altKey || evt.ctrlKey || evt.metaKey || SC.FUNCTION_KEYS[evt.which]);
1620
1713
  },
1621
1714
 
@@ -1636,7 +1729,7 @@ SC.RootResponder = SC.Object.extend(
1636
1729
  @param {KeyboardEvent} evt keypress event
1637
1730
  @returns {Boolean}
1638
1731
  */
1639
- _isPrintableKey: function(evt) {
1732
+ _isPrintableKey: function (evt) {
1640
1733
  return ((evt.originalEvent.which === undefined || evt.originalEvent.which > 0) &&
1641
1734
  !(evt.which === 8 || evt.which === 9 || evt.which === 13 || evt.which === 27));
1642
1735
  },