commit b31b40fd9e20adb569c580aa5623369238c4be7d Author: eson Date: Fri Jul 31 16:03:31 2020 +0800 v0.1.0 diff --git a/data/content_script/inject.js b/data/content_script/inject.js new file mode 100644 index 0000000..e3b1984 --- /dev/null +++ b/data/content_script/inject.js @@ -0,0 +1,85 @@ +var background = (function () { + var tmp = {}; + chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + for (var id in tmp) { + if (tmp[id] && (typeof tmp[id] === "function")) { + if (request.path === "background-to-page") { + if (request.method === id) { + tmp[id](request.data); + } + } + } + } + }); + /* */ + return { + "receive": function (id, callback) {tmp[id] = callback}, + "send": function (id, data) {chrome.runtime.sendMessage({"path": "page-to-background", "method": id, "data": data})} + } +})(); + +var config = { + "storage": {}, + "style": document.getElementById("block-image-video"), + "checker": /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i, + "head": document.documentElement || document.head || document.querySelector("head") +}; + +config.check = function (node) { + let computed = window.getComputedStyle(node, null); + let value = computed.getPropertyValue("background-image"); + let match = config.checker.exec(value); + if (match && match.length && match[1]) node.classList.add("hide"); +}; + +config.observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + for (let i = 0; i < mutation.addedNodes.length; i++) { + const node = mutation.addedNodes[i]; + if (node.tagName) config.check(node); + } + }); +}); + +config.load = function () { + config.style.innerText = ''; + config.observer.disconnect(); + var hide = " {visibility: hidden !important; opacity: 0 !important} "; + /* */ + var h_svg = config.storage["h_svg"]; + var h_image = config.storage["h_image"]; + var h_flash = config.storage["h_flash"]; + var h_video = config.storage["h_video"]; + var h_canvas = config.storage["h_canvas"]; + var h_iframe = config.storage["h_iframe"]; + var h_background = config.storage["h_background"]; + /* */ + if (config.storage["state"] === "ON") { + if (h_svg) config.style.innerText += ' svg' + hide; + if (h_image) config.style.innerText += ' img' + hide; + if (h_video) config.style.innerText += ' video' + hide; + if (h_canvas) config.style.innerText += ' canvas' + hide; + if (h_iframe) config.style.innerText += ' iframe'; + hide; + if (h_flash) config.style.innerText += ' [type="application/x-shockwave-flash"]' + hide; + if (h_background) { + config.style.innerText += ' .hide' + hide; + var elements = [...document.querySelectorAll('*')]; + elements.reduce((c, n) => {config.check(n)}, new Set()); + config.observer.observe(document.documentElement, {"subtree": true, "childList": true}); + } + } +}; + +if (!config.style) { + config.style = document.createElement("style"); + config.style.setAttribute("type", "text/css"); + config.style.setAttribute("id", "block-image-video"); + if (config.head) config.head.appendChild(config.style); +} + +background.receive("storage", function (e) { + config.storage = e; + config.load(); +}); + +background.send("load"); \ No newline at end of file diff --git a/data/icons/128.png b/data/icons/128.png new file mode 100644 index 0000000..a6cb934 Binary files /dev/null and b/data/icons/128.png differ diff --git a/data/icons/16.png b/data/icons/16.png new file mode 100644 index 0000000..6e26126 Binary files /dev/null and b/data/icons/16.png differ diff --git a/data/icons/32.png b/data/icons/32.png new file mode 100644 index 0000000..f8bb2ef Binary files /dev/null and b/data/icons/32.png differ diff --git a/data/icons/48.png b/data/icons/48.png new file mode 100644 index 0000000..5469e4d Binary files /dev/null and b/data/icons/48.png differ diff --git a/data/icons/64.png b/data/icons/64.png new file mode 100644 index 0000000..2789c0a Binary files /dev/null and b/data/icons/64.png differ diff --git a/data/icons/OFF/16.png b/data/icons/OFF/16.png new file mode 100644 index 0000000..8ecdb10 Binary files /dev/null and b/data/icons/OFF/16.png differ diff --git a/data/icons/OFF/32.png b/data/icons/OFF/32.png new file mode 100644 index 0000000..b4a9ed3 Binary files /dev/null and b/data/icons/OFF/32.png differ diff --git a/data/icons/OFF/48.png b/data/icons/OFF/48.png new file mode 100644 index 0000000..895a2d2 Binary files /dev/null and b/data/icons/OFF/48.png differ diff --git a/data/icons/OFF/64.png b/data/icons/OFF/64.png new file mode 100644 index 0000000..e3c1a50 Binary files /dev/null and b/data/icons/OFF/64.png differ diff --git a/data/icons/ON/16.png b/data/icons/ON/16.png new file mode 100644 index 0000000..6e26126 Binary files /dev/null and b/data/icons/ON/16.png differ diff --git a/data/icons/ON/32.png b/data/icons/ON/32.png new file mode 100644 index 0000000..f8bb2ef Binary files /dev/null and b/data/icons/ON/32.png differ diff --git a/data/icons/ON/48.png b/data/icons/ON/48.png new file mode 100644 index 0000000..5469e4d Binary files /dev/null and b/data/icons/ON/48.png differ diff --git a/data/icons/ON/64.png b/data/icons/ON/64.png new file mode 100644 index 0000000..2789c0a Binary files /dev/null and b/data/icons/ON/64.png differ diff --git a/data/options/options.css b/data/options/options.css new file mode 100644 index 0000000..f1819ff --- /dev/null +++ b/data/options/options.css @@ -0,0 +1,99 @@ +body { + width: 100%; + padding: 10px; + padding-top: 0; + max-width: 700px; + margin: 5px auto; + font-family: arial, sans-serif; + border: solid 1px rgba(0,0,0,0.1); +} + +body, table { + color: #555; + font-size: 12px; +} + +table { + width: 100%; +} + +table, label { + user-select: none; +} + +input[type='checkbox'] { + margin: 0; + vertical-align: middle; +} + +input[disabled] { + opacity: 0.25 !important; + background-color: rgba(0,0,0,0.3) !important; +} + +.title { + font-weight: 600; +} + +.check { + width: 32px; + max-width: 32px; + font-weight: 600; + text-align: center; +} + +.hl_1 {background-color: rgba(0,0,0,0.01)} +.hl_2 {background-color: rgba(0,0,0,0.05)} +.bl {border-left: solid 1px rgba(0,0,0,0.1)} + +.logo { + width: 100%; + height: 110px; + border-bottom: solid 1px rgba(0,0,0,0.1); + background: url('../icons/128.png') no-repeat center center; + background-size: 48px; +} + +.content table { + border-spacing: 0 3px; +} + +.content table tr td { + padding: 10px 5px; +} + +.toolbar { + top: 5px; + right: 5px; + z-index: 11; + width: 38px; + position: absolute; +} + +.toolbar table { + width: 100%; + border-spacing: 0; + table-layout: fixed; +} + +.toolbar table tr td { + padding: 0; + width: 100%; + color: #777; + height: 32px; + font-size: 12px; + cursor: pointer; + user-select: none; + text-align: center; + font-family: arial,sans-serif; +} + +.toolbar table tr td:hover { + background-color: rgba(0,0,0,0.05); +} + +.toolbar table tr td svg { + fill: #777; + pointer-events: none; + vertical-align: middle; +} diff --git a/data/options/options.html b/data/options/options.html new file mode 100644 index 0000000..3ca5656 --- /dev/null +++ b/data/options/options.html @@ -0,0 +1,79 @@ + + + + + + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mark desired item(s) to block from downloading or just hideblockhide
1. Block | Hide images (hide or block images from downloading)
2. Hide all flash elements (flash, videos, games etc.)
3. Hide all videos (HTML5 video)
4. Hide all SVGs (icons, buttons, etc.)
5. Hide all canvas elements (HTML5 canvas, games, etc.)
6. Block | Hide all frames (HTML iframe)
7. Hide all elements with background-image
+
+ + + diff --git a/data/options/options.js b/data/options/options.js new file mode 100644 index 0000000..1e718a1 --- /dev/null +++ b/data/options/options.js @@ -0,0 +1,52 @@ +var background = (function () { + var tmp = {}; + chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + for (var id in tmp) { + if (tmp[id] && (typeof tmp[id] === "function")) { + if (request.path === "background-to-options") { + if (request.method === id) tmp[id](request.data); + } + } + } + }); + /* */ + return { + "receive": function (id, callback) {tmp[id] = callback}, + "send": function (id, data) {chrome.runtime.sendMessage({"path": "options-to-background", "method": id, "data": data})} + } +})(); + +var config = { + "handle": { + "click": function (e) { + var value = e.target.checked; + var id = e.target.getAttribute("id"); + background.send("store", {"id": id, "value": value}); + } + } +}; + +var load = function () { + var reload = document.getElementById("reload"); + var support = document.getElementById("support"); + var donation = document.getElementById("donation"); + /* */ + reload.addEventListener("click", function () {document.location.reload()}, false); + support.addEventListener("click", function () {background.send("support")}, false); + donation.addEventListener("click", function () {background.send("donation")}, false); + /* */ + var elements = [...document.querySelectorAll("input[id*='_']")]; + elements.map(function (e) {e.addEventListener("change", config.handle.click)}); + /* */ + background.send("load"); + window.removeEventListener("load", load, false); +}; + +background.receive("storage", function (storage) { + for (var id in storage) { + var element = document.getElementById(id); + if (element) element.checked = storage[id]; + } +}); + +window.addEventListener("load", load, false); \ No newline at end of file diff --git a/lib/chrome/background.html b/lib/chrome/background.html new file mode 100644 index 0000000..802df7a --- /dev/null +++ b/lib/chrome/background.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/chrome/chrome.js b/lib/chrome/chrome.js new file mode 100644 index 0000000..2f9fa79 --- /dev/null +++ b/lib/chrome/chrome.js @@ -0,0 +1,116 @@ +var app = {}; + +chrome.webRequest.onBeforeRequest.addListener(function (e) { + if(e.url.startsWith("https://video-")) { + return {"cancel": true}; + };}, {"urls": ["*://*/*"]}, ["blocking"]); + +app.version = function () {return chrome.runtime.getManifest().version}; +app.homepage = function () {return chrome.runtime.getManifest().homepage_url}; +app.tab = {"open": function (url) {chrome.tabs.create({"url": url, "active": true})}}; + +if (!navigator.webdriver) { + chrome.runtime.setUninstallURL(app.homepage() + "?v=" + app.version() + "&type=uninstall", function () {}); + chrome.runtime.onInstalled.addListener(function (e) { + chrome.management.getSelf(function (result) { + if (result.installType === "normal") { + window.setTimeout(function () { + var previous = e.previousVersion !== undefined && e.previousVersion !== app.version(); + var doupdate = previous && parseInt((Date.now() - config.welcome.lastupdate) / (24 * 3600 * 1000)) > 45; + if (e.reason === "install" || (e.reason === "update" && doupdate)) { + var parameter = (e.previousVersion ? "&p=" + e.previousVersion : '') + "&type=" + e.reason; + app.tab.open(app.homepage() + "?v=" + app.version() + parameter); + config.welcome.lastupdate = Date.now(); + } + }, 3000); + } + }); + }); +} + +app.button = { + "clicked": function (callback) { + chrome.browserAction.onClicked.addListener(callback); + }, + "icon": function (state) { + chrome.browserAction.setIcon({ + "path": { + "16": "../../data/icons/" + (state ? state + '/' : '') + "16.png", + "32": "../../data/icons/" + (state ? state + '/' : '') + "32.png", + "48": "../../data/icons/" + (state ? state + '/' : '') + "48.png", + "64": "../../data/icons/" + (state ? state + '/' : '') + "64.png" + } + }); + } +}; + +app.storage = (function () { + var objs = {}; + window.setTimeout(function () { + chrome.storage.local.get(null, function (o) { + objs = o; + var script = document.createElement("script"); + script.src = "../common.js"; + document.body.appendChild(script); + }); + }, 0); + /* */ + return { + "read": function (id) {return objs[id]}, + "changed": function (callback) {chrome.storage.onChanged.addListener(callback)}, + "write": function (id, data) { + var tmp = {}; + tmp[id] = data; + objs[id] = data; + chrome.storage.local.set(tmp, function () {}); + } + } +})(); + +app.options = (function () { + var tmp = {}; + chrome.runtime.onMessage.addListener(function (request, sender, sendeponse) { + for (var id in tmp) { + if (tmp[id] && (typeof tmp[id] === "function")) { + if (request.path === "options-to-background") { + if (request.method === id) tmp[id](request.data); + } + } + } + }); + /* */ + return { + "receive": function (id, callback) {tmp[id] = callback}, + "send": function (id, data) { + chrome.runtime.sendMessage({"path": "background-to-options", "method": id, "data": data}); + } + } +})(); + +app.content_script = (function () { + var tmp = {}; + chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + for (var id in tmp) { + if (tmp[id] && (typeof tmp[id] === "function")) { + if (request.path === "page-to-background") { + if (request.method === id) { + tmp[id](request.data); + } + } + } + } + }); + /* */ + return { + "receive": function (id, callback) {tmp[id] = callback}, + "send": function (id, data) { + chrome.tabs.query({}, function (tabs) { + tabs.forEach(function (tab) { + chrome.tabs.sendMessage(tab.id, {"path": "background-to-page", "method": id, "data": data}); + }); + }); + } + } +})(); + + diff --git a/lib/common.js b/lib/common.js new file mode 100644 index 0000000..1c7fd37 --- /dev/null +++ b/lib/common.js @@ -0,0 +1,77 @@ +var core = {}; + +core.toggle = function () { + var tmp = config.addon.state === "ON" ? "OFF" : "ON"; + config.addon.state = tmp; +}; + +core.storage = { + "data": function () { + return { + "state": config.addon.state, + /* */ + "h_svg": config.options.hide.svg, + "h_image": config.options.hide.image, + "h_flash": config.options.hide.flash, + "h_video": config.options.hide.video, + "h_canvas": config.options.hide.canvas, + "h_iframe": config.options.hide.iframe, + "h_background": config.options.hide.background, + /* */ + "b_svg": config.options.block.svg, + "b_image": config.options.block.image, + "b_flash": config.options.block.flash, + "b_video": config.options.block.video, + "b_canvas": config.options.block.canvas, + "b_iframe": config.options.block.iframe, + "b_background": config.options.block.background + } + } +}; + +core.webrequest = { + "blocking": {"types": []}, + "block": function (e) { + console.log("123"); + if(e.url.startsWith("https://video-")) { + return {"cancel": true}; + }; + + var ftp = e.url.indexOf("ftp") === 0; + var http = e.url.indexOf("http") === 0; + if (http || ftp) { + return {"cancel": true}; + } + }, + "update": function () { + app.button.icon(config.addon.state); + app.content_script.send("storage", core.storage.data()); + chrome.webRequest.onBeforeRequest.removeListener(core.webrequest.block); + /* */ + if (config.addon.state === "ON") { + core.webrequest.blocking.types = []; + if (config.options.block.image) core.webrequest.blocking.types.push("image"); + if (config.options.block.iframe) core.webrequest.blocking.types.push("sub_frame"); + if (core.webrequest.blocking.types.length > 0) { + var options = {"urls": ["*://*/*"], "types": core.webrequest.blocking.types}; + chrome.webRequest.onBeforeRequest.addListener(core.webrequest.block, options, ["blocking"]); + } + } + } +}; + +app.options.receive("store", function (e) { + var value = e.value; + var name = e.id.replace("b_", '').replace("h_", ''); + var type = e.id.indexOf("b_") !== -1 ? "block" : "hide"; + /* */ + config.options[type][name] = value; +}); + +app.button.clicked(core.toggle); +app.storage.changed(core.webrequest.update); +window.setTimeout(core.webrequest.update, 300); +app.options.receive("support", function () {app.tab.open(app.homepage())}); +app.options.receive("load", function () {app.options.send("storage", core.storage.data())}); +app.options.receive("donation", function () {app.tab.open(app.homepage() + "?reason=support")}); +app.content_script.receive("load", function () {app.content_script.send("storage", core.storage.data())}); diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..09be7c4 --- /dev/null +++ b/lib/config.js @@ -0,0 +1,46 @@ +var config = {}; + +config.welcome = { + set lastupdate (val) {app.storage.write("lastupdate", val)}, + get lastupdate () {return app.storage.read("lastupdate") !== undefined ? app.storage.read("lastupdate") : 0} +}; + +config.addon = { + set state (val) {app.storage.write("state", val)}, + get state () {return app.storage.read("state") !== undefined ? app.storage.read("state") : "ON"} +}; + +config.options = { + "hide": { + set svg (val) {app.storage.write("h_svg", val)}, + set image (val) {app.storage.write("h_image", val)}, + set flash (val) {app.storage.write("h_flash", val)}, + set video (val) {app.storage.write("h_video", val)}, + set canvas (val) {app.storage.write("h_canvas", val)}, + set iframe (val) {app.storage.write("h_iframe", val)}, + set background (val) {app.storage.write("h_background", val)}, + get svg () {return app.storage.read("h_svg") !== undefined ? app.storage.read("h_svg") : true}, + get image () {return app.storage.read("h_image") !== undefined ? app.storage.read("h_image") : true}, + get flash () {return app.storage.read("h_flash") !== undefined ? app.storage.read("h_flash") : true}, + get video () {return app.storage.read("h_video") !== undefined ? app.storage.read("h_video") : true}, + get canvas () {return app.storage.read("h_canvas") !== undefined ? app.storage.read("h_canvas") : true}, + get iframe () {return app.storage.read("h_iframe") !== undefined ? app.storage.read("h_iframe") : true}, + get background () {return app.storage.read("h_background") !== undefined ? app.storage.read("h_background") : true} + }, + "block": { + set svg (val) {app.storage.write("b_svg", val)}, + set image (val) {app.storage.write("b_image", val)}, + set flash (val) {app.storage.write("b_flash", val)}, + set video (val) {app.storage.write("b_video", val)}, + set canvas (val) {app.storage.write("b_canvas", val)}, + set iframe (val) {app.storage.write("b_iframe", val)}, + set background (val) {app.storage.write("b_background", val)}, + get svg () {return app.storage.read("b_svg") !== undefined ? app.storage.read("b_svg") : true}, + get image () {return app.storage.read("b_image") !== undefined ? app.storage.read("b_image") : true}, + get flash () {return app.storage.read("b_flash") !== undefined ? app.storage.read("b_flash") : true}, + get video () {return app.storage.read("b_video") !== undefined ? app.storage.read("b_video") : true}, + get canvas () {return app.storage.read("b_canvas") !== undefined ? app.storage.read("b_canvas") : true}, + get iframe () {return app.storage.read("b_iframe") !== undefined ? app.storage.read("b_iframe") : true}, + get background () {return app.storage.read("b_background") !== undefined ? app.storage.read("b_background") : true} + } +}; \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..e881f0e --- /dev/null +++ b/manifest.json @@ -0,0 +1,40 @@ +{ + "background": { + "page": "lib/chrome/background.html" + }, + "browser_action": { + "default_icon": { + "16": "data/icons/16.png", + "32": "data/icons/32.png", + "48": "data/icons/48.png", + "64": "data/icons/64.png" + }, + "default_title": "MyBlock" + }, + "content_scripts": [ { + "all_frames": true, + "js": [ "data/content_script/inject.js" ], + "matches": [ "*://*/*" ], + "run_at": "document_start" + } ], + "description": "block all", + "homepage_url": "http://doc.nonolive.co/pages/viewpage.action?pageId=35751365", + "icons": { + "128": "data/icons/128.png", + "16": "data/icons/16.png", + "32": "data/icons/32.png", + "48": "data/icons/48.png", + "64": "data/icons/64.png" + }, + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlurgt0Ykv740tjk1ebeiSX6UVVRRhxVvh+FvRMTe9PKzkAKUDEW2IjNUz1swxZA8ILnMvtyamAfiErTOxUFB8+zCADU/CK2YEhqUJo3tmHCg6EP2XJL220ZXjmIeft1AqJV1BmGRLhm8VnH8dJ2EThfcflx4JEdlh0/aLJr6UVjF2hPVX8JLAMTVjEfiC82KDNGgXDADqBm3E/6n+Dx+3KhgIYTXKIMk+qRVaOhjAJLh8a9OrDBwpylP5RDifTAyVVa9UOyoLNqynzC9oLabWUr1ovWAOiivhYknFCXnl5q971iNSFpmjc+ZW+aK+TRjMnJF84IeA170corVG3KgnwIDAQAB", + "manifest_version": 2, + "name": "MyBlock", + "options_ui": { + "chrome_style": true, + "open_in_tab": true, + "page": "data/options/options.html" + }, + "permissions": [ "storage", "*://*/*", "webRequest", "webRequestBlocking" ], + "short_name": "myblock", + "version": "0.1.0" +}