diff options
Diffstat (limited to 'src/content/content.js')
-rw-r--r-- | src/content/content.js | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/src/content/content.js b/src/content/content.js index 886c363..8f772b1 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -1,7 +1,81 @@ 'use strict'; // debug = () => {}; // REL_ONLY - +{ + let listenersMap = new Map(); + let backlog = new Set(); + var ns = { + on(eventName, listener) { + let listeners = listenersMap.get(eventName); + if (!listeners) listenersMap.set(eventName, listeners = new Set()); + listeners.add(listener); + if (backlog.has(eventName)) this.fire(eventName, listener); + }, + detach(eventName, listener) { + let listeners = listenersMap.get(eventName); + if (listeners) listeners.delete(listener); + }, + fire(eventName, listener = null) { + if (listener) { + listener({type:eventName, source: this}); + return; + } + let listeners = listenersMap.get(eventName); + if (listeners) { + for (let l of listeners) { + this.fire(eventName, l); + } + } + backlog.add(eventName); + }, + 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(() => top.name.replace(eraseTabInfoRx, ""), top.wrappedJSObject), + set: exportFunction(value => { + let preamble = top.name.match(tabInfoRx); + top.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"); + }, + perms: { DEFAULT: null, CURRENT: null, tabInfo: {}, MARKER: "" }, + allows(cap) { + let perms = this.perms.CURRENT; + return perms && perms.capabilities.includes(cap); + }, + getWindowName() { + return top !== window || !this.perms.MARKER ? window.name + : window.name.split(this.perms.MARKER + ",").pop(); + } + } +} + var canScript = true, shouldScript = false; let now = () => performance.now() + performance.timeOrigin; @@ -24,7 +98,6 @@ function probe() { var _ = browser.i18n.getMessage; - var embeddingDocument = false; var seen = { |