export class FileView extends HTMLElement { icons = { menu: ` `, down: ` `, up: ` `, } textEn = { addAbove: 'Add above', addBelow: 'Add below', delete: 'Delete', } textEs = { addAbove: 'Añadir arriba', addBelow: 'Añadir abajo', delete: 'Borrar', } constructor() { super() this.language = navigator.language this.attachShadow({mode: 'open'}) this.headerEl = document.createElement('div') this.headerEl.classList.add('header') this.contentEl = document.createElement('div') this.contentEl.classList.add('content') this.shadowRoot.appendChild(this.headerEl) this.shadowRoot.appendChild(this.contentEl) this.nameEl = document.createElement('input') this.nameEl.classList.add('name') this.nameEl.setAttribute('spellcheck', 'false') this.nameEl.addEventListener('input', e => { this.setFileType(e.target.value) }) this.headerEl.appendChild(this.nameEl) this.collapseBtn = document.createElement( 'button' ) this.collapseBtn.innerHTML = this.icons.up this.collapseBtn.addEventListener('click', () => { this.collapsed = !this.collapsed }) this.headerEl.appendChild(this.collapseBtn) this.menuBtn = document.createElement('button') this.menuBtn.innerHTML = this.icons.menu this.menuBtn.addEventListener('click', () => { this.openMenu() }) this.headerEl.appendChild(this.menuBtn) this.menu = document.createElement( 'm-menu-dropdown' ) this.shadowRoot.appendChild(this.menu) } connectedCallback() { const style = document.createElement('style') style.textContent = ` :host { display: flex; flex-direction: column; align-items: stretch; } div.header { display: flex; flex-direction: row; align-items: stretch; background-color: #f2dbd8; color: #000; padding: 3px 0; } div.header > * { background: inherit; color: inherit; border: none; } .name { flex-grow: 1; padding: 0 5px; font: inherit; font-family: monospace; outline: none; } div.header button svg { margin-bottom: -3px; } div.content { display: flex; flex-direction: column; align-items: stretch; min-height: 5px; } div.content.collapsed > * { display: none; } svg { height: 20px; width: 20px; } ` this.shadowRoot.appendChild(style) } openMenu() { this.menu.clear() this.menu.add(this.text.addAbove, () => { this.dispatchEvent(new CustomEvent( 'click-add-above', {bubbles: true} )) }) this.menu.add(this.text.addBelow, () => { this.dispatchEvent(new CustomEvent( 'click-add-below', {bubbles: true} )) }) if (this.fileCount.value > 1) { this.menu.add(this.text.delete, () => { this.remove() this.fileCount.value -= 1 }) } this.menu.open(this.menuBtn) } set codeMirror(value) { this._codeMirror = value const tagName = ( this.codeMirror ? 'm-editor-code-edit' : 'm-editor-text-edit' ) this.editEl = document.createElement(tagName) this.contentEl.replaceChildren(this.editEl) } get codeMirror() { return this._codeMirror } set name(name) { this.nameEl.value = name this.setFileType(name) } get name() { return this.nameEl.value } set data(data) { this.editEl.value = data } get data() { return this.editEl.value } set collapsed(value) { const cl = this.contentEl.classList if (value) { cl.add('collapsed') } else { cl.remove('collapsed') } this.collapseBtn.innerHTML = ( value ? this.icons.down : this.icons.up ) } get collapsed() { return this.contentEl.classList.contains( 'collapsed' ) } setFileType(value) { if (this.codeMirror && this.editEl) { let fileType if (value.endsWith('.js')) { fileType = 'js' } else if (value.endsWith('.html')) { fileType = 'html' } else if (value.endsWith('.css')) { fileType = 'css' } else if (value.endsWith('.json')) { fileType = 'json' } this.editEl.fileType = fileType } } get language() { return this._language } set language(language) { this._language = language this.text = this.langEs ? this.textEs : this.textEn } get langEs() { return /^es\b/.test(this.language) } }