Hack: use top.name to store per-tab content-side configuration (e.g. unrestricted tab status).
This commit is contained in:
parent
50d71ca381
commit
e959accb70
|
@ -1,5 +1,7 @@
|
||||||
"use script";
|
"use strict";
|
||||||
{
|
{
|
||||||
|
let marker = JSON.stringify(uuid());
|
||||||
|
|
||||||
let Scripts = {
|
let Scripts = {
|
||||||
references: new Set(),
|
references: new Set(),
|
||||||
opts: {
|
opts: {
|
||||||
|
@ -54,7 +56,27 @@
|
||||||
let siteKeys2MatchPatterns = keys => keys && flatten(keys.map(siteKey2MatchPattern)).filter(p => !!p) || [];
|
let siteKeys2MatchPatterns = keys => keys && flatten(keys.map(siteKey2MatchPattern)).filter(p => !!p) || [];
|
||||||
|
|
||||||
var ChildPolicies = {
|
var ChildPolicies = {
|
||||||
|
async storeTabInfo(tabId, info) {
|
||||||
|
try {
|
||||||
|
await browser.tabs.executeScript(tabId, {
|
||||||
|
code: `window.name = ${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + window.name;`,
|
||||||
|
allFrames: false,
|
||||||
|
matchAboutBlank: true,
|
||||||
|
runAt: "document_start",
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
async update(policy) {
|
async update(policy) {
|
||||||
|
Scripts.forget();
|
||||||
|
|
||||||
|
if (!policy.enforced) {
|
||||||
|
await Scripts.register(`ns.setup(null, ${marker});`,
|
||||||
|
["<all_urls>"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let serialized = policy.dry ? policy.dry(true) : policy;
|
let serialized = policy.dry ? policy.dry(true) : policy;
|
||||||
let permsMap = new Map();
|
let permsMap = new Map();
|
||||||
let trusted = JSON.stringify(serialized.TRUSTED);
|
let trusted = JSON.stringify(serialized.TRUSTED);
|
||||||
|
@ -96,15 +118,11 @@
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scripts.forget();
|
|
||||||
// register new content scripts
|
// register new content scripts
|
||||||
for (let [perms, keys] of [...permsMap]) {
|
for (let [perms, keys] of [...permsMap]) {
|
||||||
await Scripts.register(`ns.perms.CURRENT = ${perms};`, siteKeys2MatchPatterns(keys), excludeMap.get(perms));
|
await Scripts.register(`ns.perms.CURRENT = ${perms};`, siteKeys2MatchPatterns(keys), excludeMap.get(perms));
|
||||||
}
|
}
|
||||||
await Scripts.register(
|
await Scripts.register(`ns.setup(${JSON.stringify(serialized.DEFAULT)}, ${marker});`,
|
||||||
`ns.perms.DEFAULT = ${JSON.stringify(serialized.DEFAULT)};
|
|
||||||
if(!ns.perms.CURRENT) ns.perms.CURRENT = ns.perms.DEFAULT;
|
|
||||||
ns.fire("perms");`,
|
|
||||||
["<all_urls>"]);
|
["<all_urls>"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,8 @@ var Settings = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof unrestrictedTab === "boolean") {
|
if (typeof unrestrictedTab === "boolean") {
|
||||||
ns.unrestrictedTabs[settings.unrestrictedTab ? "add" : "delete"](tabId);
|
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
|
||||||
|
ChildPolicies.storeTabInfo(tabId, {unrestricted: unrestrictedTab});
|
||||||
}
|
}
|
||||||
if (reloadAffected) {
|
if (reloadAffected) {
|
||||||
browser.tabs.reload(tabId);
|
browser.tabs.reload(tabId);
|
||||||
|
|
|
@ -28,7 +28,6 @@ ns.defaults = (async () => {
|
||||||
|
|
||||||
// dynamic settings
|
// dynamic settings
|
||||||
if (!ns.local.uuid) {
|
if (!ns.local.uuid) {
|
||||||
await include("/lib/uuid.js");
|
|
||||||
ns.local.uuid = uuid();
|
ns.local.uuid = uuid();
|
||||||
await ns.save(ns.local);
|
await ns.save(ns.local);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,47 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
perms: { DEFAULT: null, CURRENT: null },
|
setup(DEFAULT, MARKER) {
|
||||||
|
this.perms.DEFAULT = DEFAULT;
|
||||||
|
if(!this.perms.CURRENT) this.perms.CURRENT = DEFAULT;
|
||||||
|
|
||||||
|
// ugly hack: since now we use registerContentScript instead of the
|
||||||
|
// filterRequest dynamic script injection hack, we use top.name
|
||||||
|
// to store per-tab information. We don't want web content to
|
||||||
|
// mess with it, though, so we wrap it around auto-hiding accessors
|
||||||
|
this.perms.MARKER = MARKER;
|
||||||
|
let eraseTabInfoRx = new RegExp(`[^]*${MARKER},?`);
|
||||||
|
if (eraseTabInfoRx.test(top.name)) {
|
||||||
|
let _name = top.name;
|
||||||
|
let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`);
|
||||||
|
if (top === window) { // wrap to hide
|
||||||
|
Reflect.defineProperty(top.wrappedJSObject, "name", {
|
||||||
|
get: exportFunction(() => _name.replace(eraseTabInfoRx, ""), top.wrappedJSObject),
|
||||||
|
set: exportFunction(value => {
|
||||||
|
let preamble = _name.match(tabInfoRx);
|
||||||
|
_name = `${preamble && preamble[0] || ""}${value}`;
|
||||||
|
return value;
|
||||||
|
}, top.wrappedJSObject)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let tabInfoMatch = _name.match(tabInfoRx);
|
||||||
|
if (tabInfoMatch) try {
|
||||||
|
this.perms.tabInfo = JSON.parse(tabInfoMatch[1]);
|
||||||
|
} catch (e) {
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.perms.DEFAULT || this.perms.tabInfo.unrestricted) {
|
||||||
|
this.allows = () => true;
|
||||||
|
}
|
||||||
|
ns.fire("perms");
|
||||||
|
},
|
||||||
|
storeTabInfo(info) {
|
||||||
|
let {MARKER} = this.perms;
|
||||||
|
window.name = `${MARKER}${JSON.stringify([info])}${MARKER},${window.name.split(marker).pop()}`;
|
||||||
|
},
|
||||||
|
perms: { DEFAULT: null, CURRENT: null, tabInfo: {} },
|
||||||
allows(cap) {
|
allows(cap) {
|
||||||
let perms = this.perms.CURRENT;
|
let perms = this.perms.CURRENT;
|
||||||
return perms && perms.capabilities.includes(cap);
|
return perms && perms.capabilities.includes(cap);
|
||||||
|
|
Loading…
Reference in New Issue