puppeteer.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright 2010-2019 Gildas Lormeau
  3. * contact : gildas.lormeau <at> gmail.com
  4. *
  5. * This file is part of SingleFile.
  6. *
  7. * The code in this file is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU Affero General Public License
  9. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * The code in this file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15. * General Public License for more details.
  16. *
  17. * As additional permission under GNU AGPL version 3 section 7, you may
  18. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  19. * AGPL normally required by section 4, provided you include this license
  20. * notice and a URL through which recipients can access the Corresponding
  21. * Source.
  22. */
  23. /* global require, exports, SingleFileBrowser, frameTree, lazyLoader, document, window */
  24. const fs = require("fs");
  25. const puppeteer = require("puppeteer-core");
  26. const SCRIPTS = [
  27. "../../lib/hooks/hooks-frame.js",
  28. "../../lib/frame-tree/content/content-frame-tree.js",
  29. "../../lib/lazy/content/content-lazy-loader.js",
  30. "../../lib/single-file/util/doc-util.js",
  31. "../../lib/single-file/util/doc-helper.js",
  32. "../../lib/single-file/util/timeout.js",
  33. "../../lib/single-file/vendor/css-tree.js",
  34. "../../lib/single-file/vendor/html-srcset-parser.js",
  35. "../../lib/single-file/vendor/css-minifier.js",
  36. "../../lib/single-file/vendor/css-font-property-parser.js",
  37. "../../lib/single-file/vendor/css-media-query-parser.js",
  38. "../../lib/single-file/modules/html-minifier.js",
  39. "../../lib/single-file/modules/css-fonts-minifier.js",
  40. "../../lib/single-file/modules/css-fonts-alt-minifier.js",
  41. "../../lib/single-file/modules/css-matched-rules.js",
  42. "../../lib/single-file/modules/css-medias-alt-minifier.js",
  43. "../../lib/single-file/modules/css-rules-minifier.js",
  44. "../../lib/single-file/modules/html-images-alt-minifier.js",
  45. "../../lib/single-file/modules/html-serializer.js",
  46. "../../lib/single-file/single-file-core.js",
  47. "../../lib/single-file/single-file-browser.js"
  48. ];
  49. exports.getPageData = async options => {
  50. const browserOptions = {};
  51. if (options.browserHeadless !== undefined) {
  52. browserOptions.headless = options.browserHeadless && !options.browserDebug;
  53. }
  54. browserOptions.args = [];
  55. if (options.browserDisableWebSecurity === undefined || options.browserDisableWebSecurity) {
  56. browserOptions.args.push("--disable-web-security");
  57. browserOptions.args.push("--no-pings");
  58. }
  59. if (!options.browserHeadless && options.browserDebug) {
  60. browserOptions.args.push("--auto-open-devtools-for-tabs");
  61. }
  62. if (options.browserExecutablePath) {
  63. browserOptions.executablePath = options.browserExecutablePath || "chrome";
  64. }
  65. let browser;
  66. try {
  67. browser = await puppeteer.launch(browserOptions);
  68. const page = await browser.newPage();
  69. if (options.userAgent) {
  70. await page.setUserAgent(options.userAgent);
  71. }
  72. if (options.browserWidth && options.browserHeight) {
  73. await page.setViewport({
  74. width: options.browserWidth,
  75. height: options.browserHeight
  76. });
  77. }
  78. if (options.browserBypassCSP === undefined || options.browserBypassCSP) {
  79. await page.setBypassCSP(true);
  80. }
  81. let scripts = SCRIPTS.map(scriptPath => fs.readFileSync(require.resolve(scriptPath)).toString()).join("\n");
  82. await page.evaluateOnNewDocument(scripts);
  83. if (options.browserDebug) {
  84. await page.waitFor(3000);
  85. }
  86. await page.goto(options.url, {
  87. waitUntil: options.browserWaitUntil || "networkidle0"
  88. });
  89. return await page.evaluate(async options => {
  90. options.insertSingleFileComment = true;
  91. const preInitializationPromises = [];
  92. if (!options.saveRawPage) {
  93. if (!options.removeFrames) {
  94. preInitializationPromises.push(frameTree.getAsync(options));
  95. }
  96. if (options.loadDeferredImages) {
  97. preInitializationPromises.push(lazyLoader.process(options));
  98. }
  99. }
  100. [options.framesData] = await Promise.all(preInitializationPromises);
  101. options.doc = document;
  102. options.win = window;
  103. const SingleFile = SingleFileBrowser.getClass();
  104. const singleFile = new SingleFile(options);
  105. await singleFile.run();
  106. return await singleFile.getPageData();
  107. }, options);
  108. } finally {
  109. if (browser && !options.browserDebug) {
  110. await browser.close();
  111. }
  112. }
  113. };