Adding support for AdGuard pseudo-classes · uBlock-LLC/uBlock@b1944e4 · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content
This repository was archived by the owner on Sep 9, 2022. It is now read-only.

Commit b1944e4

Browse files
committed
Adding support for AdGuard pseudo-classes
- Added support for following AdGuard pseudo-classes :matches-css() :matches-css-before :matches-css-after - Removed obsolete filter list / Updated filter list links / Added new filter list / Changed location of filter list - Fixed issues to make uBlock compatible with Chrome 49 - Doing parsing and validation of Extended CSS at the time of filter list data processing. It saves time when actually applying extended CSS
1 parent f03bb5b commit b1944e4

File tree

8 files changed

+257
-117
lines changed

8 files changed

+257
-117
lines changed

platform/chromium/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifest_version": 2,
33

44
"name": "uBlock",
5-
"version": "0.9.5.20",
5+
"version": "0.9.5.21",
66

77
"default_locale": "en",
88
"description": "__MSG_extShortDesc__",

src/background.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<title>uBlock</title>
66
</head>
77
<body>
8+
<script src="js/polyfill.js"></script>
89
<script src="lib/punycode.js"></script>
910
<script src="lib/publicsuffixlist.js"></script>
1011
<script src="lib/yamd5.js"></script>

src/js/background.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ return {
9191

9292
// read-only
9393
systemSettings: {
94-
compiledMagic: 'wertpszukpsrere',
95-
selfieMagic: 'werthiasrsrere'
94+
compiledMagic: 'wertpszukpslklk',
95+
selfieMagic: 'werthiasrslklk'
9696
},
9797
restoreBackupSettings: {
9898
lastRestoreFile: '',

src/js/contentscript-end.js

Lines changed: 92 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,24 @@ vAPI.proceduralCosmeticFiltering = (function() {
139139

140140
if (selector[0] == ">") {
141141
selector = ":scope" + selector;
142-
143-
if (scopeSupported) {
144-
return all ? subtree.querySelectorAll(selector) :
145-
subtree.querySelector(selector);
142+
if (scopeSupported) {
143+
try {
144+
return all ? subtree.querySelectorAll(selector) :
145+
subtree.querySelector(selector);
146+
} catch(e) {
147+
return null;
148+
}
149+
}
150+
if (scopeSupported == null)
151+
return tryQuerySelector(subtree, selector, all);
152+
return null;
153+
}
154+
try {
155+
return all ? subtree.querySelectorAll(selector) :
156+
subtree.querySelector(selector);
157+
} catch(e) {
158+
return null;
146159
}
147-
if (scopeSupported == null)
148-
return tryQuerySelector(subtree, selector, all);
149-
return null;
150-
}
151-
return all ? subtree.querySelectorAll(selector) :
152-
subtree.querySelector(selector);
153160
}
154161
/* Scriptlet below borrowed from: https://github.com/adblockplus/adblockpluscore/blob/3e16d3602509b2dbb2238ab1ebcbc5e5b5993862/lib/common.js#L40 */
155162
function filterToRegExp(text, captureAll = false) {
@@ -276,7 +283,13 @@ vAPI.proceduralCosmeticFiltering = (function() {
276283
if (typeof styleFilter === 'undefined') {
277284
continue;
278285
}
279-
selectors.push(styleFilter[filter]);
286+
if(styleFilter.hasOwnProperty(filter)) {
287+
if(Array.isArray(styleFilter[filter])) {
288+
selectors.push(...styleFilter[filter]);
289+
} else {
290+
selectors.push(styleFilter[filter]);
291+
}
292+
}
280293
}
281294
return selectors;
282295
};
@@ -352,10 +365,10 @@ vAPI.proceduralCosmeticFiltering = (function() {
352365
}
353366
return combineSelectors;
354367
}
355-
var hasSelector = function(hasSelector, prefix) {
368+
var hasSelector = function(hasSelector, prefix, hasParallelSiblingSelector = false) {
356369
this.prefix = prefix;
357370
this._innerSelectors = hasSelector;
358-
this.hasParallelSiblingSelector = false;
371+
this.hasParallelSiblingSelector = hasParallelSiblingSelector;
359372
this.dependsOnDOM = true;
360373
}
361374
hasSelector.prototype = {
@@ -373,6 +386,7 @@ vAPI.proceduralCosmeticFiltering = (function() {
373386
},
374387
getSelectors: function(rootnode, selectors, targets) {
375388
var nodes = prime(rootnode,this.prefix);
389+
if(nodes == null) return;
376390
var matchSelector = [];
377391
var lastRoot = null;
378392
for ( var node of nodes ) {
@@ -401,10 +415,10 @@ vAPI.proceduralCosmeticFiltering = (function() {
401415
return;
402416
}
403417
}
404-
var containSelector = function(selectorText, prefix) {
418+
var containSelector = function(selectorText, prefix, hasParallelSiblingSelector = false) {
405419
this.prefix = prefix;
406420
this._regexp = makeRegExpParameter(selectorText);
407-
this.hasParallelSiblingSelector = false;
421+
this.hasParallelSiblingSelector = hasParallelSiblingSelector;
408422
this.dependsOnCharacterData = true;
409423
this.dependsOnDOM = true;
410424
}
@@ -413,6 +427,7 @@ vAPI.proceduralCosmeticFiltering = (function() {
413427
var matchSelector = [];
414428
let lastRoot = null;
415429
var nodes = prime(rootnode, this.prefix);
430+
if(nodes == null) return;
416431
for ( var node of nodes ) {
417432
if (lastRoot && lastRoot.contains(node) && !this.hasParallelSiblingSelector){
418433
continue;
@@ -431,6 +446,29 @@ vAPI.proceduralCosmeticFiltering = (function() {
431446
return;
432447
}
433448
}
449+
var matchCSSSelector = function(selectorText, prefix, temp , pseudoClass) {
450+
this.prefix = prefix;
451+
this.pseudoClass = pseudoClass;
452+
let matches = /([^:]+):(.*)/g.exec(selectorText);
453+
this.propertName = matches[1];
454+
this._regexp = makeRegExpParameter(matches[2].trim());
455+
}
456+
matchCSSSelector.prototype = {
457+
getSelectors: function(rootnode, selectors) {
458+
var matchSelector = [];
459+
var nodes = prime(rootnode, this.prefix);
460+
if(nodes == null) return;
461+
for ( var node of nodes ) {
462+
const style = window.getComputedStyle(node, this.pseudoClass);
463+
if ( style !== null && this._regexp && this._regexp.test(style[this.propertName])) {
464+
matchSelector.push(makeSelector(node));
465+
}
466+
}
467+
if(matchSelector.length > 0)
468+
selectors.set('contains',matchSelector);
469+
return;
470+
}
471+
}
434472
var plainSelector = function(selectorText) {
435473
this.selector = selectorText;
436474
this.maybeContainsSiblingCombinators = /[~+]/.test(selectorText);
@@ -443,10 +481,10 @@ vAPI.proceduralCosmeticFiltering = (function() {
443481
return;
444482
}
445483
}
446-
var propsSelector = function(propertyExpression, prefix) {
484+
var propsSelector = function(propertyExpression, prefix, hasParallelSiblingSelector = false) {
447485
this.prefix = prefix;
448486
this.propertyExpression = propertyExpression;
449-
this.hasParallelSiblingSelector = false;
487+
this.hasParallelSiblingSelector = hasParallelSiblingSelector;
450488
this.dependsOnStyles = true;
451489
this.dependsOnDOM = true;
452490
styleObserver.registerStyleFilter(propertyExpression);
@@ -455,6 +493,7 @@ vAPI.proceduralCosmeticFiltering = (function() {
455493
getSelectors: function(rootnode, selectors, targets) {
456494
var matchSelector = [];
457495
var nodes = prime(rootnode, this.prefix);
496+
if(nodes == null) return;
458497
var styleSelectors = styleObserver.getSelector(this.propertyExpression);
459498
if (styleSelectors.length === 0)
460499
return;
@@ -478,80 +517,53 @@ vAPI.proceduralCosmeticFiltering = (function() {
478517
}
479518
}
480519
var proceduralSelector = function() {
481-
this.operatorMap = new Map([['has', hasSelector], ['contains', containSelector], ['properties', propsSelector]]);
520+
this.operatorMap = new Map([['plain', plainSelector],['-abp-has', hasSelector],['has', hasSelector], ['-abp-contains', containSelector],['contains', containSelector], ['matches-css', matchCSSSelector], ['matches-css-after', matchCSSSelector], ['matches-css-before', matchCSSSelector], ['-abp-properties', propsSelector]]);
482521
this.patterns = [];
483522
}
484523
proceduralSelector.prototype = {
485-
parseProcedure : function(expression, prefix = "") {
524+
buildFunction(s) {
486525
let tasks = [];
487-
let matches = abpSelectorRegexp.exec(expression);
488-
if(!matches) {
489-
return [new plainSelector(expression)];
490-
}
491-
var prefix = expression.substring(0,matches.index);
492-
let remaining = expression.substring(matches.index + matches[0].length);
493-
let parsed = this.parseContent(remaining,0);
494-
let selectorText = parsed.text;
495-
if(matches[1] == "properties") {
496-
tasks.push(new (this.operatorMap.get(matches[1]))(selectorText,prefix));
497-
}
498-
else if(matches[1] == "has") {
499-
let procSelector = this.parseProcedure(selectorText, prefix);
500-
tasks.push(new (this.operatorMap.get(matches[1]))(procSelector,prefix));
501-
}
502-
else if(matches[1] == "contains") {
503-
tasks.push(new (this.operatorMap.get(matches[1]))(selectorText,prefix));
504-
}
505-
else {
506-
console.error(new SyntaxError("Failed to parse uBlock."));
507-
return null;
508-
}
509-
let suffixtext = remaining.substring(parsed.end + 1);
510-
if (suffixtext != "") {
511-
let suffix = this.parseProcedure(suffixtext);
512-
if(suffix.length == 1 && suffix[0] instanceof plainSelector && suffix[0].maybeContainsSiblingCombinators) {
513-
for (let task of tasks) {
514-
if(task instanceof hasSelector || task instanceof containSelector || task instanceof proceduralSelector) {
515-
task.hasParallelSiblingSelector = true;
516-
}
526+
let selectorText = "";
527+
for (var property in s) {
528+
let cls = new (this.operatorMap.get(property))(s[property].st, s[property].pf, s[property].pss, s[property].ps);
529+
if(property == "plain") {
530+
tasks.push(cls);
531+
selectorText += s[property].st;
532+
return [tasks, selectorText];
533+
}
534+
selectorText += s[property].pf + ':' + property + '(';
535+
let inner = s[property]._is
536+
if(inner) {
537+
cls["_innerSelectors"] = [];
538+
for(let i = 0; i < inner.length; i++) {
539+
let [innerTasks, innerSelectorText] = this.buildFunction(inner[i]);
540+
selectorText += innerSelectorText;
541+
cls["_innerSelectors"].push(...innerTasks);
517542
}
543+
} else {
544+
selectorText += s[property].st;
518545
}
519-
tasks.push(...suffix);
546+
selectorText += ")";
547+
tasks.push(cls);
520548
}
521-
return tasks;
549+
return [tasks, selectorText];
522550
},
523-
parseContent: function(content, startIndex) {
524-
let parens = 1;
525-
let quote = null;
526-
let i = startIndex;
527-
for (; i < content.length; i++) {
528-
let c = content[i];
529-
if (c == "\\") {
530-
i++;
531-
}
532-
else if (quote) {
533-
if (c == quote)
534-
quote = null;
535-
}
536-
else if (c == "'" || c == '"')
537-
quote = c;
538-
else if (c == "(")
539-
parens++;
540-
else if (c == ")") {
541-
parens--;
542-
if (parens == 0)
543-
break;
544-
}
551+
decompile(s) {
552+
let ss = JSON.parse(s);
553+
let tasks = [];
554+
let selectorText = "";
555+
for(let i = 0; i < ss.length; i++) {
556+
let [innerTasks, innerSelectorText] = this.buildFunction(ss[i]);
557+
tasks.push(...innerTasks);
558+
selectorText += innerSelectorText;
545559
}
546-
if (parens > 0)
547-
return null;
548-
return {text: content.substring(startIndex, i), end: i};
549-
},
560+
return [tasks, selectorText];
561+
},
550562
applyPatterns: function(patterns) {
551563
this.patterns = [];
552564
for (let selector of patterns) {
553-
var tasks = this.parseProcedure(selector,"");
554-
this.patterns.push([selector, tasks]);
565+
let [tasks, selectorText] = this.decompile(selector);
566+
this.patterns.push([selectorText, tasks]);
555567
}
556568
if(this.patterns.length > 0) {
557569
this.processPattern();
@@ -571,7 +583,7 @@ vAPI.proceduralCosmeticFiltering = (function() {
571583
styleObserver.readStyleSheet(stylesheet);
572584
}
573585

574-
var matchSelector = [];
586+
var matchSelector = [];
575587
var matchProcSelector = [];
576588
let mutationTargets = this.extractMutationTargets(mutations);
577589
var mutations = mutations;
@@ -686,24 +698,6 @@ vAPI.proceduralCosmeticFiltering = (function() {
686698
//this.processPattern([stylesheet]);
687699
objQueueProcessing.add([stylesheet]);
688700
}
689-
/*var hideElements = function(selectors) {
690-
// https://github.com/uBlockAdmin/uBlock/issues/207
691-
// Do not call querySelectorAll() using invalid CSS selectors
692-
if ( selectors.length === 0 ) {
693-
return;
694-
}
695-
if ( document.body === null ) {
696-
return;
697-
}
698-
// https://github.com/uBlockAdmin/uBlock/issues/158
699-
// Using CSSStyleDeclaration.setProperty is more reliable
700-
var elems = document.querySelectorAll(selectors);
701-
var i = elems.length;
702-
while ( i-- ) {
703-
elems[i].style.setProperty('display', 'none', 'important');
704-
}
705-
messager.send({ what: 'cosmeticFiltersActivated' });
706-
};*/
707701
return new proceduralSelector();
708702
})();
709703

0 commit comments

Comments
 (0)

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.