import EventTarget from '../event/EventTarget.js'; import IBrowserWindow from './IBrowserWindow.js'; import DOMException from '../exception/DOMException.js'; import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum.js'; import Location from '../location/Location.js'; import ICrossOriginBrowserWindow from './ICrossOriginBrowserWindow.js'; /** * Browser window with limited access due to CORS restrictions in iframes. */ export default class CrossOriginBrowserWindow extends EventTarget implements ICrossOriginBrowserWindow { public readonly self = this; public readonly window = this; public readonly parent: IBrowserWindow | ICrossOriginBrowserWindow; public readonly top: IBrowserWindow | ICrossOriginBrowserWindow; public readonly location: Location; #targetWindow: IBrowserWindow; /** * Constructor. * * @param target Target window. * @param [parent] Parent window. */ constructor(target: IBrowserWindow, parent?: IBrowserWindow) { super(); this.parent = parent ?? this; this.top = parent ?? this; this.location = new Proxy( {}, { get: () => { throw new DOMException( `Blocked a frame with origin "${this.parent.location.origin}" from accessing a cross-origin frame.`, DOMExceptionNameEnum.securityError ); }, set: () => { throw new DOMException( `Blocked a frame with origin "${this.parent.location.origin}" from accessing a cross-origin frame.`, DOMExceptionNameEnum.securityError ); } } ); this.#targetWindow = target; } /** * Returns the opener. * * @returns Opener. */ public get opener(): IBrowserWindow | ICrossOriginBrowserWindow | null { return this.#targetWindow.opener; } /** * Returns the closed state. * * @returns Closed state. */ public get closed(): boolean { return this.#targetWindow.closed; } /** * Shifts focus away from the window. */ public blur(): void { this.#targetWindow.blur(); } /** * Gives focus to the window. */ public focus(): void { this.#targetWindow.focus(); } /** * Closes the window. */ public close(): void { this.#targetWindow.close(); } /** * Safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it. * * @param message Message. * @param [targetOrigin=*] Target origin. * @param transfer Transfer. Not implemented. */ public postMessage(message: unknown, targetOrigin = '*', transfer?: unknown[]): void { this.#targetWindow.postMessage(message, targetOrigin, transfer); } }