Refining element hiding rules

Posting here is no longer possible, please use the corresponding product forum.
Locked
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

Refining element hiding rules

Post by dindog »

Local list like Chinalist, which serves as a supplement of Easylist, maintainer sometime encounter problem about hiding rule like this:

Say there is a hiding rule in EasyList:

Code: Select all

 ~a.com###ad
Then there is a local site( http://www.b.com ) which #ad should not be hided, we could not add rule like:

Code: Select all

 ~b.com###ad
because the EasyList will override it anyway, only two options we get:

1. contact to Easylist to update, but this is non-sense to ask a English oriented blocking list update for a non-English site...
2. we add

Code: Select all

@@||b.com$elemhide
, but the disadvantage is apparent. We can't hide anything.

Is is possible to merge rule like ~a.com###ad and ~b.com###ad to single rule or some other sorts to make the above case work?
Ares2
Posts: 1275
Joined: Fri Feb 15, 2008 12:47 pm

Re: [Feature Req] Hiding Rule refine

Post by Ares2 »

Semi-OT: In the specific case of EasyList, it's really no problem to just tell us so we can adjust the rule (or eventually remove if it if the issue is more widespread).
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

Re: [Feature Req] Hiding Rule refine

Post by dindog »

Ares2 wrote:Semi-OT: In the specific case of EasyList, it's really no problem to just tell us so we can adjust the rule (or eventually remove if it if the issue is more widespread).
That is kind, but if ABP can auto merge hiding rule like that would be the best resort.

Besides, I think it's technically possible to merge hiding rule, and since ABP cache the css in a file anyway, it only happen every time a rule is added or delete, subscription update, no running performance lost if I understand right.
Ares2
Posts: 1275
Joined: Fri Feb 15, 2008 12:47 pm

Re: [Feature Req] Hiding Rule refine

Post by Ares2 »

It would indeed be useful, but I remember (can't find the topic now) that something like this has been brought up before without being implemented, so maybe there was a problem doing it.

Anyway, moved to "Bug reports", let's see what Wladimir says.
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

Re: Hiding Rule refine

Post by dindog »

I have a quick look at the source of ElemHide.jsm and FilterClasses.jsm, a rule like ~abc.com###ad will turn into #ad and write to elemhide.css, where does it deal with exception hiding rule? ( I know, silly question from a js beginner...) :lol:
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

A patch of ElemHiding Rule

Post by dindog »

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)
Last edited by dindog on Thu Mar 15, 2012 11:06 am, edited 4 times in total.
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

Re: A patch of ElemHiding Rule

Post by dindog »

Image
Wladimir Palant

Re: Hiding Rule refine

Post by Wladimir Palant »

The same thing was proposed by the RuAdList author a while ago - not quite "merging" the rules but rather a special "whitelisting" rule. This is a suboptimal solution because an element hiding rule can be written in many different ways, it can be ###ad or ##div#ad or ##[id="ad"] or ##[id*="ad"]. You would be relying on EasyList not changing this rule (or better - using a script to check regularly that it didn't change). But given that there doesn't seem to be a better option maybe it should be implemented.

@dindog: Unfortunately, you cannot have :not(domain(site.com)) in the CSS file. So technically, in your case Adblock Plus will still deal with #ad on site.com, despite the exception. But HitRegistrationChannel in ElemHide.jsm will return a different XBL binding in this case, one that doesn't have any effect. This is probably the largest hack in the Adblock Plus code, I would be happy to get rid of it if somehow possible.
dindog
Posts: 14
Joined: Sun Dec 12, 2010 7:07 pm

Re: Hiding Rule refine

Post by dindog »

Wladimir Palant wrote:The same thing was proposed by the RuAdList author a while ago - not quite "merging" the rules but rather a special "whitelisting" rule. This is a suboptimal solution because an element hiding rule can be written in many different ways, it can be ###ad or ##div#ad or ##[id="ad"] or ##[id*="ad"]. You would be relying on EasyList not changing this rule (or better - using a script to check regularly that it didn't change). But given that there doesn't seem to be a better option maybe it should be implemented.
You're right. Though I think this is a affordable effort (in point of view of a rule committee, maybe not the case to ABP developer :wink: . ) if no better solution in foreseeable future, to check rule like this regularly, that won't be much: Most of the current $elemhide rules are written because of this issue, and we check them necessity every a while anyway.
Locked