initial work on popup, which lets the user know which related frames are loading script on the current page
This commit is contained in:
parent
8126e1a105
commit
f0424dcbdd
7 changed files with 135 additions and 19 deletions
85
background_scripts/bootstrap.js
vendored
85
background_scripts/bootstrap.js
vendored
|
@ -4,6 +4,7 @@
|
|||
|
||||
const {packingLib, standards, storageLib} = window.WEB_API_MANAGER;
|
||||
const rootObject = window.browser || window.chrome;
|
||||
const defaultKey = "(default)";
|
||||
|
||||
// Once loaded from storage, will be a mapping from regular expressions
|
||||
// (or the default option, "(default)"), to an array of standards
|
||||
|
@ -14,14 +15,42 @@
|
|||
domainRules = loadedDomainRules;
|
||||
});
|
||||
|
||||
rootObject.runtime.onMessage.addListener(function (request, sender, tab) {
|
||||
const [label, data] = request;
|
||||
// Listen for updates to the domain rules from the config page.
|
||||
if (label === "rulesUpdate") {
|
||||
domainRules = data;
|
||||
}
|
||||
});
|
||||
// Manage the state of the browser activity, by displaying the number
|
||||
// of origins / frames
|
||||
const updateBrowserActionBadge = function (activeInfo) {
|
||||
const {tabId, windowId} = activeInfo;
|
||||
rootObject.tabs.executeScript(
|
||||
tabId,
|
||||
{
|
||||
allFrames: true,
|
||||
code: "window.location.host"
|
||||
},
|
||||
function (allHosts) {
|
||||
|
||||
if (rootObject.runtime.lastError) {
|
||||
rootObject.browserAction.disable(tabId);
|
||||
return;
|
||||
}
|
||||
|
||||
rootObject.browserAction.enable(tabId);
|
||||
|
||||
const numFrames = allHosts
|
||||
? Array.from(new Set(allHosts)).length.toString()
|
||||
: "";
|
||||
|
||||
rootObject.browserAction.setBadgeText({
|
||||
text: numFrames,
|
||||
tabId: tabId
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
rootObject.tabs.onUpdated.addListener(updateBrowserActionBadge);
|
||||
rootObject.tabs.onActivated.addListener(updateBrowserActionBadge);
|
||||
rootObject.windows.onFocusChanged.addListener(updateBrowserActionBadge);
|
||||
|
||||
// Inject the blocking settings for each visited domain / frame.
|
||||
const extractHostFromUrl = function (url) {
|
||||
const uri = URI(url);
|
||||
return uri.hostname();
|
||||
|
@ -40,6 +69,37 @@
|
|||
return prev;
|
||||
};
|
||||
|
||||
const whichDomainRuleMatches = function (hostName) {
|
||||
// of the URL being requested.
|
||||
const matchingUrlReduceFunctionBound = matchingUrlReduceFunction.bind(undefined, hostName);
|
||||
const matchingPattern = Object
|
||||
.keys(domainRules)
|
||||
.filter((aRule) => aRule !== defaultKey)
|
||||
.sort()
|
||||
.reduce(matchingUrlReduceFunctionBound, undefined);
|
||||
|
||||
return matchingPattern || defaultKey;
|
||||
};
|
||||
|
||||
// Listen for updates to the domain rules from the config page.
|
||||
rootObject.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||
const [label, data] = request;
|
||||
if (label === "rulesUpdate") {
|
||||
domainRules = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (label === "rulesForDomains") {
|
||||
const ruleForDomain = data.map(whichDomainRuleMatches);
|
||||
const mapping = {};
|
||||
for (let i = 0; i < ruleForDomain.length; i += 1) {
|
||||
mapping[data[i]] = ruleForDomain[i];
|
||||
}
|
||||
sendResponse(mapping);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
const requestFilter = {
|
||||
urls: ["<all_urls>"],
|
||||
types: ["main_frame", "sub_frame"]
|
||||
|
@ -50,18 +110,11 @@
|
|||
|
||||
const url = details.url;
|
||||
const hostName = extractHostFromUrl(url);
|
||||
const defaultKey = "(default)";
|
||||
|
||||
// Decide which set of blocking rules to use, depending on the host
|
||||
// of the URL being requested.
|
||||
const matchingUrlReduceFunctionBound = matchingUrlReduceFunction.bind(undefined, hostName);
|
||||
const matchingPattern = Object
|
||||
.keys(domainRules)
|
||||
.filter((aRule) => aRule !== defaultKey)
|
||||
.sort()
|
||||
.reduce(matchingUrlReduceFunctionBound, undefined);
|
||||
|
||||
const standardsToBlock = domainRules[matchingPattern || defaultKey];
|
||||
const matchingDomainKey = whichDomainRuleMatches(hostName);
|
||||
const standardsToBlock = domainRules[matchingDomainKey];
|
||||
|
||||
const options = Object.keys(standards);
|
||||
const packedValues = packingLib.pack(options, standardsToBlock);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval'; object-src 'self'">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Web API Manager Configuration</title>
|
||||
|
|
BIN
images/uic-128.png
Normal file
BIN
images/uic-128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
images/uic-48.png
Normal file
BIN
images/uic-48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
|
@ -3,14 +3,21 @@
|
|||
"name": "WebAPI Manager",
|
||||
"version": "0.4",
|
||||
"description": "Improves browser security by restricting page access to parts of the Web API.",
|
||||
"icons": {
|
||||
"48": "images/uic-48.png",
|
||||
"128": "images/uic-128.png"
|
||||
},
|
||||
"browser_action": {
|
||||
"default_popup": "popup/popup.html"
|
||||
},
|
||||
"permissions": [
|
||||
"http://*/*", "https://*/*",
|
||||
"<all_urls>",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"webNavigation"
|
||||
"webNavigation",
|
||||
"activeTab"
|
||||
],
|
||||
"content_scripts": [
|
||||
{
|
||||
|
|
37
popup/js/example.js
Normal file
37
popup/js/example.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
(function () {
|
||||
const rootObject = window.browser || window.chrome;
|
||||
|
||||
rootObject.tabs.executeScript(
|
||||
{
|
||||
allFrames: true,
|
||||
code: "window.location.host"
|
||||
},
|
||||
function (response) {
|
||||
|
||||
const uniqueDomains = Array.from(new Set(response)).sort();
|
||||
const message = ["rulesForDomains", uniqueDomains];
|
||||
rootObject.runtime.sendMessage(message, function (response) {
|
||||
|
||||
const listGroupElm = document.querySelector("ul.list-group");
|
||||
const domainNames = Object.keys(response);
|
||||
|
||||
domainNames.forEach(function (aDomain) {
|
||||
const domainRule = response[aDomain];
|
||||
|
||||
const liElm = document.createElement("li");
|
||||
liElm.className = "list-group-item";
|
||||
|
||||
const spanElm = document.createElement("span");
|
||||
spanElm.className = "badge";
|
||||
const badgeText = document.createTextNode(domainRule);
|
||||
spanElm.appendChild(badgeText);
|
||||
liElm.appendChild(spanElm);
|
||||
|
||||
const textElm = document.createTextNode(aDomain);
|
||||
liElm.appendChild(textElm);
|
||||
listGroupElm.appendChild(liElm);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}());
|
20
popup/popup.html
Normal file
20
popup/popup.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Frame listing popup</title>
|
||||
<link href="../config/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="../config/css/bootstrap-theme.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<section>
|
||||
This page has loaded the followng frames…
|
||||
<ul class="list-group">
|
||||
</ul>
|
||||
</section>
|
||||
<script src="js/example.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in a new issue