| Index: lib/matcher.js |
| =================================================================== |
| --- a/lib/matcher.js |
| +++ b/lib/matcher.js |
| @@ -105,35 +105,45 @@ |
| } |
| } |
| /** |
| * Removes a filter by a given keyword from a map. |
| * @param {RegExpFilter} filter |
| * @param {string} keyword |
| * @param {Map.<string,(RegExpFilter|Set.<RegExpFilter>)>} map |
| + * @returns {boolean} Whether the filter was removed. |
| */ |
| function removeFilterByKeyword(filter, keyword, map) |
| { |
| let set = map.get(keyword); |
| if (typeof set == "undefined") |
| - return; |
| + return false; |
| if (set.size == 1) |
| { |
| - if (filter == set) |
| - map.delete(keyword); |
| + if (filter != set) |
| + return false; |
| + |
| + map.delete(keyword); |
| } |
| else |
| { |
| + let count = set.size; |
| + |
| set.delete(filter); |
| + if (set.size == count) |
| + return false; |
| + |
| if (set.size == 1) |
| map.set(keyword, [...set][0]); |
| } |
| + |
| + return true; |
| } |
| /** |
| * Checks whether a particular filter is slow. |
| * @param {RegExpFilter} filter |
| * @returns {boolean} |
| */ |
| function isSlowFilter(filter) |
| @@ -211,24 +221,50 @@ |
| } |
| /** |
| * Removes a filter from the matcher |
| * @param {RegExpFilter} filter |
| */ |
| remove(filter) |
| { |
| - let keyword = this.findKeyword(filter); |
| + let keyword = null; |
| + let candidates = null; |
| + |
| + let {pattern} = filter; |
| + if (pattern == null) |
| + { |
| + candidates = [""]; |
| + } |
| + else |
| + { |
| + candidates = pattern.toLowerCase().match(allKeywordsRegExp); |
| + if (!candidates) |
| + candidates = [""]; |
| + } |
| + |
| let locationOnly = filter.isLocationOnly(); |
| - removeFilterByKeyword(filter, keyword, |
| - locationOnly ? this._simpleFiltersByKeyword : |
| - this._complexFiltersByKeyword); |
| + // The keyword used to add a filter depends on the current list of filters |
| + // at the time of addition. At this point we don't know what keyword was |
| + // used to add the filter. We must try all the candidates. |
| + for (let candidate of candidates) |
| + { |
| + candidate = candidate.substring(1); |
| - if (locationOnly) |
| + if (removeFilterByKeyword(filter, candidate, |
| + locationOnly ? this._simpleFiltersByKeyword : |
| + this._complexFiltersByKeyword)) |
| + { |
| + keyword = candidate; |
| + break; |
| + } |
| + } |
| + |
| + if (locationOnly || keyword == null) |
| return; |
| for (let type of nonDefaultTypes(filter.contentType)) |
| { |
| let map = this._filterMapsByType.get(type); |
| if (map) |
| removeFilterByKeyword(filter, keyword, map); |
| } |