diff options
38 files changed, 951 insertions, 683 deletions
diff --git a/js/package.json b/js/package.json index 46f72df2e..e55e0e31f 100644 --- a/js/package.json +++ b/js/package.json @@ -28,7 +28,7 @@ "grunt-cachebuster": "^0.1.5", "grunt-contrib-concat": "^0.5.1", "grunt-contrib-connect": "^0.10.1", - "grunt-contrib-cssmin": "^0.12.2", + "grunt-contrib-cssmin": "^0.12.3", "grunt-contrib-jshint": "^0.11.2", "grunt-contrib-uglify": "^0.9.1", "grunt-contrib-watch": "^0.6.1", @@ -40,9 +40,9 @@ "grunt-protractor-webdriver": "^0.2.0", "grunt-wrap": "^0.3.0", "karma": "^0.12.31", - "karma-chrome-launcher": "^0.1.8", + "karma-chrome-launcher": "^0.1.12", "karma-coverage": "^0.3.1", - "karma-firefox-launcher": "^0.1.4", + "karma-firefox-launcher": "^0.1.6", "karma-jasmine": "^0.3.5" }, "dependencies": {} diff --git a/js/vendor/angular-animate/.bower.json b/js/vendor/angular-animate/.bower.json index dc1346b69..d87b94297 100644 --- a/js/vendor/angular-animate/.bower.json +++ b/js/vendor/angular-animate/.bower.json @@ -1,17 +1,17 @@ { "name": "angular-animate", - "version": "1.4.0-rc.1", + "version": "1.4.0-rc.2", "main": "./angular-animate.js", "ignore": [], "dependencies": { - "angular": "1.4.0-rc.1" + "angular": "1.4.0-rc.2" }, "homepage": "https://github.com/angular/bower-angular-animate", - "_release": "1.4.0-rc.1", + "_release": "1.4.0-rc.2", "_resolution": { "type": "version", - "tag": "v1.4.0-rc.1", - "commit": "872a7357132b252b0856edeea082d6e57d516ea7" + "tag": "v1.4.0-rc.2", + "commit": "00ae49c898ec3e9f78dcbd9d85b222f2322c48bf" }, "_source": "git://github.com/angular/bower-angular-animate.git", "_target": "~1.4.*", diff --git a/js/vendor/angular-animate/angular-animate.js b/js/vendor/angular-animate/angular-animate.js index 66fc23934..126be09b9 100644 --- a/js/vendor/angular-animate/angular-animate.js +++ b/js/vendor/angular-animate/angular-animate.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.4.0-rc.1 + * @license AngularJS v1.4.0-rc.2 * (c) 2010-2015 Google, Inc. http://angularjs.org * License: MIT */ @@ -21,6 +21,7 @@ var isElement = angular.isElement; var ELEMENT_NODE = 1; var COMMENT_NODE = 8; +var NG_ANIMATE_CLASSNAME = 'ng-animate'; var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren'; var isPromiseLike = function(p) { @@ -77,18 +78,29 @@ function removeFromArray(arr, val) { } function stripCommentsFromElement(element) { - if (element.nodeType === ELEMENT_NODE) { - return jqLite(element); + if (element instanceof jqLite) { + switch (element.length) { + case 0: + return []; + break; + + case 1: + // there is no point of stripping anything if the element + // is the only element within the jqLite wrapper. + // (it's important that we retain the element instance.) + if (element[0].nodeType === ELEMENT_NODE) { + return element; + } + break; + + default: + return jqLite(extractElementNode(element)); + break; + } } - if (element.length === 0) return []; - // there is no point of stripping anything if the element - // is the only element within the jqLite wrapper. - // (it's important that we retain the element instance.) - if (element.length === 1) { - return element[0].nodeType === ELEMENT_NODE && element; - } else { - return jqLite(extractElementNode(element)); + if (element.nodeType === ELEMENT_NODE) { + return jqLite(element); } } @@ -240,6 +252,10 @@ function resolveElementClasses(existing, toAdd, toRemove) { return classes; } +function getDomNode(element) { + return (element instanceof angular.element) ? element[0] : element; +} + var $$AnimateChildrenDirective = [function() { return function(scope, element, attrs) { var val = attrs.ngAnimateChildren; @@ -293,16 +309,11 @@ var $$AnimateChildrenDirective = [function() { * return { * enter: function(element, doneFn) { * var height = element[0].offsetHeight; - * var animation = $animateCss(element, { + * return $animateCss(element, { * from: { height:'0px' }, * to: { height:height + 'px' }, * duration: 1 // one second * }); - * - * // if no possible animation can be triggered due - * // to the combination of options then `animation` - * // will be returned as undefined - * animation.start().done(doneFn); * } * } * }]); @@ -325,18 +336,13 @@ var $$AnimateChildrenDirective = [function() { * return { * enter: function(element, doneFn) { * var height = element[0].offsetHeight; - * var animation = $animateCss(element, { + * return $animateCss(element, { * addClass: 'red large-text pulse-twice', * easing: 'ease-out', * from: { height:'0px' }, * to: { height:height + 'px' }, * duration: 1 // one second * }); - * - * // if no possible animation can be triggered due - * // to the combination of options then `animation` - * // will be returned as undefined - * animation.start().done(doneFn); * } * } * }]); @@ -376,10 +382,11 @@ var $$AnimateChildrenDirective = [function() { * styles using the `from` and `to` properties. * * ```js - * var animation = $animateCss(element, { + * var animator = $animateCss(element, { * from: { background:'red' }, * to: { background:'blue' } * }); + * animator.start(); * ``` * * ```css @@ -412,10 +419,10 @@ var $$AnimateChildrenDirective = [function() { * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties: * * ```js - * var animation = $animateCss(element, { ... }); + * var animator = $animateCss(element, { ... }); * ``` * - * Now what do the contents of our `animation` variable look like: + * Now what do the contents of our `animator` variable look like: * * ```js * { @@ -432,26 +439,14 @@ var $$AnimateChildrenDirective = [function() { * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties * and that changing them will not reconfigure the parameters of the animation. * - * By calling `animation.start()` we do get back a promise, however, due to the nature of animations we may not want to tap into the default behaviour of - * animations (since they cause a digest to occur which may slow down the animation performance-wise). Therefore instead of calling `then` to capture when - * the animation ends be sure to call `done(callback)` (this is the recommended way to use `$animateCss` within JavaScript-animations). - * - * The example below should put this into perspective: + * ### runner.done() vs runner.then() + * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the + * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**. + * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()` + * unless you really need a digest to kick off afterwards. * - * ```js - * var animation = $animateCss(element, { ... }); - * - * // remember that if there is no CSS animation detected on the element - * // then the value returned from $animateCss will be null - * if (animation) { - * animation.start().done(function() { - * // yaay the animation is over - * doneCallback(); - * }); - * } else { - * doneCallback(); - * } - * ``` + * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss + * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code). Check the [animation code above](#usage) to see how this works. * * @param {DOMElement} element the element that will be animated * @param {object} options the animation-related options that will be applied during the animation @@ -477,7 +472,7 @@ var $$AnimateChildrenDirective = [function() { * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`) * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occuring on the classes being added and removed.) * - * @return {null|object} an object with a start method and details about the animation. If no animation is detected then a value of `null` will be returned. + * @return {object} an object with start and end methods and details about the animation. * * * `start` - The method to start the animation. This will return a `Promise` when called. * * `end` - This method will cancel the animation and remove all applied CSS classes and styles. @@ -726,7 +721,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { return stagger || {}; } - var bod = $document[0].body; + var bod = getDomNode($document).body; var cancelLastRAFRequest; var rafWaitQueue = []; function waitUntilQuiet(callback) { @@ -775,7 +770,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { } function init(element, options) { - var node = element[0]; + var node = getDomNode(element); options = prepareAnimationOptions(options); var temporaryStyles = []; @@ -792,8 +787,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { var maxDurationTime; if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) { - close(); - return; + return closeAndReturnNoopAnimator(); } var method = options.event && isArray(options.event) @@ -840,8 +834,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { // there is no way we can trigger an animation since no styles and // no classes are being applied which would then trigger a transition if (!hasToStyles && !setupClasses) { - close(); - return false; + return closeAndReturnNoopAnimator(); } var cacheKey, stagger; @@ -936,8 +929,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { } if (maxDuration === 0 && !flags.recalculateTimingStyles) { - close(); - return false; + return closeAndReturnNoopAnimator(); } // we need to recalculate the delay value since we used a pre-emptive negative @@ -965,6 +957,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { // TODO(matsko): for 1.5 change this code to have an animator object for better debugging return { + $$willAnimate: true, end: endFn, start: function() { if (animationClosed) return; @@ -1044,6 +1037,23 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { } } + function closeAndReturnNoopAnimator() { + runner = new $$AnimateRunner({ + end: endFn, + cancel: cancelFn + }); + + close(); + + return { + $$willAnimate: false, + start: function() { + return runner; + }, + end: endFn + }; + } + function start() { if (animationClosed) return; @@ -1220,8 +1230,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro $$animationProvider.drivers.push('$$animateCssDriver'); var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim'; - var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-animate-anchor'; - var NG_ANIMATE_ANCHOR_SUFFIX = '-anchor'; + var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor'; var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out'; var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in'; @@ -1232,8 +1241,8 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro // only browsers that support these properties can render animations if (!$sniffer.animations && !$sniffer.transitions) return noop; - var bodyNode = $document[0].body; - var rootNode = $rootElement[0]; + var bodyNode = getDomNode($document).body; + var rootNode = getDomNode($rootElement); var rootBodyElement = jqLite(bodyNode.parentNode === rootNode ? bodyNode : rootNode); @@ -1260,15 +1269,13 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro } function prepareAnchoredAnimation(classes, outAnchor, inAnchor) { - var clone = jqLite(outAnchor[0].cloneNode(true)); - var startingClasses = filterCssClasses(clone.attr('class') || ''); - var anchorClasses = pendClasses(classes, NG_ANIMATE_ANCHOR_SUFFIX); + var clone = jqLite(getDomNode(outAnchor).cloneNode(true)); + var startingClasses = filterCssClasses(getClassVal(clone)); outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME); - clone.addClass(anchorClasses); rootBodyElement.append(clone); @@ -1329,7 +1336,7 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro function calculateAnchorStyles(anchor) { var styles = {}; - var coords = anchor[0].getBoundingClientRect(); + var coords = getDomNode(anchor).getBoundingClientRect(); // we iterate directly since safari messes up and doesn't return // all the keys for the coods object when iterated @@ -1349,22 +1356,36 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro } function prepareOutAnimation() { - return $animateCss(clone, { + var animator = $animateCss(clone, { addClass: NG_OUT_ANCHOR_CLASS_NAME, delay: true, from: calculateAnchorStyles(outAnchor) }); + + // read the comment within `prepareRegularAnimation` to understand + // why this check is necessary + return animator.$$willAnimate ? animator : null; + } + + function getClassVal(element) { + return element.attr('class') || ''; } function prepareInAnimation() { - var endingClasses = filterCssClasses(inAnchor.attr('class')); - var classes = getUniqueValues(endingClasses, startingClasses); - return $animateCss(clone, { + var endingClasses = filterCssClasses(getClassVal(inAnchor)); + var toAdd = getUniqueValues(endingClasses, startingClasses); + var toRemove = getUniqueValues(startingClasses, endingClasses); + + var animator = $animateCss(clone, { to: calculateAnchorStyles(inAnchor), - addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + classes, - removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + startingClasses, + addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd, + removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove, delay: true }); + + // read the comment within `prepareRegularAnimation` to understand + // why this check is necessary + return animator.$$willAnimate ? animator : null; } function end() { @@ -1445,7 +1466,13 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro options.onDone = animationDetails.domOperation; } - return $animateCss(element, options); + var animator = $animateCss(element, options); + + // the driver lookup code inside of $$animation attempts to spawn a + // driver one by one until a driver returns a.$$willAnimate animator object. + // $animateCss will always return an object, however, it will pass in + // a flag as a hint as to whether an animation was detected or not + return animator.$$willAnimate ? animator : null; } }]; }]; @@ -1595,9 +1622,20 @@ var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) { args.push(options); var value = fn.apply(fn, args); + if (value) { + if (isFunction(value.start)) { + value = value.start(); + } - // optional onEnd / onCancel callback - return isFunction(value) ? value : noop; + if (value instanceof $$AnimateRunner) { + value.done(onDone); + } else if (isFunction(value)) { + // optional onEnd / onCancel callback + return value; + } + } + + return noop; } function groupEventedAnimations(element, event, options, animations, fnName) { @@ -1876,7 +1914,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { } function findCallbacks(element, event) { - var targetNode = element[0]; + var targetNode = getDomNode(element); var matches = []; var entries = callbackRegistry[event]; @@ -1957,7 +1995,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { // (bool) - Global setter bool = animationsEnabled = !!element; } else { - var node = element.length ? element[0] : element; + var node = getDomNode(element); var recordExists = disabledElementsLookup.get(node); if (argCount === 1) { @@ -1980,11 +2018,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { }; function queueAnimation(element, event, options) { + var node, parent; element = stripCommentsFromElement(element); - var node = element[0]; + if (element) { + node = getDomNode(element); + parent = element.parent(); + } options = prepareAnimationOptions(options); - var parent = element.parent(); // we create a fake runner with a working promise. // These methods will become available after the digest has passed @@ -1994,7 +2035,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { // a jqLite wrapper that contains only comment nodes... If this // happens then there is no way we can perform an animation if (!node) { - runner.end(); + close(); return runner; } @@ -2167,7 +2208,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { close(!status); var animationDetails = activeAnimationsLookup.get(node); if (animationDetails && animationDetails.counter === counter) { - clearElementAnimationState(element); + clearElementAnimationState(getDomNode(element)); } notifyProgress(runner, event, 'close', {}); }); @@ -2194,7 +2235,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { } function closeChildAnimations(element) { - var node = element[0]; + var node = getDomNode(element); var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']'); forEach(children, function(child) { var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME)); @@ -2213,19 +2254,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { } function clearElementAnimationState(element) { - element = element.length ? element[0] : element; - element.removeAttribute(NG_ANIMATE_ATTR_NAME); - activeAnimationsLookup.remove(element); + var node = getDomNode(element); + node.removeAttribute(NG_ANIMATE_ATTR_NAME); + activeAnimationsLookup.remove(node); } - function isMatchingElement(a,b) { - a = a.length ? a[0] : a; - b = b.length ? b[0] : b; - return a === b; + function isMatchingElement(nodeOrElmA, nodeOrElmB) { + return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB); } function closeParentClassBasedAnimations(startingElement) { - var parentNode = startingElement[0]; + var parentNode = getDomNode(startingElement); do { if (!parentNode || parentNode.nodeType !== ELEMENT_NODE) break; @@ -2251,7 +2290,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { } } - function areAnimationsAllowed(element, parent, event) { + function areAnimationsAllowed(element, parentElement, event) { var bodyElementDetected = false; var rootElementDetected = false; var parentAnimationDetected = false; @@ -2259,17 +2298,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { var parentHost = element.data(NG_ANIMATE_PIN_DATA); if (parentHost) { - parent = parentHost; + parentElement = parentHost; } - while (parent && parent.length) { + while (parentElement && parentElement.length) { if (!rootElementDetected) { // angular doesn't want to attempt to animate elements outside of the application // therefore we need to ensure that the rootElement is an ancestor of the current element - rootElementDetected = isMatchingElement(parent, $rootElement); + rootElementDetected = isMatchingElement(parentElement, $rootElement); } - var parentNode = parent[0]; + var parentNode = parentElement[0]; if (parentNode.nodeType !== ELEMENT_NODE) { // no point in inspecting the #document element break; @@ -2284,7 +2323,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { } if (isUndefined(animateChildren) || animateChildren === true) { - var value = parent.data(NG_ANIMATE_CHILDREN_DATA); + var value = parentElement.data(NG_ANIMATE_CHILDREN_DATA); if (isDefined(value)) { animateChildren = value; } @@ -2296,11 +2335,11 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { if (!rootElementDetected) { // angular doesn't want to attempt to animate elements outside of the application // therefore we need to ensure that the rootElement is an ancestor of the current element - rootElementDetected = isMatchingElement(parent, $rootElement); + rootElementDetected = isMatchingElement(parentElement, $rootElement); if (!rootElementDetected) { - parentHost = parent.data(NG_ANIMATE_PIN_DATA); + parentHost = parentElement.data(NG_ANIMATE_PIN_DATA); if (parentHost) { - parent = parentHost; + parentElement = parentHost; } } } @@ -2308,10 +2347,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { if (!bodyElementDetected) { // we also need to ensure that the element is or will be apart of the body element // otherwise it is pointless to even issue an animation to be rendered - bodyElementDetected = isMatchingElement(parent, bodyElement); + bodyElementDetected = isMatchingElement(parentElement, bodyElement); } - parent = parent.parent(); + parentElement = parentElement.parent(); } var allowAnimation = !parentAnimationDetected || animateChildren; @@ -2322,14 +2361,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { details = details || {}; details.state = state; |