Remove old stuff
Former-commit-id: 50fd27b68a2ad3c5218eb173c49a861f0460c813 [formerly e56cd8e4222e343cb9e6c3c3c10bc12246883524] [formerly 192799f220fadcefe62bc26c6c4ac5f8d354b85a [formerly bed096a0ca
]]
Former-commit-id: 4e32b348cb281498a72991b0240101b7c2faf8d9 [formerly 7ea09fbcf48d79706930c920fd90111d79613c8a]
Former-commit-id: 1b772ee57d53183be4b699e39a22be2232ad741b
pull/726/head
parent
007e1a63c0
commit
6f2e867f13
|
@ -1,79 +0,0 @@
|
||||||
var buttons = {
|
|
||||||
previousState: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.setLoading = function (name) {
|
|
||||||
if (typeof this[name] === 'undefined') return
|
|
||||||
let i = this[name].querySelector('i')
|
|
||||||
|
|
||||||
this.previousState[name] = i.innerHTML
|
|
||||||
i.style.opacity = 0
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
i.classList.add('spin')
|
|
||||||
i.innerHTML = 'autorenew'
|
|
||||||
i.style.opacity = 1
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Changes an element to done animation
|
|
||||||
buttons.setDone = function (name, success = true) {
|
|
||||||
let i = this[name].querySelector('i')
|
|
||||||
|
|
||||||
i.style.opacity = 0
|
|
||||||
|
|
||||||
let thirdStep = () => {
|
|
||||||
i.innerHTML = this.previousState[name]
|
|
||||||
i.style.opacity = null
|
|
||||||
|
|
||||||
if (selectedItems.length === 0 && document.getElementById('listing')) {
|
|
||||||
document.sendCostumEvent('changed-selected')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let secondStep = () => {
|
|
||||||
i.style.opacity = 0
|
|
||||||
setTimeout(thirdStep, 200)
|
|
||||||
}
|
|
||||||
|
|
||||||
let firstStep = () => {
|
|
||||||
i.classList.remove('spin')
|
|
||||||
i.innerHTML = success
|
|
||||||
? 'done'
|
|
||||||
: 'close'
|
|
||||||
i.style.opacity = 1
|
|
||||||
setTimeout(secondStep, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(firstStep, 200)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
listing.addDoubleTapEvent = function () {
|
|
||||||
let items = document.getElementsByClassName('item'),
|
|
||||||
touches = {
|
|
||||||
id: '',
|
|
||||||
count: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.from(items).forEach(file => {
|
|
||||||
file.addEventListener('touchstart', event => {
|
|
||||||
if (touches.id != file.id) {
|
|
||||||
touches.id = file.id
|
|
||||||
touches.count = 1
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
touches.count = 0
|
|
||||||
}, 300)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
touches.count++
|
|
||||||
|
|
||||||
if (touches.count > 1) {
|
|
||||||
window.location = file.dataset.url
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,278 +0,0 @@
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var editor = {}
|
|
||||||
|
|
||||||
editor.textareaAutoGrow = function () {
|
|
||||||
let autogrow = function () {
|
|
||||||
console.log(this.style.height)
|
|
||||||
this.style.height = 'auto'
|
|
||||||
this.style.height = (this.scrollHeight) + 'px'
|
|
||||||
}
|
|
||||||
|
|
||||||
let textareas = document.getElementsByTagName('textarea')
|
|
||||||
|
|
||||||
let addAutoGrow = () => {
|
|
||||||
Array.from(textareas).forEach(textarea => {
|
|
||||||
autogrow.bind(textarea)()
|
|
||||||
textarea.addEventListener('keyup', autogrow)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
addAutoGrow()
|
|
||||||
window.addEventListener('resize', addAutoGrow)
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.toggleSourceEditor = function (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
if (document.querySelector('[data-kind="content-only"]')) {
|
|
||||||
window.location = window.location.pathname + '?visual=true'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
window.location = window.location.pathname + '?visual=false'
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteFrontMatterItem (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
document.getElementById(this.dataset.delete).remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFromBaseTemplate (id, type, name, parent) {
|
|
||||||
let clone = document.importNode(templates.base.content, true)
|
|
||||||
clone.querySelector('fieldset').id = id
|
|
||||||
clone.querySelector('fieldset').dataset.type = type
|
|
||||||
clone.querySelector('h3').innerHTML = name
|
|
||||||
clone.querySelector('.delete').dataset.delete = id
|
|
||||||
clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem)
|
|
||||||
clone.querySelector('.add').addEventListener('click', addFrontMatterItem)
|
|
||||||
|
|
||||||
if (parent.classList.contains('frontmatter')) {
|
|
||||||
parent.insertBefore(clone, document.querySelector('div.button.add'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
parent.appendChild(clone)
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFromArrayItemTemplate (id, number, parent) {
|
|
||||||
let clone = document.importNode(templates.arrayItem.content, true)
|
|
||||||
clone.querySelector('[data-type="array-item"]').id = `${id}-${number}`
|
|
||||||
clone.querySelector('input').name = id
|
|
||||||
clone.querySelector('input').id = id
|
|
||||||
clone.querySelector('div.action').dataset.delete = `${id}-${number}`
|
|
||||||
clone.querySelector('div.action').addEventListener('click', deleteFrontMatterItem)
|
|
||||||
parent.querySelector('.group').appendChild(clone)
|
|
||||||
document.getElementById(`${id}-${number}`).querySelector('input').focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFromObjectItemTemplate (id, name, parent) {
|
|
||||||
let clone = document.importNode(templates.objectItem.content, true)
|
|
||||||
clone.querySelector('.block').id = `block-${id}`
|
|
||||||
clone.querySelector('.block').dataset.content = id
|
|
||||||
clone.querySelector('label').for = id
|
|
||||||
clone.querySelector('label').innerHTML = name
|
|
||||||
clone.querySelector('input').name = id
|
|
||||||
clone.querySelector('input').id = id
|
|
||||||
clone.querySelector('.action').dataset.delete = `block-${id}`
|
|
||||||
clone.querySelector('.action').addEventListener('click', deleteFrontMatterItem)
|
|
||||||
|
|
||||||
parent.appendChild(clone)
|
|
||||||
document.getElementById(id).focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFrontMatterItemPrompt (parent) {
|
|
||||||
return function (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
let value = event.currentTarget.querySelector('input').value
|
|
||||||
if (value === '') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
closePrompt(event)
|
|
||||||
|
|
||||||
let name = value.substring(0, value.lastIndexOf(':'))
|
|
||||||
let type = value.substring(value.lastIndexOf(':') + 1, value.length)
|
|
||||||
|
|
||||||
if (type !== '' && type !== 'array' && type !== 'object') {
|
|
||||||
name = value
|
|
||||||
}
|
|
||||||
|
|
||||||
name = name.replace(' ', '_')
|
|
||||||
|
|
||||||
let id = name
|
|
||||||
|
|
||||||
if (parent.id != '') {
|
|
||||||
id = parent.id + '.' + id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == 'array' || type == 'object') {
|
|
||||||
if (parent.dataset.type == 'parent') {
|
|
||||||
makeFromBaseTemplate(id, type, name, document.querySelector('.frontmatter'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
makeFromBaseTemplate(id, type, name, block)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let group = parent.querySelector('.group')
|
|
||||||
|
|
||||||
if (group == null) {
|
|
||||||
parent.insertAdjacentHTML('afterbegin', '<div class="group"></div>')
|
|
||||||
group = parent.querySelector('.group')
|
|
||||||
}
|
|
||||||
|
|
||||||
makeFromObjectItemTemplate(id, name, group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFrontMatterItem (event) {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
let parent = event.currentTarget.parentNode
|
|
||||||
let type = parent.dataset.type
|
|
||||||
|
|
||||||
// If the block is an array
|
|
||||||
if (type === 'array') {
|
|
||||||
let id = parent.id + '[]'
|
|
||||||
let count = parent.querySelectorAll('.group > div').length
|
|
||||||
let fieldsets = parent.getElementsByTagName('fieldset')
|
|
||||||
|
|
||||||
if (fieldsets.length > 0) {
|
|
||||||
let itemType = fieldsets[0].dataset.type
|
|
||||||
let itemID = parent.id + '[' + fieldsets.length + ']'
|
|
||||||
let itemName = fieldsets.length
|
|
||||||
|
|
||||||
makeFromBaseTemplate(itemID, itemType, itemName, parent)
|
|
||||||
} else {
|
|
||||||
makeFromArrayItemTemplate(id, count, parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'object' || type === 'parent') {
|
|
||||||
let clone = document.importNode(templates.question.content, true)
|
|
||||||
clone.querySelector('form').id = tempID
|
|
||||||
clone.querySelector('h3').innerHTML = 'New field'
|
|
||||||
clone.querySelector('p').innerHTML = 'Write the field name and then press enter. If you want to create an array or an object, end the name with <code>:array</code> or <code>:object.</code>'
|
|
||||||
clone.querySelector('.ok').innerHTML = 'Create'
|
|
||||||
clone.querySelector('form').addEventListener('submit', addFrontMatterItemPrompt(parent))
|
|
||||||
clone.querySelector('form').classList.add('active')
|
|
||||||
document.querySelector('body').appendChild(clone)
|
|
||||||
|
|
||||||
document.querySelector('.overlay').classList.add('active')
|
|
||||||
document.getElementById(tempID).classList.add('active')
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
if (!document.getElementById('editor')) return
|
|
||||||
|
|
||||||
editor.textareaAutoGrow()
|
|
||||||
|
|
||||||
templates.arrayItem = document.getElementById('array-item-template')
|
|
||||||
templates.base = document.getElementById('base-template')
|
|
||||||
templates.objectItem = document.getElementById('object-item-template')
|
|
||||||
templates.temporary = document.getElementById('temporary-template')
|
|
||||||
|
|
||||||
buttons.save = document.querySelector('#save')
|
|
||||||
buttons.editSource = document.querySelector('#edit-source')
|
|
||||||
|
|
||||||
if (buttons.editSource) {
|
|
||||||
buttons.editSource.addEventListener('click', editor.toggleSourceEditor)
|
|
||||||
}
|
|
||||||
|
|
||||||
let container = document.getElementById('editor'),
|
|
||||||
kind = container.dataset.kind,
|
|
||||||
rune = container.dataset.rune
|
|
||||||
|
|
||||||
if (kind != 'frontmatter-only') {
|
|
||||||
let editor = document.querySelector('.content #ace'),
|
|
||||||
mode = editor.dataset.mode,
|
|
||||||
textarea = document.querySelector('textarea[name="content"]'),
|
|
||||||
aceEditor = ace.edit('ace'),
|
|
||||||
options = {
|
|
||||||
wrap: true,
|
|
||||||
maxLines: Infinity,
|
|
||||||
theme: 'ace/theme/github',
|
|
||||||
showPrintMargin: false,
|
|
||||||
fontSize: '1em',
|
|
||||||
minLines: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
aceEditor.getSession().setMode('ace/mode/' + mode)
|
|
||||||
aceEditor.getSession().setValue(textarea.value)
|
|
||||||
aceEditor.getSession().on('change', function () {
|
|
||||||
textarea.value = aceEditor.getSession().getValue()
|
|
||||||
})
|
|
||||||
|
|
||||||
if (mode == 'markdown') options.showGutter = false
|
|
||||||
aceEditor.setOptions(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
let deleteFrontMatterItemButtons = document.getElementsByClassName('delete')
|
|
||||||
Array.from(deleteFrontMatterItemButtons).forEach(button => {
|
|
||||||
button.addEventListener('click', deleteFrontMatterItem)
|
|
||||||
})
|
|
||||||
|
|
||||||
let addFrontMatterItemButtons = document.getElementsByClassName('add')
|
|
||||||
Array.from(addFrontMatterItemButtons).forEach(button => {
|
|
||||||
button.addEventListener('click', addFrontMatterItem)
|
|
||||||
})
|
|
||||||
|
|
||||||
let saveContent = function () {
|
|
||||||
let data = form2js(document.querySelector('form'))
|
|
||||||
|
|
||||||
if (typeof data.content === 'undefined' && kind !== 'frontmatter-only') {
|
|
||||||
data.content = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data.content === 'number') {
|
|
||||||
data.content = data.content.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
let request = new XMLHttpRequest()
|
|
||||||
|
|
||||||
buttons.setLoading('save')
|
|
||||||
|
|
||||||
webdav.put(window.location.pathname, JSON.stringify(data), {
|
|
||||||
'Kind': kind,
|
|
||||||
'Rune': rune
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
buttons.setDone('save')
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.log(e)
|
|
||||||
buttons.setDone('save', false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelector('#save').addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
saveContent()
|
|
||||||
})
|
|
||||||
|
|
||||||
document.querySelector('form').addEventListener('submit', (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
saveContent()
|
|
||||||
})
|
|
||||||
|
|
||||||
window.addEventListener('keydown', (event) => {
|
|
||||||
if (event.ctrlKey || event.metaKey) {
|
|
||||||
switch (String.fromCharCode(event.which).toLowerCase()) {
|
|
||||||
case 's':
|
|
||||||
event.preventDefault()
|
|
||||||
saveContent()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
|
@ -1,356 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2010 Maxim Vasiliev
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author Maxim Vasiliev
|
|
||||||
* Date: 09.09.2010
|
|
||||||
* Time: 19:02:33
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
(function (root, factory)
|
|
||||||
{
|
|
||||||
if (typeof exports !== 'undefined' && typeof module !== 'undefined' && module.exports) {
|
|
||||||
// NodeJS
|
|
||||||
module.exports = factory();
|
|
||||||
}
|
|
||||||
else if (typeof define === 'function' && define.amd)
|
|
||||||
{
|
|
||||||
// AMD. Register as an anonymous module.
|
|
||||||
define(factory);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Browser globals
|
|
||||||
root.form2js = factory();
|
|
||||||
}
|
|
||||||
}(this, function ()
|
|
||||||
{
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns form values represented as Javascript object
|
|
||||||
* "name" attribute defines structure of resulting object
|
|
||||||
*
|
|
||||||
* @param rootNode {Element|String} root form element (or it's id) or array of root elements
|
|
||||||
* @param delimiter {String} structure parts delimiter defaults to '.'
|
|
||||||
* @param skipEmpty {Boolean} should skip empty text values, defaults to true
|
|
||||||
* @param nodeCallback {Function} custom function to get node value
|
|
||||||
* @param useIdIfEmptyName {Boolean} if true value of id attribute of field will be used if name of field is empty
|
|
||||||
*/
|
|
||||||
function form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName, getDisabled)
|
|
||||||
{
|
|
||||||
getDisabled = getDisabled ? true : false;
|
|
||||||
if (typeof skipEmpty == 'undefined' || skipEmpty == null) skipEmpty = true;
|
|
||||||
if (typeof delimiter == 'undefined' || delimiter == null) delimiter = '.';
|
|
||||||
if (arguments.length < 5) useIdIfEmptyName = false;
|
|
||||||
|
|
||||||
rootNode = typeof rootNode == 'string' ? document.getElementById(rootNode) : rootNode;
|
|
||||||
|
|
||||||
var formValues = [],
|
|
||||||
currNode,
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
/* If rootNode is array - combine values */
|
|
||||||
if (rootNode.constructor == Array || (typeof NodeList != "undefined" && rootNode.constructor == NodeList))
|
|
||||||
{
|
|
||||||
while(currNode = rootNode[i++])
|
|
||||||
{
|
|
||||||
formValues = formValues.concat(getFormValues(currNode, nodeCallback, useIdIfEmptyName, getDisabled));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
formValues = getFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
return processNameValues(formValues, skipEmpty, delimiter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes collection of { name: 'name', value: 'value' } objects.
|
|
||||||
* @param nameValues
|
|
||||||
* @param skipEmpty if true skips elements with value == '' or value == null
|
|
||||||
* @param delimiter
|
|
||||||
*/
|
|
||||||
function processNameValues(nameValues, skipEmpty, delimiter)
|
|
||||||
{
|
|
||||||
var result = {},
|
|
||||||
arrays = {},
|
|
||||||
i, j, k, l,
|
|
||||||
value,
|
|
||||||
nameParts,
|
|
||||||
currResult,
|
|
||||||
arrNameFull,
|
|
||||||
arrName,
|
|
||||||
arrIdx,
|
|
||||||
namePart,
|
|
||||||
name,
|
|
||||||
_nameParts;
|
|
||||||
|
|
||||||
for (i = 0; i < nameValues.length; i++)
|
|
||||||
{
|
|
||||||
value = nameValues[i].value;
|
|
||||||
|
|
||||||
if (skipEmpty && (value === '' || value === null)) continue;
|
|
||||||
|
|
||||||
name = nameValues[i].name;
|
|
||||||
_nameParts = name.split(delimiter);
|
|
||||||
nameParts = [];
|
|
||||||
currResult = result;
|
|
||||||
arrNameFull = '';
|
|
||||||
|
|
||||||
for(j = 0; j < _nameParts.length; j++)
|
|
||||||
{
|
|
||||||
namePart = _nameParts[j].split('][');
|
|
||||||
if (namePart.length > 1)
|
|
||||||
{
|
|
||||||
for(k = 0; k < namePart.length; k++)
|
|
||||||
{
|
|
||||||
if (k == 0)
|
|
||||||
{
|
|
||||||
namePart[k] = namePart[k] + ']';
|
|
||||||
}
|
|
||||||
else if (k == namePart.length - 1)
|
|
||||||
{
|
|
||||||
namePart[k] = '[' + namePart[k];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
namePart[k] = '[' + namePart[k] + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
arrIdx = namePart[k].match(/([a-z_]+)?\[([a-z_][a-z0-9_]+?)\]/i);
|
|
||||||
if (arrIdx)
|
|
||||||
{
|
|
||||||
for(l = 1; l < arrIdx.length; l++)
|
|
||||||
{
|
|
||||||
if (arrIdx[l]) nameParts.push(arrIdx[l]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
nameParts.push(namePart[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nameParts = nameParts.concat(namePart);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < nameParts.length; j++)
|
|
||||||
{
|
|
||||||
namePart = nameParts[j];
|
|
||||||
|
|
||||||
if (namePart.indexOf('[]') > -1 && j == nameParts.length - 1)
|
|
||||||
{
|
|
||||||
arrName = namePart.substr(0, namePart.indexOf('['));
|
|
||||||
arrNameFull += arrName;
|
|
||||||
|
|
||||||
if (!currResult[arrName]) currResult[arrName] = [];
|
|
||||||
currResult[arrName].push(value);
|
|
||||||
}
|
|
||||||
else if (namePart.indexOf('[') > -1)
|
|
||||||
{
|
|
||||||
arrName = namePart.substr(0, namePart.indexOf('['));
|
|
||||||
arrIdx = namePart.replace(/(^([a-z_]+)?\[)|(\]$)/gi, '');
|
|
||||||
|
|
||||||
/* Unique array name */
|
|
||||||
arrNameFull += '_' + arrName + '_' + arrIdx;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Because arrIdx in field name can be not zero-based and step can be
|
|
||||||
* other than 1, we can't use them in target array directly.
|
|
||||||
* Instead we're making a hash where key is arrIdx and value is a reference to
|
|
||||||
* added array element
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!arrays[arrNameFull]) arrays[arrNameFull] = {};
|
|
||||||
if (arrName != '' && !currResult[arrName]) currResult[arrName] = [];
|
|
||||||
|
|
||||||
if (j == nameParts.length - 1)
|
|
||||||
{
|
|
||||||
if (arrName == '')
|
|
||||||
{
|
|
||||||
currResult.push(value);
|
|
||||||
arrays[arrNameFull][arrIdx] = convertValue(currResult[currResult.length - 1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currResult[arrName].push(value);
|
|
||||||
arrays[arrNameFull][arrIdx] = convertValue(currResult[arrName][currResult[arrName].length - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!arrays[arrNameFull][arrIdx])
|
|
||||||
{
|
|
||||||
if ((/^[0-9a-z_]+\[?/i).test(nameParts[j+1])) currResult[arrName].push({});
|
|
||||||
else currResult[arrName].push([]);
|
|
||||||
|
|
||||||
arrays[arrNameFull][arrIdx] = convertValue(currResult[arrName][currResult[arrName].length - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currResult = convertValue(arrays[arrNameFull][arrIdx]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
arrNameFull += namePart;
|
|
||||||
|
|
||||||
if (j < nameParts.length - 1) /* Not the last part of name - means object */
|
|
||||||
{
|
|
||||||
if (!currResult[namePart]) currResult[namePart] = {};
|
|
||||||
currResult = convertValue(currResult[namePart]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currResult[namePart] = convertValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertValue(value) {
|
|
||||||
if (value == "true") return true;
|
|
||||||
if (value == "false") return false;
|
|
||||||
if (!isNaN(value)) return parseInt(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled)
|
|
||||||
{
|
|
||||||
var result = extractNodeValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
|
|
||||||
return result.length > 0 ? result : getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled)
|
|
||||||
{
|
|
||||||
var result = [],
|
|
||||||
currentNode = rootNode.firstChild;
|
|
||||||
|
|
||||||
while (currentNode)
|
|
||||||
{
|
|
||||||
result = result.concat(extractNodeValues(currentNode, nodeCallback, useIdIfEmptyName, getDisabled));
|
|
||||||
currentNode = currentNode.nextSibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractNodeValues(node, nodeCallback, useIdIfEmptyName, getDisabled) {
|
|
||||||
if (node.disabled && !getDisabled) return [];
|
|
||||||
|
|
||||||
var callbackResult, fieldValue, result, fieldName = getFieldName(node, useIdIfEmptyName);
|
|
||||||
|
|
||||||
callbackResult = nodeCallback && nodeCallback(node);
|
|
||||||
|
|
||||||
if (callbackResult && callbackResult.name) {
|
|
||||||
result = [callbackResult];
|
|
||||||
}
|
|
||||||
else if (fieldName != '' && node.nodeName.match(/INPUT|TEXTAREA/i)) {
|
|
||||||
fieldValue = getFieldValue(node, getDisabled);
|
|
||||||
if (null === fieldValue) {
|
|
||||||
result = [];
|
|
||||||
} else {
|
|
||||||
result = [ { name: fieldName, value: fieldValue} ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fieldName != '' && node.nodeName.match(/SELECT/i)) {
|
|
||||||
fieldValue = getFieldValue(node, getDisabled);
|
|
||||||
result = [ { name: fieldName.replace(/\[\]$/, ''), value: fieldValue } ];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = getSubFormValues(node, nodeCallback, useIdIfEmptyName, getDisabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFieldName(node, useIdIfEmptyName)
|
|
||||||
{
|
|
||||||
if (node.name && node.name != '') return node.name;
|
|
||||||
else if (useIdIfEmptyName && node.id && node.id != '') return node.id;
|
|
||||||
else return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getFieldValue(fieldNode, getDisabled)
|
|
||||||
{
|
|
||||||
if (fieldNode.disabled && !getDisabled) return null;
|
|
||||||
|
|
||||||
switch (fieldNode.nodeName) {
|
|
||||||
case 'INPUT':
|
|
||||||
case 'TEXTAREA':
|
|
||||||
switch (fieldNode.type.toLowerCase()) {
|
|
||||||
case 'radio':
|
|
||||||
if (fieldNode.checked && fieldNode.value === "false") return false;
|
|
||||||
case 'checkbox':
|
|
||||||
if (fieldNode.checked && fieldNode.value === "true") return true;
|
|
||||||
if (!fieldNode.checked && fieldNode.value === "true") return false;
|
|
||||||
if (fieldNode.checked) return fieldNode.value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'button':
|
|
||||||
case 'reset':
|
|
||||||
case 'submit':
|
|
||||||
case 'image':
|
|
||||||
return '';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return fieldNode.value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'SELECT':
|
|
||||||
return getSelectedOptionValue(fieldNode);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelectedOptionValue(selectNode)
|
|
||||||
{
|
|
||||||
var multiple = selectNode.multiple,
|
|
||||||
result = [],
|
|
||||||
options,
|
|
||||||
i, l;
|
|
||||||
|
|
||||||
if (!multiple) return selectNode.value;
|
|
||||||
|
|
||||||
for (options = selectNode.getElementsByTagName("option"), i = 0, l = options.length; i < l; i++)
|
|
||||||
{
|
|
||||||
if (options[i].selected) result.push(options[i].value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return form2js;
|
|
||||||
|
|
||||||
}));
|
|
|
@ -1,24 +0,0 @@
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "left" }}
|
|
||||||
{{- if and (not .IsDir) (.User.AllowEdit) }}
|
|
||||||
{{- if .Editor}}
|
|
||||||
|
|
||||||
{{- if eq .Data.Mode "markdown" }}
|
|
||||||
<button aria-label="Preview" class="action" id="preview" onclick="notImplemented(event);">
|
|
||||||
<i class="material-icons" title="Preview">remove_red_eye</i>
|
|
||||||
</button>
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- if eq .Data.Visual true }}
|
|
||||||
<button aria-label="Toggle edit source" class="action" id="edit-source">
|
|
||||||
<i class="material-icons" title="Toggle edit source">code</i>
|
|
||||||
</button>
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/* end if editor */}}
|
|
||||||
|
|
||||||
<button aria-label="Save" class="action" id="save">
|
|
||||||
<i class="material-icons" title="Save">save</i>
|
|
||||||
</button>
|
|
||||||
{{- end }}
|
|
|
@ -1,57 +0,0 @@
|
||||||
{{ define "content" }}
|
|
||||||
{{- with .Data }}
|
|
||||||
<form id="editor" {{ if eq .Mode "markdown" }}class="markdown"{{ end }} data-kind="{{ .Class }}" data-rune="{{ if eq .Class "complete" }}{{ .FrontMatter.Rune }}{{ end }}">
|
|
||||||
{{- if or (eq .Class "frontmatter-only") (eq .Class "complete") }}
|
|
||||||
{{- if (eq .Class "complete")}}
|
|
||||||
<h2>Metadata</h2>
|
|
||||||
{{- end }}
|
|
||||||
<div class="frontmatter" data-type="parent">
|
|
||||||
{{- template "blocks" .FrontMatter.Content }}
|
|
||||||
<div class="button add">Add field</div>
|
|
||||||
</div>
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ if or (eq .Class "content-only") (eq .Class "complete") }}
|
|
||||||
{{ if (eq .Class "complete")}}
|
|
||||||
<h2>Body</h2>
|
|
||||||
{{ end }}
|
|
||||||
<div class="content">
|
|
||||||
<div id="ace" data-mode="{{ .Mode }}"></div>
|
|
||||||
<textarea class="source" name="content">{{ .Content }}</textarea>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</form>
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
<template id="base-template">
|
|
||||||
<fieldset id="" data-type="">
|
|
||||||
<h3></h3>
|
|
||||||
<div class="action add">
|
|
||||||
<i class="material-icons">add</i>
|
|
||||||
</div>
|
|
||||||
<div class="action delete" data-delete="">
|
|
||||||
<i class="material-icons">close</i>
|
|
||||||
</div>
|
|
||||||
<div class="group"></div>
|
|
||||||
</fieldset>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="object-item-template">
|
|
||||||
<div class="block" id="block-${bid}" data-content="${bid}">
|
|
||||||
<label for="${bid}">${name}</label>
|
|
||||||
<input name="${bid}" id="${bid}" type="text" data-parent-type="object"></input>
|
|
||||||
<div class="action delete" data-delete="block-${bid}">
|
|
||||||
<i class="material-icons">close</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="array-item-template">
|
|
||||||
<div id="" data-type="array-item">
|
|
||||||
<input name="" id="" type="text" data-parent-type="array"></input>
|
|
||||||
<div class="action delete" data-delete="">
|
|
||||||
<i class="material-icons">close</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
{{ end }}
|
|
|
@ -1,32 +0,0 @@
|
||||||
{{ define "blocks" }}
|
|
||||||
{{ if .Fields }}<div class="group">{{ end }}
|
|
||||||
{{- range $key, $value := .Fields }}
|
|
||||||
{{- if eq $value.Parent.Type "array" }}
|
|
||||||
<div id="{{ $value.Name }}-{{ $key }}" data-type="array-item">
|
|
||||||
{{- template "value" $value }}
|
|
||||||
<div class="action delete" data-delete="{{ $value.Name }}-{{ $key }}">
|
|
||||||
<i class="material-icons" title="Close">close</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- else }}
|
|
||||||
<div class="block" id="block-{{ $value.Name }}" data-content="{{ $value.Name }}">
|
|
||||||
<label for="{{ $value.Name }}">{{ $value.Title }}</label>
|
|
||||||
{{ template "value" $value }}
|
|
||||||
<div class="action delete" data-delete="block-{{ $value.Name }}">
|
|
||||||
<i class="material-icons" title="Close">close</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Fields }}</div>{{ end }}
|
|
||||||
|
|
||||||
{{- range $key, $value := .Arrays }}
|
|
||||||
{{- template "fielset" $value }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- range $key, $value := .Objects }}
|
|
||||||
{{- template "fielset" $value }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
Loading…
Reference in New Issue