├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── backgrounds └── main.js ├── icons ├── icon.png └── icon@2x.png ├── manifest.json ├── options ├── options.css ├── options.html └── options.js └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "standard", 3 | "env": { 4 | "browser": true, 5 | "webextensions": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /yarn.lock 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ery Widyanto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # firefox-simple-blocker -------------------------------------------------------------------------------- /backgrounds/main.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var debug = false 4 | var mode = 0 5 | 6 | let regexes = [] 7 | 8 | function normalizeData (data) { 9 | if (!data.simpleBlocker) { 10 | data = { 11 | simpleBlocker: { 12 | regexes: '', 13 | debug: debug, 14 | mode: mode 15 | } 16 | } 17 | } 18 | 19 | return data 20 | } 21 | 22 | function updateCacheVar (strRegexArray, lmode, ldebug) { 23 | mode = lmode 24 | debug = ldebug 25 | regexes = [] 26 | for (let r of strRegexArray) { 27 | if (r) { 28 | try { 29 | regexes.push(new RegExp(r)) 30 | } catch (e) { 31 | // silent 32 | } 33 | } 34 | } 35 | } 36 | 37 | function save (stringRegexes, lmode, ldebug) { // eslint-disable-line no-unused-vars 38 | browser.storage.local.get('simpleBlocker').then((data) => { 39 | data = normalizeData(data) 40 | data.simpleBlocker.regexes = stringRegexes 41 | data.simpleBlocker.mode = lmode 42 | data.simpleBlocker.debug = ldebug 43 | browser.storage.local.set(data) 44 | updateCacheVar( 45 | stringRegexes.split(/\r?\n/), 46 | lmode, 47 | ldebug 48 | ) 49 | }) 50 | } 51 | 52 | function retrieve () { // eslint-disable-line no-unused-vars 53 | return browser.storage.local.get('simpleBlocker').then((data) => { 54 | data = normalizeData(data) 55 | updateCacheVar( 56 | data.simpleBlocker.regexes.split(/\r?\n/), 57 | data.simpleBlocker.mode, 58 | data.simpleBlocker.debug 59 | ) 60 | 61 | return data.simpleBlocker 62 | }) 63 | } 64 | 65 | function filterRequest (request) { 66 |   let cancel = mode == '1' 67 |   for (let regex of regexes) { 68 |     if (mode === '0' && regex.test(request.url)) { 69 |       cancel = true 70 |       break 71 |     } 72 |     if (mode === '1' && regex.test(request.url)) { 73 |         cancel = false 74 |         break 75 |     } 76 |   } 77 | 78 |   if (debug === '1' && cancel == true) { 79 |         console.log('Canceled request: ' + request.url) 80 |   } 81 |   return { cancel: cancel } 82 | } 83 | 84 | browser.storage.local.get('simpleBlocker').then((data) => { 85 | data = normalizeData(data) 86 | updateCacheVar( 87 | data.simpleBlocker.regexes.split(/\r?\n/), 88 | data.simpleBlocker.mode, 89 | data.simpleBlocker.debug 90 | ) 91 | 92 | // browser.storage.local.remove("simpleBlocker") 93 | }) 94 | 95 | browser.webRequest.onBeforeRequest.addListener( 96 | filterRequest, 97 | { urls: [''] }, 98 | ['blocking'] 99 | ) 100 | -------------------------------------------------------------------------------- /icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eryw/firefox-simple-blocker/87b717e180c0bef855dbda19725583b49f15a8d8/icons/icon.png -------------------------------------------------------------------------------- /icons/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eryw/firefox-simple-blocker/87b717e180c0bef855dbda19725583b49f15a8d8/icons/icon@2x.png -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Block URL using regular expression", 3 | "manifest_version": 2, 4 | "name": "Simple Blocker", 5 | "version": "0.3.7", 6 | "author": "Ery Widyanto", 7 | 8 | "permissions": [ 9 | "webRequest", 10 | "webRequestBlocking", 11 | "storage", 12 | "" 13 | ], 14 | 15 | "background": { 16 | "scripts": ["backgrounds/main.js"] 17 | }, 18 | 19 | "options_ui": { 20 | "page": "options/options.html" 21 | }, 22 | 23 | "icons": { 24 | "48": "icons/icon.png", 25 | "96": "icons/icon@2x.png" 26 | }, 27 | 28 | "applications": { 29 | "gecko": { 30 | "id": "simpleblocker@ery.my.id", 31 | "strict_min_version": "51.0" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /options/options.css: -------------------------------------------------------------------------------- 1 | textarea, fieldset, button { 2 | margin: 5px 2px; 3 | } 4 | textarea { 5 | margin-top: 12px; 6 | width: calc(100% - 8px); 7 | display: block; 8 | } 9 | fieldset > legend { 10 | font-weight: bold; 11 | font-size: 0.8rem; 12 | } 13 | button { 14 | margin-top: 14px; 15 | display: block; 16 | font-weight: bold; 17 | } 18 | aside { 19 | color: red; 20 | font-size: 0.8rem; 21 | font-style: italic; 22 | padding-top: 4px; 23 | display: none; 24 | } 25 | small { 26 | font-style: italic; 27 | } 28 | .visible { 29 | display: block; 30 | } 31 | -------------------------------------------------------------------------------- /options/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | Debug 11 | 14 | 17 |
18 |
19 | Filter Mode 20 | 23 | 26 |
27 |
28 | Filter List 29 | 30 | Regular expressions separated by newline. For details of Firefox's regular expression see 31 | MDN document 33 | 34 |
35 |
36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /options/options.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | let tout 4 | let background = browser.extension.getBackgroundPage() 5 | 6 | let autoSave = function (e) { 7 | e.stopPropagation() 8 | clearTimeout(tout) 9 | 10 | tout = setTimeout(function () { 11 | background.save(document.querySelector('#regexes').value, 12 | document.querySelector('input[name="mode"]:checked').value, 13 | document.querySelector('input[name="debugging"]:checked').value 14 | ) 15 | }, 1000) 16 | } 17 | 18 | document.addEventListener('DOMContentLoaded', function () { 19 | background.retrieve().then((data) => { 20 | document.querySelector('#regexes').value = data.regexes 21 | document.querySelector('input[name="mode"][value="' + data.mode + '"]').checked = true 22 | document.querySelector('input[name="debugging"][value="' + data.debug + '"]').checked = true 23 | }) 24 | }) 25 | 26 | document.querySelectorAll('input').forEach(el => el.addEventListener('change', autoSave)) 27 | document.querySelectorAll('textarea').forEach(el => el.addEventListener('keypress', autoSave)) 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firefox-simple-blocker", 3 | "version": "0.3.5", 4 | "main": "index.js", 5 | "repository": "git@github.com:eryw/firefox-simple-blocker.git", 6 | "author": "eryw ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "eslint-config-standard": "^10.2.1", 10 | "eslint-plugin-import": "^2.7.0", 11 | "eslint-plugin-node": "^5.1.1", 12 | "eslint-plugin-promise": "^3.5.0", 13 | "eslint-plugin-standard": "^3.0.1" 14 | }, 15 | "standard": { 16 | "globals": [ "browser" ] 17 | } 18 | } 19 | --------------------------------------------------------------------------------