From ffe5b63dbade012744f6a91a6f9a89b3615d5246 Mon Sep 17 00:00:00 2001 From: JoelEinbinder Date: Mon, 26 Feb 2018 12:10:06 -0800 Subject: [PATCH] chore: refactor Browser.js into seperate files (#2097) This patch splits Browser.js into multiple separate files. --- lib/Browser.js | 119 ++++++----------------------------------------- lib/Launcher.js | 2 +- lib/Target.js | 79 +++++++++++++++++++++++++++++++ lib/TaskQueue.js | 17 +++++++ lib/externs.d.ts | 12 ++++- 5 files changed, 122 insertions(+), 107 deletions(-) create mode 100644 lib/Target.js create mode 100644 lib/TaskQueue.js diff --git a/lib/Browser.js b/lib/Browser.js index e0bdfe88b3f..6e1e3e7ce6c 100644 --- a/lib/Browser.js +++ b/lib/Browser.js @@ -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} + * @return {!Promise} */ async newPage() { const {targetId} = await this._connection.send('Target.createTarget', {url: 'about:blank'}); @@ -121,7 +127,7 @@ class Browser extends EventEmitter { } /** - * @return {!Promise>} + * @return {!Promise>} */ 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} */ - 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} - */ - createCDPSession() { - return this._browser._connection.createSession(this._targetId); - } - - /** - * @return {!Promise} - */ - 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; diff --git a/lib/Launcher.js b/lib/Launcher.js index cc0a7d7e71d..909bef5a7d7 100644 --- a/lib/Launcher.js +++ b/lib/Launcher.js @@ -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'); diff --git a/lib/Target.js b/lib/Target.js new file mode 100644 index 00000000000..2df89384e1e --- /dev/null +++ b/lib/Target.js @@ -0,0 +1,79 @@ +const Page = require('./Page'); +const {helper} = require('./helper'); + +class Target { + /** + * @param {!Puppeteer.TargetInfo} targetInfo + * @param {!function():!Promise} 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} */ + 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} + */ + createCDPSession() { + return this._sessionFactory(); + } + + /** + * @return {!Promise} + */ + 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; \ No newline at end of file diff --git a/lib/TaskQueue.js b/lib/TaskQueue.js new file mode 100644 index 00000000000..78c2c88be08 --- /dev/null +++ b/lib/TaskQueue.js @@ -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; \ No newline at end of file diff --git a/lib/externs.d.ts b/lib/externs.d.ts index 0d2f36de889..112861ae0c7 100644 --- a/lib/externs.d.ts +++ b/lib/externs.d.ts @@ -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 {}