Skip to content

Commit 1632390

Browse files
committed
fix: update near-membrane-dom to use ShadowRealm
1 parent 7cb3cac commit 1632390

1 file changed

Lines changed: 49 additions & 14 deletions

File tree

packages/near-membrane-dom/src/browser-realm.ts

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,49 @@ interface BrowserEnvironmentOptions {
146146

147147
const createHooksCallback = createMembraneMarshall();
148148

149+
interface RealmControls {
150+
cleanup: () => {};
151+
evaluator: typeof eval;
152+
needsManualCleanUp: boolean;
153+
}
154+
// @ts-ignore: TypeScript doesn't know what a ShadowRealm is yet.
155+
const { ShadowRealm: ShadowRealmCtor } = globalThis;
156+
function createRealmControls(options: BrowserEnvironmentOptions): RealmControls {
157+
let cleanup = () => {};
158+
let evaluator: typeof eval;
159+
let needsManualCleanUp = false;
160+
161+
if (typeof ShadowRealmCtor === 'function') {
162+
// @ts-ignore: TypeScript doesn't know what a ShadowRealm is yet.
163+
const shadowRealm = new ShadowRealm();
164+
evaluator = shadowRealm.evaluate.bind(shadowRealm);
165+
} else {
166+
const { keepAlive } = options;
167+
const iframe = createDetachableIframe();
168+
const redWindow = HTMLIFrameElementContentWindowGetter(iframe)!.window;
169+
const { document: redDocument } = redWindow;
170+
cleanup = () => {
171+
// Once we get the iframe info ready, and all mapped, we can proceed
172+
// to detach the iframe only if the keepAlive option isn't true.
173+
if (keepAlive !== true) {
174+
removeIframe(iframe);
175+
} else {
176+
// TODO: Temporary hack to preserve the document reference in Firefox.
177+
// https://bugzilla.mozilla.org/show_bug.cgi?id=543435
178+
DocumentOpen(redDocument);
179+
DocumentClose(redDocument);
180+
}
181+
};
182+
evaluator = redWindow.eval;
183+
needsManualCleanUp = true;
184+
}
185+
return {
186+
cleanup,
187+
evaluator,
188+
needsManualCleanUp,
189+
} as RealmControls;
190+
}
191+
149192
export default function createVirtualEnvironment(
150193
globalObjectShape: object,
151194
globalObjectVirtualizationTarget: WindowProxy & typeof globalThis,
@@ -164,12 +207,10 @@ export default function createVirtualEnvironment(
164207
providedOptions
165208
);
166209
// eslint-disable-next-line prefer-object-spread
167-
const { distortionCallback, endowments = {}, keepAlive, support, instrumentation } = options;
168-
const iframe = createDetachableIframe();
169-
const redWindow = HTMLIFrameElementContentWindowGetter(iframe)!.window;
170-
const { document: redDocument } = redWindow;
210+
const { distortionCallback, endowments = {}, support, instrumentation } = options;
211+
const realmControls = createRealmControls(options);
171212
const blueConnector = createHooksCallback;
172-
const redConnector = createConnector(redWindow.eval);
213+
const redConnector = createConnector(realmControls.evaluator);
173214
// Extract the global references and descriptors before any interference.
174215
const blueRefs = getCachedBlueReferences(globalObjectVirtualizationTarget);
175216
// Create a new environment.
@@ -184,15 +225,9 @@ export default function createVirtualEnvironment(
184225
linkIntrinsics(env, globalObjectVirtualizationTarget);
185226
linkUnforgeables(env, globalObjectVirtualizationTarget);
186227
tameDOM(env, blueRefs, getResolvedShapeDescriptors(globalObjectShape, endowments));
187-
// Once we get the iframe info ready, and all mapped, we can proceed
188-
// to detach the iframe only if the keepAlive option isn't true.
189-
if (keepAlive !== true) {
190-
removeIframe(iframe);
191-
} else {
192-
// TODO: Temporary hack to preserve the document reference in Firefox.
193-
// https://bugzilla.mozilla.org/show_bug.cgi?id=543435
194-
DocumentOpen(redDocument);
195-
DocumentClose(redDocument);
228+
229+
if (realmControls.needsManualCleanUp) {
230+
realmControls.cleanup();
196231
}
197232
return env;
198233
}

0 commit comments

Comments
 (0)