2017-03-26 11:24:21 +01:00
'use strict'
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
var editor = {}
2017-03-25 18:35:04 +00:00
editor . textareaAutoGrow = function () {
let autogrow = function () {
console . log ( this . style . height )
2017-03-26 11:24:21 +01:00
this . style . height = 'auto'
this . style . height = ( this . scrollHeight ) + 'px'
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
let textareas = document . getElementsByTagName ( 'textarea' )
2017-03-25 18:35:04 +00:00
let addAutoGrow = () => {
Array . from ( textareas ). forEach ( textarea => {
2017-03-26 11:24:21 +01:00
autogrow . bind ( textarea )()
textarea . addEventListener ( 'keyup' , autogrow )
})
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
addAutoGrow ()
2017-03-25 18:35:04 +00:00
window . addEventListener ( 'resize' , addAutoGrow )
}
editor . toggleSourceEditor = function ( event ) {
2017-03-26 11:24:21 +01:00
event . preventDefault ()
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( document . querySelector ( '[data-kind="content-only"]' )) {
window . location = window . location . pathname + '?visual=true'
return
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
window . location = window . location . pathname + '?visual=false'
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
function deleteFrontMatterItem ( event ) {
event . preventDefault ()
document . getElementById ( this . dataset . delete ). remove ()
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
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' ))
2017-03-25 18:35:04 +00:00
return
}
2017-03-26 11:24:21 +01:00
parent . appendChild ( clone )
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
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 )
2017-03-25 18:35:04 +00:00
parent . querySelector ( '.group' ). appendChild ( clone )
2017-03-26 11:24:21 +01:00
document . getElementById ( ` ${ id } - ${ number } ` ). querySelector ( 'input' ). focus ()
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
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 )
2017-03-25 18:35:04 +00:00
parent . appendChild ( clone )
2017-03-26 11:24:21 +01:00
document . getElementById ( id ). focus ()
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
function addFrontMatterItemPrompt ( parent ) {
2017-03-25 18:35:04 +00:00
return function ( event ) {
2017-03-26 11:24:21 +01:00
event . preventDefault ()
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
let value = event . currentTarget . querySelector ( 'input' ). value
if ( value === '' ) {
return true
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
closePrompt ( event )
2017-03-25 18:35:04 +00:00
let name = value . substring ( 0 , value . lastIndexOf ( ':' )),
2017-03-26 11:24:21 +01:00
type = value . substring ( value . lastIndexOf ( ':' ) + 1 , value . length )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( type !== '' && type !== 'array' && type !== 'object' ) {
name = value
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
name = name . replace ( ' ' , '_' )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
let id = name
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( parent . id != '' ) {
id = parent . id + '.' + id
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
if ( type == 'array' || type == 'object' ) {
if ( parent . dataset . type == 'parent' ) {
makeFromBaseTemplate ( id , type , name , document . querySelector ( '.frontmatter' ))
return
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
makeFromBaseTemplate ( id , type , name , block )
return
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
let group = parent . querySelector ( '.group' )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( group == null ) {
parent . insertAdjacentHTML ( 'afterbegin' , '<div class="group"></div>' )
group = parent . querySelector ( '.group' )
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
makeFromObjectItemTemplate ( id , name , group )
2017-03-25 18:35:04 +00:00
}
}
2017-03-26 11:24:21 +01:00
function addFrontMatterItem ( event ) {
event . preventDefault ()
2017-03-25 18:35:04 +00:00
let parent = event . currentTarget . parentNode ,
2017-03-26 11:24:21 +01:00
type = parent . dataset . type
2017-03-25 18:35:04 +00:00
// If the block is an array
2017-03-26 11:24:21 +01:00
if ( type === 'array' ) {
let id = parent . id + '[]' ,
2017-03-25 18:35:04 +00:00
count = parent . querySelectorAll ( '.group > div' ). length ,
2017-03-26 11:24:21 +01:00
fieldsets = parent . getElementsByTagName ( 'fieldset' )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( fieldsets . length > 0 ) {
2017-03-25 18:35:04 +00:00
let itemType = fieldsets [ 0 ]. dataset . type ,
2017-03-26 11:24:21 +01:00
itemID = parent . id + '[' + fieldsets . length + ']' ,
itemName = fieldsets . length
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
makeFromBaseTemplate ( itemID , itemType , itemName , parent )
2017-03-25 18:35:04 +00:00
} else {
2017-03-26 11:24:21 +01:00
makeFromArrayItemTemplate ( id , count , parent )
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
return
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
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 ))
2017-03-25 18:35:04 +00:00
clone . querySelector ( 'form' ). classList . add ( 'active' )
2017-03-26 11:24:21 +01:00
document . querySelector ( 'body' ). appendChild ( clone )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
document . querySelector ( '.overlay' ). classList . add ( 'active' )
document . getElementById ( tempID ). classList . add ( 'active' )
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
return false
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
document . addEventListener ( 'DOMContentLoaded' , ( event ) => {
if ( ! document . getElementById ( 'editor' )) return
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
editor . textareaAutoGrow ()
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
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' )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
buttons . save = document . querySelector ( '#save' )
buttons . editSource = document . querySelector ( '#edit-source' )
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( buttons . editSource ) {
2017-03-25 18:35:04 +00:00
buttons . editSource . addEventListener ( 'click' , editor . toggleSourceEditor )
}
let container = document . getElementById ( 'editor' ),
kind = container . dataset . kind ,
2017-03-26 11:24:21 +01:00
rune = container . dataset . rune
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( kind != 'frontmatter-only' ) {
2017-03-25 18:35:04 +00:00
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 ,
2017-03-26 11:24:21 +01:00
theme : 'ace/theme/github' ,
2017-03-25 18:35:04 +00:00
showPrintMargin : false ,
2017-03-26 11:24:21 +01:00
fontSize : '1em' ,
2017-03-25 18:35:04 +00:00
minLines : 20
2017-03-26 11:24:21 +01:00
}
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
aceEditor . getSession (). setMode ( 'ace/mode/' + mode )
aceEditor . getSession (). setValue ( textarea . value )
2017-03-25 18:35:04 +00:00
aceEditor . getSession (). on ( 'change' , function () {
2017-03-26 11:24:21 +01:00
textarea . value = aceEditor . getSession (). getValue ()
})
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( mode == 'markdown' ) options . showGutter = false
aceEditor . setOptions ( options )
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
let deleteFrontMatterItemButtons = document . getElementsByClassName ( 'delete' )
2017-03-25 18:35:04 +00:00
Array . from ( deleteFrontMatterItemButtons ). forEach ( button => {
2017-03-26 11:24:21 +01:00
button . addEventListener ( 'click' , deleteFrontMatterItem )
})
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
let addFrontMatterItemButtons = document . getElementsByClassName ( 'add' )
2017-03-25 18:35:04 +00:00
Array . from ( addFrontMatterItemButtons ). forEach ( button => {
2017-03-26 11:24:21 +01:00
button . addEventListener ( 'click' , addFrontMatterItem )
})
2017-03-25 18:35:04 +00:00
let saveContent = function () {
2017-03-26 11:24:21 +01:00
let data = form2js ( document . querySelector ( 'form' ))
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
if ( typeof data . content === 'undefined' && kind !== 'frontmatter-only' ) {
data . content = ''
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
if ( typeof data . content === 'number' ) {
data . content = data . content . toString ()
2017-03-25 18:35:04 +00:00
}
2017-03-26 11:24:21 +01:00
let request = new XMLHttpRequest ()
2017-03-25 18:35:04 +00:00
buttons . setLoading ( 'save' )
webdav . put ( window . location . pathname , JSON . stringify ( data ), {
2017-03-26 11:24:21 +01:00
'Kind' : kind ,
'Rune' : rune
})
2017-03-25 18:35:04 +00:00
. then (() => {
buttons . setDone ( 'save' )
})
. catch ( e => {
2017-03-26 11:24:21 +01:00
console . log ( e )
2017-03-25 18:35:04 +00:00
buttons . setDone ( 'save' , false )
})
}
document . querySelector ( '#save' ). addEventListener ( 'click' , event => {
2017-03-26 11:24:21 +01:00
event . preventDefault ()
saveContent ()
})
2017-03-25 18:35:04 +00:00
document . querySelector ( 'form' ). addEventListener ( 'submit' , ( event ) => {
2017-03-26 11:24:21 +01:00
event . preventDefault ()
saveContent ()
})
2017-03-25 18:35:04 +00:00
window . addEventListener ( 'keydown' , ( event ) => {
2017-03-26 11:24:21 +01:00
if ( event . ctrlKey || event . metaKey ) {
switch ( String . fromCharCode ( event . which ). toLowerCase ()) {
case 's' :
event . preventDefault ()
saveContent ()
break
2017-03-25 18:35:04 +00:00
}
}
2017-03-26 11:24:21 +01:00
})
2017-03-25 18:35:04 +00:00
2017-03-26 11:24:21 +01:00
return false
})