diff options
Diffstat (limited to 'src/js/contentscript-extra.js')
-rw-r--r-- | src/js/contentscript-extra.js | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/src/js/contentscript-extra.js b/src/js/contentscript-extra.js index 45c5262..34b0ef0 100644 --- a/src/js/contentscript-extra.js +++ b/src/js/contentscript-extra.js @@ -30,6 +30,9 @@ if ( /******************************************************************************/ const nonVisualElements = { + head: true, + link: true, + meta: true, script: true, style: true, }; @@ -196,28 +199,27 @@ class PSelectorOthersTask extends PSelectorTask { const toKeep = new Set(this.targets); const toDiscard = new Set(); const body = document.body; + const head = document.head; let discard = null; for ( let keep of this.targets ) { - while ( keep !== null && keep !== body ) { + while ( keep !== null && keep !== body && keep !== head ) { toKeep.add(keep); toDiscard.delete(keep); discard = keep.previousElementSibling; while ( discard !== null ) { - if ( - nonVisualElements[discard.localName] !== true && - toKeep.has(discard) === false - ) { - toDiscard.add(discard); + if ( nonVisualElements[discard.localName] !== true ) { + if ( toKeep.has(discard) === false ) { + toDiscard.add(discard); + } } discard = discard.previousElementSibling; } discard = keep.nextElementSibling; while ( discard !== null ) { - if ( - nonVisualElements[discard.localName] !== true && - toKeep.has(discard) === false - ) { - toDiscard.add(discard); + if ( nonVisualElements[discard.localName] !== true ) { + if ( toKeep.has(discard) === false ) { + toDiscard.add(discard); + } } discard = discard.nextElementSibling; } @@ -240,6 +242,36 @@ class PSelectorOthersTask extends PSelectorTask { } } +class PSelectorShadowTask extends PSelectorTask { + constructor(task) { + super(); + this.selector = task[1]; + } + transpose(node, output) { + const root = this.openOrClosedShadowRoot(node); + if ( root === null ) { return; } + const nodes = root.querySelectorAll(this.selector); + output.push(...nodes); + } + get openOrClosedShadowRoot() { + if ( PSelectorShadowTask.openOrClosedShadowRoot !== undefined ) { + return PSelectorShadowTask.openOrClosedShadowRoot; + } + if ( typeof chrome === 'object' && chrome !== null ) { + if ( chrome.dom instanceof Object ) { + if ( typeof chrome.dom.openOrClosedShadowRoot === 'function' ) { + PSelectorShadowTask.openOrClosedShadowRoot = + chrome.dom.openOrClosedShadowRoot; + return PSelectorShadowTask.openOrClosedShadowRoot; + } + } + } + PSelectorShadowTask.openOrClosedShadowRoot = node => + node.openOrClosedShadowRoot || null; + return PSelectorShadowTask.openOrClosedShadowRoot; + } +} + // https://github.com/AdguardTeam/ExtendedCss/issues/31#issuecomment-302391277 // Prepend `:scope ` if needed. class PSelectorSpathTask extends PSelectorTask { @@ -364,7 +396,6 @@ class PSelectorXpathTask extends PSelectorTask { class PSelector { constructor(o) { - this.raw = o.raw; this.selector = o.selector; this.tasks = []; const tasks = []; @@ -435,6 +466,7 @@ PSelector.prototype.operatorToTaskMap = new Map([ [ 'min-text-length', PSelectorMinTextLengthTask ], [ 'not', PSelectorIfNotTask ], [ 'others', PSelectorOthersTask ], + [ 'shadow', PSelectorShadowTask ], [ 'spath', PSelectorSpathTask ], [ 'upward', PSelectorUpwardTask ], [ 'watch-attr', PSelectorWatchAttrs ], |