Commit 59cabea6 authored by Pascal Hartig's avatar Pascal Hartig

Update all AngularJS apps to 1.2.7

parent da052bf1
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-angular-perf", "name": "todomvc-angular-perf",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "~1.2.1", "angular": "1.2.7",
"todomvc-common": "~0.1.9" "todomvc-common": "~0.1.9"
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -78,7 +78,7 @@ todomvc.controller('TodoCtrl', function TodoCtrl($scope, $location, todoStorage, ...@@ -78,7 +78,7 @@ todomvc.controller('TodoCtrl', function TodoCtrl($scope, $location, todoStorage,
$scope.markAll = function (completed) { $scope.markAll = function (completed) {
todos.forEach(function (todo) { todos.forEach(function (todo) {
todo.completed = completed; todo.completed = !completed;
}); });
$scope.remainingCount = completed ? 0 : todos.length; $scope.remainingCount = completed ? 0 : todos.length;
todoStorage.put(todos); todoStorage.put(todos);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-angular", "name": "todomvc-angular",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "1.2.6", "angular": "1.2.7",
"angularfire": "~0.5.0", "angularfire": "~0.5.0",
"todomvc-common": "~0.1.4" "todomvc-common": "~0.1.4"
}, },
......
/** /**
* @license AngularJS v1.2.7-build.2025+sha.d1c4766 * @license AngularJS v1.2.6
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
......
/** /**
* @license AngularJS v1.2.7-build.2025+sha.d1c4766 * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
...@@ -68,7 +68,7 @@ function minErr(module) { ...@@ -68,7 +68,7 @@ function minErr(module) {
return match; return match;
}); });
message = message + '\nhttp://errors.angularjs.org/1.2.7-build.2025+sha.d1c4766/' + message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
(module ? module + '/' : '') + code; (module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) { for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
...@@ -1038,7 +1038,9 @@ function fromJson(json) { ...@@ -1038,7 +1038,9 @@ function fromJson(json) {
function toBoolean(value) { function toBoolean(value) {
if (value && value.length !== 0) { if (typeof value === 'function') {
value = true;
} else if (value && value.length !== 0) {
var v = lowercase("" + value); var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]'); value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else { } else {
...@@ -1831,7 +1833,7 @@ function setupModuleLoader(window) { ...@@ -1831,7 +1833,7 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/ */
var version = { var version = {
full: '1.2.7-build.2025+sha.d1c4766', // all of these placeholder strings will be replaced by grunt's full: '1.2.7', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task major: 1, // package task
minor: 2, minor: 2,
dot: 7, dot: 7,
...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) { ...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) {
path.unshift(serviceName); path.unshift(serviceName);
cache[serviceName] = INSTANTIATING; cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName); return cache[serviceName] = factory(serviceName);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally { } finally {
path.shift(); path.shift();
} }
...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) {
* @param {boolean=} replace Should new url replace current history record ? * @param {boolean=} replace Should new url replace current history record ?
*/ */
self.url = function(url, replace) { self.url = function(url, replace) {
// Android Browser BFCache causes location reference to become stale. // Android Browser BFCache causes location, history reference to become stale.
if (location !== window.location) location = window.location; if (location !== window.location) location = window.location;
if (history !== window.history) history = window.history;
// setter // setter
if (url) { if (url) {
...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) {
* @description * @description
* Register callback function that will be called, when url changes. * Register callback function that will be called, when url changes.
* *
* It's only called when the url is changed by outside of angular: * It's only called when the url is changed from outside of angular:
* - user types different url into address bar * - user types different url into address bar
* - user clicks on history (forward/back) button * - user clicks on history (forward/back) button
* - user clicks on a link * - user clicks on a link
...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) {
/** /**
* @name ng.$browser#baseHref * @name ng.$browser#baseHref
* @methodOf ng.$browser * @methodOf ng.$browser
* *
* @description * @description
* Returns current <base href> * Returns current <base href>
* (always relative - without domain) * (always relative - without domain)
...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) {
*/ */
self.baseHref = function() { self.baseHref = function() {
var href = baseElement.attr('href'); var href = baseElement.attr('href');
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : ''; return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
}; };
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) {
* It is not meant to be used directly, use the $cookie service instead. * It is not meant to be used directly, use the $cookie service instead.
* *
* The return values vary depending on the arguments that the method was called with as follows: * The return values vary depending on the arguments that the method was called with as follows:
* *
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it * it
* - cookies(name, value) -> set name to value, if value is undefined delete the cookie * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
* - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
* way) * way)
* *
* @returns {Object} Hash of all cookies (if called without any parameter) * @returns {Object} Hash of all cookies (if called without any parameter)
*/ */
self.cookies = function(name, value) { self.cookies = function(name, value) {
...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() { ...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() {
* @function * @function
* *
* @description * @description
* Compiles a piece of HTML string or DOM into a template and produces a template function, which * Compiles an 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. * 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 * The compilation is a process of walking the DOM tree and matching DOM elements to
...@@ -7865,13 +7873,13 @@ function $HttpProvider() { ...@@ -7865,13 +7873,13 @@ function $HttpProvider() {
}]; }];
} }
var XHR = window.XMLHttpRequest || function() { function createXhr(method) {
// IE8 doesn't support PATCH method, but the ActiveX object does
/* global ActiveXObject */ /* global ActiveXObject */
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} return (msie <= 8 && lowercase(method) === 'patch')
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} ? new ActiveXObject('Microsoft.XMLHTTP')
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} : new window.XMLHttpRequest();
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest."); }
};
/** /**
...@@ -7893,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() { ...@@ -7893,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() {
*/ */
function $HttpBackendProvider() { function $HttpBackendProvider() {
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]); return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]);
}]; }];
} }
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) { function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
var ABORTED = -1; var ABORTED = -1;
// TODO(vojta): fix the signature // TODO(vojta): fix the signature
...@@ -7922,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7922,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
delete callbacks[callbackId]; delete callbacks[callbackId];
}); });
} else { } else {
var xhr = new XHR();
var xhr = createXhr(method);
xhr.open(method, url, true); xhr.open(method, url, true);
forEach(headers, function(value, key) { forEach(headers, function(value, key) {
if (isDefined(value)) { if (isDefined(value)) {
...@@ -7934,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7934,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
// response is in the cache. the promise api will ensure that to the app code the api is // response is in the cache. the promise api will ensure that to the app code the api is
// always async // always async
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // onreadystatechange might by called multiple times with readyState === 4 on mobile webkit caused by
// xhrs that are resolved while the app is in the background (see #5426).
// since calling completeRequest sets the `xhr` variable to null, we just check if it's not null before
// continuing
//
// we can't set xhr.onreadystatechange to undefined or delete it because that breaks IE8 (method=PATCH) and
// Safari respectively.
if (xhr && xhr.readyState == 4) {
var responseHeaders = null, var responseHeaders = null,
response = null; response = null;
...@@ -9181,16 +9198,17 @@ function $LocationProvider(){ ...@@ -9181,16 +9198,17 @@ function $LocationProvider(){
// update $location when $browser url changes // update $location when $browser url changes
$browser.onUrlChange(function(newUrl) { $browser.onUrlChange(function(newUrl) {
if ($location.absUrl() != newUrl) { if ($location.absUrl() != newUrl) {
if ($rootScope.$broadcast('$locationChangeStart', newUrl,
$location.absUrl()).defaultPrevented) {
$browser.url($location.absUrl());
return;
}
$rootScope.$evalAsync(function() { $rootScope.$evalAsync(function() {
var oldUrl = $location.absUrl(); var oldUrl = $location.absUrl();
$location.$$parse(newUrl); $location.$$parse(newUrl);
afterLocationChange(oldUrl); if ($rootScope.$broadcast('$locationChangeStart', newUrl,
oldUrl).defaultPrevented) {
$location.$$parse(oldUrl);
$browser.url(oldUrl);
} else {
afterLocationChange(oldUrl);
}
}); });
if (!$rootScope.$$phase) $rootScope.$digest(); if (!$rootScope.$$phase) $rootScope.$digest();
} }
...@@ -11300,6 +11318,7 @@ function $RootScopeProvider(){ ...@@ -11300,6 +11318,7 @@ function $RootScopeProvider(){
this.$$asyncQueue = []; this.$$asyncQueue = [];
this.$$postDigestQueue = []; this.$$postDigestQueue = [];
this.$$listeners = {}; this.$$listeners = {};
this.$$listenerCount = {};
this.$$isolateBindings = {}; this.$$isolateBindings = {};
} }
...@@ -11359,6 +11378,7 @@ function $RootScopeProvider(){ ...@@ -11359,6 +11378,7 @@ function $RootScopeProvider(){
} }
child['this'] = child; child['this'] = child;
child.$$listeners = {}; child.$$listeners = {};
child.$$listenerCount = {};
child.$parent = this; child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail; child.$$prevSibling = this.$$childTail;
...@@ -11518,6 +11538,7 @@ function $RootScopeProvider(){ ...@@ -11518,6 +11538,7 @@ function $RootScopeProvider(){
return function() { return function() {
arrayRemove(array, watcher); arrayRemove(array, watcher);
lastDirtyWatch = null;
}; };
}, },
...@@ -11863,6 +11884,8 @@ function $RootScopeProvider(){ ...@@ -11863,6 +11884,8 @@ function $RootScopeProvider(){
this.$$destroyed = true; this.$$destroyed = true;
if (this === $rootScope) return; if (this === $rootScope) return;
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
...@@ -12052,8 +12075,18 @@ function $RootScopeProvider(){ ...@@ -12052,8 +12075,18 @@ function $RootScopeProvider(){
} }
namedListeners.push(listener); namedListeners.push(listener);
var current = this;
do {
if (!current.$$listenerCount[name]) {
current.$$listenerCount[name] = 0;
}
current.$$listenerCount[name]++;
} while ((current = current.$parent));
var self = this;
return function() { return function() {
namedListeners[indexOf(namedListeners, listener)] = null; namedListeners[indexOf(namedListeners, listener)] = null;
decrementListenerCount(self, 1, name);
}; };
}, },
...@@ -12165,8 +12198,7 @@ function $RootScopeProvider(){ ...@@ -12165,8 +12198,7 @@ function $RootScopeProvider(){
listeners, i, length; listeners, i, length;
//down while you can, then up and next sibling or up and next sibling until back at root //down while you can, then up and next sibling or up and next sibling until back at root
do { while ((current = next)) {
current = next;
event.currentScope = current; event.currentScope = current;
listeners = current.$$listeners[name] || []; listeners = current.$$listeners[name] || [];
for (i=0, length = listeners.length; i<length; i++) { for (i=0, length = listeners.length; i<length; i++) {
...@@ -12188,12 +12220,14 @@ function $RootScopeProvider(){ ...@@ -12188,12 +12220,14 @@ function $RootScopeProvider(){
// Insanity Warning: scope depth-first traversal // Insanity Warning: scope depth-first traversal
// yes, this code is a bit crazy, but it works and we have tests to prove it! // yes, this code is a bit crazy, but it works and we have tests to prove it!
// this piece should be kept in sync with the traversal in $digest // this piece should be kept in sync with the traversal in $digest
if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) { // (though it differs due to having the extra check for $$listenerCount)
if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
(current !== target && current.$$nextSibling)))) {
while(current !== target && !(next = current.$$nextSibling)) { while(current !== target && !(next = current.$$nextSibling)) {
current = current.$parent; current = current.$parent;
} }
} }
} while ((current = next)); }
return event; return event;
} }
...@@ -12222,6 +12256,16 @@ function $RootScopeProvider(){ ...@@ -12222,6 +12256,16 @@ function $RootScopeProvider(){
return fn; return fn;
} }
function decrementListenerCount(current, count, name) {
do {
current.$$listenerCount[name] -= count;
if (current.$$listenerCount[name] === 0) {
delete current.$$listenerCount[name];
}
} while ((current = current.$parent));
}
/** /**
* function used as an initial value for watchers. * function used as an initial value for watchers.
* because it's unique we can easily tell it apart from other values * because it's unique we can easily tell it apart from other values
...@@ -13440,7 +13484,7 @@ function $SnifferProvider() { ...@@ -13440,7 +13484,7 @@ function $SnifferProvider() {
// http://code.google.com/p/android/issues/detail?id=17471 // http://code.google.com/p/android/issues/detail?id=17471
// https://github.com/angular/angular.js/issues/904 // https://github.com/angular/angular.js/issues/904
// older webit browser (533.9) on Boxee box has exactly the same problem as Android has // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
// so let's not use the history API also // so let's not use the history API also
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
// jshint -W018 // jshint -W018
...@@ -13862,21 +13906,21 @@ function $FilterProvider($provide) { ...@@ -13862,21 +13906,21 @@ function $FilterProvider($provide) {
* property of the object. That's equivalent to the simple substring match with a `string` * property of the object. That's equivalent to the simple substring match with a `string`
* as described above. * as described above.
* *
* - `function`: A predicate function can be used to write arbitrary filters. The function is * - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
* called for each element of `array`. The final result is an array of those elements that * called for each element of `array`. The final result is an array of those elements that
* the predicate returned true for. * the predicate returned true for.
* *
* @param {function(expected, actual)|true|undefined} comparator Comparator which is used in * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
* determining if the expected value (from the filter expression) and actual value (from * determining if the expected value (from the filter expression) and actual value (from
* the object in the array) should be considered a match. * the object in the array) should be considered a match.
* *
* Can be one of: * Can be one of:
* *
* - `function(expected, actual)`: * - `function(actual, expected)`:
* The function will be given the object value and the predicate value to compare and * The function will be given the object value and the predicate value to compare and
* should return true if the item should be included in filtered result. * should return true if the item should be included in filtered result.
* *
* - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`. * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
* this is essentially strict comparison of expected and actual. * this is essentially strict comparison of expected and actual.
* *
* - `false|undefined`: A short hand for a function which will look for a substring match in case * - `false|undefined`: A short hand for a function which will look for a substring match in case
...@@ -15981,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { ...@@ -15981,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
} }
if (ctrl.$viewValue !== value) { if (ctrl.$viewValue !== value) {
scope.$apply(function() { if (scope.$$phase) {
ctrl.$setViewValue(value); ctrl.$setViewValue(value);
}); } else {
scope.$apply(function() {
ctrl.$setViewValue(value);
});
}
} }
}; };
...@@ -19062,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19062,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
$$tlb: true, $$tlb: true,
link: function($scope, $element, $attr, ctrl, $transclude){ link: function($scope, $element, $attr, ctrl, $transclude){
var expression = $attr.ngRepeat; var expression = $attr.ngRepeat;
var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
lhs, rhs, valueIdentifier, keyIdentifier, lhs, rhs, valueIdentifier, keyIdentifier,
hashFnLocals = {$id: hashKey}; hashFnLocals = {$id: hashKey};
...@@ -19074,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19074,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
lhs = match[1]; lhs = match[1];
rhs = match[2]; rhs = match[2];
trackByExp = match[4]; trackByExp = match[3];
if (trackByExp) { if (trackByExp) {
trackByExpGetter = $parse(trackByExp); trackByExpGetter = $parse(trackByExp);
......
{ {
"name": "angular", "name": "angular",
"version": "1.2.7-build.2025+sha.d1c4766", "version": "1.2.7",
"main": "./angular.js", "main": "./angular.js",
"dependencies": { "dependencies": {
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-typescript-angular", "name": "todomvc-typescript-angular",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "1.2.6", "angular": "1.2.7",
"todomvc-common": "~0.1.6" "todomvc-common": "~0.1.6"
} }
} }
/** /**
* @license AngularJS v1.2.6 * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
...@@ -68,7 +68,7 @@ function minErr(module) { ...@@ -68,7 +68,7 @@ function minErr(module) {
return match; return match;
}); });
message = message + '\nhttp://errors.angularjs.org/1.2.6/' + message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
(module ? module + '/' : '') + code; (module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) { for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
...@@ -1038,7 +1038,9 @@ function fromJson(json) { ...@@ -1038,7 +1038,9 @@ function fromJson(json) {
function toBoolean(value) { function toBoolean(value) {
if (value && value.length !== 0) { if (typeof value === 'function') {
value = true;
} else if (value && value.length !== 0) {
var v = lowercase("" + value); var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]'); value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else { } else {
...@@ -1831,11 +1833,11 @@ function setupModuleLoader(window) { ...@@ -1831,11 +1833,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/ */
var version = { var version = {
full: '1.2.6', // all of these placeholder strings will be replaced by grunt's full: '1.2.7', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task major: 1, // package task
minor: 2, minor: 2,
dot: 6, dot: 7,
codeName: 'taco-salsafication' codeName: 'emoji-clairvoyance'
}; };
...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) { ...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) {
path.unshift(serviceName); path.unshift(serviceName);
cache[serviceName] = INSTANTIATING; cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName); return cache[serviceName] = factory(serviceName);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally { } finally {
path.shift(); path.shift();
} }
...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) {
* @param {boolean=} replace Should new url replace current history record ? * @param {boolean=} replace Should new url replace current history record ?
*/ */
self.url = function(url, replace) { self.url = function(url, replace) {
// Android Browser BFCache causes location reference to become stale. // Android Browser BFCache causes location, history reference to become stale.
if (location !== window.location) location = window.location; if (location !== window.location) location = window.location;
if (history !== window.history) history = window.history;
// setter // setter
if (url) { if (url) {
...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) {
* @description * @description
* Register callback function that will be called, when url changes. * Register callback function that will be called, when url changes.
* *
* It's only called when the url is changed by outside of angular: * It's only called when the url is changed from outside of angular:
* - user types different url into address bar * - user types different url into address bar
* - user clicks on history (forward/back) button * - user clicks on history (forward/back) button
* - user clicks on a link * - user clicks on a link
...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) {
/** /**
* @name ng.$browser#baseHref * @name ng.$browser#baseHref
* @methodOf ng.$browser * @methodOf ng.$browser
* *
* @description * @description
* Returns current <base href> * Returns current <base href>
* (always relative - without domain) * (always relative - without domain)
...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) {
*/ */
self.baseHref = function() { self.baseHref = function() {
var href = baseElement.attr('href'); var href = baseElement.attr('href');
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : ''; return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
}; };
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) {
* It is not meant to be used directly, use the $cookie service instead. * It is not meant to be used directly, use the $cookie service instead.
* *
* The return values vary depending on the arguments that the method was called with as follows: * The return values vary depending on the arguments that the method was called with as follows:
* *
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it * it
* - cookies(name, value) -> set name to value, if value is undefined delete the cookie * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
* - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
* way) * way)
* *
* @returns {Object} Hash of all cookies (if called without any parameter) * @returns {Object} Hash of all cookies (if called without any parameter)
*/ */
self.cookies = function(name, value) { self.cookies = function(name, value) {
...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() { ...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() {
* @function * @function
* *
* @description * @description
* Compiles a piece of HTML string or DOM into a template and produces a template function, which * Compiles an 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. * 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 * The compilation is a process of walking the DOM tree and matching DOM elements to
...@@ -7049,7 +7057,7 @@ function $HttpProvider() { ...@@ -7049,7 +7057,7 @@ function $HttpProvider() {
* will result in the success callback being called. Note that if the response is a redirect, * 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 * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
* called for such responses. * called for such responses.
* *
* # Calling $http from outside AngularJS * # Calling $http from outside AngularJS
* The `$http` service will not actually send the request until the next `$digest()` is * 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 * executed. Normally this is not an issue, since almost all the time your call to `$http` will
...@@ -7236,19 +7244,20 @@ function $HttpProvider() { ...@@ -7236,19 +7244,20 @@ function $HttpProvider() {
* return responseOrNewPromise * return responseOrNewPromise
* } * }
* return $q.reject(rejection); * return $q.reject(rejection);
* }; * }
* } * };
* }); * });
* *
* $httpProvider.interceptors.push('myHttpInterceptor'); * $httpProvider.interceptors.push('myHttpInterceptor');
* *
* *
* // register the interceptor via an anonymous factory * // alternatively, register the interceptor via an anonymous factory
* $httpProvider.interceptors.push(function($q, dependency1, dependency2) { * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
* return { * return {
* 'request': function(config) { * 'request': function(config) {
* // same as above * // same as above
* }, * },
*
* 'response': function(response) { * 'response': function(response) {
* // same as above * // same as above
* } * }
...@@ -7864,13 +7873,13 @@ function $HttpProvider() { ...@@ -7864,13 +7873,13 @@ function $HttpProvider() {
}]; }];
} }
var XHR = window.XMLHttpRequest || function() { function createXhr(method) {
// IE8 doesn't support PATCH method, but the ActiveX object does
/* global ActiveXObject */ /* global ActiveXObject */
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} return (msie <= 8 && lowercase(method) === 'patch')
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} ? new ActiveXObject('Microsoft.XMLHTTP')
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} : new window.XMLHttpRequest();
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest."); }
};
/** /**
...@@ -7892,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() { ...@@ -7892,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() {
*/ */
function $HttpBackendProvider() { function $HttpBackendProvider() {
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]); return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]);
}]; }];
} }
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) { function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
var ABORTED = -1; var ABORTED = -1;
// TODO(vojta): fix the signature // TODO(vojta): fix the signature
...@@ -7921,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7921,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
delete callbacks[callbackId]; delete callbacks[callbackId];
}); });
} else { } else {
var xhr = new XHR();
var xhr = createXhr(method);
xhr.open(method, url, true); xhr.open(method, url, true);
forEach(headers, function(value, key) { forEach(headers, function(value, key) {
if (isDefined(value)) { if (isDefined(value)) {
...@@ -7933,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7933,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
// response is in the cache. the promise api will ensure that to the app code the api is // response is in the cache. the promise api will ensure that to the app code the api is
// always async // always async
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // onreadystatechange might by called multiple times with readyState === 4 on mobile webkit caused by
// xhrs that are resolved while the app is in the background (see #5426).
// since calling completeRequest sets the `xhr` variable to null, we just check if it's not null before
// continuing
//
// we can't set xhr.onreadystatechange to undefined or delete it because that breaks IE8 (method=PATCH) and
// Safari respectively.
if (xhr && xhr.readyState == 4) {
var responseHeaders = null, var responseHeaders = null,
response = null; response = null;
...@@ -9180,16 +9198,17 @@ function $LocationProvider(){ ...@@ -9180,16 +9198,17 @@ function $LocationProvider(){
// update $location when $browser url changes // update $location when $browser url changes
$browser.onUrlChange(function(newUrl) { $browser.onUrlChange(function(newUrl) {
if ($location.absUrl() != newUrl) { if ($location.absUrl() != newUrl) {
if ($rootScope.$broadcast('$locationChangeStart', newUrl,
$location.absUrl()).defaultPrevented) {
$browser.url($location.absUrl());
return;
}
$rootScope.$evalAsync(function() { $rootScope.$evalAsync(function() {
var oldUrl = $location.absUrl(); var oldUrl = $location.absUrl();
$location.$$parse(newUrl); $location.$$parse(newUrl);
afterLocationChange(oldUrl); if ($rootScope.$broadcast('$locationChangeStart', newUrl,
oldUrl).defaultPrevented) {
$location.$$parse(oldUrl);
$browser.url(oldUrl);
} else {
afterLocationChange(oldUrl);
}
}); });
if (!$rootScope.$$phase) $rootScope.$digest(); if (!$rootScope.$$phase) $rootScope.$digest();
} }
...@@ -11299,6 +11318,7 @@ function $RootScopeProvider(){ ...@@ -11299,6 +11318,7 @@ function $RootScopeProvider(){
this.$$asyncQueue = []; this.$$asyncQueue = [];
this.$$postDigestQueue = []; this.$$postDigestQueue = [];
this.$$listeners = {}; this.$$listeners = {};
this.$$listenerCount = {};
this.$$isolateBindings = {}; this.$$isolateBindings = {};
} }
...@@ -11358,6 +11378,7 @@ function $RootScopeProvider(){ ...@@ -11358,6 +11378,7 @@ function $RootScopeProvider(){
} }
child['this'] = child; child['this'] = child;
child.$$listeners = {}; child.$$listeners = {};
child.$$listenerCount = {};
child.$parent = this; child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail; child.$$prevSibling = this.$$childTail;
...@@ -11517,6 +11538,7 @@ function $RootScopeProvider(){ ...@@ -11517,6 +11538,7 @@ function $RootScopeProvider(){
return function() { return function() {
arrayRemove(array, watcher); arrayRemove(array, watcher);
lastDirtyWatch = null;
}; };
}, },
...@@ -11862,6 +11884,8 @@ function $RootScopeProvider(){ ...@@ -11862,6 +11884,8 @@ function $RootScopeProvider(){
this.$$destroyed = true; this.$$destroyed = true;
if (this === $rootScope) return; if (this === $rootScope) return;
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
...@@ -12051,8 +12075,18 @@ function $RootScopeProvider(){ ...@@ -12051,8 +12075,18 @@ function $RootScopeProvider(){
} }
namedListeners.push(listener); namedListeners.push(listener);
var current = this;
do {
if (!current.$$listenerCount[name]) {
current.$$listenerCount[name] = 0;
}
current.$$listenerCount[name]++;
} while ((current = current.$parent));
var self = this;
return function() { return function() {
namedListeners[indexOf(namedListeners, listener)] = null; namedListeners[indexOf(namedListeners, listener)] = null;
decrementListenerCount(self, 1, name);
}; };
}, },
...@@ -12164,8 +12198,7 @@ function $RootScopeProvider(){ ...@@ -12164,8 +12198,7 @@ function $RootScopeProvider(){
listeners, i, length; listeners, i, length;
//down while you can, then up and next sibling or up and next sibling until back at root //down while you can, then up and next sibling or up and next sibling until back at root
do { while ((current = next)) {
current = next;
event.currentScope = current; event.currentScope = current;
listeners = current.$$listeners[name] || []; listeners = current.$$listeners[name] || [];
for (i=0, length = listeners.length; i<length; i++) { for (i=0, length = listeners.length; i<length; i++) {
...@@ -12187,12 +12220,14 @@ function $RootScopeProvider(){ ...@@ -12187,12 +12220,14 @@ function $RootScopeProvider(){
// Insanity Warning: scope depth-first traversal // Insanity Warning: scope depth-first traversal
// yes, this code is a bit crazy, but it works and we have tests to prove it! // yes, this code is a bit crazy, but it works and we have tests to prove it!
// this piece should be kept in sync with the traversal in $digest // this piece should be kept in sync with the traversal in $digest
if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) { // (though it differs due to having the extra check for $$listenerCount)
if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
(current !== target && current.$$nextSibling)))) {
while(current !== target && !(next = current.$$nextSibling)) { while(current !== target && !(next = current.$$nextSibling)) {
current = current.$parent; current = current.$parent;
} }
} }
} while ((current = next)); }
return event; return event;
} }
...@@ -12221,6 +12256,16 @@ function $RootScopeProvider(){ ...@@ -12221,6 +12256,16 @@ function $RootScopeProvider(){
return fn; return fn;
} }
function decrementListenerCount(current, count, name) {
do {
current.$$listenerCount[name] -= count;
if (current.$$listenerCount[name] === 0) {
delete current.$$listenerCount[name];
}
} while ((current = current.$parent));
}
/** /**
* function used as an initial value for watchers. * function used as an initial value for watchers.
* because it's unique we can easily tell it apart from other values * because it's unique we can easily tell it apart from other values
...@@ -13439,7 +13484,7 @@ function $SnifferProvider() { ...@@ -13439,7 +13484,7 @@ function $SnifferProvider() {
// http://code.google.com/p/android/issues/detail?id=17471 // http://code.google.com/p/android/issues/detail?id=17471
// https://github.com/angular/angular.js/issues/904 // https://github.com/angular/angular.js/issues/904
// older webit browser (533.9) on Boxee box has exactly the same problem as Android has // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
// so let's not use the history API also // so let's not use the history API also
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
// jshint -W018 // jshint -W018
...@@ -13861,21 +13906,21 @@ function $FilterProvider($provide) { ...@@ -13861,21 +13906,21 @@ function $FilterProvider($provide) {
* property of the object. That's equivalent to the simple substring match with a `string` * property of the object. That's equivalent to the simple substring match with a `string`
* as described above. * as described above.
* *
* - `function`: A predicate function can be used to write arbitrary filters. The function is * - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
* called for each element of `array`. The final result is an array of those elements that * called for each element of `array`. The final result is an array of those elements that
* the predicate returned true for. * the predicate returned true for.
* *
* @param {function(expected, actual)|true|undefined} comparator Comparator which is used in * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
* determining if the expected value (from the filter expression) and actual value (from * determining if the expected value (from the filter expression) and actual value (from
* the object in the array) should be considered a match. * the object in the array) should be considered a match.
* *
* Can be one of: * Can be one of:
* *
* - `function(expected, actual)`: * - `function(actual, expected)`:
* The function will be given the object value and the predicate value to compare and * The function will be given the object value and the predicate value to compare and
* should return true if the item should be included in filtered result. * should return true if the item should be included in filtered result.
* *
* - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`. * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
* this is essentially strict comparison of expected and actual. * this is essentially strict comparison of expected and actual.
* *
* - `false|undefined`: A short hand for a function which will look for a substring match in case * - `false|undefined`: A short hand for a function which will look for a substring match in case
...@@ -15980,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { ...@@ -15980,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
} }
if (ctrl.$viewValue !== value) { if (ctrl.$viewValue !== value) {
scope.$apply(function() { if (scope.$$phase) {
ctrl.$setViewValue(value); ctrl.$setViewValue(value);
}); } else {
scope.$apply(function() {
ctrl.$setViewValue(value);
});
}
} }
}; };
...@@ -19061,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19061,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
$$tlb: true, $$tlb: true,
link: function($scope, $element, $attr, ctrl, $transclude){ link: function($scope, $element, $attr, ctrl, $transclude){
var expression = $attr.ngRepeat; var expression = $attr.ngRepeat;
var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
lhs, rhs, valueIdentifier, keyIdentifier, lhs, rhs, valueIdentifier, keyIdentifier,
hashFnLocals = {$id: hashKey}; hashFnLocals = {$id: hashKey};
...@@ -19073,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19073,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
lhs = match[1]; lhs = match[1];
rhs = match[2]; rhs = match[2];
trackByExp = match[4]; trackByExp = match[3];
if (trackByExp) { if (trackByExp) {
trackByExpGetter = $parse(trackByExp); trackByExpGetter = $parse(trackByExp);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "todomvc-angular-requirejs", "name": "todomvc-angular-requirejs",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "1.2.6", "angular": "1.2.7",
"todomvc-common": "~0.1.9", "todomvc-common": "~0.1.9",
"requirejs": "~2.1.9" "requirejs": "~2.1.9"
} }
......
/** /**
* @license AngularJS v1.2.6 * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
...@@ -68,7 +68,7 @@ function minErr(module) { ...@@ -68,7 +68,7 @@ function minErr(module) {
return match; return match;
}); });
message = message + '\nhttp://errors.angularjs.org/1.2.6/' + message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
(module ? module + '/' : '') + code; (module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) { for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
...@@ -1038,7 +1038,9 @@ function fromJson(json) { ...@@ -1038,7 +1038,9 @@ function fromJson(json) {
function toBoolean(value) { function toBoolean(value) {
if (value && value.length !== 0) { if (typeof value === 'function') {
value = true;
} else if (value && value.length !== 0) {
var v = lowercase("" + value); var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]'); value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else { } else {
...@@ -1831,11 +1833,11 @@ function setupModuleLoader(window) { ...@@ -1831,11 +1833,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/ */
var version = { var version = {
full: '1.2.6', // all of these placeholder strings will be replaced by grunt's full: '1.2.7', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task major: 1, // package task
minor: 2, minor: 2,
dot: 6, dot: 7,
codeName: 'taco-salsafication' codeName: 'emoji-clairvoyance'
}; };
...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) { ...@@ -3663,6 +3665,11 @@ function createInjector(modulesToLoad) {
path.unshift(serviceName); path.unshift(serviceName);
cache[serviceName] = INSTANTIATING; cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName); return cache[serviceName] = factory(serviceName);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally { } finally {
path.shift(); path.shift();
} }
...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4197,8 +4204,9 @@ function Browser(window, document, $log, $sniffer) {
* @param {boolean=} replace Should new url replace current history record ? * @param {boolean=} replace Should new url replace current history record ?
*/ */
self.url = function(url, replace) { self.url = function(url, replace) {
// Android Browser BFCache causes location reference to become stale. // Android Browser BFCache causes location, history reference to become stale.
if (location !== window.location) location = window.location; if (location !== window.location) location = window.location;
if (history !== window.history) history = window.history;
// setter // setter
if (url) { if (url) {
...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4250,7 +4258,7 @@ function Browser(window, document, $log, $sniffer) {
* @description * @description
* Register callback function that will be called, when url changes. * Register callback function that will be called, when url changes.
* *
* It's only called when the url is changed by outside of angular: * It's only called when the url is changed from outside of angular:
* - user types different url into address bar * - user types different url into address bar
* - user clicks on history (forward/back) button * - user clicks on history (forward/back) button
* - user clicks on a link * - user clicks on a link
...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4292,7 +4300,7 @@ function Browser(window, document, $log, $sniffer) {
/** /**
* @name ng.$browser#baseHref * @name ng.$browser#baseHref
* @methodOf ng.$browser * @methodOf ng.$browser
* *
* @description * @description
* Returns current <base href> * Returns current <base href>
* (always relative - without domain) * (always relative - without domain)
...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) {
*/ */
self.baseHref = function() { self.baseHref = function() {
var href = baseElement.attr('href'); var href = baseElement.attr('href');
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : ''; return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
}; };
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) { ...@@ -4323,13 +4331,13 @@ function Browser(window, document, $log, $sniffer) {
* It is not meant to be used directly, use the $cookie service instead. * It is not meant to be used directly, use the $cookie service instead.
* *
* The return values vary depending on the arguments that the method was called with as follows: * The return values vary depending on the arguments that the method was called with as follows:
* *
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it * it
* - cookies(name, value) -> set name to value, if value is undefined delete the cookie * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
* - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
* way) * way)
* *
* @returns {Object} Hash of all cookies (if called without any parameter) * @returns {Object} Hash of all cookies (if called without any parameter)
*/ */
self.cookies = function(name, value) { self.cookies = function(name, value) {
...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() { ...@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() {
* @function * @function
* *
* @description * @description
* Compiles a piece of HTML string or DOM into a template and produces a template function, which * Compiles an 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. * 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 * The compilation is a process of walking the DOM tree and matching DOM elements to
...@@ -7049,7 +7057,7 @@ function $HttpProvider() { ...@@ -7049,7 +7057,7 @@ function $HttpProvider() {
* will result in the success callback being called. Note that if the response is a redirect, * 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 * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
* called for such responses. * called for such responses.
* *
* # Calling $http from outside AngularJS * # Calling $http from outside AngularJS
* The `$http` service will not actually send the request until the next `$digest()` is * 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 * executed. Normally this is not an issue, since almost all the time your call to `$http` will
...@@ -7236,19 +7244,20 @@ function $HttpProvider() { ...@@ -7236,19 +7244,20 @@ function $HttpProvider() {
* return responseOrNewPromise * return responseOrNewPromise
* } * }
* return $q.reject(rejection); * return $q.reject(rejection);
* }; * }
* } * };
* }); * });
* *
* $httpProvider.interceptors.push('myHttpInterceptor'); * $httpProvider.interceptors.push('myHttpInterceptor');
* *
* *
* // register the interceptor via an anonymous factory * // alternatively, register the interceptor via an anonymous factory
* $httpProvider.interceptors.push(function($q, dependency1, dependency2) { * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
* return { * return {
* 'request': function(config) { * 'request': function(config) {
* // same as above * // same as above
* }, * },
*
* 'response': function(response) { * 'response': function(response) {
* // same as above * // same as above
* } * }
...@@ -7864,13 +7873,13 @@ function $HttpProvider() { ...@@ -7864,13 +7873,13 @@ function $HttpProvider() {
}]; }];
} }
var XHR = window.XMLHttpRequest || function() { function createXhr(method) {
// IE8 doesn't support PATCH method, but the ActiveX object does
/* global ActiveXObject */ /* global ActiveXObject */
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} return (msie <= 8 && lowercase(method) === 'patch')
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} ? new ActiveXObject('Microsoft.XMLHTTP')
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} : new window.XMLHttpRequest();
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest."); }
};
/** /**
...@@ -7892,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() { ...@@ -7892,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() {
*/ */
function $HttpBackendProvider() { function $HttpBackendProvider() {
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]); return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]);
}]; }];
} }
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) { function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
var ABORTED = -1; var ABORTED = -1;
// TODO(vojta): fix the signature // TODO(vojta): fix the signature
...@@ -7921,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7921,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
delete callbacks[callbackId]; delete callbacks[callbackId];
}); });
} else { } else {
var xhr = new XHR();
var xhr = createXhr(method);
xhr.open(method, url, true); xhr.open(method, url, true);
forEach(headers, function(value, key) { forEach(headers, function(value, key) {
if (isDefined(value)) { if (isDefined(value)) {
...@@ -7933,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) ...@@ -7933,7 +7944,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
// response is in the cache. the promise api will ensure that to the app code the api is // response is in the cache. the promise api will ensure that to the app code the api is
// always async // always async
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // onreadystatechange might by called multiple times with readyState === 4 on mobile webkit caused by
// xhrs that are resolved while the app is in the background (see #5426).
// since calling completeRequest sets the `xhr` variable to null, we just check if it's not null before
// continuing
//
// we can't set xhr.onreadystatechange to undefined or delete it because that breaks IE8 (method=PATCH) and
// Safari respectively.
if (xhr && xhr.readyState == 4) {
var responseHeaders = null, var responseHeaders = null,
response = null; response = null;
...@@ -9180,16 +9198,17 @@ function $LocationProvider(){ ...@@ -9180,16 +9198,17 @@ function $LocationProvider(){
// update $location when $browser url changes // update $location when $browser url changes
$browser.onUrlChange(function(newUrl) { $browser.onUrlChange(function(newUrl) {
if ($location.absUrl() != newUrl) { if ($location.absUrl() != newUrl) {
if ($rootScope.$broadcast('$locationChangeStart', newUrl,
$location.absUrl()).defaultPrevented) {
$browser.url($location.absUrl());
return;
}
$rootScope.$evalAsync(function() { $rootScope.$evalAsync(function() {
var oldUrl = $location.absUrl(); var oldUrl = $location.absUrl();
$location.$$parse(newUrl); $location.$$parse(newUrl);
afterLocationChange(oldUrl); if ($rootScope.$broadcast('$locationChangeStart', newUrl,
oldUrl).defaultPrevented) {
$location.$$parse(oldUrl);
$browser.url(oldUrl);
} else {
afterLocationChange(oldUrl);
}
}); });
if (!$rootScope.$$phase) $rootScope.$digest(); if (!$rootScope.$$phase) $rootScope.$digest();
} }
...@@ -11299,6 +11318,7 @@ function $RootScopeProvider(){ ...@@ -11299,6 +11318,7 @@ function $RootScopeProvider(){
this.$$asyncQueue = []; this.$$asyncQueue = [];
this.$$postDigestQueue = []; this.$$postDigestQueue = [];
this.$$listeners = {}; this.$$listeners = {};
this.$$listenerCount = {};
this.$$isolateBindings = {}; this.$$isolateBindings = {};
} }
...@@ -11358,6 +11378,7 @@ function $RootScopeProvider(){ ...@@ -11358,6 +11378,7 @@ function $RootScopeProvider(){
} }
child['this'] = child; child['this'] = child;
child.$$listeners = {}; child.$$listeners = {};
child.$$listenerCount = {};
child.$parent = this; child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail; child.$$prevSibling = this.$$childTail;
...@@ -11517,6 +11538,7 @@ function $RootScopeProvider(){ ...@@ -11517,6 +11538,7 @@ function $RootScopeProvider(){
return function() { return function() {
arrayRemove(array, watcher); arrayRemove(array, watcher);
lastDirtyWatch = null;
}; };
}, },
...@@ -11862,6 +11884,8 @@ function $RootScopeProvider(){ ...@@ -11862,6 +11884,8 @@ function $RootScopeProvider(){
this.$$destroyed = true; this.$$destroyed = true;
if (this === $rootScope) return; if (this === $rootScope) return;
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
...@@ -12051,8 +12075,18 @@ function $RootScopeProvider(){ ...@@ -12051,8 +12075,18 @@ function $RootScopeProvider(){
} }
namedListeners.push(listener); namedListeners.push(listener);
var current = this;
do {
if (!current.$$listenerCount[name]) {
current.$$listenerCount[name] = 0;
}
current.$$listenerCount[name]++;
} while ((current = current.$parent));
var self = this;
return function() { return function() {
namedListeners[indexOf(namedListeners, listener)] = null; namedListeners[indexOf(namedListeners, listener)] = null;
decrementListenerCount(self, 1, name);
}; };
}, },
...@@ -12164,8 +12198,7 @@ function $RootScopeProvider(){ ...@@ -12164,8 +12198,7 @@ function $RootScopeProvider(){
listeners, i, length; listeners, i, length;
//down while you can, then up and next sibling or up and next sibling until back at root //down while you can, then up and next sibling or up and next sibling until back at root
do { while ((current = next)) {
current = next;
event.currentScope = current; event.currentScope = current;
listeners = current.$$listeners[name] || []; listeners = current.$$listeners[name] || [];
for (i=0, length = listeners.length; i<length; i++) { for (i=0, length = listeners.length; i<length; i++) {
...@@ -12187,12 +12220,14 @@ function $RootScopeProvider(){ ...@@ -12187,12 +12220,14 @@ function $RootScopeProvider(){
// Insanity Warning: scope depth-first traversal // Insanity Warning: scope depth-first traversal
// yes, this code is a bit crazy, but it works and we have tests to prove it! // yes, this code is a bit crazy, but it works and we have tests to prove it!
// this piece should be kept in sync with the traversal in $digest // this piece should be kept in sync with the traversal in $digest
if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) { // (though it differs due to having the extra check for $$listenerCount)
if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
(current !== target && current.$$nextSibling)))) {
while(current !== target && !(next = current.$$nextSibling)) { while(current !== target && !(next = current.$$nextSibling)) {
current = current.$parent; current = current.$parent;
} }
} }
} while ((current = next)); }
return event; return event;
} }
...@@ -12221,6 +12256,16 @@ function $RootScopeProvider(){ ...@@ -12221,6 +12256,16 @@ function $RootScopeProvider(){
return fn; return fn;
} }
function decrementListenerCount(current, count, name) {
do {
current.$$listenerCount[name] -= count;
if (current.$$listenerCount[name] === 0) {
delete current.$$listenerCount[name];
}
} while ((current = current.$parent));
}
/** /**
* function used as an initial value for watchers. * function used as an initial value for watchers.
* because it's unique we can easily tell it apart from other values * because it's unique we can easily tell it apart from other values
...@@ -13439,7 +13484,7 @@ function $SnifferProvider() { ...@@ -13439,7 +13484,7 @@ function $SnifferProvider() {
// http://code.google.com/p/android/issues/detail?id=17471 // http://code.google.com/p/android/issues/detail?id=17471
// https://github.com/angular/angular.js/issues/904 // https://github.com/angular/angular.js/issues/904
// older webit browser (533.9) on Boxee box has exactly the same problem as Android has // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
// so let's not use the history API also // so let's not use the history API also
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
// jshint -W018 // jshint -W018
...@@ -13861,21 +13906,21 @@ function $FilterProvider($provide) { ...@@ -13861,21 +13906,21 @@ function $FilterProvider($provide) {
* property of the object. That's equivalent to the simple substring match with a `string` * property of the object. That's equivalent to the simple substring match with a `string`
* as described above. * as described above.
* *
* - `function`: A predicate function can be used to write arbitrary filters. The function is * - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
* called for each element of `array`. The final result is an array of those elements that * called for each element of `array`. The final result is an array of those elements that
* the predicate returned true for. * the predicate returned true for.
* *
* @param {function(expected, actual)|true|undefined} comparator Comparator which is used in * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
* determining if the expected value (from the filter expression) and actual value (from * determining if the expected value (from the filter expression) and actual value (from
* the object in the array) should be considered a match. * the object in the array) should be considered a match.
* *
* Can be one of: * Can be one of:
* *
* - `function(expected, actual)`: * - `function(actual, expected)`:
* The function will be given the object value and the predicate value to compare and * The function will be given the object value and the predicate value to compare and
* should return true if the item should be included in filtered result. * should return true if the item should be included in filtered result.
* *
* - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`. * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
* this is essentially strict comparison of expected and actual. * this is essentially strict comparison of expected and actual.
* *
* - `false|undefined`: A short hand for a function which will look for a substring match in case * - `false|undefined`: A short hand for a function which will look for a substring match in case
...@@ -15980,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { ...@@ -15980,9 +16025,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
} }
if (ctrl.$viewValue !== value) { if (ctrl.$viewValue !== value) {
scope.$apply(function() { if (scope.$$phase) {
ctrl.$setViewValue(value); ctrl.$setViewValue(value);
}); } else {
scope.$apply(function() {
ctrl.$setViewValue(value);
});
}
} }
}; };
...@@ -19061,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19061,7 +19110,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
$$tlb: true, $$tlb: true,
link: function($scope, $element, $attr, ctrl, $transclude){ link: function($scope, $element, $attr, ctrl, $transclude){
var expression = $attr.ngRepeat; var expression = $attr.ngRepeat;
var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
lhs, rhs, valueIdentifier, keyIdentifier, lhs, rhs, valueIdentifier, keyIdentifier,
hashFnLocals = {$id: hashKey}; hashFnLocals = {$id: hashKey};
...@@ -19073,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19073,7 +19122,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
lhs = match[1]; lhs = match[1];
rhs = match[2]; rhs = match[2];
trackByExp = match[4]; trackByExp = match[3];
if (trackByExp) { if (trackByExp) {
trackByExpGetter = $parse(trackByExp); trackByExpGetter = $parse(trackByExp);
......
/** vim: et:ts=4:sw=4:sts=4 /** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * @license RequireJS 2.1.10 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license. * Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details * see: http://github.com/jrburke/requirejs for details
*/ */
...@@ -12,7 +12,7 @@ var requirejs, require, define; ...@@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) { (function (global) {
var req, s, head, baseElement, dataMain, src, var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath, interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.9', version = '2.1.10',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/, jsSuffixRegExp = /\.js$/,
...@@ -108,7 +108,10 @@ var requirejs, require, define; ...@@ -108,7 +108,10 @@ var requirejs, require, define;
if (source) { if (source) {
eachProp(source, function (value, prop) { eachProp(source, function (value, prop) {
if (force || !hasProp(target, prop)) { if (force || !hasProp(target, prop)) {
if (deepStringMixin && typeof value !== 'string') { if (deepStringMixin && typeof value === 'object' && value &&
!isArray(value) && !isFunction(value) &&
!(value instanceof RegExp)) {
if (!target[prop]) { if (!target[prop]) {
target[prop] = {}; target[prop] = {};
} }
...@@ -201,6 +204,7 @@ var requirejs, require, define; ...@@ -201,6 +204,7 @@ var requirejs, require, define;
waitSeconds: 7, waitSeconds: 7,
baseUrl: './', baseUrl: './',
paths: {}, paths: {},
bundles: {},
pkgs: {}, pkgs: {},
shim: {}, shim: {},
config: {} config: {}
...@@ -214,6 +218,7 @@ var requirejs, require, define; ...@@ -214,6 +218,7 @@ var requirejs, require, define;
defQueue = [], defQueue = [],
defined = {}, defined = {},
urlFetched = {}, urlFetched = {},
bundlesMap = {},
requireCounter = 1, requireCounter = 1,
unnormalizedCounter = 1; unnormalizedCounter = 1;
...@@ -227,8 +232,8 @@ var requirejs, require, define; ...@@ -227,8 +232,8 @@ var requirejs, require, define;
* @param {Array} ary the array of path segments. * @param {Array} ary the array of path segments.
*/ */
function trimDots(ary) { function trimDots(ary) {
var i, part; var i, part, length = ary.length;
for (i = 0; ary[i]; i += 1) { for (i = 0; i < length; i++) {
part = ary[i]; part = ary[i];
if (part === '.') { if (part === '.') {
ary.splice(i, 1); ary.splice(i, 1);
...@@ -261,7 +266,7 @@ var requirejs, require, define; ...@@ -261,7 +266,7 @@ var requirejs, require, define;
* @returns {String} normalized name * @returns {String} normalized name
*/ */
function normalize(name, baseName, applyMap) { function normalize(name, baseName, applyMap) {
var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
foundMap, foundI, foundStarMap, starI, foundMap, foundI, foundStarMap, starI,
baseParts = baseName && baseName.split('/'), baseParts = baseName && baseName.split('/'),
normalizedBaseParts = baseParts, normalizedBaseParts = baseParts,
...@@ -274,29 +279,26 @@ var requirejs, require, define; ...@@ -274,29 +279,26 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will //otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end. //be relative to baseUrl in the end.
if (baseName) { if (baseName) {
if (getOwn(config.pkgs, baseName)) { //Convert baseName to array, and lop off the last part,
//If the baseName is a package name, then just treat it as one //so that . matches that 'directory' and not name of the baseName's
//name to concat the name with. //module. For instance, baseName of 'one/two/three', maps to
normalizedBaseParts = baseParts = [baseName]; //'one/two/three.js', but we want the directory, 'one/two' for
} else { //this normalization.
//Convert baseName to array, and lop off the last part, normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
//so that . matches that 'directory' and not name of the baseName's name = name.split('/');
//module. For instance, baseName of 'one/two/three', maps to lastIndex = name.length - 1;
//'one/two/three.js', but we want the directory, 'one/two' for
//this normalization. // If wanting node ID compatibility, strip .js from end
normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); // of IDs. Have to do this here, and not in nameToUrl
// because node allows either .js or non .js to map
// to same file.
if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
} }
name = normalizedBaseParts.concat(name.split('/')); name = normalizedBaseParts.concat(name);
trimDots(name); trimDots(name);
//Some use of packages may use a . path to reference the
//'main' module name, so normalize for that.
pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));
name = name.join('/'); name = name.join('/');
if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
name = pkgName;
}
} else if (name.indexOf('./') === 0) { } else if (name.indexOf('./') === 0) {
// No baseName, so this is ID is resolved relative // No baseName, so this is ID is resolved relative
// to baseUrl, pull off the leading dot. // to baseUrl, pull off the leading dot.
...@@ -308,7 +310,7 @@ var requirejs, require, define; ...@@ -308,7 +310,7 @@ var requirejs, require, define;
if (applyMap && map && (baseParts || starMap)) { if (applyMap && map && (baseParts || starMap)) {
nameParts = name.split('/'); nameParts = name.split('/');
for (i = nameParts.length; i > 0; i -= 1) { outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
nameSegment = nameParts.slice(0, i).join('/'); nameSegment = nameParts.slice(0, i).join('/');
if (baseParts) { if (baseParts) {
...@@ -325,16 +327,12 @@ var requirejs, require, define; ...@@ -325,16 +327,12 @@ var requirejs, require, define;
//Match, update name to the new value. //Match, update name to the new value.
foundMap = mapValue; foundMap = mapValue;
foundI = i; foundI = i;
break; break outerLoop;
} }
} }
} }
} }
if (foundMap) {
break;
}
//Check for a star map match, but just hold on to it, //Check for a star map match, but just hold on to it,
//if there is a shorter segment match later in a matching //if there is a shorter segment match later in a matching
//config, then favor over this star map. //config, then favor over this star map.
...@@ -355,7 +353,11 @@ var requirejs, require, define; ...@@ -355,7 +353,11 @@ var requirejs, require, define;
} }
} }
return name; // If the name points to a package's name, use
// the package main instead.
pkgMain = getOwn(config.pkgs, name);
return pkgMain ? pkgMain : name;
} }
function removeScript(name) { function removeScript(name) {
...@@ -548,7 +550,7 @@ var requirejs, require, define; ...@@ -548,7 +550,7 @@ var requirejs, require, define;
//local var ref to defQueue, so cannot just reassign the one //local var ref to defQueue, so cannot just reassign the one
//on context. //on context.
apsp.apply(defQueue, apsp.apply(defQueue,
[defQueue.length - 1, 0].concat(globalDefQueue)); [defQueue.length, 0].concat(globalDefQueue));
globalDefQueue = []; globalDefQueue = [];
} }
} }
...@@ -579,15 +581,9 @@ var requirejs, require, define; ...@@ -579,15 +581,9 @@ var requirejs, require, define;
id: mod.map.id, id: mod.map.id,
uri: mod.map.url, uri: mod.map.url,
config: function () { config: function () {
var c, return getOwn(config.config, mod.map.id) || {};
pkg = getOwn(config.pkgs, mod.map.id);
// For packages, only support config targeted
// at the main module.
c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) :
getOwn(config.config, mod.map.id);
return c || {};
}, },
exports: defined[mod.map.id] exports: handlers.exports(mod)
}); });
} }
} }
...@@ -628,7 +624,7 @@ var requirejs, require, define; ...@@ -628,7 +624,7 @@ var requirejs, require, define;
} }
function checkLoaded() { function checkLoaded() {
var map, modId, err, usingPathFallback, var err, usingPathFallback,
waitInterval = config.waitSeconds * 1000, waitInterval = config.waitSeconds * 1000,
//It is possible to disable the wait interval by using waitSeconds of 0. //It is possible to disable the wait interval by using waitSeconds of 0.
expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
...@@ -646,8 +642,8 @@ var requirejs, require, define; ...@@ -646,8 +642,8 @@ var requirejs, require, define;
//Figure out the state of all the modules. //Figure out the state of all the modules.
eachProp(enabledRegistry, function (mod) { eachProp(enabledRegistry, function (mod) {
map = mod.map; var map = mod.map,
modId = map.id; modId = map.id;
//Skip things that are not enabled or in error state. //Skip things that are not enabled or in error state.
if (!mod.enabled) { if (!mod.enabled) {
...@@ -870,17 +866,14 @@ var requirejs, require, define; ...@@ -870,17 +866,14 @@ var requirejs, require, define;
exports = context.execCb(id, factory, depExports, exports); exports = context.execCb(id, factory, depExports, exports);
} }
if (this.map.isDefine) { // Favor return value over exports. If node/cjs in play,
//If setting exports via 'module' is in play, // then will not have a return value anyway. Favor
//favor that over return value and exports. After that, // module.exports assignment over exports object.
//favor a non-undefined return value over exports use. if (this.map.isDefine && exports === undefined) {
cjsModule = this.module; cjsModule = this.module;
if (cjsModule && if (cjsModule) {
cjsModule.exports !== undefined &&
//Make sure it is not already the exports value
cjsModule.exports !== this.exports) {
exports = cjsModule.exports; exports = cjsModule.exports;
} else if (exports === undefined && this.usingExports) { } else if (this.usingExports) {
//exports already set the defined value. //exports already set the defined value.
exports = this.exports; exports = this.exports;
} }
...@@ -940,6 +933,7 @@ var requirejs, require, define; ...@@ -940,6 +933,7 @@ var requirejs, require, define;
on(pluginMap, 'defined', bind(this, function (plugin) { on(pluginMap, 'defined', bind(this, function (plugin) {
var load, normalizedMap, normalizedMod, var load, normalizedMap, normalizedMod,
bundleId = getOwn(bundlesMap, this.map.id),
name = this.map.name, name = this.map.name,
parentName = this.map.parentMap ? this.map.parentMap.name : null, parentName = this.map.parentMap ? this.map.parentMap.name : null,
localRequire = context.makeRequire(map.parentMap, { localRequire = context.makeRequire(map.parentMap, {
...@@ -985,6 +979,14 @@ var requirejs, require, define; ...@@ -985,6 +979,14 @@ var requirejs, require, define;
return; return;
} }
//If a paths config, then just load that file instead to
//resolve the plugin, as it is built into that paths layer.
if (bundleId) {
this.map.url = context.nameToUrl(bundleId);
this.load();
return;
}
load = bind(this, function (value) { load = bind(this, function (value) {
this.init([], function () { return value; }, null, { this.init([], function () { return value; }, null, {
enabled: true enabled: true
...@@ -1249,31 +1251,38 @@ var requirejs, require, define; ...@@ -1249,31 +1251,38 @@ var requirejs, require, define;
} }
} }
//Save off the paths and packages since they require special processing, //Save off the paths since they require special processing,
//they are additive. //they are additive.
var pkgs = config.pkgs, var shim = config.shim,
shim = config.shim,
objs = { objs = {
paths: true, paths: true,
bundles: true,
config: true, config: true,
map: true map: true
}; };
eachProp(cfg, function (value, prop) { eachProp(cfg, function (value, prop) {
if (objs[prop]) { if (objs[prop]) {
if (prop === 'map') { if (!config[prop]) {
if (!config.map) { config[prop] = {};
config.map = {};
}
mixin(config[prop], value, true, true);
} else {
mixin(config[prop], value, true);
} }
mixin(config[prop], value, true, true);
} else { } else {
config[prop] = value; config[prop] = value;
} }
}); });
//Reverse map the bundles
if (cfg.bundles) {
eachProp(cfg.bundles, function (value, prop) {
each(value, function (v) {
if (v !== prop) {
bundlesMap[v] = prop;
}
});
});
}
//Merge shim //Merge shim
if (cfg.shim) { if (cfg.shim) {
eachProp(cfg.shim, function (value, id) { eachProp(cfg.shim, function (value, id) {
...@@ -1294,29 +1303,25 @@ var requirejs, require, define; ...@@ -1294,29 +1303,25 @@ var requirejs, require, define;
//Adjust packages if necessary. //Adjust packages if necessary.
if (cfg.packages) { if (cfg.packages) {
each(cfg.packages, function (pkgObj) { each(cfg.packages, function (pkgObj) {
var location; var location, name;
pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
name = pkgObj.name;
location = pkgObj.location; location = pkgObj.location;
if (location) {
config.paths[name] = pkgObj.location;
}
//Create a brand new object on pkgs, since currentPackages can //Save pointer to main module ID for pkg name.
//be passed in again, and config.pkgs is the internal transformed //Remove leading dot in main, so main paths are normalized,
//state for all package configs. //and remove any trailing .js, since different package
pkgs[pkgObj.name] = { //envs have different conventions: some use a module name,
name: pkgObj.name, //some use a file name.
location: location || pkgObj.name, config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
//Remove leading dot in main, so main paths are normalized, .replace(currDirRegExp, '')
//and remove any trailing .js, since different package .replace(jsSuffixRegExp, '');
//envs have different conventions: some use a module name,
//some use a file name.
main: (pkgObj.main || 'main')
.replace(currDirRegExp, '')
.replace(jsSuffixRegExp, '')
};
}); });
//Done with modifications, assing packages back to context config
config.pkgs = pkgs;
} }
//If there are any "waiting to execute" modules in the registry, //If there are any "waiting to execute" modules in the registry,
...@@ -1469,6 +1474,15 @@ var requirejs, require, define; ...@@ -1469,6 +1474,15 @@ var requirejs, require, define;
delete urlFetched[map.url]; delete urlFetched[map.url];
delete undefEvents[id]; delete undefEvents[id];
//Clean queued defines too. Go backwards
//in array so that the splices do not
//mess up the iteration.
eachReverse(defQueue, function(args, i) {
if(args[0] === id) {
defQueue.splice(i, 1);
}
});
if (mod) { if (mod) {
//Hold on to listeners in case the //Hold on to listeners in case the
//module will be attempted to be reloaded //module will be attempted to be reloaded
...@@ -1562,8 +1576,19 @@ var requirejs, require, define; ...@@ -1562,8 +1576,19 @@ var requirejs, require, define;
* internal API, not a public one. Use toUrl for the public API. * internal API, not a public one. Use toUrl for the public API.
*/ */
nameToUrl: function (moduleName, ext, skipExt) { nameToUrl: function (moduleName, ext, skipExt) {
var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, var paths, syms, i, parentModule, url,
parentPath; parentPath, bundleId,
pkgMain = getOwn(config.pkgs, moduleName);
if (pkgMain) {
moduleName = pkgMain;
}
bundleId = getOwn(bundlesMap, moduleName);
if (bundleId) {
return context.nameToUrl(bundleId, ext, skipExt);
}
//If a colon is in the URL, it indicates a protocol is used and it is just //If a colon is in the URL, it indicates a protocol is used and it is just
//an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
...@@ -1577,7 +1602,6 @@ var requirejs, require, define; ...@@ -1577,7 +1602,6 @@ var requirejs, require, define;
} else { } else {
//A module that needs to be converted to a path. //A module that needs to be converted to a path.
paths = config.paths; paths = config.paths;
pkgs = config.pkgs;
syms = moduleName.split('/'); syms = moduleName.split('/');
//For each module name segment, see if there is a path //For each module name segment, see if there is a path
...@@ -1585,7 +1609,7 @@ var requirejs, require, define; ...@@ -1585,7 +1609,7 @@ var requirejs, require, define;
//and work up from it. //and work up from it.
for (i = syms.length; i > 0; i -= 1) { for (i = syms.length; i > 0; i -= 1) {
parentModule = syms.slice(0, i).join('/'); parentModule = syms.slice(0, i).join('/');
pkg = getOwn(pkgs, parentModule);
parentPath = getOwn(paths, parentModule); parentPath = getOwn(paths, parentModule);
if (parentPath) { if (parentPath) {
//If an array, it means there are a few choices, //If an array, it means there are a few choices,
...@@ -1595,16 +1619,6 @@ var requirejs, require, define; ...@@ -1595,16 +1619,6 @@ var requirejs, require, define;
} }
syms.splice(0, i, parentPath); syms.splice(0, i, parentPath);
break; break;
} else if (pkg) {
//If module name is just the package name, then looking
//for the main module.
if (moduleName === pkg.name) {
pkgPath = pkg.location + '/' + pkg.main;
} else {
pkgPath = pkg.location;
}
syms.splice(0, i, pkgPath);
break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment