From 4cb6d2bfcfd46984981a7f7826c2f6727dc51cca Mon Sep 17 00:00:00 2001 From: tpluscode Date: Fri, 2 Jul 2021 15:50:23 +0200 Subject: [PATCH] feat(editor-base): autoRefresh addon --- .changeset/green-islands-approve.md | 5 +++ packages/editor-base/index.js | 9 +++++ packages/editor-base/lib/autorefresh.js | 39 +++++++++++++++++++ packages/editor-base/package.json | 5 ++- packages/editor-base/test/index.test.js | 43 +++++++++++++++++++++ packages/rdf-editor/README.md | 1 + packages/rdf-editor/custom-elements.json | 11 ++++++ packages/sparql-editor/README.md | 1 + packages/sparql-editor/custom-elements.json | 11 ++++++ web-test-runner.config.mjs | 1 + 10 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 .changeset/green-islands-approve.md create mode 100644 packages/editor-base/lib/autorefresh.js create mode 100644 packages/editor-base/test/index.test.js diff --git a/.changeset/green-islands-approve.md b/.changeset/green-islands-approve.md new file mode 100644 index 00000000..88fa4ee8 --- /dev/null +++ b/.changeset/green-islands-approve.md @@ -0,0 +1,5 @@ +--- +'@rdfjs-elements/editor-base': minor +--- + +Introduced a copy of [autoRefresh addon](https://codemirror.net/doc/manual.html#addon_autorefresh) diff --git a/packages/editor-base/index.js b/packages/editor-base/index.js index 23933803..f7c0c93f 100644 --- a/packages/editor-base/index.js +++ b/packages/editor-base/index.js @@ -1,6 +1,7 @@ import { html, css, LitElement } from 'lit-element' import '@vanillawc/wc-codemirror' import { debounce } from 'throttle-debounce' +import { autoRefresh } from './lib/autorefresh.js' const Value = Symbol('Initial value') const Dirty = Symbol('Editor dirty') @@ -45,6 +46,8 @@ function whenDefined(getter) { * * @prop {Record} customPrefixes - a map of custom prefixes or overrides * + * @prop {Number} autoRefresh - controls the [autoRefresh addon](https://codemirror.net/doc/manual.html#addon_autorefresh) delay + * * @csspart error - Line or part of line highlighted as result of parsing error. By default style is red wavy underline * @csspart CodeMirror - The main CodeMirror wrapper element. This and other parts are directly generated from CSS classes set by CodeMirror and should be fairly self-explanatory but not equally useful 😉 * @csspart CodeMirror-vscrollbar @@ -94,6 +97,7 @@ export default class Editor extends LitElement { prefixes: { type: String, attribute: 'prefixes' }, isParsing: { type: Boolean, attribute: 'is-parsing', reflect: true }, autoParse: { type: Boolean, attribute: 'auto-parse' }, + autoRefresh: { type: Number, attribute: 'auto-refresh' }, parseDelay: { type: Number }, customPrefixes: { type: Object }, } @@ -251,6 +255,11 @@ export default class Editor extends LitElement { } async _initializeCodeMirror() { + autoRefresh(this.codeMirror.editor.constructor) + this.codeMirror.editor.setOption( + 'autoRefresh', + this.autoRefresh ? { delay: this.autoRefresh } : true + ) this.codeMirror.editor.setSize('100%', '100%') this.__setParseHandler() this.codeMirror.editor.on('change', () => { diff --git a/packages/editor-base/lib/autorefresh.js b/packages/editor-base/lib/autorefresh.js new file mode 100644 index 00000000..542cdd18 --- /dev/null +++ b/packages/editor-base/lib/autorefresh.js @@ -0,0 +1,39 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +export function autoRefresh(CodeMirror) { + /* eslint-disable no-param-reassign,eqeqeq */ + function stopListening(_cm, state) { + clearTimeout(state.timeout) + CodeMirror.off(window, 'mouseup', state.hurry) + CodeMirror.off(window, 'keyup', state.hurry) + } + + function startListening(cm, state) { + function check() { + if (cm.display.wrapper.offsetHeight) { + stopListening(cm, state) + if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight) + cm.refresh() + } else { + state.timeout = setTimeout(check, state.delay) + } + } + state.timeout = setTimeout(check, state.delay) + state.hurry = function () { + clearTimeout(state.timeout) + state.timeout = setTimeout(check, 50) + } + CodeMirror.on(window, 'mouseup', state.hurry) + CodeMirror.on(window, 'keyup', state.hurry) + } + + CodeMirror.defineOption('autoRefresh', false, function (cm, val) { + if (cm.state.autoRefresh) { + stopListening(cm, cm.state.autoRefresh) + cm.state.autoRefresh = null + } + if (val && cm.display.wrapper.offsetHeight == 0) + startListening(cm, (cm.state.autoRefresh = { delay: val.delay || 250 })) + }) +} diff --git a/packages/editor-base/package.json b/packages/editor-base/package.json index 5807789b..569620d6 100644 --- a/packages/editor-base/package.json +++ b/packages/editor-base/package.json @@ -8,8 +8,6 @@ "module": "index.js", "scripts": { "analyze": "run-p analyze:*", - "analyze:wc": "wca --format json --outFile ./custom-elements.json", - "analyze:readme": "wca --outFile ./README.md", "analyze:lit": "lit-analyzer --strict --quiet --rules.no-invalid-css off" }, "dependencies": { @@ -19,6 +17,9 @@ "lit-element": "^2.2.1", "throttle-debounce": "^3.0.1" }, + "devDependencies": { + "@open-wc/testing": "^2.5.29" + }, "repository": { "type": "git", "url": "https://github.com/zazuko/rdfjs-elements.git", diff --git a/packages/editor-base/test/index.test.js b/packages/editor-base/test/index.test.js new file mode 100644 index 00000000..bfdb25b9 --- /dev/null +++ b/packages/editor-base/test/index.test.js @@ -0,0 +1,43 @@ +import { expect, fixture, html } from '@open-wc/testing' +import EditorBase from '../index.js' + +customElements.define('test-editor', EditorBase) + +describe('@rdfjs-elements/editor-base', () => { + describe('autoRefresh', () => { + it('is enabled by default', async () => { + // given + const el = await fixture(html``) + await el.ready + + // then + expect(el.codeMirror.editor.getOption('autoRefresh')).to.be.true + }) + + it('can be configured with delay property', async () => { + // given + const el = await fixture( + html`` + ) + await el.ready + + // then + expect(el.codeMirror.editor.getOption('autoRefresh')).to.deep.eq({ + delay: 500, + }) + }) + + it('can be configured with delay attribute', async () => { + // given + const el = await fixture( + html`` + ) + await el.ready + + // then + expect(el.codeMirror.editor.getOption('autoRefresh')).to.deep.eq({ + delay: 1000, + }) + }) + }) +}) diff --git a/packages/rdf-editor/README.md b/packages/rdf-editor/README.md index 12f46585..9d1aa666 100644 --- a/packages/rdf-editor/README.md +++ b/packages/rdf-editor/README.md @@ -46,6 +46,7 @@ Syntax highlighting is relying on support from CodeMirror. | Property | Attribute | Modifiers | Type | Default | Description | |------------------|------------------|-----------|--------------------------|---------|--------------------------------------------------| | `autoParse` | `auto-parse` | | `boolean` | | if set to true, parses the contents automatically when typing. Otherwise, parses on `blur` event | +| `autoRefresh` | `auto-refresh` | | `Number` | | controls the [autoRefresh addon](https://codemirror.net/doc/manual.html#addon_autorefresh) delay | | `codeMirror` | | readonly | `Element \| null` | | The underlying `` element | | `customPrefixes` | `customPrefixes` | | `Record` | {} | a map of custom prefixes or overrides | | `format` | `format` | | `string` | | Media type of the RDF serialization to use.

Custom parsers and serializers must be added to `@rdf-esm/formats-common` | diff --git a/packages/rdf-editor/custom-elements.json b/packages/rdf-editor/custom-elements.json index b56c1b6c..1eda0e2d 100644 --- a/packages/rdf-editor/custom-elements.json +++ b/packages/rdf-editor/custom-elements.json @@ -47,6 +47,11 @@ "description": "if set to true, parses the contents automatically when typing. Otherwise, parses on `blur` event", "type": "boolean" }, + { + "name": "auto-refresh", + "description": "controls the [autoRefresh addon](https://codemirror.net/doc/manual.html#addon_autorefresh) delay", + "type": "Number" + }, { "name": "value", "description": "The string representation of the RDF graph.", @@ -115,6 +120,12 @@ "description": "if set to true, parses the contents automatically when typing. Otherwise, parses on `blur` event", "type": "boolean" }, + { + "name": "autoRefresh", + "attribute": "auto-refresh", + "description": "controls the [autoRefresh addon](https://codemirror.net/doc/manual.html#addon_autorefresh) delay", + "type": "Number" + }, { "name": "codeMirror", "description": "The underlying `` element", diff --git a/packages/sparql-editor/README.md b/packages/sparql-editor/README.md index 3e0f0cb2..d4f83cdc 100644 --- a/packages/sparql-editor/README.md +++ b/packages/sparql-editor/README.md @@ -28,6 +28,7 @@ const template = html`` element", diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 7d7f2d2b..3b0dfba1 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -6,6 +6,7 @@ import fakeStreamModules from '@rdfjs-elements/testing' const config = { files: [ + "packages/editor-base/**/*.test.js", "packages/rdf-editor/**/*.test.js", "packages/rdf-snippet/**/*.test.js", "packages/sparql-editor/**/*.test.js"