Merge pull request 'add edit icon' (#12) from i9 into main

Reviewed-on: https://codeberg.org/macchiato/pages/pulls/12
file-group-page
bat 3 years ago
commit 3b3fcac3f6

@ -12,8 +12,9 @@ customElements.define('m-page-menu', PageMenu)
class Setup {
async run() {
navigator.serviceWorker
.addEventListener('controllerchange', () => {
const sw = navigator.serviceWorker
sw.addEventListener('controllerchange', () => {
if (this.registration.active) {
window.location.reload(true)
}

@ -5,11 +5,19 @@ export class Header extends HTMLElement {
</svg>`,
dot: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
</svg>`,
edit: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16">
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
</svg>`,
check: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-lg" viewBox="0 0 16 16">
<path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425a.247.247 0 0 1 .02-.022Z"/>
</svg>`,
}
constructor() {
super()
this.editing = false
this.attachShadow({mode: 'open'})
this.addButton(this.icons.menu, 'nav', () => {
this.menu.pages = this.getPages()
@ -17,6 +25,11 @@ export class Header extends HTMLElement {
this.overlay.classList.add('open')
})
this.addDivider()
this.editBtn = this.addButton(this.editIcon, 'edit', () => {
this.dispatchEvent(new CustomEvent(
'click-edit', {bubbles: true}
))
})
this.addButton(this.icons.dot, 'page', () => {
this.pageMenuPanel.classList.add('open')
this.overlay.classList.add('open')
@ -33,6 +46,7 @@ export class Header extends HTMLElement {
if (onClick) {
b.addEventListener('click', onClick)
}
return b
}
addDivider() {
@ -53,7 +67,7 @@ export class Header extends HTMLElement {
this.overlay.addEventListener('click', () => {
this.close()
})
this.menu.addEventListener('close', () => {
this.menu.addEventListener('close-menu', () => {
this.close()
})
}
@ -76,7 +90,7 @@ export class Header extends HTMLElement {
el.click()
this.shadowRoot.removeChild(el)
})
this.pageMenu.addEventListener('close', () => {
this.pageMenu.addEventListener('close-menu', () => {
this.close()
})
this.pageMenuPanel = document.createElement('div')
@ -166,4 +180,19 @@ export class Header extends HTMLElement {
getPages() {
return Object.keys(localStorage).slice().sort()
}
set editing(value) {
this._editing = value
if (this.editBtn) {
this.editBtn.innerHTML = this.editIcon
}
}
get editing() {
return this._editing
}
get editIcon() {
return this.editing ? this.icons.check : this.icons.edit
}
}

@ -2,12 +2,9 @@ export class Layout extends HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'})
this.csp = "default-src 'self' 'unsafe-inline' 'unsafe-eval'"
this.header = document.createElement('m-header')
this.shadowRoot.appendChild(this.header)
this.load()
addEventListener('hashchange', () => {
this.load()
})
this.editing = false
}
connectedCallback() {
@ -24,13 +21,24 @@ export class Layout extends HTMLElement {
}
`
this.shadowRoot.appendChild(style)
this.header.editing = this.editing
this.header.addEventListener('click-edit', () => {
this.editing = !this.editing
})
this.shadowRoot.appendChild(this.header)
this.load()
addEventListener('hashchange', () => {
this.load()
})
}
load() {
const path = this.path
const prevPage = this.page
this.page = document.createElement('m-page')
this.page.csp = this.csp
this.page.path = path
this.editing = this.editing
if (prevPage !== undefined) {
prevPage.remove()
}
@ -39,9 +47,18 @@ export class Layout extends HTMLElement {
}
get path() {
return new URL(
window.location.hash.slice(1) || '/',
window.location
).pathname
return '/hello'
}
set editing(value) {
this._editing = value
this.header.editing = this.editing
if (this.page) {
this.page.editing = this.editing
}
}
get editing() {
return this._editing
}
}

@ -35,7 +35,7 @@ export class NavMenu extends HTMLElement {
this.shadowRoot.addEventListener('click', e => {
if (e.target.classList.contains('page')) {
this.dispatchEvent(new CustomEvent(
'close', {bubbles: true}
'close-menu', {bubbles: true}
))
}
})

@ -45,7 +45,7 @@ export class PageMenu extends HTMLElement {
this.shadowRoot.appendChild(btn)
btn.addEventListener('click', () => {
this.dispatchEvent(new CustomEvent(
'close', {bubbles: true}
'close-menu', {bubbles: true}
))
handler()
})

@ -17,7 +17,7 @@ const frameHtml = `<!doctype html>
</head>
<body>
<iframe srcdoc="" sandbox="allow-scripts"></iframe>
<script type="module">
${'<'}script type="module">
const frame = document.getElementsByTagName('iframe')[0]
addEventListener('message', event => {
const d = event.data
@ -27,7 +27,7 @@ addEventListener('message', event => {
frame.postMessage(event.data)
}
})
</script>
${'</'}script>
</body>
</html>`
@ -35,12 +35,11 @@ export class Page extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode: 'open'})
this.csp = "default-src 'self' 'unsafe-inline' 'unsafe-eval'"
//this.editing = false
this.textArea = document.createElement('textarea')
this.textArea.addEventListener('input', e => {
localStorage.setItem(
this.path,
e.target.value
)
this.body = e.target.value
})
const div = document.createElement('div')
div.classList.add('twrap')
@ -49,9 +48,7 @@ export class Page extends HTMLElement {
}
connectedCallback() {
this.textArea.value = localStorage.getItem(
this.path
) ?? ''
this.textArea.value = this.body
const style = document.createElement('style')
style.textContent = `
:host {
@ -76,35 +73,90 @@ export class Page extends HTMLElement {
width: 100%;
height: 90vh;
}
:host(.editing) iframe {
display: none;
}
:host(.viewing) textarea {
display: none;
}
`
this.shadowRoot.append(style)
if (this.path.startsWith('/sandbox/')) {
this.initFrame()
}
this.editing = this.editing
}
initFrame() {
const wrap = document.createElement('div')
this.shadowRoot.appendChild(wrap)
const tmp = document.createElement('iframe')
if (this.csp !== undefined) {
tmp.sandbox = "allow-same-origin allow-scripts"
const url = new URL(
'/-/frame', location.href
)
url.searchParams.set(
'csp',
"default-src 'self' 'unsafe-inline' 'unsafe-eval'"
)
url.searchParams.set('csp', this.csp)
url.searchParams.set('html', frameHtml)
tmp.src = url.href
} else {
tmp.sandbox = "allow-scripts"
tmp.srcdoc = frameHtml
}
wrap.insertAdjacentHTML(
'beforeend', tmp.outerHTML
)
const frames = wrap.getElementsByTagName('iframe')
this.frame = frames[frames.length - 1]
this.textArea.addEventListener('blur', e => {
const msg = ['srcdoc', e.target.value]
this.frame.contentWindow.postMessage(msg)
this.display(e.target.value)
})
this.frame.addEventListener('load', () => {
this.display(this.body)
})
}
display(value) {
let doc = value
if (!(/<\w/).test(doc.substring(0, 30))) {
doc = `<pre style="white-space: pre-wrap; margin: 8px 12px; font-family: monospace;">` +
doc.replace("<", "&lt;").replace(">", "&gt;") +
`</pre>`
}
const msg = ['srcdoc', doc]
this.frame.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
}
}

@ -13,6 +13,7 @@ async function initCache() {
}
self.addEventListener("install", event => {
self.skipWaiting()
event.waitUntil(initCache())
})

Loading…
Cancel
Save