From 062f10ffd7007d40bd48b399d58f63e5fd0ff19f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 28 Jun 2016 10:01:00 +0100 Subject: [PATCH] updates --- assets/.jsbeautifyrc | 62 ++ assets/public/css/styles.css | 294 +++++++-- assets/public/js/application.js | 952 +++++++++++++++--------------- assets/public/js/form-to-json.js | 349 ----------- assets/public/js/form2js.js | 2 + assets/templates/base.tmpl | 180 +++--- assets/templates/editor.tmpl | 48 +- assets/templates/frontmatter.tmpl | 85 +-- assets/templates/listing.tmpl | 9 +- internal/assets/binary.go | 35 +- 10 files changed, 1011 insertions(+), 1005 deletions(-) create mode 100644 assets/.jsbeautifyrc delete mode 100644 assets/public/js/form-to-json.js create mode 100644 assets/public/js/form2js.js diff --git a/assets/.jsbeautifyrc b/assets/.jsbeautifyrc new file mode 100644 index 00000000..54a7a705 --- /dev/null +++ b/assets/.jsbeautifyrc @@ -0,0 +1,62 @@ +{ + // The plugin looks for a .jsbeautifyrc file in the same directory as the + // source file you're prettifying (or any directory above if it doesn't exist, + // or in your home folder if everything else fails) and uses those options + // along the default ones. + + // Details: https://github.com/victorporof/Sublime-HTMLPrettify#using-your-own-jsbeautifyrc-options + // Documentation: https://github.com/einars/js-beautify/ + "html": { + "allowed_file_extensions": ["htm", "html", "xhtml", "shtml", "xml", "svg"], + "brace_style": "collapse", // [collapse|expand|end-expand|none] Put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are + "end_with_newline": false, // End output with newline + "indent_char": " ", // Indentation character + "indent_handlebars": false, // e.g. {{#foo}}, {{/foo}} + "indent_inner_html": false, // Indent and sections + "indent_scripts": "keep", // [keep|separate|normal] + "indent_size": 4, // Indentation size + "max_preserve_newlines": 0, // Maximum number of line breaks to be preserved in one chunk (0 disables) + "preserve_newlines": true, // Whether existing line breaks before elements should be preserved (only works before elements, not inside tags or for text) + "unformatted": ["a", "span", "img", "code", "pre", "sub", "sup", "em", "strong", "b", "i", "u", "strike", "big", "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6"], // List of tags that should not be reformatted + "wrap_line_length": 0 // Lines should wrap at next opportunity after this number of characters (0 disables) + }, + "css": { + "allowed_file_extensions": ["css", "scss", "sass", "less"], + "end_with_newline": false, // End output with newline + "indent_char": " ", // Indentation character + "indent_size": 4, // Indentation size + "newline_between_rules": true, // Add a new line after every css rule + "selector_separator": " ", + "selector_separator_newline": true // Separate selectors with newline or not (e.g. "a,\nbr" or "a, br") + }, + "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/css/styles.css b/assets/public/css/styles.css index 474575d6..b9cb2008 100644 --- a/assets/public/css/styles.css +++ b/assets/public/css/styles.css @@ -5,101 +5,161 @@ html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100% } + body { margin: 0 } -article, aside, details, figcaption, figure, footer, header, main, menu, nav, section, summary { + +article, +aside, +details, +figcaption, +figure, +footer, +header, +main, +menu, +nav, +section, +summary { display: block } -audio, canvas, progress, video { + +audio, +canvas, +progress, +video { display: inline-block } + audio:not([controls]) { display: none; height: 0 } + progress { vertical-align: baseline } -template, [hidden] { + +template, +[hidden] { display: none } + a { background-color: transparent; -webkit-text-decoration-skip: objects } -a:active, a:hover { + +a:active, +a:hover { outline-width: 0 } + abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted } -b, strong { + +b, +strong { font-weight: inherit } -b, strong { + +b, +strong { font-weight: bolder } + dfn { font-style: italic } + h1 { font-size: 2em; margin: 0.67em 0 } + mark { background-color: #ff0; color: #000 } + small { font-size: 80% } -sub, sup { + +sub, +sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline } + sub { bottom: -0.25em } + sup { top: -0.5em } + img { - border-style: none + border-style: none; + max-width: 100%; } + svg:not(:root) { overflow: hidden } -code, kbd, pre, samp { + +code, +kbd, +pre, +samp { font-family: monospace, monospace; font-size: 1em } + figure { margin: 1em 40px } + hr { box-sizing: content-box; height: 0; overflow: visible } -button, input, select, textarea { + +button, +input, +select, +textarea { font: inherit; margin: 0 } + optgroup { font-weight: bold } -button, input { + +button, +input { overflow: visible } -button, select { + +button, +select { text-transform: none } -button, .button, html [type="button"], [type="reset"], [type="submit"] { + +button, +.button, +html [type="button"], +[type="reset"], +[type="submit"] { /* -webkit-appearance: button; */ text-decoration: none; color: #fff !important; @@ -121,13 +181,25 @@ button, .button, html [type="button"], [type="reset"], [type="submit"] { vertical-align: middle; -webkit-tap-highlight-color: transparent; } -button::-moz-focus-inner,.button::-moz-focus-inner, . [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + +button::-moz-focus-inner, +.button::-moz-focus-inner, +. [type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { border-style: none; padding: 0 } -button:-moz-focusring, .button:-moz-focusring,, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { + +button:-moz-focusring, +.button:-moz-focusring, +, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { outline: 1px dotted ButtonText } + fieldset { border: none; margin: 0; @@ -136,6 +208,7 @@ fieldset { page-break-inside: avoid; break-inside: avoid; } + legend { box-sizing: border-box; color: inherit; @@ -144,32 +217,43 @@ legend { padding: 0; white-space: normal } + textarea { overflow: auto } -[type="checkbox"], [type="radio"] { + +[type="checkbox"], +[type="radio"] { box-sizing: border-box; padding: 0 } -[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { height: auto } + [type="search"] { -webkit-appearance: textfield; outline-offset: -2px } -[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { -webkit-appearance: none } + ::-webkit-input-placeholder { color: inherit; opacity: 0.54 } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit } + /* TANANANA */ body { @@ -178,23 +262,33 @@ body { background-color: #fcfcfc; text-rendering: optimizespeed; } + a { text-decoration: none; color: #006ed3; } -a:hover, h1 a:hover { + +a:hover, +h1 a:hover { color: #319cff; } -#summary, header { + +#summary, +header { padding-right: 7%; padding-left: 7%; } -td:first-child, th:first-child { + +td:first-child, +th:first-child { padding-left: 1em; } -td:last-child, th:last-child { + +td:last-child, +th:last-child { padding-right: 1em; } + h1 { font-size: 1.5em; font-weight: normal; @@ -202,60 +296,79 @@ h1 { white-space: nowrap; text-overflow: ellipsis; } + h1 a { color: inherit; } + h1 a:hover { text-decoration: underline; } + main { display: block; } + .meta-item { margin-right: 1em; } + table { width: 100%; border-collapse: collapse; } + tr { cursor: pointer; -webkit-transition: 0.1s ease all; transition: 0.1s ease all; border-bottom: 1px dashed #dadada; } + tr.selected { background-color: #ccc; } -td, th { + +td, +th { padding: 1em 0; text-align: left; } + th { font-size: 16px; padding-top: 15px; padding-bottom: 15px; white-space: nowrap; } + th a { color: black; } + th svg { vertical-align: middle; } + td { font-size: 14px; } + td:first-child { width: 50%; } -td:last-child, th:last-child { + +td:last-child, +th:last-child { text-align: right; } + td:first-child svg { position: absolute; } -td .goup, td .name { + +td .goup, +td .name { margin-left: 1.1em; vertical-align: middle; white-space: pre-wrap; @@ -263,26 +376,32 @@ td .goup, td .name { color: #424242; overflow-wrap: break-word; } + footer { font-size: 0.6em; margin: 1em 0; text-align: center; color: grey; } -footer a, footer a:hover { + +footer a, +footer a:hover { color: inherit; } + .container { width: 95%; max-width: 960px; margin: 0 auto; } + pre { padding: 1em; border: 1px solid #e6e6e6; border-radius: 0.5em; background-color: #f5f5f5; } + @media (max-width: 600px) { .hideable { display: none; @@ -290,18 +409,21 @@ pre { td:first-child { width: auto; } - td:nth-child(2), th:nth-child(2) { + td:nth-child(2), + th:nth-child(2) { padding-right: 5%; text-align: right; } } + /* MY STYLES */ * { box-sizing: border-box; } + /* MATERIAL ICONS */ .material-icons { @@ -328,6 +450,7 @@ pre { font-feature-settings: 'liga'; } + /* HEADER */ header { @@ -335,29 +458,37 @@ header { padding: 1.7em 0; background-color: #2196f3; } + header h1 { font-size: 2em; margin: 0; } -header a, header a:hover { + +header a, +header a:hover { color: inherit; } + header p { font-size: 1.5em; } + header p i { font-size: 1em !important; color: rgba(255, 255, 255, .31); } + header #logout { background-color: rgba(0, 0, 0, 0.1); border-radius: 0; margin: -0.5em -0.5em -0.5em 0; padding: .5em; } + header p i { vertical-align: middle; } + header form { display: inline-block; height: 100%; @@ -367,38 +498,48 @@ header form { border-radius: 0.3em; background-color: #1e88e5; } -header form i, header form input { + +header form i, +header form input { vertical-align: middle; } + header form i { margin-right: 0.3em; color: rgba(255, 255, 255, .5); } + header form input { min-width: 20em; border: 0; outline: 0; background-color: transparent; } + header form::-webkit-input-placeholder { /* WebKit, Blink, Edge */ color: rgba(255, 255, 255, .5); } + header form:-moz-placeholder { opacity: 1; /* Mozilla Firefox 4 to 18 */ color: rgba(255, 255, 255, .5); } + header form::-moz-placeholder { opacity: 1; /* Mozilla Firefox 19+ */ color: rgba(255, 255, 255, .5); } + header form:-ms-input-placeholder { /* Internet Explorer 10-11 */ color: rgba(255, 255, 255, .5); } -#toolbar, header { + +#toolbar, +header { position: fixed; top: 0; left: 0; @@ -409,20 +550,29 @@ header form:-ms-input-placeholder { padding: 0.5em; color: #fff; } -#toolbar div, header div { + +#toolbar div, +header div { vertical-align: middle; -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } -#toolbar p, header p { + +#toolbar p, +header p { display: inline-block; margin: 0; vertical-align: middle; } -#toolbar p a, #toolbar p a:hover, header p a, header p a:hover { + +#toolbar p a, +#toolbar p a:hover, +header p a, +header p a:hover { color: inherit; } + #toolbar { z-index: 1000; top: -4em; @@ -432,13 +582,17 @@ header form:-ms-input-placeholder { color: #fff; background-color: #6f6f6f; } + #toolbar.enabled { top: 0; opacity: 1; } -#toolbar div:nth-child(2), header div:nth-child(2) { + +#toolbar div:nth-child(2), +header div:nth-child(2) { text-align: right; } + .action { display: inline-block; margin: 0 0.2em; @@ -448,30 +602,36 @@ header form:-ms-input-placeholder { border: 0; border-radius: 50%; } + .action.disabled { opacity: 0.2; cursor: not-allowed; } + .action i { padding: 0.5em; -webkit-transition: 0.2s ease-in-out all; transition: 0.2s ease-in-out all; border-radius: 50%; } + .action:hover i { background-color: rgba(0, 0, 0, .1); } + .floating { position: fixed; bottom: 1em; right: 1em; } + .floating .action { background-color: #68EFAD; color: #306e50; box-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 1px 2px rgba(0, 0, 0, .12); } + /* LISTING */ #listing { @@ -485,12 +645,14 @@ header form:-ms-input-placeholder { -ms-flex-pack: justify; justify-content: space-between; } + #listing.list { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } + #listing .item { margin: 0 0.5em 1em; padding: 0.5em; @@ -506,6 +668,7 @@ header form:-ms-input-placeholder { flex-grow: 1; position: relative; } + #listing .item .checkbox { position: absolute; top: 0; @@ -515,44 +678,55 @@ header form:-ms-input-placeholder { border: 0; -webkit-appearance: initial; } + .item:hover { box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24) !important; } + .item.selected { border-color: #6f6f6f !important; } + .item div { display: inline-block; vertical-align: middle; } + .item p { font-size: 0.9em; margin: 0; color: #4e4e4e; } + .item span { font-weight: bold; } + .item i { font-size: 4em; margin-right: 0.1em; } -.item a, .item a:hover { + +.item a, +.item a:hover { color: #6f6f6f; } + /* ANIMATIONS */ i.spin { -webkit-animation: 1s spin linear infinite; animation: 1s spin linear infinite; } + @-webkit-keyframes spin { 100% { -webkit-transform: rotate(-360deg); transform: rotate(-360deg); } } + @keyframes spin { 100% { -webkit-transform: rotate(-360deg); @@ -560,6 +734,7 @@ i.spin { } } + /* EDITOR */ #editor .frontmatter { @@ -571,7 +746,9 @@ i.spin { column-gap: 1em; margin-bottom: 1em; } -#editor .group, #editor #editor-source { + +#editor .group, +#editor #editor-source { box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); display: block; border-radius: .2em; @@ -585,31 +762,41 @@ i.spin { width: 100%; break-inside: avoid-column; } + #editor .block { border-bottom: 1px solid #eee; margin-bottom: .5em; padding-bottom: .5em; } + #editor .block:last-child { border: 0; margin: 0; padding: 0; } + #editor .block label { display: block; color: #212121; font-weight: 500; } + #editor h3 { margin: 0 0 .5em; display: inline-block; vertical-align: middle; width: calc(100% - 2.5em); } -#editor .block input, #editor .block .actions { + +#editor .block input, +#editor .block .actions { display: inline-block; } -#editor .block input, #editor .block textarea, #editor fieldset input, #editor fieldset textarea { + +#editor .block input, +#editor .block textarea, +#editor fieldset input, +#editor fieldset textarea { border: 0; background-color: transparent; overflow: hidden; @@ -617,51 +804,67 @@ i.spin { resize: none; width: calc(100% - 1.5em); } + #editor .action { border: 0; background-color: transparent; font-size: .8em; margin: 0; } -#editor .delete, #editor .add { + +#editor .delete, +#editor .add { color: #ddd; } + #editor i { padding: 0; } + #editor .add:hover i { color: #8BC34A; } + #editor .delete:hover i { color: #E53935; } -#editor .add:hover i, #editor .delete:hover i { + +#editor .add:hover i, +#editor .delete:hover i { background-color: transparent; } + #editor fieldset> .action { opacity: 0; } + #editor fieldset:hover> .action { opacity: 1; } + #editor textarea[name="content"] { display: none; } + #editor fieldset fieldset { margin-left: 1em; } + #editor #submit span { vertical-align: middle; transition: 0.2s ease-in-out all; } + #editor #submit span i { vertical-align: sub; font-size: 1.3rem; margin-right: .2em; } + #editor .group.temp { background-color: #f5f5f5; } + #editor .group.temp label { font-weight: lighter; font-size: .8em; @@ -669,6 +872,13 @@ i.spin { color: #7d7d7d; } -#editor .group.temp input { - color: #212121; +#editor .group.temp input { + color: #212121; +} + +@media screen and (max-width: 1024px) { + header p a:first-of-type, + header p i:first-of-type { + display: none; + } } diff --git a/assets/public/js/application.js b/assets/public/js/application.js index f0292722..c125b9d9 100644 --- a/assets/public/js/application.js +++ b/assets/public/js/application.js @@ -1,524 +1,468 @@ -"use strict"; +'use strict'; +const tempID = "_fm_internal_temporary_id" var selectedItems = []; -// Array prototype function to remove an element -Array.prototype.removeElement = function (element) { - var i = this.indexOf(element); - if (i != -1) { - this.splice(i, 1); - } +/* * * * * * * * * * * * * * * * + * * + * GENERAL FUNCTIONS * + * * + * * * * * * * * * * * * * * * */ + +// Removes an element, if exists, from an array +Array.prototype.removeElement = function(element) { + var i = this.indexOf(element); + if (i != -1) { + this.splice(i, 1); + } } -// Array prototype function to replace an element -Array.prototype.replaceElement = function (oldEl, newEl) { - var i = this.indexOf(oldEl); - if (i != -1) { - this[i] = newEl; - } +// Replaces an element inside an array by another +Array.prototype.replaceElement = function(begin, end) { + var i = this.indexOf(begin); + if (i != -1) { + this[i] = end; + } } -// Document prototype function to send a costum event to itself -Document.prototype.sendCostumEvent = function (text) { - document.dispatchEvent(new CustomEvent(text)); +// Sends a costum event to itself +Document.prototype.sendCostumEvent = function(text) { + this.dispatchEvent(new CustomEvent(text)); } -// Document prototype to get a cookie content -Document.prototype.getCookie = function (name) { - var re = new RegExp("(?:(?:^|.*;\\s*)" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$"); - return document.cookie.replace(re, "$1"); +// Gets the content of a cookie +Document.prototype.getCookie = function(name) { + var re = new RegExp("(?:(?:^|.*;\\s*)" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$"); + return document.cookie.replace(re, "$1"); } // Changes a button to the loading animation -Element.prototype.changeToLoading = function () { - let element = this; - let originalText = element.innerHTML; +Element.prototype.changeToLoading = function() { + let element = this; + let originalText = element.innerHTML; - element.style.opacity = 0; + element.style.opacity = 0; - setTimeout(function () { - element.innerHTML = 'autorenew'; - element.style.opacity = 1; - }, 200); + setTimeout(function() { + element.innerHTML = 'autorenew'; + element.style.opacity = 1; + }, 200); - return originalText; + return originalText; } // Changes an element to done animation -Element.prototype.changeToDone = function (error, html) { - this.style.opacity = 0; +Element.prototype.changeToDone = function(error, html) { + this.style.opacity = 0; - let thirdStep = () => { - this.innerHTML = html; - this.style.opacity = 1; + let thirdStep = () => { + this.innerHTML = html; + this.style.opacity = 1; - if (selectedItems.length == 0) { - document.sendCostumEvent('changed-selected'); - } - } + if (selectedItems.length == 0) { + document.sendCostumEvent('changed-selected'); + } + } - let secondStep = () => { - this.style.opacity = 0; - setTimeout(thirdStep, 200); - } + let secondStep = () => { + this.style.opacity = 0; + setTimeout(thirdStep, 200); + } - let firstStep = () => { - if (error) { - this.innerHTML = 'close'; - } else { - this.innerHTML = 'done'; - } + let firstStep = () => { + if (error) { + this.innerHTML = 'close'; + } else { + this.innerHTML = 'done'; + } - this.style.opacity = 1; + this.style.opacity = 1; - setTimeout(secondStep, 1000); - } + setTimeout(secondStep, 1000); + } - setTimeout(firstStep, 200); - return false; -} - -// Event for toggling the mode of view -var viewEvent = function (event) { - let cookie = document.getCookie('view-list'); - let listing = document.getElementById('listing'); - - if (cookie != 'true') { - document.cookie = 'view-list=true'; - } else { - document.cookie = 'view-list=false'; - } - - handleViewType(document.getCookie('view-list')); - return false; -} - -// Handles the view type change -var handleViewType = function (viewList) { - let listing = document.getElementById('listing'); - let button = document.getElementById('view'); - - if (viewList == "true") { - listing.classList.add('list'); - button.innerHTML = 'view_module'; - return false; - } - - button.innerHTML = 'view_list'; - listing.classList.remove('list'); - return false; + setTimeout(firstStep, 200); + return false; } // Handles the open file button event -var openEvent = function (event) { - if (this.classList.contains('disabled')) { - return false; - } - if (selectedItems.length) { - window.open(selectedItems[0] + '?raw=true'); - return false; - } +var openEvent = function(event) { + if (this.classList.contains('disabled')) { + return false; + } - window.open(window.location + '?raw=true'); - return false; -} + if (selectedItems.length) { + window.open(selectedItems[0] + '?raw=true'); + return false; + } -// Handles the back button event -var backEvent = function (event) { - var items = document.getElementsByClassName('item'); - Array.from(items).forEach(link => { - link.classList.remove('selected'); - }); - selectedItems = []; - - var event = new CustomEvent('changed-selected'); - document.dispatchEvent(event); - return false; + window.open(window.location + '?raw=true'); + return false; } // Handles the delete button event -var deleteEvent = function (event) { - if (selectedItems.length) { - Array.from(selectedItems).forEach(link => { - let html = document.getElementById("delete").changeToLoading(); - let request = new XMLHttpRequest(); +var deleteEvent = function(event) { + let single = false; - request.open('DELETE', link); - request.send(); - request.onreadystatechange = function () { - if (request.readyState == 4) { - if (request.status == 200) { - document.getElementById(link).remove(); - console.log(selectedItems); - selectedItems.removeElement(link); - } - - document.getElementById('delete').changeToDone((request.status != 200), html); + if (!selectedItems.length) { + selectedItems = [window.location]; + single = true; } - } - }); - return false; - } + if (selectedItems.length) { + Array.from(selectedItems).forEach(link => { + let html = document.getElementById("delete").changeToLoading(); + let request = new XMLHttpRequest(); - let request = new XMLHttpRequest(); - request.open('DELETE', window.location); - request.send(); - request.onreadystatechange = function () { - if (request.readyState == 4) { - if (request.status == 200) { - window.location.pathname = RemoveLastDirectoryPartOf(window.location.pathname); - } + request.open('DELETE', link); + request.send(); + request.onreadystatechange = function() { + if (request.readyState == 4) { + if (request.status == 200) { + if (single) { + window.location.pathname = RemoveLastDirectoryPartOf(window.location.pathname); + } else { + document.getElementById(link).remove(); + selectedItems.removeElement(link); + } + } + document.getElementById('delete').changeToDone((request.status != 200), html); + } + } + }); - document.getElementById('delete').changeToDone((request.status != 200), html); - } - } + return false; + } - return false; + return false; } // Prevent Default event -var preventDefault = function (event) { - event.preventDefault(); -} - -// Rename file event -var renameEvent = function (event) { - if (this.classList.contains('disabled')) { - return false; - } - if (selectedItems.length) { - Array.from(selectedItems).forEach(link => { - let item = document.getElementById(link); - let span = item.getElementsByTagName('span')[0]; - let name = span.innerHTML; - - item.addEventListener('click', preventDefault); - item.removeEventListener('click', itemClickEvent); - span.setAttribute('contenteditable', 'true'); - span.focus(); - - let keyDownEvent = (event) => { - if (event.keyCode == 13) { - let newName = span.innerHTML; - let html = document.getElementById('rename').changeToLoading(); - let request = new XMLHttpRequest(); - request.open('PATCH', link); - request.setRequestHeader('Rename-To', newName); - request.send(); - request.onreadystatechange = function () { - if (request.readyState == 4) { - if (request.status != 200) { - span.innerHTML = name; - } else { - let newLink = link.replace(name, newName); - item.id = newLink; - selectedItems.replaceElement(link, newLink); - span.innerHTML = newName; - } - - document.getElementById('rename').changeToDone((request.status != 200), html); - } - } - } - - if (event.KeyCode == 27) { - span.innerHTML = name; - } - - if (event.keyCode == 13 || event.keyCode == 27) { - span.setAttribute('contenteditable', 'false'); - span.removeEventListener('keydown', keyDownEvent); - item.removeEventListener('click', preventDefault); - item.addEventListener('click', itemClickEvent); - event.preventDefault(); - } - - return false; - } - - span.addEventListener('keydown', keyDownEvent); - span.addEventListener('blur', (event) => { - span.innerHTML = name; - span.setAttribute('contenteditable', 'false'); - span.removeEventListener('keydown', keyDownEvent); - item.removeEventListener('click', preventDefault); - }); - }); - - return false; - } - - return false; +var preventDefault = function(event) { + event.preventDefault(); } // Download file event -var downloadEvent = function (event) { - if (this.classList.contains('disabled')) { - return false; - } - if (selectedItems.length) { - Array.from(selectedItems).forEach(item => { - window.open(item + "?download=true"); - }); - return false; - } - - window.open(window.location + "?download=true"); - return false; -} - -var handleFiles = function (files) { - let button = document.getElementById("upload"); - let html = button.changeToLoading(); - let data = new FormData(); - - for (let i = 0; i < files.length; i++) { - data.append(files[i].name, files[i]); - } - - let request = new XMLHttpRequest(); - request.open('POST', window.location.pathname); - request.setRequestHeader("Upload", "true"); - request.send(data); - request.onreadystatechange = function () { - if (request.readyState == 4) { - if (request.status == 200) { - location.reload(); - } - - button.changeToDone((request.status != 200), html); - } - } - - return false; -} - -var RemoveLastDirectoryPartOf = function (url) { - var arr = url.split('/'); - arr.pop(); - return (arr.join('/')); -} - -document.addEventListener("changed-selected", function (event) { - var toolbar = document.getElementById("toolbar"); - var selectedNumber = selectedItems.length; - - document.getElementById("selected-number").innerHTML = selectedNumber; - - if (selectedNumber) { - toolbar.classList.add("enabled"); - - if (selectedNumber > 1) { - document.getElementById("open").classList.add("disabled"); - document.getElementById("rename").classList.add("disabled"); - } - - if (selectedNumber == 1) { - document.getElementById("open").classList.remove("disabled"); - document.getElementById("rename").classList.remove("disabled"); - } - - return false; - } - - toolbar.classList.remove("enabled"); - return false; -}); - -var itemClickEvent = function (event) { - var url = this.getElementsByTagName('a')[0].getAttribute('href'); - - if (selectedItems.length != 0) event.preventDefault(); - if (selectedItems.indexOf(url) == -1) { - this.classList.add('selected'); - selectedItems.push(url); - } else { - this.classList.remove('selected'); - selectedItems.removeElement(url); - } - - var event = new CustomEvent('changed-selected'); - document.dispatchEvent(event); - return false; -} - -var localizeDatetime = function (e, index, ar) { - if (e.textContent === undefined) { - return; - } - var d = new Date(e.getAttribute('datetime')); - if (isNaN(d)) { - d = new Date(e.textContent); - if (isNaN(d)) { - return; - } - } - e.textContent = d.toLocaleString(); -} - -document.addEventListener("DOMContentLoaded", function (event) { - - document.getElementById("logout").addEventListener("click", event => { - let request = new XMLHttpRequest(); - request.open('GET', window.location.pathname, true, "username", "password"); - request.send(); - request.onreadystatechange = function () { - if (request.readyState == 4) { - window.location = "/"; - } - } - }); - - var timeList = Array.prototype.slice.call(document.getElementsByTagName("time")); - timeList.forEach(localizeDatetime); - - var items = document.getElementsByClassName('item'); - Array.from(items).forEach(link => { - link.addEventListener('click', itemClickEvent); - }); - - document.getElementById("open").addEventListener("click", openEvent); - document.addEventListener('keydown', (event) => { - if (event.keyCode == 27) { - backEvent(event); - } - }); - if (document.getElementById("back")) { - document.getElementById("back").addEventListener("click", backEvent) - }; - if (document.getElementById("view")) { - handleViewType(document.getCookie("view-list")); - document.getElementById("view").addEventListener("click", viewEvent) - }; - if (document.getElementById("upload")) { - document.getElementById("upload").addEventListener("click", (event) => { - document.getElementById("upload-input").click(); - }); - } - document.getElementById("delete").addEventListener("click", deleteEvent); - document.getElementById("download").addEventListener("click", downloadEvent); - - let rename = document.getElementById("rename"); - if (rename) { - rename.addEventListener("click", renameEvent); - } - - if (document.getElementById("listing")) { - document.addEventListener("dragover", function (event) { - event.preventDefault(); - }, false); - - document.addEventListener("dragover", (event) => { - Array.from(items).forEach(file => { - file.style.opacity = 0.5; - }); - }, false); - - document.addEventListener("dragleave", (event) => { - Array.from(items).forEach(file => { - file.style.opacity = 1; - }); - }, false); - - document.addEventListener("drop", function (event) { - event.preventDefault(); - var dt = event.dataTransfer; - var files = dt.files; - - handleFiles(files); - }, false); - } - - if (document.getElementById('editor')) { - handleEditorPage(); - } - - textareaAutoGrow(); - - return false; -}); - -var textareaAutoGrow = function() { - let autogrow = function() { - this.style.height = '5px'; - 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) -} - -var handleEditorPage = function () { - let container = document.getElementById('editor'); - let button = document.querySelector('#submit span:first-child'); - let kind = container.dataset.kind; - - if (kind != 'frontmatter-only') { - let editor = document.getElementById('editor-source'); - let mode = editor.dataset.mode; - let textarea = document.querySelector('textarea[name="content"]'); - let aceEditor = ace.edit('editor-source'); - aceEditor.getSession().setMode("ace/mode/" + mode); - aceEditor.getSession().setValue(textarea.value); - aceEditor.getSession().on('change', function() { - textarea.value = aceEditor.getSession().getValue(); - }); - aceEditor.setOptions({ - wrap: true, - maxLines: Infinity, - theme: "ace/theme/github", - showPrintMargin: false, - fontSize: "1em", - minLines: 20 +var downloadEvent = function(event) { + if (this.classList.contains('disabled')) { + return false; + } + if (selectedItems.length) { + Array.from(selectedItems).forEach(item => { + window.open(item + "?download=true"); }); + return false; } - let deleteFrontMatterItemButtons = document.getElementsByClassName('delete'); - Array.from(deleteFrontMatterItemButtons).forEach(button => { - button.addEventListener('click', deleteFrontMatterItem); - }); + window.open(window.location + "?download=true"); + return false; +} - let addFrontMatterItemButtons = document.getElementsByClassName('add'); - Array.from(addFrontMatterItemButtons).forEach(button => { - button.addEventListener('click', addFrontMatterItem); - }); +// Remove the last directory of an url +var RemoveLastDirectoryPartOf = function(url) { + var arr = url.split('/'); + arr.pop(); + return (arr.join('/')); +} - document.querySelector('form').addEventListener('submit', (event) => { - event.preventDefault(); +/* * * * * * * * * * * * * * * * + * * + * LISTING SPECIFIC FUNCTIONS * + * * + * * * * * * * * * * * * * * * */ - let data = form2js(document.querySelector('form')); - let html = button.changeToLoading(); - let request = new XMLHttpRequest(); - request.open("PUT", window.location); - request.setRequestHeader('Kind', kind); - request.send(JSON.stringify(data)); - request.onreadystatechange = function() { - if (request.readyState == 4) { - button.changeToDone((request.status != 200), html); +// Rename file event +var renameEvent = function(event) { + if (this.classList.contains('disabled') || !selectedItems.length) { + return false; + } + + // This mustn't happen + if (selectedItems.length > 1) { + alert("Something went wrong. Please refresh the page."); + location.refresh(); + } + + Array.from(selectedItems).forEach(link => { + let item = document.getElementById(link); + let span = item.getElementsByTagName('span')[0]; + let name = span.innerHTML; + + item.addEventListener('click', preventDefault); + item.removeEventListener('click', itemClickEvent); + span.setAttribute('contenteditable', 'true'); + span.focus(); + + let keyDownEvent = (event) => { + if (event.keyCode == 13) { + let newName = span.innerHTML; + let html = document.getElementById('rename').changeToLoading(); + let request = new XMLHttpRequest(); + request.open('PATCH', link); + request.setRequestHeader('Rename-To', newName); + request.send(); + request.onreadystatechange = function() { + if (request.readyState == 4) { + if (request.status != 200) { + span.innerHTML = name; + } else { + let newLink = link.replace(name, newName); + item.id = newLink; + selectedItems.replaceElement(link, newLink); + span.innerHTML = newName; + } + + document.getElementById('rename').changeToDone((request.status != 200), html); + } + } } + + if (event.KeyCode == 27) { + span.innerHTML = name; + } + + if (event.keyCode == 13 || event.keyCode == 27) { + span.setAttribute('contenteditable', 'false'); + span.removeEventListener('keydown', keyDownEvent); + item.removeEventListener('click', preventDefault); + item.addEventListener('click', itemClickEvent); + event.preventDefault(); + } + + return false; } + + span.addEventListener('keydown', keyDownEvent); + span.addEventListener('blur', (event) => { + span.innerHTML = name; + span.setAttribute('contenteditable', 'false'); + span.removeEventListener('keydown', keyDownEvent); + item.removeEventListener('click', preventDefault); + }); }); return false; } +// Upload files +var handleFiles = function(files) { + let button = document.getElementById("upload"); + let html = button.changeToLoading(); + let data = new FormData(); + + for (let i = 0; i < files.length; i++) { + data.append(files[i].name, files[i]); + } + + let request = new XMLHttpRequest(); + request.open('POST', window.location.pathname); + request.setRequestHeader("Upload", "true"); + request.send(data); + request.onreadystatechange = function() { + if (request.readyState == 4) { + if (request.status == 200) { + location.reload(); + } + + button.changeToDone((request.status != 200), html); + } + } + + return false; +} + +// Handles the back button event +var backEvent = function(event) { + var items = document.getElementsByClassName('item'); + Array.from(items).forEach(link => { + link.classList.remove('selected'); + }); + selectedItems = []; + + var event = new CustomEvent('changed-selected'); + document.dispatchEvent(event); + return false; +} + +// Handles the click event +var itemClickEvent = function(event) { + var url = this.getElementsByTagName('a')[0].getAttribute('href'); + + if (selectedItems.length != 0) event.preventDefault(); + if (selectedItems.indexOf(url) == -1) { + this.classList.add('selected'); + selectedItems.push(url); + } else { + this.classList.remove('selected'); + selectedItems.removeElement(url); + } + + var event = new CustomEvent('changed-selected'); + document.dispatchEvent(event); + return false; +} + +// Handles the datetimes present on the document +var localizeDatetime = function(e, index, ar) { + if (e.textContent === undefined) { + return; + } + var d = new Date(e.getAttribute('datetime')); + if (isNaN(d)) { + d = new Date(e.textContent); + if (isNaN(d)) { + return; + } + } + e.textContent = d.toLocaleString(); +} + +// Toggles the view mode +var viewEvent = function(event) { + let cookie = document.getCookie('view-list'); + let listing = document.getElementById('listing'); + + if (cookie != 'true') { + document.cookie = 'view-list=true'; + } else { + document.cookie = 'view-list=false'; + } + + handleViewType(document.getCookie('view-list')); + return false; +} + +// Handles the view mode change +var handleViewType = function(viewList) { + let listing = document.getElementById('listing'); + let button = document.getElementById('view'); + + if (viewList == "true") { + listing.classList.add('list'); + button.innerHTML = 'view_module'; + return false; + } + + button.innerHTML = 'view_list'; + listing.classList.remove('list'); + return false; +} + +// Handles the event when there is change on selected elements +document.addEventListener("changed-selected", function(event) { + var toolbar = document.getElementById("toolbar"); + var selectedNumber = selectedItems.length; + + document.getElementById("selected-number").innerHTML = selectedNumber; + + if (selectedNumber) { + toolbar.classList.add("enabled"); + + if (selectedNumber > 1) { + document.getElementById("open").classList.add("disabled"); + document.getElementById("rename").classList.add("disabled"); + } + + if (selectedNumber == 1) { + document.getElementById("open").classList.remove("disabled"); + document.getElementById("rename").classList.remove("disabled"); + } + + return false; + } + + toolbar.classList.remove("enabled"); + return false; +}); + +document.addEventListener('listing', event => { + // Handle date times + let timeList = document.getElementsByTagName("time"); + Array.from(timeList).forEach(localizeDatetime); + + // Handles the current view mode and adds the event to the button + handleViewType(document.getCookie("view-list")); + document.getElementById("view").addEventListener("click", viewEvent); + + // Add event to items + let items = document.getElementsByClassName('item'); + Array.from(items).forEach(link => { + link.addEventListener('click', itemClickEvent); + }); + + // Add event to back button and executes back event on ESC + document.getElementById("back").addEventListener("click", backEvent) + document.addEventListener('keydown', (event) => { + if (event.keyCode == 27) { + backEvent(event); + } + }); + + // Enables upload button + document.getElementById("upload").addEventListener("click", (event) => { + document.getElementById("upload-input").click(); + }); + + // Enables rename button + document.getElementById("rename").addEventListener("click", renameEvent); + + // Drag and Drop + document.addEventListener("dragover", function(event) { + event.preventDefault(); + }, false); + + document.addEventListener("dragover", (event) => { + Array.from(items).forEach(file => { + file.style.opacity = 0.5; + }); + }, false); + + document.addEventListener("dragleave", (event) => { + Array.from(items).forEach(file => { + file.style.opacity = 1; + }); + }, false); + + document.addEventListener("drop", function(event) { + event.preventDefault(); + var dt = event.dataTransfer; + var files = dt.files; + + handleFiles(files); + }, false); +}); + +/* * * * * * * * * * * * * * * * + * * + * EDITOR SPECIFIC FUNCTIONS * + * * + * * * * * * * * * * * * * * * */ + +// auto grow textareas +var textareaAutoGrow = function() { + let autogrow = function() { + this.style.height = '5px'; + 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) +} + var deleteFrontMatterItem = function(event) { event.preventDefault(); document.getElementById(this.dataset.delete).remove(); } -const tempID = "_fm_internal_temporary_id" - var addFrontMatterItem = function(event) { event.preventDefault(); @@ -643,7 +587,95 @@ var addFrontMatterItem = function(event) { }); } - - return false; } + +document.addEventListener("editor", (event) => { + textareaAutoGrow(); + + let container = document.getElementById('editor'); + let button = document.querySelector('#submit span:first-child'); + let kind = container.dataset.kind; + + if (kind != 'frontmatter-only') { + let editor = document.getElementById('editor-source'); + let mode = editor.dataset.mode; + let textarea = document.querySelector('textarea[name="content"]'); + let aceEditor = ace.edit('editor-source'); + aceEditor.getSession().setMode("ace/mode/" + mode); + aceEditor.getSession().setValue(textarea.value); + aceEditor.getSession().on('change', function() { + textarea.value = aceEditor.getSession().getValue(); + }); + aceEditor.setOptions({ + wrap: true, + maxLines: Infinity, + theme: "ace/theme/github", + showPrintMargin: false, + fontSize: "1em", + minLines: 20 + }); + } + + 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); + }); + + document.querySelector('form').addEventListener('submit', (event) => { + event.preventDefault(); + + let data = form2js(document.querySelector('form')); + let html = button.changeToLoading(); + let request = new XMLHttpRequest(); + request.open("PUT", window.location); + request.setRequestHeader('Kind', kind); + request.send(JSON.stringify(data)); + request.onreadystatechange = function() { + if (request.readyState == 4) { + button.changeToDone((request.status != 200), html); + } + } + }); + + return false; +}); + +/* * * * * * * * * * * * * * * * + * * + * BOOTSTRAP * + * * + * * * * * * * * * * * * * * * */ +document.addEventListener("DOMContentLoaded", function(event) { + // Add event to logout button + document.getElementById("logout").addEventListener("click", event => { + let request = new XMLHttpRequest(); + request.open('GET', window.location.pathname, true, "username", "password"); + request.send(); + request.onreadystatechange = function() { + if (request.readyState == 4) { + window.location = "/"; + } + } + }); + + // Enables open, delete and download buttons + document.getElementById("open").addEventListener("click", openEvent); + document.getElementById("delete").addEventListener("click", deleteEvent); + document.getElementById("download").addEventListener("click", downloadEvent); + + if (document.getElementById('listing')) { + document.sendCostumEvent('listing'); + } + + if (document.getElementById('editor')) { + document.sendCostumEvent('editor'); + } + + return false; +}); diff --git a/assets/public/js/form-to-json.js b/assets/public/js/form-to-json.js deleted file mode 100644 index 4968ad94..00000000 --- a/assets/public/js/form-to-json.js +++ /dev/null @@ -1,349 +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] = currResult[currResult.length - 1]; - } - else - { - currResult[arrName].push(value); - arrays[arrNameFull][arrIdx] = 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] = currResult[arrName][currResult[arrName].length - 1]; - } - } - - currResult = 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 = currResult[namePart]; - } - else - { - currResult[namePart] = value; - } - } - } - } - - return result; - } - - 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; - -})); diff --git a/assets/public/js/form2js.js b/assets/public/js/form2js.js new file mode 100644 index 00000000..ccb684ae --- /dev/null +++ b/assets/public/js/form2js.js @@ -0,0 +1,2 @@ +/* https://github.com/maxatwork/form2js */ +(function(a,b){if(typeof exports!=="undefined"&&typeof module!=="undefined"&&module.exports){module.exports=b()}else{if(typeof define==="function"&&define.amd){define(b)}else{a.form2js=b()}}}(this,function(){function e(m,k,j,q,l,r){r=r?true:false;if(typeof j=="undefined"||j==null){j=true}if(typeof k=="undefined"||k==null){k="."}if(arguments.length<5){l=false}m=typeof m=="string"?document.getElementById(m):m;var p=[],o,n=0;if(m.constructor==Array||(typeof NodeList!="undefined"&&m.constructor==NodeList)){while(o=m[n++]){p=p.concat(d(o,q,l,r))}}else{p=d(m,q,l,r)}return b(p,j,k)}function b(s,A,C){var p={},q={},y,x,w,v,u,r,n,t,o,m,z,D,B;for(y=0;y1){for(w=0;w-1&&x==r.length-1){o=z.substr(0,z.indexOf("["));t+=o;if(!n[o]){n[o]=[]}n[o].push(u)}else{if(z.indexOf("[")>-1){o=z.substr(0,z.indexOf("["));m=z.replace(/(^([a-z_]+)?\[)|(\]$)/gi,"");t+="_"+o+"_"+m;if(!q[t]){q[t]={}}if(o!=""&&!n[o]){n[o]=[]}if(x==r.length-1){if(o==""){n.push(u);q[t][m]=n[n.length-1]}else{n[o].push(u);q[t][m]=n[o][n[o].length-1]}}else{if(!q[t][m]){if((/^[0-9a-z_]+\[?/i).test(r[x+1])){n[o].push({})}else{n[o].push([])}q[t][m]=n[o][n[o].length-1]}}n=q[t][m]}else{t+=z;if(x0?i:g(l,k,m,j)}function g(l,k,n,j){var i=[],m=l.firstChild;while(m){i=i.concat(a(m,k,n,j));m=m.nextSibling}return i}function a(m,k,o,j){if(m.disabled&&!j){return[]}var l,n,i,p=f(m,o);l=k&&k(m);if(l&&l.name){i=[l]}else{if(p!=""&&m.nodeName.match(/INPUT|TEXTAREA/i)){n=c(m,j);if(null===n){i=[]}else{i=[{name:p,value:n}]}}else{if(p!=""&&m.nodeName.match(/SELECT/i)){n=c(m,j);i=[{name:p.replace(/\[\]$/,""),value:n}]}else{i=g(m,k,o,j)}}}return i}function f(i,j){if(i.name&&i.name!=""){return i.name}else{if(j&&i.id&&i.id!=""){return i.id}else{return""}}}function c(j,i){if(j.disabled&&!i){return null}switch(j.nodeName){case"INPUT":case"TEXTAREA":switch(j.type.toLowerCase()){case"radio":if(j.checked&&j.value==="false"){return false}case"checkbox":if(j.checked&&j.value==="true"){return true}if(!j.checked&&j.value==="true"){return false}if(j.checked){return j.value}break;case"button":case"reset":case"submit":case"image":return"";break;default:return j.value;break}break;case"SELECT":return h(j);break;default:break}return null}function h(o){var k=o.multiple,j=[],n,p,m;if(!k){return o.value}for(n=o.getElementsByTagName("option"),p=0,m=n.length;p - - {{.Name}} - - - - - - - - {{ if ne .Config.StyleSheet "" }}{{ end }} - - -
-
- {{ $lnk := .PreviousLink }} - {{ if ne $lnk ""}}{{ end }} - - {{ if ne $lnk ""}}{{ end }} + + {{.Name}} + + + + -

- - {{ if .Config.HugoEnabled }}Hugo{{ else }}File Manager{{ end }} - - {{ if ne .Name "/"}}chevron_right{{ .Name }} -

- {{ end }} + {{ if ne .Config.StyleSheet "" }} + + {{ end }} + + +
+
+ {{ $lnk := .PreviousLink }} + {{ if ne $lnk ""}} + + {{ end }} + + {{ if ne $lnk ""}} + + {{ end }} + +

+ + {{ if .Config.HugoEnabled }}Hugo{{ else }}File Manager{{ end }} + + {{ if ne .Name "/"}} + chevron_right{{ .Name }} +

+ {{ end }} +
+ +
+ {{ if .IsDir}} + +
+ view_headline +
+
+ file_upload +
+ {{ else }} + {{ template "actions" . }} + {{ end }} + + {{ if .Config.HugoEnabled }} + +
+ settings +
+
+ {{ end }} + +
+ exit_to_app
+
+
+ {{ if .IsDir }} +
- {{ if .IsDir}} - -
- view_headline -
-
- file_upload -
- {{ else }} - {{ template "actions" . }} - {{ end }} - - {{ if .Config.HugoEnabled }} - -
- settings -
-
- {{ end }} - -
- exit_to_app -
-
-
- -{{ if .IsDir }} -
-
-
- arrow_back -
-

0 selected.

+
+ arrow_back +
+

+ 0 + selected.

- {{ template "actions" . }} + {{ template "actions" . }}
-
-{{ end }} + + {{ end }} -
-{{ template "content" .Data }} -
+
+ {{ template "content" .Data }} +
-{{ if .IsDir }} -
+ {{ if .IsDir }} +
- add + add
-
-{{ end }} +
+ {{ end }} - - +
+ Served with + Caddy + and + File Manager. + {{ if .Config.HugoEnabled }}With a flavour of + Hugo.{{ end }} +
+ + + + + + diff --git a/assets/templates/editor.tmpl b/assets/templates/editor.tmpl index 339781f5..ecf8774f 100644 --- a/assets/templates/editor.tmpl +++ b/assets/templates/editor.tmpl @@ -1,26 +1,32 @@ {{ define "content" }} -
-
- {{ if or (eq .Class "frontmatter-only") (eq .Class "complete") }} -
- {{ template "blocks" .FrontMatter }} -
Add field
-
- {{ end }} +
+ + {{ if or (eq .Class "frontmatter-only") (eq .Class "complete") }} +
+ {{ template "blocks" .FrontMatter }} +
Add field
+
+ {{ end }} - {{ if or (eq .Class "content-only") (eq .Class "complete") }} + {{ if or (eq .Class "content-only") (eq .Class "complete") }} - {{ if (eq .Class "complete")}}

Body

{{ end }} -
-
- -
- {{ end }} + {{ if (eq .Class "complete")}} +

Body

+ {{ end }} +
+
+ +
+ {{ end }} -
- -
- -
+
+ +
+ +
{{ end }} diff --git a/assets/templates/frontmatter.tmpl b/assets/templates/frontmatter.tmpl index 8d01d6dc..1811468b 100644 --- a/assets/templates/frontmatter.tmpl +++ b/assets/templates/frontmatter.tmpl @@ -1,55 +1,60 @@ {{ define "blocks" }} - {{ if .Fields }}
{{ end }} - {{ range $key, $value := .Fields }} - {{ if eq $value.Parent.Type "array" }} -
- {{ template "value" $value }} -
- close -
-
- {{ else }} -
- - {{ template "value" $value }} -
- close -
-
- {{ end }} - {{ end }} - {{ if .Fields }}
{{ end }} + {{ if .Fields }} +
+ {{ end }} + {{ range $key, $value := .Fields }} + {{ if eq $value.Parent.Type "array" }} +
+ {{ template "value" $value }} +
+ close +
+
+ {{ else }} +
+ + {{ template "value" $value }} +
+ close +
+
+ {{ end }} + {{ end }} + {{ if .Fields }} +
+ {{ end }} - {{ range $key, $value := .Arrays }} - {{ template "fielset" $value }} - {{ end }} + {{ range $key, $value := .Arrays }} + {{ template "fielset" $value }} + {{ end }} - {{ range $key, $value := .Objects }} - {{ template "fielset" $value }} - {{ end }} + {{ range $key, $value := .Objects }} + {{ template "fielset" $value }} + {{ end }} {{ end }} {{ define "value" }} -{{ if eq .HTMLType "textarea" }} - -{{ else if eq .HTMLType "datetime" }} - -{{ else }} - + {{ if eq .HTMLType "textarea" }} + + {{ else if eq .HTMLType "datetime" }} + + {{ else }} + + {{ end }} {{ end }} -{{ end }} - {{ define "fielset" }} -
- {{ if not (eq .Title "") }}

{{ SplitCapitalize .Title }}

{{ end }} +
+ {{ if not (eq .Title "") }} +

{{ SplitCapitalize .Title }}

+ {{ end }}
- add + add
- close + close
- {{ template "blocks" .Content }} -
+ {{ template "blocks" .Content }} +
{{ end }} diff --git a/assets/templates/listing.tmpl b/assets/templates/listing.tmpl index e6f20c8a..44541240 100644 --- a/assets/templates/listing.tmpl +++ b/assets/templates/listing.tmpl @@ -25,11 +25,10 @@

- + + {{- end}} - {{- end}} - - -{{ end }} + + {{ end }} diff --git a/internal/assets/binary.go b/internal/assets/binary.go index 9f7714d0..45e67d7b 100644 --- a/internal/assets/binary.go +++ b/internal/assets/binary.go @@ -1,8 +1,9 @@ // Code generated by go-bindata. // sources: +// assets/.jsbeautifyrc // assets/public/css/styles.css // assets/public/js/application.js -// assets/public/js/form-to-json.js +// assets/public/js/form2js.js // assets/templates/actions.tmpl // assets/templates/base.tmpl // assets/templates/editor.tmpl @@ -35,6 +36,24 @@ type asset struct { info os.FileInfo } +// Jsbeautifyrc reads file data from disk. It returns an error on failure. +func Jsbeautifyrc() (*asset, error) { + path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\.jsbeautifyrc" + name := ".jsbeautifyrc" + bytes, err := bindataRead(path, name) + if err != nil { + return nil, err + } + + fi, err := os.Stat(path) + if err != nil { + err = fmt.Errorf("Error reading asset info %s at %s: %v", name, path, err) + } + + a := &asset{bytes: bytes, info: fi} + return a, err +} + // publicCssStylesCss reads file data from disk. It returns an error on failure. func publicCssStylesCss() (*asset, error) { path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\public\\css\\styles.css" @@ -71,10 +90,10 @@ func publicJsApplicationJs() (*asset, error) { return a, err } -// publicJsFormToJsonJs reads file data from disk. It returns an error on failure. -func publicJsFormToJsonJs() (*asset, error) { - path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\public\\js\\form-to-json.js" - name := "public/js/form-to-json.js" +// publicJsForm2jsJs reads file data from disk. It returns an error on failure. +func publicJsForm2jsJs() (*asset, error) { + path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\public\\js\\form2js.js" + name := "public/js/form2js.js" bytes, err := bindataRead(path, name) if err != nil { return nil, err @@ -249,9 +268,10 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ + ".jsbeautifyrc": Jsbeautifyrc, "public/css/styles.css": publicCssStylesCss, "public/js/application.js": publicJsApplicationJs, - "public/js/form-to-json.js": publicJsFormToJsonJs, + "public/js/form2js.js": publicJsForm2jsJs, "templates/actions.tmpl": templatesActionsTmpl, "templates/base.tmpl": templatesBaseTmpl, "templates/editor.tmpl": templatesEditorTmpl, @@ -300,13 +320,14 @@ type bintree struct { Children map[string]*bintree } var _bintree = &bintree{nil, map[string]*bintree{ + ".jsbeautifyrc": &bintree{Jsbeautifyrc, map[string]*bintree{}}, "public": &bintree{nil, map[string]*bintree{ "css": &bintree{nil, map[string]*bintree{ "styles.css": &bintree{publicCssStylesCss, map[string]*bintree{}}, }}, "js": &bintree{nil, map[string]*bintree{ "application.js": &bintree{publicJsApplicationJs, map[string]*bintree{}}, - "form-to-json.js": &bintree{publicJsFormToJsonJs, map[string]*bintree{}}, + "form2js.js": &bintree{publicJsForm2jsJs, map[string]*bintree{}}, }}, }}, "templates": &bintree{nil, map[string]*bintree{