From b9e3605f64a606e52c0e8625f15841718355d94f Mon Sep 17 00:00:00 2001 From: Gerben Date: Sun, 27 May 2018 23:48:22 +0200 Subject: [PATCH] Only check suspicious changes. Saves computation, though we might miss some changes due to activations of CSS rules. --- src/content_script.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/content_script.js b/src/content_script.js index 4975ef1..b0499f9 100644 --- a/src/content_script.js +++ b/src/content_script.js @@ -4,11 +4,11 @@ import throttle from 'lodash/throttle' import { onEnabledChange, isEnabled } from './perOrigin' -function hideBanners() { +function hideBanners(elements) { const revertSteps = [] /* Hide all elements with position:fixed */ - const fixedElements = Array.from(document.querySelectorAll('*')) + const fixedElements = elements .filter(el => ( getComputedStyle(el).position === 'fixed' && el.style.opacity !== '0' // ignore if we already hid this one @@ -36,7 +36,7 @@ function hideBanners() { }) /* Stop position:sticky elements from sticking. */ - const stickyElements = Array.from(document.querySelectorAll('*')) + const stickyElements = elements .filter(el => getComputedStyle(el).position === 'sticky') stickyElements.forEach(el => { @@ -57,10 +57,13 @@ async function main() { // Fortunately we only need the origin, which should remain the same. const url = window.location.href - function run() { + function run(elements) { if (enabled && scrolledDown) { // Hide everything that looks annoying. Remember the steps to revert this. - revertSteps = hideBanners().concat(revertSteps) + if (elements === undefined) { + elements = Array.from(document.querySelectorAll('*')) + } + revertSteps = hideBanners(elements).concat(revertSteps) } else { // Unhide everything we have hidden. if (revertSteps.length > 0) { @@ -87,12 +90,31 @@ async function main() { } }) - // Run on any page mutation, but at most once per second. - const observer = new MutationObserver(throttle(() => run(), 1000)) + // Run on suspicious page mutations. + const observer = new MutationObserver(mutationList => { + let elements = [] + mutationList.forEach(mutationRecord => { + if (mutationRecord.type === 'attributes') { + const modifiedElement = mutationRecord.target + elements.push(modifiedElement) + if (mutationRecord.attributeName === 'class') { + // A change in class is likely to influence style of the element's offspring + const children = Array.from(modifiedElement.querySelectorAll('*')) + elements = elements.concat(children) + } + } else if (mutationRecord.type === 'childList') { + const newElements = [...mutationRecord.addedNodes] + .filter(node => node instanceof Element) + elements = elements.concat(newElements) + } + }) + run(elements) + }) observer.observe(document, { subtree: true, childList: true, attributes: true, + attributeFilter: ['class', 'style'], }) // Run once now.