mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-14 15:00:01 -04:00
85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import { iswindow, isworker } from "..";
|
|
import { SCRAMJETCLIENT } from "../../symbols";
|
|
import { ScramjetClient } from "../client";
|
|
import { config } from "../../shared";
|
|
// import { argdbg } from "./err";
|
|
import { indirectEval } from "./eval";
|
|
|
|
export function createWrapFn(client: ScramjetClient, self: typeof globalThis) {
|
|
return function (identifier: any) {
|
|
if (identifier === self) return client.globalProxy;
|
|
if (identifier === self.location) return client.locationProxy;
|
|
if (identifier === eval) return indirectEval;
|
|
|
|
if (iswindow) {
|
|
if (identifier === self.parent) {
|
|
if (SCRAMJETCLIENT in self.parent.self) {
|
|
// ... then we're in a subframe, and the parent frame is also in a proxy context, so we should return its proxy
|
|
return self.parent.self[SCRAMJETCLIENT].globalProxy;
|
|
} else {
|
|
// ... then we should pretend we aren't nested and return the current window
|
|
return client.globalProxy;
|
|
}
|
|
} else if (identifier === self.document) {
|
|
return client.documentProxy;
|
|
}
|
|
|
|
// TODO .top
|
|
}
|
|
|
|
return identifier;
|
|
};
|
|
}
|
|
|
|
export const order = 4;
|
|
export default function (client: ScramjetClient, self: typeof globalThis) {
|
|
// the main magic of the proxy. all attempts to access any "banned objects" will be redirected here, and instead served a proxy object
|
|
// this contrasts from how other proxies will leave the root object alone and instead attempt to catch every member access
|
|
// this presents some issues (see element.ts), but makes us a good bit faster at runtime!
|
|
Object.defineProperty(self, config.globals.wrapfn, {
|
|
value: client.wrapfn,
|
|
writable: false,
|
|
configurable: false,
|
|
});
|
|
Object.defineProperty(self, config.globals.wrapthisfn, {
|
|
value: function (i) {
|
|
if (i === self) return client.globalProxy;
|
|
return i;
|
|
},
|
|
writable: false,
|
|
configurable: false,
|
|
});
|
|
|
|
self.$scramitize = function (v) {
|
|
if (typeof v === "string" && v.includes("scramjet")) {
|
|
debugger;
|
|
}
|
|
|
|
if (typeof v === "string" && v.includes(location.origin)) {
|
|
debugger;
|
|
}
|
|
|
|
if (iswindow && v instanceof Document && v.defaultView.$scramjet) {
|
|
debugger;
|
|
}
|
|
|
|
return v;
|
|
};
|
|
|
|
// location = "..." can't be rewritten as wrapfn(location) = ..., so instead it will actually be rewritten as
|
|
// ((t)=>$scramjet$tryset(location,"+=",t)||location+=t)(...);
|
|
// it has to be a discrete function because there's always the possibility that "location" is a local variable
|
|
// we have to use an IIFE to avoid duplicating side-effects in the getter
|
|
Object.defineProperty(self, config.globals.trysetfn, {
|
|
value: function (lhs: any, op: string, rhs: any) {
|
|
if (lhs instanceof Location) {
|
|
// @ts-ignore
|
|
locationProxy.href = rhs;
|
|
|
|
return true;
|
|
}
|
|
},
|
|
writable: false,
|
|
configurable: false,
|
|
});
|
|
}
|