angular.js v1.2.0 Release Notes

Release Date: 2013-11-08 // over 10 years ago
  • 🔋 Features

    • animations:
      • ensure CSS transitions can work with inherited CSS class definitions (9d69a0a7)
      • provide support for staggering animations with CSS (74848307)
    • 📜 $parse: secure expressions by hiding "private" properties (3d6a89e8)
    • 📄 docs:
      • provide index pages for each angular module (a7e12b79)
      • add forward slash shortcut key for search bar (74912802)
    • jqLite: expose isolateScope() getter similar to scope() (27e9340b)
    • misc: add externs file for Closure Compiler (9d0a6977)

    🐛 Bug Fixes

    • $animate:
      • don't force animations to be enabled (98adc9e0)
      • only apply the fallback property if any transition animations are detected (94700807)
      • avoid hanging animations if the active CSS transition class is missing (b89584db, #4732, #4490)
      • ensure staggering animations understand multiple delay values (41a2d5b3)
      • ensure the active class is not applied if cancelled during reflow (e53ff431, #4699)
      • use direct DOM comparison when checking for $rootElement (d434eabe, #4679)
      • ensure former nodes are fully cleaned up when a follow-up structural animation takes place (7f0767ac, #4435)
      • ensure enable/disable animations work when the document node is used (6818542c, #4669)
      • skip unnecessary addClass/removeClass animations (76b628bc, #4401, #2332)
      • ensure animations work properly when the $rootElement is being animated (2623de14, #4397, #4231)
      • only cancel class-based animations if the follow-up class contains CSS transition/keyframe animation code (f5289fe8, #4463, #3784)
    • $compile:
      • don't leak isolate scope state when replaced directive is used multiple times (b5af198f)
      • correct isolate scope distribution to controllers (3fe4491a)
      • replaced element has isolate scope (97c7a4e3)
      • only pass isolate scope to children that belong to the isolate directive (d0efd5ee)
      • make isolate scope truly isolate (909cabd3, #1924, #2500)
      • don't instantiate controllers twice for element transclude directives (18ae985c, #4654)
      • attribute bindings should not break due to terminal directives (79223eae, #4525, #4528, #4649)
      • instantiate controllers when re-entering compilation (faf5b980, #4434, #4616)
    • $injector: allow a constructor function to return a function (c22adbf1)
    • 📜 $parse: check function call context to be safe (6d324c76, #4417)
    • 🤡 angular-mocks: add inline dependency annotation (6d23591c, #4448)
    • animateSpec: run digest to enable animations before tests (aea76f0d)
    • bootstrap-prettify: share $animate and $$postDigestQueue with demo apps (1df3da36)
    • csp:
    • docModuleComponents: implement anchor scroll when content added (eb51b024, #4703)
    • input: keep track of min/max attars on-the-fly (4b653aea)
    • ngAnimate: fix cancelChildAnimations throwing exception (b9557b0a, #4548)
    • ngClassSpec: clear animation enable fn from postDigestQueue (ffa9d0a6)
    • ngEventDirectives: parse expression only once during compile phase. (9a828738)
    • ngIf:
      • destroy child scope when destroying DOM (9483373c)
      • ngIf removes elements dynamically added to it (e19067c9)
    • ngInclude: only run anchorScroll after animation is done (d378f550, #4723)
    • ngMock: throw more descriptive errors for $animate.flushNext() (6fb19157)
    • ngModel: deregister from the form on scope not DOM destruction (8f989d65, #4226, #4779)
    • ngScenario: correctly disable animations for end 2 end tests (9d004585)
    • ngView:
      • only run anchorScroll after animation is done (da344daa)
      • ensure the new view element is placed after the old view element (3f568b22, #4362)
    • ngdocs:
      • create mock Doc objects correctly (d4493fda)
      • shortDescription() should not error if no description (4c8fa353)
      • remove the side search bar (6c20ec19)

    💥 Breaking Changes

    • $compile:

      • due to d0efd5ee, Child elements that are defined either in the application template or in some other directives template do not get the isolate scope. In theory, nobody should rely on this behavior, as it is very rare - in most cases the isolate directive has a template.
      • due to 909cabd3, Directives without isolate scope do not get the isolate scope from an isolate directive on the same element. If your code depends on this behavior (non-isolate directive needs to access state from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly.

    Before

      <input ng-model="$parent.value" ng-isolate>
    
      .directive('ngIsolate', function() {
        return {
          scope: {},
          template: '{{value}}'
        };
      });
    

    After

      <input ng-model="value" ng-isolate>
    
      .directive('ngIsolate', function() {
        return {
          scope: {value: '=ngModel'},
          template: '{{value}}
        };
      });
    

    Closes #1924 and #2500

    Previously, the interpolation priority was -100 in 1.2.0-rc.2, and 100 before 1.2.0-rc.2. Before this change the binding was setup in the post-linking phase.

    Now the attribute interpolation (binding) executes as a directive with priority 100 and the binding is set up in the pre-linking phase.

    Closes #4525, #4528, and #4649

    This commit introduces the notion of "private" properties (properties whose names begin and/or end with an underscore) on the scope chain. These properties will not be available to Angular expressions (i.e. {{ }} interpolation in templates and strings passed to $parse) They are freely available to JavaScript code (as before).

    Motivation

    Angular expressions execute in a limited context. They do not have direct access to the global scope, window, document or the Function constructor. However, they have direct access to names/properties on the scope chain. It has been a long standing best practice to keep sensitive APIs outside of the scope chain (in a closure or your controller.) That's easier said that done for two reasons:

    1. JavaScript does not have a notion of private properties so if you need someone on the scope chain for JavaScript use, you also expose it to Angular expressions
    2. the new "controller as" syntax that's now in increased usage exposes the entire controller on the scope chain greatly increasing the exposed surface.

    Though Angular expressions are written and controlled by the developer, they:

    1. Typically deal with user input
    2. Don't get the kind of test coverage that JavaScript code would

    This commit provides a way, via a naming convention, to allow publishing/restricting properties from controllers/scopes to Angular expressions enabling one to only expose those properties that are actually needed by the expressions.

    • csp: due to 08f376f2, triggering ngCsp directive via ng:csp attribute is not supported any more. Please use data-ng-csp instead.

    • jqLite: due to 27e9340b, jqLite.scope() (commonly used through angular.element(node).scope()) does not return the isolate scope on the element that triggered directive with isolate scope. Use jqLite.isolateScope() instead.