diff --git a/lib/angularjs-rails/version.rb b/lib/angularjs-rails/version.rb
index ce88232..e269701 100644
--- a/lib/angularjs-rails/version.rb
+++ b/lib/angularjs-rails/version.rb
@@ -1,6 +1,6 @@
module AngularJS
module Rails
- VERSION = "1.2.6"
+ VERSION = "1.2.7"
UNSTABLE_VERSION = "1.1.5"
end
end
diff --git a/vendor/assets/javascripts/angular-animate.js b/vendor/assets/javascripts/angular-animate.js
index de2b18d..2d882eb 100644
--- a/vendor/assets/javascripts/angular-animate.js
+++ b/vendor/assets/javascripts/angular-animate.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -616,9 +616,14 @@ angular.module('ngAnimate', ['ng'])
}
var animations = [];
+
//only add animations if the currently running animation is not structural
//or if there is no animation running at all
- if(!ngAnimateState.running || !(isClassBased && ngAnimateState.structural)) {
+ var allowAnimations = isClassBased ?
+ !ngAnimateState.disabled && (!ngAnimateState.running || !ngAnimateState.structural) :
+ true;
+
+ if(allowAnimations) {
forEach(matches, function(animation) {
//add the animation to the queue to if it is allowed to be cancelled
if(!animation.allowCancel || animation.allowCancel(element, animationEvent, className)) {
@@ -1147,7 +1152,7 @@ angular.module('ngAnimate', ['ng'])
var propertyStyle = timings.transitionPropertyStyle;
if(propertyStyle.indexOf('all') == -1) {
style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';';
- style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + 's;';
+ style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ';';
appliedStyles.push(CSS_PREFIX + 'transition-property');
appliedStyles.push(CSS_PREFIX + 'transition-duration');
}
diff --git a/vendor/assets/javascripts/angular-cookies.js b/vendor/assets/javascripts/angular-cookies.js
index 76d3c14..a1e5029 100644
--- a/vendor/assets/javascripts/angular-cookies.js
+++ b/vendor/assets/javascripts/angular-cookies.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
diff --git a/vendor/assets/javascripts/angular-loader.js b/vendor/assets/javascripts/angular-loader.js
index 74750ee..bea9de5 100644
--- a/vendor/assets/javascripts/angular-loader.js
+++ b/vendor/assets/javascripts/angular-loader.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -69,7 +69,7 @@ function minErr(module) {
return match;
});
- message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
+ message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
diff --git a/vendor/assets/javascripts/angular-mocks.js b/vendor/assets/javascripts/angular-mocks.js
index 8a7d750..61b2481 100644
--- a/vendor/assets/javascripts/angular-mocks.js
+++ b/vendor/assets/javascripts/angular-mocks.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -1579,6 +1579,10 @@ function MockHttpExpectation(method, url, data, headers) {
};
}
+function createMockXhr() {
+ return new MockXhr();
+}
+
function MockXhr() {
// hack for testing $http, $httpBackend
diff --git a/vendor/assets/javascripts/angular-resource.js b/vendor/assets/javascripts/angular-resource.js
index 8025a37..0194d49 100644
--- a/vendor/assets/javascripts/angular-resource.js
+++ b/vendor/assets/javascripts/angular-resource.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -406,7 +406,7 @@ angular.module('ngResource', ['ng']).
});
// strip trailing slashes and set the url
- url = url.replace(/\/+$/, '');
+ url = url.replace(/\/+$/, '') || '/';
// then replace collapse `/.` if found in the last URL path segment before the query
// E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
diff --git a/vendor/assets/javascripts/angular-route.js b/vendor/assets/javascripts/angular-route.js
index 72caca1..cffd28a 100644
--- a/vendor/assets/javascripts/angular-route.js
+++ b/vendor/assets/javascripts/angular-route.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -842,7 +842,7 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
var locals = $route.current && $route.current.locals,
template = locals && locals.$template;
- if (template) {
+ if (angular.isDefined(template)) {
var newScope = scope.$new();
var current = $route.current;
diff --git a/vendor/assets/javascripts/angular-sanitize.js b/vendor/assets/javascripts/angular-sanitize.js
index dc385ec..d9ffa1e 100644
--- a/vendor/assets/javascripts/angular-sanitize.js
+++ b/vendor/assets/javascripts/angular-sanitize.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -211,7 +211,7 @@ var validAttrs = angular.extend({}, uriAttrs, makeMap(
'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
- 'scope,scrolling,shape,span,start,summary,target,title,type,'+
+ 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
'valign,value,vspace,width'));
function makeMap(str) {
diff --git a/vendor/assets/javascripts/angular-scenario.js b/vendor/assets/javascripts/angular-scenario.js
index 9ba3169..9a44cab 100644
--- a/vendor/assets/javascripts/angular-scenario.js
+++ b/vendor/assets/javascripts/angular-scenario.js
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
})( window );
/**
- * @license AngularJS v1.2.6
+ * @license AngularJS v1.2.7
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -9860,7 +9860,7 @@ function minErr(module) {
return match;
});
- message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
+ message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -10830,7 +10830,9 @@ function fromJson(json) {
function toBoolean(value) {
- if (value && value.length !== 0) {
+ if (typeof value === 'function') {
+ value = true;
+ } else if (value && value.length !== 0) {
var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else {
@@ -11623,11 +11625,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
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
minor: 2,
- dot: 6,
- codeName: 'taco-salsafication'
+ dot: 7,
+ codeName: 'emoji-clairvoyance'
};
@@ -13455,6 +13457,11 @@ function createInjector(modulesToLoad) {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName);
+ } catch (err) {
+ if (cache[serviceName] === INSTANTIATING) {
+ delete cache[serviceName];
+ }
+ throw err;
} finally {
path.shift();
}
@@ -13989,8 +13996,9 @@ function Browser(window, document, $log, $sniffer) {
* @param {boolean=} replace Should new url replace current history record ?
*/
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 (history !== window.history) history = window.history;
// setter
if (url) {
@@ -14042,7 +14050,7 @@ function Browser(window, document, $log, $sniffer) {
* @description
* 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 clicks on history (forward/back) button
* - user clicks on a link
@@ -14084,7 +14092,7 @@ function Browser(window, document, $log, $sniffer) {
/**
* @name ng.$browser#baseHref
* @methodOf ng.$browser
- *
+ *
* @description
* Returns current
* (always relative - without domain)
@@ -14093,7 +14101,7 @@ function Browser(window, document, $log, $sniffer) {
*/
self.baseHref = function() {
var href = baseElement.attr('href');
- return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : '';
+ return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
};
//////////////////////////////////////////////////////////////
@@ -14115,13 +14123,13 @@ function Browser(window, document, $log, $sniffer) {
* 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:
- *
+ *
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it
* - 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
* way)
- *
+ *
* @returns {Object} Hash of all cookies (if called without any parameter)
*/
self.cookies = function(name, value) {
@@ -14499,7 +14507,7 @@ function $TemplateCacheProvider() {
* @function
*
* @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.
*
* The compilation is a process of walking the DOM tree and matching DOM elements to
@@ -16841,7 +16849,7 @@ function $HttpProvider() {
* will result in the success callback being called. Note that if the response is a redirect,
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
* called for such responses.
- *
+ *
* # Calling $http from outside AngularJS
* The `$http` service will not actually send the request until the next `$digest()` is
* executed. Normally this is not an issue, since almost all the time your call to `$http` will
@@ -17028,19 +17036,20 @@ function $HttpProvider() {
* return responseOrNewPromise
* }
* return $q.reject(rejection);
- * };
- * }
+ * }
+ * };
* });
*
* $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) {
* return {
* 'request': function(config) {
* // same as above
* },
+ *
* 'response': function(response) {
* // same as above
* }
@@ -17656,13 +17665,13 @@ function $HttpProvider() {
}];
}
-var XHR = window.XMLHttpRequest || function() {
+function createXhr(method) {
+ // IE8 doesn't support PATCH method, but the ActiveX object does
/* global ActiveXObject */
- try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
- throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
-};
+ return (msie <= 8 && lowercase(method) === 'patch')
+ ? new ActiveXObject('Microsoft.XMLHTTP')
+ : new window.XMLHttpRequest();
+}
/**
@@ -17684,11 +17693,11 @@ var XHR = window.XMLHttpRequest || function() {
*/
function $HttpBackendProvider() {
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;
// TODO(vojta): fix the signature
@@ -17713,7 +17722,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
delete callbacks[callbackId];
});
} else {
- var xhr = new XHR();
+
+ var xhr = createXhr(method);
+
xhr.open(method, url, true);
forEach(headers, function(value, key) {
if (isDefined(value)) {
@@ -17725,7 +17736,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
// always async
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,
response = null;
@@ -18972,16 +18990,17 @@ function $LocationProvider(){
// update $location when $browser url changes
$browser.onUrlChange(function(newUrl) {
if ($location.absUrl() != newUrl) {
- if ($rootScope.$broadcast('$locationChangeStart', newUrl,
- $location.absUrl()).defaultPrevented) {
- $browser.url($location.absUrl());
- return;
- }
$rootScope.$evalAsync(function() {
var oldUrl = $location.absUrl();
$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();
}
@@ -21091,6 +21110,7 @@ function $RootScopeProvider(){
this.$$asyncQueue = [];
this.$$postDigestQueue = [];
this.$$listeners = {};
+ this.$$listenerCount = {};
this.$$isolateBindings = {};
}
@@ -21150,6 +21170,7 @@ function $RootScopeProvider(){
}
child['this'] = child;
child.$$listeners = {};
+ child.$$listenerCount = {};
child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail;
@@ -21309,6 +21330,7 @@ function $RootScopeProvider(){
return function() {
arrayRemove(array, watcher);
+ lastDirtyWatch = null;
};
},
@@ -21654,6 +21676,8 @@ function $RootScopeProvider(){
this.$$destroyed = true;
if (this === $rootScope) return;
+ forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
+
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
@@ -21843,8 +21867,18 @@ function $RootScopeProvider(){
}
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() {
namedListeners[indexOf(namedListeners, listener)] = null;
+ decrementListenerCount(self, 1, name);
};
},
@@ -21956,8 +21990,7 @@ function $RootScopeProvider(){
listeners, i, length;
//down while you can, then up and next sibling or up and next sibling until back at root
- do {
- current = next;
+ while ((current = next)) {
event.currentScope = current;
listeners = current.$$listeners[name] || [];
for (i=0, length = listeners.length; i
* (always relative - without domain)
@@ -4301,7 +4309,7 @@ function Browser(window, document, $log, $sniffer) {
*/
self.baseHref = function() {
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) {
* 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:
- *
+ *
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it
* - 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
* way)
- *
+ *
* @returns {Object} Hash of all cookies (if called without any parameter)
*/
self.cookies = function(name, value) {
@@ -4707,7 +4715,7 @@ function $TemplateCacheProvider() {
* @function
*
* @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.
*
* The compilation is a process of walking the DOM tree and matching DOM elements to
@@ -7049,7 +7057,7 @@ function $HttpProvider() {
* will result in the success callback being called. Note that if the response is a redirect,
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
* called for such responses.
- *
+ *
* # Calling $http from outside AngularJS
* The `$http` service will not actually send the request until the next `$digest()` is
* executed. Normally this is not an issue, since almost all the time your call to `$http` will
@@ -7236,19 +7244,20 @@ function $HttpProvider() {
* return responseOrNewPromise
* }
* return $q.reject(rejection);
- * };
- * }
+ * }
+ * };
* });
*
* $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) {
* return {
* 'request': function(config) {
* // same as above
* },
+ *
* 'response': function(response) {
* // same as above
* }
@@ -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 */
- try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
- throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
-};
+ return (msie <= 8 && lowercase(method) === 'patch')
+ ? new ActiveXObject('Microsoft.XMLHTTP')
+ : new window.XMLHttpRequest();
+}
/**
@@ -7892,11 +7901,11 @@ var XHR = window.XMLHttpRequest || function() {
*/
function $HttpBackendProvider() {
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;
// TODO(vojta): fix the signature
@@ -7921,7 +7930,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
delete callbacks[callbackId];
});
} else {
- var xhr = new XHR();
+
+ var xhr = createXhr(method);
+
xhr.open(method, url, true);
forEach(headers, function(value, key) {
if (isDefined(value)) {
@@ -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
// always async
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,
response = null;
@@ -9180,16 +9198,17 @@ function $LocationProvider(){
// update $location when $browser url changes
$browser.onUrlChange(function(newUrl) {
if ($location.absUrl() != newUrl) {
- if ($rootScope.$broadcast('$locationChangeStart', newUrl,
- $location.absUrl()).defaultPrevented) {
- $browser.url($location.absUrl());
- return;
- }
$rootScope.$evalAsync(function() {
var oldUrl = $location.absUrl();
$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();
}
@@ -11299,6 +11318,7 @@ function $RootScopeProvider(){
this.$$asyncQueue = [];
this.$$postDigestQueue = [];
this.$$listeners = {};
+ this.$$listenerCount = {};
this.$$isolateBindings = {};
}
@@ -11358,6 +11378,7 @@ function $RootScopeProvider(){
}
child['this'] = child;
child.$$listeners = {};
+ child.$$listenerCount = {};
child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail;
@@ -11517,6 +11538,7 @@ function $RootScopeProvider(){
return function() {
arrayRemove(array, watcher);
+ lastDirtyWatch = null;
};
},
@@ -11862,6 +11884,8 @@ function $RootScopeProvider(){
this.$$destroyed = true;
if (this === $rootScope) return;
+ forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
+
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
@@ -12051,8 +12075,18 @@ function $RootScopeProvider(){
}
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() {
namedListeners[indexOf(namedListeners, listener)] = null;
+ decrementListenerCount(self, 1, name);
};
},
@@ -12164,8 +12198,7 @@ function $RootScopeProvider(){
listeners, i, length;
//down while you can, then up and next sibling or up and next sibling until back at root
- do {
- current = next;
+ while ((current = next)) {
event.currentScope = current;
listeners = current.$$listeners[name] || [];
for (i=0, length = listeners.length; i