123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- "use strict";
- /**
- * Copyright 2022 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.Realm = void 0;
- const protocol_js_1 = require("../../../protocol/protocol.js");
- const log_js_1 = require("../../../utils/log.js");
- const scriptEvaluator_js_1 = require("./scriptEvaluator.js");
- class Realm {
- #realmStorage;
- #browsingContextStorage;
- #realmId;
- #browsingContextId;
- #executionContextId;
- #origin;
- #type;
- #cdpClient;
- #eventManager;
- #scriptEvaluator;
- sandbox;
- cdpSessionId;
- #logger;
- constructor(realmStorage, browsingContextStorage, realmId, browsingContextId, executionContextId, origin, type, sandbox, cdpSessionId, cdpClient, eventManager, logger) {
- this.#realmId = realmId;
- this.#browsingContextId = browsingContextId;
- this.#executionContextId = executionContextId;
- this.sandbox = sandbox;
- this.#origin = origin;
- this.#type = type;
- this.cdpSessionId = cdpSessionId;
- this.#cdpClient = cdpClient;
- this.#realmStorage = realmStorage;
- this.#browsingContextStorage = browsingContextStorage;
- this.#eventManager = eventManager;
- this.#scriptEvaluator = new scriptEvaluator_js_1.ScriptEvaluator(this.#eventManager);
- this.#realmStorage.addRealm(this);
- this.#logger = logger;
- this.#eventManager.registerEvent({
- method: protocol_js_1.Script.EventNames.RealmCreated,
- params: this.toBiDi(),
- }, this.browsingContextId);
- }
- async #releaseObject(handle) {
- try {
- await this.cdpClient.sendCommand('Runtime.releaseObject', {
- objectId: handle,
- });
- }
- catch (e) {
- // Heuristic to determine if the problem is in the unknown handler.
- // Ignore the error if so.
- if (!(e.code === -32000 && e.message === 'Invalid remote object id')) {
- throw e;
- }
- }
- }
- async disown(handle) {
- // Disowning an object from different realm does nothing.
- if (this.#realmStorage.knownHandlesToRealm.get(handle) !== this.realmId) {
- return;
- }
- await this.#releaseObject(handle);
- this.#realmStorage.knownHandlesToRealm.delete(handle);
- }
- cdpToBidiValue(cdpValue, resultOwnership) {
- const deepSerializedValue = cdpValue.result.deepSerializedValue;
- const bidiValue = this.deepSerializedToBiDi(deepSerializedValue);
- if (cdpValue.result.objectId) {
- const objectId = cdpValue.result.objectId;
- if (resultOwnership === 'root') {
- // Extend BiDi value with `handle` based on required `resultOwnership`
- // and CDP response but not on the actual BiDi type.
- bidiValue.handle = objectId;
- // Remember all the handles sent to client.
- this.#realmStorage.knownHandlesToRealm.set(objectId, this.realmId);
- }
- else {
- // No need in awaiting for the object to be released.
- void this.#releaseObject(objectId).catch((error) => this.#logger?.(log_js_1.LogType.system, error));
- }
- }
- return bidiValue;
- }
- deepSerializedToBiDi(webDriverValue) {
- // This relies on the CDP to implement proper BiDi serialization, except
- // backendNodeId/sharedId and `platformobject`.
- const result = webDriverValue;
- if (Object.hasOwn(result, 'weakLocalObjectReference')) {
- result.internalId = `${result.weakLocalObjectReference}`;
- delete result['weakLocalObjectReference'];
- }
- // Platform object is a special case. It should have only `{type: object}`
- // without `value` field.
- if (result.type === 'platformobject') {
- return { type: 'object' };
- }
- const bidiValue = result.value;
- if (bidiValue === undefined) {
- return result;
- }
- if (result.type === 'node') {
- if (Object.hasOwn(bidiValue, 'backendNodeId')) {
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- result.sharedId = `${this.navigableId}${scriptEvaluator_js_1.SHARED_ID_DIVIDER}${bidiValue.backendNodeId}`;
- delete bidiValue['backendNodeId'];
- }
- if (Object.hasOwn(bidiValue, 'children')) {
- for (const i in bidiValue.children) {
- bidiValue.children[i] = this.deepSerializedToBiDi(bidiValue.children[i]);
- }
- }
- }
- // Recursively update the nested values.
- if (['array', 'set'].includes(webDriverValue.type)) {
- for (const i in bidiValue) {
- bidiValue[i] = this.deepSerializedToBiDi(bidiValue[i]);
- }
- }
- if (['object', 'map'].includes(webDriverValue.type)) {
- for (const i in bidiValue) {
- bidiValue[i] = [
- this.deepSerializedToBiDi(bidiValue[i][0]),
- this.deepSerializedToBiDi(bidiValue[i][1]),
- ];
- }
- }
- return result;
- }
- toBiDi() {
- return {
- realm: this.realmId,
- origin: this.origin,
- type: this.type,
- context: this.browsingContextId,
- ...(this.sandbox === undefined ? {} : { sandbox: this.sandbox }),
- };
- }
- get realmId() {
- return this.#realmId;
- }
- get navigableId() {
- return (this.#browsingContextStorage.findContext(this.#browsingContextId)
- ?.navigableId ?? 'UNKNOWN');
- }
- get browsingContextId() {
- return this.#browsingContextId;
- }
- get executionContextId() {
- return this.#executionContextId;
- }
- get origin() {
- return this.#origin;
- }
- get type() {
- return this.#type;
- }
- get cdpClient() {
- return this.#cdpClient;
- }
- async callFunction(functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions) {
- const context = this.#browsingContextStorage.getContext(this.browsingContextId);
- await context.awaitUnblocked();
- return {
- result: await this.#scriptEvaluator.callFunction(this, functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions),
- };
- }
- async scriptEvaluate(expression, awaitPromise, resultOwnership, serializationOptions) {
- const context = this.#browsingContextStorage.getContext(this.browsingContextId);
- await context.awaitUnblocked();
- return {
- result: await this.#scriptEvaluator.scriptEvaluate(this, expression, awaitPromise, resultOwnership, serializationOptions),
- };
- }
- /**
- * Serializes a given CDP object into BiDi, keeping references in the
- * target's `globalThis`.
- * @param cdpObject CDP remote object to be serialized.
- * @param resultOwnership Indicates desired ResultOwnership.
- */
- async serializeCdpObject(cdpObject, resultOwnership) {
- return this.#scriptEvaluator.serializeCdpObject(cdpObject, resultOwnership, this);
- }
- /**
- * Gets the string representation of an object. This is equivalent to
- * calling toString() on the object value.
- * @param cdpObject CDP remote object representing an object.
- * @return string The stringified object.
- */
- async stringifyObject(cdpObject) {
- return scriptEvaluator_js_1.ScriptEvaluator.stringifyObject(cdpObject, this);
- }
- delete() {
- this.#eventManager.registerEvent({
- method: protocol_js_1.Script.EventNames.RealmDestroyed,
- params: {
- realm: this.realmId,
- },
- }, this.browsingContextId);
- }
- }
- exports.Realm = Realm;
- //# sourceMappingURL=realm.js.map
|