FUCK THIS SHIT (Fix WebExtension message cloning and image bitmap compatibility)

This commit is contained in:
wuggy 2026-09-19 05:25:53 -07:00
commit f3ce3c21ee
2 changed files with 33 additions and 13 deletions

View file

@ -518,7 +518,8 @@ class ProxyAPIImplementation extends SchemaAPIInterface {
map.ids.set(id, listener); map.ids.set(id, listener);
map.listeners.set(listener, id); map.listeners.set(listener, id);
this.childApiManager.messageManager.sendAsyncMessage("API:AddListener", { MessageChannel.sendAsyncMessage(this.childApiManager.messageManager,
"API:AddListener", {
childId: this.childApiManager.id, childId: this.childApiManager.id,
listenerId: id, listenerId: id,
path: this.path, path: this.path,
@ -537,7 +538,8 @@ class ProxyAPIImplementation extends SchemaAPIInterface {
map.listeners.delete(listener); map.listeners.delete(listener);
map.ids.delete(id); map.ids.delete(id);
this.childApiManager.messageManager.sendAsyncMessage("API:RemoveListener", { MessageChannel.sendAsyncMessage(this.childApiManager.messageManager,
"API:RemoveListener", {
childId: this.childApiManager.id, childId: this.childApiManager.id,
listenerId: id, listenerId: id,
path: this.path, path: this.path,
@ -587,7 +589,8 @@ class ChildAPIManager {
}; };
Object.assign(params, contextData); Object.assign(params, contextData);
this.messageManager.sendAsyncMessage("API:CreateProxyContext", params); MessageChannel.sendAsyncMessage(this.messageManager,
"API:CreateProxyContext", params);
} }
receiveMessage({name, messageName, data}) { receiveMessage({name, messageName, data}) {
@ -626,7 +629,7 @@ class ChildAPIManager {
* @param {Array} args The parameters for the function. * @param {Array} args The parameters for the function.
*/ */
callParentFunctionNoReturn(path, args) { callParentFunctionNoReturn(path, args) {
this.messageManager.sendAsyncMessage("API:Call", { MessageChannel.sendAsyncMessage(this.messageManager, "API:Call", {
childId: this.id, childId: this.id,
path, path,
args, args,
@ -649,7 +652,7 @@ class ChildAPIManager {
let deferred = PromiseUtils.defer(); let deferred = PromiseUtils.defer();
this.callPromises.set(callId, deferred); this.callPromises.set(callId, deferred);
this.messageManager.sendAsyncMessage("API:Call", { MessageChannel.sendAsyncMessage(this.messageManager, "API:Call", {
childId: this.id, childId: this.id,
callId, callId,
path, path,
@ -684,7 +687,8 @@ class ChildAPIManager {
} }
close() { close() {
this.messageManager.sendAsyncMessage("API:CloseProxyContext", {childId: this.id}); MessageChannel.sendAsyncMessage(this.messageManager,
"API:CloseProxyContext", {childId: this.id});
} }
get cloneScope() { get cloneScope() {
@ -785,10 +789,9 @@ class ExtensionPageContextChild extends BaseContext {
return nativeCreateImageBitmap.apply(this, args); return nativeCreateImageBitmap.apply(this, args);
}; };
try { try {
// Window.createImageBitmap is inherited from a WebIDL prototype in // Some older bindings reject assignment to the WebIDL method. Define
// older UXP builds. Assignment can therefore leave the native // an own property on this extension window so no other window is
// method in place; define an own property so extension feature probes // affected.
// actually reach the compatibility wrapper.
Object.defineProperty(contentWindow, "createImageBitmap", { Object.defineProperty(contentWindow, "createImageBitmap", {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
@ -797,8 +800,15 @@ class ExtensionPageContextChild extends BaseContext {
}); });
} catch (e) { } catch (e) {
try { try {
contentWindow.createImageBitmap = extensionCreateImageBitmap; // This also works through the Window Xray wrapper used by older
} catch (e2) {} // UXP extension globals.
Cu.exportFunction(extensionCreateImageBitmap, contentWindow,
{defineAs: "createImageBitmap"});
} catch (e2) {
try {
contentWindow.createImageBitmap = extensionCreateImageBitmap;
} catch (e3) {}
}
} }
} }

View file

@ -302,7 +302,12 @@ function makeMessageCloneable(value, seen = new Set()) {
} }
seen.add(value); seen.add(value);
let className = Cu.getClassName(value, true); let className;
try {
className = Cu.getClassName(value, true);
} catch (e) {
return undefined;
}
if (className == "Array") { if (className == "Array") {
return value.map(item => makeMessageCloneable(item, seen)); return value.map(item => makeMessageCloneable(item, seen));
} }
@ -334,6 +339,11 @@ function sendMessageWithCloneFallback(target, name, data) {
} }
this.MessageChannel = { this.MessageChannel = {
// Keep direct extension API messages on the clone-safe UXP path too.
sendAsyncMessage(target, name, data) {
sendMessageWithCloneFallback(target, name, data);
},
init() { init() {
Services.obs.addObserver(this, "message-manager-close", false); Services.obs.addObserver(this, "message-manager-close", false);
Services.obs.addObserver(this, "message-manager-disconnect", false); Services.obs.addObserver(this, "message-manager-disconnect", false);