I've implemented this:
forum/viewtopic.php?f=11&t=9660
And as a beginner of Javascript, there must be something you will need to change, but at least it's does the job, quite simple and almost no running performance lost ( I don't have the data, it will take some more time to initialize and maybe a litte more memory for it hold more object)
The idea is for every Element Hiding Rule, we cache a object index only by it CSS selector. When ABP start initialization, everytime it meets an Element Hiding Rule, looks for other processed Hiding rule has the same selector, and marked them all the exclude domain.
new HidingRule(text, domain, selector) --> ProcessedHidingRule[selector] ---> for each "text" in ProcessedHidingRule[selector]
--->Refresh Filter.knownFilters[text] exception domains.
Bug:( because I just learn JS a while and don't comprehend a lot parts of ABP,I think all this can be fixed )
1. it don't take enabled/disabled into account yet
2. now is always a rule behind because when update, the processing text is not converted into knownFilter yet. This could resolve by change the timing
Code: Select all
Filter.SelectorFilter(text, domain, selector);
run
The following are all modified in very end of "\modules\FilterClasses.jsm"
Code: Select all
ElemHideFilter.fromText = function(text, domain, tagName, attrRules, selector)
{
/*...........
...........*/
Filter.SelectorFilter(text, domain, selector);
// Add this line, the insert point would be optimized,
// now it can't change the up comming filter of this text,
// because it not exist yet.
return new ElemHideFilter(text, domain, selector);
}
/**
*
*add a type knownSelectorFilter
* and sync the rule with same enable and disable
* and this object is a little different from knownFilters, for it's
* index by selector, like
* knownSelectorFilter[selector] = [domain1[, domain2] ]
* @type OBJECT
*/
Filter.knownSelectorFilter = {
__proto__: null
};
Filter.SelectorFilter = function(text, domains, selector) {
let CSSArray = Filter.knownSelectorFilter;
/*
* initialize the selector index
*/
if (!(selector in CSSArray))
{
CSSArray[selector] = {__proto__: null };
CSSArray[selector].exceptionDomain = [];
CSSArray[selector].textArray = []
}
// keep all exception domains in CSSArray[selector].exceptionDomain
// this should take into account of the rules enabled or not, though I didn't finish it.
let domains = domains.split(',');
for (let i = 0; i < domains.length; i++)
{
let domain = domains[i].toUpperCase();
if (domain[0] == '~' && CSSArray[selector].exceptionDomain.indexOf(domain) == -1)
{
CSSArray[selector].exceptionDomain.push(domain);
}
}
// update existed rules share the same selector
let extra = CSSArray[selector].exceptionDomain;
let textArray = CSSArray[selector].textArray;
for (let i = 0; i < textArray.length; i++)
{
let text = textArray[i];
for (let j = 0; j < extra.length; j++)
{
domain = extra[j].substr(1);
if (!Filter.knownFilters[text].domains)
{
Filter.knownFilters[text].domains = {__proto__: null};
}
Filter.knownFilters[text].domains[domain] = false;
}
Filter.knownFilters[text].domains[""] = true;
}
// end update
// add text to update list
// if the insert point is after this text filter create,
// should push before update the existed rules
CSSArray[selector].textArray.push(text);
}
Really useful for maintainer of list as supplement of other list. ( like all those local list work with easylist, much better resort compare to @@URL$elemhide in most case)