Browser extension to hide view-reducing screen junk from websites.
Browse Source

Add pageAction button to enable/disable per origin

tags/v1.1.0
Gerben 6 years ago
parent
commit
45086cf67f
8 changed files with 135 additions and 7 deletions
  1. +2
    -1
      .babelrc
  2. +7
    -1
      extension/manifest.json
  3. +1
    -0
      package.json
  4. +7
    -0
      src/background_script.js
  5. +15
    -5
      src/content_script.js
  6. +27
    -0
      src/listenableStorage.js
  7. +31
    -0
      src/pageActionButton.js
  8. +45
    -0
      src/perOrigin.js

+ 2
- 1
.babelrc View File

@@ -5,6 +5,7 @@
"firefox": "55", "firefox": "55",
"chrome": "60" "chrome": "60"
} }
}]
}],
"stage-3"
] ]
} }

+ 7
- 1
extension/manifest.json View File

@@ -2,6 +2,10 @@
"name": "bannerbanner", "name": "bannerbanner",
"description": "Hide view-reducing screen junk from websites.", "description": "Hide view-reducing screen junk from websites.",
"version": "1.0.0", "version": "1.0.0",
"page_action": {
"browser_style": true,
"default_title": "Ban banners"
},
"background": { "background": {
"scripts": ["background_script.js"] "scripts": ["background_script.js"]
}, },
@@ -11,7 +15,9 @@
"run_at": "document_end" "run_at": "document_end"
}], }],
"permissions": [ "permissions": [
"<all_urls>"
"<all_urls>",
"storage",
"tabs"
], ],
"applications": { "applications": {
"gecko": {"id": "bannerbanner@bannerbanner"} "gecko": {"id": "bannerbanner@bannerbanner"}


+ 1
- 0
package.json View File

@@ -15,6 +15,7 @@
}, },
"devDependencies": { "devDependencies": {
"babel-preset-env": "^1.6.1", "babel-preset-env": "^1.6.1",
"babel-preset-stage-3": "^6.24.1",
"babelify": "^7.3.0", "babelify": "^7.3.0",
"browserify": "^14.3.0", "browserify": "^14.3.0",
"crx": "^3.2.1", "crx": "^3.2.1",


+ 7
- 0
src/background_script.js View File

@@ -1 +1,8 @@
import browser from 'webextension-polyfill' import browser from 'webextension-polyfill'

import pageActionButton from './pageActionButton'
import { toggleEnabled, isEnabled } from './perOrigin'


pageActionButton({ predicate: tab => true })
browser.pageAction.onClicked.addListener(tab => toggleEnabled(tab.url))

+ 15
- 5
src/content_script.js View File

@@ -1,6 +1,9 @@
import browser from 'webextension-polyfill' import browser from 'webextension-polyfill'
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'


import { onEnabledChange, isEnabled } from './perOrigin'


function hideBanners() { function hideBanners() {
const revertSteps = [] const revertSteps = []


@@ -47,20 +50,27 @@ function hideBanners() {
return revertSteps return revertSteps
} }



function main() { function main() {
let revertSteps = [] let revertSteps = []


function onScroll(event) {
if (window.scrollY > 20) {
// XXX We read the location only once, but it may be changed by page scripts.
// Fortunately we only need the origin, which should remain the same.
const url = window.location.href

async function run() {
const enabled = await isEnabled(url)
if (enabled && window.scrollY > 20) {
// Hide everything that looks annoying. Remember the steps to revert this.
revertSteps = hideBanners().concat(revertSteps) revertSteps = hideBanners().concat(revertSteps)
} else if (window.scrollY <= 0) {
} else if (!enabled || window.scrollY <= 0) {
// Unhide everything we have hidden.
revertSteps.forEach(step => step()) revertSteps.forEach(step => step())
revertSteps = [] revertSteps = []
} }
} }


window.addEventListener('scroll', throttle(onScroll, 1000))
window.addEventListener('scroll', throttle(run, 300))
onEnabledChange(url, run)
} }


main() main()

+ 27
- 0
src/listenableStorage.js View File

@@ -0,0 +1,27 @@
/* Augments the WebExtension storage API to allow listening for changes on a
* single variable of a single storage area (i.e. local or sync).
*
* Usage example:
* const storage = listenableStorage(browser.storage)
* storage.local.onChanged('someVar', newValue => { .... })
*/

export default storage => {
const mkOnChange = storageName => {
return (key, cb) => {
const listener = (changes, areaName) => {
if (changes[key]) {
const newValue = changes[key].newValue
cb(newValue)
}
}
storage.onChanged.addListener(listener)
}
}

return storage && ({
...storage,
local: storage.local && { ...storage.local, onChanged: mkOnChange('local') },
sync: storage.sync && { ...storage.sync, onChanged: mkOnChange('sync') },
})
}

+ 31
- 0
src/pageActionButton.js View File

@@ -0,0 +1,31 @@
/* Show a page action button on a tab whenever the given predicate is true.
* The predicate is passed a Tab object, and is evaluated whenever the tab has
* changed.
*
* Example usage:
* pageAction({ predicate: tab => tab.url.startsWith('https') })
*/

import browser from 'webextension-polyfill'


export default async function pageActionButton({ predicate }) {
async function maybeShowButton(tab) {
if (await predicate(tab)) {
browser.pageAction.show(tab.id)
} else {
browser.pageAction.hide(tab.id)
}
}

// Show/hide the button on current tabs.
const tabs = await browser.tabs.query({})
for (const tab of tabs) {
maybeShowButton(tab)
}

// Show/hide the button whenever a tab changes.
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
maybeShowButton(tab)
});
}

+ 45
- 0
src/perOrigin.js View File

@@ -0,0 +1,45 @@
/* Tells or toggles for any URL whether the extension should be enabled.
* Groups URL by their origin; a whole origin is enabled or disabled.
*/

import browser from 'webextension-polyfill'

import listenableStorage from './listenableStorage'

const browserStorage = listenableStorage(browser.storage)

// Whichever is supported.
// XXX Causes data loss when the browser suddenly supports the sync storage area.
const storage = browserStorage.sync || browserStorage.local

const keyForUrl = url => {
const origin = new URL(url).origin
return `enable_on_origin_${origin}`
}

export async function disable(url) {
await storage.set({ [keyForUrl(url)]: false })
}

export async function enable(url) {
await storage.set({ [keyForUrl(url)]: true })
}

export async function toggleEnabled(url) {
const enabled = await isEnabled(url)
if (enabled) {
await disable(url)
} else {
await enable(url)
}
}

export async function isEnabled(url, defaultValue = true) {
const key = keyForUrl(url)
const result = await storage.get({ [key]: defaultValue })
return result[key]
}

export function onEnabledChange(url, cb) {
storage.onChanged(keyForUrl(url), cb)
}

Loading…
Cancel
Save