This commit is contained in:
Toshit Chawda 2024-12-13 18:49:24 -08:00
commit 0bf06630b7
No known key found for this signature in database
GPG key ID: 91480ED99E2B3D9D

View file

@ -1,7 +1,6 @@
import { rewriteUrl } from "../../shared"; import { rewriteUrl } from "../../shared";
import { ScramjetClient } from "../client"; import { ScramjetClient } from "../client";
import { type MessageC2W } from "../../worker"; import { type MessageC2W } from "../../worker";
import { getOwnPropertyDescriptorHandler } from "../helpers";
import { flagEnabled } from "../../scramjet"; import { flagEnabled } from "../../scramjet";
// we need a late order because we're mangling with addEventListener at a higher level // we need a late order because we're mangling with addEventListener at a higher level
@ -14,9 +13,16 @@ export function disabled(_client: ScramjetClient, _self: Self) {
Reflect.deleteProperty(Navigator.prototype, "serviceWorker"); Reflect.deleteProperty(Navigator.prototype, "serviceWorker");
} }
export default function (client: ScramjetClient, _self: Self) { type FakeRegistrationState = {
let registration; scope: string;
active: ServiceWorker;
};
export default function (client: ScramjetClient, _self: Self) {
const registrationmap: WeakMap<
ServiceWorkerRegistration,
FakeRegistrationState
> = new WeakMap();
client.Proxy("EventTarget.prototype.addEventListener", { client.Proxy("EventTarget.prototype.addEventListener", {
apply(ctx) { apply(ctx) {
if (registration === ctx.this) { if (registration === ctx.this) {
@ -61,6 +67,12 @@ export default function (client: ScramjetClient, _self: Self) {
client.Proxy("ServiceWorkerContainer.prototype.register", { client.Proxy("ServiceWorkerContainer.prototype.register", {
apply(ctx) { apply(ctx) {
const fakeRegistration = new EventTarget() as ServiceWorkerRegistration;
Object.setPrototypeOf(
fakeRegistration,
self.ServiceWorkerRegistration.prototype
);
fakeRegistration.constructor = ctx.fn;
let url = rewriteUrl(ctx.args[0], client.meta) + "?dest=serviceworker"; let url = rewriteUrl(ctx.args[0], client.meta) + "?dest=serviceworker";
if (ctx.args[1] && ctx.args[1].type === "module") { if (ctx.args[1] && ctx.args[1].type === "module") {
url += "&type=module"; url += "&type=module";
@ -68,6 +80,10 @@ export default function (client: ScramjetClient, _self: Self) {
const worker = client.natives.construct("SharedWorker", url); const worker = client.natives.construct("SharedWorker", url);
const handle = worker.port; const handle = worker.port;
const state: FakeRegistrationState = {
scope: ctx.args[0],
active: handle as ServiceWorker,
};
const controller = client.descriptors.get( const controller = client.descriptors.get(
"ServiceWorkerContainer.prototype.controller", "ServiceWorkerContainer.prototype.controller",
client.serviceWorker client.serviceWorker
@ -84,39 +100,7 @@ export default function (client: ScramjetClient, _self: Self) {
[handle] [handle]
); );
const fakeRegistration = new Proxy( registrationmap.set(fakeRegistration, state);
{
__proto__: ServiceWorkerRegistration.prototype,
},
{
get(target, prop) {
if (prop === "installing") {
return null;
}
if (prop === "waiting") {
return null;
}
if (prop === "active") {
return handle;
}
if (prop === "scope") {
return ctx.args[0];
}
if (prop === "unregister") {
return () => {};
}
if (prop === "addEventListener") {
return () => {};
}
return Reflect.get(target, prop);
},
getOwnPropertyDescriptor: getOwnPropertyDescriptorHandler,
}
);
registration = fakeRegistration;
ctx.return(new Promise((resolve) => resolve(fakeRegistration))); ctx.return(new Promise((resolve) => resolve(fakeRegistration)));
}, },
}); });