| if (getComputedStyle(mutation.target).position == 'fixed' || | if (getComputedStyle(mutation.target).position == 'fixed' || | ||||
| getComputedStyle(mutation.target).position == 'sticky') { | getComputedStyle(mutation.target).position == 'sticky') { | ||||
| mutation.target.remove(); | mutation.target.remove(); | ||||
| console.log("Killing new sticky!"); | |||||
| console.log("Killing a sticky!"); | |||||
| // Compensate for fullscreen paywalls. | |||||
| restoreScrollability(); | |||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| observer.observe(document.querySelector("body"), { | |||||
| observer.observe(document.querySelector("html"), { | |||||
| attributes: true, | attributes: true, | ||||
| childList: true, | childList: true, | ||||
| subtree: true | subtree: true | ||||
| /******************/ | /******************/ | ||||
| function initialize() { | function initialize() { | ||||
| chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode", "constantVigilance" ], | |||||
| chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode" ], | |||||
| (result) => { | (result) => { | ||||
| let shouldKillSticky = checkForShouldKillSticky(result); | let shouldKillSticky = checkForShouldKillSticky(result); | ||||
| updateIcon(shouldKillSticky); | updateIcon(shouldKillSticky); | ||||
| let constantVigilance = (result.constantVigilance == "false") ? false : true; | |||||
| window.onload = () => { | |||||
| if (shouldKillSticky) { | |||||
| if (shouldKillSticky) { | |||||
| startConstantVigilance(); | |||||
| window.onload = () => { | |||||
| killSticky(); | killSticky(); | ||||
| if (constantVigilance) startConstantVigilance(); | |||||
| } | } | ||||
| }; | |||||
| } | |||||
| }); | }); | ||||
| } | } | ||||
| initialize(); | initialize(); |
| element.remove(); | element.remove(); | ||||
| } | } | ||||
| }); | }); | ||||
| // Compensate for full-screen paywalls. | |||||
| restoreScrollability(); | |||||
| } | |||||
| /* Full-screen paywalls not only bring up sticky elements, they also make | |||||
| the page un-scrollable. This ensures that the page remains scrollable. | |||||
| */ | |||||
| function restoreScrollability() { | |||||
| document.querySelectorAll("html, body").forEach(container => { | |||||
| container.style.setProperty("overflow-y", "auto", "important"); | |||||
| }); | |||||
| } | } |
| border-bottom: 1px solid currentColor; | border-bottom: 1px solid currentColor; | ||||
| } | } | ||||
| /**********************/ | |||||
| /* 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; | |||||
| } | |||||
| .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; | |||||
| } | |||||
| /******************/ | /******************/ | ||||
| /* WHITELIST MODE */ | /* WHITELIST MODE */ | ||||
| /******************/ | /******************/ |
| <input type='checkbox' id='whitelist-mode'></input> | <input type='checkbox' id='whitelist-mode'></input> | ||||
| <span class='whitelist-mode-label'>Whitelist mode</span> | <span class='whitelist-mode-label'>Whitelist mode</span> | ||||
| </span> | </span> | ||||
| <span class='constant-vigilance-container'> | |||||
| <input type='checkbox' name='constant-vigilance' id='constant-vigilance' checked></input> | |||||
| <label for='constant-vigilance' title='Continue monitoring the page for sticky elements added after page load. (See help for more info.)'>CONSTANT VIGILANCE!</label> | |||||
| </span> | |||||
| <span class='buttons'> | <span class='buttons'> | ||||
| <button disabled type='button' class='reset-button'>Reset</button> | <button disabled type='button' class='reset-button'>Reset</button> | ||||
| <button disabled type='button' class='save-button'>Save</button> | <button disabled type='button' class='save-button'>Save</button> | ||||
| <h3>Whitelist mode</h3> | <h3>Whitelist mode</h3> | ||||
| <p>In <strong>whitelist mode</strong>, <em>the matching patterns list is ignored</em>. Stickies are <em>always</em> killed, <em>unless</em> the page matches one of the patterns in the <strong>exclusion patterns</strong> list.</p> | <p>In <strong>whitelist mode</strong>, <em>the matching patterns list is ignored</em>. Stickies are <em>always</em> killed, <em>unless</em> the page matches one of the patterns in the <strong>exclusion patterns</strong> list.</p> | ||||
| <p>(In whitelist mode, the behavior of the main button (<span class='fa fa-heavy'></span>) in the AlwaysKillSticky popup is reversed.)</p> | <p>(In whitelist mode, the behavior of the main button (<span class='fa fa-heavy'></span>) in the AlwaysKillSticky popup is reversed.)</p> | ||||
| <h2>Constant vigilance</h2> | |||||
| <p>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.</p> | |||||
| <p>This feature may slightly impact browser performance on some sites or some computers. If you disable it, stickies will still be killed immediately upon page load, but not thereafter.</p> | |||||
| <h2>Advanced usage</h2> | <h2>Advanced usage</h2> | ||||
| <p>AlwaysKillSticky automatically manages the lists of matching and exclusion patterns. When you enable or disable sticky-killing for a site (by clicking the big button in the AlwaysKillSticky popup), the pattern lists are automatically modified appropriately. There is usually no need to edit the lists yourself.</p> | <p>AlwaysKillSticky automatically manages the lists of matching and exclusion patterns. When you enable or disable sticky-killing for a site (by clicking the big button in the AlwaysKillSticky popup), the pattern lists are automatically modified appropriately. There is usually no need to edit the lists yourself.</p> | ||||
| <p>However, if you prefer more fine-grained control (e.g., if you want to kill stickies on all sites on a domain, or if you want to exclude specific paths of a site), you can edit the pattern lists by hand. The matching and exclusion patterns are <a href='https://en.wikipedia.org/wiki/Regular_expression' rel='nofollow' target='_blank'>regular expressions</a> (a.k.a. “regexps”). (The site <a href='https://regexr.com/' rel='nofollow' target='_blank'>RegExr.com</a> is useful if you are not entirely familiar with how regexps work—or even if you are.)</p> | <p>However, if you prefer more fine-grained control (e.g., if you want to kill stickies on all sites on a domain, or if you want to exclude specific paths of a site), you can edit the pattern lists by hand. The matching and exclusion patterns are <a href='https://en.wikipedia.org/wiki/Regular_expression' rel='nofollow' target='_blank'>regular expressions</a> (a.k.a. “regexps”). (The site <a href='https://regexr.com/' rel='nofollow' target='_blank'>RegExr.com</a> is useful if you are not entirely familiar with how regexps work—or even if you are.)</p> |
| let matchingPatterns = document.querySelector("#matchingPatterns textarea").value; | let matchingPatterns = document.querySelector("#matchingPatterns textarea").value; | ||||
| let exclusionPatterns = document.querySelector("#exclusionPatterns textarea").value; | let exclusionPatterns = document.querySelector("#exclusionPatterns textarea").value; | ||||
| let mode = document.querySelector("input#whitelist-mode").checked ? "whitelist" : "blacklist"; | let mode = document.querySelector("input#whitelist-mode").checked ? "whitelist" : "blacklist"; | ||||
| let constantVigilance = document.querySelector("input#constant-vigilance").checked ? "true" : "false"; | |||||
| chrome.storage.sync.set({ | chrome.storage.sync.set({ | ||||
| "matchingPatterns": matchingPatterns, | "matchingPatterns": matchingPatterns, | ||||
| "exclusionPatterns": exclusionPatterns, | "exclusionPatterns": exclusionPatterns, | ||||
| "mode": mode, | |||||
| "constantVigilance": constantVigilance | |||||
| "mode": mode | |||||
| }, () => { setButtonsActive(false); }); | }, () => { setButtonsActive(false); }); | ||||
| } | } | ||||
| discarding the user's changes. | discarding the user's changes. | ||||
| */ | */ | ||||
| function resetChanges(callback) { | function resetChanges(callback) { | ||||
| chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode", "constantVigilance" ], (result) => { | |||||
| chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode" ], (result) => { | |||||
| AKS.matchingPatterns = result.matchingPatterns || ""; | AKS.matchingPatterns = result.matchingPatterns || ""; | ||||
| AKS.exclusionPatterns = result.exclusionPatterns || "" | AKS.exclusionPatterns = result.exclusionPatterns || "" | ||||
| AKS.mode = result.mode || "blacklist"; | AKS.mode = result.mode || "blacklist"; | ||||
| AKS.constantVigilance = result.constantVigilance || "true"; | |||||
| document.querySelector("#matchingPatterns textarea").value = AKS.matchingPatterns; | document.querySelector("#matchingPatterns textarea").value = AKS.matchingPatterns; | ||||
| document.querySelector("#exclusionPatterns textarea").value = AKS.exclusionPatterns; | document.querySelector("#exclusionPatterns textarea").value = AKS.exclusionPatterns; | ||||
| toggleModeSelectorState(AKS.mode); | toggleModeSelectorState(AKS.mode); | ||||
| // Set CONSTANT VIGILANCE! checkbox state. | |||||
| document.querySelector("input#constant-vigilance").checked = AKS.constantVigilance == "true"; | |||||
| // De-activate the "Reset" and "Save" buttons. | // De-activate the "Reset" and "Save" buttons. | ||||
| setButtonsActive(false); | setButtonsActive(false); | ||||
| }); | }); | ||||
| }); | }); | ||||
| /* 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. | // Listener for open help button. | ||||
| document.querySelector(".open-help-button").addActivateEvent((event) => { | document.querySelector(".open-help-button").addActivateEvent((event) => { | ||||
| setHelpOverlayVisible(true); | setHelpOverlayVisible(true); |
| { | { | ||||
| "manifest_version": 2, | "manifest_version": 2, | ||||
| "name": "AlwaysKillSticky", | "name": "AlwaysKillSticky", | ||||
| "version": "1.1.3", | |||||
| "version": "1.2", | |||||
| "description": "Get rid of sticky elements on websites - permanently!", | "description": "Get rid of sticky elements on websites - permanently!", | ||||
| "author": "Said Achmiz", | "author": "Said Achmiz", | ||||
| "homepage_url": "https://git.sr.ht/~achmizs/AlwaysKillSticky.git", | "homepage_url": "https://git.sr.ht/~achmizs/AlwaysKillSticky.git", | ||||
| }, | }, | ||||
| "content_scripts": [ { | "content_scripts": [ { | ||||
| "matches": [ "http://*/*", "https://*/*" ], | "matches": [ "http://*/*", "https://*/*" ], | ||||
| "run_at": "document_end", | |||||
| "run_at": "document_start", | |||||
| "js": [ "functions.js", "contentScript.js" ] | "js": [ "functions.js", "contentScript.js" ] | ||||
| } | } | ||||
| ], | ], |
| { | { | ||||
| "manifest_version": 2, | "manifest_version": 2, | ||||
| "name": "AlwaysKillSticky", | "name": "AlwaysKillSticky", | ||||
| "version": "1.1.3", | |||||
| "version": "1.2", | |||||
| "description": "Get rid of sticky elements on websites - permanently!", | "description": "Get rid of sticky elements on websites - permanently!", | ||||
| "author": "Said Achmiz", | "author": "Said Achmiz", | ||||
| "browser_specific_settings": { | "browser_specific_settings": { | ||||
| }, | }, | ||||
| "content_scripts": [ { | "content_scripts": [ { | ||||
| "matches": [ "http://*/*", "https://*/*" ], | "matches": [ "http://*/*", "https://*/*" ], | ||||
| "run_at": "document_end", | |||||
| "run_at": "document_start", | |||||
| "js": [ "functions.js", "contentScript.js" ] | "js": [ "functions.js", "contentScript.js" ] | ||||
| } | } | ||||
| ], | ], |