diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..63339e38 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# 4 space indentation +[*.go] +indent_style = tab +indent_size = 4 diff --git a/.jsbeautifyrc b/.jsbeautifyrc new file mode 100644 index 00000000..71f718e7 --- /dev/null +++ b/.jsbeautifyrc @@ -0,0 +1,22 @@ +{ + "html": { + "brace_style": "collapse", + "indent_scripts": "normal", + "max_preserve_newlines": 1, + "preserve_newlines": true, + "unformatted": ["a", "sub", "sup", "b", "i", "u"], + "wrap_line_length": 0 + }, + "css": { + "end_with_newline": false, + "newline_between_rules": true, + "selector_separator": " ", + "selector_separator_newline": true + }, + "js": { + "indent_with_tabs": false, + "preserve_newlines": true, + "max_preserve_newlines": 2, + "jslint_happy": true + } +} diff --git a/assets/public/js/.jsbeautifyrc b/assets/public/js/.jsbeautifyrc deleted file mode 100644 index 3077c481..00000000 --- a/assets/public/js/.jsbeautifyrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "js": { - "allowed_file_extensions": ["js", "json", "jshintrc", "jsbeautifyrc"], - - // Set brace_style - // collapse: (old default) Put braces on the same line as control statements - // collapse-preserve-inline: (new default) Same as collapse but better support for ES6 destructuring and other features. https://github.com/victorporof/Sublime-HTMLPrettify/issues/231 - // expand: Put braces on own line (Allman / ANSI style) - // end-expand: Put end braces on own line - // none: Keep them where they are - "brace_style": "collapse-preserve-inline", - - "break_chained_methods": false, // Break chained method calls across subsequent lines - "e4x": false, // Pass E4X xml literals through untouched - "end_with_newline": false, // End output with newline - "indent_char": " ", // Indentation character - "indent_level": 0, // Initial indentation level - "indent_size": 4, // Indentation size - "indent_with_tabs": false, // Indent with tabs, overrides `indent_size` and `indent_char` - "jslint_happy": false, // If true, then jslint-stricter mode is enforced - "keep_array_indentation": false, // Preserve array indentation - "keep_function_indentation": false, // Preserve function indentation - "max_preserve_newlines": 0, // Maximum number of line breaks to be preserved in one chunk (0 disables) - "preserve_newlines": true, // Whether existing line breaks should be preserved - "space_after_anon_function": false, // Should the space before an anonymous function's parens be added, "function()" vs "function ()" - "space_before_conditional": true, // Should the space before conditional statement be added, "if(true)" vs "if (true)" - "space_in_empty_paren": false, // Add padding spaces within empty paren, "f()" vs "f( )" - "space_in_paren": false, // Add padding spaces within paren, ie. f( a, b ) - "unescape_strings": false, // Should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65" - "wrap_line_length": 0 // Lines should wrap at next opportunity after this number of characters (0 disables) - } -} diff --git a/assets/public/js/application.js b/assets/public/js/application.js index 2c563b2f..04cbd888 100644 --- a/assets/public/js/application.js +++ b/assets/public/js/application.js @@ -1,130 +1,145 @@ 'use strict'; document.addEventListener('DOMContentLoaded', event => { - document.querySelector('footer').innerHTML += 'With a flavour of Hugo.'; - document.querySelector('.only-side > p > a').innerHTML = "Hugo"; + document.querySelector('#top-bar > div > p:first-child').innerHTML = 'Hugo for Caddy' + document.querySelector('footer').innerHTML += ' With a flavour of Hugo.'; - let link = document.querySelector('.only-side > p a:first-child').getAttribute('href') + "/settings/" - document.getElementById('logout').insertAdjacentHTML('beforebegin', ` + document.querySelector('#bottom-bar>*:first-child').style.maxWidth = "calc(100% - 27em)" + + let link = baseURL + "/settings/" + + document.getElementById('info').insertAdjacentHTML('beforebegin', `
settings Settings
`); -}); -document.addEventListener('listing', event => { - if (window.location.pathname.includes('/content/')) { - document.getElementById('newdir').placeholder = "file[:archetype]..."; - document.getElementById('newdir').removeEventListener('keydown', newDirEvent); - document.getElementById('newdir').addEventListener('keydown', event => { + if(buttons.new && window.location.pathname === baseURL + "/content/") { + buttons.new.removeEventListener('click', listing.newFileButton); + buttons.new.addEventListener('click', hugo.newFileButton); + } - if (event.keyCode == 27) { - document.getElementById('newdir').classList.toggle('enabled'); - setTimeout(() => { - document.getElementById('newdir').value = ''; - }, 200); - } + if(buttons.save) { + let box = document.getElementById('file-only'); - if (event.keyCode == 13) { - event.preventDefault(); + box.insertAdjacentHTML('beforeend', `
+ send + Publish +
`); - let value = document.getElementById('newdir').value; - let index = value.lastIndexOf(':'); - let name = value.substring(0, index); - let archetype = value.substring(index + 1, value.length); - if (name == "") name = archetype; - if (index == -1) archetype = ""; + buttons.publish = document.getElementById('publish') + buttons.publish.addEventListener('click', hugo.publish) - let button = document.getElementById('new'); - let html = button.changeToLoading(); - let request = new XMLHttpRequest(); - request.open("PUT", toWebDavURL(window.location.pathname + name)); - request.setRequestHeader('Filename', name); - request.setRequestHeader('Archetype', archetype); - request.send(); - request.onreadystatechange = function() { - if (request.readyState == 4) { - if (request.status != 200 && request.status != 201) { - button.changeToDone(true, html); - return; - } - - button.changeToDone(false, html); - window.location = window.location.pathname + name; - } - } - } - }); - } -}); + if((document.getElementById('date') || document.getElementById('publishdate')) && + document.getElementById('editor').dataset.kind == "complete") { -document.addEventListener('editor', event => { - let container = document.getElementById('editor'), - kind = container.dataset.kind; + box.insertAdjacentHTML('beforeend', `
+ alarm + Schedule +
`); - document.getElementById('submit').insertAdjacentHTML('afterend', `
- -
`); - - if ((document.getElementById('date') || document.getElementById('publishdate')) && document.getElementById('editor').dataset.kind == "complete") { - document.querySelector('#editor .right').insertAdjacentHTML('afterbegin', ` `); - - let button = document.querySelector('#schedule span:first-child'); - - document.getElementById('schedule').addEventListener('click', event => { - event.preventDefault(); - - let date = document.getElementById('date').value; - if (document.getElementById('publishDate')) { - date = document.getElementById('publishDate').value; - } - - let data = form2js(document.querySelector('form')); - let html = button.changeToLoading(); - let request = new XMLHttpRequest(); - request.open("PUT", toWebDavURL(window.location.pathname)); - request.setRequestHeader('Kind', kind); - request.setRequestHeader('Schedule', date); - request.send(JSON.stringify(data)); - request.onreadystatechange = function() { - if (request.readyState == 4) { - button.changeToDone((request.status != 200 && request.status != 201), html); - } - } - }); + buttons.schedule = document.getElementById('schedule') + buttons.schedule.addEventListener('click', hugo.schedule) } - document.getElementById('publish').addEventListener('click', event => { - event.preventDefault(); + document.querySelector('#bottom-bar>*:first-child').style.maxWidth = "calc(100% - 30em)" + } +}); - if (document.getElementById('draft')) { - document.getElementById('block-draft').remove(); - } +var hugo = {}; - let button = document.querySelector('#publish span:first-child'), - data = form2js(document.querySelector('form')), - html = button.changeToLoading(), - request = new XMLHttpRequest(); - - request.open("PUT", toWebDavURL(window.location.pathname)); - request.setRequestHeader('Kind', kind); - request.setRequestHeader('Regenerate', "true"); - request.send(JSON.stringify(data)); - request.onreadystatechange = function() { - if (request.readyState == 4) { - button.changeToDone((request.status != 200 && request.status != 201), html); - } - } +hugo.newFileButton = function (event) { + event.preventDefault(); + event.stopPropagation(); + + let clone = document.importNode(templates.question.content, true); + clone.querySelector('h3').innerHTML = 'New file'; + clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir. To use an archetype, use file[:archetype].'; + clone.querySelector('.ok').innerHTML = 'Create'; + clone.querySelector('form').addEventListener('submit', hugo.newFilePrompt); + + document.querySelector('body').appendChild(clone) + document.querySelector('.overlay').classList.add('active'); + document.querySelector('.prompt').classList.add('active'); +} + +hugo.newFilePrompt = function (event) { + event.preventDefault(); + buttons.setLoading('new'); + + let value = event.currentTarget.querySelector('input').value, + index = value.lastIndexOf(':'), + name = value.substring(0, index), + archetype = value.substring(index + 1, value.length); + + if(name == "") name = archetype; + if(index == -1) archetype = ""; + + webdav.new(window.location.pathname + name, '', { + 'Filename': name, + 'Archetype': archetype + }) + .then(() => { + buttons.setDone('new'); + window.location = window.location.pathname + name; + }) + .catch(e => { + console.log(e); + buttons.setDone('new', false); }); -}); \ No newline at end of file + + closePrompt(event); + return false; +} + +hugo.publish = function (event) { + event.preventDefault(); + + if(document.getElementById('draft')) { + document.getElementById('block-draft').remove(); + } + + buttons.setLoading('publish'); + + let data = JSON.stringify(form2js(document.querySelector('form'))), + headers = { + 'Kind': document.getElementById('editor').dataset.kind, + 'Regenerate': 'true' + }; + + webdav.put(window.location.pathname, data, headers) + .then(() => { + buttons.setDone('publish'); + }) + .catch(e => { + console.log(e); + buttons.setDone('publish', false) + }) +} + +hugo.schedule = function (event) { + event.preventDefault(); + + let date = document.getElementById('date').value; + if(document.getElementById('publishDate')) { + date = document.getElementById('publishDate').value; + } + + buttons.setLoading('publish'); + + let data = JSON.stringify(form2js(document.querySelector('form'))), + headers = { + 'Kind': document.getElementById('editor').dataset.kind, + 'Schedule': 'true' + }; + + webdav.put(window.location.pathname, data, headers) + .then(() => { + buttons.setDone('publish'); + }) + .catch(e => { + console.log(e); + buttons.setDone('publish', false) + }) +} diff --git a/setup.go b/setup.go index 22e96cb1..6bfe7453 100644 --- a/setup.go +++ b/setup.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "log" + "net/http" "os" "os/exec" "path/filepath" @@ -94,6 +95,8 @@ func parse(c *caddy.Controller, root string) (*Config, *filemanager.FileManager, cfg.Public = strings.Replace(root, "./", "", -1) cfg.BaseURL = "/admin" cfg.Root = "./" + cfg.BeforePublish = func(r *http.Request, c *config.Config, u *config.User) error { return nil } + cfg.AfterPublish = func(r *http.Request, c *config.Config, u *config.User) error { return nil } args := c.RemainingArgs()