import { EditorBuild } from "/loader/editor-build.js" export class Layout extends HTMLElement { cspProfiles = { local: "default-src 'self' 'unsafe-inline' 'unsafe-eval'", unpkg: "default-src unpkg.com 'self' 'unsafe-inline' 'unsafe-eval'", open: undefined, } constructor() { super() this.attachShadow({mode: 'open'}) this.csp = "default-src 'self' 'unsafe-inline' 'unsafe-eval'" this.header = document.createElement('m-header') this.dialogWrap = document.createElement('div') this.header.dialogWrap = this.dialogWrap this.pageActions = document.createElement( 'm-page-actions' ) this.pageActions.cspProfiles = this.cspProfiles this.header.pageActions = this.pageActions this.shadowRoot.append( this.header, this.dialogWrap, this.pageActions, ) } connectedCallback() { const style = document.createElement('style') style.textContent = ` :host { display: flex; flex-direction: column; align-items: stretch; height: 100svh; min-height: 100svh; max-height: 100svh; overflow-y: hidden; position: relative; } m-page, m-file-group-page { flex-grow: 1; } m-dialog::part(footer) { padding-top: 15px; } ` this.shadowRoot.appendChild(style) this.header.editing = this.editing this.header.addEventListener('click-edit', () => { this.editing = !this.editing }) this.header.addEventListener('create-page', () => { this.editing = true }) this.load() addEventListener('hashchange', () => { this.load() }) this.addEventListener('hash-change', () => { this.load() }) this.addEventListener('settings-change', () => { this.load() }) } load() { const path = this.path this.editing = false const prevPage = this.page let isGroup = false const body = this.storage.getItem(path) || '' if (body.match(/^\s*{/)) { try { const bodyData = JSON.parse(body) isGroup = ( Array.isArray(bodyData?.files) && bodyData.type === 'm-file-group' ) } catch (err) { // do nothing, is not file group } } this.page = document.createElement( isGroup ? 'm-file-group-page' : 'm-page' ) this.page.storage = this.storage if (isGroup) { this.page.cspOff = this.csp === undefined this.page.cspProfiles = this.cspProfiles } else { this.page.csp = this.csp } if (isGroup) { this.page.editorBuild = this.editorBuild } this.page.path = path this.editing = this.editing if (prevPage !== undefined) { prevPage.remove() } this.shadowRoot.appendChild(this.page) this.header.path = path this.pageActions.path = path this.pageActions.page = this.page } get path() { const hash = ( location.hash.slice(1) || '/' ) return hash.startsWith('/') ? new URL( hash, location.href ).pathname : hash } set editing(value) { this.storage.session.setItem( 'editing', value ? 'true' : 'false' ) this.header.editing = this.editing if (this.page) { this.page.editing = this.editing } } get editing() { try { return ( this.storage.session.getItem('editing') === 'true' ) } catch (e) { return false } } get editorBuild() { if (this._editorBuild === undefined) { this._editorBuild = new EditorBuild() } return this._editorBuild } set storage(value) { this._storage = value this.header.storage = value this.pageActions.storage = value } get storage() { return this._storage } }