From 85bdcda74705fdde94b2656e9ac7599c79292de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=B1=84=EC=A4=80=20-=20CJ=20Lee?= Date: Thu, 13 Jul 2023 21:41:34 +0900 Subject: [PATCH] feat(client): close `vite-error-overlay` with Escape key (#13795) --- packages/vite/src/client/overlay.ts | 12 +++++++++++- playground/html/__tests__/html.spec.ts | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/client/overlay.ts b/packages/vite/src/client/overlay.ts index 30e0abf07267b5..9469dd5149a7e7 100644 --- a/packages/vite/src/client/overlay.ts +++ b/packages/vite/src/client/overlay.ts @@ -140,6 +140,7 @@ const codeframeRE = /^(?:>?\s+\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm const { HTMLElement = class {} as typeof globalThis.HTMLElement } = globalThis export class ErrorOverlay extends HTMLElement { root: ShadowRoot + closeOnEsc: (e: KeyboardEvent) => void constructor(err: ErrorPayload['err'], links = true) { super() @@ -171,9 +172,18 @@ export class ErrorOverlay extends HTMLElement { this.root.querySelector('.window')!.addEventListener('click', (e) => { e.stopPropagation() }) + this.addEventListener('click', () => { this.close() }) + + this.closeOnEsc = (e: KeyboardEvent) => { + if (e.key === 'Escape' || e.code === 'Escape') { + this.close() + } + } + + document.addEventListener('keydown', this.closeOnEsc) } text(selector: string, text: string, linkFiles = false): void { @@ -201,9 +211,9 @@ export class ErrorOverlay extends HTMLElement { } } } - close(): void { this.parentNode?.removeChild(this) + document.removeEventListener('keydown', this.closeOnEsc) } } diff --git a/playground/html/__tests__/html.spec.ts b/playground/html/__tests__/html.spec.ts index d588c2cae64ec6..815fc68f7b88c0 100644 --- a/playground/html/__tests__/html.spec.ts +++ b/playground/html/__tests__/html.spec.ts @@ -245,6 +245,26 @@ describe.runIf(isServe)('invalid', () => { expect(message).toMatch(/^Unable to parse HTML/) }) + test('should close overlay when clicked away', async () => { + await page.goto(viteTestUrl + '/invalid.html') + const errorOverlay = await page.waitForSelector('vite-error-overlay') + expect(errorOverlay).toBeTruthy() + + await page.click('html') + const isVisbleOverlay = await errorOverlay.isVisible() + expect(isVisbleOverlay).toBeFalsy() + }) + + test('should close overlay when escape key is pressed', async () => { + await page.goto(viteTestUrl + '/invalid.html') + const errorOverlay = await page.waitForSelector('vite-error-overlay') + expect(errorOverlay).toBeTruthy() + + await page.keyboard.press('Escape') + const isVisbleOverlay = await errorOverlay.isVisible() + expect(isVisbleOverlay).toBeFalsy() + }) + test('should reload when fixed', async () => { await page.goto(viteTestUrl + '/invalid.html') await editFile('invalid.html', (content) => {