lots of JSlint based cleanup
This commit is contained in:
parent
463b9a10b4
commit
b8d2eaeca0
14 changed files with 138 additions and 95 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,4 +2,5 @@ node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
content_scripts/dist/*.js
|
content_scripts/dist/*.js
|
||||||
|
web-ext-artifacts/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
Web API Manager
|
Web API Manager
|
||||||
===
|
===
|
||||||
|
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
---
|
---
|
||||||
This extension allows users to selectively allow different hosts on the web
|
This extension allows users to selectively allow different hosts on the web
|
||||||
|
@ -9,6 +10,7 @@ security and privacy sensitive web users to limit the attack surface presented
|
||||||
to websites, and to limit websites to the functionality they actually need
|
to websites, and to limit websites to the functionality they actually need
|
||||||
to carry out user-serving purposes.
|
to carry out user-serving purposes.
|
||||||
|
|
||||||
|
|
||||||
Background
|
Background
|
||||||
---
|
---
|
||||||
Web browsers gain staggering numbers of new features, without their users
|
Web browsers gain staggering numbers of new features, without their users
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true*/
|
||||||
/*global chrome, browser, window, URI*/
|
/*global window*/
|
||||||
(function () {
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
const {packingLib, standards, storageLib} = window.WEB_API_MANAGER;
|
const {packingLib, standards, storageLib, domainMatcherLib} = window.WEB_API_MANAGER;
|
||||||
const rootObject = window.browser || window.chrome;
|
const rootObject = window.browser || window.chrome;
|
||||||
const defaultKey = "(default)";
|
const defaultKey = "(default)";
|
||||||
|
|
||||||
|
@ -11,6 +12,9 @@
|
||||||
// that should be blocked on matching domains.
|
// that should be blocked on matching domains.
|
||||||
let domainRules;
|
let domainRules;
|
||||||
|
|
||||||
|
// The extension depends on this fetch happening before the DOM on any
|
||||||
|
// pages is loaded. The Chrome and Firefox docs *do not* promise this,
|
||||||
|
// but in testing this is always the case.
|
||||||
storageLib.get(function (loadedDomainRules) {
|
storageLib.get(function (loadedDomainRules) {
|
||||||
domainRules = loadedDomainRules;
|
domainRules = loadedDomainRules;
|
||||||
});
|
});
|
||||||
|
@ -18,7 +22,7 @@
|
||||||
// Manage the state of the browser activity, by displaying the number
|
// Manage the state of the browser activity, by displaying the number
|
||||||
// of origins / frames
|
// of origins / frames
|
||||||
const updateBrowserActionBadge = function (activeInfo) {
|
const updateBrowserActionBadge = function (activeInfo) {
|
||||||
const {tabId, windowId} = activeInfo;
|
const tabId = activeInfo.tabId;
|
||||||
rootObject.tabs.executeScript(
|
rootObject.tabs.executeScript(
|
||||||
tabId,
|
tabId,
|
||||||
{
|
{
|
||||||
|
@ -50,39 +54,8 @@
|
||||||
rootObject.tabs.onActivated.addListener(updateBrowserActionBadge);
|
rootObject.tabs.onActivated.addListener(updateBrowserActionBadge);
|
||||||
rootObject.windows.onFocusChanged.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();
|
|
||||||
};
|
|
||||||
|
|
||||||
const matchingUrlReduceFunction = function (domain, prev, next) {
|
|
||||||
if (prev) {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
const domainRegex = new RegExp(next);
|
|
||||||
if (domainRegex.test(domain)) {
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
// Listen for updates to the domain rules from the config page.
|
||||||
rootObject.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
rootObject.runtime.onMessage.addListener(function (request, ignore, sendResponse) {
|
||||||
const [label, data] = request;
|
const [label, data] = request;
|
||||||
if (label === "rulesUpdate") {
|
if (label === "rulesUpdate") {
|
||||||
domainRules = data;
|
domainRules = data;
|
||||||
|
@ -90,12 +63,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label === "rulesForDomains") {
|
if (label === "rulesForDomains") {
|
||||||
const ruleForDomain = data.map(whichDomainRuleMatches);
|
|
||||||
const mapping = {};
|
const matchHostNameBound = domainMatcherLib.matchHostName.bind(undefined, Object.keys(domainRules));
|
||||||
for (let i = 0; i < ruleForDomain.length; i += 1) {
|
const rulesForDomains = data.map(matchHostNameBound);
|
||||||
mapping[data[i]] = ruleForDomain[i];
|
const domainToRuleMapping = {};
|
||||||
}
|
|
||||||
sendResponse(mapping);
|
data.forEach(function (aHostName, index) {
|
||||||
|
domainToRuleMapping[aHostName] = rulesForDomains[index] || defaultKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
sendResponse(domainToRuleMapping);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -106,15 +83,15 @@
|
||||||
};
|
};
|
||||||
const requestOptions = ["blocking", "responseHeaders"];
|
const requestOptions = ["blocking", "responseHeaders"];
|
||||||
|
|
||||||
chrome.webRequest.onHeadersReceived.addListener(function (details) {
|
// Inject the blocking settings for each visited domain / frame.
|
||||||
|
rootObject.webRequest.onHeadersReceived.addListener(function (details) {
|
||||||
|
|
||||||
const url = details.url;
|
const url = details.url;
|
||||||
const hostName = extractHostFromUrl(url);
|
|
||||||
|
|
||||||
// Decide which set of blocking rules to use, depending on the host
|
// Decide which set of blocking rules to use, depending on the host
|
||||||
// of the URL being requested.
|
// of the URL being requested.
|
||||||
const matchingDomainKey = whichDomainRuleMatches(hostName);
|
const matchingDomainRule = domainMatcherLib.matchUrl(Object.keys(domainRules), url);
|
||||||
const standardsToBlock = domainRules[matchingDomainKey];
|
const standardsToBlock = domainRules[matchingDomainRule || defaultKey];
|
||||||
|
|
||||||
const options = Object.keys(standards);
|
const options = Object.keys(standards);
|
||||||
const packedValues = packingLib.pack(options, standardsToBlock);
|
const packedValues = packingLib.pack(options, standardsToBlock);
|
||||||
|
@ -129,4 +106,4 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
}, requestFilter, requestOptions);
|
}, requestFilter, requestOptions);
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<script src="../lib/init.js"></script>
|
<script src="../lib/init.js"></script>
|
||||||
<script src="../lib/storage.js"></script>
|
|
||||||
<script src="../content_scripts/dist/defaults.js"></script>
|
<script src="../content_scripts/dist/defaults.js"></script>
|
||||||
<script src="../content_scripts/dist/standards.js"></script>
|
<script src="../content_scripts/dist/standards.js"></script>
|
||||||
|
<script src="../lib/storage.js"></script>
|
||||||
<script src="js/lib/vue.js"></script>
|
<script src="js/lib/vue.js"></script>
|
||||||
<script src="js/state.js"></script>
|
<script src="js/state.js"></script>
|
||||||
<script src="js/components/domain-rules.vue.js"></script>
|
<script src="js/components/domain-rules.vue.js"></script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true, this: true*/
|
||||||
/*global window, browser, Vue*/
|
/*global window, Vue*/
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
@ -65,6 +65,6 @@
|
||||||
isDefault: function (domainName) {
|
isDefault: function (domainName) {
|
||||||
return domainName === "(default)";
|
return domainName === "(default)";
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}());
|
}());
|
|
@ -1,6 +1,7 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true, this: true*/
|
||||||
/*global window, browser, Vue*/
|
/*global window, Vue*/
|
||||||
(function () {
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
const standardsDefaults = window.WEB_API_MANAGER.defaults;
|
const standardsDefaults = window.WEB_API_MANAGER.defaults;
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,15 @@
|
||||||
const rootObject = (window.browser || window.chrome);
|
const rootObject = (window.browser || window.chrome);
|
||||||
const doc = window.document;
|
const doc = window.document;
|
||||||
const standards = window.WEB_API_MANAGER.standards;
|
const standards = window.WEB_API_MANAGER.standards;
|
||||||
const defaultConservativeRules = window.WEB_API_MANAGER.defaults.conservative;
|
|
||||||
const {storageLib, stateLib} = window.WEB_API_MANAGER;
|
const {storageLib, stateLib} = window.WEB_API_MANAGER;
|
||||||
const defaultDomain = "(default)";
|
const defaultDomain = "(default)";
|
||||||
|
|
||||||
const state = stateLib.generateStateObject(defaultDomain, standards);
|
const state = stateLib.generateStateObject(defaultDomain, standards);
|
||||||
|
|
||||||
const onSettingsLoaded = function (settingsResults) {
|
const onSettingsLoaded = function (loadedDomainRules) {
|
||||||
|
|
||||||
let loadedDomainRules;
|
|
||||||
|
|
||||||
if (Object.keys(settingsResults).length !== 0) {
|
|
||||||
loadedDomainRules = settingsResults;
|
|
||||||
} else {
|
|
||||||
loadedDomainRules = Object.create(null);
|
|
||||||
loadedDomainRules[defaultDomain] = defaultConservativeRules;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.setDomainRules(loadedDomainRules);
|
state.setDomainRules(loadedDomainRules);
|
||||||
|
|
||||||
const vm = new Vue({
|
const vm = new Vue({
|
||||||
el: doc.body,
|
el: doc.body,
|
||||||
data: state
|
data: state
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true, this: true*/
|
||||||
/*global window, browser, Vue*/
|
/*global window, browser, Vue*/
|
||||||
(function () {
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
window.WEB_API_MANAGER.stateLib = {};
|
window.WEB_API_MANAGER.stateLib = {};
|
||||||
|
|
||||||
|
@ -12,27 +13,27 @@
|
||||||
domainRules: {},
|
domainRules: {},
|
||||||
domainNames: [],
|
domainNames: [],
|
||||||
selectedStandards: [],
|
selectedStandards: [],
|
||||||
|
|
||||||
setDomainRules: function (newDomainRules) {
|
setDomainRules: function (newDomainRules) {
|
||||||
this.domainRules = newDomainRules;
|
this.domainRules = newDomainRules;
|
||||||
this.domainNames = Object.keys(newDomainRules);
|
this.domainNames = Object.keys(newDomainRules);
|
||||||
this.selectedStandards = this.domainRules[this.selectedDomain];
|
this.selectedStandards = this.domainRules[this.selectedDomain];
|
||||||
},
|
},
|
||||||
|
|
||||||
setSelectedDomain: function (newDomain) {
|
setSelectedDomain: function (newDomain) {
|
||||||
this.selectedDomain = newDomain;
|
this.selectedDomain = newDomain;
|
||||||
this.selectedStandards = this.domainRules[newDomain];
|
this.selectedStandards = this.domainRules[newDomain];
|
||||||
},
|
},
|
||||||
|
|
||||||
setSelectedStandards: function (selectedStandards) {
|
setSelectedStandards: function (selectedStandards) {
|
||||||
this.selectedStandards = selectedStandards;
|
this.selectedStandards = selectedStandards;
|
||||||
this.domainRules[this.selectedDomain] = selectedStandards;
|
this.domainRules[this.selectedDomain] = selectedStandards;
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteDomainRule: function (domainToDelete) {
|
deleteDomainRule: function (domainToDelete) {
|
||||||
delete this.domainRules[domainToDelete];
|
delete this.domainRules[domainToDelete];
|
||||||
this.domainNames = Object.keys(this.domainRules);
|
this.domainNames = Object.keys(this.domainRules);
|
||||||
|
|
||||||
// If we're deleted the domain thats currently selected, then
|
// If we're deleted the domain thats currently selected, then
|
||||||
// select the default domain.
|
// select the default domain.
|
||||||
if (this.selectedDomain === domainToDelete) {
|
if (this.selectedDomain === domainToDelete) {
|
||||||
|
|
46
lib/domainmatcher.js
Normal file
46
lib/domainmatcher.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*jslint es6: true*/
|
||||||
|
/*global window*/
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
const defaultKey = "(default)";
|
||||||
|
|
||||||
|
const extractHostNameFromUrl = function (url) {
|
||||||
|
const uri = window.URI(url);
|
||||||
|
return uri.hostname();
|
||||||
|
};
|
||||||
|
|
||||||
|
const matchingUrlReduceFunction = function (hostName, prev, next) {
|
||||||
|
if (prev) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
const domainRegex = new RegExp(next);
|
||||||
|
if (domainRegex.test(hostName)) {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
const matchHostName = function (domainRegExes, hostName) {
|
||||||
|
// of the URL being requested.
|
||||||
|
const matchingUrlReduceFunctionBound = matchingUrlReduceFunction.bind(undefined, hostName);
|
||||||
|
const matchingPattern = domainRegExes
|
||||||
|
.filter((aRule) => aRule !== defaultKey)
|
||||||
|
.sort()
|
||||||
|
.reduce(matchingUrlReduceFunctionBound, undefined);
|
||||||
|
|
||||||
|
return matchingPattern || undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const matchUrl = function (domainRegExes, url) {
|
||||||
|
const hostName = extractHostNameFromUrl(url);
|
||||||
|
return matchHostName(domainRegExes, hostName);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.WEB_API_MANAGER.domainMatcherLib = {
|
||||||
|
matchHostName,
|
||||||
|
matchUrl
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
|
@ -1,3 +1,7 @@
|
||||||
|
/*global window*/
|
||||||
// Initial content script for the Web API manager extension, that creates
|
// Initial content script for the Web API manager extension, that creates
|
||||||
// the "namespace" we'll use for all the content scripts in the extension.
|
// the "namespace" we'll use for all the content scripts in the extension.
|
||||||
window.WEB_API_MANAGER = {};
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
window.WEB_API_MANAGER = {};
|
||||||
|
}());
|
||||||
|
|
21
lib/pack.js
21
lib/pack.js
|
@ -1,8 +1,9 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true, for: true, bitwise: true*/
|
||||||
/*global window*/
|
/*global window*/
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const {btoa, atob} = window;
|
||||||
const bucketSize = 8;
|
const bucketSize = 8;
|
||||||
|
|
||||||
const bufferToBase64 = function (buf) {
|
const bufferToBase64 = function (buf) {
|
||||||
|
@ -16,7 +17,7 @@
|
||||||
const binstr = atob(base64);
|
const binstr = atob(base64);
|
||||||
const buf = new Uint8Array(binstr.length);
|
const buf = new Uint8Array(binstr.length);
|
||||||
Array.prototype.forEach.call(binstr, function (ch, i) {
|
Array.prototype.forEach.call(binstr, function (ch, i) {
|
||||||
buf[i] = ch.charCodeAt(0);
|
buf[i] = ch.charCodeAt(0);
|
||||||
});
|
});
|
||||||
return buf;
|
return buf;
|
||||||
};
|
};
|
||||||
|
@ -47,11 +48,13 @@
|
||||||
const binnedOptions = options.reduce(binToBucketSizeFunc, []);
|
const binnedOptions = options.reduce(binToBucketSizeFunc, []);
|
||||||
const bitFields = new Uint8Array(numBuckets);
|
const bitFields = new Uint8Array(numBuckets);
|
||||||
|
|
||||||
for (let i = 0; i < numBuckets; i += 1) {
|
let i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < numBuckets; i += 1) {
|
||||||
let bitfield = 0;
|
let bitfield = 0;
|
||||||
let currentBucket = binnedOptions[i];
|
let currentBucket = binnedOptions[i];
|
||||||
|
|
||||||
for (let j = 0; j < currentBucket.length; j += 1) {
|
for (j = 0; j < currentBucket.length; j += 1) {
|
||||||
|
|
||||||
let currentOption = currentBucket[j];
|
let currentOption = currentBucket[j];
|
||||||
if (selected.indexOf(currentOption) !== -1) {
|
if (selected.indexOf(currentOption) !== -1) {
|
||||||
|
@ -68,7 +71,6 @@
|
||||||
|
|
||||||
const unpack = function (options, data) {
|
const unpack = function (options, data) {
|
||||||
|
|
||||||
const numBuckets = Math.ceil(options.length / bucketSize);
|
|
||||||
const binToBucketSizeFunc = binOptionsReduceFunction.bind(undefined, bucketSize);
|
const binToBucketSizeFunc = binOptionsReduceFunction.bind(undefined, bucketSize);
|
||||||
options.sort();
|
options.sort();
|
||||||
|
|
||||||
|
@ -77,11 +79,13 @@
|
||||||
|
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (let i = 0; i < bitFields.length; i += 1) {
|
let i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < bitFields.length; i += 1) {
|
||||||
let currentBitField = bitFields[i];
|
let currentBitField = bitFields[i];
|
||||||
let currentOptionsBin = binnedOptions[i];
|
let currentOptionsBin = binnedOptions[i];
|
||||||
|
|
||||||
for (let j = 0; j < bucketSize; j += 1) {
|
for (j = 0; j < bucketSize; j += 1) {
|
||||||
if (currentBitField & (1 << j)) {
|
if (currentBitField & (1 << j)) {
|
||||||
let currentOption = currentOptionsBin[j];
|
let currentOption = currentOptionsBin[j];
|
||||||
result.push(currentOption);
|
result.push(currentOption);
|
||||||
|
@ -93,6 +97,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
window.WEB_API_MANAGER.packingLib = {
|
window.WEB_API_MANAGER.packingLib = {
|
||||||
pack, unpack
|
pack,
|
||||||
|
unpack
|
||||||
};
|
};
|
||||||
}());
|
}());
|
|
@ -3,13 +3,25 @@
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const browserObj = window.browser || window.chrome;
|
const rootObject = window.browser || window.chrome;
|
||||||
|
const defaultConservativeRules = window.WEB_API_MANAGER.defaults.conservative;
|
||||||
const webApiManagerKeySettingsKey = "webApiManagerDomainRules";
|
const webApiManagerKeySettingsKey = "webApiManagerDomainRules";
|
||||||
const storageObject = browserObj.storage;
|
const storageObject = rootObject.storage;
|
||||||
|
|
||||||
const get = function (callback) {
|
const get = function (callback) {
|
||||||
storageObject.local.get(webApiManagerKeySettingsKey, function (results) {
|
storageObject.local.get(webApiManagerKeySettingsKey, function (results) {
|
||||||
callback(results && results[webApiManagerKeySettingsKey]);
|
|
||||||
|
let loadedDomainRules = results && results[webApiManagerKeySettingsKey];
|
||||||
|
|
||||||
|
// If there are no currently saved domain rules, then create
|
||||||
|
// a stubbed out one, using the conservative blocking rule set.
|
||||||
|
if (!loadedDomainRules || Object.keys(loadedDomainRules).length === 0) {
|
||||||
|
loadedDomainRules = {
|
||||||
|
"(default)": defaultConservativeRules
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(loadedDomainRules);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "WebAPI Manager",
|
"name": "WebAPI Manager",
|
||||||
"version": "0.5",
|
"version": "0.7",
|
||||||
"description": "Improves browser security by restricting page access to parts of the Web API.",
|
"description": "Improves browser security by restricting page access to parts of the Web API.",
|
||||||
"icons": {
|
"icons": {
|
||||||
"48": "images/uic-48.png",
|
"48": "images/uic-48.png",
|
||||||
|
@ -37,20 +37,21 @@
|
||||||
"lib/init.js",
|
"lib/init.js",
|
||||||
"lib/js.cookie.js",
|
"lib/js.cookie.js",
|
||||||
"lib/storage.js",
|
"lib/storage.js",
|
||||||
"lib/URI.js"
|
"lib/URI.js",
|
||||||
|
"content_scripts/dist/defaults.js"
|
||||||
],
|
],
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"lib/init.js",
|
"lib/init.js",
|
||||||
"lib/pack.js",
|
"lib/pack.js",
|
||||||
"lib/storage.js",
|
|
||||||
"lib/URI.js",
|
"lib/URI.js",
|
||||||
"content_scripts/dist/standards.js",
|
"content_scripts/dist/standards.js",
|
||||||
|
"content_scripts/dist/defaults.js",
|
||||||
|
"lib/storage.js",
|
||||||
"background_scripts/background.js"
|
"background_scripts/background.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "config/index.html",
|
"page": "config/index.html"
|
||||||
"chrome_style": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
/*jslint es6: true*/
|
/*jslint es6: true*/
|
||||||
/*global window*/
|
/*global window*/
|
||||||
(function () {
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
const rootObject = window.browser || window.chrome;
|
const rootObject = window.browser || window.chrome;
|
||||||
const configureButton = window.document.getElementById("config-page-link");
|
const doc = window.document;
|
||||||
|
const configureButton = doc.getElementById("config-page-link");
|
||||||
|
|
||||||
configureButton.addEventListener("click", function (event) {
|
configureButton.addEventListener("click", function (event) {
|
||||||
rootObject.runtime.openOptionsPage();
|
rootObject.runtime.openOptionsPage();
|
||||||
|
@ -21,26 +24,26 @@
|
||||||
const message = ["rulesForDomains", uniqueDomains];
|
const message = ["rulesForDomains", uniqueDomains];
|
||||||
rootObject.runtime.sendMessage(message, function (response) {
|
rootObject.runtime.sendMessage(message, function (response) {
|
||||||
|
|
||||||
const listGroupElm = document.querySelector("ul.list-group");
|
const listGroupElm = doc.querySelector("ul.list-group");
|
||||||
const domainNames = Object.keys(response);
|
const domainNames = Object.keys(response);
|
||||||
|
|
||||||
domainNames.forEach(function (aDomain) {
|
domainNames.forEach(function (aDomain) {
|
||||||
const domainRule = response[aDomain];
|
const domainRule = response[aDomain];
|
||||||
|
|
||||||
const liElm = document.createElement("li");
|
const liElm = doc.createElement("li");
|
||||||
liElm.className = "list-group-item";
|
liElm.className = "list-group-item";
|
||||||
if (domainRule !== "(default)") {
|
if (domainRule !== "(default)") {
|
||||||
liElm.className += " list-group-item-success";
|
liElm.className += " list-group-item-success";
|
||||||
}
|
}
|
||||||
|
|
||||||
const spanElm = document.createElement("span");
|
const spanElm = doc.createElement("span");
|
||||||
spanElm.className = "badge";
|
spanElm.className = "badge";
|
||||||
|
|
||||||
const badgeText = document.createTextNode(domainRule);
|
const badgeText = doc.createTextNode(domainRule);
|
||||||
spanElm.appendChild(badgeText);
|
spanElm.appendChild(badgeText);
|
||||||
liElm.appendChild(spanElm);
|
liElm.appendChild(spanElm);
|
||||||
|
|
||||||
const textElm = document.createTextNode(aDomain);
|
const textElm = doc.createTextNode(aDomain);
|
||||||
liElm.appendChild(textElm);
|
liElm.appendChild(textElm);
|
||||||
listGroupElm.appendChild(liElm);
|
listGroupElm.appendChild(liElm);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue