This commit is contained in:
eson 2020-07-31 16:03:31 +08:00
commit b31b40fd9e
22 changed files with 602 additions and 0 deletions

View File

@ -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");

BIN
data/icons/128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
data/icons/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
data/icons/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
data/icons/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
data/icons/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
data/icons/OFF/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

BIN
data/icons/OFF/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

BIN
data/icons/OFF/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
data/icons/OFF/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
data/icons/ON/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
data/icons/ON/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
data/icons/ON/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
data/icons/ON/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

99
data/options/options.css Normal file
View File

@ -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;
}

79
data/options/options.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="options.css">
</head>
<body>
<div class="logo"></div>
<div class="toolbar">
<table>
<tr>
<td id="reload" title="Reload UI">
<svg height="10" width="10" viewBox="0 0 512 512">
<path d="M281.525,228.102l104.758-78.042 c12.082-12.085,12.082-24.259,0-36.342L281.525,35.674c-3.274-2.359-7.359-3.725-11.723-3.725c-10.992,0-19.803,8.536-19.803,19.083 v35.429C144.611,86.737,59.205,172.046,59.205,277.258c0,105.396,85.672,190.793,191.248,190.793 c98.03,0,178.809-73.498,189.977-168.169c0.092-0.275,0.367-3.187,0.367-4.455c0-9.992-8.181-18.169-18.261-18.169h-45.793 c-14.993,0-26.349,10.355-27.893,18.986c-8.811,46.156-49.519,80.954-98.397,80.954c-55.329,0-100.127-44.701-100.127-99.94 c0-55.064,44.523-99.667,99.674-99.941v35.437c0,10.541,8.811,19.076,19.803,19.076C274.166,231.83,278.251,230.471,281.525,228.102 z"/>
</svg>
</td>
</tr>
<tr>
<td id="support" title="Open support page">
<svg height="10" width="10" viewBox="0 0 1792 1792">
<path d="M1088 1256v240q0 16-12 28t-28 12h-240q-16 0-28-12t-12-28v-240q0-16 12-28t28-12h240q16 0 28 12t12 28zm316-600q0 54-15.5 101t-35 76.5-55 59.5-57.5 43.5-61 35.5q-41 23-68.5 65t-27.5 67q0 17-12 32.5t-28 15.5h-240q-15 0-25.5-18.5t-10.5-37.5v-45q0-83 65-156.5t143-108.5q59-27 84-56t25-76q0-42-46.5-74t-107.5-32q-65 0-108 29-35 25-107 115-13 16-31 16-12 0-25-8l-164-125q-13-10-15.5-25t5.5-28q160-266 464-266 80 0 161 31t146 83 106 127.5 41 158.5z"/>
</svg>
</td>
</tr>
<tr>
<td id="donation" title="Make a donation">
<svg height="10" width="10" viewBox="-0.709 -11.555 141.732 141.732">
<path d="M140.314,37.654C140.314,16.858,123.402,0,102.537,0c-13.744,0-25.77,7.317-32.379,18.255C63.549,7.317,51.521,0,37.777,0 C16.912,0,0,16.858,0,37.654c0,10.821,4.588,20.57,11.922,27.438h-0.01l54.084,51.584c0.992,1.188,2.48,1.945,4.148,1.945 c1.545,0,2.936-0.653,3.92-1.696l54.346-51.833h-0.016C135.729,58.225,140.314,48.476,140.314,37.654"/>
</svg>
</td>
</tr>
</table>
</div>
<div class="content">
<table>
<tr>
<td class="title">Mark desired item(s) to block from downloading or just hide</td>
<td class="check">block</td><td class="check">hide</td>
</tr>
<tr class="hl_1">
<td>1. Block | Hide images (hide or block images from downloading)</td>
<td class="check"><input id="b_image" type="checkbox"></td>
<td class="check bl"><input id="h_image" type="checkbox"></td>
</tr>
<tr class="hl_2">
<td>2. Hide all flash elements (flash, videos, games etc.)</td>
<td class="check"><input id="b_flash" type="checkbox" disabled></td>
<td class="check bl"><input id="h_flash" type="checkbox"></td>
</tr>
<tr class="hl_1">
<td>3. Hide all videos (HTML5 video)</td>
<td class="check"><input id="b_video" type="checkbox" disabled></td>
<td class="check bl"><input id="h_video" type="checkbox"></td>
</tr>
<tr class="hl_2">
<td>4. Hide all SVGs (icons, buttons, etc.)</td>
<td class="check"><input id="b_svg" type="checkbox" disabled></td>
<td class="check bl"><input id="h_svg" type="checkbox"></td>
</tr>
<tr class="hl_1">
<td>5. Hide all canvas elements (HTML5 canvas, games, etc.)</td>
<td class="check"><input id="b_canvas" type="checkbox" disabled></td>
<td class="check bl"><input id="h_canvas" type="checkbox"></td>
</tr>
<tr class="hl_2">
<td>6. Block | Hide all frames (HTML iframe)</td>
<td class="check"><input id="b_iframe" type="checkbox"></td>
<td class="check bl"><input id="h_iframe" type="checkbox"></td>
</tr>
<tr class="hl_1">
<td>7. Hide all elements with background-image</td>
<td class="check"><input id="b_background" type="checkbox" disabled></td>
<td class="check bl"><input id="h_background" type="checkbox"></td>
</tr>
</table>
</div>
<script type="text/javascript" src="options.js"></script>
</body>
</html>

52
data/options/options.js Normal file
View File

@ -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);

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<script src="../config.js"></script>
<script src="chrome.js"></script>
</body>
</html>

116
lib/chrome/chrome.js Normal file
View File

@ -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});
});
});
}
}
})();

77
lib/common.js Normal file
View File

@ -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())});

46
lib/config.js Normal file
View File

@ -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}
}
};

40
manifest.json Normal file
View File

@ -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"
}