126 lines
4.7 KiB
JavaScript
126 lines
4.7 KiB
JavaScript
"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.PreloadScript = void 0;
|
|
const uuid_js_1 = require("../../../utils/uuid.js");
|
|
const ChannelProxy_js_1 = require("./ChannelProxy.js");
|
|
/**
|
|
* BiDi IDs are generated by the server and are unique within contexts.
|
|
*
|
|
* CDP preload script IDs are generated by the client and are unique
|
|
* within sessions.
|
|
*
|
|
* 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 PreloadScript {
|
|
/** 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;
|
|
/** Targets, in which the preload script is initialized. */
|
|
#targetIds = new Set();
|
|
/** Channels to be added as arguments to functionDeclaration. */
|
|
#channels;
|
|
/** The script sandbox / world name. */
|
|
#sandbox;
|
|
/** The browsing contexts to execute the preload scripts in, if any. */
|
|
#contexts;
|
|
get id() {
|
|
return this.#id;
|
|
}
|
|
get targetIds() {
|
|
return this.#targetIds;
|
|
}
|
|
constructor(params, logger) {
|
|
this.#channels =
|
|
params.arguments?.map((a) => new ChannelProxy_js_1.ChannelProxy(a.value, logger)) ?? [];
|
|
this.#functionDeclaration = params.functionDeclaration;
|
|
this.#sandbox = params.sandbox;
|
|
this.#contexts = params.contexts;
|
|
}
|
|
/** Channels of the preload script. */
|
|
get channels() {
|
|
return this.#channels;
|
|
}
|
|
/** Contexts of the preload script, if any */
|
|
get contexts() {
|
|
return this.#contexts;
|
|
}
|
|
/**
|
|
* 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 targets by calling the
|
|
* `Page.addScriptToEvaluateOnNewDocument` command.
|
|
*/
|
|
async initInTargets(cdpTargets, runImmediately) {
|
|
await Promise.all(Array.from(cdpTargets).map((cdpTarget) => this.initInTarget(cdpTarget, runImmediately)));
|
|
}
|
|
/**
|
|
* Adds the script to the given CDP target by calling the
|
|
* `Page.addScriptToEvaluateOnNewDocument` command.
|
|
*/
|
|
async initInTarget(cdpTarget, runImmediately) {
|
|
const addCdpPreloadScriptResult = await cdpTarget.cdpClient.sendCommand('Page.addScriptToEvaluateOnNewDocument', {
|
|
source: this.#getEvaluateString(),
|
|
worldName: this.#sandbox,
|
|
runImmediately,
|
|
});
|
|
this.#cdpPreloadScripts.push({
|
|
target: cdpTarget,
|
|
preloadScriptId: addCdpPreloadScriptResult.identifier,
|
|
});
|
|
this.#targetIds.add(cdpTarget.id);
|
|
}
|
|
/**
|
|
* Removes this script from all CDP targets.
|
|
*/
|
|
async remove() {
|
|
await Promise.all([
|
|
this.#cdpPreloadScripts.map(async (cdpPreloadScript) => {
|
|
const cdpTarget = cdpPreloadScript.target;
|
|
const cdpPreloadScriptId = cdpPreloadScript.preloadScriptId;
|
|
return await cdpTarget.cdpClient.sendCommand('Page.removeScriptToEvaluateOnNewDocument', {
|
|
identifier: cdpPreloadScriptId,
|
|
});
|
|
}),
|
|
]);
|
|
}
|
|
/** Removes the provided cdp target from the list of cdp preload scripts. */
|
|
dispose(cdpTargetId) {
|
|
this.#cdpPreloadScripts = this.#cdpPreloadScripts.filter((cdpPreloadScript) => cdpPreloadScript.target?.id !== cdpTargetId);
|
|
this.#targetIds.delete(cdpTargetId);
|
|
}
|
|
}
|
|
exports.PreloadScript = PreloadScript;
|
|
//# sourceMappingURL=PreloadScript.js.map
|