2017-06-25 09:11:25 +01:00
'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 )
2017-06-26 17:53:29 +01:00
let name = value . substring ( 0 , value . lastIndexOf ( ':' ))
let type = value . substring ( value . lastIndexOf ( ':' ) + 1 , value . length )
2017-06-25 09:11:25 +01:00
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 ()
2017-06-26 17:53:29 +01:00
let parent = event . currentTarget . parentNode
let type = parent . dataset . type
2017-06-25 09:11:25 +01:00
// If the block is an array
if ( type === 'array' ) {
2017-06-26 17:53:29 +01:00
let id = parent . id + '[]'
let count = parent . querySelectorAll ( '.group > div' ). length
let fieldsets = parent . getElementsByTagName ( 'fieldset' )
2017-06-25 09:11:25 +01:00
if ( fieldsets . length > 0 ) {
2017-06-26 17:53:29 +01:00
let itemType = fieldsets [ 0 ]. dataset . type
let itemID = parent . id + '[' + fieldsets . length + ']'
let itemName = fieldsets . length
2017-06-25 09:11:25 +01:00
makeFromBaseTemplate ( itemID , itemType , itemName , parent )
} else {
makeFromArrayItemTemplate ( id , count , parent )
}
return
}
2017-06-26 17:53:29 +01:00
if ( type === 'object' || type === 'parent' ) {
2017-06-25 09:11:25 +01:00
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
})