diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.js
index 5b490836c..b19f02de4 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.4.2
+ * @license AngularJS v1.4.5
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -21,12 +21,60 @@ var isElement = angular.isElement;
var ELEMENT_NODE = 1;
var COMMENT_NODE = 8;
+var ADD_CLASS_SUFFIX = '-add';
+var REMOVE_CLASS_SUFFIX = '-remove';
+var EVENT_CLASS_PREFIX = 'ng-';
+var ACTIVE_CLASS_SUFFIX = '-active';
+
var NG_ANIMATE_CLASSNAME = 'ng-animate';
var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
+// Detect proper transitionend/animationend event names.
+var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
+
+// If unprefixed events are not supported but webkit-prefixed are, use the latter.
+// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
+// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
+// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
+// Register both events in case `window.onanimationend` is not supported because of that,
+// do the same for `transitionend` as Safari is likely to exhibit similar behavior.
+// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
+// therefore there is no reason to test anymore for other vendor prefixes:
+// http://caniuse.com/#search=transition
+if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
+ CSS_PREFIX = '-webkit-';
+ TRANSITION_PROP = 'WebkitTransition';
+ TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
+} else {
+ TRANSITION_PROP = 'transition';
+ TRANSITIONEND_EVENT = 'transitionend';
+}
+
+if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
+ CSS_PREFIX = '-webkit-';
+ ANIMATION_PROP = 'WebkitAnimation';
+ ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
+} else {
+ ANIMATION_PROP = 'animation';
+ ANIMATIONEND_EVENT = 'animationend';
+}
+
+var DURATION_KEY = 'Duration';
+var PROPERTY_KEY = 'Property';
+var DELAY_KEY = 'Delay';
+var TIMING_KEY = 'TimingFunction';
+var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
+var ANIMATION_PLAYSTATE_KEY = 'PlayState';
+var SAFE_FAST_FORWARD_DURATION_VALUE = 9999;
+
+var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
+var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
+var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
+var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
+
var isPromiseLike = function(p) {
return p && p.then ? true : false;
-}
+};
function assertArg(arg, name, reason) {
if (!arg) {
@@ -177,8 +225,21 @@ function mergeAnimationOptions(element, target, newOptions) {
var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
+ if (newOptions.preparationClasses) {
+ target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses);
+ delete newOptions.preparationClasses;
+ }
+
+ // noop is basically when there is no callback; otherwise something has been set
+ var realDomOperation = target.domOperation !== noop ? target.domOperation : null;
+
extend(target, newOptions);
+ // TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this.
+ if (realDomOperation) {
+ target.domOperation = realDomOperation;
+ }
+
if (classes.addClass) {
target.addClass = classes.addClass;
} else {
@@ -256,18 +317,81 @@ function getDomNode(element) {
return (element instanceof angular.element) ? element[0] : element;
}
+function applyGeneratedPreparationClasses(element, event, options) {
+ var classes = '';
+ if (event) {
+ classes = pendClasses(event, EVENT_CLASS_PREFIX, true);
+ }
+ if (options.addClass) {
+ classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX));
+ }
+ if (options.removeClass) {
+ classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX));
+ }
+ if (classes.length) {
+ options.preparationClasses = classes;
+ element.addClass(classes);
+ }
+}
+
+function clearGeneratedClasses(element, options) {
+ if (options.preparationClasses) {
+ element.removeClass(options.preparationClasses);
+ options.preparationClasses = null;
+ }
+ if (options.activeClasses) {
+ element.removeClass(options.activeClasses);
+ options.activeClasses = null;
+ }
+}
+
+function blockTransitions(node, duration) {
+ // we use a negative delay value since it performs blocking
+ // yet it doesn't kill any existing transitions running on the
+ // same element which makes this safe for class-based animations
+ var value = duration ? '-' + duration + 's' : '';
+ applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
+ return [TRANSITION_DELAY_PROP, value];
+}
+
+function blockKeyframeAnimations(node, applyBlock) {
+ var value = applyBlock ? 'paused' : '';
+ var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
+ applyInlineStyle(node, [key, value]);
+ return [key, value];
+}
+
+function applyInlineStyle(node, styleTuple) {
+ var prop = styleTuple[0];
+ var value = styleTuple[1];
+ node.style[prop] = value;
+}
+
+function concatWithSpace(a,b) {
+ if (!a) return b;
+ if (!b) return a;
+ return a + ' ' + b;
+}
+
+function $$BodyProvider() {
+ this.$get = ['$document', function($document) {
+ return jqLite($document[0].body);
+ }];
+}
+
var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
- var tickQueue = [];
- var cancelFn;
+ var queue, cancelFn;
function scheduler(tasks) {
// we make a copy since RAFScheduler mutates the state
// of the passed in array variable and this would be difficult
// to track down on the outside code
- tickQueue.push([].concat(tasks));
+ queue = queue.concat(tasks);
nextTick();
}
+ queue = scheduler.queue = [];
+
/* waitUntilQuiet does two things:
* 1. It will run the FINAL `fn` value only when an uncancelled RAF has passed through
* 2. It will delay the next wave of tasks from running until the quiet `fn` has run.
@@ -289,17 +413,12 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
return scheduler;
function nextTick() {
- if (!tickQueue.length) return;
+ if (!queue.length) return;
- var updatedQueue = [];
- for (var i = 0; i < tickQueue.length; i++) {
- var innerQueue = tickQueue[i];
- runNextTask(innerQueue);
- if (innerQueue.length) {
- updatedQueue.push(innerQueue);
- }
+ var items = queue.shift();
+ for (var i = 0; i < items.length; i++) {
+ items[i]();
}
- tickQueue = updatedQueue;
if (!cancelFn) {
$$rAF(function() {
@@ -307,11 +426,6 @@ var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
});
}
}
-
- function runNextTask(tasks) {
- var nextTask = tasks.shift();
- nextTask();
- }
}];
var $$AnimateChildrenDirective = [function() {
@@ -328,6 +442,8 @@ var $$AnimateChildrenDirective = [function() {
};
}];
+var ANIMATE_TIMER_KEY = '$$animateCss';
+
/**
* @ngdoc service
* @name $animateCss
@@ -514,7 +630,7 @@ var $$AnimateChildrenDirective = [function() {
* to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.)
* * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both).
* * `transition` - The raw CSS transition style that will be used (e.g. `1s linear all`).
- * * `keyframe` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
+ * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
* * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation.
* * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition.
* * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation.
@@ -528,63 +644,19 @@ var $$AnimateChildrenDirective = [function() {
* * `stagger` - A numeric time value representing the delay between successively animated elements
* ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.})
* * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a
- * `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.)
+ * * `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 {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.
*/
-
-// Detect proper transitionend/animationend event names.
-var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
-
-// If unprefixed events are not supported but webkit-prefixed are, use the latter.
-// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
-// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
-// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
-// Register both events in case `window.onanimationend` is not supported because of that,
-// do the same for `transitionend` as Safari is likely to exhibit similar behavior.
-// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
-// therefore there is no reason to test anymore for other vendor prefixes:
-// http://caniuse.com/#search=transition
-if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
- CSS_PREFIX = '-webkit-';
- TRANSITION_PROP = 'WebkitTransition';
- TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
-} else {
- TRANSITION_PROP = 'transition';
- TRANSITIONEND_EVENT = 'transitionend';
-}
-
-if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
- CSS_PREFIX = '-webkit-';
- ANIMATION_PROP = 'WebkitAnimation';
- ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
-} else {
- ANIMATION_PROP = 'animation';
- ANIMATIONEND_EVENT = 'animationend';
-}
-
-var DURATION_KEY = 'Duration';
-var PROPERTY_KEY = 'Property';
-var DELAY_KEY = 'Delay';
-var TIMING_KEY = 'TimingFunction';
-var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
-var ANIMATION_PLAYSTATE_KEY = 'PlayState';
-var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
-var CLOSING_TIME_BUFFER = 1.5;
var ONE_SECOND = 1000;
var BASE_TEN = 10;
-var SAFE_FAST_FORWARD_DURATION_VALUE = 9999;
-
-var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
-var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
-
-var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
-var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
+var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
+var CLOSING_TIME_BUFFER = 1.5;
var DETECT_CSS_PROPERTIES = {
transitionDuration: TRANSITION_DURATION_PROP,
@@ -602,6 +674,15 @@ var DETECT_STAGGER_CSS_PROPERTIES = {
animationDelay: ANIMATION_DELAY_PROP
};
+function getCssKeyframeDurationStyle(duration) {
+ return [ANIMATION_DURATION_PROP, duration + 's'];
+}
+
+function getCssDelayStyle(delay, isKeyframeAnimation) {
+ var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
+ return [prop, delay + 's'];
+}
+
function computeCssStyles($window, element, properties) {
var styles = Object.create(null);
var detectedStyles = $window.getComputedStyle(element) || {};
@@ -658,37 +739,6 @@ function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
return [style, value];
}
-function getCssKeyframeDurationStyle(duration) {
- return [ANIMATION_DURATION_PROP, duration + 's'];
-}
-
-function getCssDelayStyle(delay, isKeyframeAnimation) {
- var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
- return [prop, delay + 's'];
-}
-
-function blockTransitions(node, duration) {
- // we use a negative delay value since it performs blocking
- // yet it doesn't kill any existing transitions running on the
- // same element which makes this safe for class-based animations
- var value = duration ? '-' + duration + 's' : '';
- applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
- return [TRANSITION_DELAY_PROP, value];
-}
-
-function blockKeyframeAnimations(node, applyBlock) {
- var value = applyBlock ? 'paused' : '';
- var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
- applyInlineStyle(node, [key, value]);
- return [key, value];
-}
-
-function applyInlineStyle(node, styleTuple) {
- var prop = styleTuple[0];
- var value = styleTuple[1];
- node.style[prop] = value;
-}
-
function createLocalCacheLookup() {
var cache = Object.create(null);
return {
@@ -721,9 +771,9 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
var gcsStaggerLookup = createLocalCacheLookup();
this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout',
- '$document', '$sniffer', '$$rAFScheduler',
+ '$$forceReflow', '$sniffer', '$$rAFScheduler', '$animate',
function($window, $$jqLite, $$AnimateRunner, $timeout,
- $document, $sniffer, $$rAFScheduler) {
+ $$forceReflow, $sniffer, $$rAFScheduler, $animate) {
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
@@ -780,7 +830,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
return stagger || {};
}
- var bod = getDomNode($document).body;
+ var cancelLastRAFRequest;
var rafWaitQueue = [];
function waitUntilQuiet(callback) {
rafWaitQueue.push(callback);
@@ -788,27 +838,19 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
gcsLookup.flush();
gcsStaggerLookup.flush();
- //the line below will force the browser to perform a repaint so
- //that all the animated elements within the animation frame will
- //be properly updated and drawn on screen. This is required to
- //ensure that the preparation animation is properly flushed so that
- //the active state picks up from there. DO NOT REMOVE THIS LINE.
- //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
- //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
- //WILL TAKE YEARS AWAY FROM YOUR LIFE.
- var width = bod.offsetWidth + 1;
+ // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
+ // PLEASE EXAMINE THE `$$forceReflow` service to understand why.
+ var pageWidth = $$forceReflow();
// we use a for loop to ensure that if the queue is changed
// during this looping then it will consider new requests
for (var i = 0; i < rafWaitQueue.length; i++) {
- rafWaitQueue[i](width);
+ rafWaitQueue[i](pageWidth);
}
rafWaitQueue.length = 0;
});
}
- return init;
-
function computeTimings(node, className, cacheKey) {
var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES);
var aD = timings.animationDelay;
@@ -823,8 +865,14 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
return timings;
}
- function init(element, options) {
+ return function init(element, options) {
var node = getDomNode(element);
+ if (!node
+ || !node.parentNode
+ || !$animate.enabled()) {
+ return closeAndReturnNoopAnimator();
+ }
+
options = prepareAnimationOptions(options);
var temporaryStyles = [];
@@ -853,20 +901,20 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
var addRemoveClassName = '';
if (isStructural) {
- structuralClassName = pendClasses(method, 'ng-', true);
+ structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);
} else if (method) {
structuralClassName = method;
}
if (options.addClass) {
- addRemoveClassName += pendClasses(options.addClass, '-add');
+ addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);
}
if (options.removeClass) {
if (addRemoveClassName.length) {
addRemoveClassName += ' ';
}
- addRemoveClassName += pendClasses(options.removeClass, '-remove');
+ addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX);
}
// there may be a situation where a structural animation is combined together
@@ -877,17 +925,20 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
// there actually is a detected transition or keyframe animation
if (options.applyClassesEarly && addRemoveClassName.length) {
applyAnimationClasses(element, options);
- addRemoveClassName = '';
}
- var setupClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
- var fullClassName = classes + ' ' + setupClasses;
- var activeClasses = pendClasses(setupClasses, '-active');
+ var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
+ var fullClassName = classes + ' ' + preparationClasses;
+ var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
+ var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
- // 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) {
+ // there is no way we can trigger an animation if no styles and
+ // no classes are being applied which would then trigger a transition,
+ // unless there a is raw keyframe value that is applied to the element.
+ if (!containsKeyframeAnimation
+ && !hasToStyles
+ && !preparationClasses) {
return closeAndReturnNoopAnimator();
}
@@ -902,10 +953,12 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
};
} else {
cacheKey = gcsHashFn(node, fullClassName);
- stagger = computeCachedCssStaggerStyles(node, setupClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
+ stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
}
- $$jqLite.addClass(element, setupClasses);
+ if (!options.$$skipPreparationClasses) {
+ $$jqLite.addClass(element, preparationClasses);
+ }
var applyOnlyDuration;
@@ -944,7 +997,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
// transition delay to allow for the transition to naturally do it's thing. The beauty here is
// that if there is no transition defined then nothing will happen and this will also allow
// other transitions to be stacked on top of each other without any chopping them out.
- if (isFirst) {
+ if (isFirst && !options.skipBlocking) {
blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
}
@@ -986,6 +1039,18 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
return closeAndReturnNoopAnimator();
}
+ if (options.delay != null) {
+ var delayStyle = parseFloat(options.delay);
+
+ if (flags.applyTransitionDelay) {
+ temporaryStyles.push(getCssDelayStyle(delayStyle));
+ }
+
+ if (flags.applyAnimationDelay) {
+ temporaryStyles.push(getCssDelayStyle(delayStyle, true));
+ }
+ }
+
// we need to recalculate the delay value since we used a pre-emptive negative
// delay value and the delay value is required for the final event checking. This
// property will ensure that this will happen after the RAF phase has passed.
@@ -1003,12 +1068,13 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
}
applyAnimationFromStyles(element, options);
- if (!flags.blockTransition) {
+
+ if (flags.blockTransition || flags.blockKeyframeAnimation) {
+ applyBlocking(maxDuration);
+ } else if (!options.skipBlocking) {
blockTransitions(node, false);
}
- applyBlocking(maxDuration);
-
// TODO(matsko): for 1.5 change this code to have an animator object for better debugging
return {
$$willAnimate: true,
@@ -1050,7 +1116,9 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
animationClosed = true;
animationPaused = false;
- $$jqLite.removeClass(element, setupClasses);
+ if (!options.$$skipPreparationClasses) {
+ $$jqLite.removeClass(element, preparationClasses);
+ }
$$jqLite.removeClass(element, activeClasses);
blockKeyframeAnimations(node, false);
@@ -1097,6 +1165,8 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
cancel: cancelFn
});
+ // should flush the cache animation
+ waitUntilQuiet(noop);
close();
return {
@@ -1110,6 +1180,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
function start() {
if (animationClosed) return;
+ if (!node.parentNode) {
+ close();
+ return;
+ }
var startTime, events = [];
@@ -1173,7 +1247,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
$$jqLite.addClass(element, activeClasses);
if (flags.recalculateTimingStyles) {
- fullClassName = node.className + ' ' + setupClasses;
+ fullClassName = node.className + ' ' + preparationClasses;
cacheKey = gcsHashFn(node, fullClassName);
timings = computeTimings(node, fullClassName, cacheKey);
@@ -1190,27 +1264,16 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
flags.hasAnimations = timings.animationDuration > 0;
}
- if (flags.applyTransitionDelay || flags.applyAnimationDelay) {
+ if (flags.applyAnimationDelay) {
relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay)
? parseFloat(options.delay)
: relativeDelay;
maxDelay = Math.max(relativeDelay, 0);
-
- var delayStyle;
- if (flags.applyTransitionDelay) {
- timings.transitionDelay = relativeDelay;
- delayStyle = getCssDelayStyle(relativeDelay);
- temporaryStyles.push(delayStyle);
- node.style[delayStyle[0]] = delayStyle[1];
- }
-
- if (flags.applyAnimationDelay) {
- timings.animationDelay = relativeDelay;
- delayStyle = getCssDelayStyle(relativeDelay, true);
- temporaryStyles.push(delayStyle);
- node.style[delayStyle[0]] = delayStyle[1];
- }
+ timings.animationDelay = relativeDelay;
+ delayStyle = getCssDelayStyle(relativeDelay, true);
+ temporaryStyles.push(delayStyle);
+ node.style[delayStyle[0]] = delayStyle[1];
}
maxDelayTime = maxDelay * ONE_SECOND;
@@ -1239,17 +1302,47 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
}
startTime = Date.now();
- element.on(events.join(' '), onAnimationProgress);
- $timeout(onAnimationExpired, maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime);
+ var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;
+ var endTime = startTime + timerTime;
+ var animationsData = element.data(ANIMATE_TIMER_KEY) || [];
+ var setupFallbackTimer = true;
+ if (animationsData.length) {
+ var currentTimerData = animationsData[0];
+ setupFallbackTimer = endTime > currentTimerData.expectedEndTime;
+ if (setupFallbackTimer) {
+ $timeout.cancel(currentTimerData.timer);
+ } else {
+ animationsData.push(close);
+ }
+ }
+
+ if (setupFallbackTimer) {
+ var timer = $timeout(onAnimationExpired, timerTime, false);
+ animationsData[0] = {
+ timer: timer,
+ expectedEndTime: endTime
+ };
+ animationsData.push(close);
+ element.data(ANIMATE_TIMER_KEY, animationsData);
+ }
+
+ element.on(events.join(' '), onAnimationProgress);
applyAnimationToStyles(element, options);
}
function onAnimationExpired() {
- // although an expired animation is a failed animation, getting to
- // this outcome is very easy if the CSS code screws up. Therefore we
- // should still continue normally as if the animation completed correctly.
- close();
+ var animationsData = element.data(ANIMATE_TIMER_KEY);
+
+ // this will be false in the event that the element was
+ // removed from the DOM (via a leave animation or something
+ // similar)
+ if (animationsData) {
+ for (var i = 1; i < animationsData.length; i++) {
+ animationsData[i]();
+ }
+ element.removeData(ANIMATE_TIMER_KEY);
+ }
}
function onAnimationProgress(event) {
@@ -1276,7 +1369,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
}
}
}
- }
+ };
}];
}];
@@ -1289,17 +1382,19 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';
var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';
- this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$document', '$sniffer',
- function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $document, $sniffer) {
+ this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$$body', '$sniffer', '$$jqLite',
+ function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $$body, $sniffer, $$jqLite) {
// only browsers that support these properties can render animations
if (!$sniffer.animations && !$sniffer.transitions) return noop;
- var bodyNode = getDomNode($document).body;
+ var bodyNode = getDomNode($$body);
var rootNode = getDomNode($rootElement);
var rootBodyElement = jqLite(bodyNode.parentNode === rootNode ? bodyNode : rootNode);
+ var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
+
return function initDriverFn(animationDetails) {
return animationDetails.from && animationDetails.to
? prepareFromToAnchorAnimation(animationDetails.from,
@@ -1450,8 +1545,8 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
}
function prepareFromToAnchorAnimation(from, to, classes, anchors) {
- var fromAnimation = prepareRegularAnimation(from);
- var toAnimation = prepareRegularAnimation(to);
+ var fromAnimation = prepareRegularAnimation(from, noop);
+ var toAnimation = prepareRegularAnimation(to, noop);
var anchorAnimations = [];
forEach(anchors, function(anchor) {
@@ -1507,19 +1602,23 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
var options = animationDetails.options || {};
if (animationDetails.structural) {
- // structural animations ensure that the CSS classes are always applied
- // before the detection starts.
- options.structural = options.applyClassesEarly = true;
+ options.event = animationDetails.event;
+ options.structural = true;
+ options.applyClassesEarly = true;
// we special case the leave animation since we want to ensure that
// the element is removed as soon as the animation is over. Otherwise
// a flicker might appear or the element may not be removed at all
- options.event = animationDetails.event;
- if (options.event === 'leave') {
+ if (animationDetails.event === 'leave') {
options.onDone = options.domOperation;
}
- } else {
- options.event = null;
+ }
+
+ // We assign the preparationClasses as the actual animation event since
+ // the internals of $animateCss will just suffix the event token values
+ // with `-active` to trigger the animation.
+ if (options.preparationClasses) {
+ options.event = concatWithSpace(options.event, options.preparationClasses);
}
var animator = $animateCss(element, options);
@@ -1538,8 +1637,8 @@ var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationPro
// by the time...
var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
- this.$get = ['$injector', '$$AnimateRunner', '$$rAFMutex', '$$jqLite',
- function($injector, $$AnimateRunner, $$rAFMutex, $$jqLite) {
+ this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',
+ function($injector, $$AnimateRunner, $$jqLite) {
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
// $animateJs(element, 'enter');
@@ -1896,8 +1995,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
});
rules.skip.push(function(element, newAnimation, currentAnimation) {
- // if there is a current animation then skip the class-based animation
- return currentAnimation.structural && !newAnimation.structural;
+ // if there is an ongoing current animation then don't even bother running the class-based animation
+ return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;
});
rules.cancel.push(function(element, newAnimation, currentAnimation) {
@@ -1919,14 +2018,13 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
return (nO.addClass && nO.addClass === cO.removeClass) || (nO.removeClass && nO.removeClass === cO.addClass);
});
- this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
- '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite',
- function($$rAF, $rootScope, $rootElement, $document, $$HashMap,
- $$animation, $$AnimateRunner, $templateRequest, $$jqLite) {
+ this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$body', '$$HashMap',
+ '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',
+ function($$rAF, $rootScope, $rootElement, $document, $$body, $$HashMap,
+ $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow) {
var activeAnimationsLookup = new $$HashMap();
var disabledElementsLookup = new $$HashMap();
-
var animationsEnabled = null;
// Wait until all directive and route-related templates are downloaded and
@@ -1958,8 +2056,6 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
}
);
- var bodyElement = jqLite($document[0].body);
-
var callbackRegistry = {};
// remember that the classNameFilter is set during the provider/config
@@ -2095,22 +2191,22 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
// These methods will become available after the digest has passed
var runner = new $$AnimateRunner();
- // there are situations where a directive issues an animation for
- // a jqLite wrapper that contains only comment nodes... If this
- // happens then there is no way we can perform an animation
- if (!node) {
- close();
- return runner;
- }
-
if (isArray(options.addClass)) {
options.addClass = options.addClass.join(' ');
}
+ if (options.addClass && !isString(options.addClass)) {
+ options.addClass = null;
+ }
+
if (isArray(options.removeClass)) {
options.removeClass = options.removeClass.join(' ');
}
+ if (options.removeClass && !isString(options.removeClass)) {
+ options.removeClass = null;
+ }
+
if (options.from && !isObject(options.from)) {
options.from = null;
}
@@ -2119,6 +2215,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
options.to = null;
}
+ // there are situations where a directive issues an animation for
+ // a jqLite wrapper that contains only comment nodes... If this
+ // happens then there is no way we can perform an animation
+ if (!node) {
+ close();
+ return runner;
+ }
+
var className = [node.className, options.addClass, options.removeClass].join(' ');
if (!isAnimatableClassName(className)) {
close();
@@ -2183,8 +2287,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
// method which will call the runner methods in async.
existingAnimation.close();
} else {
- // this will merge the existing animation options into this new follow-up animation
- mergeAnimationOptions(element, newAnimation.options, existingAnimation.options);
+ // this will merge the new animation options into existing animation options
+ mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
+ return existingAnimation.runner;
}
} else {
// a joined animation means that this animation will take over the existing one
@@ -2195,9 +2300,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
if (existingAnimation.state === RUNNING_STATE) {
normalizeAnimationOptions(element, options);
} else {
+ applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
+
event = newAnimation.event = existingAnimation.event;
options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
- return runner;
+
+ //we return the same runner since only the option values of this animation will
+ //be fed into the `existingAnimation`.
+ return existingAnimation.runner;
}
}
}
@@ -2223,10 +2333,6 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
return runner;
}
- if (isStructural) {
- closeParentClassBasedAnimations(parent);
- }
-
// the counter keeps track of cancelled animations
var counter = (existingAnimation.counter || 0) + 1;
newAnimation.counter = counter;
@@ -2284,12 +2390,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
? 'setClass'
: animationDetails.event;
- if (animationDetails.structural) {
- closeParentClassBasedAnimations(parentElement);
- }
-
markElementAnimationState(element, RUNNING_STATE);
var realRunner = $$animation(element, event, animationDetails.options);
+
realRunner.done(function(status) {
close(!status);
var animationDetails = activeAnimationsLookup.get(node);
@@ -2313,6 +2416,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
}
function close(reject) { // jshint ignore:line
+ clearGeneratedClasses(element, options);
applyAnimationClasses(element, options);
applyAnimationStyles(element, options);
options.domOperation();
@@ -2349,36 +2453,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
}
- function closeParentClassBasedAnimations(startingElement) {
- var parentNode = getDomNode(startingElement);
- do {
- if (!parentNode || parentNode.nodeType !== ELEMENT_NODE) break;
-
- var animationDetails = activeAnimationsLookup.get(parentNode);
- if (animationDetails) {
- examineParentAnimation(parentNode, animationDetails);
- }
-
- parentNode = parentNode.parentNode;
- } while (true);
-
- // since animations are detected from CSS classes, we need to flush all parent
- // class-based animations so that the parent classes are all present for child
- // animations to properly function (otherwise any CSS selectors may not work)
- function examineParentAnimation(node, animationDetails) {
- // enter/leave/move always have priority
- if (animationDetails.structural || !hasAnimationClasses(animationDetails.options)) return;
-
- if (animationDetails.state === RUNNING_STATE) {
- animationDetails.runner.end();
- }
- clearElementAnimationState(node);
- }
- }
-
function areAnimationsAllowed(element, parentElement, event) {
- var bodyElementDetected = false;
- var rootElementDetected = false;
+ var bodyElementDetected = isMatchingElement(element, $$body) || element[0].nodeName === 'HTML';
+ var rootElementDetected = isMatchingElement(element, $rootElement);
var parentAnimationDetected = false;
var animateChildren;
@@ -2433,7 +2510,7 @@ 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(parentElement, bodyElement);
+ bodyElementDetected = isMatchingElement(parentElement, $$body);
}
parentElement = parentElement.parent();
@@ -2459,19 +2536,34 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
}];
}];
-var $$rAFMutexFactory = ['$$rAF', function($$rAF) {
+var $$AnimateAsyncRunFactory = ['$$rAF', function($$rAF) {
+ var waitQueue = [];
+
+ function waitForTick(fn) {
+ waitQueue.push(fn);
+ if (waitQueue.length > 1) return;
+ $$rAF(function() {
+ for (var i = 0; i < waitQueue.length; i++) {
+ waitQueue[i]();
+ }
+ waitQueue = [];
+ });
+ }
+
return function() {
var passed = false;
- $$rAF(function() {
+ waitForTick(function() {
passed = true;
});
- return function(fn) {
- passed ? fn() : $$rAF(fn);
+ return function(callback) {
+ passed ? callback() : waitForTick(callback);
};
};
}];
-var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) {
+var $$AnimateRunnerFactory = ['$q', '$sniffer', '$$animateAsyncRun',
+ function($q, $sniffer, $$animateAsyncRun) {
+
var INITIAL_STATE = 0;
var DONE_PENDING_STATE = 1;
var DONE_COMPLETE_STATE = 2;
@@ -2516,7 +2608,7 @@ var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) {
this.setHost(host);
this._doneCallbacks = [];
- this._runInAnimationFrame = $$rAFMutex();
+ this._runInAnimationFrame = $$animateAsyncRun();
this._state = 0;
}
@@ -2628,15 +2720,93 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
return element.data(RUNNER_STORAGE_KEY);
}
- this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$rAFScheduler',
- function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$rAFScheduler) {
+ this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler',
+ function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$HashMap, $$rAFScheduler) {
var animationQueue = [];
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
- var totalPendingClassBasedAnimations = 0;
- var totalActiveClassBasedAnimations = 0;
- var classBasedAnimationsQueue = [];
+ function sortAnimations(animations) {
+ var tree = { children: [] };
+ var i, lookup = new $$HashMap();
+
+ // this is done first beforehand so that the hashmap
+ // is filled with a list of the elements that will be animated
+ for (i = 0; i < animations.length; i++) {
+ var animation = animations[i];
+ lookup.put(animation.domNode, animations[i] = {
+ domNode: animation.domNode,
+ fn: animation.fn,
+ children: []
+ });
+ }
+
+ for (i = 0; i < animations.length; i++) {
+ processNode(animations[i]);
+ }
+
+ return flatten(tree);
+
+ function processNode(entry) {
+ if (entry.processed) return entry;
+ entry.processed = true;
+
+ var elementNode = entry.domNode;
+ var parentNode = elementNode.parentNode;
+ lookup.put(elementNode, entry);
+
+ var parentEntry;
+ while (parentNode) {
+ parentEntry = lookup.get(parentNode);
+ if (parentEntry) {
+ if (!parentEntry.processed) {
+ parentEntry = processNode(parentEntry);
+ }
+ break;
+ }
+ parentNode = parentNode.parentNode;
+ }
+
+ (parentEntry || tree).children.push(entry);
+ return entry;
+ }
+
+ function flatten(tree) {
+ var result = [];
+ var queue = [];
+ var i;
+
+ for (i = 0; i < tree.children.length; i++) {
+ queue.push(tree.children[i]);
+ }
+
+ var remainingLevelEntries = queue.length;
+ var nextLevelEntries = 0;
+ var row = [];
+
+ for (i = 0; i < queue.length; i++) {
+ var entry = queue[i];
+ if (remainingLevelEntries <= 0) {
+ remainingLevelEntries = nextLevelEntries;
+ nextLevelEntries = 0;
+ result.push(row);
+ row = [];
+ }
+ row.push(entry.fn);
+ entry.children.forEach(function(childEntry) {
+ nextLevelEntries++;
+ queue.push(childEntry);
+ });
+ remainingLevelEntries--;
+ }
+
+ if (row.length) {
+ result.push(row);
+ }
+
+ return result;
+ }
+ }
// TODO(matsko): document the signature in a better way
return function(element, event, options) {
@@ -2666,19 +2836,12 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
options.tempClasses = null;
}
- var classBasedIndex;
- if (!isStructural) {
- classBasedIndex = totalPendingClassBasedAnimations;
- totalPendingClassBasedAnimations += 1;
- }
-
animationQueue.push({
// this data is used by the postDigest code and passed into
// the driver step function
element: element,
classes: classes,
event: event,
- classBasedIndex: classBasedIndex,
structural: isStructural,
options: options,
beforeStart: beforeStart,
@@ -2693,10 +2856,6 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
if (animationQueue.length > 1) return runner;
$rootScope.$$postDigest(function() {
- totalActiveClassBasedAnimations = totalPendingClassBasedAnimations;
- totalPendingClassBasedAnimations = 0;
- classBasedAnimationsQueue.length = 0;
-
var animations = [];
forEach(animationQueue, function(entry) {
// the element was destroyed early on which removed the runner
@@ -2704,67 +2863,58 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
// at all and it already has been closed due to destruction.
if (getRunner(entry.element)) {
animations.push(entry);
+ } else {
+ entry.close();
}
});
// now any future animations will be in another postDigest
animationQueue.length = 0;
- forEach(groupAnimations(animations), function(animationEntry) {
- if (animationEntry.structural) {
- triggerAnimationStart();
- } else {
- classBasedAnimationsQueue.push({
- node: getDomNode(animationEntry.element),
- fn: triggerAnimationStart
- });
+ var groupedAnimations = groupAnimations(animations);
+ var toBeSortedAnimations = [];
- if (animationEntry.classBasedIndex === totalActiveClassBasedAnimations - 1) {
- // we need to sort each of the animations in order of parent to child
- // relationships. This ensures that the child classes are applied at the
- // right time.
- classBasedAnimationsQueue = classBasedAnimationsQueue.sort(function(a,b) {
- return b.node.contains(a.node);
- }).map(function(entry) {
- return entry.fn;
- });
+ forEach(groupedAnimations, function(animationEntry) {
+ toBeSortedAnimations.push({
+ domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element),
+ fn: function triggerAnimationStart() {
+ // it's important that we apply the `ng-animate` CSS class and the
+ // temporary classes before we do any driver invoking since these
+ // CSS classes may be required for proper CSS detection.
+ animationEntry.beforeStart();
- $$rAFScheduler(classBasedAnimationsQueue);
- }
- }
+ var startAnimationFn, closeFn = animationEntry.close;
- function triggerAnimationStart() {
- // it's important that we apply the `ng-animate` CSS class and the
- // temporary classes before we do any driver invoking since these
- // CSS classes may be required for proper CSS detection.
- animationEntry.beforeStart();
+ // in the event that the element was removed before the digest runs or
+ // during the RAF sequencing then we should not trigger the animation.
+ var targetElement = animationEntry.anchors
+ ? (animationEntry.from.element || animationEntry.to.element)
+ : animationEntry.element;
- var startAnimationFn, closeFn = animationEntry.close;
+ if (getRunner(targetElement)) {
+ var operation = invokeFirstDriver(animationEntry);
+ if (operation) {
+ startAnimationFn = operation.start;
+ }
+ }
- // in the event that the element was removed before the digest runs or
- // during the RAF sequencing then we should not trigger the animation.
- var targetElement = animationEntry.anchors
- ? (animationEntry.from.element || animationEntry.to.element)
- : animationEntry.element;
-
- if (getRunner(targetElement)) {
- var operation = invokeFirstDriver(animationEntry);
- if (operation) {
- startAnimationFn = operation.start;
+ if (!startAnimationFn) {
+ closeFn();
+ } else {
+ var animationRunner = startAnimationFn();
+ animationRunner.done(function(status) {
+ closeFn(!status);
+ });
+ updateAnimationRunners(animationEntry, animationRunner);
}
}
-
- if (!startAnimationFn) {
- closeFn();
- } else {
- var animationRunner = startAnimationFn();
- animationRunner.done(function(status) {
- closeFn(!status);
- });
- updateAnimationRunners(animationEntry, animationRunner);
- }
- }
+ });
});
+
+ // we need to sort each of the animations in order of parent to child
+ // relationships. This ensures that the child classes are applied at the
+ // right time.
+ $$rAFScheduler(sortAnimations(toBeSortedAnimations));
});
return runner;
@@ -2951,7 +3101,8 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
/* global angularAnimateModule: true,
- $$rAFMutexFactory,
+ $$BodyProvider,
+ $$AnimateAsyncRunFactory,
$$rAFSchedulerFactory,
$$AnimateChildrenDirective,
$$AnimateRunnerFactory,
@@ -2969,7 +3120,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
* @description
*
* The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via
- * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` then the animation hooks are enabled for an Angular app.
+ * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an Angular app.
*
*
*
@@ -3002,7 +3153,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
* CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML
* and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation.
*
- * The example below shows how an `enter` animation can be made possible on a element using `ng-if`:
+ * The example below shows how an `enter` animation can be made possible on an element using `ng-if`:
*
* ```html
*
@@ -3137,8 +3288,8 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
* /* this will have a 100ms delay between each successive leave animation */
* transition-delay: 0.1s;
*
- * /* in case the stagger doesn't work then the duration value
- * must be set to 0 to avoid an accidental CSS inheritance */
+ * /* As of 1.4.4, this must always be set: it signals ngAnimate
+ * to not accidentally inherit a delay property from another CSS class */
* transition-duration: 0s;
* }
* .my-animation.ng-enter.ng-enter-active {
@@ -3336,6 +3487,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
* enter: function(element, doneFn) {
* var runner = $animateCss(element, {
* event: 'enter',
+ * structural: true,
* addClass: 'maroon-setting',
* from: { height:0 },
* to: { height: 200 }
@@ -3686,15 +3838,16 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
* @description
* The ngAnimate `$animate` service documentation is the same for the core `$animate` service.
*
- * Click here {@link ng.$animate $animate to learn more about animations with `$animate`}.
+ * Click here {@link ng.$animate to learn more about animations with `$animate`}.
*/
angular.module('ngAnimate', [])
- .directive('ngAnimateChildren', $$AnimateChildrenDirective)
+ .provider('$$body', $$BodyProvider)
- .factory('$$rAFMutex', $$rAFMutexFactory)
+ .directive('ngAnimateChildren', $$AnimateChildrenDirective)
.factory('$$rAFScheduler', $$rAFSchedulerFactory)
.factory('$$AnimateRunner', $$AnimateRunnerFactory)
+ .factory('$$animateAsyncRun', $$AnimateAsyncRunFactory)
.provider('$$animateQueue', $$AnimateQueueProvider)
.provider('$$animation', $$AnimationProvider)
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.min.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.min.js
index eab2d76f3..71ae4d932 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.min.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-animate.min.js
@@ -1,52 +1,56 @@
/*
- AngularJS v1.4.2
+ AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
-(function(F,t,W){'use strict';function ua(a,b,c){if(!a)throw ngMinErr("areq",b||"?",c||"required");return a}function va(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;X(a)&&(a=a.join(" "));X(b)&&(b=b.join(" "));return a+" "+b}function Ea(a){var b={};a&&(a.to||a.from)&&(b.to=a.to,b.from=a.from);return b}function ba(a,b,c){var d="";a=X(a)?a:a&&U(a)&&a.length?a.split(/\s+/):[];u(a,function(a,s){a&&0=F&&b>=J&&(C=!0,h())}if(!K){var x,p=[],l=function(a){if(C)D&&a&&(D=!1,h());else if(D=!a,y.animationDuration)if(a=ma(k,D),D)m.push(a);else{var b=m,c=b.indexOf(a);0<=a&&b.splice(c,1)}},r=0<
-U&&(y.transitionDuration&&0===T.transitionDuration||y.animationDuration&&0===T.animationDuration)&&Math.max(T.animationDelay,T.transitionDelay);r?n(b,Math.floor(r*U*1E3),!1):b();t.resume=function(){l(!0)};t.pause=function(){l(!1)}}}var k=A(a);c=ia(c);var m=[],r=a.attr("class"),v=Ea(c),K,D,C,p,t,H,F,J,G;if(0===c.duration||!l.animations&&!l.transitions)return x();var aa=c.event&&X(c.event)?c.event.join(" "):c.event,R="",N="";aa&&c.structural?R=ba(aa,"ng-",!0):aa&&(R=aa);c.addClass&&(N+=ba(c.addClass,
-"-add"));c.removeClass&&(N.length&&(N+=" "),N+=ba(c.removeClass,"-remove"));c.applyClassesEarly&&N.length&&(B(a,c),N="");var Y=[R,N].join(" ").trim(),fa=r+" "+Y,W=ba(Y,"-active"),r=v.to&&0=a&&(a=h,h=0,b.push(e),e=[]);e.push(l.fn);
+l.children.forEach(function(a){h++;c.push(a)});a--}e.length&&b.push(e);return b}(c)}var O=[],x=Q(a);return function(t,z,E){function h(a){a=a.hasAttribute("ng-animate-ref")?[a]:a.querySelectorAll("[ng-animate-ref]");var b=[];q(a,function(a){var c=a.getAttribute("ng-animate-ref");c&&c.length&&b.push(a)});return b}function S(a){var b=[],c={};q(a,function(a,g){var d=G(a.element),f=0<=["enter","move"].indexOf(a.event),d=a.structural?h(d):[];if(d.length){var e=f?"to":"from";q(d,function(a){var b=a.getAttribute("ng-animate-ref");
+c[b]=c[b]||{};c[b][e]={animationID:g,element:I(a)}})}else b.push(a)});var d={},f={};q(c,function(c,e){var h=c.from,r=c.to;if(h&&r){var J=a[h.animationID],k=a[r.animationID],B=h.animationID.toString();if(!f[B]){var l=f[B]={structural:!0,beforeStart:function(){J.beforeStart();k.beforeStart()},close:function(){J.close();k.close()},classes:u(J.classes,k.classes),from:J,to:k,anchors:[]};l.classes.length?b.push(l):(b.push(J),b.push(k))}f[B].anchors.push({out:h.element,"in":r.element})}else h=h?h.animationID:
+r.animationID,r=h.toString(),d[r]||(d[r]=!0,b.push(a[h]))});return b}function u(a,b){a=a.split(" ");b=b.split(" ");for(var c=[],d=0;dC.expectedEndTime)?v.cancel(C.timer):p.push(r)}z&&(u=v(d,u,!1),p[0]={timer:u,expectedEndTime:k},p.push(r),a.data("$$animateCss",p));a.on(m.join(" "),l);xa(a,c)}}
+function d(){var b=a.data("$$animateCss");if(b){for(var c=1;c=M&&b>=K&&(S=!0,r())}if(!s)if(g.parentNode){var H,m=[],k=function(a){if(S)z&&a&&(z=!1,r());else if(z=!a,D.animationDuration)if(a=na(g,z),z)w.push(a);else{var b=w,c=b.indexOf(a);0<=a&&b.splice(c,1)}},p=0` tag will be used as path.
- * This is import so that cookies will be visible for all routes in case html5mode is enabled
+ * This is important so that cookies will be visible for all routes in case html5mode is enabled
*
**/
var defaults = this.defaults = {};
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-cookies.min.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-cookies.min.js
index aaab5e52a..181624cf0 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-cookies.min.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-cookies.min.js
@@ -1,5 +1,5 @@
/*
- AngularJS v1.4.2
+ AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.js
index eb3fd576d..092d894ce 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.js
@@ -1,10 +1,11 @@
/**
- * @license AngularJS v1.4.2
+ * @license AngularJS v1.4.5
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
(function() {'use strict';
+ function isFunction(value) {return typeof value === 'function';};
/**
* @description
@@ -58,7 +59,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message += '\nhttp://errors.angularjs.org/1.4.2/' +
+ message += '\nhttp://errors.angularjs.org/1.4.5/' +
(module ? module + '/' : '') + code;
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -108,8 +109,8 @@ function setupModuleLoader(window) {
* All modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
- * When passed two or more arguments, a new module is created. If passed only one argument, an
- * existing module (the name passed as the first argument to `module`) is retrieved.
+ * Passing one argument retrieves an existing {@link angular.Module},
+ * whereas passing more than one argument creates a new {@link angular.Module}
*
*
* # Module
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.min.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.min.js
index 47fe937eb..8a318554f 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.min.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-loader.min.js
@@ -1,9 +1,10 @@
/*
- AngularJS v1.4.2
+ AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
-(function(){'use strict';function d(b){return function(){var a=arguments[0],e;e="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.4.2/"+(b?b+"/":"")+a;for(a=1;a"”’]/i,
+ /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
MAILTO_REGEXP = /^mailto:/i;
return function(text, target) {
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-sanitize.min.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-sanitize.min.js
index eeb72f257..4404fea84 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-sanitize.min.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-sanitize.min.js
@@ -1,5 +1,5 @@
/*
- AngularJS v1.4.2
+ AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-scenario.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-scenario.js
index 6b13ea614..ce24ace63 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-scenario.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-scenario.js
@@ -9190,7 +9190,7 @@ return jQuery;
}));
/**
- * @license AngularJS v1.4.2
+ * @license AngularJS v1.4.5
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -9249,7 +9249,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message += '\nhttp://errors.angularjs.org/1.4.2/' +
+ message += '\nhttp://errors.angularjs.org/1.4.5/' +
(module ? module + '/' : '') + code;
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -9615,6 +9615,8 @@ function baseExtend(dst, objs, deep) {
if (deep && isObject(src)) {
if (isDate(src)) {
dst[key] = new Date(src.valueOf());
+ } else if (isRegExp(src)) {
+ dst[key] = new RegExp(src);
} else {
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
baseExtend(dst[key], [src], true);
@@ -10245,22 +10247,39 @@ function equals(o1, o2) {
}
var csp = function() {
- if (isDefined(csp.isActive_)) return csp.isActive_;
+ if (!isDefined(csp.rules)) {
- var active = !!(document.querySelector('[ng-csp]') ||
- document.querySelector('[data-ng-csp]'));
- if (!active) {
+ var ngCspElement = (document.querySelector('[ng-csp]') ||
+ document.querySelector('[data-ng-csp]'));
+
+ if (ngCspElement) {
+ var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
+ ngCspElement.getAttribute('data-ng-csp');
+ csp.rules = {
+ noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
+ noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
+ };
+ } else {
+ csp.rules = {
+ noUnsafeEval: noUnsafeEval(),
+ noInlineStyle: false
+ };
+ }
+ }
+
+ return csp.rules;
+
+ function noUnsafeEval() {
try {
/* jshint -W031, -W054 */
new Function('');
/* jshint +W031, +W054 */
+ return false;
} catch (e) {
- active = true;
+ return true;
}
}
-
- return (csp.isActive_ = active);
};
/**
@@ -10492,13 +10511,19 @@ function tryDecodeURIComponent(value) {
* @returns {Object.}
*/
function parseKeyValue(/**string*/keyValue) {
- var obj = {}, key_value, key;
+ var obj = {};
forEach((keyValue || "").split('&'), function(keyValue) {
+ var splitPoint, key, val;
if (keyValue) {
- key_value = keyValue.replace(/\+/g,'%20').split('=');
- key = tryDecodeURIComponent(key_value[0]);
+ key = keyValue = keyValue.replace(/\+/g,'%20');
+ splitPoint = keyValue.indexOf('=');
+ if (splitPoint !== -1) {
+ key = keyValue.substring(0, splitPoint);
+ val = keyValue.substring(splitPoint + 1);
+ }
+ key = tryDecodeURIComponent(key);
if (isDefined(key)) {
- var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ val = isDefined(val) ? tryDecodeURIComponent(val) : true;
if (!hasOwnProperty.call(obj, key)) {
obj[key] = val;
} else if (isArray(obj[key])) {
@@ -11094,8 +11119,8 @@ function setupModuleLoader(window) {
* All modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
- * When passed two or more arguments, a new module is created. If passed only one argument, an
- * existing module (the name passed as the first argument to `module`) is retrieved.
+ * Passing one argument retrieves an existing {@link angular.Module},
+ * whereas passing more than one argument creates a new {@link angular.Module}
*
*
* # Module
@@ -11436,7 +11461,6 @@ function toDebugString(obj) {
/* global angularModule: true,
version: true,
- $LocaleProvider,
$CompileProvider,
htmlAnchorDirective,
@@ -11453,7 +11477,6 @@ function toDebugString(obj) {
ngClassDirective,
ngClassEvenDirective,
ngClassOddDirective,
- ngCspDirective,
ngCloakDirective,
ngControllerDirective,
ngFormDirective,
@@ -11490,6 +11513,7 @@ function toDebugString(obj) {
$AnchorScrollProvider,
$AnimateProvider,
+ $CoreAnimateCssProvider,
$$CoreAnimateQueueProvider,
$$CoreAnimateRunnerProvider,
$BrowserProvider,
@@ -11498,6 +11522,7 @@ function toDebugString(obj) {
$DocumentProvider,
$ExceptionHandlerProvider,
$FilterProvider,
+ $$ForceReflowProvider,
$InterpolateProvider,
$IntervalProvider,
$$HashMapProvider,
@@ -11520,7 +11545,6 @@ function toDebugString(obj) {
$$TestabilityProvider,
$TimeoutProvider,
$$RAFProvider,
- $$AsyncCallbackProvider,
$WindowProvider,
$$jqLiteProvider,
$$CookieReaderProvider
@@ -11542,11 +11566,11 @@ function toDebugString(obj) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.4.2', // all of these placeholder strings will be replaced by grunt's
+ full: '1.4.5', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 4,
- dot: 2,
- codeName: 'nebular-readjustment'
+ dot: 5,
+ codeName: 'permanent-internship'
};
@@ -11585,11 +11609,6 @@ function publishExternalAPI(angular) {
});
angularModule = setupModuleLoader(window);
- try {
- angularModule('ngLocale');
- } catch (e) {
- angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
- }
angularModule('ng', ['ngLocale'], ['$provide',
function ngModule($provide) {
@@ -11652,6 +11671,7 @@ function publishExternalAPI(angular) {
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
$animate: $AnimateProvider,
+ $animateCss: $CoreAnimateCssProvider,
$$animateQueue: $$CoreAnimateQueueProvider,
$$AnimateRunner: $$CoreAnimateRunnerProvider,
$browser: $BrowserProvider,
@@ -11660,6 +11680,7 @@ function publishExternalAPI(angular) {
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
+ $$forceReflow: $$ForceReflowProvider,
$interpolate: $InterpolateProvider,
$interval: $IntervalProvider,
$http: $HttpProvider,
@@ -11681,7 +11702,6 @@ function publishExternalAPI(angular) {
$timeout: $TimeoutProvider,
$window: $WindowProvider,
$$rAF: $$RAFProvider,
- $$asyncCallback: $$AsyncCallbackProvider,
$$jqLite: $$jqLiteProvider,
$$HashMap: $$HashMapProvider,
$$cookieReader: $$CookieReaderProvider
@@ -11755,7 +11775,7 @@ function publishExternalAPI(angular) {
* - [`html()`](http://api.jquery.com/html/)
* - [`next()`](http://api.jquery.com/next/) - Does not support selectors
* - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
- * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
+ * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
* - [`prepend()`](http://api.jquery.com/prepend/)
@@ -11769,7 +11789,7 @@ function publishExternalAPI(angular) {
* - [`text()`](http://api.jquery.com/text/)
* - [`toggleClass()`](http://api.jquery.com/toggleClass/)
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
- * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
+ * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces or event object as parameter
* - [`val()`](http://api.jquery.com/val/)
* - [`wrap()`](http://api.jquery.com/wrap/)
*
@@ -12880,7 +12900,7 @@ var $$HashMapProvider = [function() {
* Implicit module which gets automatically added to each {@link auto.$injector $injector}.
*/
-var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
+var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
@@ -13536,6 +13556,7 @@ function createInjector(modulesToLoad, strictDi) {
// Module Loading
////////////////////////////////////
function loadModules(modulesToLoad) {
+ assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
var runBlocks = [], moduleFn;
forEach(modulesToLoad, function(module) {
if (loadedModules.get(module)) return;
@@ -14045,31 +14066,31 @@ var $$CoreAnimateQueueProvider = function() {
};
function addRemoveClassesPostDigest(element, add, remove) {
- var data = postDigestQueue.get(element);
- var classVal;
+ var classVal, data = postDigestQueue.get(element);
if (!data) {
postDigestQueue.put(element, data = {});
postDigestElements.push(element);
}
- if (add) {
- forEach(add.split(' '), function(className) {
- if (className) {
- data[className] = true;
- }
- });
- }
+ var updateData = function(classes, value) {
+ var changed = false;
+ if (classes) {
+ classes = isString(classes) ? classes.split(' ') :
+ isArray(classes) ? classes : [];
+ forEach(classes, function(className) {
+ if (className) {
+ changed = true;
+ data[className] = value;
+ }
+ });
+ }
+ return changed;
+ };
- if (remove) {
- forEach(remove.split(' '), function(className) {
- if (className) {
- data[className] = false;
- }
- });
- }
-
- if (postDigestElements.length > 1) return;
+ var classesAdded = updateData(add, true);
+ var classesRemoved = updateData(remove, false);
+ if ((!classesAdded && !classesRemoved) || postDigestElements.length > 1) return;
$rootScope.$$postDigest(function() {
forEach(postDigestElements, function(element) {
@@ -14528,15 +14549,88 @@ var $AnimateProvider = ['$provide', function($provide) {
}];
}];
-function $$AsyncCallbackProvider() {
- this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
- return $$rAF.supported
- ? function(fn) { return $$rAF(fn); }
- : function(fn) {
- return $timeout(fn, 0, false);
+/**
+ * @ngdoc service
+ * @name $animateCss
+ * @kind object
+ *
+ * @description
+ * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,
+ * then the `$animateCss` service will actually perform animations.
+ *
+ * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.
+ */
+var $CoreAnimateCssProvider = function() {
+ this.$get = ['$$rAF', '$q', function($$rAF, $q) {
+
+ var RAFPromise = function() {};
+ RAFPromise.prototype = {
+ done: function(cancel) {
+ this.defer && this.defer[cancel === true ? 'reject' : 'resolve']();
+ },
+ end: function() {
+ this.done();
+ },
+ cancel: function() {
+ this.done(true);
+ },
+ getPromise: function() {
+ if (!this.defer) {
+ this.defer = $q.defer();
+ }
+ return this.defer.promise;
+ },
+ then: function(f1,f2) {
+ return this.getPromise().then(f1,f2);
+ },
+ 'catch': function(f1) {
+ return this.getPromise()['catch'](f1);
+ },
+ 'finally': function(f1) {
+ return this.getPromise()['finally'](f1);
+ }
+ };
+
+ return function(element, options) {
+ if (options.from) {
+ element.css(options.from);
+ options.from = null;
+ }
+
+ var closed, runner = new RAFPromise();
+ return {
+ start: run,
+ end: run
};
+
+ function run() {
+ $$rAF(function() {
+ close();
+ if (!closed) {
+ runner.done();
+ }
+ closed = true;
+ });
+ return runner;
+ }
+
+ function close() {
+ if (options.addClass) {
+ element.addClass(options.addClass);
+ options.addClass = null;
+ }
+ if (options.removeClass) {
+ element.removeClass(options.removeClass);
+ options.removeClass = null;
+ }
+ if (options.to) {
+ element.css(options.to);
+ options.to = null;
+ }
+ }
+ };
}];
-}
+};
/* global stripHash: true */
@@ -15700,7 +15794,7 @@ function $TemplateCacheProvider() {
* otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
*
* Note that you can also require the directive's own controller - it will be made available like
- * like any other controller.
+ * any other controller.
*
* * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
* This is the same as the `$transclude`
@@ -15726,7 +15820,7 @@ function $TemplateCacheProvider() {
*
* ### Transclusion
*
- * Transclusion is the process of extracting a collection of DOM element from one part of the DOM and
+ * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
* copying them to another part of the DOM, while maintaining their connection to the original AngularJS
* scope from where they were taken.
*
@@ -16481,7 +16575,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
listeners.push(fn);
$rootScope.$evalAsync(function() {
- if (!listeners.$$inter && attrs.hasOwnProperty(key)) {
+ if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
// no one registered attribute interpolation function, so lets call it manually
fn(attrs[key]);
}
@@ -17860,24 +17954,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
lastValue,
parentGet, parentSet, compare;
- if (!hasOwnProperty.call(attrs, attrName)) {
- // In the case of user defined a binding with the same name as a method in Object.prototype but didn't set
- // the corresponding attribute. We need to make sure subsequent code won't access to the prototype function
- attrs[attrName] = undefined;
- }
-
switch (mode) {
case '@':
- if (!attrs[attrName] && !optional) {
- destination[scopeName] = undefined;
+ if (!optional && !hasOwnProperty.call(attrs, attrName)) {
+ destination[scopeName] = attrs[attrName] = void 0;
}
-
attrs.$observe(attrName, function(value) {
- destination[scopeName] = value;
+ if (isString(value)) {
+ destination[scopeName] = value;
+ }
});
attrs.$$observers[attrName].$$scope = scope;
- if (attrs[attrName]) {
+ if (isString(attrs[attrName])) {
// If the attribute has been provided then we trigger an interpolation to ensure
// the value is there for use in the link fn
destination[scopeName] = $interpolate(attrs[attrName])(scope);
@@ -17885,11 +17974,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
break;
case '=':
- if (optional && !attrs[attrName]) {
- return;
+ if (!hasOwnProperty.call(attrs, attrName)) {
+ if (optional) break;
+ attrs[attrName] = void 0;
}
- parentGet = $parse(attrs[attrName]);
+ if (optional && !attrs[attrName]) break;
+ parentGet = $parse(attrs[attrName]);
if (parentGet.literal) {
compare = equals;
} else {
@@ -17928,7 +18019,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
break;
case '&':
- parentGet = $parse(attrs[attrName]);
+ // Don't assign Object.prototype method to scope
+ parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
// Don't assign noop to destination if expression is not valid
if (parentGet === noop && optional) break;
@@ -18305,6 +18397,29 @@ function $ExceptionHandlerProvider() {
}];
}
+var $$ForceReflowProvider = function() {
+ this.$get = ['$document', function($document) {
+ return function(domNode) {
+ //the line below will force the browser to perform a repaint so
+ //that all the animated elements within the animation frame will
+ //be properly updated and drawn on screen. This is required to
+ //ensure that the preparation animation is properly flushed so that
+ //the active state picks up from there. DO NOT REMOVE THIS LINE.
+ //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
+ //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
+ //WILL TAKE YEARS AWAY FROM YOUR LIFE.
+ if (domNode) {
+ if (!domNode.nodeType && domNode instanceof jqLite) {
+ domNode = domNode[0];
+ }
+ } else {
+ domNode = $document[0].body;
+ }
+ return domNode.offsetWidth + 1;
+ };
+ }];
+};
+
var APPLICATION_JSON = 'application/json';
var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
var JSON_START = /^\[|^\{(?!\{)/;
@@ -18313,6 +18428,12 @@ var JSON_ENDS = {
'{': /}$/
};
var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
+var $httpMinErr = minErr('$http');
+var $httpMinErrLegacyFn = function(method) {
+ return function() {
+ throw $httpMinErr('legacy', 'The method `{0}` on the promise returned from `$http` has been disabled.', method);
+ };
+};
function serializeValue(v) {
if (isObject(v)) {
@@ -18413,8 +18534,8 @@ function $HttpParamSerializerJQLikeProvider() {
function serialize(toSerialize, prefix, topLevel) {
if (toSerialize === null || isUndefined(toSerialize)) return;
if (isArray(toSerialize)) {
- forEach(toSerialize, function(value) {
- serialize(value, prefix + '[]');
+ forEach(toSerialize, function(value, index) {
+ serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
});
} else if (isObject(toSerialize) && !isDate(toSerialize)) {
forEachSorted(toSerialize, function(value, key) {
@@ -18635,6 +18756,30 @@ function $HttpProvider() {
return useApplyAsync;
};
+ var useLegacyPromise = true;
+ /**
+ * @ngdoc method
+ * @name $httpProvider#useLegacyPromiseExtensions
+ * @description
+ *
+ * Configure `$http` service to return promises without the shorthand methods `success` and `error`.
+ * This should be used to make sure that applications work without these methods.
+ *
+ * Defaults to false. If no value is specified, returns the current configured value.
+ *
+ * @param {boolean=} value If true, `$http` will return a normal promise without the `success` and `error` methods.
+ *
+ * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.
+ * otherwise, returns the current configured value.
+ **/
+ this.useLegacyPromiseExtensions = function(value) {
+ if (isDefined(value)) {
+ useLegacyPromise = !!value;
+ return this;
+ }
+ return useLegacyPromise;
+ };
+
/**
* @ngdoc property
* @name $httpProvider#interceptors
@@ -18701,17 +18846,15 @@ function $HttpProvider() {
*
* ## General usage
* The `$http` service is a function which takes a single argument — a configuration object —
- * that is used to generate an HTTP request and returns a {@link ng.$q promise}
- * with two $http specific methods: `success` and `error`.
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}.
*
* ```js
* // Simple GET request example :
* $http.get('/someUrl').
- * success(function(data, status, headers, config) {
+ * then(function(response) {
* // this callback will be called asynchronously
* // when the response is available
- * }).
- * error(function(data, status, headers, config) {
+ * }, function(response) {
* // called asynchronously if an error occurs
* // or server returns response with an error status.
* });
@@ -18720,21 +18863,23 @@ function $HttpProvider() {
* ```js
* // Simple POST request example (passing data) :
* $http.post('/someUrl', {msg:'hello word!'}).
- * success(function(data, status, headers, config) {
+ * then(function(response) {
* // this callback will be called asynchronously
* // when the response is available
- * }).
- * error(function(data, status, headers, config) {
+ * }, function(response) {
* // called asynchronously if an error occurs
* // or server returns response with an error status.
* });
* ```
*
+ * The response object has these properties:
*
- * Since the returned value of calling the $http function is a `promise`, you can also use
- * the `then` method to register callbacks, and these callbacks will receive a single argument –
- * an object representing the response. See the API signature and type info below for more
- * details.
+ * - **data** – `{string|Object}` – The response body transformed with the transform
+ * functions.
+ * - **status** – `{number}` – HTTP status code of the response.
+ * - **headers** – `{function([headerName])}` – Header getter function.
+ * - **config** – `{Object}` – The configuration object that was used to generate the request.
+ * - **statusText** – `{string}` – HTTP status text of the response.
*
* A response status code between 200 and 299 is considered a success status and
* will result in the success callback being called. Note that if the response is a redirect,
@@ -18758,8 +18903,8 @@ function $HttpProvider() {
* request data must be passed in for POST/PUT requests.
*
* ```js
- * $http.get('/someUrl').success(successCallback);
- * $http.post('/someUrl', data).success(successCallback);
+ * $http.get('/someUrl').then(successCallback);
+ * $http.post('/someUrl', data).then(successCallback);
* ```
*
* Complete list of shortcut methods:
@@ -18773,6 +18918,14 @@ function $HttpProvider() {
* - {@link ng.$http#patch $http.patch}
*
*
+ * ## Deprecation Notice
+ *
+ * The `$http` legacy promise methods `success` and `error` have been deprecated.
+ * Use the standard `then` method instead.
+ * If {@link $httpProvider#useLegacyPromiseExtensions `$httpProvider.useLegacyPromiseExtensions`} is set to
+ * `false` then these methods will throw {@link $http:legacy `$http/legacy`} error.
+ *
+ *
* ## Setting HTTP Headers
*
* The $http service will automatically add certain HTTP headers to all requests. These defaults
@@ -18816,7 +18969,7 @@ function $HttpProvider() {
* data: { test: 'test' }
* }
*
- * $http(req).success(function(){...}).error(function(){...});
+ * $http(req).then(function(){...}, function(){...});
* ```
*
* ## Transforming Requests and Responses
@@ -19048,7 +19201,6 @@ function $HttpProvider() {
* In order to prevent collisions in environments where multiple Angular apps share the
* same domain or subdomain, we recommend that each application uses unique cookie name.
*
- *
* @param {object} config Object describing the request to be made and how it should be
* processed. The object has following properties:
*
@@ -19093,20 +19245,9 @@ function $HttpProvider() {
* - **responseType** - `{string}` - see
* [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).
*
- * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
- * standard `then` method and two http specific methods: `success` and `error`. The `then`
- * method takes two arguments a success and an error callback which will be called with a
- * response object. The `success` and `error` methods take a single argument - a function that
- * will be called when the request succeeds or fails respectively. The arguments passed into
- * these functions are destructured representation of the response object passed into the
- * `then` method. The response object has these properties:
+ * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object
+ * when the request succeeds or fails.
*
- * - **data** – `{string|Object}` – The response body transformed with the transform
- * functions.
- * - **status** – `{number}` – HTTP status code of the response.
- * - **headers** – `{function([headerName])}` – Header getter function.
- * - **config** – `{Object}` – The configuration object that was used to generate the request.
- * - **statusText** – `{string}` – HTTP status text of the response.
*
* @property {Array.
+ * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered.
* @returns {Object} Registered filter instance, or if a map of filters was provided then a map
* of the registered filter instances.
*/
@@ -27609,9 +27636,9 @@ function getTypeForFilter(val) {
}
element(by.model('amount')).clear();
element(by.model('amount')).sendKeys('-1234');
- expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
- expect(element(by.id('currency-custom')).getText()).toBe('(USD$1,234.00)');
- expect(element(by.id('currency-no-fractions')).getText()).toBe('(USD$1,234)');
+ expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00');
+ expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00');
+ expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234');
});
@@ -28451,6 +28478,10 @@ function orderByFilter($parse) {
if (sortPredicate.length === 0) { sortPredicate = ['+']; }
var predicates = processPredicates(sortPredicate, reverseOrder);
+ // Add a predicate at the end that evaluates to the element index. This makes the
+ // sort stable as it works as a tie-breaker when all the input predicates cannot
+ // distinguish between two elements.
+ predicates.push({ get: function() { return {}; }, descending: reverseOrder ? -1 : 1});
// The next three lines are a version of a Swartzian Transform idiom from Perl
// (sometimes called the Decorate-Sort-Undecorate idiom)
@@ -29451,7 +29482,6 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
');
-!window.angular.$$csp() && window.angular.element(document).find('head').prepend('');
\ No newline at end of file
+!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('');
+!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('');
\ No newline at end of file
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.js
index ec300d9d6..faa29c356 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.4.2
+ * @license AngularJS v1.4.5
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.min.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.min.js
index c2fb22ef0..5266fe719 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.min.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular-touch.min.js
@@ -1,5 +1,5 @@
/*
- AngularJS v1.4.2
+ AngularJS v1.4.5
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
diff --git a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular.js b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular.js
index a37c30144..a6aafd5b3 100644
--- a/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular.js
+++ b/archetypes/struts2-archetype-angularjs/src/main/resources/archetype-resources/src/main/webapp/js/lib/angular/angular.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.4.2
+ * @license AngularJS v1.4.5
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message += '\nhttp://errors.angularjs.org/1.4.2/' +
+ message += '\nhttp://errors.angularjs.org/1.4.5/' +
(module ? module + '/' : '') + code;
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -423,6 +423,8 @@ function baseExtend(dst, objs, deep) {
if (deep && isObject(src)) {
if (isDate(src)) {
dst[key] = new Date(src.valueOf());
+ } else if (isRegExp(src)) {
+ dst[key] = new RegExp(src);
} else {
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
baseExtend(dst[key], [src], true);
@@ -1053,22 +1055,39 @@ function equals(o1, o2) {
}
var csp = function() {
- if (isDefined(csp.isActive_)) return csp.isActive_;
+ if (!isDefined(csp.rules)) {
- var active = !!(document.querySelector('[ng-csp]') ||
- document.querySelector('[data-ng-csp]'));
- if (!active) {
+ var ngCspElement = (document.querySelector('[ng-csp]') ||
+ document.querySelector('[data-ng-csp]'));
+
+ if (ngCspElement) {
+ var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
+ ngCspElement.getAttribute('data-ng-csp');
+ csp.rules = {
+ noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
+ noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
+ };
+ } else {
+ csp.rules = {
+ noUnsafeEval: noUnsafeEval(),
+ noInlineStyle: false
+ };
+ }
+ }
+
+ return csp.rules;
+
+ function noUnsafeEval() {
try {
/* jshint -W031, -W054 */
new Function('');
/* jshint +W031, +W054 */
+ return false;
} catch (e) {
- active = true;
+ return true;
}
}
-
- return (csp.isActive_ = active);
};
/**
@@ -1300,13 +1319,19 @@ function tryDecodeURIComponent(value) {
* @returns {Object.}
*/
function parseKeyValue(/**string*/keyValue) {
- var obj = {}, key_value, key;
+ var obj = {};
forEach((keyValue || "").split('&'), function(keyValue) {
+ var splitPoint, key, val;
if (keyValue) {
- key_value = keyValue.replace(/\+/g,'%20').split('=');
- key = tryDecodeURIComponent(key_value[0]);
+ key = keyValue = keyValue.replace(/\+/g,'%20');
+ splitPoint = keyValue.indexOf('=');
+ if (splitPoint !== -1) {
+ key = keyValue.substring(0, splitPoint);
+ val = keyValue.substring(splitPoint + 1);
+ }
+ key = tryDecodeURIComponent(key);
if (isDefined(key)) {
- var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ val = isDefined(val) ? tryDecodeURIComponent(val) : true;
if (!hasOwnProperty.call(obj, key)) {
obj[key] = val;
} else if (isArray(obj[key])) {
@@ -1902,8 +1927,8 @@ function setupModuleLoader(window) {
* All modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
- * When passed two or more arguments, a new module is created. If passed only one argument, an
- * existing module (the name passed as the first argument to `module`) is retrieved.
+ * Passing one argument retrieves an existing {@link angular.Module},
+ * whereas passing more than one argument creates a new {@link angular.Module}
*
*
* # Module
@@ -2244,7 +2269,6 @@ function toDebugString(obj) {
/* global angularModule: true,
version: true,
- $LocaleProvider,
$CompileProvider,
htmlAnchorDirective,
@@ -2261,7 +2285,6 @@ function toDebugString(obj) {
ngClassDirective,
ngClassEvenDirective,
ngClassOddDirective,
- ngCspDirective,
ngCloakDirective,
ngControllerDirective,
ngFormDirective,
@@ -2298,6 +2321,7 @@ function toDebugString(obj) {
$AnchorScrollProvider,
$AnimateProvider,
+ $CoreAnimateCssProvider,
$$CoreAnimateQueueProvider,
$$CoreAnimateRunnerProvider,
$BrowserProvider,
@@ -2306,6 +2330,7 @@ function toDebugString(obj) {
$DocumentProvider,
$ExceptionHandlerProvider,
$FilterProvider,
+ $$ForceReflowProvider,
$InterpolateProvider,
$IntervalProvider,
$$HashMapProvider,
@@ -2328,7 +2353,6 @@ function toDebugString(obj) {
$$TestabilityProvider,
$TimeoutProvider,
$$RAFProvider,
- $$AsyncCallbackProvider,
$WindowProvider,
$$jqLiteProvider,
$$CookieReaderProvider
@@ -2350,11 +2374,11 @@ function toDebugString(obj) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.4.2', // all of these placeholder strings will be replaced by grunt's
+ full: '1.4.5', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 4,
- dot: 2,
- codeName: 'nebular-readjustment'
+ dot: 5,
+ codeName: 'permanent-internship'
};
@@ -2393,11 +2417,6 @@ function publishExternalAPI(angular) {
});
angularModule = setupModuleLoader(window);
- try {
- angularModule('ngLocale');
- } catch (e) {
- angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
- }
angularModule('ng', ['ngLocale'], ['$provide',
function ngModule($provide) {
@@ -2460,6 +2479,7 @@ function publishExternalAPI(angular) {
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
$animate: $AnimateProvider,
+ $animateCss: $CoreAnimateCssProvider,
$$animateQueue: $$CoreAnimateQueueProvider,
$$AnimateRunner: $$CoreAnimateRunnerProvider,
$browser: $BrowserProvider,
@@ -2468,6 +2488,7 @@ function publishExternalAPI(angular) {
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
+ $$forceReflow: $$ForceReflowProvider,
$interpolate: $InterpolateProvider,
$interval: $IntervalProvider,
$http: $HttpProvider,
@@ -2489,7 +2510,6 @@ function publishExternalAPI(angular) {
$timeout: $TimeoutProvider,
$window: $WindowProvider,
$$rAF: $$RAFProvider,
- $$asyncCallback: $$AsyncCallbackProvider,
$$jqLite: $$jqLiteProvider,
$$HashMap: $$HashMapProvider,
$$cookieReader: $$CookieReaderProvider
@@ -2563,7 +2583,7 @@ function publishExternalAPI(angular) {
* - [`html()`](http://api.jquery.com/html/)
* - [`next()`](http://api.jquery.com/next/) - Does not support selectors
* - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
- * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
+ * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
* - [`prepend()`](http://api.jquery.com/prepend/)
@@ -2577,7 +2597,7 @@ function publishExternalAPI(angular) {
* - [`text()`](http://api.jquery.com/text/)
* - [`toggleClass()`](http://api.jquery.com/toggleClass/)
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
- * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
+ * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces or event object as parameter
* - [`val()`](http://api.jquery.com/val/)
* - [`wrap()`](http://api.jquery.com/wrap/)
*
@@ -3688,7 +3708,7 @@ var $$HashMapProvider = [function() {
* Implicit module which gets automatically added to each {@link auto.$injector $injector}.
*/
-var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
+var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
@@ -4344,6 +4364,7 @@ function createInjector(modulesToLoad, strictDi) {
// Module Loading
////////////////////////////////////
function loadModules(modulesToLoad) {
+ assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
var runBlocks = [], moduleFn;
forEach(modulesToLoad, function(module) {
if (loadedModules.get(module)) return;
@@ -4853,31 +4874,31 @@ var $$CoreAnimateQueueProvider = function() {
};
function addRemoveClassesPostDigest(element, add, remove) {
- var data = postDigestQueue.get(element);
- var classVal;
+ var classVal, data = postDigestQueue.get(element);
if (!data) {
postDigestQueue.put(element, data = {});
postDigestElements.push(element);
}
- if (add) {
- forEach(add.split(' '), function(className) {
- if (className) {
- data[className] = true;
- }
- });
- }
+ var updateData = function(classes, value) {
+ var changed = false;
+ if (classes) {
+ classes = isString(classes) ? classes.split(' ') :
+ isArray(classes) ? classes : [];
+ forEach(classes, function(className) {
+ if (className) {
+ changed = true;
+ data[className] = value;
+ }
+ });
+ }
+ return changed;
+ };
- if (remove) {
- forEach(remove.split(' '), function(className) {
- if (className) {
- data[className] = false;
- }
- });
- }
-
- if (postDigestElements.length > 1) return;
+ var classesAdded = updateData(add, true);
+ var classesRemoved = updateData(remove, false);
+ if ((!classesAdded && !classesRemoved) || postDigestElements.length > 1) return;
$rootScope.$$postDigest(function() {
forEach(postDigestElements, function(element) {
@@ -5336,15 +5357,88 @@ var $AnimateProvider = ['$provide', function($provide) {
}];
}];
-function $$AsyncCallbackProvider() {
- this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
- return $$rAF.supported
- ? function(fn) { return $$rAF(fn); }
- : function(fn) {
- return $timeout(fn, 0, false);
+/**
+ * @ngdoc service
+ * @name $animateCss
+ * @kind object
+ *
+ * @description
+ * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,
+ * then the `$animateCss` service will actually perform animations.
+ *
+ * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.
+ */
+var $CoreAnimateCssProvider = function() {
+ this.$get = ['$$rAF', '$q', function($$rAF, $q) {
+
+ var RAFPromise = function() {};
+ RAFPromise.prototype = {
+ done: function(cancel) {
+ this.defer && this.defer[cancel === true ? 'reject' : 'resolve']();
+ },
+ end: function() {
+ this.done();
+ },
+ cancel: function() {
+ this.done(true);
+ },
+ getPromise: function() {
+ if (!this.defer) {
+ this.defer = $q.defer();
+ }
+ return this.defer.promise;
+ },
+ then: function(f1,f2) {
+ return this.getPromise().then(f1,f2);
+ },
+ 'catch': function(f1) {
+ return this.getPromise()['catch'](f1);
+ },
+ 'finally': function(f1) {
+ return this.getPromise()['finally'](f1);
+ }
+ };
+
+ return function(element, options) {
+ if (options.from) {
+ element.css(options.from);
+ options.from = null;
+ }
+
+ var closed, runner = new RAFPromise();
+ return {
+ start: run,
+ end: run
};
+
+ function run() {
+ $$rAF(function() {
+ close();
+ if (!closed) {
+ runner.done();
+ }
+ closed = true;
+ });
+ return runner;
+ }
+
+ function close() {
+ if (options.addClass) {
+ element.addClass(options.addClass);
+ options.addClass = null;
+ }
+ if (options.removeClass) {
+ element.removeClass(options.removeClass);
+ options.removeClass = null;
+ }
+ if (options.to) {
+ element.css(options.to);
+ options.to = null;
+ }
+ }
+ };
}];
-}
+};
/* global stripHash: true */
@@ -6508,7 +6602,7 @@ function $TemplateCacheProvider() {
* otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
*
* Note that you can also require the directive's own controller - it will be made available like
- * like any other controller.
+ * any other controller.
*
* * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
* This is the same as the `$transclude`
@@ -6534,7 +6628,7 @@ function $TemplateCacheProvider() {
*
* ### Transclusion
*
- * Transclusion is the process of extracting a collection of DOM element from one part of the DOM and
+ * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
* copying them to another part of the DOM, while maintaining their connection to the original AngularJS
* scope from where they were taken.
*
@@ -7289,7 +7383,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
listeners.push(fn);
$rootScope.$evalAsync(function() {
- if (!listeners.$$inter && attrs.hasOwnProperty(key)) {
+ if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
// no one registered attribute interpolation function, so lets call it manually
fn(attrs[key]);
}
@@ -8668,24 +8762,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
lastValue,
parentGet, parentSet, compare;
- if (!hasOwnProperty.call(attrs, attrName)) {
- // In the case of user defined a binding with the same name as a method in Object.prototype but didn't set
- // the corresponding attribute. We need to make sure subsequent code won't access to the prototype function
- attrs[attrName] = undefined;
- }
-
switch (mode) {
case '@':
- if (!attrs[attrName] && !optional) {
- destination[scopeName] = undefined;
+ if (!optional && !hasOwnProperty.call(attrs, attrName)) {
+ destination[scopeName] = attrs[attrName] = void 0;
}
-
attrs.$observe(attrName, function(value) {
- destination[scopeName] = value;
+ if (isString(value)) {
+ destination[scopeName] = value;
+ }
});
attrs.$$observers[attrName].$$scope = scope;
- if (attrs[attrName]) {
+ if (isString(attrs[attrName])) {
// If the attribute has been provided then we trigger an interpolation to ensure
// the value is there for use in the link fn
destination[scopeName] = $interpolate(attrs[attrName])(scope);
@@ -8693,11 +8782,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
break;
case '=':
- if (optional && !attrs[attrName]) {
- return;
+ if (!hasOwnProperty.call(attrs, attrName)) {
+ if (optional) break;
+ attrs[attrName] = void 0;
}
- parentGet = $parse(attrs[attrName]);
+ if (optional && !attrs[attrName]) break;
+ parentGet = $parse(attrs[attrName]);
if (parentGet.literal) {
compare = equals;
} else {
@@ -8736,7 +8827,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
break;
case '&':
- parentGet = $parse(attrs[attrName]);
+ // Don't assign Object.prototype method to scope
+ parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
// Don't assign noop to destination if expression is not valid
if (parentGet === noop && optional) break;
@@ -9113,6 +9205,29 @@ function $ExceptionHandlerProvider() {
}];
}
+var $$ForceReflowProvider = function() {
+ this.$get = ['$document', function($document) {
+ return function(domNode) {
+ //the line below will force the browser to perform a repaint so
+ //that all the animated elements within the animation frame will
+ //be properly updated and drawn on screen. This is required to
+ //ensure that the preparation animation is properly flushed so that
+ //the active state picks up from there. DO NOT REMOVE THIS LINE.
+ //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
+ //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
+ //WILL TAKE YEARS AWAY FROM YOUR LIFE.
+ if (domNode) {
+ if (!domNode.nodeType && domNode instanceof jqLite) {
+ domNode = domNode[0];
+ }
+ } else {
+ domNode = $document[0].body;
+ }
+ return domNode.offsetWidth + 1;
+ };
+ }];
+};
+
var APPLICATION_JSON = 'application/json';
var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
var JSON_START = /^\[|^\{(?!\{)/;
@@ -9121,6 +9236,12 @@ var JSON_ENDS = {
'{': /}$/
};
var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
+var $httpMinErr = minErr('$http');
+var $httpMinErrLegacyFn = function(method) {
+ return function() {
+ throw $httpMinErr('legacy', 'The method `{0}` on the promise returned from `$http` has been disabled.', method);
+ };
+};
function serializeValue(v) {
if (isObject(v)) {
@@ -9221,8 +9342,8 @@ function $HttpParamSerializerJQLikeProvider() {
function serialize(toSerialize, prefix, topLevel) {
if (toSerialize === null || isUndefined(toSerialize)) return;
if (isArray(toSerialize)) {
- forEach(toSerialize, function(value) {
- serialize(value, prefix + '[]');
+ forEach(toSerialize, function(value, index) {
+ serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
});
} else if (isObject(toSerialize) && !isDate(toSerialize)) {
forEachSorted(toSerialize, function(value, key) {
@@ -9443,6 +9564,30 @@ function $HttpProvider() {
return useApplyAsync;
};
+ var useLegacyPromise = true;
+ /**
+ * @ngdoc method
+ * @name $httpProvider#useLegacyPromiseExtensions
+ * @description
+ *
+ * Configure `$http` service to return promises without the shorthand methods `success` and `error`.
+ * This should be used to make sure that applications work without these methods.
+ *
+ * Defaults to false. If no value is specified, returns the current configured value.
+ *
+ * @param {boolean=} value If true, `$http` will return a normal promise without the `success` and `error` methods.
+ *
+ * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.
+ * otherwise, returns the current configured value.
+ **/
+ this.useLegacyPromiseExtensions = function(value) {
+ if (isDefined(value)) {
+ useLegacyPromise = !!value;
+ return this;
+ }
+ return useLegacyPromise;
+ };
+
/**
* @ngdoc property
* @name $httpProvider#interceptors
@@ -9509,17 +9654,15 @@ function $HttpProvider() {
*
* ## General usage
* The `$http` service is a function which takes a single argument — a configuration object —
- * that is used to generate an HTTP request and returns a {@link ng.$q promise}
- * with two $http specific methods: `success` and `error`.
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}.
*
* ```js
* // Simple GET request example :
* $http.get('/someUrl').
- * success(function(data, status, headers, config) {
+ * then(function(response) {
* // this callback will be called asynchronously
* // when the response is available
- * }).
- * error(function(data, status, headers, config) {
+ * }, function(response) {
* // called asynchronously if an error occurs
* // or server returns response with an error status.
* });
@@ -9528,21 +9671,23 @@ function $HttpProvider() {
* ```js
* // Simple POST request example (passing data) :
* $http.post('/someUrl', {msg:'hello word!'}).
- * success(function(data, status, headers, config) {
+ * then(function(response) {
* // this callback will be called asynchronously
* // when the response is available
- * }).
- * error(function(data, status, headers, config) {
+ * }, function(response) {
* // called asynchronously if an error occurs
* // or server returns response with an error status.
* });
* ```
*
+ * The response object has these properties:
*
- * Since the returned value of calling the $http function is a `promise`, you can also use
- * the `then` method to register callbacks, and these callbacks will receive a single argument –
- * an object representing the response. See the API signature and type info below for more
- * details.
+ * - **data** – `{string|Object}` – The response body transformed with the transform
+ * functions.
+ * - **status** – `{number}` – HTTP status code of the response.
+ * - **headers** – `{function([headerName])}` – Header getter function.
+ * - **config** – `{Object}` – The configuration object that was used to generate the request.
+ * - **statusText** – `{string}` – HTTP status text of the response.
*
* A response status code between 200 and 299 is considered a success status and
* will result in the success callback being called. Note that if the response is a redirect,
@@ -9566,8 +9711,8 @@ function $HttpProvider() {
* request data must be passed in for POST/PUT requests.
*
* ```js
- * $http.get('/someUrl').success(successCallback);
- * $http.post('/someUrl', data).success(successCallback);
+ * $http.get('/someUrl').then(successCallback);
+ * $http.post('/someUrl', data).then(successCallback);
* ```
*
* Complete list of shortcut methods:
@@ -9581,6 +9726,14 @@ function $HttpProvider() {
* - {@link ng.$http#patch $http.patch}
*
*
+ * ## Deprecation Notice
+ *
+ * The `$http` legacy promise methods `success` and `error` have been deprecated.
+ * Use the standard `then` method instead.
+ * If {@link $httpProvider#useLegacyPromiseExtensions `$httpProvider.useLegacyPromiseExtensions`} is set to
+ * `false` then these methods will throw {@link $http:legacy `$http/legacy`} error.
+ *
+ *
* ## Setting HTTP Headers
*
* The $http service will automatically add certain HTTP headers to all requests. These defaults
@@ -9624,7 +9777,7 @@ function $HttpProvider() {
* data: { test: 'test' }
* }
*
- * $http(req).success(function(){...}).error(function(){...});
+ * $http(req).then(function(){...}, function(){...});
* ```
*
* ## Transforming Requests and Responses
@@ -9856,7 +10009,6 @@ function $HttpProvider() {
* In order to prevent collisions in environments where multiple Angular apps share the
* same domain or subdomain, we recommend that each application uses unique cookie name.
*
- *
* @param {object} config Object describing the request to be made and how it should be
* processed. The object has following properties:
*
@@ -9901,20 +10053,9 @@ function $HttpProvider() {
* - **responseType** - `{string}` - see
* [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).
*
- * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
- * standard `then` method and two http specific methods: `success` and `error`. The `then`
- * method takes two arguments a success and an error callback which will be called with a
- * response object. The `success` and `error` methods take a single argument - a function that
- * will be called when the request succeeds or fails respectively. The arguments passed into
- * these functions are destructured representation of the response object passed into the
- * `then` method. The response object has these properties:
+ * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object
+ * when the request succeeds or fails.
*
- * - **data** – `{string|Object}` – The response body transformed with the transform
- * functions.
- * - **status** – `{number}` – HTTP status code of the response.
- * - **headers** – `{function([headerName])}` – Header getter function.
- * - **config** – `{Object}` – The configuration object that was used to generate the request.
- * - **statusText** – `{string}` – HTTP status text of the response.
*
* @property {Array.