I will likely interchange the following without noticing, purely out of habit (sorry).
"IPC" stands for "inter-process communication".
A "remote browser" is a <xul:browser> with the remote="true" attribute.
A "frame script" is a script that can be sent to a child process to hear and respond to messages
There are several types, and different types are available depending on which process you're in.
Check out the documentation for message managers on MDN and the documentation in nsIMessageManager.idl for a low-level breakdown.
The one you're most likely to work with is the "browser" message manager.
let browser = gBrowser.selectedBrowser; let mm = browser.messageManager; // ^-- Available even if <xul:browser> is not remote!
mm.sendAsyncMessage("Foo", { bar: "baz", // JSON serializable stuff and nsIPrincipal's can go in here. }); mm.addMessageListener("Done", (message) => { dump("Child sent done."); });
-- snip -- // Inside some frame script: addMessageListener("Foo", (message) => { dump("Parent said: " + message.data.bar + "\n"); sendAsyncMessage("Done"); // Could also use sendSyncMessage("Done"); });
let browser = gBrowser.selectedBrowser; let mm = browser.messageManager; mm.loadFrameScript("chrome://browser/content/foo.js", false); // Set second arg to true if we want to load this once remote browser // is ready / available. Otherwise, script will only load if remote // browser is ready / available.
Loaded in all <xul:browser>'s, remote or not:
Loaded just in remote <xul:browser>'s:
let doc = gBrowser.selectedBrowser.contentDocumentAsCPOW; let el = doc.getElementById("someElementInContent"); if (el.hasAttribute("foo")) { el.setAttribute("bar", "baz"); }
Components.utils.isCrossProcessWrapper(thing);
Sometimes, a CPOW is just the best way forward.
// Some frame script addEventListener("click", (event) => { sendAsyncMessage("Foo:Click", null, { target: event.target, }); });
-- snip -- // Parent process script let mm = gBrowser.selectedBrowser.messageManager; mm.addMessageListener("Foo:Click", (message) => { dump("I got the item with ID: " + message.objects.target.id); });
let doc = gBrowser.selectedBrowser.contentDocumentAsCPOW; let anchors = doc.querySelectorAll("a"); for (let anchor of anchors) { if (anchor.href.startsWith("https://")) { el.classList.add("ssl"); } }
let win = gBrowser.selectedBrowser.contentWindowAsCPOW; win.focus();
let win = gBrowser.selectedBrowser.contentWindowAsCPOW; let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShell); let svc = Cc["@mozilla.org/someservice;1"].getService(Ci.nsISomeService); svc.someMethod(docShell);
/