Переглянути джерело

added support for playwright (wip)

Gildas 5 роки тому
батько
коміт
95efd156fe
4 змінених файлів з 101 додано та 3 видалено
  1. 1 1
      cli/args.js
  2. 97 0
      cli/back-ends/playwright-firefox.js
  3. 2 1
      cli/single-file-cli-api.js
  4. 1 1
      package.json

+ 1 - 1
cli/args.js

@@ -80,7 +80,7 @@ const args = require("yargs")
 		"crawl-rewrite-rules": []
 	})
 	.options("back-end", { description: "Back-end to use" })
-	.choices("back-end", ["jsdom", "puppeteer", "webdriver-chromium", "webdriver-gecko", "puppeteer-firefox"])
+	.choices("back-end", ["jsdom", "puppeteer", "webdriver-chromium", "webdriver-gecko", "puppeteer-firefox", "playwright-firefox"])
 	.options("browser-headless", { description: "Run the browser in headless mode (puppeteer, webdriver-gecko, webdriver-chromium)" })
 	.boolean("browser-headless")
 	.options("browser-executable-path", { description: "Path to chrome/chromium executable (puppeteer, webdriver-gecko, webdriver-chromium)" })

+ 97 - 0
cli/back-ends/playwright-firefox.js

@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010-2020 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   The code in this file is free software: you can redistribute it and/or 
+ *   modify it under the terms of the GNU Affero General Public License 
+ *   (GNU AGPL) as published by the Free Software Foundation, either version 3
+ *   of the License, or (at your option) any later version.
+ * 
+ *   The code in this file is distributed in the hope that it will be useful, 
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero 
+ *   General Public License for more details.
+ *
+ *   As additional permission under GNU AGPL version 3 section 7, you may 
+ *   distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU 
+ *   AGPL normally required by section 4, provided you include this license 
+ *   notice and a URL through which recipients can access the Corresponding 
+ *   Source.
+ */
+
+/* global singlefile, require, exports */
+
+const playwright = require("playwright").firefox;
+const scripts = require("./common/scripts.js");
+
+const NETWORK_IDLE_STATE = "networkidle0";
+
+let browser;
+
+exports.initialize = async options => {
+	browser = await playwright.launch(getBrowserOptions(options));
+};
+
+exports.getPageData = async options => {
+	let page;
+	try {
+		page = await browser.newPage({
+			bypassCSP: options.browserBypassCSP === undefined || options.browserBypassCSP
+		});
+		await setPageOptions(page, options);
+		return await getPageData(browser, page, options);
+	} finally {
+		if (page) {
+			await page.close();
+		}
+	}
+};
+
+exports.closeBrowser = () => {
+	if (browser) {
+		return browser.close();
+	}
+};
+
+function getBrowserOptions(options) {
+	const browserOptions = {};
+	if (options.browserHeadless !== undefined) {
+		browserOptions.headless = options.browserHeadless && !options.browserDebug;
+	}
+	browserOptions.args = options.browserArgs ? JSON.parse(options.browserArgs) : [];
+	if (options.browserExecutablePath) {
+		browserOptions.executablePath = options.browserExecutablePath || "firefox";
+	}
+	browserOptions.product = "firefox";
+	return browserOptions;
+}
+
+async function setPageOptions(page, options) {
+	if (options.browserWidth && options.browserHeight) {
+		await page.setViewportSize({
+			width: options.browserWidth,
+			height: options.browserHeight
+		});
+	}
+}
+
+async function getPageData(browser, page, options) {
+	const injectedScript = await scripts.get(options);
+	await page.addInitScript(injectedScript);
+	if (options.browserDebug) {
+		await page.waitForTimeout(3000);
+	}
+	await page.goto(options.url, {
+		timeout: options.browserLoadMaxTime || 0,
+		waitUntil: options.browserWaitUntil || NETWORK_IDLE_STATE
+	});
+	return await page.evaluate(async options => {
+		const pageData = await singlefile.lib.getPageData(options);
+		if (options.includeInfobar) {
+			await singlefile.common.ui.content.infobar.includeScript(pageData);
+		}
+		return pageData;
+	}, options);
+}

+ 2 - 1
cli/single-file-cli-api.js

@@ -34,7 +34,8 @@ const backEnds = {
 	puppeteer: "./back-ends/puppeteer.js",
 	"puppeteer-firefox": "./back-ends/puppeteer-firefox.js",
 	"webdriver-chromium": "./back-ends/webdriver-chromium.js",
-	"webdriver-gecko": "./back-ends/webdriver-gecko.js"
+	"webdriver-gecko": "./back-ends/webdriver-gecko.js",
+	"playwright-firefox": "./back-ends/playwright-firefox.js"
 };
 
 let backend, tasks = [], maxParallelWorkers = 8, sessionFilename;

+ 1 - 1
package.json

@@ -18,4 +18,4 @@
 		"strong-data-uri": "^1.0.6",
 		"yargs": "^15.4.1"
 	}
-}
+}