From ae0ba037719d22b63c38722312ba3563d731e660 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Thu, 8 Apr 2021 10:00:40 -0700 Subject: [PATCH 1/9] Restore accidentally commented webkit/firefox test browsers --- web-test-runner.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-test-runner.config.js b/web-test-runner.config.js index 43f07f9b..e47e4786 100644 --- a/web-test-runner.config.js +++ b/web-test-runner.config.js @@ -15,7 +15,7 @@ export default { nodeResolve: true, browsers: [ playwrightLauncher({product: 'chromium'}), - // playwrightLauncher({product: 'webkit'}), + playwrightLauncher({product: 'webkit'}), // Playwright Firefox does not seem to work at all with Service Workers. The // issue can be reproduced by launching Firefox with flag "-juggler 0". So // for now we'll use Puppeteer for Firefox. @@ -27,7 +27,7 @@ export default { // // TODO(aomarks) Look into this a little more and file an issue on // Playwright (or Firefox). - // puppeteerLauncher({launchOptions: {product: 'firefox'}}), + puppeteerLauncher({launchOptions: {product: 'firefox'}}), ], browserStartTimeout: 30000, // default 30000 testsStartTimeout: 20000, // default 10000 From d7ba36be358829c75c2f5ccf0c6d2bdbb03e36cd Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Thu, 8 Apr 2021 08:40:26 -0700 Subject: [PATCH 2/9] Switch to contenteditable inputStyle, for a11y --- CHANGELOG.md | 7 ++++++- src/playground-code-editor.ts | 1 + src/test/playground-ide_test.ts | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab0cfb86..43a8285c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - +## Unreleased + +### Changed + +- The editor now uses the CodeMirror `contenteditable` input style, which has + much better screen reader support. ## [0.8.0] - 2021-04-02 diff --git a/src/playground-code-editor.ts b/src/playground-code-editor.ts index 288e57bd..b0a8442b 100644 --- a/src/playground-code-editor.ts +++ b/src/playground-code-editor.ts @@ -273,6 +273,7 @@ export class PlaygroundCodeEditor extends LitElement { lineNumbers: this.lineNumbers, mode: this._getLanguageMode(), readOnly: this.readonly, + inputStyle: 'contenteditable', } ); cm.on('change', () => { diff --git a/src/test/playground-ide_test.ts b/src/test/playground-ide_test.ts index 64fd90bd..463e231a 100644 --- a/src/test/playground-ide_test.ts +++ b/src/test/playground-ide_test.ts @@ -217,4 +217,26 @@ suite('playground-ide', () => { }; await assertPreviewContains('Hello HTML'); }); + + test('a11y: is contenteditable', async () => { + const ide = document.createElement('playground-ide'); + ide.config = { + files: { + 'index.html': { + content: 'Foo\nBar', + }, + }, + }; + container.appendChild(ide); + await assertPreviewContains('Foo'); + + const cmCode = await pierce( + 'playground-ide', + 'playground-file-editor', + 'playground-code-editor', + '.CodeMirror-code' + ); + + assert.equal(cmCode.getAttribute('contenteditable'), 'true'); + }); }); From 94d1bb87a132a19aef409b2f64ff1aaa6fc9a8a7 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Thu, 8 Apr 2021 09:53:08 -0700 Subject: [PATCH 3/9] Annote line numbers with aria-hidden --- CHANGELOG.md | 3 +++ src/playground-code-editor.ts | 39 +++++++++++++++++++++++++++ src/test/playground-ide_test.ts | 48 ++++++++++++++++++++++++++++++++- tsconfig.json | 2 +- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a8285c..6ad6e14b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - The editor now uses the CodeMirror `contenteditable` input style, which has much better screen reader support. +- Line numbers are now annotated with `aria-hidden` so that they are not voiced + by screen readers. + ## [0.8.0] - 2021-04-02 ### Added diff --git a/src/playground-code-editor.ts b/src/playground-code-editor.ts index b0a8442b..e8ced2aa 100644 --- a/src/playground-code-editor.ts +++ b/src/playground-code-editor.ts @@ -189,6 +189,7 @@ export class PlaygroundCodeEditor extends LitElement { this._valueChangingFromOutside = false; break; case 'lineNumbers': + this._enableOrDisableAriaLineNumberObserver(); cm.setOption('lineNumbers', this.lineNumbers); break; case 'type': @@ -256,6 +257,7 @@ export class PlaygroundCodeEditor extends LitElement { const cm = CodeMirror( (dom) => { this._cmDom = dom; + this._enableOrDisableAriaLineNumberObserver(); this._resizing = true; requestAnimationFrame(() => { requestAnimationFrame(() => { @@ -296,6 +298,43 @@ export class PlaygroundCodeEditor extends LitElement { this._codemirror = cm; } + private _ariaLineNumberObserver?: MutationObserver; + + /** + * Prevent screen readers from voicing line numbers. + * + * When line numbers are active, watch for lines inserted into the DOM by + * CodeMirror, and add the "aria-hidden" attribute to their line numbers. + * + * See https://github.com/codemirror/CodeMirror/issues/6578 + */ + private _enableOrDisableAriaLineNumberObserver() { + if (this.lineNumbers && !this._ariaLineNumberObserver) { + // Start observing newly added lines. + const linesParent = this._cmDom?.querySelector('.CodeMirror-code'); + if (!linesParent) { + console.error('Internal playground error: .CodeMirror-code missing'); + return; + } + this._ariaLineNumberObserver = new MutationObserver((mutations) => { + for (const mutation of mutations) { + for (const node of mutation.addedNodes) { + // Could be e.g. a text node. Cast so we can check for presence of + // querySelector with optional chaining instead of a typeof test. + (node as Partial) + .querySelector?.('.CodeMirror-gutter-wrapper') + ?.setAttribute('aria-hidden', 'true'); + } + } + }); + this._ariaLineNumberObserver.observe(linesParent, {childList: true}); + } else if (!this.lineNumbers && this._ariaLineNumberObserver) { + // Line numbers are no longer rendering. + this._ariaLineNumberObserver.disconnect(); + this._ariaLineNumberObserver = undefined; + } + } + /** * Create hidden and folded regions for playground-hide and playground-fold * comments. diff --git a/src/test/playground-ide_test.ts b/src/test/playground-ide_test.ts index 463e231a..c50163d0 100644 --- a/src/test/playground-ide_test.ts +++ b/src/test/playground-ide_test.ts @@ -223,7 +223,7 @@ suite('playground-ide', () => { ide.config = { files: { 'index.html': { - content: 'Foo\nBar', + content: 'Foo', }, }, }; @@ -239,4 +239,50 @@ suite('playground-ide', () => { assert.equal(cmCode.getAttribute('contenteditable'), 'true'); }); + + test('a11y: line numbers get aria-hidden attribute', async () => { + const ide = document.createElement('playground-ide'); + ide.lineNumbers = true; + ide.config = { + files: { + 'index.html': { + content: 'Foo\nBar', + }, + }, + }; + container.appendChild(ide); + await assertPreviewContains('Foo\nBar'); + + const editor = (await pierce( + 'playground-ide', + 'playground-file-editor', + 'playground-code-editor' + )) as PlaygroundCodeEditor; + + const queryHiddenLineNumbers = () => + [ + ...editor.shadowRoot!.querySelectorAll('.CodeMirror-gutter-wrapper'), + ].filter((gutter) => gutter.getAttribute('aria-hidden') === 'true'); + + // Initial render with line-numbers enabled. + assert.equal(queryHiddenLineNumbers().length, 2); + + // Disable line numbers. + ide.lineNumbers = false; + await new Promise((r) => requestAnimationFrame(r)); + assert.equal(queryHiddenLineNumbers().length, 0); + + // Re-enable line numbers. + ide.lineNumbers = true; + await new Promise((r) => requestAnimationFrame(r)); + assert.equal(queryHiddenLineNumbers().length, 2); + + // Add a line. + const editorInternals = (editor as unknown) as { + _codemirror: PlaygroundCodeEditor['_codemirror']; + }; + editorInternals._codemirror!.setValue(editor.value + '\nBaz'); + await new Promise((r) => requestAnimationFrame(r)); + assert.equal(queryHiddenLineNumbers().length, 3); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 66488ca8..f1b38d08 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "incremental": true, "target": "es2019", "module": "esnext", - "lib": ["ES2020", "ES2015.iterable", "DOM"], + "lib": ["ES2020", "ES2015.iterable", "DOM", "DOM.Iterable"], "declaration": true, "declarationMap": true, "sourceMap": false, From f44a34b5f867fcc105cfa921afa620b60bb8c78d Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Fri, 9 Apr 2021 09:13:44 -0700 Subject: [PATCH 4/9] Fix broken README table formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6905680b..8f403c76 100644 --- a/README.md +++ b/README.md @@ -534,12 +534,12 @@ project element. ### Properties | Name         |  Type | Default   | Description | -| ---------------- | ----------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------- | --- | +| ---------------- | ----------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------- | | `projectSrc` | `string` | `undefined` | URL of a [project files manifest](#option-2-json-manifest) to load. | | `files` | `SampleFile[]` | `undefined` | Get or set the array of project files ([details](#option-3-files-property)). | | `sandboxScope` | `string` | `"playground-elements"` | The service worker scope to register on. | | `sandboxBaseUrl` | `string` | _module parent directory_ | Base URL for script execution sandbox ([details](#sandbox)). | -| `diagnostics` | `Map` | `undefined` | Map from filename to array of Language Server Protocol diagnostics resulting from the latest compilation. | ` | +| `diagnostics` | `Map` | `undefined` | Map from filename to array of Language Server Protocol diagnostics resulting from the latest compilation. | ### Methods From 795f90f4a9c19144b97d3faaeb1217980796daf2 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Fri, 9 Apr 2021 08:33:42 -0700 Subject: [PATCH 5/9] Don't enter edit mode on Tab focus until Enter is pressed --- CHANGELOG.md | 9 +++ src/playground-code-editor.ts | 104 ++++++++++++++++++++++++++++++-- src/test/playground-ide_test.ts | 64 +++++++++++++++++++- 3 files changed, 168 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ad6e14b..d5a352bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- [**BREAKING**] Focusing the editor using the Tab key no longer activates edit + mode immediately. This prevents the Tab key from being trapped, which was an + accessibility problem for keyboard users. + + Instead, when the editor is focused, users can now press Enter to begin + editing, and Escape to stop editing. A prompt is displayed with these + instructions when focused. Focusing the editor with a mouse click continues to + activate edit mode immediately, as before. + - The editor now uses the CodeMirror `contenteditable` input style, which has much better screen reader support. diff --git a/src/playground-code-editor.ts b/src/playground-code-editor.ts index e8ced2aa..bff30ae9 100644 --- a/src/playground-code-editor.ts +++ b/src/playground-code-editor.ts @@ -9,10 +9,12 @@ import { customElement, css, property, + query, internalProperty, PropertyValues, html, } from 'lit-element'; +import {nothing} from 'lit-html'; import {ifDefined} from 'lit-html/directives/if-defined.js'; import {CodeMirror} from './lib/codemirror.js'; import codemirrorStyles from './_codemirror/codemirror-styles.js'; @@ -49,12 +51,40 @@ export class PlaygroundCodeEditor extends LitElement { position: relative; } + #focusContainer { + height: 100%; + position: relative; + } + .CodeMirror { height: 100% !important; font-family: inherit !important; border-radius: inherit; } + #keyboardHelpScrim { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + z-index: 999; + pointer-events: none; + } + + #keyboardHelp { + background: #00000099; + padding: 20px 80px; + border-radius: 10px; + color: white; + font-family: sans-serif; + font-size: 18px; + } + .CodeMirror-foldmarker { font-family: sans-serif; } @@ -164,6 +194,15 @@ export class PlaygroundCodeEditor extends LitElement { position: string; }; + @internalProperty() + private _showKeyboardHelp = false; + + @query('#focusContainer') + private _focusContainer?: HTMLDivElement; + + @query('.CodeMirror-code') + private _codemirrorEditable?: HTMLDivElement; + private _resizeObserver?: ResizeObserver; private _resizing = false; private _valueChangingFromOutside = false; @@ -213,15 +252,34 @@ export class PlaygroundCodeEditor extends LitElement { } render() { + if (this.readonly) { + return this._cmDom; + } return html` - ${this._cmDom}
-
- ${this._tooltipDiagnostic?.diagnostic.message} + ${this._showKeyboardHelp + ? html`
+

+ Press Enter to start editing
Press Escape to exit editor +

+
` + : nothing} + ${this._cmDom} +
+
+ ${this._tooltipDiagnostic?.diagnostic.message} +
`; @@ -276,6 +334,10 @@ export class PlaygroundCodeEditor extends LitElement { mode: this._getLanguageMode(), readOnly: this.readonly, inputStyle: 'contenteditable', + // Don't allow naturally tabbing into the editor, because it's a + // tab-trap. Instead, the container is focusable, and Enter/Escape are + // used to explicitly enter the editable area. + tabindex: -1, } ); cm.on('change', () => { @@ -298,6 +360,36 @@ export class PlaygroundCodeEditor extends LitElement { this._codemirror = cm; } + private _onMousedown() { + // Directly focus editable region. + this._codemirrorEditable?.focus(); + } + + private _onFocus() { + // Outer container was focused, either by tabbing from outside, or by + // pressing Escape. + this._showKeyboardHelp = true; + } + + private _onBlur() { + // Outer container was unfocused, either by tabbing away from it, or by + // pressing Enter. + this._showKeyboardHelp = false; + } + + private _onKeyDown(event: KeyboardEvent) { + if (event.key === 'Enter' && event.target === this._focusContainer) { + this._codemirrorEditable?.focus(); + // Prevent typing a newline from this same event. + event.preventDefault(); + } else if (event.key === 'Escape') { + // Note there is no API for "select the next naturally focusable element", + // so instead we just re-focus the outer container, from which point the + // user can tab to move focus entirely elsewhere. + this._focusContainer?.focus(); + } + } + private _ariaLineNumberObserver?: MutationObserver; /** diff --git a/src/test/playground-ide_test.ts b/src/test/playground-ide_test.ts index c50163d0..241e561c 100644 --- a/src/test/playground-ide_test.ts +++ b/src/test/playground-ide_test.ts @@ -31,6 +31,8 @@ suite('playground-ide', () => { assert.instanceOf(document.createElement('playground-ide'), PlaygroundIde); }); + const raf = async () => new Promise((r) => requestAnimationFrame(r)); + const pierce = async (...selectors: string[]) => { let node = document.body; for (const selector of selectors) { @@ -269,12 +271,12 @@ suite('playground-ide', () => { // Disable line numbers. ide.lineNumbers = false; - await new Promise((r) => requestAnimationFrame(r)); + await raf(); assert.equal(queryHiddenLineNumbers().length, 0); // Re-enable line numbers. ide.lineNumbers = true; - await new Promise((r) => requestAnimationFrame(r)); + await raf(); assert.equal(queryHiddenLineNumbers().length, 2); // Add a line. @@ -282,7 +284,63 @@ suite('playground-ide', () => { _codemirror: PlaygroundCodeEditor['_codemirror']; }; editorInternals._codemirror!.setValue(editor.value + '\nBaz'); - await new Promise((r) => requestAnimationFrame(r)); + await raf(); assert.equal(queryHiddenLineNumbers().length, 3); }); + + test('a11y: focusing shows keyboard prompt', async () => { + const ide = document.createElement('playground-ide'); + ide.config = { + files: { + 'index.html': { + content: 'Foo', + }, + }, + }; + container.appendChild(ide); + await assertPreviewContains('Foo'); + + const editor = (await pierce( + 'playground-ide', + 'playground-file-editor', + 'playground-code-editor' + )) as PlaygroundCodeEditor; + const focusContainer = editor.shadowRoot!.querySelector( + '#focusContainer' + ) as HTMLElement; + const editableRegion = editor.shadowRoot!.querySelector( + '.CodeMirror-code' + ) as HTMLElement; + const keyboardHelp = 'Press Enter'; + + // Not focused initially + assert.notInclude(focusContainer.textContent, keyboardHelp); + + // When the inner container is focused, show the keyboard prompt + focusContainer.focus(); + await raf(); + assert.isTrue(focusContainer.matches(':focus')); + assert.include(focusContainer.textContent, keyboardHelp); + + // Press Enter to start editing + focusContainer.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'})); + await raf(); + assert.isTrue(editableRegion.matches(':focus')); + assert.notInclude(focusContainer.textContent, keyboardHelp); + + // Press Escape to stop editing + editableRegion.dispatchEvent( + new KeyboardEvent('keydown', {key: 'Escape', bubbles: true}) + ); + await raf(); + assert.isTrue(focusContainer.matches(':focus')); + assert.include(focusContainer.textContent, keyboardHelp); + + // Focus something else entirely + focusContainer.blur(); + await raf(); + assert.isFalse(focusContainer.matches(':focus')); + assert.isFalse(editableRegion.matches(':focus')); + assert.notInclude(focusContainer.textContent, keyboardHelp); + }); }); From b17c2421dc86dcafcd62ea9893f0409d626df0fe Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Fri, 9 Apr 2021 11:10:03 -0700 Subject: [PATCH 6/9] Better constrain the height of the editor in IDE --- src/playground-ide.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/playground-ide.ts b/src/playground-ide.ts index bf803600..1da785cd 100644 --- a/src/playground-ide.ts +++ b/src/playground-ide.ts @@ -98,6 +98,7 @@ export class PlaygroundIde extends LitElement { playground-file-editor { flex: 1; + height: calc(100% - var(--playground-bar-height), 35px); } #rhs { From 2dca08153b88defd3bbdb15c1c1346507aa31e24 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Sat, 10 Apr 2021 15:07:54 -0700 Subject: [PATCH 7/9] Update codemirror dependency to git commit with shadow root fix https://github.com/codemirror/CodeMirror/pull/6651 fixes an issue when CodeMirror is in a shadow root and using contenteditable mode. It's not yet released, so temporarily depend on the git commit. Note we generate and distribute our own CodeMirror build, so this is only a devDependency so it won't cause any versioning issues for consumers. --- package-lock.json | 236 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 120 insertions(+), 118 deletions(-) diff --git a/package-lock.json b/package-lock.json index 876accb3..10d87b3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@web/test-runner-playwright": "^0.8.0", "@web/test-runner-puppeteer": "^0.9.0", "clean-css": "^4.2.3", - "codemirror": "^5.58.1", + "codemirror": "git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", "codemirror-grammar-mode": "^0.1.10", "google_modes": "git+https://github.com/codemirror/google-modes.git#b78e1c3841a567505c41ad7befa6ca2c289e889e", "playwright": "^1.5.1", @@ -1030,9 +1030,9 @@ } }, "node_modules/@types/chai": { - "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz", - "integrity": "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==", + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", + "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==", "dev": true }, "node_modules/@types/co-body": { @@ -1336,9 +1336,9 @@ } }, "node_modules/@web/dev-server": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.10.tgz", - "integrity": "sha512-5Pj2GPNKO6Uq2aQCq1+/fkXdZ5guALevUb6M324oiTr1srBXHod6QunbzqXovO5Bcgmo79ZOneHMgoQNwxtIYA==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.11.tgz", + "integrity": "sha512-4yqxfL2FBbHxHlu2+KFIF+iXN7f9MiGu8j/gNT6gnTPruCL6AUBm+skT5kRqaA6DYnmd4qbVc3EWnJvZY3RvGQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.11", @@ -1346,7 +1346,7 @@ "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.1.3", "@web/dev-server-core": "^0.3.8", - "@web/dev-server-rollup": "^0.3.2", + "@web/dev-server-rollup": "^0.3.3", "camelcase": "^6.2.0", "chalk": "^4.1.0", "command-line-args": "^5.1.1", @@ -1395,9 +1395,9 @@ } }, "node_modules/@web/dev-server-rollup": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.2.tgz", - "integrity": "sha512-c5ROnMAUrOJPXTQFFXZiOy0ta4Y5yXLA2QkD71htNhIcqeOI4yx6ueDtuFqovRxVI0qcWGk46UdfZ0UGT/9MIg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.3.tgz", + "integrity": "sha512-3v+PG9xC+Q07NOVTqqYuab/XqDQfWXltVzOI6HstBD0RWP7u7Bk4G0BwSjD3RNdIzyrTW//zCwyCN7UkHNhIBA==", "dev": true, "dependencies": { "@web/dev-server-core": "^0.3.3", @@ -1424,17 +1424,17 @@ } }, "node_modules/@web/test-runner": { - "version": "0.12.18", - "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.12.18.tgz", - "integrity": "sha512-TfDuqM+4DfIxb4GzTlOoA4JEX15IXDkuVNzHYphChJCVkK+3GJxl173z0ZVjiUYXfudVM8LrKwR72XY3piv/8w==", + "version": "0.12.19", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.12.19.tgz", + "integrity": "sha512-7uOBWfhVaJStLDEua1qVPdRsE+vZ3ljDIFql60hse6ml+ZG7we3XjWs5fsuNMBK9SIRaSFdPBGLp4H1kq5Ying==", "dev": true, "dependencies": { "@web/browser-logs": "^0.2.0", "@web/config-loader": "^0.1.3", - "@web/dev-server": "^0.1.8", + "@web/dev-server": "^0.1.11", "@web/test-runner-chrome": "^0.9.4", - "@web/test-runner-commands": "^0.4.1", - "@web/test-runner-core": "^0.10.13", + "@web/test-runner-commands": "^0.4.2", + "@web/test-runner-core": "^0.10.14", "@web/test-runner-mocha": "^0.7.2", "camelcase": "^6.2.0", "chalk": "^4.1.0", @@ -1470,21 +1470,21 @@ } }, "node_modules/@web/test-runner-commands": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.4.1.tgz", - "integrity": "sha512-y1U9+jucQ1ZB9YRgMFIjXTUSu/in54yt4Lf4GcY9fHoSyGVWDub085ARWipmagsD9SRN1QnIYTkMk+jRa/EiLQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.4.2.tgz", + "integrity": "sha512-6Wb7rkb2dxbGTjs/VHLFTEp9OOo01B82YYG1260E4baMSt8UMw/eF9NJpOjxC7Z8ySURphJYW/Riwi0bWWwIeQ==", "dev": true, "dependencies": { - "@web/test-runner-core": "^0.10.8" + "@web/test-runner-core": "^0.10.14" }, "engines": { "node": ">=12.0.0" } }, "node_modules/@web/test-runner-core": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.13.tgz", - "integrity": "sha512-w6seztsj/UKUz9HP5KeMZ1JdUadt293SplsrKKaUJTZDMLO8+xvyo+vpt1Mv7zICu0wyuQN0AdD3GjKKX6dFHw==", + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.14.tgz", + "integrity": "sha512-RfY6KAtWHBZvfS/JGAkvp6zprFROd3m7gPJJAUFkfYXyMUQZQnNGI5nI+Shft1FcsST16/ivPog6TPNka55+ig==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.11", @@ -1822,9 +1822,9 @@ "dev": true }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -1943,9 +1943,9 @@ "peer": true }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/base64-js": { @@ -2013,9 +2013,9 @@ } }, "node_modules/boxen": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.0.tgz", - "integrity": "sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.1.tgz", + "integrity": "sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA==", "dev": true, "peer": true, "dependencies": { @@ -2438,15 +2438,17 @@ }, "node_modules/codemirror": { "version": "5.60.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.60.0.tgz", - "integrity": "sha512-AEL7LhFOlxPlCL8IdTcJDblJm8yrAGib7I+DErJPdZd4l6imx8IMgKK3RblVgBQqz3TZJR4oknQ03bz+uNjBYA==", - "dev": true + "resolved": "git+ssh://git@github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", + "integrity": "sha512-TtmOpkqnIuZQ1EAZJfYepgAPus49V9WR1u+uJD/qHcYLvX2iZSE69E+JCZqUz9OPupIDooox/wHV2q4edYnpUA==", + "dev": true, + "license": "MIT" }, "node_modules/codemirror-grammar-mode": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/codemirror-grammar-mode/-/codemirror-grammar-mode-0.1.10.tgz", "integrity": "sha512-/e93ee3bg/g+CFpgRnH6UrUnQC0FQTeDUr9Ts9dMvDYv606Zx9owQeWWvMlV1kQBkjSfUG+6bIA8Q5BQnQQX2w==", "dev": true, + "license": "MIT", "bin": { "grammar-mode": "src/grammar-mode.js" } @@ -3816,9 +3818,9 @@ } }, "node_modules/is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "bin": { "is-docker": "cli.js" @@ -4420,16 +4422,16 @@ } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/mime": { @@ -4890,9 +4892,9 @@ "dev": true }, "node_modules/open": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/open/-/open-8.0.4.tgz", - "integrity": "sha512-Txc9FOcvjrr5Kv+Zb3w89uKMKiP7wH8mLdYj1xJa+YnhhntEYhbB6cQHjS4O6P+jFwMEzEQVVcpfnu9WkKNuLQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/open/-/open-8.0.5.tgz", + "integrity": "sha512-hkPXCz7gijWp2GoWqsQ4O/5p7F6d5pIQ/+9NyeWG1nABJ4zvLi9kJRv1a44kVf5p13wK0WMoiRA+Xey68yOytA==", "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", @@ -5085,9 +5087,9 @@ "peer": true }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true, "engines": { "node": ">=8.6" @@ -5759,9 +5761,9 @@ } }, "node_modules/rollup": { - "version": "2.44.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz", - "integrity": "sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==", + "version": "2.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.45.1.tgz", + "integrity": "sha512-vPD+JoDj3CY8k6m1bLcAFttXMe78P4CMxoau0iLVS60+S9kLsv2379xaGy4NgYWu+h2WTlucpoLPAoUoixFBag==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -6544,9 +6546,9 @@ } }, "node_modules/tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -6603,9 +6605,9 @@ } }, "node_modules/typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7958,9 +7960,9 @@ } }, "@types/chai": { - "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz", - "integrity": "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==", + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", + "integrity": "sha512-vI5iOAsez9+roLS3M3+Xx7w+WRuDtSmF8bQkrbcIJ2sC1PcDgVoA0WGpa+bIrJ+y8zqY2oi//fUctkxtIcXJCw==", "dev": true }, "@types/co-body": { @@ -8258,9 +8260,9 @@ } }, "@web/dev-server": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.10.tgz", - "integrity": "sha512-5Pj2GPNKO6Uq2aQCq1+/fkXdZ5guALevUb6M324oiTr1srBXHod6QunbzqXovO5Bcgmo79ZOneHMgoQNwxtIYA==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.11.tgz", + "integrity": "sha512-4yqxfL2FBbHxHlu2+KFIF+iXN7f9MiGu8j/gNT6gnTPruCL6AUBm+skT5kRqaA6DYnmd4qbVc3EWnJvZY3RvGQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.11", @@ -8268,7 +8270,7 @@ "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.1.3", "@web/dev-server-core": "^0.3.8", - "@web/dev-server-rollup": "^0.3.2", + "@web/dev-server-rollup": "^0.3.3", "camelcase": "^6.2.0", "chalk": "^4.1.0", "command-line-args": "^5.1.1", @@ -8307,9 +8309,9 @@ } }, "@web/dev-server-rollup": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.2.tgz", - "integrity": "sha512-c5ROnMAUrOJPXTQFFXZiOy0ta4Y5yXLA2QkD71htNhIcqeOI4yx6ueDtuFqovRxVI0qcWGk46UdfZ0UGT/9MIg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.3.tgz", + "integrity": "sha512-3v+PG9xC+Q07NOVTqqYuab/XqDQfWXltVzOI6HstBD0RWP7u7Bk4G0BwSjD3RNdIzyrTW//zCwyCN7UkHNhIBA==", "dev": true, "requires": { "@web/dev-server-core": "^0.3.3", @@ -8330,17 +8332,17 @@ } }, "@web/test-runner": { - "version": "0.12.18", - "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.12.18.tgz", - "integrity": "sha512-TfDuqM+4DfIxb4GzTlOoA4JEX15IXDkuVNzHYphChJCVkK+3GJxl173z0ZVjiUYXfudVM8LrKwR72XY3piv/8w==", + "version": "0.12.19", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.12.19.tgz", + "integrity": "sha512-7uOBWfhVaJStLDEua1qVPdRsE+vZ3ljDIFql60hse6ml+ZG7we3XjWs5fsuNMBK9SIRaSFdPBGLp4H1kq5Ying==", "dev": true, "requires": { "@web/browser-logs": "^0.2.0", "@web/config-loader": "^0.1.3", - "@web/dev-server": "^0.1.8", + "@web/dev-server": "^0.1.11", "@web/test-runner-chrome": "^0.9.4", - "@web/test-runner-commands": "^0.4.1", - "@web/test-runner-core": "^0.10.13", + "@web/test-runner-commands": "^0.4.2", + "@web/test-runner-core": "^0.10.14", "@web/test-runner-mocha": "^0.7.2", "camelcase": "^6.2.0", "chalk": "^4.1.0", @@ -8366,18 +8368,18 @@ } }, "@web/test-runner-commands": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.4.1.tgz", - "integrity": "sha512-y1U9+jucQ1ZB9YRgMFIjXTUSu/in54yt4Lf4GcY9fHoSyGVWDub085ARWipmagsD9SRN1QnIYTkMk+jRa/EiLQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.4.2.tgz", + "integrity": "sha512-6Wb7rkb2dxbGTjs/VHLFTEp9OOo01B82YYG1260E4baMSt8UMw/eF9NJpOjxC7Z8ySURphJYW/Riwi0bWWwIeQ==", "dev": true, "requires": { - "@web/test-runner-core": "^0.10.8" + "@web/test-runner-core": "^0.10.14" } }, "@web/test-runner-core": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.13.tgz", - "integrity": "sha512-w6seztsj/UKUz9HP5KeMZ1JdUadt293SplsrKKaUJTZDMLO8+xvyo+vpt1Mv7zICu0wyuQN0AdD3GjKKX6dFHw==", + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.14.tgz", + "integrity": "sha512-RfY6KAtWHBZvfS/JGAkvp6zprFROd3m7gPJJAUFkfYXyMUQZQnNGI5nI+Shft1FcsST16/ivPog6TPNka55+ig==", "dev": true, "requires": { "@babel/code-frame": "^7.12.11", @@ -8644,9 +8646,9 @@ "dev": true }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -8747,9 +8749,9 @@ "peer": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64-js": { @@ -8799,9 +8801,9 @@ } }, "boxen": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.0.tgz", - "integrity": "sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.1.tgz", + "integrity": "sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA==", "dev": true, "peer": true, "requires": { @@ -9110,10 +9112,10 @@ "peer": true }, "codemirror": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.60.0.tgz", - "integrity": "sha512-AEL7LhFOlxPlCL8IdTcJDblJm8yrAGib7I+DErJPdZd4l6imx8IMgKK3RblVgBQqz3TZJR4oknQ03bz+uNjBYA==", - "dev": true + "version": "git+ssh://git@github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", + "integrity": "sha512-TtmOpkqnIuZQ1EAZJfYepgAPus49V9WR1u+uJD/qHcYLvX2iZSE69E+JCZqUz9OPupIDooox/wHV2q4edYnpUA==", + "dev": true, + "from": "codemirror@git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80" }, "codemirror-grammar-mode": { "version": "0.1.10", @@ -10218,9 +10220,9 @@ } }, "is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, "is-extglob": { @@ -10717,13 +10719,13 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime": { @@ -11083,9 +11085,9 @@ "dev": true }, "open": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/open/-/open-8.0.4.tgz", - "integrity": "sha512-Txc9FOcvjrr5Kv+Zb3w89uKMKiP7wH8mLdYj1xJa+YnhhntEYhbB6cQHjS4O6P+jFwMEzEQVVcpfnu9WkKNuLQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/open/-/open-8.0.5.tgz", + "integrity": "sha512-hkPXCz7gijWp2GoWqsQ4O/5p7F6d5pIQ/+9NyeWG1nABJ4zvLi9kJRv1a44kVf5p13wK0WMoiRA+Xey68yOytA==", "dev": true, "requires": { "define-lazy-prop": "^2.0.0", @@ -11229,9 +11231,9 @@ "peer": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, "pkg-dir": { @@ -11755,9 +11757,9 @@ } }, "rollup": { - "version": "2.44.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz", - "integrity": "sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==", + "version": "2.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.45.1.tgz", + "integrity": "sha512-vPD+JoDj3CY8k6m1bLcAFttXMe78P4CMxoau0iLVS60+S9kLsv2379xaGy4NgYWu+h2WTlucpoLPAoUoixFBag==", "dev": true, "requires": { "fsevents": "~2.3.1" @@ -12373,9 +12375,9 @@ } }, "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" }, "tsscmp": { "version": "1.0.6", @@ -12417,9 +12419,9 @@ } }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "dev": true }, "typical": { diff --git a/package.json b/package.json index 7abaf3c8..460557dd 100755 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@web/test-runner-playwright": "^0.8.0", "@web/test-runner-puppeteer": "^0.9.0", "clean-css": "^4.2.3", - "codemirror": "^5.58.1", + "codemirror": "git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", "codemirror-grammar-mode": "^0.1.10", "google_modes": "git+https://github.com/codemirror/google-modes.git#b78e1c3841a567505c41ad7befa6ca2c289e889e", "playwright": "^1.5.1", From 07a4160fb758b10d8f69b548fe389b217b53eb6c Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Mon, 12 Apr 2021 07:38:14 -0700 Subject: [PATCH 8/9] Replace custom line number aria-hidden logic with latest codemirror commit --- package-lock.json | 12 +++++------ package.json | 2 +- src/playground-code-editor.ts | 39 ----------------------------------- 3 files changed, 7 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10d87b3d..2dbf9b2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@web/test-runner-playwright": "^0.8.0", "@web/test-runner-puppeteer": "^0.9.0", "clean-css": "^4.2.3", - "codemirror": "git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", + "codemirror": "git+https://github.com/codemirror/CodeMirror.git#2997167571787db3da8a15e5ac65c8ddaf316f0a", "codemirror-grammar-mode": "^0.1.10", "google_modes": "git+https://github.com/codemirror/google-modes.git#b78e1c3841a567505c41ad7befa6ca2c289e889e", "playwright": "^1.5.1", @@ -2438,8 +2438,8 @@ }, "node_modules/codemirror": { "version": "5.60.0", - "resolved": "git+ssh://git@github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", - "integrity": "sha512-TtmOpkqnIuZQ1EAZJfYepgAPus49V9WR1u+uJD/qHcYLvX2iZSE69E+JCZqUz9OPupIDooox/wHV2q4edYnpUA==", + "resolved": "git+ssh://git@github.com/codemirror/CodeMirror.git#2997167571787db3da8a15e5ac65c8ddaf316f0a", + "integrity": "sha512-2zZuYEvTGnoFTBnECDiEYJ8AWDrkT7LjyHaCkoY029a9JGCKptogaessLiIj67ZL+UBgN49+4PhOUumoekes+g==", "dev": true, "license": "MIT" }, @@ -9112,10 +9112,10 @@ "peer": true }, "codemirror": { - "version": "git+ssh://git@github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", - "integrity": "sha512-TtmOpkqnIuZQ1EAZJfYepgAPus49V9WR1u+uJD/qHcYLvX2iZSE69E+JCZqUz9OPupIDooox/wHV2q4edYnpUA==", + "version": "git+ssh://git@github.com/codemirror/CodeMirror.git#2997167571787db3da8a15e5ac65c8ddaf316f0a", + "integrity": "sha512-2zZuYEvTGnoFTBnECDiEYJ8AWDrkT7LjyHaCkoY029a9JGCKptogaessLiIj67ZL+UBgN49+4PhOUumoekes+g==", "dev": true, - "from": "codemirror@git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80" + "from": "codemirror@git+https://github.com/codemirror/CodeMirror.git#2997167571787db3da8a15e5ac65c8ddaf316f0a" }, "codemirror-grammar-mode": { "version": "0.1.10", diff --git a/package.json b/package.json index 460557dd..ace89850 100755 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@web/test-runner-playwright": "^0.8.0", "@web/test-runner-puppeteer": "^0.9.0", "clean-css": "^4.2.3", - "codemirror": "git+https://github.com/codemirror/CodeMirror.git#770433e79286f42eab1aab81d2e44d05636ccc80", + "codemirror": "git+https://github.com/codemirror/CodeMirror.git#2997167571787db3da8a15e5ac65c8ddaf316f0a", "codemirror-grammar-mode": "^0.1.10", "google_modes": "git+https://github.com/codemirror/google-modes.git#b78e1c3841a567505c41ad7befa6ca2c289e889e", "playwright": "^1.5.1", diff --git a/src/playground-code-editor.ts b/src/playground-code-editor.ts index bff30ae9..5c4cfd15 100644 --- a/src/playground-code-editor.ts +++ b/src/playground-code-editor.ts @@ -228,7 +228,6 @@ export class PlaygroundCodeEditor extends LitElement { this._valueChangingFromOutside = false; break; case 'lineNumbers': - this._enableOrDisableAriaLineNumberObserver(); cm.setOption('lineNumbers', this.lineNumbers); break; case 'type': @@ -315,7 +314,6 @@ export class PlaygroundCodeEditor extends LitElement { const cm = CodeMirror( (dom) => { this._cmDom = dom; - this._enableOrDisableAriaLineNumberObserver(); this._resizing = true; requestAnimationFrame(() => { requestAnimationFrame(() => { @@ -390,43 +388,6 @@ export class PlaygroundCodeEditor extends LitElement { } } - private _ariaLineNumberObserver?: MutationObserver; - - /** - * Prevent screen readers from voicing line numbers. - * - * When line numbers are active, watch for lines inserted into the DOM by - * CodeMirror, and add the "aria-hidden" attribute to their line numbers. - * - * See https://github.com/codemirror/CodeMirror/issues/6578 - */ - private _enableOrDisableAriaLineNumberObserver() { - if (this.lineNumbers && !this._ariaLineNumberObserver) { - // Start observing newly added lines. - const linesParent = this._cmDom?.querySelector('.CodeMirror-code'); - if (!linesParent) { - console.error('Internal playground error: .CodeMirror-code missing'); - return; - } - this._ariaLineNumberObserver = new MutationObserver((mutations) => { - for (const mutation of mutations) { - for (const node of mutation.addedNodes) { - // Could be e.g. a text node. Cast so we can check for presence of - // querySelector with optional chaining instead of a typeof test. - (node as Partial) - .querySelector?.('.CodeMirror-gutter-wrapper') - ?.setAttribute('aria-hidden', 'true'); - } - } - }); - this._ariaLineNumberObserver.observe(linesParent, {childList: true}); - } else if (!this.lineNumbers && this._ariaLineNumberObserver) { - // Line numbers are no longer rendering. - this._ariaLineNumberObserver.disconnect(); - this._ariaLineNumberObserver = undefined; - } - } - /** * Create hidden and folded regions for playground-hide and playground-fold * comments. From 452a62d9ff92ae415ceb1d1ebfbe715807906b77 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Fri, 9 Apr 2021 11:11:25 -0700 Subject: [PATCH 9/9] Temporarily deploy configurator branch --- .github/workflows/deploy-demo.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index f66879a7..872b601c 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -4,6 +4,8 @@ on: push: branches: - master + # TODO temporary + - a11y-1 jobs: deploy: