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 => ` `)) .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/, ...) }