Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cosmetic filtering #3303

Merged
merged 9 commits into from Dec 14, 2019

only use MutationObserver when cosmetic filtering is enabled

  • Loading branch information
antonok-edm committed Dec 5, 2019
commit e7af49706e68462f9192f569a10f88ed0c33f8a8
@@ -9,6 +9,7 @@ transpile_web_ui("brave_extension") {
["brave_extension_background", rebase_path("background.ts")],
["content", rebase_path("content.ts")],
["content_dapps", rebase_path("content_dapps.ts")],
["content_cosmetic", rebase_path("content_cosmetic.ts")],
["webstore", rebase_path("webstore.ts")],
]

@@ -9,82 +9,12 @@ chrome.runtime.sendMessage({
})

const unique = require('unique-selector').default

let target: EventTarget | null
let genericExceptions: Array<string> | undefined = undefined

const queriedIds = new Set()
const queriedClasses = new Set()
const regexWhitespace = /\s/

function getCurrentURL () {
return window.location.hostname
}

const getClassesAndIds = function (addedNodes: Element[]) {
const ids = []
const classes = []

for (const node of addedNodes) {
let nodeId = node.id
if (nodeId && nodeId.length !== 0) {
nodeId = nodeId.trim()
if (!queriedIds.has(nodeId) && nodeId.length !== 0) {
ids.push(nodeId)
queriedIds.add(nodeId)
}
}
let nodeClass = node.className
if (nodeClass && nodeClass.length !== 0 && !regexWhitespace.test(nodeClass)) {
if (!queriedClasses.has(nodeClass)) {
classes.push(nodeClass)
queriedClasses.add(nodeClass)
}
} else {
let nodeClasses = node.classList
if (nodeClasses) {
let j = nodeClasses.length
while (j--) {
const nodeClassJ = nodeClasses[j]
if (queriedClasses.has(nodeClassJ) === false) {
classes.push(nodeClassJ)
queriedClasses.add(nodeClassJ)
}
}
}
}
}
return { classes, ids }
}

const handleNewNodes = (newNodes: Element[]) => {
const { classes, ids } = getClassesAndIds(newNodes)
chrome.runtime.sendMessage({
type: 'classIdStylesheet',
classes,
ids,
exceptions: genericExceptions
})
}

function applyCosmeticFilterMutationObserver () {
let targetNode = document.documentElement
let observer = new MutationObserver(mutations => {
const nodeList: Element[] = []
for (const mutation of mutations) {
for (let nodeIndex = 0; nodeIndex < mutation.addedNodes.length; nodeIndex++) {
nodeList.push(mutation.addedNodes[nodeIndex] as Element)
}
}
handleNewNodes(nodeList)
})
let observerConfig = {
childList: true,
subtree: true
}
observer.observe(targetNode, observerConfig)
}

document.addEventListener('contextmenu', (event) => {
// send host and store target
// `target` needed for when background page handles `addBlockElement`
@@ -102,15 +32,5 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
sendResponse(unique(target))
break
}
case 'cosmeticFilterGenericExceptions': {
genericExceptions = msg.exceptions

let allNodes = Array.from(document.querySelectorAll('[id],[class]'))
handleNewNodes(allNodes)
applyCosmeticFilterMutationObserver()

sendResponse(null)
break
}
}
})
@@ -0,0 +1,85 @@
let genericExceptions: Array<string> | undefined = undefined

const queriedIds = new Set()
const queriedClasses = new Set()
const regexWhitespace = /\s/

const getClassesAndIds = function (addedNodes: Element[]) {
const ids = []
const classes = []

for (const node of addedNodes) {
let nodeId = node.id
if (nodeId && nodeId.length !== 0) {
nodeId = nodeId.trim()
if (!queriedIds.has(nodeId) && nodeId.length !== 0) {
ids.push(nodeId)
queriedIds.add(nodeId)
}
}
let nodeClass = node.className
if (nodeClass && nodeClass.length !== 0 && !regexWhitespace.test(nodeClass)) {
if (!queriedClasses.has(nodeClass)) {
classes.push(nodeClass)
queriedClasses.add(nodeClass)
}
} else {
let nodeClasses = node.classList
if (nodeClasses) {
let j = nodeClasses.length
while (j--) {
const nodeClassJ = nodeClasses[j]
if (queriedClasses.has(nodeClassJ) === false) {
classes.push(nodeClassJ)
queriedClasses.add(nodeClassJ)
}
}
}
}
}
return { classes, ids }
}

const handleNewNodes = (newNodes: Element[]) => {
const { classes, ids } = getClassesAndIds(newNodes)
chrome.runtime.sendMessage({
type: 'classIdStylesheet',
classes,
ids,
exceptions: genericExceptions
})
}

function applyCosmeticFilterMutationObserver () {
let targetNode = document.documentElement
let observer = new MutationObserver(mutations => {
const nodeList: Element[] = []
for (const mutation of mutations) {
for (let nodeIndex = 0; nodeIndex < mutation.addedNodes.length; nodeIndex++) {
nodeList.push(mutation.addedNodes[nodeIndex] as Element)
}
}
handleNewNodes(nodeList)
})
let observerConfig = {
childList: true,
subtree: true
}
observer.observe(targetNode, observerConfig)
}

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
const action = typeof msg === 'string' ? msg : msg.type
switch (action) {
case 'cosmeticFilterGenericExceptions': {
genericExceptions = msg.exceptions

let allNodes = Array.from(document.querySelectorAll('[id],[class]'))
handleNewNodes(allNodes)
applyCosmeticFilterMutationObserver()

sendResponse(null)
break
}
}
})
@@ -28,7 +28,8 @@
"https://*/*"
],
"js": [
"out/content.bundle.js"
"out/content.bundle.js",
"out/content_cosmetic.bundle.js"
],
"run_at": "document_start",
"all_frames": true
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.