diff --git a/horizon/static/horizon/lib/angular/angular-cookies.js b/horizon/static/horizon/lib/angular/angular-cookies.js deleted file mode 100755 index ba48add896..0000000000 --- a/horizon/static/horizon/lib/angular/angular-cookies.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @license AngularJS v1.2.1 - * (c) 2010-2012 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -/** - * @ngdoc overview - * @name ngCookies - * @description - * - * # ngCookies - * - * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. - * - * {@installModule cookies} - * - *
- * - * See {@link ngCookies.$cookies `$cookies`} and - * {@link ngCookies.$cookieStore `$cookieStore`} for usage. - */ - - -angular.module('ngCookies', ['ng']). - /** - * @ngdoc object - * @name ngCookies.$cookies - * @requires $browser - * - * @description - * Provides read/write access to browser's cookies. - * - * Only a simple Object is exposed and by adding or removing properties to/from - * this object, new cookies are created/deleted at the end of current $eval. - * - * Requires the {@link ngCookies `ngCookies`} module to be installed. - * - * @example -- * describe('$exceptionHandlerProvider', function() { - * - * it('should capture log messages and exceptions', function() { - * - * module(function($exceptionHandlerProvider) { - * $exceptionHandlerProvider.mode('log'); - * }); - * - * inject(function($log, $exceptionHandler, $timeout) { - * $timeout(function() { $log.log(1); }); - * $timeout(function() { $log.log(2); throw 'banana peel'; }); - * $timeout(function() { $log.log(3); }); - * expect($exceptionHandler.errors).toEqual([]); - * expect($log.assertEmpty()); - * $timeout.flush(); - * expect($exceptionHandler.errors).toEqual(['banana peel']); - * expect($log.log.logs).toEqual([[1], [2], [3]]); - * }); - * }); - * }); - *- */ - -angular.mock.$ExceptionHandlerProvider = function() { - var handler; - - /** - * @ngdoc method - * @name ngMock.$exceptionHandlerProvider#mode - * @methodOf ngMock.$exceptionHandlerProvider - * - * @description - * Sets the logging mode. - * - * @param {string} mode Mode of operation, defaults to `rethrow`. - * - * - `rethrow`: If any errors are passed into the handler in tests, it typically - * means that there is a bug in the application or test, so this mock will - * make these tests fail. - * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` - * mode stores an array of errors in `$exceptionHandler.errors`, to allow later - * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and - * {@link ngMock.$log#reset reset()} - */ - this.mode = function(mode) { - switch(mode) { - case 'rethrow': - handler = function(e) { - throw e; - }; - break; - case 'log': - var errors = []; - - handler = function(e) { - if (arguments.length == 1) { - errors.push(e); - } else { - errors.push([].slice.call(arguments, 0)); - } - }; - - handler.errors = errors; - break; - default: - throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); - } - }; - - this.$get = function() { - return handler; - }; - - this.mode('rethrow'); -}; - - -/** - * @ngdoc service - * @name ngMock.$log - * - * @description - * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays - * (one array per logging level). These arrays are exposed as `logs` property of each of the - * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`. - * - */ -angular.mock.$LogProvider = function() { - var debug = true; - - function concat(array1, array2, index) { - return array1.concat(Array.prototype.slice.call(array2, index)); - } - - this.debugEnabled = function(flag) { - if (angular.isDefined(flag)) { - debug = flag; - return this; - } else { - return debug; - } - }; - - this.$get = function () { - var $log = { - log: function() { $log.log.logs.push(concat([], arguments, 0)); }, - warn: function() { $log.warn.logs.push(concat([], arguments, 0)); }, - info: function() { $log.info.logs.push(concat([], arguments, 0)); }, - error: function() { $log.error.logs.push(concat([], arguments, 0)); }, - debug: function() { - if (debug) { - $log.debug.logs.push(concat([], arguments, 0)); - } - } - }; - - /** - * @ngdoc method - * @name ngMock.$log#reset - * @methodOf ngMock.$log - * - * @description - * Reset all of the logging arrays to empty. - */ - $log.reset = function () { - /** - * @ngdoc property - * @name ngMock.$log#log.logs - * @propertyOf ngMock.$log - * - * @description - * Array of messages logged using {@link ngMock.$log#log}. - * - * @example - *
- * $log.log('Some Log'); - * var first = $log.log.logs.unshift(); - *- */ - $log.log.logs = []; - /** - * @ngdoc property - * @name ngMock.$log#info.logs - * @propertyOf ngMock.$log - * - * @description - * Array of messages logged using {@link ngMock.$log#info}. - * - * @example - *
- * $log.info('Some Info'); - * var first = $log.info.logs.unshift(); - *- */ - $log.info.logs = []; - /** - * @ngdoc property - * @name ngMock.$log#warn.logs - * @propertyOf ngMock.$log - * - * @description - * Array of messages logged using {@link ngMock.$log#warn}. - * - * @example - *
- * $log.warn('Some Warning'); - * var first = $log.warn.logs.unshift(); - *- */ - $log.warn.logs = []; - /** - * @ngdoc property - * @name ngMock.$log#error.logs - * @propertyOf ngMock.$log - * - * @description - * Array of messages logged using {@link ngMock.$log#error}. - * - * @example - *
- * $log.log('Some Error'); - * var first = $log.error.logs.unshift(); - *- */ - $log.error.logs = []; - /** - * @ngdoc property - * @name ngMock.$log#debug.logs - * @propertyOf ngMock.$log - * - * @description - * Array of messages logged using {@link ngMock.$log#debug}. - * - * @example - *
- * $log.debug('Some Error'); - * var first = $log.debug.logs.unshift(); - *- */ - $log.debug.logs = []; - }; - - /** - * @ngdoc method - * @name ngMock.$log#assertEmpty - * @methodOf ngMock.$log - * - * @description - * Assert that the all of the logging methods have no logged messages. If messages present, an - * exception is thrown. - */ - $log.assertEmpty = function() { - var errors = []; - angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) { - angular.forEach($log[logLevel].logs, function(log) { - angular.forEach(log, function (logItem) { - errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + - (logItem.stack || '')); - }); - }); - }); - if (errors.length) { - errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or "+ - "an expected log message was not checked and removed:"); - errors.push(''); - throw new Error(errors.join('\n---------\n')); - } - }; - - $log.reset(); - return $log; - }; -}; - - -/** - * @ngdoc service - * @name ngMock.$interval - * - * @description - * Mock implementation of the $interval service. - * - * 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. - * - * @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. - */ -angular.mock.$IntervalProvider = function() { - this.$get = ['$rootScope', '$q', - function($rootScope, $q) { - var repeatFns = [], - nextRepeatId = 0, - now = 0; - - var $interval = function(fn, delay, count, invokeApply) { - var deferred = $q.defer(), - promise = deferred.promise, - iteration = 0, - skipApply = (angular.isDefined(invokeApply) && !invokeApply); - - count = (angular.isDefined(count)) ? count : 0, - promise.then(null, null, fn); - - promise.$$intervalId = nextRepeatId; - - function tick() { - deferred.notify(iteration++); - - if (count > 0 && iteration >= count) { - var fnIndex; - deferred.resolve(iteration); - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (fnIndex !== undefined) { - repeatFns.splice(fnIndex, 1); - } - } - - if (!skipApply) $rootScope.$apply(); - } - - repeatFns.push({ - nextTime:(now + delay), - delay: delay, - fn: tick, - id: nextRepeatId, - deferred: deferred - }); - repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); - - nextRepeatId++; - return promise; - }; - - $interval.cancel = function(promise) { - var fnIndex; - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (fnIndex !== undefined) { - repeatFns[fnIndex].deferred.reject('canceled'); - repeatFns.splice(fnIndex, 1); - return true; - } - - return false; - }; - - /** - * @ngdoc method - * @name ngMock.$interval#flush - * @methodOf ngMock.$interval - * @description - * - * Runs interval tasks scheduled to be run in the next `millis` milliseconds. - * - * @param {number=} millis maximum timeout amount to flush up until. - * - * @return {number} The amount of time moved forward. - */ - $interval.flush = function(millis) { - now += millis; - while (repeatFns.length && repeatFns[0].nextTime <= now) { - var task = repeatFns[0]; - task.fn(); - task.nextTime += task.delay; - repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); - } - return millis; - }; - - return $interval; - }]; -}; - - -/* jshint -W101 */ -/* The R_ISO8061_STR regex is never going to fit into the 100 char limit! - * This directive should go inside the anonymous function but a bug in JSHint means that it would - * not be enacted early enough to prevent the warning. - */ -(function() { - var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; - - function jsonStringToDate(string) { - var match; - if (match = string.match(R_ISO8061_STR)) { - var date = new Date(0), - tzHour = 0, - tzMin = 0; - if (match[9]) { - tzHour = int(match[9] + match[10]); - tzMin = int(match[9] + match[11]); - } - date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3])); - date.setUTCHours(int(match[4]||0) - tzHour, - int(match[5]||0) - tzMin, - int(match[6]||0), - int(match[7]||0)); - return date; - } - return string; - } - - function int(str) { - return parseInt(str, 10); - } - - function padNumber(num, digits, trim) { - var neg = ''; - if (num < 0) { - neg = '-'; - num = -num; - } - num = '' + num; - while(num.length < digits) num = '0' + num; - if (trim) - num = num.substr(num.length - digits); - return neg + num; - } - - - /** - * @ngdoc object - * @name angular.mock.TzDate - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. - * - * Mock of the Date type which has its timezone specified via constructor arg. - * - * The main purpose is to create Date-like instances with timezone fixed to the specified timezone - * offset, so that we can test code that depends on local timezone settings without dependency on - * the time zone settings of the machine where the code is running. - * - * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) - * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* - * - * @example - * !!!! WARNING !!!!! - * This is not a complete Date object so only methods that were implemented can be called safely. - * To make matters worse, TzDate instances inherit stuff from Date via a prototype. - * - * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is - * incomplete we might be missing some non-standard methods. This can result in errors like: - * "Date.prototype.foo called on incompatible Object". - * - *
- * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); - * newYearInBratislava.getTimezoneOffset() => -60; - * newYearInBratislava.getFullYear() => 2010; - * newYearInBratislava.getMonth() => 0; - * newYearInBratislava.getDate() => 1; - * newYearInBratislava.getHours() => 0; - * newYearInBratislava.getMinutes() => 0; - * newYearInBratislava.getSeconds() => 0; - *- * - */ - angular.mock.TzDate = function (offset, timestamp) { - var self = new Date(0); - if (angular.isString(timestamp)) { - var tsStr = timestamp; - - self.origDate = jsonStringToDate(timestamp); - - timestamp = self.origDate.getTime(); - if (isNaN(timestamp)) - throw { - name: "Illegal Argument", - message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" - }; - } else { - self.origDate = new Date(timestamp); - } - - var localOffset = new Date(timestamp).getTimezoneOffset(); - self.offsetDiff = localOffset*60*1000 - offset*1000*60*60; - self.date = new Date(timestamp + self.offsetDiff); - - self.getTime = function() { - return self.date.getTime() - self.offsetDiff; - }; - - self.toLocaleDateString = function() { - return self.date.toLocaleDateString(); - }; - - self.getFullYear = function() { - return self.date.getFullYear(); - }; - - self.getMonth = function() { - return self.date.getMonth(); - }; - - self.getDate = function() { - return self.date.getDate(); - }; - - self.getHours = function() { - return self.date.getHours(); - }; - - self.getMinutes = function() { - return self.date.getMinutes(); - }; - - self.getSeconds = function() { - return self.date.getSeconds(); - }; - - self.getMilliseconds = function() { - return self.date.getMilliseconds(); - }; - - self.getTimezoneOffset = function() { - return offset * 60; - }; - - self.getUTCFullYear = function() { - return self.origDate.getUTCFullYear(); - }; - - self.getUTCMonth = function() { - return self.origDate.getUTCMonth(); - }; - - self.getUTCDate = function() { - return self.origDate.getUTCDate(); - }; - - self.getUTCHours = function() { - return self.origDate.getUTCHours(); - }; - - self.getUTCMinutes = function() { - return self.origDate.getUTCMinutes(); - }; - - self.getUTCSeconds = function() { - return self.origDate.getUTCSeconds(); - }; - - self.getUTCMilliseconds = function() { - return self.origDate.getUTCMilliseconds(); - }; - - self.getDay = function() { - return self.date.getDay(); - }; - - // provide this method only on browsers that already have it - if (self.toISOString) { - self.toISOString = function() { - return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + - padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + - padNumber(self.origDate.getUTCDate(), 2) + 'T' + - padNumber(self.origDate.getUTCHours(), 2) + ':' + - padNumber(self.origDate.getUTCMinutes(), 2) + ':' + - padNumber(self.origDate.getUTCSeconds(), 2) + '.' + - padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; - }; - } - - //hide all methods not implemented in this mock that the Date prototype exposes - var unimplementedMethods = ['getUTCDay', - 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', - 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', - 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', - 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString', - 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf']; - - angular.forEach(unimplementedMethods, function(methodName) { - self[methodName] = function() { - throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); - }; - }); - - return self; - }; - - //make "tzDateInstance instanceof Date" return true - angular.mock.TzDate.prototype = Date.prototype; -})(); -/* jshint +W101 */ - -angular.mock.animate = angular.module('mock.animate', ['ng']) - - .config(['$provide', function($provide) { - - $provide.decorator('$animate', function($delegate) { - var animate = { - queue : [], - enabled : $delegate.enabled, - flushNext : function(name) { - var tick = animate.queue.shift(); - - if (!tick) throw new Error('No animation to be flushed'); - if(tick.method !== name) { - throw new Error('The next animation is not "' + name + - '", but is "' + tick.method + '"'); - } - tick.fn(); - return tick; - } - }; - - angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { - animate[method] = function() { - var params = arguments; - animate.queue.push({ - method : method, - params : params, - element : angular.isElement(params[0]) && params[0], - parent : angular.isElement(params[1]) && params[1], - after : angular.isElement(params[2]) && params[2], - fn : function() { - $delegate[method].apply($delegate, params); - } - }); - }; - }); - - return animate; - }); - - }]); - - -/** - * @ngdoc function - * @name angular.mock.dump - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available function. - * - * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for - * debugging. - * - * This method is also available on window, where it can be used to display objects on debug - * console. - * - * @param {*} object - any object to turn into string. - * @return {string} a serialized string of the argument - */ -angular.mock.dump = function(object) { - return serialize(object); - - function serialize(object) { - var out; - - if (angular.isElement(object)) { - object = angular.element(object); - out = angular.element(''); - angular.forEach(object, function(element) { - out.append(angular.element(element).clone()); - }); - out = out.html(); - } else if (angular.isArray(object)) { - out = []; - angular.forEach(object, function(o) { - out.push(serialize(o)); - }); - out = '[ ' + out.join(', ') + ' ]'; - } else if (angular.isObject(object)) { - if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) { - out = serializeScope(object); - } else if (object instanceof Error) { - out = object.stack || ('' + object.name + ': ' + object.message); - } else { - // TODO(i): this prevents methods being logged, - // we should have a better way to serialize objects - out = angular.toJson(object, true); - } - } else { - out = String(object); - } - - return out; - } - - function serializeScope(scope, offset) { - offset = offset || ' '; - var log = [offset + 'Scope(' + scope.$id + '): {']; - for ( var key in scope ) { - if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { - log.push(' ' + key + ': ' + angular.toJson(scope[key])); - } - } - var child = scope.$$childHead; - while(child) { - log.push(serializeScope(child, offset + ' ')); - child = child.$$nextSibling; - } - log.push('}'); - return log.join('\n' + offset); - } -}; - -/** - * @ngdoc object - * @name ngMock.$httpBackend - * @description - * Fake HTTP backend implementation suitable for unit testing applications that use the - * {@link ng.$http $http service}. - * - * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less - * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. - * - * During unit testing, we want our unit tests to run quickly and have no external dependencies so - * we don’t want to send {@link https://developer.mozilla.org/en/xmlhttprequest XHR} or - * {@link http://en.wikipedia.org/wiki/JSONP JSONP} requests to a real server. All we really need is - * to verify whether a certain request has been sent or not, or alternatively just let the - * application make requests, respond with pre-trained responses and assert that the end result is - * what we expect it to be. - * - * This mock implementation can be used to respond with static or dynamic responses via the - * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). - * - * When an Angular application needs some data from a server, it calls the $http service, which - * sends the request to a real server using $httpBackend service. With dependency injection, it is - * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify - * the requests and respond with some testing data without sending a request to real server. - * - * There are two ways to specify what test data should be returned as http responses by the mock - * backend when the code under test makes http requests: - * - * - `$httpBackend.expect` - specifies a request expectation - * - `$httpBackend.when` - specifies a backend definition - * - * - * # Request Expectations vs Backend Definitions - * - * Request expectations provide a way to make assertions about requests made by the application and - * to define responses for those requests. The test will fail if the expected requests are not made - * or they are made in the wrong order. - * - * Backend definitions allow you to define a fake backend for your application which doesn't assert - * if a particular request was made or not, it just returns a trained response if a request is made. - * The test will pass whether or not the request gets made during testing. - * - * - *
Request expectations | Backend definitions | |
---|---|---|
Syntax | - *.expect(...).respond(...) | - *.when(...).respond(...) | - *
Typical usage | - *strict unit tests | - *loose (black-box) unit testing | - *
Fulfills multiple requests | - *NO | - *YES | - *
Order of requests matters | - *YES | - *NO | - *
Request required | - *YES | - *NO | - *
Response required | - *optional (see below) | - *YES | - *
- // The controller code - function MyController($scope, $http) { - var authToken; - - $http.get('/auth.py').success(function(data, status, headers) { - authToken = headers('A-Token'); - $scope.user = data; - }); - - $scope.saveMessage = function(message) { - var headers = { 'Authorization': authToken }; - $scope.status = 'Saving...'; - - $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) { - $scope.status = ''; - }).error(function() { - $scope.status = 'ERROR!'; - }); - }; - } -- * - * Now we setup the mock backend and create the test specs. - * -
- // testing controller - describe('MyController', function() { - var $httpBackend, $rootScope, createController; - - beforeEach(inject(function($injector) { - // Set up the mock http service responses - $httpBackend = $injector.get('$httpBackend'); - // backend definition common for all tests - $httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'}); - - // Get hold of a scope (i.e. the root scope) - $rootScope = $injector.get('$rootScope'); - // The $controller service is used to create instances of controllers - var $controller = $injector.get('$controller'); - - createController = function() { - return $controller('MyController', {'$scope' : $rootScope }); - }; - })); - - - afterEach(function() { - $httpBackend.verifyNoOutstandingExpectation(); - $httpBackend.verifyNoOutstandingRequest(); - }); - - - it('should fetch authentication token', function() { - $httpBackend.expectGET('/auth.py'); - var controller = createController(); - $httpBackend.flush(); - }); - - - it('should send msg to server', function() { - var controller = createController(); - $httpBackend.flush(); - - // now you don’t care about the authentication, but - // the controller will still send the request and - // $httpBackend will respond without you having to - // specify the expectation and response for this request - - $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); - $rootScope.saveMessage('message content'); - expect($rootScope.status).toBe('Saving...'); - $httpBackend.flush(); - expect($rootScope.status).toBe(''); - }); - - - it('should send auth header', function() { - var controller = createController(); - $httpBackend.flush(); - - $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { - // check if the header was send, if it wasn't the expectation won't - // match the request and the test will fail - return headers['Authorization'] == 'xxx'; - }).respond(201, ''); - - $rootScope.saveMessage('whatever'); - $httpBackend.flush(); - }); - }); -- */ -angular.mock.$HttpBackendProvider = function() { - this.$get = ['$rootScope', createHttpBackendMock]; -}; - -/** - * General factory function for $httpBackend mock. - * Returns instance for unit testing (when no arguments specified): - * - passing through is disabled - * - auto flushing is disabled - * - * Returns instance for e2e testing (when `$delegate` and `$browser` specified): - * - passing through (delegating request to real backend) is enabled - * - auto flushing is enabled - * - * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified) - * @param {Object=} $browser Auto-flushing enabled if specified - * @return {Object} Instance of $httpBackend mock - */ -function createHttpBackendMock($rootScope, $delegate, $browser) { - var definitions = [], - expectations = [], - responses = [], - responsesPush = angular.bind(responses, responses.push); - - function createResponse(status, data, headers) { - if (angular.isFunction(status)) return status; - - return function() { - return angular.isNumber(status) - ? [status, data, headers] - : [200, status, data]; - }; - } - - // TODO(vojta): change params to: method, url, data, headers, callback - function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { - var xhr = new MockXhr(), - expectation = expectations[0], - wasExpected = false; - - function prettyPrint(data) { - return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp) - ? data - : angular.toJson(data); - } - - function wrapResponse(wrapped) { - if (!$browser && timeout && timeout.then) timeout.then(handleTimeout); - - return handleResponse; - - function handleResponse() { - var response = wrapped.response(method, url, data, headers); - xhr.$$respHeaders = response[2]; - callback(response[0], response[1], xhr.getAllResponseHeaders()); - } - - function handleTimeout() { - for (var i = 0, ii = responses.length; i < ii; i++) { - if (responses[i] === handleResponse) { - responses.splice(i, 1); - callback(-1, undefined, ''); - break; - } - } - } - } - - if (expectation && expectation.match(method, url)) { - if (!expectation.matchData(data)) - throw new Error('Expected ' + expectation + ' with different data\n' + - 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data); - - if (!expectation.matchHeaders(headers)) - throw new Error('Expected ' + expectation + ' with different headers\n' + - 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + - prettyPrint(headers)); - - expectations.shift(); - - if (expectation.response) { - responses.push(wrapResponse(expectation)); - return; - } - wasExpected = true; - } - - var i = -1, definition; - while ((definition = definitions[++i])) { - if (definition.match(method, url, data, headers || {})) { - if (definition.response) { - // if $browser specified, we do auto flush all requests - ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); - } else if (definition.passThrough) { - $delegate(method, url, data, callback, headers, timeout, withCredentials); - } else throw new Error('No response defined !'); - return; - } - } - throw wasExpected ? - new Error('No response defined !') : - new Error('Unexpected request: ' + method + ' ' + url + '\n' + - (expectation ? 'Expected ' + expectation : 'No more request expected')); - } - - /** - * @ngdoc method - * @name ngMock.$httpBackend#when - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. - * - * - respond – - * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can return - * an array containing response status (number), response data (string) and response headers - * (Object). - */ - $httpBackend.when = function(method, url, data, headers) { - var definition = new MockHttpExpectation(method, url, data, headers), - chain = { - respond: function(status, data, headers) { - definition.response = createResponse(status, data, headers); - } - }; - - if ($browser) { - chain.passThrough = function() { - definition.passThrough = true; - }; - } - - definitions.push(definition); - return chain; - }; - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenGET - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenHEAD - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenDELETE - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenPOST - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenPUT - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#whenJSONP - * @methodOf ngMock.$httpBackend - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - createShortMethods('when'); - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expect - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation. - * - * @param {string} method HTTP method. - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current expectation. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - * - * - respond – - * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can return - * an array containing response status (number), response data (string) and response headers - * (Object). - */ - $httpBackend.expect = function(method, url, data, headers) { - var expectation = new MockHttpExpectation(method, url, data, headers); - expectations.push(expectation); - return { - respond: function(status, data, headers) { - expectation.response = createResponse(status, data, headers); - } - }; - }; - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectGET - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for GET requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. See #expect for more info. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectHEAD - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for HEAD requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectDELETE - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for DELETE requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectPOST - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for POST requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectPUT - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for PUT requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectPATCH - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for PATCH requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - - /** - * @ngdoc method - * @name ngMock.$httpBackend#expectJSONP - * @methodOf ngMock.$httpBackend - * @description - * Creates a new request expectation for JSONP requests. For more info see `expect()`. - * - * @param {string|RegExp} url HTTP url. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. - */ - createShortMethods('expect'); - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#flush - * @methodOf ngMock.$httpBackend - * @description - * Flushes all pending requests using the trained responses. - * - * @param {number=} count Number of responses to flush (in the order they arrived). If undefined, - * all pending requests will be flushed. If there are no pending requests when the flush method - * is called an exception is thrown (as this typically a sign of programming error). - */ - $httpBackend.flush = function(count) { - $rootScope.$digest(); - if (!responses.length) throw new Error('No pending request to flush !'); - - if (angular.isDefined(count)) { - while (count--) { - if (!responses.length) throw new Error('No more pending request to flush !'); - responses.shift()(); - } - } else { - while (responses.length) { - responses.shift()(); - } - } - $httpBackend.verifyNoOutstandingExpectation(); - }; - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#verifyNoOutstandingExpectation - * @methodOf ngMock.$httpBackend - * @description - * Verifies that all of the requests defined via the `expect` api were made. If any of the - * requests were not made, verifyNoOutstandingExpectation throws an exception. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - *
- * afterEach($httpBackend.verifyNoOutstandingExpectation); - *- */ - $httpBackend.verifyNoOutstandingExpectation = function() { - $rootScope.$digest(); - if (expectations.length) { - throw new Error('Unsatisfied requests: ' + expectations.join(', ')); - } - }; - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#verifyNoOutstandingRequest - * @methodOf ngMock.$httpBackend - * @description - * Verifies that there are no outstanding requests that need to be flushed. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - *
- * afterEach($httpBackend.verifyNoOutstandingRequest); - *- */ - $httpBackend.verifyNoOutstandingRequest = function() { - if (responses.length) { - throw new Error('Unflushed requests: ' + responses.length); - } - }; - - - /** - * @ngdoc method - * @name ngMock.$httpBackend#resetExpectations - * @methodOf ngMock.$httpBackend - * @description - * Resets all request expectations, but preserves all backend definitions. Typically, you would - * call resetExpectations during a multiple-phase test when you want to reuse the same instance of - * $httpBackend mock. - */ - $httpBackend.resetExpectations = function() { - expectations.length = 0; - responses.length = 0; - }; - - return $httpBackend; - - - function createShortMethods(prefix) { - angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) { - $httpBackend[prefix + method] = function(url, headers) { - return $httpBackend[prefix](method, url, undefined, headers); - }; - }); - - angular.forEach(['PUT', 'POST', 'PATCH'], function(method) { - $httpBackend[prefix + method] = function(url, data, headers) { - return $httpBackend[prefix](method, url, data, headers); - }; - }); - } -} - -function MockHttpExpectation(method, url, data, headers) { - - this.data = data; - this.headers = headers; - - this.match = function(m, u, d, h) { - if (method != m) return false; - if (!this.matchUrl(u)) return false; - if (angular.isDefined(d) && !this.matchData(d)) return false; - if (angular.isDefined(h) && !this.matchHeaders(h)) return false; - return true; - }; - - this.matchUrl = function(u) { - if (!url) return true; - if (angular.isFunction(url.test)) return url.test(u); - return url == u; - }; - - this.matchHeaders = function(h) { - if (angular.isUndefined(headers)) return true; - if (angular.isFunction(headers)) return headers(h); - return angular.equals(headers, h); - }; - - this.matchData = function(d) { - if (angular.isUndefined(data)) return true; - if (data && angular.isFunction(data.test)) return data.test(d); - if (data && angular.isFunction(data)) return data(d); - if (data && !angular.isString(data)) return angular.toJson(data) == d; - return data == d; - }; - - this.toString = function() { - return method + ' ' + url; - }; -} - -function MockXhr() { - - // hack for testing $http, $httpBackend - MockXhr.$$lastInstance = this; - - this.open = function(method, url, async) { - this.$$method = method; - this.$$url = url; - this.$$async = async; - this.$$reqHeaders = {}; - this.$$respHeaders = {}; - }; - - this.send = function(data) { - this.$$data = data; - }; - - this.setRequestHeader = function(key, value) { - this.$$reqHeaders[key] = value; - }; - - this.getResponseHeader = function(name) { - // the lookup must be case insensitive, - // that's why we try two quick lookups first and full scan last - var header = this.$$respHeaders[name]; - if (header) return header; - - name = angular.lowercase(name); - header = this.$$respHeaders[name]; - if (header) return header; - - header = undefined; - angular.forEach(this.$$respHeaders, function(headerVal, headerName) { - if (!header && angular.lowercase(headerName) == name) header = headerVal; - }); - return header; - }; - - this.getAllResponseHeaders = function() { - var lines = []; - - angular.forEach(this.$$respHeaders, function(value, key) { - lines.push(key + ': ' + value); - }); - return lines.join('\n'); - }; - - this.abort = angular.noop; -} - - -/** - * @ngdoc function - * @name ngMock.$timeout - * @description - * - * This service is just a simple decorator for {@link ng.$timeout $timeout} service - * that adds a "flush" and "verifyNoPendingTasks" methods. - */ - -angular.mock.$TimeoutDecorator = function($delegate, $browser) { - - /** - * @ngdoc method - * @name ngMock.$timeout#flush - * @methodOf ngMock.$timeout - * @description - * - * Flushes the queue of pending tasks. - * - * @param {number=} delay maximum timeout amount to flush up until - */ - $delegate.flush = function(delay) { - $browser.defer.flush(delay); - }; - - /** - * @ngdoc method - * @name ngMock.$timeout#verifyNoPendingTasks - * @methodOf ngMock.$timeout - * @description - * - * Verifies that there are no pending tasks that need to be flushed. - */ - $delegate.verifyNoPendingTasks = function() { - if ($browser.deferredFns.length) { - throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' + - formatPendingTasksAsString($browser.deferredFns)); - } - }; - - function formatPendingTasksAsString(tasks) { - var result = []; - angular.forEach(tasks, function(task) { - result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}'); - }); - - return result.join(', '); - } - - return $delegate; -}; - -/** - * - */ -angular.mock.$RootElementProvider = function() { - this.$get = function() { - return angular.element(''); - }; -}; - -/** - * @ngdoc overview - * @name ngMock - * @description - * - * # ngMock - * - * The `ngMock` module providers support to inject and mock Angular services into unit tests. - * In addition, ngMock also extends various core ng services such that they can be - * inspected and controlled in a synchronous manner within test code. - * - * {@installModule mocks} - * - * - * - */ -angular.module('ngMock', ['ng']).provider({ - $browser: angular.mock.$BrowserProvider, - $exceptionHandler: angular.mock.$ExceptionHandlerProvider, - $log: angular.mock.$LogProvider, - $interval: angular.mock.$IntervalProvider, - $httpBackend: angular.mock.$HttpBackendProvider, - $rootElement: angular.mock.$RootElementProvider -}).config(['$provide', function($provide) { - $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); -}]); - -/** - * @ngdoc overview - * @name ngMockE2E - * @description - * - * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. - * Currently there is only one mock present in this module - - * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock. - */ -angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { - $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); -}]); - -/** - * @ngdoc object - * @name ngMockE2E.$httpBackend - * @description - * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of - * applications that use the {@link ng.$http $http service}. - * - * *Note*: For fake http backend implementation suitable for unit testing please see - * {@link ngMock.$httpBackend unit-testing $httpBackend mock}. - * - * This implementation can be used to respond with static or dynamic responses via the `when` api - * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the - * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch - * templates from a webserver). - * - * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application - * is being developed with the real backend api replaced with a mock, it is often desirable for - * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch - * templates or static files from the webserver). To configure the backend with this behavior - * use the `passThrough` request handler of `when` instead of `respond`. - * - * Additionally, we don't want to manually have to flush mocked out requests like we do during unit - * testing. For this reason the e2e $httpBackend automatically flushes mocked out requests - * automatically, closely simulating the behavior of the XMLHttpRequest object. - * - * To setup the application to run with this http backend, you have to create a module that depends - * on the `ngMockE2E` and your application modules and defines the fake backend: - * - *
- * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); - * myAppDev.run(function($httpBackend) { - * phones = [{name: 'phone1'}, {name: 'phone2'}]; - * - * // returns the current list of phones - * $httpBackend.whenGET('/phones').respond(phones); - * - * // adds a new phone to the phones array - * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { - * phones.push(angular.fromJson(data)); - * }); - * $httpBackend.whenGET(/^\/templates\//).passThrough(); - * //... - * }); - *- * - * Afterwards, bootstrap your app with this new module. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#when - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can return - * an array containing response status (number), response data (string) and response headers - * (Object). - * - passThrough – `{function()}` – Any request matching a backend definition with `passThrough` - * handler, will be pass through to the real backend (an XHR request will be made to the - * server. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenGET - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenHEAD - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenDELETE - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenPOST - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenPUT - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenPATCH - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for PATCH requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ - -/** - * @ngdoc method - * @name ngMockE2E.$httpBackend#whenJSONP - * @methodOf ngMockE2E.$httpBackend - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp} url HTTP url. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. - */ -angular.mock.e2e = {}; -angular.mock.e2e.$httpBackendDecorator = - ['$rootScope', '$delegate', '$browser', createHttpBackendMock]; - - -angular.mock.clearDataCache = function() { - var key, - cache = angular.element.cache; - - for(key in cache) { - if (Object.prototype.hasOwnProperty.call(cache,key)) { - var handle = cache[key].handle; - - handle && angular.element(handle.elem).off(); - delete cache[key]; - } - } -}; - - - -(window.jasmine || window.mocha) && (function(window) { - - var currentSpec = null; - - beforeEach(function() { - currentSpec = this; - }); - - afterEach(function() { - var injector = currentSpec.$injector; - - currentSpec.$injector = null; - currentSpec.$modules = null; - currentSpec = null; - - if (injector) { - injector.get('$rootElement').off(); - injector.get('$browser').pollFns.length = 0; - } - - angular.mock.clearDataCache(); - - // clean up jquery's fragment cache - angular.forEach(angular.element.fragments, function(val, key) { - delete angular.element.fragments[key]; - }); - - MockXhr.$$lastInstance = null; - - angular.forEach(angular.callbacks, function(val, key) { - delete angular.callbacks[key]; - }); - angular.callbacks.counter = 0; - }); - - function isSpecRunning() { - return currentSpec && (window.mocha || currentSpec.queue.running); - } - - /** - * @ngdoc function - * @name angular.mock.module - * @description - * - * *NOTE*: This function is also published on window for easy access.
- * - * angular.module('myApplicationModule', []) - * .value('mode', 'app') - * .value('version', 'v1.0.1'); - * - * - * describe('MyApp', function() { - * - * // You need to load modules that you want to test, - * // it loads only the "ng" module by default. - * beforeEach(module('myApplicationModule')); - * - * - * // inject() is used to inject arguments of all given functions - * it('should provide a version', inject(function(mode, version) { - * expect(version).toEqual('v1.0.1'); - * expect(mode).toEqual('app'); - * })); - * - * - * // The inject and module method can also be used inside of the it or beforeEach - * it('should override a version and test the new version is injected', function() { - * // module() takes functions or strings (module aliases) - * module(function($provide) { - * $provide.value('version', 'overridden'); // override version here - * }); - * - * inject(function(version) { - * expect(version).toEqual('overridden'); - * }); - * }); - * }); - * - *- * - * @param {...Function} fns any number of functions which will be injected using the injector. - */ - window.inject = angular.mock.inject = function() { - var blockFns = Array.prototype.slice.call(arguments, 0); - var errorForStack = new Error('Declaration Location'); - return isSpecRunning() ? workFn() : workFn; - ///////////////////// - function workFn() { - var modules = currentSpec.$modules || []; - - modules.unshift('ngMock'); - modules.unshift('ng'); - var injector = currentSpec.$injector; - if (!injector) { - injector = currentSpec.$injector = angular.injector(modules); - } - for(var i = 0, ii = blockFns.length; i < ii; i++) { - try { - /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ - injector.invoke(blockFns[i] || angular.noop, this); - /* jshint +W040 */ - } catch (e) { - if(e.stack && errorForStack) e.stack += '\n' + errorForStack.stack; - throw e; - } finally { - errorForStack = null; - } - } - } - }; -})(window); \ No newline at end of file diff --git a/horizon/static/horizon/lib/angular/angular.js b/horizon/static/horizon/lib/angular/angular.js deleted file mode 100644 index 589ddb327c..0000000000 --- a/horizon/static/horizon/lib/angular/angular.js +++ /dev/null @@ -1,20131 +0,0 @@ -/** - * @license AngularJS v1.2.1 - * (c) 2010-2012 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, document, undefined) {'use strict'; - -/** - * @description - * - * This object provides a utility for producing rich Error messages within - * Angular. It can be called as follows: - * - * var exampleMinErr = minErr('example'); - * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); - * - * The above creates an instance of minErr in the example namespace. The - * resulting error will have a namespaced error code of example.one. The - * resulting error will replace {0} with the value of foo, and {1} with the - * value of bar. The object is not restricted in the number of arguments it can - * take. - * - * If fewer arguments are specified than necessary for interpolation, the extra - * interpolation markers will be preserved in the final string. - * - * Since data will be parsed statically during a build step, some restrictions - * are applied with respect to how minErr instances are created and called. - * Instances should have names of the form namespaceMinErr for a minErr created - * using minErr('namespace') . Error codes, namespaces and template strings - * should all be static strings, not variables or general expressions. - * - * @param {string} module The namespace to use for the new minErr instance. - * @returns {function(string, string, ...): Error} instance - */ - -function minErr(module) { - return function () { - var code = arguments[0], - prefix = '[' + (module ? module + ':' : '') + code + '] ', - template = arguments[1], - templateArgs = arguments, - stringify = function (obj) { - if (typeof obj === 'function') { - return obj.toString().replace(/ \{[\s\S]*$/, ''); - } else if (typeof obj === 'undefined') { - return 'undefined'; - } else if (typeof obj !== 'string') { - return JSON.stringify(obj); - } - return obj; - }, - message, i; - - message = prefix + template.replace(/\{\d+\}/g, function (match) { - var index = +match.slice(1, -1), arg; - - if (index + 2 < templateArgs.length) { - arg = templateArgs[index + 2]; - if (typeof arg === 'function') { - return arg.toString().replace(/ ?\{[\s\S]*$/, ''); - } else if (typeof arg === 'undefined') { - return 'undefined'; - } else if (typeof arg !== 'string') { - return toJson(arg); - } - return arg; - } - return match; - }); - - message = message + '\nhttp://errors.angularjs.org/1.2.1/' + - (module ? module + '/' : '') + code; - for (i = 2; i < arguments.length; i++) { - message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + - encodeURIComponent(stringify(arguments[i])); - } - - return new Error(message); - }; -} - -/* We need to tell jshint what variables are being exported */ -/* global - -angular, - -msie, - -jqLite, - -jQuery, - -slice, - -push, - -toString, - -ngMinErr, - -_angular, - -angularModule, - -nodeName_, - -uid, - - -lowercase, - -uppercase, - -manualLowercase, - -manualUppercase, - -nodeName_, - -isArrayLike, - -forEach, - -sortedKeys, - -forEachSorted, - -reverseParams, - -nextUid, - -setHashKey, - -extend, - -int, - -inherit, - -noop, - -identity, - -valueFn, - -isUndefined, - -isDefined, - -isObject, - -isString, - -isNumber, - -isDate, - -isArray, - -isFunction, - -isRegExp, - -isWindow, - -isScope, - -isFile, - -isBoolean, - -trim, - -isElement, - -makeMap, - -map, - -size, - -includes, - -indexOf, - -arrayRemove, - -isLeafNode, - -copy, - -shallowCopy, - -equals, - -csp, - -concat, - -sliceArgs, - -bind, - -toJsonReplacer, - -toJson, - -fromJson, - -toBoolean, - -startingTag, - -tryDecodeURIComponent, - -parseKeyValue, - -toKeyValue, - -encodeUriSegment, - -encodeUriQuery, - -angularInit, - -bootstrap, - -snake_case, - -bindJQuery, - -assertArg, - -assertArgFn, - -assertNotHasOwnProperty, - -getter, - -getBlockElements - -*/ - -//////////////////////////////////// - -/** - * @ngdoc function - * @name angular.lowercase - * @function - * - * @description Converts the specified string to lowercase. - * @param {string} string String to be converted to lowercase. - * @returns {string} Lowercased string. - */ -var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;}; - - -/** - * @ngdoc function - * @name angular.uppercase - * @function - * - * @description Converts the specified string to uppercase. - * @param {string} string String to be converted to uppercase. - * @returns {string} Uppercased string. - */ -var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;}; - - -var manualLowercase = function(s) { - /* jshint bitwise: false */ - return isString(s) - ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);}) - : s; -}; -var manualUppercase = function(s) { - /* jshint bitwise: false */ - return isString(s) - ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);}) - : s; -}; - - -// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish -// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods -// with correct but slower alternatives. -if ('i' !== 'I'.toLowerCase()) { - lowercase = manualLowercase; - uppercase = manualUppercase; -} - - -var /** holds major version number for IE or NaN for real browsers */ - msie, - jqLite, // delay binding since jQuery could be loaded after us. - jQuery, // delay binding - slice = [].slice, - push = [].push, - toString = Object.prototype.toString, - ngMinErr = minErr('ng'), - - - _angular = window.angular, - /** @name angular */ - angular = window.angular || (window.angular = {}), - angularModule, - nodeName_, - uid = ['0', '0', '0']; - -/** - * IE 11 changed the format of the UserAgent string. - * See http://msdn.microsoft.com/en-us/library/ms537503.aspx - */ -msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]); -if (isNaN(msie)) { - msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]); -} - - -/** - * @private - * @param {*} obj - * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, - * String ...) - */ -function isArrayLike(obj) { - if (obj == null || isWindow(obj)) { - return false; - } - - var length = obj.length; - - if (obj.nodeType === 1 && length) { - return true; - } - - return isString(obj) || isArray(obj) || length === 0 || - typeof length === 'number' && length > 0 && (length - 1) in obj; -} - -/** - * @ngdoc function - * @name angular.forEach - * @function - * - * @description - * Invokes the `iterator` function once for each item in `obj` collection, which can be either an - * object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value` - * is the value of an object property or an array element and `key` is the object property key or - * array element index. Specifying a `context` for the function is optional. - * - * Note: this function was previously known as `angular.foreach`. - * -
- var values = {name: 'misko', gender: 'male'}; - var log = []; - angular.forEach(values, function(value, key){ - this.push(key + ': ' + value); - }, log); - expect(log).toEqual(['name: misko', 'gender:male']); -- * - * @param {Object|Array} obj Object to iterate over. - * @param {Function} iterator Iterator function. - * @param {Object=} context Object to become context (`this`) for the iterator function. - * @returns {Object|Array} Reference to `obj`. - */ -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)) { - iterator.call(context, obj[key], key); - } - } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context); - } else if (isArrayLike(obj)) { - for (key = 0; key < obj.length; key++) - iterator.call(context, obj[key], key); - } else { - for (key in obj) { - if (obj.hasOwnProperty(key)) { - iterator.call(context, obj[key], key); - } - } - } - } - return obj; -} - -function sortedKeys(obj) { - var keys = []; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - keys.push(key); - } - } - return keys.sort(); -} - -function forEachSorted(obj, iterator, context) { - var keys = sortedKeys(obj); - for ( var i = 0; i < keys.length; i++) { - iterator.call(context, obj[keys[i]], keys[i]); - } - return keys; -} - - -/** - * when using forEach the params are value, key, but it is often useful to have key, value. - * @param {function(string, *)} iteratorFn - * @returns {function(*, string)} - */ -function reverseParams(iteratorFn) { - return function(value, key) { iteratorFn(key, value); }; -} - -/** - * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric - * characters such as '012ABC'. The reason why we are not using simply a number counter is that - * the number string gets longer over time, and it can also overflow, where as the nextId - * will grow much slower, it is a string, and it will never overflow. - * - * @returns an unique alpha-numeric string - */ -function nextUid() { - var index = uid.length; - var digit; - - while(index) { - index--; - digit = uid[index].charCodeAt(0); - if (digit == 57 /*'9'*/) { - uid[index] = 'A'; - return uid.join(''); - } - if (digit == 90 /*'Z'*/) { - uid[index] = '0'; - } else { - uid[index] = String.fromCharCode(digit + 1); - return uid.join(''); - } - } - uid.unshift('0'); - return uid.join(''); -} - - -/** - * Set or clear the hashkey for an object. - * @param obj object - * @param h the hashkey (!truthy to delete the hashkey) - */ -function setHashKey(obj, h) { - if (h) { - obj.$$hashKey = h; - } - else { - delete obj.$$hashKey; - } -} - -/** - * @ngdoc function - * @name angular.extend - * @function - * - * @description - * Extends the destination object `dst` by copying all of the properties from the `src` object(s) - * to `dst`. You can specify multiple `src` objects. - * - * @param {Object} dst Destination object. - * @param {...Object} src Source object(s). - * @returns {Object} Reference to `dst`. - */ -function extend(dst) { - var h = dst.$$hashKey; - forEach(arguments, function(obj){ - if (obj !== dst) { - forEach(obj, function(value, key){ - dst[key] = value; - }); - } - }); - - setHashKey(dst,h); - return dst; -} - -function int(str) { - return parseInt(str, 10); -} - - -function inherit(parent, extra) { - return extend(new (extend(function() {}, {prototype:parent}))(), extra); -} - -/** - * @ngdoc function - * @name angular.noop - * @function - * - * @description - * A function that performs no operations. This function can be useful when writing code in the - * functional style. -
- function foo(callback) { - var result = calculateResult(); - (callback || angular.noop)(result); - } -- */ -function noop() {} -noop.$inject = []; - - -/** - * @ngdoc function - * @name angular.identity - * @function - * - * @description - * A function that returns its first argument. This function is useful when writing code in the - * functional style. - * -
- function transformer(transformationFn, value) { - return (transformationFn || angular.identity)(value); - }; -- */ -function identity($) {return $;} -identity.$inject = []; - - -function valueFn(value) {return function() {return value;};} - -/** - * @ngdoc function - * @name angular.isUndefined - * @function - * - * @description - * Determines if a reference is undefined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is undefined. - */ -function isUndefined(value){return typeof value == 'undefined';} - - -/** - * @ngdoc function - * @name angular.isDefined - * @function - * - * @description - * Determines if a reference is defined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is defined. - */ -function isDefined(value){return typeof value != 'undefined';} - - -/** - * @ngdoc function - * @name angular.isObject - * @function - * - * @description - * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not - * considered to be objects. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Object` but not `null`. - */ -function isObject(value){return value != null && typeof value == 'object';} - - -/** - * @ngdoc function - * @name angular.isString - * @function - * - * @description - * Determines if a reference is a `String`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `String`. - */ -function isString(value){return typeof value == 'string';} - - -/** - * @ngdoc function - * @name angular.isNumber - * @function - * - * @description - * Determines if a reference is a `Number`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Number`. - */ -function isNumber(value){return typeof value == 'number';} - - -/** - * @ngdoc function - * @name angular.isDate - * @function - * - * @description - * Determines if a value is a date. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Date`. - */ -function isDate(value){ - return toString.apply(value) == '[object Date]'; -} - - -/** - * @ngdoc function - * @name angular.isArray - * @function - * - * @description - * Determines if a reference is an `Array`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Array`. - */ -function isArray(value) { - return toString.apply(value) == '[object Array]'; -} - - -/** - * @ngdoc function - * @name angular.isFunction - * @function - * - * @description - * Determines if a reference is a `Function`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Function`. - */ -function isFunction(value){return typeof value == 'function';} - - -/** - * Determines if a value is a regular expression object. - * - * @private - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `RegExp`. - */ -function isRegExp(value) { - return toString.apply(value) == '[object RegExp]'; -} - - -/** - * Checks if `obj` is a window object. - * - * @private - * @param {*} obj Object to check - * @returns {boolean} True if `obj` is a window obj. - */ -function isWindow(obj) { - return obj && obj.document && obj.location && obj.alert && obj.setInterval; -} - - -function isScope(obj) { - return obj && obj.$evalAsync && obj.$watch; -} - - -function isFile(obj) { - return toString.apply(obj) === '[object File]'; -} - - -function isBoolean(value) { - return typeof value == 'boolean'; -} - - -var trim = (function() { - // native trim is way faster: http://jsperf.com/angular-trim-test - // but IE doesn't have it... :-( - // TODO: we should move this into IE/ES5 polyfill - if (!String.prototype.trim) { - return function(value) { - return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; - }; - } - return function(value) { - return isString(value) ? value.trim() : value; - }; -})(); - - -/** - * @ngdoc function - * @name angular.isElement - * @function - * - * @description - * Determines if a reference is a DOM element (or wrapped jQuery element). - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element). - */ -function isElement(node) { - return node && - (node.nodeName // we are a direct element - || (node.on && node.find)); // we have an on and find method part of jQuery API -} - -/** - * @param str 'key1,key2,...' - * @returns {object} in the form of {key1:true, key2:true, ...} - */ -function makeMap(str){ - var obj = {}, items = str.split(","), i; - for ( i = 0; i < items.length; i++ ) - obj[ items[i] ] = true; - return obj; -} - - -if (msie < 9) { - nodeName_ = function(element) { - element = element.nodeName ? element : element[0]; - return (element.scopeName && element.scopeName != 'HTML') - ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName; - }; -} else { - nodeName_ = function(element) { - return element.nodeName ? element.nodeName : element[0].nodeName; - }; -} - - -function map(obj, iterator, context) { - var results = []; - forEach(obj, function(value, index, list) { - results.push(iterator.call(context, value, index, list)); - }); - return results; -} - - -/** - * @description - * Determines the number of elements in an array, the number of properties an object has, or - * the length of a string. - * - * Note: This function is used to augment the Object type in Angular expressions. See - * {@link angular.Object} for more information about Angular arrays. - * - * @param {Object|Array|string} obj Object, array, or string to inspect. - * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object - * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array. - */ -function size(obj, ownPropsOnly) { - var count = 0, key; - - if (isArray(obj) || isString(obj)) { - return obj.length; - } else if (isObject(obj)){ - for (key in obj) - if (!ownPropsOnly || obj.hasOwnProperty(key)) - count++; - } - - return count; -} - - -function includes(array, obj) { - return indexOf(array, obj) != -1; -} - -function indexOf(array, obj) { - if (array.indexOf) return array.indexOf(obj); - - for ( var i = 0; i < array.length; i++) { - if (obj === array[i]) return i; - } - return -1; -} - -function arrayRemove(array, value) { - var index = indexOf(array, value); - if (index >=0) - array.splice(index, 1); - return value; -} - -function isLeafNode (node) { - if (node) { - switch (node.nodeName) { - case "OPTION": - case "PRE": - case "TITLE": - return true; - } - } - return false; -} - -/** - * @ngdoc function - * @name angular.copy - * @function - * - * @description - * Creates a deep copy of `source`, which should be an object or an array. - * - * * If no destination is supplied, a copy of the object or array is created. - * * If a destination is provided, all of its elements (for array) or properties (for objects) - * are deleted and then all elements/properties from the source are copied to it. - * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. - * * If `source` is identical to 'destination' an exception will be thrown. - * - * @param {*} source The source that will be used to make a copy. - * Can be any type, including primitives, `null`, and `undefined`. - * @param {(Object|Array)=} destination Destination into which the source is copied. If - * provided, must be of the same type as `source`. - * @returns {*} The copy or updated `destination`, if `destination` was specified. - * - * @example -
form = {{user | json}}-
master = {{master | json}}-
- * // Create a new module - * var myModule = angular.module('myModule', []); - * - * // register a new service - * myModule.value('appName', 'MyCoolApp'); - * - * // configure existing services inside initialization blocks. - * myModule.config(function($locationProvider) { - * // Configure existing providers - * $locationProvider.hashPrefix('!'); - * }); - *- * - * Then you can create an injector and load your modules like this: - * - *
- * var injector = angular.injector(['ng', 'MyModule']) - *- * - * However it's more likely that you'll just use - * {@link ng.directive:ngApp ngApp} or - * {@link angular.bootstrap} to simplify this process for you. - * - * @param {!string} name The name of the module to create or retrieve. - * @param {Array.
- * module.animation('.animation-name', function($inject1, $inject2) { - * return { - * eventName : function(element, done) { - * //code to run the animation - * //once complete, then run done() - * return function cancellationFunction(element) { - * //code to cancel the animation - * } - * } - * } - * }) - *- * - * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and - * {@link ngAnimate ngAnimate module} for more information. - */ - animation: invokeLater('$animateProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#filter - * @methodOf angular.Module - * @param {string} name Filter name. - * @param {Function} filterFactory Factory function for creating new instance of filter. - * @description - * See {@link ng.$filterProvider#register $filterProvider.register()}. - */ - filter: invokeLater('$filterProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#controller - * @methodOf angular.Module - * @param {string|Object} name Controller name, or an object map of controllers where the - * keys are the names and the values are the constructors. - * @param {Function} constructor Controller constructor function. - * @description - * See {@link ng.$controllerProvider#register $controllerProvider.register()}. - */ - controller: invokeLater('$controllerProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#directive - * @methodOf angular.Module - * @param {string|Object} name Directive name, or an object map of directives where the - * keys are the names and the values are the factories. - * @param {Function} directiveFactory Factory function for creating new instance of - * directives. - * @description - * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. - */ - directive: invokeLater('$compileProvider', 'directive'), - - /** - * @ngdoc method - * @name angular.Module#config - * @methodOf angular.Module - * @param {Function} configFn Execute this function on module load. Useful for service - * configuration. - * @description - * Use this method to register work which needs to be performed on module loading. - */ - config: config, - - /** - * @ngdoc method - * @name angular.Module#run - * @methodOf angular.Module - * @param {Function} initializationFn Execute this function after injector creation. - * Useful for application initialization. - * @description - * Use this method to register work which should be performed when the injector is done - * loading all modules. - */ - run: function(block) { - runBlocks.push(block); - return this; - } - }; - - if (configFn) { - config(configFn); - } - - return moduleInstance; - - /** - * @param {string} provider - * @param {string} method - * @param {String=} insertMethod - * @returns {angular.Module} - */ - function invokeLater(provider, method, insertMethod) { - return function() { - invokeQueue[insertMethod || 'push']([provider, method, arguments]); - return moduleInstance; - }; - } - }); - }; - }); - -} - -/* global - angularModule: true, - version: true, - - $LocaleProvider, - $CompileProvider, - - htmlAnchorDirective, - inputDirective, - inputDirective, - formDirective, - scriptDirective, - selectDirective, - styleDirective, - optionDirective, - ngBindDirective, - ngBindHtmlDirective, - ngBindTemplateDirective, - ngClassDirective, - ngClassEvenDirective, - ngClassOddDirective, - ngCspDirective, - ngCloakDirective, - ngControllerDirective, - ngFormDirective, - ngHideDirective, - ngIfDirective, - ngIncludeDirective, - ngInitDirective, - ngNonBindableDirective, - ngPluralizeDirective, - ngRepeatDirective, - ngShowDirective, - ngStyleDirective, - ngSwitchDirective, - ngSwitchWhenDirective, - ngSwitchDefaultDirective, - ngOptionsDirective, - ngTranscludeDirective, - ngModelDirective, - ngListDirective, - ngChangeDirective, - requiredDirective, - requiredDirective, - ngValueDirective, - ngAttributeAliasDirectives, - ngEventDirectives, - - $AnchorScrollProvider, - $AnimateProvider, - $BrowserProvider, - $CacheFactoryProvider, - $ControllerProvider, - $DocumentProvider, - $ExceptionHandlerProvider, - $FilterProvider, - $InterpolateProvider, - $IntervalProvider, - $HttpProvider, - $HttpBackendProvider, - $LocationProvider, - $LogProvider, - $ParseProvider, - $RootScopeProvider, - $QProvider, - $SceProvider, - $SceDelegateProvider, - $SnifferProvider, - $TemplateCacheProvider, - $TimeoutProvider, - $WindowProvider -*/ - - -/** - * @ngdoc property - * @name angular.version - * @description - * An object that contains information about the current AngularJS version. This object has the - * following properties: - * - * - `full` – `{string}` – Full version string, such as "0.9.18". - * - `major` – `{number}` – Major version number, such as "0". - * - `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.1', // all of these placeholder strings will be replaced by grunt's - major: 1, // package task - minor: 2, - dot: 1, - codeName: 'underscore-empathy' -}; - - -function publishExternalAPI(angular){ - extend(angular, { - 'bootstrap': bootstrap, - 'copy': copy, - 'extend': extend, - 'equals': equals, - 'element': jqLite, - 'forEach': forEach, - 'injector': createInjector, - 'noop':noop, - 'bind':bind, - 'toJson': toJson, - 'fromJson': fromJson, - 'identity':identity, - 'isUndefined': isUndefined, - 'isDefined': isDefined, - 'isString': isString, - 'isFunction': isFunction, - 'isObject': isObject, - 'isNumber': isNumber, - 'isElement': isElement, - 'isArray': isArray, - 'version': version, - 'isDate': isDate, - 'lowercase': lowercase, - 'uppercase': uppercase, - 'callbacks': {counter: 0}, - '$$minErr': minErr, - '$$csp': csp - }); - - angularModule = setupModuleLoader(window); - try { - angularModule('ngLocale'); - } catch (e) { - angularModule('ngLocale', []).provider('$locale', $LocaleProvider); - } - - angularModule('ng', ['ngLocale'], ['$provide', - function ngModule($provide) { - $provide.provider('$compile', $CompileProvider). - directive({ - a: htmlAnchorDirective, - input: inputDirective, - textarea: inputDirective, - form: formDirective, - script: scriptDirective, - select: selectDirective, - style: styleDirective, - option: optionDirective, - ngBind: ngBindDirective, - ngBindHtml: ngBindHtmlDirective, - ngBindTemplate: ngBindTemplateDirective, - ngClass: ngClassDirective, - ngClassEven: ngClassEvenDirective, - ngClassOdd: ngClassOddDirective, - ngCloak: ngCloakDirective, - ngController: ngControllerDirective, - ngForm: ngFormDirective, - ngHide: ngHideDirective, - ngIf: ngIfDirective, - ngInclude: ngIncludeDirective, - ngInit: ngInitDirective, - ngNonBindable: ngNonBindableDirective, - ngPluralize: ngPluralizeDirective, - ngRepeat: ngRepeatDirective, - ngShow: ngShowDirective, - ngStyle: ngStyleDirective, - ngSwitch: ngSwitchDirective, - ngSwitchWhen: ngSwitchWhenDirective, - ngSwitchDefault: ngSwitchDefaultDirective, - ngOptions: ngOptionsDirective, - ngTransclude: ngTranscludeDirective, - ngModel: ngModelDirective, - ngList: ngListDirective, - ngChange: ngChangeDirective, - required: requiredDirective, - ngRequired: requiredDirective, - ngValue: ngValueDirective - }). - directive(ngAttributeAliasDirectives). - directive(ngEventDirectives); - $provide.provider({ - $anchorScroll: $AnchorScrollProvider, - $animate: $AnimateProvider, - $browser: $BrowserProvider, - $cacheFactory: $CacheFactoryProvider, - $controller: $ControllerProvider, - $document: $DocumentProvider, - $exceptionHandler: $ExceptionHandlerProvider, - $filter: $FilterProvider, - $interpolate: $InterpolateProvider, - $interval: $IntervalProvider, - $http: $HttpProvider, - $httpBackend: $HttpBackendProvider, - $location: $LocationProvider, - $log: $LogProvider, - $parse: $ParseProvider, - $rootScope: $RootScopeProvider, - $q: $QProvider, - $sce: $SceProvider, - $sceDelegate: $SceDelegateProvider, - $sniffer: $SnifferProvider, - $templateCache: $TemplateCacheProvider, - $timeout: $TimeoutProvider, - $window: $WindowProvider - }); - } - ]); -} - -/* global - - -JQLitePrototype, - -addEventListenerFn, - -removeEventListenerFn, - -BOOLEAN_ATTR -*/ - -////////////////////////////////// -//JQLite -////////////////////////////////// - -/** - * @ngdoc function - * @name angular.element - * @function - * - * @description - * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. - * - * If jQuery is available, `angular.element` is an alias for the - * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element` - * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite." - * - *
- * // create an injector - * var $injector = angular.injector(['ng']); - * - * // use the injector to kick off your application - * // use the type inference to auto inject arguments, or use implicit injection - * $injector.invoke(function($rootScope, $compile, $document){ - * $compile($document)($rootScope); - * $rootScope.$digest(); - * }); - *- */ - - -/** - * @ngdoc overview - * @name AUTO - * @description - * - * Implicit module which gets automatically added to each {@link AUTO.$injector $injector}. - */ - -var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; -var FN_ARG_SPLIT = /,/; -var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; -var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -var $injectorMinErr = minErr('$injector'); -function annotate(fn) { - var $inject, - fnText, - argDecl, - last; - - if (typeof fn == 'function') { - if (!($inject = fn.$inject)) { - $inject = []; - if (fn.length) { - fnText = fn.toString().replace(STRIP_COMMENTS, ''); - argDecl = fnText.match(FN_ARGS); - forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){ - arg.replace(FN_ARG, function(all, underscore, name){ - $inject.push(name); - }); - }); - } - fn.$inject = $inject; - } - } else if (isArray(fn)) { - last = fn.length - 1; - assertArgFn(fn[last], 'fn'); - $inject = fn.slice(0, last); - } else { - assertArgFn(fn, 'fn', true); - } - return $inject; -} - -/////////////////////////////////////// - -/** - * @ngdoc object - * @name AUTO.$injector - * @function - * - * @description - * - * `$injector` is used to retrieve object instances as defined by - * {@link AUTO.$provide provider}, instantiate types, invoke methods, - * and load modules. - * - * The following always holds true: - * - *
- * var $injector = angular.injector(); - * expect($injector.get('$injector')).toBe($injector); - * expect($injector.invoke(function($injector){ - * return $injector; - * }).toBe($injector); - *- * - * # Injection Function Annotation - * - * JavaScript does not have annotations, and annotations are needed for dependency injection. The - * following are all valid ways of annotating function with injection arguments and are equivalent. - * - *
- * // inferred (only works if code not minified/obfuscated) - * $injector.invoke(function(serviceA){}); - * - * // annotated - * function explicit(serviceA) {}; - * explicit.$inject = ['serviceA']; - * $injector.invoke(explicit); - * - * // inline - * $injector.invoke(['serviceA', function(serviceA){}]); - *- * - * ## Inference - * - * In JavaScript calling `toString()` on a function returns the function definition. The definition - * can then be parsed and the function arguments can be extracted. *NOTE:* This does not work with - * minification, and obfuscation tools since these tools change the argument names. - * - * ## `$inject` Annotation - * By adding a `$inject` property onto a function the injection parameters can be specified. - * - * ## Inline - * As an array of injection names, where the last item in the array is the function to call. - */ - -/** - * @ngdoc method - * @name AUTO.$injector#get - * @methodOf AUTO.$injector - * - * @description - * Return an instance of the service. - * - * @param {string} name The name of the instance to retrieve. - * @return {*} The instance. - */ - -/** - * @ngdoc method - * @name AUTO.$injector#invoke - * @methodOf AUTO.$injector - * - * @description - * Invoke the method and supply the method arguments from the `$injector`. - * - * @param {!function} fn The function to invoke. Function parameters are injected according to the - * {@link guide/di $inject Annotation} rules. - * @param {Object=} self The `this` for the invoked method. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {*} the value returned by the invoked `fn` function. - */ - -/** - * @ngdoc method - * @name AUTO.$injector#has - * @methodOf AUTO.$injector - * - * @description - * Allows the user to query if the particular service exist. - * - * @param {string} Name of the service to query. - * @returns {boolean} returns true if injector has given service. - */ - -/** - * @ngdoc method - * @name AUTO.$injector#instantiate - * @methodOf AUTO.$injector - * @description - * Create a new instance of JS type. The method takes a constructor function invokes the new - * operator and supplies all of the arguments to the constructor function as specified by the - * constructor annotation. - * - * @param {function} Type Annotated constructor function. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {Object} new instance of `Type`. - */ - -/** - * @ngdoc method - * @name AUTO.$injector#annotate - * @methodOf AUTO.$injector - * - * @description - * Returns an array of service names which the function is requesting for injection. This API is - * used by the injector to determine which services need to be injected into the function when the - * function is invoked. There are three ways in which the function can be annotated with the needed - * dependencies. - * - * # Argument names - * - * The simplest form is to extract the dependencies from the arguments of the function. This is done - * by converting the function into a string using `toString()` method and extracting the argument - * names. - *
- * // Given - * function MyController($scope, $route) { - * // ... - * } - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - *- * - * This method does not work with code minification / obfuscation. For this reason the following - * annotation strategies are supported. - * - * # The `$inject` property - * - * If a function has an `$inject` property and its value is an array of strings, then the strings - * represent names of services to be injected into the function. - *
- * // Given - * var MyController = function(obfuscatedScope, obfuscatedRoute) { - * // ... - * } - * // Define function dependencies - * MyController.$inject = ['$scope', '$route']; - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - *- * - * # The array notation - * - * It is often desirable to inline Injected functions and that's when setting the `$inject` property - * is very inconvenient. In these situations using the array notation to specify the dependencies in - * a way that survives minification is a better choice: - * - *
- * // We wish to write this (not minification / obfuscation safe) - * injector.invoke(function($compile, $rootScope) { - * // ... - * }); - * - * // We are forced to write break inlining - * var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) { - * // ... - * }; - * tmpFn.$inject = ['$compile', '$rootScope']; - * injector.invoke(tmpFn); - * - * // To better support inline function the inline annotation is supported - * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) { - * // ... - * }]); - * - * // Therefore - * expect(injector.annotate( - * ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}]) - * ).toEqual(['$compile', '$rootScope']); - *- * - * @param {function|Array.
- * // Define the eventTracker provider - * function EventTrackerProvider() { - * var trackingUrl = '/track'; - * - * // A provider method for configuring where the tracked events should been saved - * this.setTrackingUrl = function(url) { - * trackingUrl = url; - * }; - * - * // The service factory function - * this.$get = ['$http', function($http) { - * var trackedEvents = {}; - * return { - * // Call this to track an event - * event: function(event) { - * var count = trackedEvents[event] || 0; - * count += 1; - * trackedEvents[event] = count; - * return count; - * }, - * // Call this to save the tracked events to the trackingUrl - * save: function() { - * $http.post(trackingUrl, trackedEvents); - * } - * }; - * }]; - * } - * - * describe('eventTracker', function() { - * var postSpy; - * - * beforeEach(module(function($provide) { - * // Register the eventTracker provider - * $provide.provider('eventTracker', EventTrackerProvider); - * })); - * - * beforeEach(module(function(eventTrackerProvider) { - * // Configure eventTracker provider - * eventTrackerProvider.setTrackingUrl('/custom-track'); - * })); - * - * it('tracks events', inject(function(eventTracker) { - * expect(eventTracker.event('login')).toEqual(1); - * expect(eventTracker.event('login')).toEqual(2); - * })); - * - * it('saves to the tracking url', inject(function(eventTracker, $http) { - * postSpy = spyOn($http, 'post'); - * eventTracker.event('login'); - * eventTracker.save(); - * expect(postSpy).toHaveBeenCalled(); - * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track'); - * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track'); - * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 }); - * })); - * }); - *- */ - -/** - * @ngdoc method - * @name AUTO.$provide#factory - * @methodOf AUTO.$provide - * @description - * - * Register a **service factory**, which will be called to return the service instance. - * This is short for registering a service where its provider consists of only a `$get` property, - * which is the given service factory function. - * You should use {@link AUTO.$provide#factory $provide.factory(getFn)} if you do not need to - * configure your service in a provider. - * - * @param {string} name The name of the instance. - * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand - * for `$provide.provider(name, {$get: $getFn})`. - * @returns {Object} registered provider instance - * - * @example - * Here is an example of registering a service - *
- * $provide.factory('ping', ['$http', function($http) { - * return function ping() { - * return $http.send('/ping'); - * }; - * }]); - *- * You would then inject and use this service like this: - *
- * someModule.controller('Ctrl', ['ping', function(ping) { - * ping(); - * }]); - *- */ - - -/** - * @ngdoc method - * @name AUTO.$provide#service - * @methodOf AUTO.$provide - * @description - * - * Register a **service constructor**, which will be invoked with `new` to create the service - * instance. - * This is short for registering a service where its provider's `$get` property is the service - * constructor function that will be used to instantiate the service instance. - * - * You should use {@link AUTO.$provide#methods_service $provide.service(class)} if you define your service - * as a type/class. This is common when using {@link http://coffeescript.org CoffeeScript}. - * - * @param {string} name The name of the instance. - * @param {Function} constructor A class (constructor function) that will be instantiated. - * @returns {Object} registered provider instance - * - * @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. - *
- * class Ping - * constructor: (@$http)-> - * send: ()=> - * @$http.get('/ping') - * - * $provide.service('ping', ['$http', Ping]) - *- * You would then inject and use this service like this: - *
- * someModule.controller 'Ctrl', ['ping', (ping)-> - * ping.send() - * ] - *- */ - - -/** - * @ngdoc method - * @name AUTO.$provide#value - * @methodOf AUTO.$provide - * @description - * - * Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a - * number, an array, an object or a function. This is short for registering a service where its - * provider's `$get` property is a factory function that takes no arguments and returns the **value - * service**. - * - * Value services are similar to constant services, except that they cannot be injected into a - * module configuration function (see {@link angular.Module#config}) but they can be overridden by - * an Angular - * {@link AUTO.$provide#decorator decorator}. - * - * @param {string} name The name of the instance. - * @param {*} value The value. - * @returns {Object} registered provider instance - * - * @example - * Here are some examples of creating value services. - *
- * $provide.constant('ADMIN_USER', 'admin'); - * - * $provide.constant('RoleLookup', { admin: 0, writer: 1, reader: 2 }); - * - * $provide.constant('halfOf', function(value) { - * return value / 2; - * }); - *- */ - - -/** - * @ngdoc method - * @name AUTO.$provide#constant - * @methodOf AUTO.$provide - * @description - * - * Register a **constant service**, such as a string, a number, an array, an object or a function, - * with the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be - * injected into a module configuration function (see {@link angular.Module#config}) and it cannot - * be overridden by an Angular {@link AUTO.$provide#decorator decorator}. - * - * @param {string} name The name of the constant. - * @param {*} value The constant value. - * @returns {Object} registered instance - * - * @example - * Here a some examples of creating constants: - *
- * $provide.constant('SHARD_HEIGHT', 306); - * - * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']); - * - * $provide.constant('double', function(value) { - * return value * 2; - * }); - *- */ - - -/** - * @ngdoc method - * @name AUTO.$provide#decorator - * @methodOf AUTO.$provide - * @description - * - * Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator - * intercepts the creation of a service, allowing it to override or modify the behaviour of the - * service. The object returned by the decorator may be the original service, or a new service - * object which replaces or wraps and delegates to the original service. - * - * @param {string} name The name of the service to decorate. - * @param {function()} decorator This function will be invoked when the service needs to be - * instantiated and should return the decorated service instance. The function is called using - * the {@link AUTO.$injector#invoke injector.invoke} method and is therefore fully injectable. - * Local injection arguments: - * - * * `$delegate` - The original service instance, which can be monkey patched, configured, - * decorated or delegated to. - * - * @example - * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting - * calls to {@link ng.$log#error $log.warn()}. - *
- * $provider.decorator('$log', ['$delegate', function($delegate) { - * $delegate.warn = $delegate.error; - * return $delegate; - * }]); - *- */ - - -function createInjector(modulesToLoad) { - var INSTANTIATING = {}, - providerSuffix = 'Provider', - path = [], - loadedModules = new HashMap(), - providerCache = { - $provide: { - provider: supportObject(provider), - factory: supportObject(factory), - service: supportObject(service), - value: supportObject(value), - constant: supportObject(constant), - decorator: decorator - } - }, - providerInjector = (providerCache.$injector = - createInternalInjector(providerCache, function() { - throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- ')); - })), - instanceCache = {}, - instanceInjector = (instanceCache.$injector = - createInternalInjector(instanceCache, function(servicename) { - var provider = providerInjector.get(servicename + providerSuffix); - return instanceInjector.invoke(provider.$get, provider); - })); - - - forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); }); - - return instanceInjector; - - //////////////////////////////////// - // $provider - //////////////////////////////////// - - function supportObject(delegate) { - return function(key, value) { - if (isObject(key)) { - forEach(key, reverseParams(delegate)); - } else { - return delegate(key, value); - } - }; - } - - function provider(name, provider_) { - assertNotHasOwnProperty(name, 'service'); - if (isFunction(provider_) || isArray(provider_)) { - provider_ = providerInjector.instantiate(provider_); - } - if (!provider_.$get) { - throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); - } - return providerCache[name + providerSuffix] = provider_; - } - - function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } - - function service(name, constructor) { - return factory(name, ['$injector', function($injector) { - return $injector.instantiate(constructor); - }]); - } - - function value(name, val) { return factory(name, valueFn(val)); } - - function constant(name, value) { - assertNotHasOwnProperty(name, 'constant'); - providerCache[name] = value; - instanceCache[name] = value; - } - - function decorator(serviceName, decorFn) { - var origProvider = providerInjector.get(serviceName + providerSuffix), - orig$get = origProvider.$get; - - origProvider.$get = function() { - var origInstance = instanceInjector.invoke(orig$get, origProvider); - return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); - }; - } - - //////////////////////////////////// - // Module Loading - //////////////////////////////////// - function loadModules(modulesToLoad){ - var runBlocks = [], moduleFn, invokeQueue, i, ii; - forEach(modulesToLoad, function(module) { - if (loadedModules.get(module)) return; - loadedModules.put(module, true); - - try { - if (isString(module)) { - moduleFn = angularModule(module); - runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); - - for(invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { - var invokeArgs = invokeQueue[i], - provider = providerInjector.get(invokeArgs[0]); - - provider[invokeArgs[1]].apply(provider, invokeArgs[2]); - } - } else if (isFunction(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else if (isArray(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else { - assertArgFn(module, 'module'); - } - } catch (e) { - if (isArray(module)) { - module = module[module.length - 1]; - } - if (e.message && e.stack && e.stack.indexOf(e.message) == -1) { - // Safari & FF's stack traces don't contain error.message content - // unlike those of Chrome and IE - // So if stack doesn't contain message, we create a new string that contains both. - // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here. - /* jshint -W022 */ - e = e.message + '\n' + e.stack; - } - throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", - module, e.stack || e.message || e); - } - }); - return runBlocks; - } - - //////////////////////////////////// - // internal Injector - //////////////////////////////////// - - function createInternalInjector(cache, factory) { - - function getService(serviceName) { - if (cache.hasOwnProperty(serviceName)) { - if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); - } - return cache[serviceName]; - } else { - try { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - return cache[serviceName] = factory(serviceName); - } finally { - path.shift(); - } - } - } - - function invoke(fn, self, locals){ - var args = [], - $inject = annotate(fn), - length, i, - key; - - for(i = 0, length = $inject.length; i < length; i++) { - key = $inject[i]; - if (typeof key !== 'string') { - throw $injectorMinErr('itkn', - 'Incorrect injection token! Expected service name as string, got {0}', key); - } - args.push( - locals && locals.hasOwnProperty(key) - ? locals[key] - : getService(key) - ); - } - if (!fn.$inject) { - // this means that we must be an array. - fn = fn[length]; - } - - - // Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke - switch (self ? -1 : args.length) { - case 0: return fn(); - case 1: return fn(args[0]); - case 2: return fn(args[0], args[1]); - case 3: return fn(args[0], args[1], args[2]); - case 4: return fn(args[0], args[1], args[2], args[3]); - case 5: return fn(args[0], args[1], args[2], args[3], args[4]); - case 6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - case 8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); - case 9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], - args[8]); - case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], - args[8], args[9]); - default: return fn.apply(self, args); - } - } - - function instantiate(Type, locals) { - var Constructor = function() {}, - instance, returnedValue; - - // Check if Type is annotated and use just the given function at n-1 as parameter - // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]); - Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype; - instance = new Constructor(); - returnedValue = invoke(Type, instance, locals); - - return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance; - } - - return { - invoke: invoke, - instantiate: instantiate, - get: getService, - annotate: annotate, - has: function(name) { - return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); - } - }; - } -} - -/** - * @ngdoc function - * @name ng.$anchorScroll - * @requires $window - * @requires $location - * @requires $rootScope - * - * @description - * When called, it checks current value of `$location.hash()` and scroll to related element, - * according to rules specified in - * {@link http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document Html5 spec}. - * - * It also watches the `$location.hash()` and scrolls whenever it changes to match any anchor. - * This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`. - * - * @example -
- * return { - * eventFn : function(element, done) { - * //code to run the animation - * //once complete, then run done() - * return function cancellationFunction() { - * //code to cancel the animation - * } - * } - * } - *- * - * @param {string} name The name of the animation. - * @param {function} factory The factory function that will be executed to return the animation - * object. - */ - this.register = function(name, factory) { - var key = name + '-animation'; - if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel', - "Expecting class selector starting with '.' got '{0}'.", name); - this.$$selectors[name.substr(1)] = key; - $provide.factory(key, factory); - }; - - this.$get = ['$timeout', function($timeout) { - - /** - * - * @ngdoc object - * @name ng.$animate - * @description The $animate service provides rudimentary DOM manipulation functions to - * insert, remove and move elements within the DOM, as well as adding and removing classes. - * This service is the core service used by the ngAnimate $animator service which provides - * high-level animation hooks for CSS and JavaScript. - * - * $animate is available in the AngularJS core, however, the ngAnimate module must be included - * to enable full out animation support. Otherwise, $animate will only perform simple DOM - * manipulation operations. - * - * To learn more about enabling animation support, click here to visit the {@link ngAnimate - * ngAnimate module page} as well as the {@link ngAnimate.$animate ngAnimate $animate service - * page}. - */ - return { - - /** - * - * @ngdoc function - * @name ng.$animate#enter - * @methodOf ng.$animate - * @function - * @description Inserts the element into the DOM either after the `after` element or within - * the `parent` element. Once complete, the done() callback will be fired (if provided). - * @param {jQuery/jqLite element} element the element which will be inserted into the DOM - * @param {jQuery/jqLite element} parent the parent element which will append the element as - * a child (if the after element is not present) - * @param {jQuery/jqLite element} after the sibling element which will append the element - * after itself - * @param {function=} done callback function that will be called after the element has been - * inserted into the DOM - */ - enter : function(element, parent, after, done) { - var afterNode = after && after[after.length - 1]; - var parentNode = parent && parent[0] || afterNode && afterNode.parentNode; - // IE does not like undefined so we have to pass null. - var afterNextSibling = (afterNode && afterNode.nextSibling) || null; - forEach(element, function(node) { - parentNode.insertBefore(node, afterNextSibling); - }); - done && $timeout(done, 0, false); - }, - - /** - * - * @ngdoc function - * @name ng.$animate#leave - * @methodOf ng.$animate - * @function - * @description Removes the element from the DOM. Once complete, the done() callback will be - * fired (if provided). - * @param {jQuery/jqLite element} element the element which will be removed from the DOM - * @param {function=} done callback function that will be called after the element has been - * removed from the DOM - */ - leave : function(element, done) { - element.remove(); - done && $timeout(done, 0, false); - }, - - /** - * - * @ngdoc function - * @name ng.$animate#move - * @methodOf ng.$animate - * @function - * @description Moves the position of the provided element within the DOM to be placed - * either after the `after` element or inside of the `parent` element. Once complete, the - * done() callback will be fired (if provided). - * - * @param {jQuery/jqLite element} element the element which will be moved around within the - * DOM - * @param {jQuery/jqLite element} parent the parent element where the element will be - * inserted into (if the after element is not present) - * @param {jQuery/jqLite element} after the sibling element where the element will be - * positioned next to - * @param {function=} done the callback function (if provided) that will be fired after the - * element has been moved to its new position - */ - move : function(element, parent, after, done) { - // Do not remove element before insert. Removing will cause data associated with the - // element to be dropped. Insert will implicitly do the remove. - this.enter(element, parent, after, done); - }, - - /** - * - * @ngdoc function - * @name ng.$animate#addClass - * @methodOf ng.$animate - * @function - * @description Adds the provided className CSS class value to the provided element. Once - * complete, the done() callback will be fired (if provided). - * @param {jQuery/jqLite element} element the element which will have the className value - * added to it - * @param {string} className the CSS class which will be added to the element - * @param {function=} done the callback function (if provided) that will be fired after the - * className value has been added to the element - */ - addClass : function(element, className, done) { - className = isString(className) ? - className : - isArray(className) ? className.join(' ') : ''; - forEach(element, function (element) { - jqLiteAddClass(element, className); - }); - done && $timeout(done, 0, false); - }, - - /** - * - * @ngdoc function - * @name ng.$animate#removeClass - * @methodOf ng.$animate - * @function - * @description Removes the provided className CSS class value from the provided element. - * Once complete, the done() callback will be fired (if provided). - * @param {jQuery/jqLite element} element the element which will have the className value - * removed from it - * @param {string} className the CSS class which will be removed from the element - * @param {function=} done the callback function (if provided) that will be fired after the - * className value has been removed from the element - */ - removeClass : function(element, className, done) { - className = isString(className) ? - className : - isArray(className) ? className.join(' ') : ''; - forEach(element, function (element) { - jqLiteRemoveClass(element, className); - }); - done && $timeout(done, 0, false); - }, - - enabled : noop - }; - }]; -}]; - -/** - * ! This is a private undocumented service ! - * - * @name ng.$browser - * @requires $log - * @description - * This object has two goals: - * - * - hide all the global state in the browser caused by the window object - * - abstract away all the browser specific features and inconsistencies - * - * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser` - * service, which can be used for convenient testing of the application without the interaction with - * the real browser apis. - */ -/** - * @param {object} window The global window object. - * @param {object} document jQuery wrapped document. - * @param {function()} XHR XMLHttpRequest constructor. - * @param {object} $log console.log or an object with the same interface. - * @param {object} $sniffer $sniffer service - */ -function Browser(window, document, $log, $sniffer) { - var self = this, - rawDocument = document[0], - location = window.location, - history = window.history, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - pendingDeferIds = {}; - - self.isMock = false; - - var outstandingRequestCount = 0; - var outstandingRequestCallbacks = []; - - // TODO(vojta): remove this temporary api - self.$$completeOutstandingRequest = completeOutstandingRequest; - self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; }; - - /** - * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks` - * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed. - */ - function completeOutstandingRequest(fn) { - try { - fn.apply(null, sliceArgs(arguments, 1)); - } finally { - outstandingRequestCount--; - if (outstandingRequestCount === 0) { - while(outstandingRequestCallbacks.length) { - try { - outstandingRequestCallbacks.pop()(); - } catch (e) { - $log.error(e); - } - } - } - } - } - - /** - * @private - * Note: this method is used only by scenario runner - * TODO(vojta): prefix this method with $$ ? - * @param {function()} callback Function that will be called when no outstanding request - */ - self.notifyWhenNoOutstandingRequests = function(callback) { - // force browser to execute all pollFns - this is needed so that cookies and other pollers fire - // at some deterministic time in respect to the test runner's actions. Leaving things up to the - // regular poller would result in flaky tests. - forEach(pollFns, function(pollFn){ pollFn(); }); - - if (outstandingRequestCount === 0) { - callback(); - } else { - outstandingRequestCallbacks.push(callback); - } - }; - - ////////////////////////////////////////////////////////////// - // Poll Watcher API - ////////////////////////////////////////////////////////////// - var pollFns = [], - pollTimeout; - - /** - * @name ng.$browser#addPollFn - * @methodOf ng.$browser - * - * @param {function()} fn Poll function to add - * - * @description - * Adds a function to the list of functions that poller periodically executes, - * and starts polling if not started yet. - * - * @returns {function()} the added function - */ - self.addPollFn = function(fn) { - if (isUndefined(pollTimeout)) startPoller(100, setTimeout); - pollFns.push(fn); - return fn; - }; - - /** - * @param {number} interval How often should browser call poll functions (ms) - * @param {function()} setTimeout Reference to a real or fake `setTimeout` function. - * - * @description - * Configures the poller to run in the specified intervals, using the specified - * setTimeout fn and kicks it off. - */ - function startPoller(interval, setTimeout) { - (function check() { - forEach(pollFns, function(pollFn){ pollFn(); }); - pollTimeout = setTimeout(check, interval); - })(); - } - - ////////////////////////////////////////////////////////////// - // URL API - ////////////////////////////////////////////////////////////// - - var lastBrowserUrl = location.href, - baseElement = document.find('base'), - newLocation = null; - - /** - * @name ng.$browser#url - * @methodOf ng.$browser - * - * @description - * GETTER: - * Without any argument, this method just returns current value of location.href. - * - * SETTER: - * With at least one argument, this method sets url to new value. - * If html5 history api supported, pushState/replaceState is used, otherwise - * location.href/location.replace is used. - * Returns its own instance to allow chaining - * - * NOTE: this api is intended for use only by the $location service. Please use the - * {@link ng.$location $location service} to change url. - * - * @param {string} url New url (when used as setter) - * @param {boolean=} replace Should new url replace current history record ? - */ - self.url = function(url, replace) { - // Android Browser BFCache causes location reference to become stale. - if (location !== window.location) location = window.location; - - // setter - if (url) { - if (lastBrowserUrl == url) return; - lastBrowserUrl = url; - if ($sniffer.history) { - if (replace) history.replaceState(null, '', url); - else { - history.pushState(null, '', url); - // Crazy Opera Bug: http://my.opera.com/community/forums/topic.dml?id=1185462 - baseElement.attr('href', baseElement.attr('href')); - } - } else { - newLocation = url; - if (replace) { - location.replace(url); - } else { - location.href = url; - } - } - return self; - // getter - } else { - // - newLocation is a workaround for an IE7-9 issue with location.replace and location.href - // methods not updating location.href synchronously. - // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172 - return newLocation || location.href.replace(/%27/g,"'"); - } - }; - - var urlChangeListeners = [], - urlChangeInit = false; - - function fireUrlChange() { - newLocation = null; - if (lastBrowserUrl == self.url()) return; - - lastBrowserUrl = self.url(); - forEach(urlChangeListeners, function(listener) { - listener(self.url()); - }); - } - - /** - * @name ng.$browser#onUrlChange - * @methodOf ng.$browser - * @TODO(vojta): refactor to use node's syntax for events - * - * @description - * Register callback function that will be called, when url changes. - * - * It's only called when the url is changed by outside of angular: - * - user types different url into address bar - * - user clicks on history (forward/back) button - * - user clicks on a link - * - * It's not called when url is changed by $browser.url() method - * - * The listener gets called with new url as parameter. - * - * NOTE: this api is intended for use only by the $location service. Please use the - * {@link ng.$location $location service} to monitor url changes in angular apps. - * - * @param {function(string)} listener Listener function to be called when url changes. - * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous. - */ - self.onUrlChange = function(callback) { - if (!urlChangeInit) { - // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera) - // don't fire popstate when user change the address bar and don't fire hashchange when url - // changed by push/replaceState - - // html5 history api - popstate event - if ($sniffer.history) jqLite(window).on('popstate', fireUrlChange); - // hashchange event - if ($sniffer.hashchange) jqLite(window).on('hashchange', fireUrlChange); - // polling - else self.addPollFn(fireUrlChange); - - urlChangeInit = true; - } - - urlChangeListeners.push(callback); - return callback; - }; - - ////////////////////////////////////////////////////////////// - // Misc API - ////////////////////////////////////////////////////////////// - - /** - * @name ng.$browser#baseHref - * @methodOf ng.$browser - * - * @description - * Returns current
- * - * var cache = $cacheFactory('cacheId'); - * expect($cacheFactory.get('cacheId')).toBe(cache); - * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined(); - * - * cache.put("key", "value"); - * cache.put("another key", "another value"); - * - * // We've specified no options on creation - * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); - * - *- * - * - * @param {string} cacheId Name or id of the newly created cache. - * @param {object=} options Options object that specifies the cache behavior. Properties: - * - * - `{number=}` `capacity` — turns the cache into LRU cache. - * - * @returns {object} Newly created cache object with the following set of methods: - * - * - `{object}` `info()` — Returns id, size, and options of cache. - * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns - * it. - * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss. - * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache. - * - `{void}` `removeAll()` — Removes all cached values. - * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory. - * - */ -function $CacheFactoryProvider() { - - this.$get = function() { - var caches = {}; - - function cacheFactory(cacheId, options) { - if (cacheId in caches) { - throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId); - } - - var size = 0, - stats = extend({}, options, {id: cacheId}), - data = {}, - capacity = (options && options.capacity) || Number.MAX_VALUE, - lruHash = {}, - freshEnd = null, - staleEnd = null; - - return caches[cacheId] = { - - put: function(key, value) { - var lruEntry = lruHash[key] || (lruHash[key] = {key: key}); - - refresh(lruEntry); - - if (isUndefined(value)) return; - if (!(key in data)) size++; - data[key] = value; - - if (size > capacity) { - this.remove(staleEnd.key); - } - - return value; - }, - - - get: function(key) { - var lruEntry = lruHash[key]; - - if (!lruEntry) return; - - refresh(lruEntry); - - return data[key]; - }, - - - remove: function(key) { - var lruEntry = lruHash[key]; - - if (!lruEntry) return; - - if (lruEntry == freshEnd) freshEnd = lruEntry.p; - if (lruEntry == staleEnd) staleEnd = lruEntry.n; - link(lruEntry.n,lruEntry.p); - - delete lruHash[key]; - delete data[key]; - size--; - }, - - - removeAll: function() { - data = {}; - size = 0; - lruHash = {}; - freshEnd = staleEnd = null; - }, - - - destroy: function() { - data = null; - stats = null; - lruHash = null; - delete caches[cacheId]; - }, - - - info: function() { - return extend({}, stats, {size: size}); - } - }; - - - /** - * makes the `entry` the freshEnd of the LRU linked list - */ - function refresh(entry) { - if (entry != freshEnd) { - if (!staleEnd) { - staleEnd = entry; - } else if (staleEnd == entry) { - staleEnd = entry.n; - } - - link(entry.n, entry.p); - link(entry, freshEnd); - freshEnd = entry; - freshEnd.n = null; - } - } - - - /** - * bidirectionally links two entries of the LRU linked list - */ - function link(nextEntry, prevEntry) { - if (nextEntry != prevEntry) { - if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify - if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify - } - } - } - - - /** - * @ngdoc method - * @name ng.$cacheFactory#info - * @methodOf ng.$cacheFactory - * - * @description - * Get information about all the of the caches that have been created - * - * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` - */ - cacheFactory.info = function() { - var info = {}; - forEach(caches, function(cache, cacheId) { - info[cacheId] = cache.info(); - }); - return info; - }; - - - /** - * @ngdoc method - * @name ng.$cacheFactory#get - * @methodOf ng.$cacheFactory - * - * @description - * Get access to a cache object by the `cacheId` used when it was created. - * - * @param {string} cacheId Name or id of a cache to access. - * @returns {object} Cache object identified by the cacheId or undefined if no such cache. - */ - cacheFactory.get = function(cacheId) { - return caches[cacheId]; - }; - - - return cacheFactory; - }; -} - -/** - * @ngdoc object - * @name ng.$templateCache - * - * @description - * The first time a template is used, it is loaded in the template cache for quick retrieval. You - * can load templates directly into the cache in a `script` tag, or by consuming the - * `$templateCache` service directly. - * - * Adding via the `script` tag: - *
- * - * - * - * - * ... - * - *- * - * **Note:** the `script` tag containing the template does not need to be included in the `head` of - * the document, but it must be below the `ng-app` definition. - * - * Adding via the $templateCache service: - * - *
- * var myApp = angular.module('myApp', []); - * myApp.run(function($templateCache) { - * $templateCache.put('templateId.html', 'This is the content of the template'); - * }); - *- * - * To retrieve the template later, simply use it in your HTML: - *
- * - *- * - * or get it via Javascript: - *
- * $templateCache.get('templateId.html') - *- * - * See {@link ng.$cacheFactory $cacheFactory}. - * - */ -function $TemplateCacheProvider() { - this.$get = ['$cacheFactory', function($cacheFactory) { - return $cacheFactory('templates'); - }]; -} - -/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE! - * - * DOM-related variables: - * - * - "node" - DOM Node - * - "element" - DOM Element or Node - * - "$node" or "$element" - jqLite-wrapped node or element - * - * - * Compiler related stuff: - * - * - "linkFn" - linking fn of a single directive - * - "nodeLinkFn" - function that aggregates all linking fns for a particular node - * - "childLinkFn" - function that aggregates all linking fns for child nodes of a particular node - * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList) - */ - - -/** - * @ngdoc function - * @name ng.$compile - * @function - * - * @description - * Compiles a piece of HTML string or DOM into a template and produces a template function, which - * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together. - * - * The compilation is a process of walking the DOM tree and matching DOM elements to - * {@link ng.$compileProvider#methods_directive directives}. - * - *
- * var myModule = angular.module(...); - * - * myModule.directive('directiveName', function factory(injectables) { - * var directiveDefinitionObject = { - * priority: 0, - * template: '', // or // function(tElement, tAttrs) { ... }, - * // or - * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, - * replace: false, - * transclude: false, - * restrict: 'A', - * scope: false, - * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, - * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], - * compile: function compile(tElement, tAttrs, transclude) { - * return { - * pre: function preLink(scope, iElement, iAttrs, controller) { ... }, - * post: function postLink(scope, iElement, iAttrs, controller) { ... } - * } - * // or - * // return function postLink( ... ) { ... } - * }, - * // or - * // link: { - * // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, - * // post: function postLink(scope, iElement, iAttrs, controller) { ... } - * // } - * // or - * // link: function postLink( ... ) { ... } - * }; - * return directiveDefinitionObject; - * }); - *- * - *
- * var myModule = angular.module(...); - * - * myModule.directive('directiveName', function factory(injectables) { - * var directiveDefinitionObject = { - * link: function postLink(scope, iElement, iAttrs) { ... } - * }; - * return directiveDefinitionObject; - * // or - * // return function postLink(scope, iElement, iAttrs) { ... } - * }); - *- * - * - * - * ### Directive Definition Object - * - * The directive definition object provides instructions to the {@link api/ng.$compile - * compiler}. The attributes are: - * - * #### `priority` - * When there are multiple directives defined on a single DOM element, sometimes it - * is necessary to specify the order in which the directives are applied. The `priority` is used - * to sort the directives before their `compile` functions get called. Priority is defined as a - * number. Directives with greater numerical `priority` are compiled first. Pre-link functions - * are also run in priority order, but post-link functions are run in reverse order. The order - * of directives with the same priority is undefined. The default priority is `0`. - * - * #### `terminal` - * If set to true then the current `priority` will be the last set of directives - * which will execute (any directives at the current priority will still execute - * as the order of execution on same `priority` is undefined). - * - * #### `scope` - * **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the - * same element request a new scope, only one new scope is created. The new scope rule does not - * apply for the root of the template since the root of the template always gets a new scope. - * - * **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from - * normal scope in that it does not prototypically inherit from the parent scope. This is useful - * when creating reusable components, which should not accidentally read or modify data in the - * parent scope. - * - * The 'isolate' scope takes an object hash which defines a set of local scope properties - * derived from the parent scope. These local properties are useful for aliasing values for - * templates. Locals definition is a hash of local scope property to its source: - * - * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is - * always a string since DOM attributes are strings. If no `attr` name is specified then the - * attribute name is assumed to be the same as the local name. - * Given `
- * function compile(tElement, tAttrs, transclude) { ... } - *- * - * The compile function deals with transforming the template DOM. Since most directives do not do - * template transformation, it is not used often. Examples that require compile functions are - * directives that transform template DOM, such as {@link - * api/ng.directive:ngRepeat ngRepeat}, or load the contents - * asynchronously, such as {@link api/ngRoute.directive:ngView ngView}. The - * compile function takes the following arguments. - * - * * `tElement` - template element - The element where the directive has been declared. It is - * safe to do template transformation on the element and child elements only. - * - * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared - * between all directive compile functions. - * - * * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)` - * - *
- * function link(scope, iElement, iAttrs, controller, transcludeFn) { ... } - *- * - * The link function is responsible for registering DOM listeners as well as updating the DOM. It is - * executed after the template has been cloned. This is where most of the directive logic will be - * put. - * - * * `scope` - {@link api/ng.$rootScope.Scope Scope} - The scope to be used by the - * directive for registering {@link api/ng.$rootScope.Scope#methods_$watch watches}. - * - * * `iElement` - instance element - The element where the directive is to be used. It is safe to - * manipulate the children of the element only in `postLink` function since the children have - * already been linked. - * - * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared - * between all directive linking functions. - * - * * `controller` - a controller instance - A controller instance if at least one directive on the - * element defines a controller. The controller is shared among all the directives, which allows - * the directives to use the controllers as a communication channel. - * - * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope. - * The scope can be overridden by an optional first argument. This is the same as the `$transclude` - * parameter of directive controllers. - * `function([scope], cloneLinkingFn)`. - * - * - * #### Pre-linking function - * - * Executed before the child elements are linked. Not safe to do DOM transformation since the - * compiler linking function will fail to locate the correct elements for linking. - * - * #### Post-linking function - * - * Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function. - * - * - * ### Attributes - * - * The {@link api/ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the - * `link()` or `compile()` functions. It has a variety of uses. - * - * accessing *Normalized attribute names:* - * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'. - * the attributes object allows for normalized access to - * the attributes. - * - * * *Directive inter-communication:* All directives share the same instance of the attributes - * object which allows the directives to use the attributes object as inter directive - * communication. - * - * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object - * allowing other directives to read the interpolated value. - * - * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes - * that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also - * the only way to easily get the actual value because during the linking phase the interpolation - * hasn't been evaluated yet and so the value is at this time set to `undefined`. - * - *
- * function linkingFn(scope, elm, attrs, ctrl) { - * // get the attribute value - * console.log(attrs.ngModel); - * - * // change the attribute - * attrs.$set('ngModel', 'new value'); - * - * // observe changes to interpolated attribute - * attrs.$observe('ngModel', function(value) { - * console.log('ngModel has changed value to ' + value); - * }); - * } - *- * - * Below is an example using `$compileProvider`. - * - *
- * var element = $compile('- * - * - 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: - *{{total}}
')(scope); - *
- * var templateHTML = angular.element('- * - * - * For information on how the compiler works, see the - * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide. - */ - -var $compileMinErr = minErr('$compile'); - -/** - * @ngdoc service - * @name ng.$compileProvider - * @function - * - * @description - */ -$CompileProvider.$inject = ['$provide']; -function $CompileProvider($provide) { - var hasDirectives = {}, - Suffix = 'Directive', - COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, - CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/, - aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/, - imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//; - - // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes - // The assumption is that future DOM event attribute names will begin with - // 'on' and be composed of only English letters. - var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/; - - /** - * @ngdoc function - * @name ng.$compileProvider#directive - * @methodOf ng.$compileProvider - * @function - * - * @description - * Register a new directive with the compiler. - * - * @param {string|Object} name Name of the directive in camel-case (i.e.{{total}}
'), - * scope = ....; - * - * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) { - * //attach the clone to DOM document at the right place - * }); - * - * //now we have reference to the cloned DOM via `clone` - *
ngBind
which
- * will match as ng-bind
), or an object map of directives where the keys are the
- * names and the values are the factories.
- * @param {function|Array} directiveFactory An injectable directive factory function. See
- * {@link guide/directive} for more info.
- * @returns {ng.$compileProvider} Self for chaining.
- */
- this.directive = function registerDirective(name, directiveFactory) {
- assertNotHasOwnProperty(name, 'directive');
- if (isString(name)) {
- assertArg(directiveFactory, 'directiveFactory');
- if (!hasDirectives.hasOwnProperty(name)) {
- hasDirectives[name] = [];
- $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
- function($injector, $exceptionHandler) {
- var directives = [];
- forEach(hasDirectives[name], function(directiveFactory, index) {
- try {
- var directive = $injector.invoke(directiveFactory);
- if (isFunction(directive)) {
- directive = { compile: valueFn(directive) };
- } else if (!directive.compile && directive.link) {
- directive.compile = valueFn(directive.link);
- }
- directive.priority = directive.priority || 0;
- directive.index = index;
- directive.name = directive.name || name;
- directive.require = directive.require || (directive.controller && directive.name);
- directive.restrict = directive.restrict || 'A';
- directives.push(directive);
- } catch (e) {
- $exceptionHandler(e);
- }
- });
- return directives;
- }]);
- }
- hasDirectives[name].push(directiveFactory);
- } else {
- forEach(name, reverseParams(registerDirective));
- }
- return this;
- };
-
-
- /**
- * @ngdoc function
- * @name ng.$compileProvider#aHrefSanitizationWhitelist
- * @methodOf ng.$compileProvider
- * @function
- *
- * @description
- * Retrieves or overrides the default regular expression that is used for whitelisting of safe
- * urls during a[href] sanitization.
- *
- * The sanitization is a security measure aimed at prevent XSS attacks via html links.
- *
- * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
- * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
- * regular expression. If a match is found, the original url is written into the dom. Otherwise,
- * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
- *
- * @param {RegExp=} regexp New regexp to whitelist urls with.
- * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
- * chaining otherwise.
- */
- this.aHrefSanitizationWhitelist = function(regexp) {
- if (isDefined(regexp)) {
- aHrefSanitizationWhitelist = regexp;
- return this;
- }
- return aHrefSanitizationWhitelist;
- };
-
-
- /**
- * @ngdoc function
- * @name ng.$compileProvider#imgSrcSanitizationWhitelist
- * @methodOf ng.$compileProvider
- * @function
- *
- * @description
- * Retrieves or overrides the default regular expression that is used for whitelisting of safe
- * urls during img[src] sanitization.
- *
- * The sanitization is a security measure aimed at prevent XSS attacks via html links.
- *
- * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
- * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
- * regular expression. If a match is found, the original url is written into the dom. Otherwise,
- * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
- *
- * @param {RegExp=} regexp New regexp to whitelist urls with.
- * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
- * chaining otherwise.
- */
- this.imgSrcSanitizationWhitelist = function(regexp) {
- if (isDefined(regexp)) {
- imgSrcSanitizationWhitelist = regexp;
- return this;
- }
- return imgSrcSanitizationWhitelist;
- };
-
-
- this.$get = [
- '$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
- '$controller', '$rootScope', '$document', '$sce', '$animate',
- function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
- $controller, $rootScope, $document, $sce, $animate) {
-
- var Attributes = function(element, attr) {
- this.$$element = element;
- this.$attr = attr || {};
- };
-
- Attributes.prototype = {
- $normalize: directiveNormalize,
-
-
- /**
- * @ngdoc function
- * @name ng.$compile.directive.Attributes#$addClass
- * @methodOf ng.$compile.directive.Attributes
- * @function
- *
- * @description
- * Adds the CSS class value specified by the classVal parameter to the element. If animations
- * are enabled then an animation will be triggered for the class addition.
- *
- * @param {string} classVal The className value that will be added to the element
- */
- $addClass : function(classVal) {
- if(classVal && classVal.length > 0) {
- $animate.addClass(this.$$element, classVal);
- }
- },
-
- /**
- * @ngdoc function
- * @name ng.$compile.directive.Attributes#$removeClass
- * @methodOf ng.$compile.directive.Attributes
- * @function
- *
- * @description
- * Removes the CSS class value specified by the classVal parameter from the element. If
- * animations are enabled then an animation will be triggered for the class removal.
- *
- * @param {string} classVal The className value that will be removed from the element
- */
- $removeClass : function(classVal) {
- if(classVal && classVal.length > 0) {
- $animate.removeClass(this.$$element, classVal);
- }
- },
-
- /**
- * Set a normalized attribute on the element in a way such that all directives
- * can share the attribute. This function properly handles boolean attributes.
- * @param {string} key Normalized key. (ie ngAttribute)
- * @param {string|boolean} value The value to set. If `null` attribute will be deleted.
- * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
- * Defaults to true.
- * @param {string=} attrName Optional none normalized name. Defaults to key.
- */
- $set: function(key, value, writeAttr, attrName) {
- //special case for class attribute addition + removal
- //so that class changes can tap into the animation
- //hooks provided by the $animate service
- if(key == 'class') {
- value = value || '';
- var current = this.$$element.attr('class') || '';
- this.$removeClass(tokenDifference(current, value).join(' '));
- this.$addClass(tokenDifference(value, current).join(' '));
- } else {
- var booleanKey = getBooleanAttrName(this.$$element[0], key),
- normalizedVal,
- nodeName;
-
- if (booleanKey) {
- this.$$element.prop(key, value);
- attrName = booleanKey;
- }
-
- this[key] = value;
-
- // translate normalized key to actual key
- if (attrName) {
- this.$attr[key] = attrName;
- } else {
- attrName = this.$attr[key];
- if (!attrName) {
- this.$attr[key] = attrName = snake_case(key, '-');
- }
- }
-
- nodeName = nodeName_(this.$$element);
-
- // sanitize a[href] and img[src] values
- if ((nodeName === 'A' && key === 'href') ||
- (nodeName === 'IMG' && key === 'src')) {
- // NOTE: urlResolve() doesn't support IE < 8 so we don't sanitize for that case.
- if (!msie || msie >= 8 ) {
- normalizedVal = urlResolve(value).href;
- if (normalizedVal !== '') {
- if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
- (key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
- this[key] = value = 'unsafe:' + normalizedVal;
- }
- }
- }
- }
-
- if (writeAttr !== false) {
- if (value === null || value === undefined) {
- this.$$element.removeAttr(attrName);
- } else {
- this.$$element.attr(attrName, value);
- }
- }
- }
-
- // fire observers
- var $$observers = this.$$observers;
- $$observers && forEach($$observers[key], function(fn) {
- try {
- fn(value);
- } catch (e) {
- $exceptionHandler(e);
- }
- });
-
- function tokenDifference(str1, str2) {
- var values = [],
- tokens1 = str1.split(/\s+/),
- tokens2 = str2.split(/\s+/);
-
- outer:
- for(var i=0;i- * angular.module('exceptionOverride', []).factory('$exceptionHandler', function () { - * return function (exception, cause) { - * exception.message += ' (caused by "' + cause + '")'; - * throw exception; - * }; - * }); - *- * - * This example will override the normal action of `$exceptionHandler`, to make angular - * exceptions fail hard when they happen, instead of just logging to the console. - * - * @param {Error} exception Exception associated with the error. - * @param {string=} cause optional information about the context in which - * the error was thrown. - * - */ -function $ExceptionHandlerProvider() { - this.$get = ['$log', function($log) { - return function(exception, cause) { - $log.error.apply($log, arguments); - }; - }]; -} - -/** - * Parse headers into key value object - * - * @param {string} headers Raw headers as a string - * @returns {Object} Parsed headers as key value object - */ -function parseHeaders(headers) { - var parsed = {}, key, val, i; - - if (!headers) return parsed; - - forEach(headers.split('\n'), function(line) { - i = line.indexOf(':'); - key = lowercase(trim(line.substr(0, i))); - val = trim(line.substr(i + 1)); - - if (key) { - if (parsed[key]) { - parsed[key] += ', ' + val; - } else { - parsed[key] = val; - } - } - }); - - return parsed; -} - - -/** - * Returns a function that provides access to parsed headers. - * - * Headers are lazy parsed when first requested. - * @see parseHeaders - * - * @param {(string|Object)} headers Headers to provide access to. - * @returns {function(string=)} Returns a getter function which if called with: - * - * - if called with single an argument returns a single header value or null - * - if called with no arguments returns an object containing all headers. - */ -function headersGetter(headers) { - var headersObj = isObject(headers) ? headers : undefined; - - return function(name) { - if (!headersObj) headersObj = parseHeaders(headers); - - if (name) { - return headersObj[lowercase(name)] || null; - } - - return headersObj; - }; -} - - -/** - * Chain all given functions - * - * This function is used for both request and response transforming - * - * @param {*} data Data to transform. - * @param {function(string=)} headers Http headers getter fn. - * @param {(function|Array.
- * $http({method: 'GET', url: '/someUrl'}). - * success(function(data, status, headers, config) { - * // this callback will be called asynchronously - * // when the response is available - * }). - * error(function(data, status, headers, config) { - * // called asynchronously if an error occurs - * // or server returns response with an error status. - * }); - *- * - * 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. - * - * 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, - * XMLHttpRequest will transparently follow it, meaning that the error callback will not be - * called for such responses. - * - * # Calling $http from outside AngularJS - * The `$http` service will not actually send the request until the next `$digest()` is - * executed. Normally this is not an issue, since almost all the time your call to `$http` will - * be from within a `$apply()` block. - * If you are calling `$http` from outside Angular, then you should wrap it in a call to - * `$apply` to cause a $digest to occur and also to handle errors in the block correctly. - * - * ``` - * $scope.$apply(function() { - * $http(...); - * }); - * ``` - * - * # Writing Unit Tests that use $http - * When unit testing you are mostly responsible for scheduling the `$digest` cycle. If you do - * not trigger a `$digest` before calling `$httpBackend.flush()` then the request will not have - * been made and `$httpBackend.expect(...)` expectations will fail. The solution is to run the - * code that calls the `$http()` method inside a $apply block as explained in the previous - * section. - * - * ``` - * $httpBackend.expectGET(...); - * $scope.$apply(function() { - * $http.get(...); - * }); - * $httpBackend.flush(); - * ``` - * - * # Shortcut methods - * - * Since all invocations of the $http service require passing in an HTTP method and URL, and - * POST/PUT requests require request data to be provided as well, shortcut methods - * were created: - * - *
- * $http.get('/someUrl').success(successCallback); - * $http.post('/someUrl', data).success(successCallback); - *- * - * Complete list of shortcut methods: - * - * - {@link ng.$http#methods_get $http.get} - * - {@link ng.$http#methods_head $http.head} - * - {@link ng.$http#methods_post $http.post} - * - {@link ng.$http#methods_put $http.put} - * - {@link ng.$http#methods_delete $http.delete} - * - {@link ng.$http#methods_jsonp $http.jsonp} - * - * - * # Setting HTTP Headers - * - * The $http service will automatically add certain HTTP headers to all requests. These defaults - * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration - * object, which currently contains this default configuration: - * - * - `$httpProvider.defaults.headers.common` (headers that are common for all requests): - * - `Accept: application/json, text/plain, * / *` - * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests) - * - `Content-Type: application/json` - * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests) - * - `Content-Type: application/json` - * - * To add or overwrite these defaults, simply add or remove a property from these configuration - * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object - * with the lowercased HTTP method name as the key, e.g. - * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }. - * - * The defaults can also be set at runtime via the `$http.defaults` object in the same - * fashion. In addition, you can supply a `headers` property in the config object passed when - * calling `$http(config)`, which overrides the defaults without changing them globally. - * - * - * # Transforming Requests and Responses - * - * Both requests and responses can be transformed using transform functions. By default, Angular - * applies these transformations: - * - * Request transformations: - * - * - If the `data` property of the request configuration object contains an object, serialize it - * into JSON format. - * - * Response transformations: - * - * - If XSRF prefix is detected, strip it (see Security Considerations section below). - * - If JSON response is detected, deserialize it using a JSON parser. - * - * To globally augment or override the default transforms, modify the - * `$httpProvider.defaults.transformRequest` and `$httpProvider.defaults.transformResponse` - * properties. These properties are by default an array of transform functions, which allows you - * to `push` or `unshift` a new transformation function into the transformation chain. You can - * also decide to completely override any default transformations by assigning your - * transformation functions to these properties directly without the array wrapper. - * - * Similarly, to locally override the request/response transforms, augment the - * `transformRequest` and/or `transformResponse` properties of the configuration object passed - * into `$http`. - * - * - * # Caching - * - * To enable caching, set the request configuration `cache` property to `true` (to use default - * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}). - * When the cache is enabled, `$http` stores the response from the server in the specified - * cache. The next time the same request is made, the response is served from the cache without - * sending a request to the server. - * - * Note that even if the response is served from cache, delivery of the data is asynchronous in - * the same way that real requests are. - * - * If there are multiple GET requests for the same URL that should be cached using the same - * cache, but the cache is not populated yet, only one request to the server will be made and - * the remaining requests will be fulfilled using the response from the first request. - * - * You can change the default cache to a new object (built with - * {@link ng.$cacheFactory `$cacheFactory`}) by updating the - * {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set - * their `cache` property to `true` will now use this cache object. - * - * If you set the default cache to `false` then only requests that specify their own custom - * cache object will be cached. - * - * # Interceptors - * - * Before you start creating interceptors, be sure to understand the - * {@link ng.$q $q and deferred/promise APIs}. - * - * For purposes of global error handling, authentication, or any kind of synchronous or - * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be - * able to intercept requests before they are handed to the server and - * responses before they are handed over to the application code that - * initiated these requests. The interceptors leverage the {@link ng.$q - * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing. - * - * The interceptors are service factories that are registered with the `$httpProvider` by - * adding them to the `$httpProvider.interceptors` array. The factory is called and - * injected with dependencies (if specified) and returns the interceptor. - * - * There are two kinds of interceptors (and two kinds of rejection interceptors): - * - * * `request`: interceptors get called with http `config` object. The function is free to - * modify the `config` or create a new one. The function needs to return the `config` - * directly or as a promise. - * * `requestError`: interceptor gets called when a previous interceptor threw an error or - * resolved with a rejection. - * * `response`: interceptors get called with http `response` object. The function is free to - * modify the `response` or create a new one. The function needs to return the `response` - * directly or as a promise. - * * `responseError`: interceptor gets called when a previous interceptor threw an error or - * resolved with a rejection. - * - * - *
- * // register the interceptor as a service - * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { - * return { - * // optional method - * 'request': function(config) { - * // do something on success - * return config || $q.when(config); - * }, - * - * // optional method - * 'requestError': function(rejection) { - * // do something on error - * if (canRecover(rejection)) { - * return responseOrNewPromise - * } - * return $q.reject(rejection); - * }, - * - * - * - * // optional method - * 'response': function(response) { - * // do something on success - * return response || $q.when(response); - * }, - * - * // optional method - * 'responseError': function(rejection) { - * // do something on error - * if (canRecover(rejection)) { - * return responseOrNewPromise - * } - * return $q.reject(rejection); - * }; - * } - * }); - * - * $httpProvider.interceptors.push('myHttpInterceptor'); - * - * - * // register the interceptor via an anonymous factory - * $httpProvider.interceptors.push(function($q, dependency1, dependency2) { - * return { - * 'request': function(config) { - * // same as above - * }, - * 'response': function(response) { - * // same as above - * } - * }; - * }); - *- * - * # Response interceptors (DEPRECATED) - * - * Before you start creating interceptors, be sure to understand the - * {@link ng.$q $q and deferred/promise APIs}. - * - * For purposes of global error handling, authentication or any kind of synchronous or - * asynchronous preprocessing of received responses, it is desirable to be able to intercept - * responses for http requests before they are handed over to the application code that - * initiated these requests. The response interceptors leverage the {@link ng.$q - * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing. - * - * The interceptors are service factories that are registered with the $httpProvider by - * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and - * injected with dependencies (if specified) and returns the interceptor — a function that - * takes a {@link ng.$q promise} and returns the original or a new promise. - * - *
- * // register the interceptor as a service - * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { - * return function(promise) { - * return promise.then(function(response) { - * // do something on success - * return response; - * }, function(response) { - * // do something on error - * if (canRecover(response)) { - * return responseOrNewPromise - * } - * return $q.reject(response); - * }); - * } - * }); - * - * $httpProvider.responseInterceptors.push('myHttpInterceptor'); - * - * - * // register the interceptor via an anonymous factory - * $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) { - * return function(promise) { - * // same as above - * } - * }); - *- * - * - * # Security Considerations - * - * When designing web applications, consider security threats from: - * - * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx - * JSON vulnerability} - * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} - * - * Both server and the client must cooperate in order to eliminate these threats. Angular comes - * pre-configured with strategies that address these issues, but for this to work backend server - * cooperation is required. - * - * ## JSON Vulnerability Protection - * - * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx - * JSON vulnerability} allows third party website to turn your JSON resource URL into - * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To - * counter this your server can prefix all JSON requests with following string `")]}',\n"`. - * Angular will automatically strip the prefix before processing it as JSON. - * - * For example if your server needs to return: - *
- * ['one','two'] - *- * - * which is vulnerable to attack, your server can return: - *
- * )]}', - * ['one','two'] - *- * - * Angular will strip the prefix, before processing the JSON. - * - * - * ## Cross Site Request Forgery (XSRF) Protection - * - * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which - * an unauthorized site can gain your user's private data. Angular provides a mechanism - * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie - * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only - * JavaScript that runs on your domain could read the cookie, your server can be assured that - * the XHR came from JavaScript running on your domain. The header will not be set for - * cross-domain requests. - * - * To take advantage of this, your server needs to set a token in a JavaScript readable session - * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the - * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure - * that only JavaScript running on your domain could have sent the request. The token must be - * unique for each user and must be verifiable by the server (to prevent the JavaScript from - * making up its own tokens). We recommend that the token is a digest of your site's - * authentication cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} - * for added security. - * - * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName - * properties of either $httpProvider.defaults, or the per-request config object. - * - * - * @param {object} config Object describing the request to be made and how it should be - * processed. The object has following properties: - * - * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc) - * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested. - * - **params** – `{Object.