From 7f72e6b49c3fae3b748ce7e60f970b07bb0346b6 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Mon, 25 Sep 2023 02:57:13 +0900 Subject: [PATCH 1/5] Make previewable the in-memory huge content As same as #551, the preview window may fail to open data URI due to the limitation of the display length.. If passed data URI to the preview window, Marp CLI try to convert to Blob URL and open it instead. --- src/preview.ts | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/preview.ts b/src/preview.ts index 521b3350..a9ecb689 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -4,7 +4,7 @@ import { nanoid } from 'nanoid' import type { Page, Browser, Target } from 'puppeteer-core' import TypedEmitter from 'typed-emitter' import { ConvertType, mimeTypes } from './converter' -import { error } from './error' +import { CLIError, error } from './error' import { File, FileType } from './file' import { generatePuppeteerDataDirPath, @@ -93,7 +93,24 @@ export class Preview extends (EventEmitter as new () => TypedEmitter { - await page.goto(uri, { timeout: 0, waitUntil: 'domcontentloaded' }) + if (uri.startsWith('data:')) { + // A data URI with a huge size may fail opening with a browser due to the limitation of URL length. + // If received a data URI, try to open it with a converted Blob URL. + await Promise.all([ + page.waitForNavigation({ + timeout: 5000, + waitUntil: 'domcontentloaded', + }), + page.evaluate(async (uri) => { + const res = await fetch(uri, { cache: 'no-cache' }) + const blob = await res.blob() + location.href = URL.createObjectURL(blob) + }, uri), + ]) + } else { + await page.goto(uri, { timeout: 0, waitUntil: 'domcontentloaded' }) + } + await page .target() .createCDPSession() @@ -126,13 +143,12 @@ export class Preview extends (EventEmitter as new () => TypedEmitter { - for (const page of await pptr.pages()) { - await page.evaluate( - `window.open('about:blank?__marp_cli_id=${id}', '', 'width=${this.options.width},height=${this.options.height}')` - ) - break - } + void (async () => { + const [page] = await pptr.pages() + + await page.evaluate( + `window.open('about:blank?__marp_cli_id=${id}', '', 'width=${this.options.width},height=${this.options.height}')` + ) })() }) ) From 19f0b943861f2228dc215b340fa62318a7b8717f Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Mon, 25 Sep 2023 03:00:05 +0900 Subject: [PATCH 2/5] Fix ESLint --- src/preview.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preview.ts b/src/preview.ts index a9ecb689..36f36a2a 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -4,7 +4,7 @@ import { nanoid } from 'nanoid' import type { Page, Browser, Target } from 'puppeteer-core' import TypedEmitter from 'typed-emitter' import { ConvertType, mimeTypes } from './converter' -import { CLIError, error } from './error' +import { error } from './error' import { File, FileType } from './file' import { generatePuppeteerDataDirPath, From 42762031b9249c841eabe06c639c0b2fa1532fc1 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Sat, 30 Sep 2023 23:11:00 +0900 Subject: [PATCH 3/5] Improve stability of preview window on macOS --- src/preview.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/preview.ts b/src/preview.ts index 36f36a2a..2298eb91 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -14,6 +14,8 @@ import { } from './utils/puppeteer' import { isChromeInWSLHost } from './utils/wsl' +const emptyPageURI = `data:text/html;base64,PHRpdGxlPk1hcnAgQ0xJPC90aXRsZT4` // Marp CLI + export namespace Preview { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- TypedEmitter requires type definition instead of interface export type Events = { @@ -165,10 +167,10 @@ export class Preview extends (EventEmitter as new () => TypedEmitter${encodeURIComponent('Marp CLI')}`, + `--app=${emptyPageURI}`, `--window-size=${this.options.width},${this.options.height}`, ], - defaultViewport: null as any, + defaultViewport: null, headless: process.env.NODE_ENV === 'test' ? enableHeadless() : false, ignoreDefaultArgs: ['--enable-automation'], userDataDir: await generatePuppeteerDataDirPath('marp-cli-preview', { @@ -193,6 +195,7 @@ export class Preview extends (EventEmitter as new () => TypedEmitter Date: Mon, 2 Oct 2023 01:02:27 +0900 Subject: [PATCH 4/5] Always reload empty page on initializing preview window --- src/preview.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preview.ts b/src/preview.ts index 2298eb91..6ca45e9f 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -189,13 +189,13 @@ export class Preview extends (EventEmitter as new () => TypedEmitter Date: Mon, 2 Oct 2023 01:11:08 +0900 Subject: [PATCH 5/5] [ci skip] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5203d031..2517add9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Improve stability of in-memory preview for large content ([#553](https://github.com/marp-team/marp-cli/pull/553)) + ## v3.3.0 - 2023-09-23 ### Added