Skip to content

Commit

Permalink
Cosmetic filtering content script: fix mutation handler attribute mod…
Browse files Browse the repository at this point in the history
…ification and add stronger types
  • Loading branch information
petemill committed Feb 4, 2020
1 parent 14ff077 commit d2675a1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ let notYetQueriedIds: string[] = []

let backgroundReady: boolean = false

function isElement (node: Node): boolean {
return (node.nodeType === 1)
}

function asElement (node: Node): Element | null {
return isElement(node) ? node as Element : null
}

function isHTMLElement (node: Node): boolean {
return ('innerText' in node)
}

function asHTMLElement (node: Node): HTMLElement | null {
return isHTMLElement(node) ? node as HTMLElement : null
}

const fetchNewClassIdRules = function () {
// Only let the backend know that we've found new classes and id attributes
// if the back end has told us its ready to go and we have at least one new
Expand All @@ -37,12 +53,12 @@ const fetchNewClassIdRules = function () {
}
}

const handleMutations = function (mutations: any[]) {
const handleMutations: MutationCallback = function (mutations: MutationRecord[]) {
for (const aMutation of mutations) {
if (aMutation.type === 'attribute') {
if (aMutation.type === 'attributes') {
// Since we're filtering for attribute modifications, we can be certain
// that the targets are always HTMLElements, and never TextNode.
const changedElm = aMutation.target
const changedElm = aMutation.target as Element
switch (aMutation.attributeName) {
case 'class':
for (const aClassName of changedElm.classList.values()) {
Expand All @@ -62,13 +78,17 @@ const handleMutations = function (mutations: any[]) {
break
}
} else if (aMutation.addedNodes.length > 0) {
for (const element of aMutation.addedNodes) {
for (const node of aMutation.addedNodes) {
const element = asElement(node)
if (!element) {
continue
}
const id = element.id
if (id && !queriedIds.has(id)) {
notYetQueriedIds.push(id)
queriedIds.add(id)
}
const classList: any = element.classList
const classList = element.classList
if (classList) {
for (const className of classList.values()) {
if (className && !queriedClasses.has(className)) {
Expand All @@ -93,7 +113,7 @@ let observerConfig = {
cosmeticObserver.observe(document.documentElement, observerConfig)

const _parseDomainCache = Object.create(null)
const getParsedDomain = (aDomain: any) => {
const getParsedDomain = (aDomain: string) => {
const cacheResult = _parseDomainCache[aDomain]
if (cacheResult !== undefined) {
return cacheResult
Expand Down Expand Up @@ -225,11 +245,14 @@ const isSubTreeFirstParty = (elm: Element, possibleQueryResult?: IsFirstPartyQue
return (queryResult.foundThirdPartyResource === false)
}

const foundText = (elm as HTMLElement).innerText
return (
queryResult.foundThirdPartyResource === false &&
foundText.trim().length > 0
)
if (queryResult.foundThirdPartyResource) {
return false
}
const htmlElement = asHTMLElement(elm)
if (!htmlElement || !htmlElement.innerText.trim().length) {
return false
}
return true
}

const hideSelectors = (selectors: string[]) => {
Expand All @@ -243,12 +266,12 @@ const hideSelectors = (selectors: string[]) => {
})
}

const alreadyHiddenSelectors = new Set()
const alreadyHiddenSelectors = new Set<string>()
const alreadyHiddenThirdPartySubTrees = new WeakSet()
const allSelectorsSet = new Set()
const firstRunQueue = new Set()
const secondRunQueue = new Set()
const finalRunQueue = new Set()
const allSelectorsSet = new Set<string>()
const firstRunQueue = new Set<string>()
const secondRunQueue = new Set<string>()
const finalRunQueue = new Set<string>()
const allQueues = [firstRunQueue, secondRunQueue, finalRunQueue]
const numQueues = allQueues.length
const pumpIntervalMs = 50
Expand All @@ -273,7 +296,7 @@ const pumpCosmeticFilterQueues = () => {
const matchingElms = document.querySelectorAll(comboSelector)
const selectorsToHide = []

for (const aMatchingElm of Array.from(matchingElms)) {
for (const aMatchingElm of matchingElms) {
if (alreadyHiddenThirdPartySubTrees.has(aMatchingElm)) {
continue
}
Expand Down
9 changes: 6 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
"noImplicitAny": true,
// esnext modules supports import() async webpack modules
"module": "esnext",
// chrome 70 supports 100% es2017/8
"target": "es2017",
// chrome 80 supports 100% es2019
"target": "es2019",
"allowJs": true,
// convert jsx to react components
"jsx": "react",
"lib": [
"es6",
"dom",
"DOM.Iterable",
"es7",
"es2017"
"es2017",
"es2018",
"es2019"
],
"moduleResolution": "node",
"baseUrl": ".",
Expand Down

0 comments on commit d2675a1

Please sign in to comment.