diff --git a/app.js b/app.js new file mode 100644 index 0000000..79a22e0 --- /dev/null +++ b/app.js @@ -0,0 +1,120 @@ +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" +import { Builder } from "/loader/builder.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 + 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'], '*') + this.shadowRoot.addEventListener('input', (e) => { + this.handleInput() + }) + } + + 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(files) + } + + save(e) { + const files = this.el.files.map( + ({name, data}) => ({name, data}) + ) + const data = JSON.stringify({ + type: 'm-file-group', + files, + }) + parent.postMessage(['save', data], '*') + } + + 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( + '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 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) diff --git a/text-edit.js b/text-edit.js index f32db0b..398cfea 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) @@ -50,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