Simplify frame manager, do not fetch resources upfront (#159)

This patch:
- gets rid of Page.getResourceTree() protocol method
- rolls chromium to 490379

Fixes #127
This commit is contained in:
Pavel Feldman 2017-07-28 16:52:38 -07:00 committed by Andrey Lushnikov
parent bd767002bb
commit 7fdf800a39
3 changed files with 35 additions and 56 deletions

View File

@ -20,28 +20,17 @@ let EventEmitter = require('events');
let helper = require('./helper'); let helper = require('./helper');
class FrameManager extends EventEmitter { class FrameManager extends EventEmitter {
/**
* @param {!Connection} client
* @param {!Mouse} mouse
* @return {!Promise<!FrameManager>}
*/
static async create(client, mouse) {
let mainFramePayload = await client.send('Page.getResourceTree');
return new FrameManager(client, mainFramePayload.frameTree, mouse);
}
/** /**
* @param {!Connection} client * @param {!Connection} client
* @param {!Object} frameTree * @param {!Object} frameTree
* @param {!Mouse} mouse * @param {!Mouse} mouse
*/ */
constructor(client, frameTree, mouse) { constructor(client, mouse) {
super(); super();
this._client = client; this._client = client;
this._mouse = mouse; this._mouse = mouse;
/** @type {!Map<string, !Frame>} */ /** @type {!Map<string, !Frame>} */
this._frames = new Map(); this._frames = new Map();
this._mainFrame = this._addFramesRecursively(null, frameTree);
this._client.on('Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId)); this._client.on('Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId));
this._client.on('Page.frameNavigated', event => this._onFrameNavigated(event.frame)); this._client.on('Page.frameNavigated', event => this._onFrameNavigated(event.frame));
@ -82,13 +71,34 @@ class FrameManager extends EventEmitter {
* @param {!Object} framePayload * @param {!Object} framePayload
*/ */
_onFrameNavigated(framePayload) { _onFrameNavigated(framePayload) {
let frame = this._frames.get(framePayload.id); const isMainFrame = !framePayload.parentId;
if (!frame) { let frame = isMainFrame ? this._mainFrame : this._frames.get(framePayload.id);
// Simulate missed "frameAttached" for a main frame navigation to the new backend process. console.assert(isMainFrame || frame, 'We either navigate top level or have old version of the navigated frame');
console.assert(!framePayload.parentId, 'Main frame shouldn\'t have parent frame id.');
frame = this._mainFrame; // Detach all child frames first.
if (frame) {
for (let child of frame.childFrames())
this._removeFramesRecursively(child);
} }
this._navigateFrame(frame, framePayload);
// Update or create main frame.
if (isMainFrame) {
if (frame) {
// Update frame id to retain frame identity on cross-process navigation.
this._frames.delete(frame._id, frame);
frame._id = framePayload.id;
} else {
// Initial main frame navigation.
frame = new Frame(this._client, this._mouse, null, framePayload.id);
}
this._frames.set(framePayload.id, frame);
this._mainFrame = frame;
}
// Update frame payload.
frame._navigated(framePayload);
this.emit(FrameManager.Events.FrameNavigated, frame);
} }
/** /**
@ -106,40 +116,8 @@ class FrameManager extends EventEmitter {
if (!frame) if (!frame)
return; return;
frame._defaultContextId = context.id; frame._defaultContextId = context.id;
} for (let waitTask of frame._waitTasks)
waitTask.rerun();
/**
* @param {!Frame} frame
* @param {?Object} newFramePayload
*/
_navigateFrame(frame, newFramePayload) {
// Detach all child frames first.
for (let child of frame.childFrames())
this._removeFramesRecursively(child);
this._frames.delete(frame._id);
// Update frame id to retain frame identity.
frame._id = newFramePayload.id;
frame._navigated(newFramePayload);
this._frames.set(newFramePayload.id, frame);
this.emit(FrameManager.Events.FrameNavigated, frame);
}
/**
* @param {?Frame} parentFrame
* @param {!Object} frameTreePayload
* @return {!Frame}
*/
_addFramesRecursively(parentFrame, frameTreePayload) {
let framePayload = frameTreePayload.frame;
let frame = new Frame(this._client, this._mouse, parentFrame, framePayload.id);
frame._navigated(framePayload);
this._frames.set(frame._id, frame);
for (let i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
return frame;
} }
/** /**
@ -442,8 +420,6 @@ class Frame {
_navigated(framePayload) { _navigated(framePayload) {
this._name = framePayload.name; this._name = framePayload.name;
this._url = framePayload.url; this._url = framePayload.url;
for (let waitTask of this._waitTasks)
waitTask.rerun();
} }
_detach() { _detach() {

View File

@ -40,11 +40,12 @@ class Page extends EventEmitter {
]); ]);
const keyboard = new Keyboard(client); const keyboard = new Keyboard(client);
const mouse = new Mouse(client, keyboard); const mouse = new Mouse(client, keyboard);
const frameManager = await FrameManager.create(client, mouse); const frameManager = new FrameManager(client, mouse);
const networkManager = new NetworkManager(client); const networkManager = new NetworkManager(client);
const page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard); const page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard);
// Initialize default page size. // Initialize default page size.
await page.setViewport({width: 400, height: 300}); await page.setViewport({width: 400, height: 300});
await page.navigate('about:blank');
return page; return page;
} }
@ -273,6 +274,8 @@ class Page extends EventEmitter {
* @return {!Promise<?Response>} * @return {!Promise<?Response>}
*/ */
async reload(options) { async reload(options) {
if (!this.mainFrame())
return;
this._client.send('Page.reload'); this._client.send('Page.reload');
return this.waitForNavigation(options); return this.waitForNavigation(options);
} }

View File

@ -29,7 +29,7 @@
"ws": "^3.0.0" "ws": "^3.0.0"
}, },
"puppeteer": { "puppeteer": {
"chromium_revision": "488994" "chromium_revision": "490379"
}, },
"devDependencies": { "devDependencies": {
"commonmark": "^0.27.0", "commonmark": "^0.27.0",