chore: refactor Browser.js into seperate files (#2097)

This patch splits Browser.js into multiple separate files.
This commit is contained in:
JoelEinbinder 2018-02-26 12:10:06 -08:00 committed by Andrey Lushnikov
parent 8578283e11
commit ffe5b63dba
5 changed files with 122 additions and 107 deletions

View File

@ -14,9 +14,10 @@
* limitations under the License.
*/
const {helper} = require('./helper');
const Page = require('./Page');
const { helper } = require('./helper');
const Target = require('./Target');
const EventEmitter = require('events');
const TaskQueue = require('./TaskQueue');
class Browser extends EventEmitter {
/**
@ -63,10 +64,11 @@ class Browser extends EventEmitter {
}
/**
* @param {{targetInfo: !Target.TargetInfo}} event
* @param {{targetInfo: !Puppeteer.TargetInfo}} event
*/
async _targetCreated(event) {
const target = new Target(this, event.targetInfo);
const targetInfo = event.targetInfo;
const target = new Target(targetInfo, () => this._connection.createSession(targetInfo.targetId), this._ignoreHTTPSErrors, this._appMode, this._screenshotTaskQueue);
console.assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
this._targets.set(event.targetInfo.targetId, target);
@ -87,12 +89,16 @@ class Browser extends EventEmitter {
}
/**
* @param {{targetInfo: !Target.TargetInfo}} event
* @param {{targetInfo: !Puppeteer.TargetInfo}} event
*/
_targetInfoChanged(event) {
const target = this._targets.get(event.targetInfo.targetId);
console.assert(target, 'target should exist before targetInfoChanged');
const previousURL = target.url();
const wasInitialized = target._isInitialized;
target._targetInfoChanged(event.targetInfo);
if (wasInitialized && previousURL !== target.url())
this.emit(Browser.Events.TargetChanged, target);
}
/**
@ -103,7 +109,7 @@ class Browser extends EventEmitter {
}
/**
* @return {!Promise<!Page>}
* @return {!Promise<!Puppeteer.Page>}
*/
async newPage() {
const {targetId} = await this._connection.send('Target.createTarget', {url: 'about:blank'});
@ -121,7 +127,7 @@ class Browser extends EventEmitter {
}
/**
* @return {!Promise<!Array<!Page>>}
* @return {!Promise<!Array<!Puppeteer.Page>>}
*/
async pages() {
const pages = await Promise.all(this.targets().map(target => target.page()));
@ -171,101 +177,4 @@ Browser.Events = {
helper.tracePublicAPI(Browser);
class TaskQueue {
constructor() {
this._chain = Promise.resolve();
}
/**
* @param {function()} task
* @return {!Promise}
*/
postTask(task) {
const result = this._chain.then(task);
this._chain = result.catch(() => {});
return result;
}
}
class Target {
/**
* @param {!Browser} browser
* @param {!Target.TargetInfo} targetInfo
*/
constructor(browser, targetInfo) {
this._browser = browser;
this._targetId = targetInfo.targetId;
this._targetInfo = targetInfo;
/** @type {?Promise<!Page>} */
this._pagePromise = null;
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill);
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
if (this._isInitialized)
this._initializedCallback(true);
}
/**
* @return {!Promise<!Puppeteer.CDPSession>}
*/
createCDPSession() {
return this._browser._connection.createSession(this._targetId);
}
/**
* @return {!Promise<?Page>}
*/
async page() {
if (this._targetInfo.type === 'page' && !this._pagePromise) {
this._pagePromise = this._browser._connection.createSession(this._targetId)
.then(client => Page.create(client, this, this._browser._ignoreHTTPSErrors, this._browser._appMode, this._browser._screenshotTaskQueue));
}
return this._pagePromise;
}
/**
* @return {string}
*/
url() {
return this._targetInfo.url;
}
/**
* @return {"page"|"service_worker"|"other"|"browser"}
*/
type() {
const type = this._targetInfo.type;
if (type === 'page' || type === 'service_worker' || type === 'browser')
return type;
return 'other';
}
/**
* @param {!Target.TargetInfo} targetInfo
*/
_targetInfoChanged(targetInfo) {
const previousURL = this._targetInfo.url;
this._targetInfo = targetInfo;
if (!this._isInitialized && (this._targetInfo.type !== 'page' || this._targetInfo.url !== '')) {
this._isInitialized = true;
this._initializedCallback(true);
return;
}
if (previousURL !== targetInfo.url)
this._browser.emit(Browser.Events.TargetChanged, this);
}
}
helper.tracePublicAPI(Target);
/**
* @typedef {Object} Target.TargetInfo
* @property {string} type
* @property {string} targetId
* @property {string} title
* @property {string} url
* @property {boolean} attached
*/
module.exports = { Browser, TaskQueue, Target };
module.exports = Browser;

View File

@ -19,7 +19,7 @@ const removeFolder = require('rimraf');
const childProcess = require('child_process');
const BrowserFetcher = require('./BrowserFetcher');
const {Connection} = require('./Connection');
const {Browser} = require('./Browser');
const Browser = require('./Browser');
const readline = require('readline');
const fs = require('fs');
const {helper} = require('./helper');

79
lib/Target.js Normal file
View File

@ -0,0 +1,79 @@
const Page = require('./Page');
const {helper} = require('./helper');
class Target {
/**
* @param {!Puppeteer.TargetInfo} targetInfo
* @param {!function():!Promise<!Puppeteer.CDPSession>} sessionFactory
* @param {boolean} ignoreHTTPSErrors
* @param {boolean} appMode
* @param {!Puppeteer.TaskQueue} screenshotTaskQueue
*/
constructor(targetInfo, sessionFactory, ignoreHTTPSErrors, appMode, screenshotTaskQueue) {
this._targetInfo = targetInfo;
this._targetId = targetInfo.targetId;
this._sessionFactory = sessionFactory;
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
this._appMode = appMode;
this._screenshotTaskQueue = screenshotTaskQueue;
/** @type {?Promise<!Puppeteer.Page>} */
this._pagePromise = null;
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill);
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
if (this._isInitialized)
this._initializedCallback(true);
}
/**
* @return {!Promise<!Puppeteer.CDPSession>}
*/
createCDPSession() {
return this._sessionFactory();
}
/**
* @return {!Promise<?Page>}
*/
async page() {
if (this._targetInfo.type === 'page' && !this._pagePromise) {
this._pagePromise = this._sessionFactory()
.then(client => Page.create(client, this, this._ignoreHTTPSErrors, this._appMode, this._screenshotTaskQueue));
}
return this._pagePromise;
}
/**
* @return {string}
*/
url() {
return this._targetInfo.url;
}
/**
* @return {"page"|"service_worker"|"other"|"browser"}
*/
type() {
const type = this._targetInfo.type;
if (type === 'page' || type === 'service_worker' || type === 'browser')
return type;
return 'other';
}
/**
* @param {!Puppeteer.TargetInfo} targetInfo
*/
_targetInfoChanged(targetInfo) {
this._targetInfo = targetInfo;
if (!this._isInitialized && (this._targetInfo.type !== 'page' || this._targetInfo.url !== '')) {
this._isInitialized = true;
this._initializedCallback(true);
return;
}
}
}
helper.tracePublicAPI(Target);
module.exports = Target;

17
lib/TaskQueue.js Normal file
View File

@ -0,0 +1,17 @@
class TaskQueue {
constructor() {
this._chain = Promise.resolve();
}
/**
* @param {function()} task
* @return {!Promise}
*/
postTask(task) {
const result = this._chain.then(task);
this._chain = result.catch(() => {});
return result;
}
}
module.exports = TaskQueue;

12
lib/externs.d.ts vendored
View File

@ -1,6 +1,8 @@
import { Connection as RealConnection, CDPSession as RealCDPSession } from './Connection.js';
import {Browser as RealBrowser, TaskQueue as RealTaskQueue, Target as RealTarget} from './Browser.js';
import * as RealBrowser from './Browser.js';
import * as RealTarget from './Target.js';
import * as RealPage from './Page.js';
import * as RealTaskQueue from './TaskQueue.js';
import {Mouse as RealMouse, Keyboard as RealKeyboard, Touchscreen as RealTouchscreen} from './Input.js';
import {Frame as RealFrame, FrameManager as RealFrameManager} from './FrameManager.js';
import {JSHandle as RealJSHandle, ExecutionContext as RealExecutionContext} from './ExecutionContext.js';
@ -30,4 +32,12 @@ export interface ConnectionTransport extends NodeJS.EventEmitter {
close();
}
export interface TargetInfo {
type: string;
targetId: string;
title: string;
url: string;
attached: boolean;
}
export interface ChildProcess extends child_process.ChildProcess {}