diff --git a/rewriter/src/lib.rs b/rewriter/src/lib.rs index 66d54b0..8126378 100644 --- a/rewriter/src/lib.rs +++ b/rewriter/src/lib.rs @@ -66,6 +66,7 @@ fn get_config(scramjet: &Object, url: &str) -> Result { encode: create_encode_function(get_obj(codec, "encode")?)?, wrapfn: get_str(globals, "wrapfn")?, + wrapthisfn: get_str(globals, "wrapthisfn")?, importfn: get_str(globals, "importfn")?, rewritefn: get_str(globals, "rewritefn")?, metafn: get_str(globals, "metafn")?, diff --git a/rewriter/src/main.rs b/rewriter/src/main.rs index 67a56c7..504037f 100644 --- a/rewriter/src/main.rs +++ b/rewriter/src/main.rs @@ -118,6 +118,7 @@ fn dorewrite(source_text: &str) -> Result { prefix: "/scrammedjet/".to_string(), encode: Box::new(encode_string), wrapfn: "$wrap".to_string(), + wrapthisfn: "$gwrap".to_string(), importfn: "$import".to_string(), rewritefn: "$rewrite".to_string(), metafn: "$meta".to_string(), @@ -126,7 +127,7 @@ fn dorewrite(source_text: &str) -> Result { capture_errors: true, do_sourcemaps: true, scramitize: false, - strict_rewrites: false, + strict_rewrites: true, }, )? .as_slice(), diff --git a/rewriter/src/rewrite.rs b/rewriter/src/rewrite.rs index b2364a6..7ae75d6 100644 --- a/rewriter/src/rewrite.rs +++ b/rewriter/src/rewrite.rs @@ -44,6 +44,7 @@ pub struct Config { pub prefix: String, pub wrapfn: String, + pub wrapthisfn: String, pub importfn: String, pub rewritefn: String, pub setrealmfn: String, @@ -171,7 +172,7 @@ impl<'a> Visit<'a> for Rewriter { fn visit_this_expression(&mut self, it: &oxc_ast::ast::ThisExpression) { self.jschanges.push(JsChange::GenericChange { span: it.span, - text: format!("{}(this)", self.config.wrapfn), + text: format!("{}(this)", self.config.wrapthisfn), }); } diff --git a/src/client/shared/wrap.ts b/src/client/shared/wrap.ts index 21589c0..26be769 100644 --- a/src/client/shared/wrap.ts +++ b/src/client/shared/wrap.ts @@ -6,42 +6,25 @@ import { config } from "../../shared"; // import { indirectEval } from "./eval"; export function createWrapFn(client: ScramjetClient, self: typeof globalThis) { - return function (identifier: any, args: any) { - if (iswindow && identifier instanceof self.Window) { - return client.globalProxy; - } else if (iswindow && identifier instanceof self.parent.self.Window) { - 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 (iswindow && identifier instanceof self.top.self.Window) { - // instead of returning top, we need to return the uppermost parent that's inside a scramjet context - let current = self.self; - - for (;;) { - const test = current.parent.self; - if (test === current) break; // there is no parent, actual or emulated. - - // ... then `test` represents a window outside of the proxy context, and therefore `current` is the topmost window in the proxy context - if (!(SCRAMJETCLIENT in test)) break; - - // test is also insde a proxy, so we should continue up the chain - current = test; - } - - return current[SCRAMJETCLIENT].globalProxy.window; - } else if ( - (iswindow && identifier instanceof self.Location) || - (isworker && identifier instanceof self.WorkerLocation) - ) { + return function (identifier: any) { + if (identifier === self.location) { return client.locationProxy; - } else if (iswindow && identifier instanceof self.Document) { - return client.documentProxy; - } else if (isworker && identifier instanceof self.WorkerGlobalScope) { - return client.globalProxy; + } + + 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; @@ -58,6 +41,14 @@ export default function (client: ScramjetClient, self: typeof globalThis) { 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")) { diff --git a/src/controller/index.ts b/src/controller/index.ts index df2c3e4..c307354 100644 --- a/src/controller/index.ts +++ b/src/controller/index.ts @@ -11,6 +11,7 @@ export class ScramjetController { prefix: "/scramjet/", globals: { wrapfn: "$scramjet$wrap", + wrapthisfn: "$scramjet$wrapthis", trysetfn: "$scramjet$tryset", importfn: "$scramjet$import", rewritefn: "$scramjet$rewrite", diff --git a/src/types.d.ts b/src/types.d.ts index 2a48c03..f6f4e19 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -38,6 +38,7 @@ interface ScramjetConfig { prefix: string; globals: { wrapfn: string; + wrapthisfn: string; trysetfn: string; importfn: string; rewritefn: string;