diff --git a/options.css b/options.css index 7832d6c..c512834 100644 --- a/options.css +++ b/options.css @@ -1,3 +1,7 @@ +/***********/ +/* GENERAL */ +/***********/ + html { box-sizing: border-box; font-size: 16px; @@ -5,6 +9,7 @@ html { *, *::before, *::after { box-sizing: inherit; } + body { margin: 0 auto; display: flex; @@ -13,12 +18,21 @@ body { padding: 10px 20px; font-size: 1rem; } +body.noscroll { + overflow: hidden; +} + body > div { position: relative; } body > div + div { margin: 2.5em 0 1em 0; } + +/************/ +/* HEADINGS */ +/************/ + h1 { border-bottom: 1px solid #ddd; margin: 0.5em 0; @@ -26,11 +40,21 @@ h1 { } h2 { margin: 0; - background-color: #fff; border-bottom: 1px solid #ddd; font-size: 1.625rem; padding: 0 0 2px 0; } +h3 { + font-size: 1.3125rem; + color: #666; + border-bottom: 1px dotted #eee; + margin: 1em 0 0.5em 0; +} + +/*************/ +/* TEXTAREAS */ +/*************/ + textarea { border: 1px solid #aaa; font-family: Inconsolata, Courier, monospace; @@ -45,14 +69,20 @@ textarea { #exclusionPatterns textarea { min-height: 150px; } -form { + +/******************/ +/* OTHER CONTROLS */ +/******************/ + +.top-controls { text-align: right; margin: 0 0 2.5em 0; display: flex; + flex-flow: row wrap; align-items: center; max-width: 640px; } -form .buttons { +.top-controls .buttons { display: flex; align-items: center; justify-content: flex-end; @@ -61,19 +91,8 @@ form .buttons { button { -webkit-appearance: none; -moz-appearance: none; - border: 1px solid #bbb; - color: #fff; - padding: 10px 16px; - cursor: default; - margin: 0 0 0 0.5em; -} -button.save-button { - background-color: #16e; - font-size: 1.5rem; -} -button.reset-button { - background-color: #d3453d; - font-size: 1rem; + border: none; + background-color: transparent; } button:active { transform: scale(0.95); @@ -81,7 +100,23 @@ button:active { button:focus:active { outline: none; } -button:disabled { +.top-controls button { + border: 1px solid #bbb; + color: #fff; + padding: 10px 16px; + cursor: default; + margin: 0 0 0 0.5em; + background-color: #fff; +} +.top-controls button.save-button { + background-color: #16e; + font-size: 1.5rem; +} +.top-controls button.reset-button { + background-color: #d3453d; + font-size: 1rem; +} +.top-controls button:disabled { background-color: #777; opacity: 0.3; } @@ -137,13 +172,21 @@ input#whitelist-mode, .mode-select-container span:not(.disabled):hover { border-bottom: 1px solid currentColor; } -form button:not(:disabled):hover { +.top-controls button:not(:disabled):hover { text-shadow: 0 0 1px #fff, 0 0 3px #fff, 0 0 5px #fff; cursor: pointer; } +p.note { + font-size: 0.875em; +} + +/******************/ +/* WHITELIST MODE */ +/******************/ + #matchingPatterns.disabled h2 { color: rgba(0,0,0,0.15); } @@ -166,9 +209,11 @@ form button:not(:disabled):hover { font-family: Inconsolata, Courier, monospace; font-size: 4em; } -p.note { - font-size: 0.875em; -} + +/***************/ +/* BOTTOM INFO */ +/***************/ + .bottom-info { font-size: 0.875rem; color: #aaa; @@ -178,4 +223,120 @@ p.note { } .bottom-info p { margin: 0; -} \ No newline at end of file +} + +/****************/ +/* HELP OVERLAY */ +/****************/ + +.open-help-button-container { + position: absolute; + top: 0; + right: 0; +} + +.help-overlay { + position: fixed; + background-color: #ffe; + top: 10px; + left: 10px; + margin: 0; + border: 1px solid #777; + box-shadow: + 1px 1px 4px 0 #aaa; + width: calc(100% - 20px); + height: calc(100% - 20px); + line-height: 1.4; + padding: 36px 0 6px 0; +} +#help { + visibility: hidden; +} +#help:target { + visibility: visible; +} +.help-container { + height: 100%; + padding: 0 16px; + overflow-y: scroll; +} +.help-container::-webkit-scrollbar { + background-color: transparent; + width: 15px; +} +.help-container::-webkit-scrollbar-thumb { + background-color: #c1c1c1; + box-shadow: 0 0 0 3px #ffe inset; +} +.help-container::-webkit-scrollbar-thumb:hover { + background-color: #888; +} + +.help-overlay h1 { + margin: 0 0 0.5em 0; + line-height: 1; + padding: 0 0 4px 0; +} + +.help-overlay .close-button, +.open-help-button-container .open-help-button { + display: block; + cursor: pointer; + color: #999; + white-space: nowrap; +} +.help-overlay .close-button:hover, +.open-help-button-container .open-help-button:hover { + color: #000; +} +.help-overlay .close-button::before, +.open-help-button-container .open-help-button::before { + font-family: Font Awesome; + padding: 4px; + display: inline-block; +} + +.help-overlay .close-button { + font-size: 0.875rem; + position: absolute; + top: 0; + right: 0; + padding: 6px 12px; +} +.help-overlay .close-button::before { + content: "\F00D"; + font-weight: 300; + font-size: 1rem; + position: relative; + top: 1px; +} + +.open-help-button-container .open-help-button { + font-size: 1.125rem; + padding: 8px 12px 10px 10px; +} +.open-help-button-container .open-help-button::before { + content: "\F059"; + font-weight: 900; + font-size: 1rem; +} + +/********/ +/* MISC */ +/********/ + +code { + font-family: Inconsolata, monospace; +} +.fa { + font-family: Font Awesome; +} +.fa-light { + font-weight: 300; +} +.fa-normal { + font-weight: 400; +} +.fa-heavy { + font-weight: 900; +} diff --git a/options.html b/options.html index 979c3b9..191b79b 100644 --- a/options.html +++ b/options.html @@ -1,15 +1,16 @@ - Always Kill Sticky - Options + AlwaysKillSticky - Options + -

Always Kill Sticky

-
+

AlwaysKillSticky

+ Blacklist mode @@ -39,6 +40,43 @@

AlwaysKillSticky v0.0

© Said Achmiz 2019–present

+ + + +
+
+ +
+
+

AlwaysKillSticky Help

+

On sites/pages where it’s enabled, AlwaysKillSticky finds all elements whose position CSS property has a computed value of either sticky or fixed, and removes those elements.

+

Basic usage

+

To enable AlwaysKillSticky on a site, click the AlwaysKillSticky icon in your browser toolbar, then click the big button (shaped like a thumbtack: ). Stickies will immediately be killed, and will always be killed whenever you visit that page, or any page on the same site, in the future.

+

To stop killing stickies on a site, just click the big button again. Stickies will no longer be killed when you visit pages on that site. (After disabling sticky-killing for a page, you can click the Reload () button to refresh the page if you want to restore killed sticky elements on that page.)

+

Modes

+

AlwaysKillSticky can work in either of two modes: blacklist mode (the default) and whitelist mode. (You can switch modes at any time, via the Options page.)

+

Blacklist mode

+

In blacklist mode, stickies will only be killed if:

+
    +
  • the page URL matches one of the patterns in the matching patterns list, and;
  • +
  • the page does not match any of the patterns in the exclusion patterns list.
  • +
+

In blacklist mode, if you click the big button () in the AlwaysKillSticky popup to enable the +

Whitelist mode

+

In whitelist mode, the matching patterns list is ignored. Stickies are always killed, unless the page matches one of the patterns in the exclusion patterns list.

+

(In whitelist mode, the behavior of the main button () in the AlwaysKillSticky popup is reversed.)

+

Advanced usage

+

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.

+

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 regular expressions (a.k.a. “regexps”). (The site RegExr.com is useful if you are not entirely familiar with how regexps work—or even if you are.)

+

NOTE: Lines beginning with a pound sign (#) are comments; they are ignored.

+

How automatic management of the patterns lists works

+

The comments in the popup.js script file explain exactly what happens to the patterns lists when you use the main button () in the AlwaysKillSticky popup to enable or disable sticky-killing on a site.

+

License

+

This extension is released under the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version.

+
+
diff --git a/options.js b/options.js index cd317fc..5ee9dab 100644 --- a/options.js +++ b/options.js @@ -3,12 +3,12 @@ /**********/ /* Triggered when a click is received by the mode selector switch, or by - either of the two labels (“Blacklist” and “Whitelist”). + either of the two labels ("Blacklist" and "Whitelist"). */ function modeSelectorInputReceived() { toggleModeSelectorState(); - // Activate the “Reset” and “Save” buttons, since changes have been made. + // Activate the "Reset" and "Save" buttons, since changes have been made. setButtonsActive(true); } @@ -28,7 +28,7 @@ function toggleModeSelectorState(newMode) { container.classList.toggle("whitelist", (newMode == "whitelist")); checkbox.checked = (newMode == "whitelist"); - /* Enable both spans (the “Blacklist” and “Whitelist” labels, then disable + /* Enable both spans (the "Blacklist" and "Whitelist" labels, then disable just the label associated with the now-enabled mode. */ container.querySelectorAll("span").forEach(span => { span.classList.toggle("disabled", false); @@ -37,13 +37,13 @@ function toggleModeSelectorState(newMode) { /* In whitelist mode, the matching patterns textarea must be disabled, since the matching patterns list is treated as containing only the - single pattern “.*”. An overlay is shown, to indicate this. */ + single pattern ".*". An overlay is shown, to indicate this. */ document.querySelector("div#matchingPatterns").classList.toggle("disabled", (newMode == "whitelist")); document.querySelector("div#matchingPatterns textarea").disabled = (newMode == "whitelist"); } /* Saves the entered state in storage. - De-activate the “Reset” and “Save” buttons. + De-activate the "Reset" and "Save" buttons. */ function saveChanges() { let matchingPatterns = document.querySelector("#matchingPatterns textarea").value; @@ -57,7 +57,7 @@ function saveChanges() { } /* Retrieves the saved state from storage and reset the UI to reflect it, - discarding the user’s changes. + discarding the user's changes. */ function resetChanges(callback) { chrome.storage.sync.get([ "matchingPatterns", "exclusionPatterns", "mode" ], (result) => { @@ -70,7 +70,7 @@ function resetChanges(callback) { toggleModeSelectorState(AKS.mode); - // De-activate the “Reset” and “Save” buttons. + // De-activate the "Reset" and "Save" buttons. setButtonsActive(false); // Expand all textareas. @@ -83,16 +83,22 @@ function resetChanges(callback) { }); } -/* Activates or de-activates the “Reset” and “Save” buttons. Called when +/* Activates or de-activates the "Reset" and "Save" buttons. Called when changes are made (to activate) or when changes are saved or reset (to de-activate). */ function setButtonsActive(active) { - document.querySelectorAll("button").forEach(button => { + document.querySelectorAll(".top-controls button").forEach(button => { button.disabled = !active; }); } +/* Enables or disables scrolling on the page body, depending on whether the + help overlay is visible. */ +function setBodyScrollState() { + document.querySelector("body").classList.toggle("noscroll", location.hash == "#help"); +} + /* Expands a textarea to show all its contents (up to a maximum height which is set via CSS). */ @@ -105,6 +111,11 @@ function expandTextarea(textarea) { }); } +function setHelpOverlayVisible(visible) { + location.hash = visible ? "help" : ""; + setBodyScrollState(); +} + /******************/ /* INITIALIZATION */ /******************/ @@ -157,5 +168,24 @@ function initialize() { modeSelectorInputReceived(); }); }); + + // Listener for open help button. + document.querySelector(".open-help-button").addActivateEvent((event) => { + setHelpOverlayVisible(true); + }); + // Listener for close help button. + document.querySelector(".help-overlay .close-button").addActivateEvent((event) => { + setHelpOverlayVisible(false); + }); + + // Disable scrolling on the document body, if need be (if help is open). + setBodyScrollState(); + + // Listener for Escape key (closes the help overlay). + document.addEventListener("keyup", (event) => { + if (event.keyCode == 27 && location.hash == "#help") { + setHelpOverlayVisible(false); + } + }); } initialize(); diff --git a/popup.js b/popup.js index 4f4576e..f099df5 100644 --- a/popup.js +++ b/popup.js @@ -6,7 +6,7 @@ happens until the UI state is updated, killSticky() is called (if needed), and the new settings are saved in storage.) - What “toggle the current state” actually means depends on the current mode. + What "toggle the current state” actually means depends on the current mode. [1] In blacklist mode, toggleState() does one of the following: @@ -265,12 +265,12 @@ function initialize() { // Listener for Options button. document.querySelector("button.options-button").addActivateEvent(() => { - chrome.runtime.openOptionsPage(null); + window.open(chrome.runtime.getURL('options.html')) }); // Listener for the Help button. document.querySelector("button.help-button").addActivateEvent(() => { - // TODO: code! + window.open(chrome.runtime.getURL('options.html') + "#help"); }); // Listener for reload button (appears when sticky-killing is toggled OFF).