diff options
| author | Igor Minar | 2010-10-12 05:36:38 +0800 | 
|---|---|---|
| committer | Misko Hevery | 2010-10-13 04:37:46 +0800 | 
| commit | 70ff7a2639fc55936854ad04a6242a700ae71a02 (patch) | |
| tree | be82632c890b9734d50cd681737b6bad9a689d91 /src | |
| parent | 7e47a2d016676f37287203f26689cce1ee1eaa0c (diff) | |
| download | angular.js-70ff7a2639fc55936854ad04a6242a700ae71a02.tar.bz2 | |
fix memory leak caused by leftbehind $invalidWidgets references
- ng:switch should not clean up $invalidWidgets
- $invalidWidgets should be clean up after each eval
- add missing docs
Diffstat (limited to 'src')
| -rw-r--r-- | src/services.js | 33 | ||||
| -rw-r--r-- | src/widgets.js | 2 | 
2 files changed, 30 insertions, 5 deletions
diff --git a/src/services.js b/src/services.js index 41755962..be73c6e9 100644 --- a/src/services.js +++ b/src/services.js @@ -157,18 +157,32 @@ angularService("$hover", function(browser, document) {    });  }, {inject:['$browser', '$document']}); + + +/* Keeps references to all invalid widgets found during validation. Can be queried to find if there + * are invalid widgets currently displayed + */  angularService("$invalidWidgets", function(){    var invalidWidgets = []; + + +  /** Remove an element from the array of invalid widgets */    invalidWidgets.markValid = function(element){      var index = indexOf(invalidWidgets, element);      if (index != -1)        invalidWidgets.splice(index, 1);    }; + + +  /** Add an element to the array of invalid widgets */    invalidWidgets.markInvalid = function(element){      var index = indexOf(invalidWidgets, element);      if (index === -1)        invalidWidgets.push(element);    }; + + +  /** Return count of all invalid widgets that are currently visible */    invalidWidgets.visible = function() {      var count = 0;      foreach(invalidWidgets, function(widget){ @@ -176,24 +190,37 @@ angularService("$invalidWidgets", function(){      });      return count;    }; -  invalidWidgets.clearOrphans = function() { + + +  /* At the end of each eval removes all invalid widgets that are not part of the current DOM. */ +  this.$onEval(PRIORITY_LAST, function() {      for(var i = 0; i < invalidWidgets.length;) {        var widget = invalidWidgets[i];        if (isOrphan(widget[0])) { -        invalidWidgets.splice(i, 1); +        invalidWidgets.splice(i, 1) +        if (widget.dealoc) widget.dealoc();        } else {          i++;        }      } -  }; +  }); + + +  /** +   * Traverses DOM element's (widget's) parents and considers the element to be an orphant if one of +   * it's parents isn't the current window.document. +   */    function isOrphan(widget) {      if (widget == window.document) return false;      var parent = widget.parentNode;      return !parent || isOrphan(parent);    } +    return invalidWidgets;  }); + +  function switchRouteMatcher(on, when, dstName) {    var regex = '^' + when.replace(/[\.\\\(\)\^\$]/g, "\$1") + '$',        params = [], diff --git a/src/widgets.js b/src/widgets.js index 127718ce..c1342943 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -324,8 +324,6 @@ var ngSwitch = angularWidget('ng:switch', function (element){            element.append(caseElement);            childScope.$tryEval(switchCase.change, element);            switchCase.template(caseElement, childScope); -          if (scope.$invalidWidgets) -            scope.$invalidWidgets.clearOrphans();            childScope.$init();          }        });  | 
