acoeur/themes/acoeur/assets/js/prop.js

119 lines
4.1 KiB
JavaScript

const propUrl = document.body.dataset.editUrl + '.prop'
const preparePropertyEdition = (node) => node.dataset.old = node.innerText
const updateProperty = (node) => {
if (node.dataset.old == node.innerText) return
const body = `${node.dataset.property}: ${node.innerText.trim()}`
if (!node.innerText && !node.value) node.parentNode.remove()
fetch(propUrl, { method: 'PUT', body: body })
.catch(error => console.error('Error editing property', error))
}
const pages = document.getElementById('pages')
const prepareChoiceEdition = (node) => {
// Load list of pages from which authors can select results' page
if (node.list && !node.dataset.old && !pages.children.length)
fetch('/pages.txt', { cache: 'no-store' })
.then(pages => pages.text())
.then(pages => pages.split('\n')
.filter(line => line)
.map(line => `
<option data-title="${line.replace(/.*.md:title: /g, '')}"
data-url="${line.replace(/.md:title: .*/g, '')}">
${line.replace(/.*.md:title: /g, '')}
</option>`))
.then(options => pages.innerHTML += options.join(''))
.catch(error => console.error('Error getting pages list', error))
if (node.innerText || node.value)
node.dataset.old = (node.innerText || node.value).trim()
let newChoice = node.closest('.new_choice')
if (newChoice
&& (newChoice.querySelector('label.text').innerText
|| newChoice.querySelector('input[type=text]').value)) {
// Setup another new choice
newChoice = node.closest('form.ac_choices').appendChild(newChoice.cloneNode(true))
newChoice.querySelector('label.text').innerText = ''
newChoice.querySelector('input[type=text]').value = ''
setupChoiceEdition()
}
}
const createChoice = (node) => {
if (node.nextSibling
&& (!node.querySelector('label.text').innerText
|| !node.querySelector('input[type=text]').value)) {
// Remove previously added new choice, which seems not required anymore
node.nextSibling.remove()
}
// Only creates the new choice if both "answer" and "destination" are filled
if (!node.querySelector('label.text').innerText || !node.querySelector('input[type=text]').value) return
updateChoice(node.querySelector('label.text'))
node.classList.remove('new_choice')
setupChoiceEdition()
}
const createPage = (title) => {
// Page automatic creation, later there should be a mechanism to remove eventual orphans :)
const option = pages.appendChild(document.createElement('option'))
option.dataset.title = title
option.dataset.url = uuid()
option.innerText = title
fetch(`${propUrl}/../${option.dataset.url}.prop`, { method: 'PUT', body: `title: ${title}` })
.catch(error => console.error('Error editing property', error))
return option
}
const readPage = (node) => {
const title = node.querySelector('input[type=text]').value.trim()
let option = pages.querySelector(`option[data-title='${title}']`)
if (!option) {
option = createPage(title)
}
node.querySelector('a.gotoChoice').href = option.dataset.url
return `"[${node.querySelector('label.text').innerText.trim()}](${option.dataset.url})"`
}
const updateChoice = (node) => {
if (node.dataset.old == (node.innerText || node.value)) return
const choice = node.closest('.ac_choice')
const index = Array.from(node.closest('form').children).indexOf(choice)
const body = `${node.dataset.property}[${index}]: ${readPage(choice)}`
fetch(propUrl, { method: 'PUT', body: body })
.catch(error => console.error('Error editing property', error))
}
const deleteChoice = (node) => {
const choice = node.closest('.ac_choice')
const property = choice.querySelector('label').dataset.property
const index = Array.from(node.closest('form').children).indexOf(choice)
fetch(propUrl, { method: 'PUT', body: `${property}[${index}]: ` })
.catch(error => console.error('Error editing property', error))
choice.remove()
}
// Utility method
const uuid = () => {
const temp_url = URL.createObjectURL(new Blob())
const uuid = temp_url.toString()
URL.revokeObjectURL(temp_url)
return uuid.substring(uuid.lastIndexOf('/') + 1) // remove prefix (e.g. blob:null/, blob:www.test.com/, ...)
}