|
| 1 | +/* global mozProxies */ |
| 2 | +import { getInjectionElement } from './utils.js' |
| 3 | +export const hasMozProxies = typeof mozProxies !== 'undefined' ? mozProxies : false |
| 4 | + |
| 5 | +let dummyWindow |
| 6 | +if ('document' in globalThis && |
| 7 | + // Prevent infinate recursion of injection into Chrome |
| 8 | + globalThis.location.href !== 'about:blank') { |
| 9 | + const injectionElement = getInjectionElement() |
| 10 | + // injectionElement is null in some playwright context tests |
| 11 | + if (injectionElement) { |
| 12 | + dummyWindow = document.createElement('iframe') |
| 13 | + dummyWindow.style.display = 'none' |
| 14 | + injectionElement.appendChild(dummyWindow) |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +let dummyContentWindow = dummyWindow?.contentWindow |
| 19 | +if (hasMozProxies) { |
| 20 | + // @ts-expect-error - mozProxies is not defined on window |
| 21 | + dummyContentWindow = dummyContentWindow.wrappedJSObject |
| 22 | +} |
| 23 | +// @ts-expect-error - Symbol is not defined on window |
| 24 | +const dummySymbol = dummyContentWindow?.Symbol |
| 25 | +const iteratorSymbol = dummySymbol?.iterator |
| 26 | + |
1 | 27 | // Capture prototype to prevent overloading
|
2 |
| -function captureGlobals (object) { |
3 |
| - const newGlobal = object |
4 |
| - for (const key in object) { |
5 |
| - const value = object[key] |
6 |
| - newGlobal[key] = value |
| 28 | +function captureGlobal (globalName) { |
| 29 | + const global = dummyWindow?.contentWindow?.[globalName] |
| 30 | + |
| 31 | + // if we were unable to create a dummy window, return the global |
| 32 | + // this still has the advantage of preventing aliasing of the global through shawdowing |
| 33 | + if (!global) { |
| 34 | + return globalThis[globalName] |
7 | 35 | }
|
8 |
| - for (const key in object.prototype) { |
9 |
| - const value = object.prototype[key] |
10 |
| - newGlobal.prototype[key] = value |
| 36 | + |
| 37 | + // Alias the iterator symbol to the local symbol so for loops work |
| 38 | + if (iteratorSymbol && |
| 39 | + global?.prototype && |
| 40 | + iteratorSymbol in global.prototype) { |
| 41 | + global.prototype[Symbol.iterator] = global.prototype[iteratorSymbol] |
11 | 42 | }
|
12 |
| - return newGlobal |
| 43 | + return global |
13 | 44 | }
|
14 | 45 |
|
15 |
| -export const Set = captureGlobals(globalThis.Set) |
16 |
| -export const Reflect = captureGlobals(globalThis.Reflect) |
| 46 | +export const Set = captureGlobal('Set') |
| 47 | +export const Reflect = captureGlobal('Reflect') |
| 48 | + |
| 49 | +// Clean up the dummy window |
| 50 | +dummyWindow?.remove() |
0 commit comments