chore: contain remote objects to browser-specific code (#34890)

This commit is contained in:
Yury Semikhatsky 2025-02-21 16:52:39 -08:00 committed by GitHub
parent 6486ac006e
commit 962a752832
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 102 additions and 119 deletions

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
import { assert } from '../../utils';
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
import * as js from '../javascript';
import * as dom from '../dom';
@ -98,37 +99,26 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
if (response.type === 'success') {
if (returnByValue)
return parseEvaluationResultValue(BidiDeserializer.deserialize(response.result));
const objectId = 'handle' in response.result ? response.result.handle : undefined ;
return utilityScript._context.createHandle({ objectId, ...response.result });
return createHandle(utilityScript._context, response.result);
}
throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
}
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
const handle = this.createHandle(context, { objectId });
try {
const names = await handle.evaluate(object => {
const names = [];
const descriptors = Object.getOwnPropertyDescriptors(object);
for (const name in descriptors) {
if (descriptors[name]?.enumerable)
names.push(name);
}
return names;
});
const values = await Promise.all(names.map(name => handle.evaluateHandle((object, name) => object[name], name)));
const map = new Map<string, js.JSHandle>();
for (let i = 0; i < names.length; i++)
map.set(names[i], values[i]);
return map;
} finally {
handle.dispose();
}
}
createHandle(context: js.ExecutionContext, jsRemoteObject: js.RemoteObject): js.JSHandle {
const remoteObject: bidi.Script.RemoteValue = jsRemoteObject as bidi.Script.RemoteValue;
return new js.JSHandle(context, remoteObject.type, renderPreview(remoteObject), jsRemoteObject.objectId, remoteObjectValue(remoteObject));
async getProperties(context: js.ExecutionContext, handle: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const names = await handle.evaluate(object => {
const names = [];
const descriptors = Object.getOwnPropertyDescriptors(object);
for (const name in descriptors) {
if (descriptors[name]?.enumerable)
names.push(name);
}
return names;
});
const values = await Promise.all(names.map(name => handle.evaluateHandle((object, name) => object[name], name)));
const map = new Map<string, js.JSHandle>();
for (let i = 0; i < names.length; i++)
map.set(names[i], values[i]);
return map;
}
async releaseHandle(objectId: js.ObjectId): Promise<void> {
@ -149,11 +139,11 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
};
}
async remoteObjectForNodeId(nodeId: bidi.Script.SharedReference): Promise<js.RemoteObject> {
async remoteObjectForNodeId(context: dom.FrameExecutionContext, nodeId: bidi.Script.SharedReference): Promise<js.JSHandle> {
const result = await this._remoteValueForReference(nodeId);
if ('handle' in result)
return { objectId: result.handle!, ...result };
throw new Error('Can\'t get remote object for nodeId');
if (!('handle' in result))
throw new Error('Can\'t get remote object for nodeId');
return createHandle(context, result);
}
async contentFrameIdForFrame(handle: dom.ElementHandle) {
@ -215,3 +205,12 @@ function remoteObjectValue(remoteObject: bidi.Script.RemoteValue): any {
return remoteObject.value;
return undefined;
}
export function createHandle(context: js.ExecutionContext, remoteObject: bidi.Script.RemoteValue): js.JSHandle {
if (remoteObject.type === 'node') {
assert(context instanceof dom.FrameExecutionContext);
return new dom.ElementHandle(context, remoteObject.handle!);
}
const objectId = 'handle' in remoteObject ? remoteObject.handle : undefined;
return new js.JSHandle(context, remoteObject.type, renderPreview(remoteObject), objectId, remoteObjectValue(remoteObject));
}

View File

@ -20,7 +20,7 @@ import { BrowserContext } from '../browserContext';
import * as dialog from '../dialog';
import * as dom from '../dom';
import { Page } from '../page';
import { BidiExecutionContext } from './bidiExecutionContext';
import { BidiExecutionContext, createHandle } from './bidiExecutionContext';
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './bidiInput';
import { BidiNetworkManager } from './bidiNetworkManager';
import { BidiPDF } from './bidiPdf';
@ -130,7 +130,6 @@ export class BidiPage implements PageDelegate {
const frame = this._page._frameManager.frame(realmInfo.context);
if (!frame)
return;
const delegate = new BidiExecutionContext(this._session, realmInfo);
let worldName: types.World;
if (!realmInfo.sandbox) {
worldName = 'main';
@ -141,6 +140,7 @@ export class BidiPage implements PageDelegate {
} else {
return;
}
const delegate = new BidiExecutionContext(this._session, realmInfo);
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
(context as any)[contextDelegateSymbol] = delegate;
frame._contextCreated(worldName, context);
@ -242,7 +242,7 @@ export class BidiPage implements PageDelegate {
return;
const callFrame = params.stackTrace?.callFrames[0];
const location = callFrame ?? { url: '', lineNumber: 1, columnNumber: 1 };
this._page._addConsoleMessage(entry.method, entry.args.map(arg => context.createHandle({ objectId: (arg as any).handle, ...arg })), location, params.text || undefined);
this._page._addConsoleMessage(entry.method, entry.args.map(arg => createHandle(context, arg)), location, params.text || undefined);
}
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
@ -431,10 +431,6 @@ export class BidiPage implements PageDelegate {
return executionContext.frameIdForWindowHandle(windowHandle);
}
isElementHandle(remoteObject: bidi.Script.RemoteValue): boolean {
return remoteObject.type === 'node';
}
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
const box = await handle.evaluate(element => {
if (!(element instanceof Element))
@ -532,10 +528,7 @@ export class BidiPage implements PageDelegate {
const fromContext = toBidiExecutionContext(handle._context);
const nodeId = await fromContext.nodeIdForElementHandle(handle);
const executionContext = toBidiExecutionContext(to);
const objectId = await executionContext.remoteObjectForNodeId(nodeId);
if (objectId)
return to.createHandle(objectId) as dom.ElementHandle<T>;
throw new Error('Failed to adopt element handle.');
return await executionContext.remoteObjectForNodeId(to, nodeId) as dom.ElementHandle<T>;
}
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {

View File

@ -15,10 +15,12 @@
* limitations under the License.
*/
import { assert } from '../../utils/isomorphic/assert';
import { getExceptionMessage, releaseObject } from './crProtocolHelper';
import { rewriteErrorMessage } from '../../utils/isomorphic/stackTrace';
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
import * as js from '../javascript';
import * as dom from '../dom';
import { isSessionClosedError } from '../protocolError';
import type { CRSession } from './crConnection';
@ -69,27 +71,23 @@ export class CRExecutionContext implements js.ExecutionContextDelegate {
}).catch(rewriteError);
if (exceptionDetails)
throw new js.JavaScriptErrorInEvaluate(getExceptionMessage(exceptionDetails));
return returnByValue ? parseEvaluationResultValue(remoteObject.value) : utilityScript._context.createHandle(remoteObject);
return returnByValue ? parseEvaluationResultValue(remoteObject.value) : createHandle(utilityScript._context, remoteObject);
}
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._client.send('Runtime.getProperties', {
objectId,
objectId: object._objectId!,
ownProperties: true
});
const result = new Map();
for (const property of response.result) {
if (!property.enumerable || !property.value)
continue;
result.set(property.name, context.createHandle(property.value));
result.set(property.name, createHandle(object._context, property.value));
}
return result;
}
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}
async releaseHandle(objectId: js.ObjectId): Promise<void> {
await releaseObject(this._client, objectId);
}
@ -132,3 +130,11 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
return js.sparseArrayToString(object.preview.properties);
return object.description;
}
export function createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
if (remoteObject.subtype === 'node') {
assert(context instanceof dom.FrameExecutionContext);
return new dom.ElementHandle(context, remoteObject.objectId!);
}
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}

View File

@ -33,7 +33,7 @@ import { getAccessibilityTree } from './crAccessibility';
import { CRBrowserContext } from './crBrowser';
import { CRCoverage } from './crCoverage';
import { DragManager } from './crDragDrop';
import { CRExecutionContext } from './crExecutionContext';
import { createHandle, CRExecutionContext } from './crExecutionContext';
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './crInput';
import { CRNetworkManager } from './crNetworkManager';
import { CRPDF } from './crPdf';
@ -281,10 +281,6 @@ export class CRPage implements PageDelegate {
return this._sessionForHandle(handle)._getOwnerFrame(handle);
}
isElementHandle(remoteObject: any): boolean {
return (remoteObject as Protocol.Runtime.RemoteObject).subtype === 'node';
}
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
return this._sessionForHandle(handle)._getBoundingBox(handle);
}
@ -739,7 +735,7 @@ class FrameSession {
session.on('Target.attachedToTarget', event => this._onAttachedToTarget(event));
session.on('Target.detachedFromTarget', event => this._onDetachedFromTarget(event));
session.on('Runtime.consoleAPICalled', event => {
const args = event.args.map(o => worker._existingExecutionContext!.createHandle(o));
const args = event.args.map(o => createHandle(worker._existingExecutionContext!, o));
this._page._addConsoleMessage(event.type, args, toConsoleMessageLocation(event.stackTrace));
});
session.on('Runtime.exceptionThrown', exception => this._page.emitOnContextOnceInitialized(BrowserContext.Events.PageError, exceptionToError(exception.exceptionDetails), this._page));
@ -802,7 +798,7 @@ class FrameSession {
const context = this._contextIdToContext.get(event.executionContextId);
if (!context)
return;
const values = event.args.map(arg => context.createHandle(arg));
const values = event.args.map(arg => createHandle(context, arg));
this._page._addConsoleMessage(event.type, values, toConsoleMessageLocation(event.stackTrace));
}
@ -1171,7 +1167,7 @@ class FrameSession {
});
if (!result || result.object.subtype === 'null')
throw new Error(dom.kUnableToAdoptErrorMessage);
return to.createHandle(result.object).asElement()!;
return createHandle(to, result.object).asElement()!;
}
}

View File

@ -83,12 +83,6 @@ export class FrameExecutionContext extends js.ExecutionContext {
return js.evaluateExpression(this, expression, { ...options, returnByValue: false }, arg);
}
override createHandle(remoteObject: js.RemoteObject): js.JSHandle {
if (this.frame._page._delegate.isElementHandle(remoteObject))
return new ElementHandle(this, remoteObject.objectId!);
return super.createHandle(remoteObject);
}
injectedScript(): Promise<js.JSHandle<InjectedScript>> {
if (!this._injectedScriptPromise) {
const custom: string[] = [];
@ -124,7 +118,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
declare readonly _objectId: string;
readonly _frame: frames.Frame;
constructor(context: FrameExecutionContext, objectId: string) {
constructor(context: FrameExecutionContext, objectId: js.ObjectId) {
super(context, 'node', undefined, objectId);
this._page = context.frame._page;
this._frame = context.frame;

View File

@ -27,7 +27,7 @@ import { eventsHelper } from '../utils/eventsHelper';
import { validateBrowserContextOptions } from '../browserContext';
import { CRBrowser } from '../chromium/crBrowser';
import { CRConnection } from '../chromium/crConnection';
import { CRExecutionContext } from '../chromium/crExecutionContext';
import { createHandle, CRExecutionContext } from '../chromium/crExecutionContext';
import { toConsoleMessageLocation } from '../chromium/crProtocolHelper';
import { ConsoleMessage } from '../console';
import { helper } from '../helper';
@ -116,7 +116,7 @@ export class ElectronApplication extends SdkObject {
}
if (!this._nodeExecutionContext)
return;
const args = event.args.map(arg => this._nodeExecutionContext!.createHandle(arg));
const args = event.args.map(arg => createHandle(this._nodeExecutionContext!, arg));
const message = new ConsoleMessage(null, event.type, undefined, args, toConsoleMessageLocation(event.stackTrace));
this.emit(ElectronApplication.Events.Console, message);
}

View File

@ -15,9 +15,11 @@
* limitations under the License.
*/
import { assert } from '../../utils/isomorphic/assert';
import { rewriteErrorMessage } from '../../utils/isomorphic/stackTrace';
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
import * as js from '../javascript';
import * as dom from '../dom';
import { isSessionClosedError } from '../protocolError';
import type { FFSession } from './ffConnection';
@ -66,24 +68,20 @@ export class FFExecutionContext implements js.ExecutionContextDelegate {
checkException(payload.exceptionDetails);
if (returnByValue)
return parseEvaluationResultValue(payload.result!.value);
return utilityScript._context.createHandle(payload.result!);
return createHandle(utilityScript._context, payload.result!);
}
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._session.send('Runtime.getObjectProperties', {
executionContextId: this._executionContextId,
objectId,
objectId: object._objectId!,
});
const result = new Map();
for (const property of response.properties)
result.set(property.name, context.createHandle(property.value));
result.set(property.name, createHandle(context, property.value));
return result;
}
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type || '', renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}
async releaseHandle(objectId: js.ObjectId): Promise<void> {
await this._session.send('Runtime.disposeObject', {
executionContextId: this._executionContextId,
@ -135,3 +133,11 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
if ('value' in object)
return String(object.value);
}
export function createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
if (remoteObject.subtype === 'node') {
assert(context instanceof dom.FrameExecutionContext);
return new dom.ElementHandle(context, remoteObject.objectId!);
}
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type || '', renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}

View File

@ -22,7 +22,7 @@ import { InitScript } from '../page';
import { Page, Worker } from '../page';
import { getAccessibilityTree } from './ffAccessibility';
import { FFSession } from './ffConnection';
import { FFExecutionContext } from './ffExecutionContext';
import { createHandle, FFExecutionContext } from './ffExecutionContext';
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './ffInput';
import { FFNetworkManager } from './ffNetworkManager';
import { debugLogger } from '../utils/debugLogger';
@ -234,7 +234,7 @@ export class FFPage implements PageDelegate {
if (!context)
return;
// Juggler reports 'warn' for some internal messages generated by the browser.
this._page._addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => context.createHandle(arg)), location);
this._page._addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => createHandle(context, arg)), location);
}
_onDialogOpened(params: Protocol.Page.dialogOpenedPayload) {
@ -262,7 +262,7 @@ export class FFPage implements PageDelegate {
const context = this._contextIdToContext.get(executionContextId);
if (!context)
return;
const handle = context.createHandle(element).asElement()!;
const handle = createHandle(context, element).asElement()!;
await this._page._onFileChooserOpened(handle);
}
@ -286,7 +286,7 @@ export class FFPage implements PageDelegate {
workerSession.on('Runtime.console', event => {
const { type, args, location } = event;
const context = worker._existingExecutionContext!;
this._page._addConsoleMessage(type, args.map(arg => context.createHandle(arg)), location);
this._page._addConsoleMessage(type, args.map(arg => createHandle(context, arg)), location);
});
// Note: we receive worker exceptions directly from the page.
}
@ -443,10 +443,6 @@ export class FFPage implements PageDelegate {
return ownerFrameId || null;
}
isElementHandle(remoteObject: any): boolean {
return remoteObject.subtype === 'node';
}
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
const quads = await this.getContentQuads(handle);
if (!quads || !quads.length)
@ -535,7 +531,7 @@ export class FFPage implements PageDelegate {
});
if (!result.remoteObject)
throw new Error(dom.kUnableToAdoptErrorMessage);
return to.createHandle(result.remoteObject) as dom.ElementHandle<T>;
return createHandle(to, result.remoteObject) as dom.ElementHandle<T>;
}
async getAccessibilityTree(needle?: dom.ElementHandle) {
@ -564,7 +560,7 @@ export class FFPage implements PageDelegate {
});
if (!result.remoteObject)
throw new Error('Frame has been detached.');
return context.createHandle(result.remoteObject) as dom.ElementHandle;
return createHandle(context, result.remoteObject) as dom.ElementHandle;
}
shouldToggleStyleSheetToSyncAnimations(): boolean {

View File

@ -24,10 +24,6 @@ import type * as dom from './dom';
import type { UtilityScript } from './injected/utilityScript';
export type ObjectId = string;
export type RemoteObject = {
objectId?: ObjectId,
value?: any
};
interface TaggedAsJSHandle<T> {
__jshandle: T;
@ -55,8 +51,7 @@ export interface ExecutionContextDelegate {
rawEvaluateJSON(expression: string): Promise<any>;
rawEvaluateHandle(expression: string): Promise<ObjectId>;
evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: JSHandle<any>, values: any[], objectIds: ObjectId[]): Promise<any>;
getProperties(context: ExecutionContext, objectId: ObjectId): Promise<Map<string, JSHandle>>;
createHandle(context: ExecutionContext, remoteObject: RemoteObject): JSHandle;
getProperties(context: ExecutionContext, object: JSHandle): Promise<Map<string, JSHandle>>;
releaseHandle(objectId: ObjectId): Promise<void>;
}
@ -93,12 +88,8 @@ export class ExecutionContext extends SdkObject {
return this._raceAgainstContextDestroyed(this._delegate.evaluateWithArguments(expression, returnByValue, utilityScript, values, objectIds));
}
getProperties(context: ExecutionContext, objectId: ObjectId): Promise<Map<string, JSHandle>> {
return this._raceAgainstContextDestroyed(this._delegate.getProperties(context, objectId));
}
createHandle(remoteObject: RemoteObject): JSHandle {
return this._delegate.createHandle(this, remoteObject);
getProperties(context: ExecutionContext, object: JSHandle): Promise<Map<string, JSHandle>> {
return this._raceAgainstContextDestroyed(this._delegate.getProperties(context, object));
}
releaseHandle(objectId: ObjectId): Promise<void> {
@ -183,7 +174,7 @@ export class JSHandle<T = any> extends SdkObject {
async getProperties(): Promise<Map<string, JSHandle>> {
if (!this._objectId)
return new Map();
return this._context.getProperties(this._context, this._objectId);
return this._context.getProperties(this._context, this);
}
rawValue() {

View File

@ -75,7 +75,6 @@ export interface PageDelegate {
setBackgroundColor(color?: { r: number; g: number; b: number; a: number; }): Promise<void>;
takeScreenshot(progress: Progress, format: string, documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined, fitsViewport: boolean, scale: 'css' | 'device'): Promise<Buffer>;
isElementHandle(remoteObject: any): boolean;
adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>>;
getContentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null>; // Only called for frame owner elements.
getOwnerFrame(handle: dom.ElementHandle): Promise<string | null>; // Returns frameId.
@ -834,6 +833,7 @@ export class Worker extends SdkObject {
_createExecutionContext(delegate: js.ExecutionContextDelegate) {
this._existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
this._executionContextCallback(this._existingExecutionContext);
return this._existingExecutionContext;
}
url(): string {

View File

@ -17,7 +17,9 @@
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
import * as js from '../javascript';
import * as dom from '../dom';
import { isSessionClosedError } from '../protocolError';
import { assert } from '../../utils/isomorphic/assert';
import type { Protocol } from './protocol';
import type { WKSession } from './wkConnection';
@ -79,31 +81,26 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
throw new js.JavaScriptErrorInEvaluate(response.result.description);
if (returnByValue)
return parseEvaluationResultValue(response.result.value);
return utilityScript._context.createHandle(response.result);
return createHandle(utilityScript._context, response.result);
} catch (error) {
throw rewriteError(error);
}
}
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._session.send('Runtime.getProperties', {
objectId,
objectId: object._objectId!,
ownProperties: true
});
const result = new Map();
for (const property of response.properties) {
if (!property.enumerable || !property.value)
continue;
result.set(property.name, context.createHandle(property.value));
result.set(property.name, createHandle(context, property.value));
}
return result;
}
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
const isPromise = remoteObject.className === 'Promise';
return new js.JSHandle(context, isPromise ? 'promise' : remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}
async releaseHandle(objectId: js.ObjectId): Promise<void> {
await this._session.send('Runtime.releaseObject', { objectId });
}
@ -139,3 +136,12 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
return js.sparseArrayToString(object.preview.properties!);
return object.description;
}
export function createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
if (remoteObject.subtype === 'node') {
assert(context instanceof dom.FrameExecutionContext);
return new dom.ElementHandle(context as dom.FrameExecutionContext, remoteObject.objectId!);
}
const isPromise = remoteObject.className === 'Promise';
return new js.JSHandle(context, isPromise ? 'promise' : remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
}

View File

@ -34,7 +34,7 @@ import { PageBinding } from '../page';
import { Page } from '../page';
import { getAccessibilityTree } from './wkAccessibility';
import { WKSession } from './wkConnection';
import { WKExecutionContext } from './wkExecutionContext';
import { createHandle, WKExecutionContext } from './wkExecutionContext';
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './wkInput';
import { WKInterceptableRequest, WKRouteImpl } from './wkInterceptableRequest';
import { WKProvisionalPage } from './wkProvisionalPage';
@ -562,7 +562,7 @@ export class WKPage implements PageDelegate {
}
if (!context)
return;
handles.push(context.createHandle(p));
handles.push(createHandle(context, p));
}
this._lastConsoleMessage = {
derivedType,
@ -611,7 +611,7 @@ export class WKPage implements PageDelegate {
let handle;
try {
const context = await this._page._frameManager.frame(event.frameId)!._mainContext();
handle = context.createHandle(event.element).asElement()!;
handle = createHandle(context, event.element).asElement()!;
} catch (e) {
// During async processing, frame/context may go away. We should not throw.
return;
@ -869,10 +869,6 @@ export class WKPage implements PageDelegate {
return nodeInfo.ownerFrameId || null;
}
isElementHandle(remoteObject: any): boolean {
return (remoteObject as Protocol.Runtime.RemoteObject).subtype === 'node';
}
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
const quads = await this.getContentQuads(handle);
if (!quads || !quads.length)
@ -962,7 +958,7 @@ export class WKPage implements PageDelegate {
});
if (!result || result.object.subtype === 'null')
throw new Error(dom.kUnableToAdoptErrorMessage);
return to.createHandle(result.object) as dom.ElementHandle<T>;
return createHandle(to, result.object) as dom.ElementHandle<T>;
}
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
@ -986,7 +982,7 @@ export class WKPage implements PageDelegate {
});
if (!result || result.object.subtype === 'null')
throw new Error('Frame has been detached.');
return context.createHandle(result.object) as dom.ElementHandle;
return createHandle(context, result.object) as dom.ElementHandle;
}
private _maybeCancelCoopNavigationRequest(provisionalPage: WKProvisionalPage) {

View File

@ -17,7 +17,7 @@
import { eventsHelper } from '../utils/eventsHelper';
import { Worker } from '../page';
import { WKSession } from './wkConnection';
import { WKExecutionContext } from './wkExecutionContext';
import { createHandle, WKExecutionContext } from './wkExecutionContext';
import type { Protocol } from './protocol';
import type { RegisteredListener } from '../utils/eventsHelper';
@ -95,7 +95,7 @@ export class WKWorkers {
derivedType = 'timeEnd';
const handles = (parameters || []).map(p => {
return worker._existingExecutionContext!.createHandle(p);
return createHandle(worker._existingExecutionContext!, p);
});
const location: types.ConsoleMessageLocation = {
url: url || '',