"use strict"; /* * Copyright 2023 Google LLC. * Copyright (c) Microsoft Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BidiPreloadScript = void 0; const uuid_js_1 = require("../../../utils/uuid.js"); const channelProxy_js_1 = require("../script/channelProxy.js"); /** * BiDi IDs are generated by the server and are unique within the context. * * CDP preload script IDs are generated by the client and are unique * within the session. * * The mapping between BiDi and CDP preload script IDs is 1:many. * BiDi IDs are needed by the mapper to keep track of potential multiple CDP IDs * in the client. */ class BidiPreloadScript { /** BiDi ID, an automatically generated UUID. */ #id = (0, uuid_js_1.uuidv4)(); /** CDP preload scripts. */ #cdpPreloadScripts = []; /** The script itself, in a format expected by the spec i.e. a function. */ #functionDeclaration; /** Browsing context ID. */ #contextId; /** Targets, in which the preload script is initialized. */ #targetIds = new Set(); /** Channels to be added as arguments to functionDeclaration. */ #channels; get id() { return this.#id; } get contextId() { return this.#contextId; } get targetIds() { return this.#targetIds; } constructor(params) { if (params.sandbox !== undefined) { // TODO: Handle sandbox. throw new Error('Sandbox is not supported yet'); } this.#channels = params.arguments?.map((a) => new channelProxy_js_1.ChannelProxy(a.value)) ?? []; this.#functionDeclaration = params.functionDeclaration; this.#contextId = params.context ?? null; } /** Channels of the preload script. */ get channels() { return this.#channels; } /** * Adds the script to the given CDP targets by calling the * `Page.addScriptToEvaluateOnNewDocument` command. */ async initInTargets(cdpTargets) { await Promise.all(Array.from(cdpTargets).map((cdpTarget) => this.initInTarget(cdpTarget))); } /** * String to be evaluated. Wraps user-provided function so that the following * steps are run: * 1. Create channels. * 2. Store the created channels in window. * 3. Call the user-provided function with channels as arguments. */ #getEvaluateString() { const channelsArgStr = `[${this.channels .map((c) => c.getEvalInWindowStr()) .join(', ')}]`; return `(()=>{(${this.#functionDeclaration})(...${channelsArgStr})})()`; } /** * Adds the script to the given CDP target by calling the * `Page.addScriptToEvaluateOnNewDocument` command. */ async initInTarget(cdpTarget) { const addCdpPreloadScriptResult = await cdpTarget.cdpClient.sendCommand('Page.addScriptToEvaluateOnNewDocument', { source: this.#getEvaluateString(), }); this.#cdpPreloadScripts.push({ target: cdpTarget, preloadScriptId: addCdpPreloadScriptResult.identifier, }); this.#targetIds.add(cdpTarget.targetId); } /** * Schedules the script to be run right after * `Runtime.runIfWaitingForDebugger`, but does not wait for result. */ scheduleEvaluateInTarget(cdpTarget) { void cdpTarget.cdpClient.sendCommand('Runtime.evaluate', { expression: this.#getEvaluateString(), }); } /** * Removes this script from all CDP targets. */ async remove() { for (const cdpPreloadScript of this.#cdpPreloadScripts) { const cdpTarget = cdpPreloadScript.target; const cdpPreloadScriptId = cdpPreloadScript.preloadScriptId; await cdpTarget.cdpClient.sendCommand('Page.removeScriptToEvaluateOnNewDocument', { identifier: cdpPreloadScriptId, }); } } /** * Removes the provided cdp target from the list of cdp preload scripts. */ cdpTargetIsGone(cdpTargetId) { this.#cdpPreloadScripts = this.#cdpPreloadScripts.filter((cdpPreloadScript) => cdpPreloadScript.target?.targetId !== cdpTargetId); this.#targetIds.delete(cdpTargetId); } } exports.BidiPreloadScript = BidiPreloadScript; //# sourceMappingURL=bidiPreloadScript.js.map