@@ -52,6 +52,7 @@ export class BidiPage implements PageDelegate {
5252 readonly _networkManager: BidiNetworkManager;
5353 private readonly _pdf: BidiPDF;
5454 private _initScriptIds = new Map<InitScript, string>();
55+ readonly _frameNamePromises = new Map<string, Promise<string>>();
5556
5657 constructor(browserContext: BidiBrowserContext, bidiSession: BidiSession, opener: BidiPage | null) {
5758 this._session = bidiSession;
@@ -195,16 +196,31 @@ export class BidiPage implements PageDelegate {
195196
196197 private _onNavigationCommitted(params: bidi.BrowsingContext.NavigationInfo) {
197198 const frameId = params.context;
198- this._page.frameManager.frameCommittedNewDocumentNavigation(frameId, params.url, '', params.navigation!, /* initial */ false);
199+ const namePromise = this._frameNamePromises.get(frameId) ?? '';
200+ this._frameNamePromises.delete(frameId);
201+ this._page.frameManager.frameCommittedNewDocumentNavigation(frameId, params.url, namePromise, params.navigation!, /* initial */ false);
199202 }
200203
201- private _onDomContentLoaded(params: bidi.BrowsingContext.NavigationInfo) {
204+ private async _onDomContentLoaded(params: bidi.BrowsingContext.NavigationInfo) {
202205 const frameId = params.context;
206+ const frame = this._page.frameManager.frame(frameId)!;
207+ await this._waitForChildFrameNames(frame, false);
203208 this._page.frameManager.frameLifecycleEvent(frameId, 'domcontentloaded');
204209 }
205210
206- private _onLoad(params: bidi.BrowsingContext.NavigationInfo) {
207- this._page.frameManager.frameLifecycleEvent(params.context, 'load');
211+ private async _onLoad(params: bidi.BrowsingContext.NavigationInfo) {
212+ const frameId = params.context;
213+ const frame = this._page.frameManager.frame(frameId)!;
214+ await this._waitForChildFrameNames(frame, true);
215+ this._page.frameManager.frameLifecycleEvent(frameId, 'load');
216+ }
217+
218+ private async _waitForChildFrameNames(frame: frames.Frame, recursive: boolean) {
219+ for (const childFrame of frame.childFrames()) {
220+ await this._frameNamePromises.get(childFrame._id);
221+ if (recursive)
222+ await this._waitForChildFrameNames(childFrame, recursive);
223+ }
208224 }
209225
210226 private _onNavigationAborted(params: bidi.BrowsingContext.NavigationInfo) {
@@ -582,24 +598,24 @@ export class BidiPage implements PageDelegate {
582598 const parent = frame.parentFrame();
583599 if (!parent)
584600 throw new Error('Frame has been detached.');
585- const parentContext = await parent._mainContext();
586- const list = await parentContext.evaluateHandle(() => { return [...document.querySelectorAll('iframe,frame')]; });
587- const length = await list.evaluate(list => list.length);
588- let foundElement = null;
589- for (let i = 0; i < length; i++) {
590- const element = await list.evaluateHandle((list, i) => list[i], i);
591- const candidate = await element.contentFrame();
592- if (frame === candidate) {
593- foundElement = element;
594- break;
595- } else {
596- element.dispose();
597- }
598- }
599- list.dispose();
600- if (!foundElement)
601+ const node = await this._getFrameNode(frame);
602+ if (!node?.sharedId)
601603 throw new Error('Frame has been detached.');
602- return foundElement;
604+ const parentFrameExecutionContext = await parent._mainContext();
605+ return await toBidiExecutionContext(parentFrameExecutionContext).remoteObjectForNodeId(parentFrameExecutionContext, { sharedId: node.sharedId });
606+ }
607+
608+ async _getFrameNode(frame: frames.Frame): Promise<bidi.Script.NodeRemoteValue | undefined> {
609+ const parent = frame.parentFrame();
610+ if (!parent)
611+ return undefined;
612+
613+ const result = await this._session.send('browsingContext.locateNodes', {
614+ context: parent._id,
615+ locator: { type: 'context', value: { context: frame._id } },
616+ });
617+ const node = result.nodes[0];
618+ return node;
603619 }
604620
605621 shouldToggleStyleSheetToSyncAnimations(): boolean {
0 commit comments