File size: 2,368 Bytes
bee6636 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
// import { encodeUrl } from "../shared";
import { iswindow } from ".";
import { SCRAMJETCLIENT } from "../symbols";
import { ScramjetClient } from "./client";
// import { config } from "../shared";
import { getOwnPropertyDescriptorHandler } from "./helpers";
export const UNSAFE_GLOBALS = [
"window",
"self",
"globalThis",
"this",
"parent",
"top",
"location",
"document",
"eval",
"frames",
];
export function createGlobalProxy(
client: ScramjetClient,
self: typeof globalThis
): typeof globalThis {
return new Proxy(self, {
get(target, prop) {
const value = Reflect.get(target, prop);
if (
iswindow &&
(typeof prop === "string" || typeof prop === "number") &&
!isNaN(Number(prop)) &&
value
) {
const win: Self = value.self;
// indexing into window gives you the contentWindow of the subframes for some reason
// you can't *set* it so this should always be the right value
if (win) {
if (SCRAMJETCLIENT in win) {
// then we've already hooked this frame and we can just send over its proxy
return win[SCRAMJETCLIENT].globalProxy;
} else {
// this can happen if it's an about:blank iframe that we've never gotten the chance to inject into
// just make a new client for it and inject
const newclient = new ScramjetClient(win);
newclient.hook();
return newclient.globalProxy;
}
}
}
if (prop === "$scramjet") return undefined;
if (typeof prop === "string" && UNSAFE_GLOBALS.includes(prop)) {
// TODO strict mode detect
return client.wrapfn(value, true);
}
return value;
},
set(target, prop, value) {
if (prop === "location") {
client.url = value;
return;
}
return Reflect.set(target, prop, value);
},
has(target, prop) {
if (prop === "$scramjet") return false;
return Reflect.has(target, prop);
},
ownKeys(target) {
return Reflect.ownKeys(target).filter((key) => key !== "$scramjet");
},
defineProperty(target, property, attributes) {
if (!attributes.get && !attributes.set) {
attributes.writable = true;
}
attributes.configurable = true;
return Reflect.defineProperty(target, property, attributes);
},
getOwnPropertyDescriptor: getOwnPropertyDescriptorHandler,
});
}
|