diff --git a/docs/docs/changelog.mdx b/docs/docs/changelog.mdx index 793ac51..2c8f709 100644 --- a/docs/docs/changelog.mdx +++ b/docs/docs/changelog.mdx @@ -8,6 +8,7 @@ sidebar_position: 10 - Fix: the `change` event carries the JSON of the page in `detail` again (removed in 0.2.0), and is emitted for every change made in the editor, including the preview arrows. It is not emitted when the host sets `value` - Fix: one store per element, the content is kept when the editor is hidden and shown again, and `value` can be read right after the element is inserted +- Fix: setting `value` again with the same string (Vue does it on every render of the host) no longer resets the content, only a new value replaces it - Fix: the text alignment radios are no longer submitted with the surrounding form (#4) - Fix: preview messages are only accepted from the preview iframe and from the editor window - Fix: English and French translations diff --git a/visual-editor/server/compat.html b/visual-editor/server/compat.html index 6f6da68..a716ad6 100644 --- a/visual-editor/server/compat.html +++ b/visual-editor/server/compat.html @@ -50,7 +50,12 @@ host.changes.push(v.detail) host.value = v.detail }) - el.addEventListener('close', () => (el.hidden = true)) + // Like Vue, every render of the host sets the initial value again + const render = () => (el.value = window.initialValue ?? '[]') + el.addEventListener('close', () => { + el.hidden = true + render() + }) const form = document.querySelector('form') form.addEventListener('submit', (e) => { @@ -59,6 +64,7 @@ }) document.querySelector('#toggle').addEventListener('click', () => { el.hidden = !el.hidden + render() }) form.appendChild(el) host.ready = true diff --git a/visual-editor/src/VisualEditor.tsx b/visual-editor/src/VisualEditor.tsx index 7add5fd..de83d63 100644 --- a/visual-editor/src/VisualEditor.tsx +++ b/visual-editor/src/VisualEditor.tsx @@ -86,6 +86,8 @@ export class VisualEditor { private _store: Store | null = null // Last JSON value known by the element (emitted or received) private _lastValue = '' + // Last string value set by the host + private _hostValue: string | null = null // True while the value comes from the host (no change event) private _silent = false @@ -107,6 +109,14 @@ export class VisualEditor { | EditorComponentData[] | ((v: EditorComponentData[]) => EditorComponentData[]) ) { + if (typeof v === 'string') { + // Hosts like Vue set the same value again on every render, only a + // new value replaces the content (0.1.x ignored every later value) + if (v === this._hostValue) { + return + } + this._hostValue = v + } if (!this._store) { if (!v) { this.removeAttribute('value') @@ -175,7 +185,8 @@ export class VisualEditor { if (this._store) { return this._store } - const data = this.parseValue(this.getAttribute('value')?.toString()) + this._hostValue = this.getAttribute('value') + const data = this.parseValue(this._hostValue ?? undefined) const store = createStore( data, components,