2016-12-30 11:15:10 +00:00
'use strict' ;
2017-01-02 16:01:35 +00:00
var editor = {};
2017-01-03 17:35:13 +00:00
editor . textareaAutoGrow = function () {
let autogrow = function () {
2017-01-03 17:10:30 +00:00
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 );
});
}
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
addAutoGrow ();
window . addEventListener ( 'resize' , addAutoGrow )
2016-12-30 11:15:10 +00:00
}
2017-01-15 11:47:52 +00:00
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"
}
2016-12-30 11:15:10 +00:00
function deleteFrontMatterItem ( event ) {
2017-01-03 17:10:30 +00:00
event . preventDefault ();
document . getElementById ( this . dataset . delete ). remove ();
2016-12-30 11:15:10 +00:00
}
2016-12-31 15:29:36 +00:00
function makeFromBaseTemplate ( id , type , name , parent ) {
2017-01-03 17:10:30 +00:00
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 );
2017-01-03 17:35:13 +00:00
if ( parent . classList . contains ( "frontmatter" )) {
2017-01-03 17:10:30 +00:00
parent . insertBefore ( clone , document . querySelector ( 'div.button.add' ));
return
}
parent . appendChild ( clone );
2016-12-31 15:29:36 +00:00
}
2016-12-30 11:15:10 +00:00
2016-12-31 15:29:36 +00:00
function makeFromArrayItemTemplate ( id , number , parent ) {
2017-01-03 17:10:30 +00:00
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 ();
2016-12-31 15:29:36 +00:00
}
2016-12-30 11:36:28 +00:00
2016-12-31 15:29:36 +00:00
function makeFromObjectItemTemplate ( id , name , parent ) {
2017-01-03 17:10:30 +00:00
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 ();
2016-12-31 15:29:36 +00:00
}
2016-12-30 11:15:10 +00:00
2016-12-31 15:29:36 +00:00
function addFrontMatterItemPrompt ( parent ) {
2017-01-03 17:35:13 +00:00
return function ( event ) {
2017-01-03 17:10:30 +00:00
event . preventDefault ();
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
let value = event . currentTarget . querySelector ( 'input' ). value ;
2017-01-03 17:35:13 +00:00
if ( value === '' ) {
2017-01-03 17:10:30 +00:00
return true ;
}
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
closePrompt ( event );
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
let name = value . substring ( 0 , value . lastIndexOf ( ':' )),
2017-01-03 17:35:13 +00:00
type = value . substring ( value . lastIndexOf ( ':' ) + 1 , value . length );
2016-12-31 15:29:36 +00:00
2017-01-03 17:35:13 +00:00
if ( type !== "" && type !== "array" && type !== "object" ) {
2017-01-03 17:10:30 +00:00
name = value ;
}
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
name = name . replace ( ' ' , '_' );
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
let id = name ;
2016-12-31 15:29:36 +00:00
2017-01-03 17:35:13 +00:00
if ( parent . id != '' ) {
2017-01-03 17:10:30 +00:00
id = parent . id + "." + id ;
}
2016-12-31 15:29:36 +00:00
2017-01-03 17:35:13 +00:00
if ( type == "array" || type == "object" ) {
if ( parent . dataset . type == "parent" ) {
2017-01-03 17:10:30 +00:00
makeFromBaseTemplate ( id , type , name , document . querySelector ( '.frontmatter' ));
return ;
}
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
makeFromBaseTemplate ( id , type , name , block );
return ;
}
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
let group = parent . querySelector ( '.group' );
2016-12-31 15:29:36 +00:00
2017-01-03 17:35:13 +00:00
if ( group == null ) {
2017-01-03 17:10:30 +00:00
parent . insertAdjacentHTML ( 'afterbegin' , '<div class="group"></div>' );
group = parent . querySelector ( '.group' );
2016-12-30 11:15:10 +00:00
}
2017-01-03 17:10:30 +00:00
makeFromObjectItemTemplate ( id , name , group );
}
2016-12-31 15:29:36 +00:00
}
function addFrontMatterItem ( event ) {
2017-01-03 17:10:30 +00:00
event . preventDefault ();
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
let parent = event . currentTarget . parentNode ,
2017-01-03 17:35:13 +00:00
type = parent . dataset . type ;
2016-12-31 15:29:36 +00:00
2017-01-03 17:10:30 +00:00
// If the block is an array
2017-01-03 17:35:13 +00:00
if ( type === "array" ) {
2017-01-03 17:10:30 +00:00
let id = parent . id + "[]" ,
2017-01-03 17:35:13 +00:00
count = parent . querySelectorAll ( '.group > div' ). length ,
fieldsets = parent . getElementsByTagName ( "fieldset" );
2016-12-30 11:15:10 +00:00
2017-01-03 17:35:13 +00:00
if ( fieldsets . length > 0 ) {
2017-01-03 17:10:30 +00:00
let itemType = fieldsets [ 0 ]. dataset . type ,
2017-01-03 17:35:13 +00:00
itemID = parent . id + "[" + fieldsets . length + "]" ,
itemName = fieldsets . length ;
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
makeFromBaseTemplate ( itemID , itemType , itemName , parent );
} else {
makeFromArrayItemTemplate ( id , count , parent );
2016-12-31 15:29:36 +00:00
}
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
return ;
}
2017-01-03 17:35:13 +00:00
if ( type == "object" || type == "parent" ) {
2017-01-03 17:10:30 +00: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' );
}
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
return false ;
2016-12-30 11:15:10 +00:00
}
document . addEventListener ( "DOMContentLoaded" , ( event ) => {
2017-01-03 17:35:13 +00:00
if ( ! document . getElementById ( 'editor' )) return ;
2017-01-03 17:10:30 +00:00
editor . textareaAutoGrow ();
2017-01-15 11:47:52 +00:00
2017-01-03 17:10:30 +00: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-01-15 11:47:52 +00:00
2017-01-03 17:10:30 +00:00
buttons . save = document . querySelector ( '#save' );
2017-01-15 11:47:52 +00:00
buttons . editSource = document . querySelector ( '#edit-source' );
if ( buttons . editSource ) {
buttons . editSource . addEventListener ( 'click' , editor . toggleSourceEditor )
}
2017-01-03 17:10:30 +00:00
let container = document . getElementById ( 'editor' ),
2017-01-18 18:20:56 +00:00
kind = container . dataset . kind ,
rune = container . dataset . rune ;
2017-01-03 17:10:30 +00:00
2017-01-03 17:35:13 +00:00
if ( kind != 'frontmatter-only' ) {
2017-01-03 17:10:30 +00:00
let editor = document . querySelector ( '.content #ace' ),
2017-01-03 17:35:13 +00:00
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
};
2017-01-03 17:10:30 +00:00
aceEditor . getSession (). setMode ( "ace/mode/" + mode );
aceEditor . getSession (). setValue ( textarea . value );
2017-01-03 17:35:13 +00:00
aceEditor . getSession (). on ( 'change' , function () {
2017-01-03 17:10:30 +00:00
textarea . value = aceEditor . getSession (). getValue ();
2016-12-30 11:15:10 +00:00
});
2017-01-03 17:35:13 +00:00
if ( mode == "markdown" ) options . showGutter = false ;
2017-01-03 17:10:30 +00:00
aceEditor . setOptions ( options );
}
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
let deleteFrontMatterItemButtons = document . getElementsByClassName ( 'delete' );
Array . from ( deleteFrontMatterItemButtons ). forEach ( button => {
button . addEventListener ( 'click' , deleteFrontMatterItem );
});
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
let addFrontMatterItemButtons = document . getElementsByClassName ( 'add' );
Array . from ( addFrontMatterItemButtons ). forEach ( button => {
button . addEventListener ( 'click' , addFrontMatterItem );
});
2016-12-30 11:15:10 +00:00
2017-01-03 17:35:13 +00:00
let saveContent = function () {
2017-01-03 17:10:30 +00:00
let data = form2js ( document . querySelector ( 'form' ));
2016-12-30 11:15:10 +00:00
2017-01-03 17:35:13 +00:00
if ( typeof data . content === "undefined" && kind != 'frontmatter-only' ) {
2017-01-03 17:10:30 +00:00
data . content = "" ;
}
2016-12-30 11:36:28 +00:00
2017-01-03 17:35:13 +00:00
if ( typeof data . content === "number" ) {
2017-01-03 17:10:30 +00:00
data . content = data . content . toString ();
2016-12-30 11:15:10 +00:00
}
2017-01-03 18:13:08 +00:00
let request = new XMLHttpRequest ();
buttons . setLoading ( 'save' )
webdav . put ( window . location . pathname , JSON . stringify ( data ), {
2017-01-18 18:20:56 +00:00
'Kind' : kind ,
'Rune' : rune
2017-01-03 18:13:08 +00:00
})
. then (() => {
buttons . setDone ( 'save' )
})
. catch ( e => {
console . log ( e );
buttons . setDone ( 'save' , false )
})
2017-01-03 17:10:30 +00:00
}
document . querySelector ( '#save' ). addEventListener ( 'click' , event => {
event . preventDefault ();
saveContent ();
});
document . querySelector ( 'form' ). addEventListener ( 'submit' , ( event ) => {
event . preventDefault ();
saveContent ();
});
window . addEventListener ( 'keydown' , ( event ) => {
2017-01-03 17:35:13 +00:00
if ( event . ctrlKey || event . metaKey ) {
switch ( String . fromCharCode ( event . which ). toLowerCase ()) {
case 's' :
2016-12-30 11:15:10 +00:00
event . preventDefault ();
saveContent ();
2017-01-03 17:10:30 +00:00
break ;
}
}
});
2016-12-30 11:15:10 +00:00
2017-01-03 17:10:30 +00:00
return false ;
2017-01-15 11:47:52 +00:00
});