Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
fix(mdUtil): remove/delete cacheFactory keys when clearing/destroying…
Browse files Browse the repository at this point in the history
… cache

`mdUtil`'s custom `cacheFactory` factory, adds/removes keys when
putting/removing a single key, but leaves `keys` untouched when calling
`removeAll()` or `destroy()`. As a result, the following problems arise:

- Keys of destroyed caches continue to take up memory.
- The `keys()` method return incorrect results after calling `removeAll()`
  (i.e. it continues to return the old keys, although they are not present
  in the cache any more).

This commit fixes these issues, by overriding the `removeAll` and
`destroy` methods as well.
  • Loading branch information
gkalpak authored and ThomasBurleson committed Dec 24, 2014
1 parent bc8706a commit 8736c7c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 31 deletions.
63 changes: 33 additions & 30 deletions src/core/util/media.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
angular.module('material.core')
.factory('$mdMedia', mdMediaFactory);
.factory('$mdMedia', mdMediaFactory);

/**
* Exposes a function on the '$mdMedia' service which will return true or false,
Expand All @@ -11,41 +11,44 @@ angular.module('material.core')
* @example $mdMedia('max-width: 300px') == true if device-width <= 300px (sanitizes input, adding parens)
*/
function mdMediaFactory($window, $mdUtil, $timeout, $mdConstant) {
var cache = $mdUtil.cacheFactory('$mdMedia', { capacity: 15 });
var queriesCache = $mdUtil.cacheFactory('$mdMedia:queries', {capacity: 15});
var resultsCache = $mdUtil.cacheFactory('$mdMedia:results', {capacity: 15});

angular.element($window).on('resize', updateAll);
angular.element($window).on('resize', updateAll);

return $mdMedia;
return $mdMedia;

function $mdMedia(query) {
query = validate(query);
var result;
if (!angular.isDefined(result = cache.get(query)) ) {
return add(query);
}
return result;
function $mdMedia(query) {
var validated = queriesCache.get(query);
if (angular.isUndefined(validated)) {
validated = queriesCache.put(query, validate(query));
}

function validate(query) {
return $mdConstant.MEDIA[query] || (
query.charAt(0) != '(' ? ('(' + query + ')') : query
);
var result = resultsCache.get(validated);
if (angular.isUndefined(result)) {
result = add(validated);
}

function add(query) {
return cache.put(query, !!$window.matchMedia(query).matches);

}

function updateAll() {
var keys = cache.keys();
if (keys.length) {
for (var i = 0, ii = keys.length; i < ii; i++) {
cache.put(keys[i], !!$window.matchMedia(keys[i]).matches);
}
// trigger a $digest()
$timeout(angular.noop);
}
return result;
}

function validate(query) {
return $mdConstant.MEDIA[query] ||
((query.charAt(0) !== '(') ? ('(' + query + ')') : query);
}

function add(query) {
return resultsCache.put(query, !!$window.matchMedia(query).matches);
}

function updateAll() {
var keys = cache.keys();
if (keys.length) {
for (var i = 0, ii = keys.length; i < ii; i++) {
cache.put(keys[i], !!$window.matchMedia(keys[i]).matches);
}
// trigger a $digest()
$timeout(angular.noop);
}

}
}
15 changes: 14 additions & 1 deletion src/core/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,19 +266,32 @@ angular.module('material.core')
*/
function cacheFactory(id, options) {
var cache = $cacheFactory(id, options);

var keys = {};

cache._put = cache.put;
cache.put = function(k,v) {
keys[k] = true;
return cache._put(k, v);
};

cache._remove = cache.remove;
cache.remove = function(k) {
delete keys[k];
return cache._remove(k);
};

cache._removeAll = cache.removeAll;
cache.removeAll = function() {
keys = {};
return cache._removeAll();
};

cache._destroy = cache.destroy;
cache.destroy = function() {
keys = null;
return cache._destroy();
};

cache.keys = function() {
return Object.keys(keys);
};
Expand Down

0 comments on commit 8736c7c

Please sign in to comment.