@@ -16,9 +16,12 @@ var template = `
export class SwitchCtrl {
onChange: any;
checked: any;
+ show: any;
- constructor() {
- console.log('property: ' + this.checked, this);
+ constructor($element) {
+ // hack to workaround animation
+ // happening on first show
+ this.show = true;
}
internalOnChange() {
diff --git a/public/sass/components/_switch.scss b/public/sass/components/_switch.scss
index 1f81bc2597e..4216029bab2 100644
--- a/public/sass/components/_switch.scss
+++ b/public/sass/components/_switch.scss
@@ -65,7 +65,7 @@ $switch-height: 1.5rem;
font-family: 'FontAwesome';
content: "\f096"; // square-o
color: $text-color-faint;
- //transition: transform 0.4s;
+ transition: transform 0.4s;
backface-visibility: hidden;
text-shadow: $text-shadow-faint;
}
@@ -76,7 +76,7 @@ $switch-height: 1.5rem;
text-shadow: $text-shadow-strong;
font-family: 'FontAwesome';
- //transition: transform 0.4s;
+ transition: transform 0.4s;
transform: rotateY(180deg);
backface-visibility: hidden;
}
diff --git a/public/vendor/angular-mocks/.bower.json b/public/vendor/angular-mocks/.bower.json
index 9831478983e..03fc650628a 100644
--- a/public/vendor/angular-mocks/.bower.json
+++ b/public/vendor/angular-mocks/.bower.json
@@ -1,20 +1,20 @@
{
"name": "angular-mocks",
- "version": "1.5.1-build.4601+sha.c966876",
+ "version": "1.5.3",
"license": "MIT",
"main": "./angular-mocks.js",
"ignore": [],
"dependencies": {
- "angular": "1.5.1-build.4601+sha.c966876"
+ "angular": "1.5.3"
},
"homepage": "https://github.com/angular/bower-angular-mocks",
- "_release": "1.5.1-build.4601+sha.c966876",
+ "_release": "1.5.3",
"_resolution": {
"type": "version",
- "tag": "v1.5.1-build.4601+sha.c966876",
- "commit": "ff7c5c2ac686293829786d26d844391e45c37c11"
+ "tag": "v1.5.3",
+ "commit": "319557fe710cecc11e12c772cc1abb8098d29ccb"
},
"_source": "git://github.com/angular/bower-angular-mocks.git",
- "_target": "~1.5.1",
+ "_target": "~1.5.3",
"_originalSource": "angular-mocks"
}
\ No newline at end of file
diff --git a/public/vendor/angular-mocks/angular-mocks.js b/public/vendor/angular-mocks/angular-mocks.js
index ff28e1a7892..a1fc2fcf7ae 100644
--- a/public/vendor/angular-mocks/angular-mocks.js
+++ b/public/vendor/angular-mocks/angular-mocks.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.5.1-build.4601+sha.c966876
+ * @license AngularJS v1.5.3
* (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -134,12 +134,12 @@ angular.mock.$Browser = function() {
};
angular.mock.$Browser.prototype = {
-/**
- * @name $browser#poll
- *
- * @description
- * run all fns in pollFns
- */
+ /**
+ * @name $browser#poll
+ *
+ * @description
+ * run all fns in pollFns
+ */
poll: function poll() {
angular.forEach(this.pollFns, function(pollFn) {
pollFn();
@@ -552,7 +552,7 @@ angular.mock.$IntervalProvider = function() {
* 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.
*/
-var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
+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;
@@ -578,7 +578,7 @@ function toInt(str) {
return parseInt(str, 10);
}
-function padNumber(num, digits, trim) {
+function padNumberInMock(num, digits, trim) {
var neg = '';
if (num < 0) {
neg = '-';
@@ -727,13 +727,13 @@ angular.mock.TzDate = function(offset, timestamp) {
// 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';
+ return padNumberInMock(self.origDate.getUTCFullYear(), 4) + '-' +
+ padNumberInMock(self.origDate.getUTCMonth() + 1, 2) + '-' +
+ padNumberInMock(self.origDate.getUTCDate(), 2) + 'T' +
+ padNumberInMock(self.origDate.getUTCHours(), 2) + ':' +
+ padNumberInMock(self.origDate.getUTCMinutes(), 2) + ':' +
+ padNumberInMock(self.origDate.getUTCSeconds(), 2) + '.' +
+ padNumberInMock(self.origDate.getUTCMilliseconds(), 3) + 'Z';
};
}
@@ -1328,7 +1328,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
}
// TODO(vojta): change params to: method, url, data, headers, callback
- function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
+ function $httpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType) {
+
var xhr = new MockXhr(),
expectation = expectations[0],
wasExpected = false;
@@ -1392,7 +1393,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
// 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);
+ $delegate(method, url, data, callback, headers, timeout, withCredentials, responseType);
} else throw new Error('No response defined !');
return;
}
@@ -2095,10 +2096,12 @@ angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
/**
*
*/
+var originalRootElement;
angular.mock.$RootElementProvider = function() {
- this.$get = function() {
- return angular.element('');
- };
+ this.$get = ['$injector', function($injector) {
+ originalRootElement = angular.element('').data('$injector', $injector);
+ return originalRootElement;
+ }];
};
/**
@@ -2127,7 +2130,7 @@ angular.mock.$RootElementProvider = function() {
*
* myMod.controller('MyDirectiveController', ['$log', function($log) {
* $log.info(this.name);
- * })];
+ * }]);
*
*
* // In a test ...
@@ -2137,7 +2140,7 @@ angular.mock.$RootElementProvider = function() {
* var ctrl = $controller('MyDirectiveController', { /* no locals */ }, { name: 'Clark Kent' });
* expect(ctrl.name).toEqual('Clark Kent');
* expect($log.info.logs).toEqual(['Clark Kent']);
- * });
+ * }));
* });
*
* ```
@@ -2565,11 +2568,16 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
}];
-if (window.jasmine || window.mocha) {
+!(function(jasmineOrMocha) {
+
+ if (!jasmineOrMocha) {
+ return;
+ }
var currentSpec = null,
+ injectorState = new InjectorState(),
annotatedFunctions = [],
- isSpecRunning = function() {
+ wasInjectorCreated = function() {
return !!currentSpec;
};
@@ -2581,48 +2589,6 @@ if (window.jasmine || window.mocha) {
return angular.mock.$$annotate.apply(this, arguments);
};
-
- (window.beforeEach || window.setup)(function() {
- annotatedFunctions = [];
- currentSpec = this;
- });
-
- (window.afterEach || window.teardown)(function() {
- var injector = currentSpec.$injector;
-
- annotatedFunctions.forEach(function(fn) {
- delete fn.$inject;
- });
-
- angular.forEach(currentSpec.$modules, function(module) {
- if (module && module.$$hashKey) {
- module.$$hashKey = undefined;
- }
- });
-
- currentSpec.$injector = null;
- currentSpec.$modules = null;
- currentSpec.$providerInjector = null;
- currentSpec = null;
-
- if (injector) {
- injector.get('$rootElement').off();
- injector.get('$rootScope').$destroy();
- }
-
- // 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;
- });
-
/**
* @ngdoc function
* @name angular.mock.module
@@ -2643,9 +2609,9 @@ if (window.jasmine || window.mocha) {
* {@link auto.$provide $provide}.value, the key being the string name (or token) to associate
* with the value on the injector.
*/
- window.module = angular.mock.module = function() {
+ var module = window.module = angular.mock.module = function() {
var moduleFns = Array.prototype.slice.call(arguments, 0);
- return isSpecRunning() ? workFn() : workFn;
+ return wasInjectorCreated() ? workFn() : workFn;
/////////////////////
function workFn() {
if (currentSpec.$injector) {
@@ -2654,11 +2620,11 @@ if (window.jasmine || window.mocha) {
var fn, modules = currentSpec.$modules || (currentSpec.$modules = []);
angular.forEach(moduleFns, function(module) {
if (angular.isObject(module) && !angular.isArray(module)) {
- fn = function($provide) {
+ fn = ['$provide', function($provide) {
angular.forEach(module, function(value, key) {
$provide.value(key, value);
});
- };
+ }];
} else {
fn = module;
}
@@ -2672,6 +2638,165 @@ if (window.jasmine || window.mocha) {
}
};
+ module.$$beforeAllHook = (window.before || window.beforeAll);
+ module.$$afterAllHook = (window.after || window.afterAll);
+
+ // purely for testing ngMock itself
+ module.$$currentSpec = function(to) {
+ if (arguments.length === 0) return to;
+ currentSpec = to;
+ };
+
+ /**
+ * @ngdoc function
+ * @name angular.mock.module.sharedInjector
+ * @description
+ *
+ * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha
+ *
+ * This function ensures a single injector will be used for all tests in a given describe context.
+ * This contrasts with the default behaviour where a new injector is created per test case.
+ *
+ * Use sharedInjector when you want to take advantage of Jasmine's `beforeAll()`, or mocha's
+ * `before()` methods. Call `module.sharedInjector()` before you setup any other hooks that
+ * will create (i.e call `module()`) or use (i.e call `inject()`) the injector.
+ *
+ * You cannot call `sharedInjector()` from within a context already using `sharedInjector()`.
+ *
+ * ## Example
+ *
+ * Typically beforeAll is used to make many assertions about a single operation. This can
+ * cut down test run-time as the test setup doesn't need to be re-run, and enabling focussed
+ * tests each with a single assertion.
+ *
+ * ```js
+ * describe("Deep Thought", function() {
+ *
+ * module.sharedInjector();
+ *
+ * beforeAll(module("UltimateQuestion"));
+ *
+ * beforeAll(inject(function(DeepThought) {
+ * expect(DeepThought.answer).toBeUndefined();
+ * DeepThought.generateAnswer();
+ * }));
+ *
+ * it("has calculated the answer correctly", inject(function(DeepThought) {
+ * // Because of sharedInjector, we have access to the instance of the DeepThought service
+ * // that was provided to the beforeAll() hook. Therefore we can test the generated answer
+ * expect(DeepThought.answer).toBe(42);
+ * }));
+ *
+ * it("has calculated the answer within the expected time", inject(function(DeepThought) {
+ * expect(DeepThought.runTimeMillennia).toBeLessThan(8000);
+ * }));
+ *
+ * it("has double checked the answer", inject(function(DeepThought) {
+ * expect(DeepThought.absolutelySureItIsTheRightAnswer).toBe(true);
+ * }));
+ *
+ * });
+ *
+ * ```
+ */
+ module.sharedInjector = function() {
+ if (!(module.$$beforeAllHook && module.$$afterAllHook)) {
+ throw Error("sharedInjector() cannot be used unless your test runner defines beforeAll/afterAll");
+ }
+
+ var initialized = false;
+
+ module.$$beforeAllHook(function() {
+ if (injectorState.shared) {
+ injectorState.sharedError = Error("sharedInjector() cannot be called inside a context that has already called sharedInjector()");
+ throw injectorState.sharedError;
+ }
+ initialized = true;
+ currentSpec = this;
+ injectorState.shared = true;
+ });
+
+ module.$$afterAllHook(function() {
+ if (initialized) {
+ injectorState = new InjectorState();
+ module.$$cleanup();
+ } else {
+ injectorState.sharedError = null;
+ }
+ });
+ };
+
+ module.$$beforeEach = function() {
+ if (injectorState.shared && currentSpec && currentSpec != this) {
+ var state = currentSpec;
+ currentSpec = this;
+ angular.forEach(["$injector","$modules","$providerInjector", "$injectorStrict"], function(k) {
+ currentSpec[k] = state[k];
+ state[k] = null;
+ });
+ } else {
+ currentSpec = this;
+ originalRootElement = null;
+ annotatedFunctions = [];
+ }
+ };
+
+ module.$$afterEach = function() {
+ if (injectorState.cleanupAfterEach()) {
+ module.$$cleanup();
+ }
+ };
+
+ module.$$cleanup = function() {
+ var injector = currentSpec.$injector;
+
+ annotatedFunctions.forEach(function(fn) {
+ delete fn.$inject;
+ });
+
+ angular.forEach(currentSpec.$modules, function(module) {
+ if (module && module.$$hashKey) {
+ module.$$hashKey = undefined;
+ }
+ });
+
+ currentSpec.$injector = null;
+ currentSpec.$modules = null;
+ currentSpec.$providerInjector = null;
+ currentSpec = null;
+
+ if (injector) {
+ // Ensure `$rootElement` is instantiated, before checking `originalRootElement`
+ var $rootElement = injector.get('$rootElement');
+ var rootNode = $rootElement && $rootElement[0];
+ var cleanUpNodes = !originalRootElement ? [] : [originalRootElement[0]];
+ if (rootNode && (!originalRootElement || rootNode !== originalRootElement[0])) {
+ cleanUpNodes.push(rootNode);
+ }
+ angular.element.cleanData(cleanUpNodes);
+
+ // Ensure `$destroy()` is available, before calling it
+ // (a mocked `$rootScope` might not implement it (or not even be an object at all))
+ var $rootScope = injector.get('$rootScope');
+ if ($rootScope && $rootScope.$destroy) $rootScope.$destroy();
+ }
+
+ // 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;
+ };
+
+ (window.beforeEach || window.setup)(module.$$beforeEach);
+ (window.afterEach || window.teardown)(module.$$afterEach);
+
/**
* @ngdoc function
* @name angular.mock.inject
@@ -2774,14 +2899,14 @@ if (window.jasmine || window.mocha) {
window.inject = angular.mock.inject = function() {
var blockFns = Array.prototype.slice.call(arguments, 0);
var errorForStack = new Error('Declaration Location');
- return isSpecRunning() ? workFn.call(currentSpec) : workFn;
+ return wasInjectorCreated() ? workFn.call(currentSpec) : workFn;
/////////////////////
function workFn() {
var modules = currentSpec.$modules || [];
var strictDi = !!currentSpec.$injectorStrict;
- modules.unshift(function($injector) {
+ modules.unshift(['$injector', function($injector) {
currentSpec.$providerInjector = $injector;
- });
+ }]);
modules.unshift('ngMock');
modules.unshift('ng');
var injector = currentSpec.$injector;
@@ -2822,7 +2947,7 @@ if (window.jasmine || window.mocha) {
angular.mock.inject.strictDi = function(value) {
value = arguments.length ? !!value : true;
- return isSpecRunning() ? workFn() : workFn;
+ return wasInjectorCreated() ? workFn() : workFn;
function workFn() {
if (value !== currentSpec.$injectorStrict) {
@@ -2834,7 +2959,16 @@ if (window.jasmine || window.mocha) {
}
}
};
-}
+
+ function InjectorState() {
+ this.shared = false;
+ this.sharedError = null;
+
+ this.cleanupAfterEach = function() {
+ return !this.shared || this.sharedError;
+ };
+ }
+})(window.jasmine || window.mocha);
})(window, window.angular);
diff --git a/public/vendor/angular-mocks/bower.json b/public/vendor/angular-mocks/bower.json
index ac8b75413db..4ce65bbc809 100644
--- a/public/vendor/angular-mocks/bower.json
+++ b/public/vendor/angular-mocks/bower.json
@@ -1,10 +1,10 @@
{
"name": "angular-mocks",
- "version": "1.5.1-build.4601+sha.c966876",
+ "version": "1.5.3",
"license": "MIT",
"main": "./angular-mocks.js",
"ignore": [],
"dependencies": {
- "angular": "1.5.1-build.4601+sha.c966876"
+ "angular": "1.5.3"
}
}
diff --git a/public/vendor/angular-mocks/package.json b/public/vendor/angular-mocks/package.json
index eda7287688f..42d78038650 100644
--- a/public/vendor/angular-mocks/package.json
+++ b/public/vendor/angular-mocks/package.json
@@ -1,6 +1,6 @@
{
"name": "angular-mocks",
- "version": "1.5.1-build.4601+sha.c966876",
+ "version": "1.5.3",
"description": "AngularJS mocks for testing",
"main": "angular-mocks.js",
"scripts": {
diff --git a/public/vendor/angular-route/.bower.json b/public/vendor/angular-route/.bower.json
index 43ecb04633b..0abe0215778 100644
--- a/public/vendor/angular-route/.bower.json
+++ b/public/vendor/angular-route/.bower.json
@@ -1,20 +1,20 @@
{
"name": "angular-route",
- "version": "1.5.1-build.4601+sha.c966876",
+ "version": "1.5.3",
"license": "MIT",
"main": "./angular-route.js",
"ignore": [],
"dependencies": {
- "angular": "1.5.1-build.4601+sha.c966876"
+ "angular": "1.5.3"
},
"homepage": "https://github.com/angular/bower-angular-route",
- "_release": "1.5.1-build.4601+sha.c966876",
+ "_release": "1.5.3",
"_resolution": {
"type": "version",
- "tag": "v1.5.1-build.4601+sha.c966876",
- "commit": "967fdabf084ac9f37c6b984d8893ebfebde5fc02"
+ "tag": "v1.5.3",
+ "commit": "750e4833612071d30993c8e4a547a6982eba3b84"
},
"_source": "git://github.com/angular/bower-angular-route.git",
- "_target": "~1.5.1",
+ "_target": "~1.5.3",
"_originalSource": "angular-route"
}
\ No newline at end of file
diff --git a/public/vendor/angular-route/angular-route.js b/public/vendor/angular-route/angular-route.js
index cde0787fecf..3c9a4e8595e 100644
--- a/public/vendor/angular-route/angular-route.js
+++ b/public/vendor/angular-route/angular-route.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.5.1-build.4601+sha.c966876
+ * @license AngularJS v1.5.3
* (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -22,7 +22,11 @@
*/
/* global -ngRouteModule */
var ngRouteModule = angular.module('ngRoute', ['ng']).
- provider('$route', $RouteProvider),
+ provider('$route', $RouteProvider).
+ // Ensure `$route` will be instantiated in time to capture the initial
+ // `$locationChangeSuccess` event. This is necessary in case `ngView` is
+ // included in an asynchronously loaded template.
+ run(['$route', angular.noop]),
$routeMinErr = angular.$$minErr('ngRoute');
/**
@@ -218,9 +222,9 @@ function $RouteProvider() {
path = path
.replace(/([().])/g, '\\$1')
- .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
- var optional = option === '?' ? option : null;
- var star = option === '*' ? option : null;
+ .replace(/(\/)?:(\w+)(\*\?|[\?\*])?/g, function(_, slash, key, option) {
+ var optional = (option === '?' || option === '*?') ? '?' : null;
+ var star = (option === '*' || option === '*?') ? '*' : null;
keys.push({ name: key, optional: !!optional });
slash = slash || '';
return ''
diff --git a/public/vendor/angular-route/angular-route.min.js b/public/vendor/angular-route/angular-route.min.js
index d4888631eca..5d2e84f9498 100644
--- a/public/vendor/angular-route/angular-route.min.js
+++ b/public/vendor/angular-route/angular-route.min.js
@@ -1,15 +1,15 @@
/*
- AngularJS v1.5.1-build.4601+sha.c966876
+ AngularJS v1.5.3
(c) 2010-2016 Google, Inc. http://angularjs.org
License: MIT
*/
(function(r,d,C){'use strict';function x(s,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,y){function k(){n&&(g.cancel(n),n=null);l&&(l.$destroy(),l=null);m&&(n=g.leave(m),n.then(function(){n=null}),m=null)}function z(){var b=s.current&&s.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),f=s.current;m=y(b,function(b){g.enter(b,null,m||c).then(function(){!d.isDefined(u)||u&&!a.$eval(u)||h()});k()});l=f.scope=b;l.$emit("$viewContentLoaded");
l.$eval(v)}else k()}var l,m,n,u=b.autoscroll,v=b.onload||"";a.$on("$routeChangeSuccess",z);z()}}}function A(d,h,g){return{restrict:"ECA",priority:-400,link:function(a,c){var b=g.current,f=b.locals;c.html(f.$template);var y=d(c.contents());if(b.controller){f.$scope=a;var k=h(b.controller,f);b.controllerAs&&(a[b.controllerAs]=k);c.data("$ngControllerController",k);c.children().data("$ngControllerController",k)}a[b.resolveAs||"$resolve"]=f;y(a)}}}r=d.module("ngRoute",["ng"]).provider("$route",function(){function s(a,
-c){return d.extend(Object.create(a),c)}function h(a,d){var b=d.caseInsensitiveMatch,f={originalPath:a,regexp:a},g=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,b,c){a="?"===c?c:null;c="*"===c?c:null;g.push({name:b,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=new RegExp("^"+a+"$",b?"i":"");return f}var g={};this.when=function(a,c){var b=d.copy(c);d.isUndefined(b.reloadOnSearch)&&
-(b.reloadOnSearch=!0);d.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=d.extend(b,a&&h(a,b));if(a){var f="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[f]=d.extend({redirectTo:a},h(f,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,c,b,f,h,k,r){function l(b){var e=
-t.current;(x=(p=n())&&e&&p.$$route===e.$$route&&d.equals(p.pathParams,e.pathParams)&&!p.reloadOnSearch&&!v)||!e&&!p||a.$broadcast("$routeChangeStart",p,e).defaultPrevented&&b&&b.preventDefault()}function m(){var w=t.current,e=p;if(x)w.params=e.params,d.copy(w.params,b),a.$broadcast("$routeUpdate",w);else if(e||w)v=!1,(t.current=e)&&e.redirectTo&&(d.isString(e.redirectTo)?c.path(u(e.redirectTo,e.params)).search(e.params).replace():c.url(e.redirectTo(e.pathParams,c.path(),c.search())).replace()),f.when(e).then(function(){if(e){var a=
-d.extend({},e.resolve),b,c;d.forEach(a,function(b,e){a[e]=d.isString(b)?h.get(b):h.invoke(b,null,null,e)});d.isDefined(b=e.template)?d.isFunction(b)&&(b=b(e.params)):d.isDefined(c=e.templateUrl)&&(d.isFunction(c)&&(c=c(e.params)),d.isDefined(c)&&(e.loadedTemplateUrl=r.valueOf(c),b=k(c)));d.isDefined(b)&&(a.$template=b);return f.all(a)}}).then(function(c){e==t.current&&(e&&(e.locals=c,d.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,w))},function(b){e==t.current&&a.$broadcast("$routeChangeError",
-e,w,b)})}function n(){var a,b;d.forEach(g,function(f,g){var q;if(q=!b){var h=c.path();q=f.keys;var l={};if(f.regexp)if(h=f.regexp.exec(h)){for(var k=1,n=h.length;k
+ * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.
+ * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).
+ * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest
+ * function will be reflected on the scope and in any templates where the object is data-bound.
+ * To prevent his, transform functions should have no side-effects.
+ * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.
+ *
+ *
* ### Default Transformations
*
* The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
@@ -10614,26 +10778,35 @@ function $HttpProvider() {
*
* ## 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.
+ * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must
+ * set the config.cache value or the default cache value to TRUE or to a cache object (created
+ * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes
+ * precedence over the default cache value.
*
- * Note that even if the response is served from cache, delivery of the data is asynchronous in
- * the same way that real requests are.
+ * In order to:
+ * * cache all responses - set the default cache value to TRUE or to a cache object
+ * * cache a specific response - set config.cache value to TRUE or to a cache object
*
- * 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.
+ * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,
+ * then the default `$cacheFactory($http)` object is used.
*
- * You can change the default cache to a new object (built with
- * {@link ng.$cacheFactory `$cacheFactory`}) by updating the
- * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set
- * their `cache` property to `true` will now use this cache object.
+ * The default cache value can be set by updating the
+ * {@link ng.$http#defaults `$http.defaults.cache`} property or the
+ * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.
+ *
+ * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using
+ * the relevant cache object. The next time the same request is made, the response is returned
+ * from the cache without sending a request to the server.
+ *
+ * Take note that:
+ *
+ * * Only GET and JSONP requests are cached.
+ * * The cache key is the request URL including search parameters; headers are not considered.
+ * * Cached responses are returned asynchronously, in the same way as responses from the server.
+ * * If multiple identical requests are made using the same cache, which is not yet populated,
+ * one request will be made to the server and remaining requests will return the same response.
+ * * A cache-control header on the response does not affect if or how responses are cached.
*
- * If you set the default cache to `false` then only requests that specify their own custom
- * cache object will be cached.
*
* ## Interceptors
*
@@ -10803,7 +10976,7 @@ function $HttpProvider() {
* transform function or an array of such functions. The transform function takes the http
* response body, headers and status and returns its transformed (typically deserialized) version.
* See {@link ng.$http#overriding-the-default-transformations-per-request
- * Overriding the Default TransformationjqLiks}
+ * Overriding the Default Transformations}
* - **paramSerializer** - `{string|function(Object):string}` - A function used to
* prepare the string representation of request parameters (specified as an object).
* If specified as string, it is interpreted as function registered with the
@@ -10811,10 +10984,9 @@ function $HttpProvider() {
* by registering it as a {@link auto.$provide#service service}.
* The default serializer is the {@link $httpParamSerializer $httpParamSerializer};
* alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}
- * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
- * GET request, otherwise if a cache instance built with
- * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
- * caching.
+ * - **cache** – `{boolean|Object}` – A boolean value or object created with
+ * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
+ * See {@link $http#caching $http Caching} for more information.
* - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
* that should abort the request when resolved.
* - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
@@ -13725,8 +13897,10 @@ AST.prototype = {
primary = this.arrayDeclaration();
} else if (this.expect('{')) {
primary = this.object();
- } else if (this.constants.hasOwnProperty(this.peek().text)) {
- primary = copy(this.constants[this.consume().text]);
+ } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
+ primary = copy(this.selfReferential[this.consume().text]);
+ } else if (this.options.literals.hasOwnProperty(this.peek().text)) {
+ primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};
} else if (this.peek().identifier) {
primary = this.identifier();
} else if (this.peek().constant) {
@@ -13878,15 +14052,7 @@ AST.prototype = {
return false;
},
-
- /* `undefined` is not a constant, it is an identifier,
- * but using it as an identifier is not supported
- */
- constants: {
- 'true': { type: AST.Literal, value: true },
- 'false': { type: AST.Literal, value: false },
- 'null': { type: AST.Literal, value: null },
- 'undefined': {type: AST.Literal, value: undefined },
+ selfReferential: {
'this': {type: AST.ThisExpression },
'$locals': {type: AST.LocalsExpression }
}
@@ -14576,7 +14742,7 @@ ASTInterpreter.prototype = {
forEach(ast.body, function(expression) {
expressions.push(self.recurse(expression.expression));
});
- var fn = ast.body.length === 0 ? function() {} :
+ var fn = ast.body.length === 0 ? noop :
ast.body.length === 1 ? expressions[0] :
function(scope, locals) {
var lastValue;
@@ -14717,7 +14883,7 @@ ASTInterpreter.prototype = {
return context ? {value: locals} : locals;
};
case AST.NGValueParameter:
- return function(scope, locals, assign, inputs) {
+ return function(scope, locals, assign) {
return context ? {value: assign} : assign;
};
}
@@ -14931,7 +15097,7 @@ var Parser = function(lexer, $filter, options) {
this.lexer = lexer;
this.$filter = $filter;
this.options = options;
- this.ast = new AST(this.lexer);
+ this.ast = new AST(lexer, options);
this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
new ASTCompiler(this.ast, $filter);
};
@@ -15008,16 +15174,39 @@ function getValueOf(value) {
function $ParseProvider() {
var cacheDefault = createMap();
var cacheExpensive = createMap();
+ var literals = {
+ 'true': true,
+ 'false': false,
+ 'null': null,
+ 'undefined': undefined
+ };
+
+ /**
+ * @ngdoc method
+ * @name $parseProvider#addLiteral
+ * @description
+ *
+ * Configure $parse service to add literal values that will be present as literal at expressions.
+ *
+ * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.
+ * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.
+ *
+ **/
+ this.addLiteral = function(literalName, literalValue) {
+ literals[literalName] = literalValue;
+ };
this.$get = ['$filter', function($filter) {
var noUnsafeEval = csp().noUnsafeEval;
var $parseOptions = {
csp: noUnsafeEval,
- expensiveChecks: false
+ expensiveChecks: false,
+ literals: copy(literals)
},
$parseOptionsExpensive = {
csp: noUnsafeEval,
- expensiveChecks: true
+ expensiveChecks: true,
+ literals: copy(literals)
};
var runningChecksEnabled = false;
@@ -15266,15 +15455,15 @@ function $ParseProvider() {
* [Kris Kowal's Q](https://github.com/kriskowal/q).
*
* $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
- * implementations, and the other which resembles ES6 promises to some degree.
+ * implementations, and the other which resembles ES6 (ES2015) promises to some degree.
*
* # $q constructor
*
* The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
- * function as the first argument. This is similar to the native Promise implementation from ES6 Harmony,
+ * function as the first argument. This is similar to the native Promise implementation from ES6,
* see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
*
- * While the constructor-style use is supported, not all of the supporting methods from ES6 Harmony promises are
+ * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are
* available yet.
*
* It can be used like so:
@@ -16627,7 +16816,7 @@ function $RootScopeProvider() {
dirty, ttl = TTL,
next, current, target = this,
watchLog = [],
- logIdx, logMsg, asyncTask;
+ logIdx, asyncTask;
beginPhase('$digest');
// Check for changes to browser url that happened in sync before the call to $digest
@@ -18412,6 +18601,10 @@ function $SceProvider() {
function $SnifferProvider() {
this.$get = ['$window', '$document', function($window, $document) {
var eventSupport = {},
+ // Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by
+ // the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index)
+ isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime,
+ hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
android =
toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
@@ -18456,7 +18649,7 @@ function $SnifferProvider() {
// so let's not use the history API also
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
// jshint -W018
- history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee),
+ history: !!(hasHistoryPushState && !(android < 4) && !boxee),
// jshint +W018
hasEvent: function(event) {
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
@@ -18482,7 +18675,7 @@ function $SnifferProvider() {
}];
}
-var $compileMinErr = minErr('$compile');
+var $templateRequestMinErr = minErr('$compile');
/**
* @ngdoc provider
@@ -18578,7 +18771,7 @@ function $TemplateRequestProvider() {
function handleError(resp) {
if (!ignoreRequestError) {
- throw $compileMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
+ throw $templateRequestMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
tpl, resp.status, resp.statusText);
}
return $q.reject(resp);
@@ -19500,7 +19693,7 @@ function currencyFilter($locale) {
* Formats a number as text.
*
* If the input is null or undefined, it will just be returned.
- * If the input is infinite (Infinity/-Infinity) the Infinity symbol '∞' is returned.
+ * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.
* If the input is not a number an empty string is returned.
*
*
@@ -19636,18 +19829,37 @@ function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
var digit = digits[roundAt];
if (roundAt > 0) {
- digits.splice(roundAt);
+ // Drop fractional digits beyond `roundAt`
+ digits.splice(Math.max(parsedNumber.i, roundAt));
+
+ // Set non-fractional digits beyond `roundAt` to 0
+ for (var j = roundAt; j < digits.length; j++) {
+ digits[j] = 0;
+ }
} else {
// We rounded to zero so reset the parsedNumber
+ fractionLen = Math.max(0, fractionLen);
parsedNumber.i = 1;
- digits.length = roundAt = fractionSize + 1;
- for (var i=0; i < roundAt; i++) digits[i] = 0;
+ digits.length = Math.max(1, roundAt = fractionSize + 1);
+ digits[0] = 0;
+ for (var i = 1; i < roundAt; i++) digits[i] = 0;
}
- if (digit >= 5) digits[roundAt - 1]++;
+ if (digit >= 5) {
+ if (roundAt - 1 < 0) {
+ for (var k = 0; k > roundAt; k--) {
+ digits.unshift(0);
+ parsedNumber.i++;
+ }
+ digits.unshift(1);
+ parsedNumber.i++;
+ } else {
+ digits[roundAt - 1]++;
+ }
+ }
// Pad out with zeros to get the required fraction length
- for (; fractionLen < fractionSize; fractionLen++) digits.push(0);
+ for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
// Do any carrying, e.g. a digit was rounded up to 10
@@ -19719,7 +19931,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
// format the integer digits with grouping separators
var groups = [];
- if (digits.length > pattern.lgSize) {
+ if (digits.length >= pattern.lgSize) {
groups.unshift(digits.splice(-pattern.lgSize).join(''));
}
while (digits.length > pattern.gSize) {
@@ -19746,11 +19958,15 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
}
}
-function padNumber(num, digits, trim) {
+function padNumber(num, digits, trim, negWrap) {
var neg = '';
- if (num < 0) {
- neg = '-';
- num = -num;
+ if (num < 0 || (negWrap && num <= 0)) {
+ if (negWrap) {
+ num = -num + 1;
+ } else {
+ num = -num;
+ neg = '-';
+ }
}
num = '' + num;
while (num.length < digits) num = ZERO_CHAR + num;
@@ -19761,7 +19977,7 @@ function padNumber(num, digits, trim) {
}
-function dateGetter(name, size, offset, trim) {
+function dateGetter(name, size, offset, trim, negWrap) {
offset = offset || 0;
return function(date) {
var value = date['get' + name]();
@@ -19769,14 +19985,15 @@ function dateGetter(name, size, offset, trim) {
value += offset;
}
if (value === 0 && offset == -12) value = 12;
- return padNumber(value, size, trim);
+ return padNumber(value, size, trim, negWrap);
};
}
-function dateStrGetter(name, shortForm) {
+function dateStrGetter(name, shortForm, standAlone) {
return function(date, formats) {
var value = date['get' + name]();
- var get = uppercase(shortForm ? ('SHORT' + name) : name);
+ var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
+ var get = uppercase(propPrefix + name);
return formats[get][value];
};
@@ -19831,13 +20048,14 @@ function longEraGetter(date, formats) {
}
var DATE_FORMATS = {
- yyyy: dateGetter('FullYear', 4),
- yy: dateGetter('FullYear', 2, 0, true),
- y: dateGetter('FullYear', 1),
+ yyyy: dateGetter('FullYear', 4, 0, false, true),
+ yy: dateGetter('FullYear', 2, 0, true, true),
+ y: dateGetter('FullYear', 1, 0, false, true),
MMMM: dateStrGetter('Month'),
MMM: dateStrGetter('Month', true),
MM: dateGetter('Month', 2, 1),
M: dateGetter('Month', 1, 1),
+ LLLL: dateStrGetter('Month', false, true),
dd: dateGetter('Date', 2),
d: dateGetter('Date', 1),
HH: dateGetter('Hours', 2),
@@ -19863,7 +20081,7 @@ var DATE_FORMATS = {
GGGG: longEraGetter
};
-var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
+var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
NUMBER_STRING = /^\-?\d+$/;
/**
@@ -19883,6 +20101,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|
* * `'MMM'`: Month in year (Jan-Dec)
* * `'MM'`: Month in year, padded (01-12)
* * `'M'`: Month in year (1-12)
+ * * `'LLLL'`: Stand-alone month in year (January-December)
* * `'dd'`: Day in month, padded (01-31)
* * `'d'`: Day in month (1-31)
* * `'EEEE'`: Day in Week,(Sunday-Saturday)
@@ -21564,8 +21783,8 @@ var ngFormDirective = formDirectiveFactory(true);
ngModelMinErr: false,
*/
-// Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
-var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;
+// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
+var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
// Note: We are being more lenient, because browsers are too.
// 1. Scheme
@@ -21581,12 +21800,18 @@ var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-
var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
-var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
-var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
-var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
-var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
+var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
+var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
+var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
+var PARTIAL_VALIDATION_TYPES = createMap();
+forEach('date,datetime-local,month,time,week'.split(','), function(type) {
+ PARTIAL_VALIDATION_TYPES[type] = true;
+});
+
var inputType = {
/**
@@ -21942,7 +22167,7 @@ var inputType = {
}]);