Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This file should be executed by the [possibly unprivileged] consumer, e.g.:
// <script src="/scripts/TalosPowersContent.js"></script>
// and then e.g. TalosPowersParent.exec("sampleParentService", myArg, myCallback)
// It marely sends a query event and possibly listens to a reply event, and does not
// depend on any special privileges.
var TalosPowers;
var TalosPowersContent;
var TalosPowersParent;
(function () {
// The talos powers chrome event/message listeners are set up
// asynchronously during startup so attempts to use this code too early
// may race against the extension initialization. Code that has might
// be vulnerable to that race can use `await TalosPowers.loadPromise;`
// which waits until it can successfully exchange a simple "ping" message
// with the extension.
async function tryPing() {
let pingPromise = new Promise(resolve => {
TalosPowersParent.exec("ping", null, resolve);
});
let timeoutPromise = new Promise((resolve, reject) => {
setTimeout(reject, 500);
});
try {
await Promise.race([pingPromise, timeoutPromise]);
} catch (e) {
return tryPing();
}
return null;
}
TalosPowers = {};
Object.defineProperty(TalosPowers, "loadPromise", {
get: () => tryPing(),
configurable: true,
enumerable: true,
});
TalosPowersContent = {
/**
* Synchronously force CC and GC in this process, as well as in the
* parent process.
*/
forceCCAndGC() {
var event = new CustomEvent("TalosPowersContentForceCCAndGC", {
bubbles: true,
});
document.dispatchEvent(event);
},
focus(callback) {
if (callback) {
addEventListener("TalosPowersContentFocused", function focused() {
removeEventListener("TalosPowersContentFocused", focused);
callback();
});
}
document.dispatchEvent(
new CustomEvent("TalosPowersContentFocus", {
bubbles: true,
})
);
},
getStartupInfo() {
return new Promise(resolve => {
var event = new CustomEvent("TalosPowersContentGetStartupInfo", {
bubbles: true,
});
document.dispatchEvent(event);
addEventListener(
"TalosPowersContentGetStartupInfoResult",
function onResult(e) {
removeEventListener(
"TalosPowersContentGetStartupInfoResult",
onResult
);
resolve(e.detail);
}
);
});
},
dumpConsole() {
var event = new CustomEvent("TalosPowersContentDumpConsole", {
bubbles: true,
});
document.dispatchEvent(event);
},
goQuitApplication(waitForStartupFinished) {
var event = new CustomEvent("TalosPowersGoQuitApplication", {
bubbles: true,
detail: { waitForStartupFinished },
});
document.dispatchEvent(event);
},
wrCapture() {
var event = new CustomEvent("TalosPowersWebRenderCapture", {
bubbles: true,
});
document.dispatchEvent(event);
},
};
/**
* Generic interface to service functions which run at the parent process.
*/
// If including this script proves too much touble, you may embed the following
// code verbatim instead, and keep the copy up to date with its source here:
TalosPowersParent = {
replyId: 1,
// dispatch an event to the framescript and register the result/callback event
exec(commandName, arg, callback, opt_custom_window) {
let win = opt_custom_window || window;
let replyEvent = "TalosPowers:ParentExec:ReplyEvent:" + this.replyId++;
if (callback) {
win.addEventListener(
replyEvent,
function (e) {
callback(e.detail);
},
{ once: true }
);
}
win.dispatchEvent(
new win.CustomEvent("TalosPowers:ParentExec:QueryEvent", {
bubbles: true,
detail: {
command: {
name: commandName,
data: arg,
},
listeningTo: replyEvent,
},
})
);
},
};
// End of possibly embedded code
})();