From d4cef8763e5c58b901f982b5641ccff8da9ed57c Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Mon, 10 Apr 2023 23:41:21 -0700 Subject: [PATCH 1/4] turn off spellchecking --- text-edit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/text-edit.js b/text-edit.js index f32db0b..257bd39 100644 --- a/text-edit.js +++ b/text-edit.js @@ -6,6 +6,7 @@ export class TextEdit extends HTMLElement { this.stackEl.classList.add('stack') this.textEl = document.createElement('textarea') this.textEl.classList.add('text') + this.textEl.setAttribute('spellcheck', 'false') this.textEl.rows = 1 this.stackEl.appendChild(this.textEl) this.shadowRoot.appendChild(this.stackEl) From 9ffcbf450289ccd53b61489bed91b832b08de56e Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Mon, 10 Apr 2023 23:43:22 -0700 Subject: [PATCH 2/4] use translations for delete file menu item --- file-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/file-view.js b/file-view.js index 1522f0a..b925f22 100644 --- a/file-view.js +++ b/file-view.js @@ -39,7 +39,7 @@ export class FileView extends HTMLElement { this.menu = document.createElement( 'm-menu-dropdown' ) - this.menu.add('Borrar', () => { + this.menu.add(this.text.delete, () => { this.remove() }) this.shadowRoot.appendChild(this.menu) From eb34eb7d229e9f8b7da4b70bee9fea03ecc6fac1 Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Tue, 11 Apr 2023 05:22:43 -0700 Subject: [PATCH 3/4] build app for editor that runs in iframe --- app.js | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 app.js diff --git a/app.js b/app.js new file mode 100644 index 0000000..611dfae --- /dev/null +++ b/app.js @@ -0,0 +1,99 @@ +import { FileGroup } from "/editor/file-group.js" +import { FileView } from "/editor/file-view.js" +import { TextEdit } from "/editor/text-edit.js" +import { ButtonGroup } from "/forms/button-group.js" +import { Dropdown } from "/menu/dropdown.js" + +customElements.define( + 'm-editor-file-group', FileGroup +) +customElements.define( + 'm-editor-file-view', FileView +) +customElements.define( + 'm-editor-text-edit', TextEdit +) +customElements.define( + 'm-forms-button-group', ButtonGroup +) +customElements.define( + 'm-menu-dropdown', Dropdown +) + +class EditorApp extends HTMLElement { + constructor() { + super() + this.attachShadow({mode: 'open'}) + this.loaded = false + this.el = document.createElement( + 'm-editor-file-group' + ) + addEventListener('message', event => { + const message = event.data + console.info('editor got message', message) + if (Array.isArray(message)) { + if (message[0] === 'doc' && !this.loaded) { + this.load(message[1]) + this.loaded = true + this.shadowRoot.appendChild(this.el) + } + } + }) + parent.postMessage(['ready'], '*') + // TODO: observe input and save when doc changes + } + + connectedCallback() { + const style = document.createElement('style') + style.textContent = ` + :host { + display: flex; + flex-direction: column; + align-items: stretch; + margin: 8px; + } + ` + this.shadowRoot.append(style) + } + + load(doc) { + const files = JSON.parse(doc).files + for (const file of files) { + this.el.addFile(file) + } + this.display() + } + + save() { + const files = this.el.files.map( + ({name, data}) => ({name, data}) + ) + const data = JSON.stringify({ + type: 'm-file-group', + files, + }) + parent.postMessage(['save', data], '*') + } + + display() { + // TODO: build html + const html = '

HTML here

' + parent.postMessage(['html', html], '*') + } +} + +customElements.define( + 'm-editor-app', EditorApp +) + +class Setup { + async run() { + document.body.appendChild( + document.createElement( + 'm-editor-app' + ) + ) + } +} + +new Setup().run() \ No newline at end of file From 577169f3f56d868ab595687c57ed0ae12c517057 Mon Sep 17 00:00:00 2001 From: Benjamin Atkin Date: Tue, 11 Apr 2023 12:28:41 -0700 Subject: [PATCH 4/4] get it saving --- app.js | 35 ++++++++++++++++++++++++++++------- text-edit.js | 2 +- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index 611dfae..79a22e0 100644 --- a/app.js +++ b/app.js @@ -3,6 +3,7 @@ import { FileView } from "/editor/file-view.js" import { TextEdit } from "/editor/text-edit.js" import { ButtonGroup } from "/forms/button-group.js" import { Dropdown } from "/menu/dropdown.js" +import { Builder } from "/loader/builder.js" customElements.define( 'm-editor-file-group', FileGroup @@ -30,17 +31,23 @@ class EditorApp extends HTMLElement { ) addEventListener('message', event => { const message = event.data - console.info('editor got message', message) if (Array.isArray(message)) { if (message[0] === 'doc' && !this.loaded) { this.load(message[1]) this.loaded = true this.shadowRoot.appendChild(this.el) + } else if (message[0] === 'request-html') { + const files = this.el.files.map( + ({name, data}) => ({name, data}) + ) + this.display(files) } } }) parent.postMessage(['ready'], '*') - // TODO: observe input and save when doc changes + this.shadowRoot.addEventListener('input', (e) => { + this.handleInput() + }) } connectedCallback() { @@ -61,10 +68,10 @@ class EditorApp extends HTMLElement { for (const file of files) { this.el.addFile(file) } - this.display() + this.display(files) } - save() { + save(e) { const files = this.el.files.map( ({name, data}) => ({name, data}) ) @@ -75,11 +82,25 @@ class EditorApp extends HTMLElement { parent.postMessage(['save', data], '*') } - display() { - // TODO: build html - const html = '

HTML here

' + display(files) { + const builder = new Builder(files) + const html = builder.build(files) parent.postMessage(['html', html], '*') } + + handleInput(e) { + this.lastInputEvent = e + if (!this.inputTimeout) { + this.save(this.lastInputEvent) + this.lastInputEvent = undefined + this.inputTimeout = setTimeout(() => { + this.inputTimeout = undefined + if (this.lastInputEvent) { + this.handleInput(this.lastInputEvent) + } + }, 100) + } + } } customElements.define( diff --git a/text-edit.js b/text-edit.js index 257bd39..398cfea 100644 --- a/text-edit.js +++ b/text-edit.js @@ -51,7 +51,7 @@ export class TextEdit extends HTMLElement { set value(value) { this.textEl.value = value this.stackEl.dataset.copy = this.textEl.value - } + } get value() { return this.textEl.value