From 67664496ef8611c6c59694c4a048ed9bd8720abc Mon Sep 17 00:00:00 2001 From: bat Date: Mon, 10 Apr 2023 17:07:42 +0000 Subject: [PATCH] Get file group page component showing dummy text --- components/file-group-page.json | 178 ++++++++++++++++++++++++++++++++ components/layout.js | 17 ++- 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 components/file-group-page.json diff --git a/components/file-group-page.json b/components/file-group-page.json new file mode 100644 index 0000000..03bd4e2 --- /dev/null +++ b/components/file-group-page.json @@ -0,0 +1,178 @@ +const frameHtml = ` + + + Frame + + + + ${'<'}script type="module"> + let frame = undefined +addEventListener('message', event => { + let isNew = false + const d = event.data + if (Array.isArray(d) && d[0] === 'srcdoc') { + isNew = frame === undefined + if (isNew) { + frame = document.createElement('iframe') + frame.sandbox = "allow-scripts allow-top-navigation" + } + frame.srcdoc = d[1] + } else if (frame !== undefined) { + frame.postMessage(event.data) + } + if (isNew) { + document.body.appendChild(frame) + } +}) + ${' + +` + +export class FileGroupPage extends HTMLElement { + constructor() { + super() + this.attachShadow({mode: 'open'}) + this.csp = "default-src 'self' 'unsafe-inline' 'unsafe-eval'" + } + + connectedCallback() { + const style = document.createElement('style') + style.textContent = ` + :host { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; + grid-template-areas: "main"; + flex-direction: column; + align-items: stretch; + } + iframe { + border: none; + margin: 0; + padding: 0; + grid-area: main; + width: 100%; + } + :host(.editing) iframe.view { + display: none; + } + :host(.viewing) iframe.edit { + display: none; + } + ` + this.shadowRoot.append(style) + this.initEditFrame() + this.initViewFrame() + this.editing = this.editing + } + + initEditFrame() { + const frame = document.createElement('iframe') + if (this.csp !== undefined) { + frame.sandbox = "allow-same-origin allow-scripts allow-top-navigation" + const url = new URL( + '/-/frame', location.href + ) + url.searchParams.set('csp', this.csp) + url.searchParams.set('html', frameHtml) + frame.src = url.href + } else { + frame.sandbox = "allow-scripts allow-top-navigation" + frame.srcdoc = frameHtml + } + frame.addEventListener('load', () => { + this.displayEdit() + }) + this.editFrame = frame + this.shadowRoot.append(frame) + } + + initViewFrame() { + const frame = document.createElement('iframe') + if (this.csp !== undefined) { + frame.sandbox = "allow-same-origin allow-scripts allow-top-navigation" + const url = new URL( + '/-/frame', location.href + ) + url.searchParams.set('csp', this.csp) + url.searchParams.set('html', frameHtml) + frame.src = url.href + } else { + frame.sandbox = "allow-scripts allow-top-navigation" + frame.srcdoc = frameHtml + } + frame.addEventListener('load', () => { + this.displayView() + }) + this.viewFrame = frame + this.shadowRoot.append(frame) + } + + displayView() { + let doc = 'view here' + const msg = ['srcdoc', doc] + this.viewFrame.contentWindow.postMessage( + msg, '*' + ) + } + + displayEdit() { + let doc = 'edit here' + const msg = ['srcdoc', doc] + this.viewFrame.contentWindow.postMessage( + msg, '*' + ) + } + + set body(value) { + try { + localStorage.setItem(this.path, value) + } catch (err) { + console.error(err) + } + } + + get body() { + try { + return localStorage.getItem(this.path) + } catch (err) { + console.error(err) + return '' + } + } + + set editing(value) { + this._editing = value + if (this.shadowRoot.host) { + const classes = this.shadowRoot.host.classList + if (this.editing) { + classes.add('editing') + classes.remove('viewing') + } else { + classes.add('viewing') + classes.remove('editing') + } + } + } + + get editing() { + return this._editing + } +} \ No newline at end of file diff --git a/components/layout.js b/components/layout.js index 40e1cf9..2f37667 100644 --- a/components/layout.js +++ b/components/layout.js @@ -44,7 +44,22 @@ export class Layout extends HTMLElement { load() { const path = this.path const prevPage = this.page - this.page = document.createElement('m-page') + let isGroup = false + const body = localStorage.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.csp = this.csp this.page.path = path this.editing = this.editing