UNPKG

puppeteer-pro

Version:

A simple puppeteer wrapper to enable useful plugins with ease

159 lines 6.12 kB
"use strict"; /* eslint-disable prefer-rest-params */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Plugin = void 0; const shared_1 = require("./shared"); class Plugin { constructor() { this.browser = null; this.initialized = false; this.startCounter = 0; this.dependencies = []; this.requiresInterception = false; } get isInitialized() { return this.initialized; } get isStopped() { return this.startCounter === 0; } async addDependency(plugin) { this.dependencies.push(plugin); } async init(browser) { if (this.initialized) return; this.browser = browser; const offOnClose = []; browser.browserEvents.once('close', async () => { offOnClose.forEach(fn => fn()); this.browser = null; this.initialized = false; this.startCounter = 0; await this.onClose(); }); this.startCounter++; const thisOnTargetCreated = this.onTargetCreated.bind(this); browser.on('targetcreated', thisOnTargetCreated); offOnClose.push(() => browser.off('targetcreated', thisOnTargetCreated)); this.initialized = true; this.dependencies.forEach(x => x.init(browser)); return this.afterLaunch(browser); } async afterLaunch(_browser) { null; } async onClose() { null; } async onTargetCreated(target) { if (this.isStopped) return; if (target.type() !== 'page') return; const page = (0, shared_1.newPage)(await target.page()); if (page.isClosed()) return; const offOnClose = []; page.once('close', async () => { offOnClose.forEach(fn => fn()); }); const requestHandlers = []; page.on('request', request => { const _respond = request.respond; let responded = 0; let respondArgs; const _abort = request.abort; let aborted = 0; let abortArgs; const _continue = request.continue; let continued = 0; let continueArgs; const handleRequest = async function () { const total = responded + aborted + continued; if (!request._interceptionHandled) { if (responded === 1) await _respond.apply(request, respondArgs); else if (responded === 0 && aborted >= 1 && total === requestHandlers.length) await _abort.apply(request, abortArgs); else if (continued === requestHandlers.length) await _continue.apply(request, continueArgs); } }; request.respond = async function () { responded++; respondArgs = respondArgs || arguments; await handleRequest(); }; request.abort = async function () { aborted++; abortArgs = abortArgs || arguments; await handleRequest(); }; request.continue = async function () { continued++; continueArgs = continueArgs || arguments; await handleRequest(); }; requestHandlers.forEach(handler => handler(request)); }); const _pageOn = page.on; page.on = function async(eventName, handler) { if (eventName === 'request') { requestHandlers.push(handler); return page; } else { return _pageOn.call(page, eventName, handler); } }; if (this.requiresInterception) { await page.setRequestInterception(true); const thisOnRequest = this.onRequest.bind(this); page.on('request', thisOnRequest); offOnClose.push(() => page.off('request', thisOnRequest)); } const thisOnDialog = this.onDialog.bind(this); page.on('dialog', thisOnDialog); offOnClose.push(() => page.off('dialog', thisOnDialog)); await this.onPageCreated(page); } async onPageCreated(_page) { null; } async onRequest(request) { const interceptionHandled = request._interceptionHandled; if (interceptionHandled) return; if (this.isStopped) return request.continue(); await this.processRequest(request); } async processRequest(_request) { null; } async onDialog(dialog) { if (this.isStopped) return; const _dismiss = dialog.dismiss; dialog.dismiss = async () => { if (dialog.handled) return; await _dismiss.apply(dialog); }; await this.processDialog(dialog); } async processDialog(_dialog) { null; } async beforeRestart() { null; } async restart() { await this.beforeRestart(); this.startCounter++; if (this.requiresInterception && this.browser) this.browser.interceptions++; this.dependencies.forEach(x => x.restart()); await this.afterRestart(); } async afterRestart() { null; } async beforeStop() { null; } async stop() { await this.beforeStop(); this.startCounter--; if (this.requiresInterception && this.browser) this.browser.interceptions--; if (this.browser && this.browser.interceptions === 0) { const pages = await this.browser.pages(); pages.filter(x => !x.isClosed()).forEach(async (page) => { await page.setRequestInterception(false); }); } this.dependencies.forEach(x => x.stop()); await this.afterStop(); } async afterStop() { null; } async getFirstPage() { if (!this.browser) return null; const pages = await this.browser.pages(); const openPages = pages.filter(x => !x.isClosed()); const activePages = pages.filter(x => x.url() !== 'about:blank'); return activePages[0] || openPages[0]; } } exports.Plugin = Plugin; //# sourceMappingURL=index.js.map