From cb0de41abcbae429b770bbf76ed09d181103db85 Mon Sep 17 00:00:00 2001 From: achmizs Date: Sat, 2 Feb 2019 22:24:24 -0500 Subject: [PATCH] Added CONSTANT VIGILANCE feature --- src/contentScript.js | 32 +++++++++++++++++-- src/options.css | 76 +++++++++++++++++++++++++++++++++++++++----- src/options.html | 4 +++ src/options.js | 18 +++++++++-- 4 files changed, 117 insertions(+), 13 deletions(-) diff --git a/src/contentScript.js b/src/contentScript.js index cea8bcc..67f68db 100644 --- a/src/contentScript.js +++ b/src/contentScript.js @@ -51,17 +51,45 @@ function checkForShouldKillSticky(result) { return shouldKillSticky; } +/* Some websites add sticky elements after loading, or make existing elements + sticky (either on a timer, or based on user actions). CONSTANT VIGILANCE + counteracts this behavior, by watching the DOM for mutations, and, if + necessary, killing any newly-formed stickies. + */ +function startConstantVigilance() { + var observer = new MutationObserver((mutationsList, observer) => { + var shouldKillSticky = false; + for (var mutation of mutationsList) { + if (mutation.target.style.position == 'fixed' || + mutation.target.style.position == 'sticky') + shouldKillSticky = true; + } + if (shouldKillSticky) + requestAnimationFrame(() => { killSticky(); }); + }); + + observer.observe(document.querySelector("body"), { + attributes: true, + childList: true, + subtree: true + }); +} + /******************/ /* INITIALIZATION */ /******************/ function initialize() { - chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode" ], + chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode", "constantVigilance" ], (result) => { let shouldKillSticky = checkForShouldKillSticky(result); updateIcon(shouldKillSticky); + let constantVigilance = (result.constantVigilance == "false") ? false : true; window.onload = () => { - if (shouldKillSticky) killSticky(); + if (shouldKillSticky) { + killSticky(); + if (constantVigilance) startConstantVigilance(); + } }; }); } diff --git a/src/options.css b/src/options.css index 150386d..49089c1 100644 --- a/src/options.css +++ b/src/options.css @@ -81,7 +81,7 @@ textarea { display: flex; flex-flow: row wrap; align-items: center; - max-width: 640px; + max-width: 750px; } .top-controls .buttons { display: flex; @@ -121,6 +121,18 @@ button:focus:active { background-color: #777; opacity: 0.3; } +.top-controls button:not(:disabled):hover { + text-shadow: + 0 0 1px #fff, + 0 0 3px #fff, + 0 0 5px #fff; + cursor: pointer; +} + +/******************/ +/* MODE SELECTION */ +/******************/ + input#whitelist-mode { display: block; -webkit-appearance: none; @@ -153,6 +165,7 @@ input#whitelist-mode, align-self: flex-start; border: 1px solid #ddd; padding: 8px 10px; + margin cursor: default; background-color: #fff; } @@ -173,15 +186,59 @@ input#whitelist-mode, .mode-select-container span:not(.disabled):hover { border-bottom: 1px solid currentColor; } -.top-controls button:not(:disabled):hover { - text-shadow: - 0 0 1px #fff, - 0 0 3px #fff, - 0 0 5px #fff; + +/**********************/ +/* CONSTANT VIGILANCE */ +/**********************/ + +.constant-vigilance-container { + border: 1px solid #ddd; + padding: 9px 13px 12px 11px; + display: flex; + align-items: center; + margin: 0 0 0 10px; +} + +.constant-vigilance-container input[type='checkbox'] { + -webkit-appearance: none; + -moz-appearance: none; + border: 1px solid #000; + width: 15px; + height: 15px; + position: relative; + top: 1px; + margin: 3px 5px 0 0; +} +.constant-vigilance-container input[type='checkbox'], +.constant-vigilance-container label { cursor: pointer; } -p.note { - font-size: 0.875em; +.constant-vigilance-container label { + line-height: 1; + padding: 8px 0 0 0; + border-bottom: 1px solid transparent; + font-size: 0.875rem; +} +.constant-vigilance-container label::selection { + background-color: transparent; +} +.constant-vigilance-container input[type='checkbox']:focus { + outline: none; +} +.constant-vigilance-container input[type='checkbox']:focus + label, +.constant-vigilance-container input[type='checkbox']:hover + label, +.constant-vigilance-container input[type='checkbox'] + label:hover { + border-bottom: 1px dotted #000; +} +.constant-vigilance-container input[type='checkbox']:checked, +.constant-vigilance-container input[type='checkbox']:hover { + box-shadow: 0 0 0 2px #fff inset; +} +.constant-vigilance-container input[type='checkbox']:hover { + background-color: #ccc; +} +.constant-vigilance-container input[type='checkbox']:checked { + background-color: #000; } /******************/ @@ -341,3 +398,6 @@ code { .fa-heavy { font-weight: 900; } +p.note { + font-size: 0.875em; +} diff --git a/src/options.html b/src/options.html index 191b79b..3e5aec9 100644 --- a/src/options.html +++ b/src/options.html @@ -16,6 +16,10 @@ Whitelist mode + + + + diff --git a/src/options.js b/src/options.js index cc731ae..0015c20 100644 --- a/src/options.js +++ b/src/options.js @@ -49,10 +49,12 @@ function saveChanges() { let matchingPatterns = document.querySelector("#matchingPatterns textarea").value; let exclusionPatterns = document.querySelector("#exclusionPatterns textarea").value; let mode = document.querySelector("input#whitelist-mode").checked ? "whitelist" : "blacklist"; + let constantVigilance = document.querySelector("input#constant-vigilance").checked ? "true" : "false"; chrome.storage.sync.set({ "matchingPatterns": matchingPatterns, "exclusionPatterns": exclusionPatterns, - "mode": mode + "mode": mode, + "constantVigilance": constantVigilance }, () => { setButtonsActive(false); }); } @@ -60,16 +62,20 @@ function saveChanges() { discarding the user's changes. */ function resetChanges(callback) { - chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode" ], (result) => { + chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode", "constantVigilance" ], (result) => { AKS.matchingPatterns = result.matchingPatterns || ""; AKS.exclusionPatterns = result.exclusionPatterns || "" AKS.mode = result.mode || "blacklist"; + AKS.constantVigilance = result.constantVigilance || "true"; document.querySelector("#matchingPatterns textarea").value = AKS.matchingPatterns; document.querySelector("#exclusionPatterns textarea").value = AKS.exclusionPatterns; toggleModeSelectorState(AKS.mode); + // Set CONSTANT VIGILANCE! checkbox state. + document.querySelector("input#constant-vigilance").checked = AKS.constantVigilance == "true"; + // De-activate the "Reset" and "Save" buttons. setButtonsActive(false); @@ -160,7 +166,7 @@ function initialize() { }); // Listeners for mode select switch. - document.querySelector("input[type='checkbox']").addEventListener("change", (event) => { + document.querySelector("input#whitelist-mode").addEventListener("change", (event) => { modeSelectorInputReceived(); }); document.querySelectorAll(".mode-select-container span").forEach(span => { @@ -169,6 +175,12 @@ function initialize() { }); }); + /* Listener to activate Reset/Save buttons when the CONSTANT VIGILANCE + checkbox is toggled. */ + document.querySelector("input#constant-vigilance").addEventListener("change", (event) => { + setButtonsActive(true); + }); + // Listener for open help button. document.querySelector(".open-help-button").addActivateEvent((event) => { setHelpOverlayVisible(true);