vendor/assets/javascripts/angular-scenario.js in angularjs-rails-1.2.5 vs vendor/assets/javascripts/angular-scenario.js in angularjs-rails-1.2.6

- old
+ new

@@ -9788,11 +9788,11 @@ } })( window ); /** - * @license AngularJS v1.2.5 + * @license AngularJS v1.2.6 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ (function(window, document){ var _jQuery = window.jQuery.noConflict(true); @@ -9858,11 +9858,11 @@ return arg; } return match; }); - message = message + '\nhttp://errors.angularjs.org/1.2.5/' + + message = message + '\nhttp://errors.angularjs.org/1.2.6/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + encodeURIComponent(stringify(arguments[i])); } @@ -10082,11 +10082,13 @@ function forEach(obj, iterator, context) { var key; if (obj) { if (isFunction(obj)){ for (key in obj) { - if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) { + // Need to check if hasOwnProperty exists, + // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function + if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) { iterator.call(context, obj[key], key); } } } else if (obj.forEach && obj.forEach !== forEach) { obj.forEach(iterator, context); @@ -10638,11 +10640,11 @@ dst = dst || {}; for(var key in src) { // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src // so we don't need to worry about using our custom hasOwnProperty here - if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') { + if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') { dst[key] = src[key]; } } return dst; @@ -11619,15 +11621,15 @@ * - `minor` – `{number}` – Minor version number, such as "9". * - `dot` – `{number}` – Dot version number, such as "18". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.2.5', // all of these placeholder strings will be replaced by grunt's + full: '1.2.6', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 2, - dot: 5, - codeName: 'singularity-expansion' + dot: 6, + codeName: 'taco-salsafication' }; function publishExternalAPI(angular){ extend(angular, { @@ -11799,10 +11801,11 @@ * - [`hasClass()`](http://api.jquery.com/hasClass/) * - [`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 + * - [`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/) * - [`prop()`](http://api.jquery.com/prop/) * - [`ready()`](http://api.jquery.com/ready/) * - [`remove()`](http://api.jquery.com/remove/) @@ -12390,11 +12393,14 @@ event.isDefaultPrevented = function() { return event.defaultPrevented || event.returnValue === false; }; - forEach(events[type || event.type], function(fn) { + // Copy event handlers in case event handlers array is modified during execution. + var eventHandlersCopy = shallowCopy(events[type || event.type] || []); + + forEach(eventHandlersCopy, function(fn) { fn.call(element, event); }); // Remove monkey-patched methods (IE), // as they would cause memory leaks in IE8. @@ -12486,10 +12492,23 @@ }); }, off: jqLiteOff, + one: function(element, type, fn) { + element = jqLite(element); + + //add the listener twice so that when it is called + //you can remove the original function and still be + //able to call element.off(ev, fn) normally + element.on(type, function onFn() { + element.off(type, fn); + element.off(type, onFn); + }); + element.on(type, fn); + }, + replaceWith: function(element, replaceNode) { var index, parent = element.parentNode; jqLiteDealoc(element); forEach(new JQLite(replaceNode), function(node){ if (index) { @@ -13179,19 +13198,19 @@ * @example * Here is an example of registering a service using * {@link AUTO.$provide#methods_service $provide.service(class)} that is defined as a CoffeeScript class. * <pre> * class Ping - * constructor: (@$http)-> - * send: ()=> + * constructor: (@$http) -> + * send: () => * @$http.get('/ping') * * $provide.service('ping', ['$http', Ping]) * </pre> * You would then inject and use this service like this: * <pre> - * someModule.controller 'Ctrl', ['ping', (ping)-> + * someModule.controller 'Ctrl', ['ping', (ping) -> * ping.send() * ] * </pre> */ @@ -13654,10 +13673,32 @@ "Expecting class selector starting with '.' got '{0}'.", name); this.$$selectors[name.substr(1)] = key; $provide.factory(key, factory); }; + /** + * @ngdoc function + * @name ng.$animateProvider#classNameFilter + * @methodOf ng.$animateProvider + * + * @description + * Sets and/or returns the CSS class regular expression that is checked when performing + * an animation. Upon bootstrap the classNameFilter value is not set at all and will + * therefore enable $animate to attempt to perform an animation on any element. + * When setting the classNameFilter value, animations will only be performed on elements + * that successfully match the filter expression. This in turn can boost performance + * for low-powered devices as well as applications containing a lot of structural operations. + * @param {RegExp=} expression The className expression which will be checked against all animations + * @return {RegExp} The current CSS className expression value. If null then there is no expression value + */ + this.classNameFilter = function(expression) { + if(arguments.length === 1) { + this.$$classNameFilter = (expression instanceof RegExp) ? expression : null; + } + return this.$$classNameFilter; + }; + this.$get = ['$timeout', function($timeout) { /** * * @ngdoc object @@ -14901,18 +14942,18 @@ * * - if on the other hand, you need the element to be cloned, the view reference from the original * example would not point to the clone, but rather to the original template that was cloned. In * this case, you can access the clone via the cloneAttachFn: * <pre> - * var templateHTML = angular.element('<p>{{total}}</p>'), + * var templateElement = angular.element('<p>{{total}}</p>'), * scope = ....; * - * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) { + * var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) { * //attach the clone to DOM document at the right place * }); * - * //now we have reference to the cloned DOM via `clone` + * //now we have reference to the cloned DOM via `clonedElement` * </pre> * * * For information on how the compiler works, see the * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide. @@ -15250,10 +15291,11 @@ } }); var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); + safeAddClass($compileNodes, 'ng-scope'); return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart // and sometimes changes the structure of the DOM. var $linkNode = cloneConnectFn @@ -15264,16 +15306,17 @@ $linkNode.data('$' + name + 'Controller', instance); }); // Attach scope only to non-text nodes. for(var i = 0, ii = $linkNode.length; i<ii; i++) { - var node = $linkNode[i]; - if (node.nodeType == 1 /* element */ || node.nodeType == 9 /* document */) { + var node = $linkNode[i], + nodeType = node.nodeType; + if (nodeType === 1 /* element */ || nodeType === 9 /* document */) { $linkNode.eq(i).data('$scope', scope); } } - safeAddClass($linkNode, 'ng-scope'); + if (cloneConnectFn) cloneConnectFn($linkNode, scope); if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); return $linkNode; }; } @@ -15297,19 +15340,19 @@ * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the * scope argument is auto-generated to the new child of the transcluded parent scope. * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then * the rootElement must be set the jqLite collection of the compile root. This is * needed so that the jqLite collection items can be replaced with widgets. - * @param {number=} max directive priority + * @param {number=} maxPriority Max directive priority. * @returns {?function} A composite linking function of all of the matched directives or null. */ function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, previousCompileContext) { var linkFns = [], - nodeLinkFn, childLinkFn, directives, attrs, linkFnFound; + attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound; - for(var i = 0; i < nodeList.length; i++) { + for (var i = 0; i < nodeList.length; i++) { attrs = new Attributes(); // we must always refer to nodeList[i] since the nodes can be replaced underneath us. directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined, ignoreDirective); @@ -15317,20 +15360,23 @@ nodeLinkFn = (directives.length) ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, null, [], [], previousCompileContext) : null; + if (nodeLinkFn && nodeLinkFn.scope) { + safeAddClass(jqLite(nodeList[i]), 'ng-scope'); + } + childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || - !nodeList[i].childNodes || - !nodeList[i].childNodes.length) + !(childNodes = nodeList[i].childNodes) || + !childNodes.length) ? null - : compileNodes(nodeList[i].childNodes, + : compileNodes(childNodes, nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); - linkFns.push(nodeLinkFn); - linkFns.push(childLinkFn); - linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn); + linkFns.push(nodeLinkFn, childLinkFn); + linkFnFound = linkFnFound || nodeLinkFn || childLinkFn; //use the previous context only for the first element in the virtual group previousCompileContext = null; } // return a linking function if we have found anything, null otherwise @@ -15338,13 +15384,14 @@ function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n; // copy nodeList so that linking doesn't break due to live list updates. - var stableNodeList = []; - for (i = 0, ii = nodeList.length; i < ii; i++) { - stableNodeList.push(nodeList[i]); + var nodeListLength = nodeList.length, + stableNodeList = new Array(nodeListLength); + for (i = 0; i < nodeListLength; i++) { + stableNodeList[i] = nodeList[i]; } for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) { node = stableNodeList[n]; nodeLinkFn = linkFns[i++]; @@ -15353,11 +15400,10 @@ if (nodeLinkFn) { if (nodeLinkFn.scope) { childScope = scope.$new(); $node.data('$scope', childScope); - safeAddClass($node, 'ng-scope'); } else { childScope = scope; } childTranscludeFn = nodeLinkFn.transclude; if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { @@ -15436,13 +15482,11 @@ name = name.substr(0, name.length - 6); } nName = directiveNormalize(name.toLowerCase()); attrsMap[nName] = name; - attrs[nName] = value = trim((msie && name == 'href') - ? decodeURIComponent(node.getAttribute(name, 2)) - : attr.value); + attrs[nName] = value = trim(attr.value); if (getBooleanAttrName(node, nName)) { attrs[nName] = true; // presence means true } addAttrInterpolateDirective(node, directives, value, nName); addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, @@ -18033,18 +18077,115 @@ * To cancel an interval, call `$interval.cancel(promise)`. * * In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to * move forward by `millis` milliseconds and trigger any functions scheduled to run in that * time. + * + * <div class="alert alert-warning"> + * **Note**: Intervals created by this service must be explicitly destroyed when you are finished + * with them. In particular they are not automatically destroyed when a controller's scope or a + * directive's element are destroyed. + * You should take this into consideration and make sure to always cancel the interval at the + * appropriate moment. See the example below for more details on how and when to do this. + * </div> * * @param {function()} fn A function that should be called repeatedly. * @param {number} delay Number of milliseconds between each function call. * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat * indefinitely. * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. * @returns {promise} A promise which will be notified on each iteration. + * + * @example + <doc:example module="time"> + <doc:source> + <script> + function Ctrl2($scope,$interval) { + $scope.format = 'M/d/yy h:mm:ss a'; + $scope.blood_1 = 100; + $scope.blood_2 = 120; + + var stop; + $scope.fight = function() { + // Don't start a new fight if we are already fighting + if ( angular.isDefined(stop) ) return; + + stop = $interval(function() { + if ($scope.blood_1 > 0 && $scope.blood_2 > 0) { + $scope.blood_1 = $scope.blood_1 - 3; + $scope.blood_2 = $scope.blood_2 - 4; + } else { + $scope.stopFight(); + } + }, 100); + }; + + $scope.stopFight = function() { + if (angular.isDefined(stop)) { + $interval.cancel(stop); + stop = undefined; + } + }; + + $scope.resetFight = function() { + $scope.blood_1 = 100; + $scope.blood_2 = 120; + } + + $scope.$on('$destroy', function() { + // Make sure that the interval is destroyed too + $scope.stopFight(); + }); + } + + angular.module('time', []) + // Register the 'myCurrentTime' directive factory method. + // We inject $interval and dateFilter service since the factory method is DI. + .directive('myCurrentTime', function($interval, dateFilter) { + // return the directive link function. (compile function not needed) + return function(scope, element, attrs) { + var format, // date format + stopTime; // so that we can cancel the time updates + + // used to update the UI + function updateTime() { + element.text(dateFilter(new Date(), format)); + } + + // watch the expression, and update the UI on change. + scope.$watch(attrs.myCurrentTime, function(value) { + format = value; + updateTime(); + }); + + stopTime = $interval(updateTime, 1000); + + // listen on DOM destroy (removal) event, and cancel the next UI update + // to prevent updating time ofter the DOM element was removed. + element.bind('$destroy', function() { + $interval.cancel(stopTime); + }); + } + }); + </script> + + <div> + <div ng-controller="Ctrl2"> + Date format: <input ng-model="format"> <hr/> + Current time is: <span my-current-time="format"></span> + <hr/> + Blood 1 : <font color='red'>{{blood_1}}</font> + Blood 2 : <font color='red'>{{blood_2}}</font> + <button type="button" data-ng-click="fight()">Fight</button> + <button type="button" data-ng-click="stopFight()">StopFight</button> + <button type="button" data-ng-click="resetFight()">resetFight</button> + </div> + </div> + + </doc:source> + </doc:example> */ function interval(fn, delay, count, invokeApply) { var setInterval = $window.setInterval, clearInterval = $window.clearInterval, deferred = $q.defer(), @@ -18799,10 +18940,17 @@ // ignore rewriting if no A tag (reached root element, or no parent - removed from document) if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; } var absHref = elm.prop('href'); + + if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') { + // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during + // an animation. + absHref = urlResolve(absHref.animVal).href; + } + var rewrittenUrl = $location.$$rewrite(absHref); if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) { event.preventDefault(); if (rewrittenUrl != $browser.url()) { @@ -19007,13 +19155,20 @@ return arg; } function consoleLog(type) { var console = $window.console || {}, - logFn = console[type] || console.log || noop; + logFn = console[type] || console.log || noop, + hasApply = false; - if (logFn.apply) { + // Note: reading logFn.apply throws an error in IE11 in IE8 document mode. + // The reason behind this is that console.log has type "object" in IE8... + try { + hasApply = !! logFn.apply; + } catch (e) {} + + if (hasApply) { return function() { var args = []; forEach(arguments, function(arg) { args.push(formatError(arg)); }); @@ -19919,32 +20074,32 @@ return !options.unwrapPromises ? function cspSafeGetter(scope, locals) { var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope; - if (pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return pathVal; pathVal = pathVal[key0]; - if (!key1 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key1 ? undefined : pathVal; pathVal = pathVal[key1]; - if (!key2 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key2 ? undefined : pathVal; pathVal = pathVal[key2]; - if (!key3 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key3 ? undefined : pathVal; pathVal = pathVal[key3]; - if (!key4 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key4 ? undefined : pathVal; pathVal = pathVal[key4]; return pathVal; } : function cspSafePromiseEnabledGetter(scope, locals) { var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope, promise; - if (pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return pathVal; pathVal = pathVal[key0]; if (pathVal && pathVal.then) { promiseWarning(fullExp); if (!("$$v" in pathVal)) { @@ -19952,11 +20107,11 @@ promise.$$v = undefined; promise.then(function(val) { promise.$$v = val; }); } pathVal = pathVal.$$v; } - if (!key1 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key1 ? undefined : pathVal; pathVal = pathVal[key1]; if (pathVal && pathVal.then) { promiseWarning(fullExp); if (!("$$v" in pathVal)) { @@ -19964,11 +20119,11 @@ promise.$$v = undefined; promise.then(function(val) { promise.$$v = val; }); } pathVal = pathVal.$$v; } - if (!key2 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key2 ? undefined : pathVal; pathVal = pathVal[key2]; if (pathVal && pathVal.then) { promiseWarning(fullExp); if (!("$$v" in pathVal)) { @@ -19976,11 +20131,11 @@ promise.$$v = undefined; promise.then(function(val) { promise.$$v = val; }); } pathVal = pathVal.$$v; } - if (!key3 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key3 ? undefined : pathVal; pathVal = pathVal[key3]; if (pathVal && pathVal.then) { promiseWarning(fullExp); if (!("$$v" in pathVal)) { @@ -19988,11 +20143,11 @@ promise.$$v = undefined; promise.then(function(val) { promise.$$v = val; }); } pathVal = pathVal.$$v; } - if (!key4 || pathVal === null || pathVal === undefined) return pathVal; + if (pathVal == null) return key4 ? undefined : pathVal; pathVal = pathVal[key4]; if (pathVal && pathVal.then) { promiseWarning(fullExp); if (!("$$v" in pathVal)) { @@ -20004,10 +20159,30 @@ } return pathVal; }; } +function simpleGetterFn1(key0, fullExp) { + ensureSafeMemberName(key0, fullExp); + + return function simpleGetterFn1(scope, locals) { + if (scope == null) return undefined; + return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; + }; +} + +function simpleGetterFn2(key0, key1, fullExp) { + ensureSafeMemberName(key0, fullExp); + ensureSafeMemberName(key1, fullExp); + + return function simpleGetterFn2(scope, locals) { + if (scope == null) return undefined; + scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; + return scope == null ? undefined : scope[key1]; + }; +} + function getterFn(path, options, fullExp) { // Check whether the cache has this getter already. // We can use hasOwnProperty directly on the cache because we ensure, // see below, that the cache never stores a path called 'hasOwnProperty' if (getterFnCache.hasOwnProperty(path)) { @@ -20016,11 +20191,17 @@ var pathKeys = path.split('.'), pathKeysLength = pathKeys.length, fn; - if (options.csp) { + // When we have only 1 or 2 tokens, use optimized special case closures. + // http://jsperf.com/angularjs-parse-getter/6 + if (!options.unwrapPromises && pathKeysLength === 1) { + fn = simpleGetterFn1(pathKeys[0], fullExp); + } else if (!options.unwrapPromises && pathKeysLength === 2) { + fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp); + } else if (options.csp) { if (pathKeysLength < 6) { fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options); } else { fn = function(scope, locals) { @@ -20034,15 +20215,14 @@ } while (i < pathKeysLength); return val; }; } } else { - var code = 'var l, fn, p;\n'; + var code = 'var p;\n'; forEach(pathKeys, function(key, index) { ensureSafeMemberName(key, fullExp); - code += 'if(s === null || s === undefined) return s;\n' + - 'l=s;\n' + + code += 'if(s == null) return undefined;\n' + 's='+ (index // we simply dereference 's' on any .dot notation ? 's' // but if we are first then we check locals first, and if so read it first : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' + @@ -20061,14 +20241,14 @@ code += 'return s;'; /* jshint -W054 */ var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning /* jshint +W054 */ - evaledFnGetter.toString = function() { return code; }; - fn = function(scope, locals) { + evaledFnGetter.toString = valueFn(code); + fn = options.unwrapPromises ? function(scope, locals) { return evaledFnGetter(scope, locals, promiseWarning); - }; + } : evaledFnGetter; } // Only cache the value if it's not going to mess up the cache object // This is more performant that using Object.prototype.hasOwnProperty.call if (path !== 'hasOwnProperty') { @@ -23075,10 +23255,11 @@ }, csp: csp(), vendorPrefix: vendorPrefix, transitions : transitions, animations : animations, + android: android, msie : msie, msieDocumentMode: documentMode }; }]; } @@ -23112,97 +23293,10 @@ * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this * promise will be resolved with is the return value of the `fn` function. * - * @example - <doc:example module="time"> - <doc:source> - <script> - function Ctrl2($scope,$timeout) { - $scope.format = 'M/d/yy h:mm:ss a'; - $scope.blood_1 = 100; - $scope.blood_2 = 120; - - var stop; - $scope.fight = function() { - stop = $timeout(function() { - if ($scope.blood_1 > 0 && $scope.blood_2 > 0) { - $scope.blood_1 = $scope.blood_1 - 3; - $scope.blood_2 = $scope.blood_2 - 4; - $scope.fight(); - } else { - $timeout.cancel(stop); - } - }, 100); - }; - - $scope.stopFight = function() { - $timeout.cancel(stop); - }; - - $scope.resetFight = function() { - $scope.blood_1 = 100; - $scope.blood_2 = 120; - } - } - - angular.module('time', []) - // Register the 'myCurrentTime' directive factory method. - // We inject $timeout and dateFilter service since the factory method is DI. - .directive('myCurrentTime', function($timeout, dateFilter) { - // return the directive link function. (compile function not needed) - return function(scope, element, attrs) { - var format, // date format - timeoutId; // timeoutId, so that we can cancel the time updates - - // used to update the UI - function updateTime() { - element.text(dateFilter(new Date(), format)); - } - - // watch the expression, and update the UI on change. - scope.$watch(attrs.myCurrentTime, function(value) { - format = value; - updateTime(); - }); - - // schedule update in one second - function updateLater() { - // save the timeoutId for canceling - timeoutId = $timeout(function() { - updateTime(); // update DOM - updateLater(); // schedule another update - }, 1000); - } - - // listen on DOM destroy (removal) event, and cancel the next UI update - // to prevent updating time ofter the DOM element was removed. - element.bind('$destroy', function() { - $timeout.cancel(timeoutId); - }); - - updateLater(); // kick off the UI update process. - } - }); - </script> - - <div> - <div ng-controller="Ctrl2"> - Date format: <input ng-model="format"> <hr/> - Current time is: <span my-current-time="format"></span> - <hr/> - Blood 1 : <font color='red'>{{blood_1}}</font> - Blood 2 : <font color='red'>{{blood_2}}</font> - <button type="button" data-ng-click="fight()">Fight</button> - <button type="button" data-ng-click="stopFight()">StopFight</button> - <button type="button" data-ng-click="resetFight()">resetFight</button> - </div> - </div> - - </doc:source> - </doc:example> */ function timeout(fn, delay, invokeApply) { var deferred = $q.defer(), promise = deferred.promise, skipApply = (isDefined(invokeApply) && !invokeApply), @@ -24510,10 +24604,11 @@ /** * @ngdoc directive * @name ng.directive:ngHref * @restrict A + * @priority 99 * * @description * Using Angular markup like `{{hash}}` in an href attribute will * make the link go to the wrong URL if the user clicks it before * Angular has a chance to replace the `{{hash}}` markup with its @@ -24593,10 +24688,11 @@ /** * @ngdoc directive * @name ng.directive:ngSrc * @restrict A + * @priority 99 * * @description * Using Angular markup like `{{hash}}` in a `src` attribute doesn't * work right: The browser will fetch from the URL with the literal * text `{{hash}}` until Angular replaces the expression inside @@ -24618,10 +24714,11 @@ /** * @ngdoc directive * @name ng.directive:ngSrcset * @restrict A + * @priority 99 * * @description * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't * work right: The browser will fetch from the URL with the literal * text `{{hash}}` until Angular replaces the expression inside @@ -24643,10 +24740,11 @@ /** * @ngdoc directive * @name ng.directive:ngDisabled * @restrict A + * @priority 100 * * @description * * The following markup will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: * <pre> @@ -24686,10 +24784,11 @@ /** * @ngdoc directive * @name ng.directive:ngChecked * @restrict A + * @priority 100 * * @description * The HTML specification does not require browsers to preserve the values of boolean attributes * such as checked. (Their presence means true and their absence means false.) * If we put an Angular interpolation expression into such an attribute then the @@ -24720,20 +24819,20 @@ /** * @ngdoc directive * @name ng.directive:ngReadonly * @restrict A + * @priority 100 * * @description * The HTML specification does not require browsers to preserve the values of boolean attributes * such as readonly. (Their presence means true and their absence means false.) * If we put an Angular interpolation expression into such an attribute then the * binding information would be lost when the browser removes the attribute. * The `ngReadonly` directive solves this problem for the `readonly` attribute. * This complementary directive is not removed by the browser and so provides * a permanent reliable place to store the binding information. - * @example <doc:example> <doc:source> Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/> <input type="text" ng-readonly="checked" value="I'm Angular"/> @@ -24755,19 +24854,21 @@ /** * @ngdoc directive * @name ng.directive:ngSelected * @restrict A + * @priority 100 * * @description * The HTML specification does not require browsers to preserve the values of boolean attributes * such as selected. (Their presence means true and their absence means false.) * If we put an Angular interpolation expression into such an attribute then the * binding information would be lost when the browser removes the attribute. * The `ngSelected` directive solves this problem for the `selected` atttribute. * This complementary directive is not removed by the browser and so provides * a permanent reliable place to store the binding information. + * * @example <doc:example> <doc:source> Check me to select: <input type="checkbox" ng-model="selected"><br/> <select> @@ -24791,21 +24892,20 @@ /** * @ngdoc directive * @name ng.directive:ngOpen * @restrict A + * @priority 100 * * @description * The HTML specification does not require browsers to preserve the values of boolean attributes * such as open. (Their presence means true and their absence means false.) * If we put an Angular interpolation expression into such an attribute then the * binding information would be lost when the browser removes the attribute. * The `ngOpen` directive solves this problem for the `open` attribute. * This complementary directive is not removed by the browser and so provides * a permanent reliable place to store the binding information. - - * * @example <doc:example> <doc:source> Check me check multiple: <input type="checkbox" ng-model="open"><br/> <details id="details" ng-open="open"> @@ -25646,19 +25746,21 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { // In composition mode, users are still inputing intermediate text buffer, // hold the listener until composition is done. // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent - var composing = false; + if (!$sniffer.android) { + var composing = false; - element.on('compositionstart', function() { - composing = true; - }); + element.on('compositionstart', function(data) { + composing = true; + }); - element.on('compositionend', function() { - composing = false; - }); + element.on('compositionend', function() { + composing = false; + }); + } var listener = function() { if (composing) return; var value = element.val(); @@ -27219,11 +27321,11 @@ * document; alternatively, the css rule above must be included in the external stylesheet of the * application. * * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css - * class `ngCloak` in addition to the `ngCloak` directive as shown in the example below. + * class `ng-cloak` in addition to the `ngCloak` directive as shown in the example below. * * @element ANY * * @example <doc:example> @@ -27530,11 +27632,18 @@ * @element ANY * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon * a dblclick. (The Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-dblclick="count = count + 1" ng-init="count=0"> + Increment (on double click) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27546,11 +27655,18 @@ * @element ANY * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon * mousedown. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mousedown="count = count + 1" ng-init="count=0"> + Increment (on mouse down) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27562,11 +27678,18 @@ * @element ANY * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon * mouseup. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mouseup="count = count + 1" ng-init="count=0"> + Increment (on mouse up) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive * @name ng.directive:ngMouseover @@ -27577,11 +27700,18 @@ * @element ANY * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon * mouseover. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mouseover="count = count + 1" ng-init="count=0"> + Increment (when mouse is over) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27593,11 +27723,18 @@ * @element ANY * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon * mouseenter. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mouseenter="count = count + 1" ng-init="count=0"> + Increment (when mouse enters) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27609,11 +27746,18 @@ * @element ANY * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon * mouseleave. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mouseleave="count = count + 1" ng-init="count=0"> + Increment (when mouse leaves) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27625,11 +27769,18 @@ * @element ANY * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon * mousemove. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <button ng-mousemove="count = count + 1" ng-init="count=0"> + Increment (when mouse moves) + </button> + count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27641,11 +27792,16 @@ * @element ANY * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-keydown="count = count + 1" ng-init="count=0"> + key down count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27657,11 +27813,16 @@ * @element ANY * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-keyup="count = count + 1" ng-init="count=0"> + key up count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27673,11 +27834,16 @@ * @element ANY * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-keypress="count = count + 1" ng-init="count=0"> + key press count: {{count}} + </doc:source> + </doc:example> */ /** * @ngdoc directive @@ -27772,11 +27938,16 @@ * @element window, input, select, textarea, a * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon * copy. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value"> + copied: {{copied}} + </doc:source> + </doc:example> */ /** * @ngdoc directive * @name ng.directive:ngCut @@ -27787,11 +27958,16 @@ * @element window, input, select, textarea, a * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon * cut. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value"> + cut: {{cut}} + </doc:source> + </doc:example> */ /** * @ngdoc directive * @name ng.directive:ngPaste @@ -27802,11 +27978,16 @@ * @element window, input, select, textarea, a * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon * paste. (Event object is available as `$event`) * * @example - * See {@link ng.directive:ngClick ngClick} + <doc:example> + <doc:source> + <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'> + pasted: {{paste}} + </doc:source> + </doc:example> */ /** * @ngdoc directive * @name ng.directive:ngIf @@ -27864,13 +28045,10 @@ background:white; border:1px solid black; padding:10px; } - /&#42; - The transition styles can also be placed on the CSS base class above - &#42;/ .animate-if.ng-enter, .animate-if.ng-leave { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } @@ -28174,11 +28352,11 @@ * @description * The `ngInit` directive allows you to evaluate an expression in the * current scope. * * <div class="alert alert-error"> - * The only appropriate use of `ngInit` for aliasing special properties of + * The only appropriate use of `ngInit` is for aliasing special properties of * {@link api/ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you * should use {@link guide/controller controllers} rather than `ngInit` * to initialize values on a scope. * </div> * @@ -28673,11 +28851,11 @@ priority: 1000, terminal: true, $$tlb: true, link: function($scope, $element, $attr, ctrl, $transclude){ var expression = $attr.ngRepeat; - var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), + var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, lhs, rhs, valueIdentifier, keyIdentifier, hashFnLocals = {$id: hashKey}; if (!match) { @@ -29731,22 +29909,14 @@ } selectCtrl.init(ngModelCtrl, nullOption, unknownOption); // required validator - if (multiple && (attr.required || attr.ngRequired)) { - var requiredValidator = function(value) { - ngModelCtrl.$setValidity('required', !attr.required || (value && value.length)); - return value; + if (multiple) { + ngModelCtrl.$isEmpty = function(value) { + return !value || value.length === 0; }; - - ngModelCtrl.$parsers.push(requiredValidator); - ngModelCtrl.$formatters.unshift(requiredValidator); - - attr.$observe('required', function() { - requiredValidator(ngModelCtrl.$viewValue); - }); } if (optionsExp) setupAsOptions(scope, element, ngModelCtrl); else if (multiple) setupAsMultiple(scope, element, ngModelCtrl); else setupAsSingle(scope, element, ngModelCtrl, selectCtrl); @@ -32368,7 +32538,7 @@ }); } })(window, document); -!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n/* The styles below ensure that the CSS transition will ALWAYS\n * animate and close. A nasty bug occurs with CSS transitions where\n * when the active class isn\'t set, or if the active class doesn\'t\n * contain any styles to transition to, then, if ngAnimate is used,\n * it will appear as if the webpage is broken due to the forever hanging\n * animations. The border-spacing (!ie) and zoom (ie) CSS properties are\n * used below since they trigger a transition without making the browser\n * animate anything and they\'re both highly underused CSS properties */\n.ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; }\n.ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; }\n</style>'); +!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n</style>'); !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>'); \ No newline at end of file