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:
parent
bd767002bb
commit
7fdf800a39
@ -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() {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user