diff options
| author | Matias Niemelàˆ | 2013-08-01 22:17:10 -0400 | 
|---|---|---|
| committer | Misko Hevery | 2013-08-03 00:46:17 -0700 | 
| commit | 6e8bd786ba853613472f3864e48048a425c46823 (patch) | |
| tree | f341aea0ca016d63f657ce64fda72cd9f6339d33 | |
| parent | 4ed5fc90b984bb704da8cb66dffab43cf78abefa (diff) | |
| download | angular.js-6e8bd786ba853613472f3864e48048a425c46823.tar.bz2 | |
fix(ngAnimate): remove compound JS selector animations
| -rw-r--r-- | docs/content/error/animate/notcsel.ngdoc | 6 | ||||
| -rw-r--r-- | src/ng/animate.js | 16 | ||||
| -rw-r--r-- | src/ngAnimate/animate.js | 42 | ||||
| -rw-r--r-- | test/ng/animateSpec.js | 17 | 
4 files changed, 47 insertions, 34 deletions
| diff --git a/docs/content/error/animate/notcsel.ngdoc b/docs/content/error/animate/notcsel.ngdoc new file mode 100644 index 00000000..d8ceaa0e --- /dev/null +++ b/docs/content/error/animate/notcsel.ngdoc @@ -0,0 +1,6 @@ +@ngdoc error +@name $animate:notcsel +@fullName Not class CSS selector +@description + +Expecting a CSS selector for class. Class selectors must start with `.`, for example: `.my-class-name`. diff --git a/src/ng/animate.js b/src/ng/animate.js index 7927b12f..2d9e6191 100644 --- a/src/ng/animate.js +++ b/src/ng/animate.js @@ -1,5 +1,7 @@  'use strict'; +var $animateMinErr = minErr('$animate'); +  /**   * @ngdoc object   * @name ng.$animateProvider @@ -14,7 +16,7 @@   */  var $AnimateProvider = ['$provide', function($provide) { -  this.$$selectors = []; +  this.$$selectors = {};    /** @@ -47,13 +49,11 @@ var $AnimateProvider = ['$provide', function($provide) {     * @param {function} factory The factory function that will be executed to return the animation object.     */    this.register = function(name, factory) { -    var classes = name.substr(1).split('.'); -    name += '-animation'; -    this.$$selectors.push({ -      selectors : classes, -      name : name -    }); -    $provide.factory(name, factory); +    var key = name + '-animation'; +    if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel', +        "Expecting class selector starting with '.' got '{0}'.", name); +    this.$$selectors[name.substr(1)] = key; +    $provide.factory(key, factory);    };    this.$get = ['$timeout', function($timeout) { diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 20ceaf07..d572619f 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -174,7 +174,7 @@   * a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits   * the element's CSS class attribute value and then run the matching animation event function (if found).   * In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function - * be executed. It should be also noted that only simple or compound class selectors are allowed. + * be executed. It should be also noted that only simple class selectors are allowed.   *   * Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned.   * As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run, @@ -211,27 +211,23 @@ angular.module('ngAnimate', ['ng'])        $rootElement.data(NG_ANIMATE_STATE, rootAnimateState);        function lookup(name) { -        var i, ii;          if (name) { -          var classes = name.substr(1).split('.'), -              classMap = {}; - -          for (i = 0, ii = classes.length; i < ii; i++) { -            classMap[classes[i]] = true; -          } - -          var matches = []; -          for (i = 0, ii = selectors.length; i < ii; i++) { -            var selectorFactory = selectors[i]; -            var found = true; -            for(var j = 0, jj = selectorFactory.selectors.length; j < jj; j++) { -              var klass = selectorFactory.selectors[j]; -              if(klass.length > 0) { -                found = found && classMap[klass]; -              } -            } -            if(found) { -              matches.push($injector.get(selectorFactory.name)); +          var matches = [], +              flagMap = {}, +              classes = name.substr(1).split('.'); + +          //the empty string value is the default animation +          //operation which performs CSS transition and keyframe +          //animations sniffing. This is always included for each +          //element animation procedure +          classes.push(''); + +          for(var i=0; i < classes.length; i++) { +            var klass = classes[i], +                selectorFactoryName = selectors[klass]; +            if(selectorFactoryName && !flagMap[klass]) { +              matches.push($injector.get(selectorFactoryName)); +              flagMap[klass] = true;              }            }            return matches; @@ -444,8 +440,8 @@ angular.module('ngAnimate', ['ng'])          and the onComplete callback will be fired once the animation is fully complete.        */        function performAnimation(event, className, element, parent, after, onComplete) { -        var classes = ((element.attr('class') || '') + ' ' + className), -            animationLookup = (' ' + classes).replace(/\s+/g,'.'), +        var classes = (element.attr('class') || '') + ' ' + className; +        var animationLookup = (' ' + classes).replace(/\s+/g,'.'),              animations = [];          forEach(lookup(animationLookup), function(animation, index) {            animations.push({ diff --git a/test/ng/animateSpec.js b/test/ng/animateSpec.js index c5914a74..2e9034e4 100644 --- a/test/ng/animateSpec.js +++ b/test/ng/animateSpec.js @@ -1,9 +1,11 @@  describe("$animate", function() {    describe("without animation", function() { -    beforeEach(inject(function($compile, _$rootElement_, $rootScope) { -      element = $compile('<div></div>')($rootScope); -      $rootElement = _$rootElement_; +    beforeEach(module(function() { +      return function($compile, _$rootElement_, $rootScope) { +        element = $compile('<div></div>')($rootScope); +        $rootElement = _$rootElement_; +      };      }));      it("should add element at the start of enter animation", inject(function($animate, $compile, $rootScope) { @@ -37,5 +39,14 @@ describe("$animate", function() {        $animate.addClass(element, 'ng-hide');        expect(element).toBeHidden();      })); + +    it("should throw error on wrong selector", function() { +      module(function($animateProvider) { +        expect(function() { +          $animateProvider.register('abc', null); +        }).toThrow("[$animate:notcsel] Expecting class selector starting with '.' got 'abc'."); +      }); +      inject(); +    });    });  }); | 
