diff --git a/app.js b/app.js index ff8b521..f0fbb32 100644 --- a/app.js +++ b/app.js @@ -2,11 +2,13 @@ import { Layout } from "./components/layout.js" import { Page } from "./components/page.js" import { Header } from "./components/header.js" import { NavMenu } from "./components/nav-menu.js" +import { PageMenu } from "./components/page-menu.js" customElements.define('m-layout', Layout) customElements.define('m-page', Page) customElements.define('m-header', Header) customElements.define('m-nav-menu', NavMenu) +customElements.define('m-page-menu', PageMenu) class Setup { async run() { diff --git a/components/header.js b/components/header.js index f6bbc62..06f9be1 100644 --- a/components/header.js +++ b/components/header.js @@ -11,19 +11,24 @@ export class Header extends HTMLElement { constructor() { super() this.attachShadow({mode: 'open'}) - this.addButton(this.icons.menu, () => { + this.addButton(this.icons.menu, 'nav', () => { this.menu.pages = this.getPages() this.menuPanel.classList.add('open') this.overlay.classList.add('open') }) this.addDivider() - this.addButton(this.icons.dot) + this.addButton(this.icons.dot, 'page', () => { + this.pageMenuPanel.classList.add('open') + this.overlay.classList.add('open') + }) this.addMenu() + this.addPageMenu() } - addButton(html, onClick) { + addButton(html, cls, onClick) { const b = document.createElement('button') b.innerHTML = html + b.classList.add(cls) this.shadowRoot.appendChild(b) if (onClick) { b.addEventListener('click', onClick) @@ -53,10 +58,38 @@ export class Header extends HTMLElement { }) } + addPageMenu() { + this.pageMenu = document.createElement('m-page-menu') + this.pageMenu.add('download', () => { + const text = localStorage.getItem(this.path) + const sp = this.path.split('/') + const filename = sp[sp.length - 1] + const el = document.createElement('a') + el.setAttribute( + 'href', + 'data:text/plain;charset=utf-8,' + + encodeURIComponent(text) + ) + el.setAttribute('download', filename) + el.style.display = 'none' + this.shadowRoot.appendChild(el) + el.click() + this.shadowRoot.removeChild(el) + }) + this.pageMenu.addEventListener('close', () => { + this.close() + }) + this.pageMenuPanel = document.createElement('div') + this.pageMenuPanel.appendChild(this.pageMenu) + this.pageMenuPanel.classList.add('page-menu') + this.shadowRoot.appendChild(this.pageMenuPanel) + } + close() { this.overlay.classList.add('closing') this.overlay.classList.remove('open') this.menuPanel.classList.remove('open') + this.pageMenuPanel.classList.remove('open') setTimeout(() => { this.overlay.classList.remove('closing') }, 250) @@ -111,6 +144,21 @@ export class Header extends HTMLElement { left: 0; opacity: 15%; } + button.page { + position: relative; + } + div.page-menu { + position: fixed; + top: 28px; + right: 0; + display: flex; + align-items: flex-end; + margin-right: 0; + display: none; + } + div.page-menu.open { + display: block; + } ` this.shadowRoot.append(style) } diff --git a/components/page-menu.js b/components/page-menu.js new file mode 100644 index 0000000..61fd0da --- /dev/null +++ b/components/page-menu.js @@ -0,0 +1,66 @@ +export class PageMenu extends HTMLElement { + icons = {} + + textEn = { + download: 'Download', + } + + textEs = { + download: 'Descargar', + } + + constructor() { + super() + this.attachShadow({mode: 'open'}) + this.language = navigator.language + } + + connectedCallback() { + const style = document.createElement('style') + style.textContent = ` + :host { + background: #222; + color: #ddd; + padding: 3px; + display: flex; + flex-direction: column; + align-items: stretch; + min-width: 180px; + } + button { + background: #222; + font-size: 120%; + border: none; + color: inherit; + padding: 4px 10px; + text-align: left; + } + ` + this.shadowRoot.append(style) + } + + add(name, handler) { + const btn = document.createElement('button') + btn.innerText = this.text[name] + this.shadowRoot.appendChild(btn) + btn.addEventListener('click', () => { + this.dispatchEvent(new CustomEvent( + 'close', {bubbles: true} + )) + handler() + }) + } + + 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) + } +} \ No newline at end of file diff --git a/sw.js b/sw.js index 08c186f..b8de43e 100644 --- a/sw.js +++ b/sw.js @@ -1,13 +1,14 @@ async function initCache() { const cache = await caches.open('v1') await cache.addAll([ - '/', //8 + '/', '/index.html', '/app.js', '/components/page.js', '/components/layout.js', '/components/header.js', '/components/nav-menu.js', + '/components/page-menu.js', ]) }