From 55c2f667095d485b7b0c45149536eefe6e61062b Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Mon, 19 Oct 2020 18:10:54 +0200 Subject: [PATCH] Update text editor --- res/include/script/dependencies/Modal.js | 2 +- res/include/script/textupload.js | 58 --- res/include/style/layout.css | 31 +- res/include/style/viewer.css | 11 +- res/static/script/behave.js | 631 +++++++++++++++++++++++ res/template/file_viewer.html | 2 +- res/template/home.html | 21 +- res/template/paste.html | 74 --- res/template/text_editor.html | 152 ++++++ 9 files changed, 811 insertions(+), 171 deletions(-) delete mode 100644 res/include/script/textupload.js create mode 100644 res/static/script/behave.js delete mode 100644 res/template/paste.html create mode 100644 res/template/text_editor.html diff --git a/res/include/script/dependencies/Modal.js b/res/include/script/dependencies/Modal.js index 0a32483..e94d4f3 100644 --- a/res/include/script/dependencies/Modal.js +++ b/res/include/script/dependencies/Modal.js @@ -31,7 +31,7 @@ function Modal(parent, closeCallback, title, width, height) { this.btnClose = document.createElement("button") this.btnClose.classList = "modal_btn_close button_red" - this.btnClose.innerHTML = 'close' + this.btnClose.innerHTML = 'close' this.btnClose.addEventListener("click", e => { this.close() }) this.body = document.createElement("div") diff --git a/res/include/script/textupload.js b/res/include/script/textupload.js deleted file mode 100644 index d0043a1..0000000 --- a/res/include/script/textupload.js +++ /dev/null @@ -1,58 +0,0 @@ -function uploadText() { - var text = document.getElementById("textarea").value; - var blob = new Blob([text], {type: "text/plain"}); - var filename = prompt("What do you want to call this piece of textual art?\n\n" - + "Please add your own file extension, if you want.", - "Pixeldrain_Text_File.txt"); - - if(filename === null){ - return; - } - - new UploadManager(apiEndpoint+"/file", null).addFile( - blob, - filename, - null, - function (id){ - addUploadHistory(id); - setTimeout(window.location.href = "/u/" + id, 100); - }, - function (response, error) { alert("File upload failed! The server told us this: " + response); } - ) -} - -// Upload the file when ctrl + s is pressed -document.addEventListener("keydown", function(event) { - if ((event.ctrlKey || event.metaKey) && event.keyCode === 83) { - event.preventDefault(); - uploadText(); - return false; - } -}); - -/** - * Prevent the Tab key from moving the cursor outside of the text area - */ -document.getElementById("textarea").addEventListener( - 'keydown', - function(e) { - if(e.keyCode === 9) { // tab was pressed - // get caret position/selection - var start = this.selectionStart; - var end = this.selectionEnd; - - var target = e.target; - var value = target.value; - - // set textarea value to: text before caret + tab + text after caret - target.value = value.substring(0, start) + "\t" + value.substring(end); - - // put caret at right position again (add one for the tab) - this.selectionStart = this.selectionEnd = start + 1; - - // prevent the focus lose - e.preventDefault(); - } - }, - false -); diff --git a/res/include/style/layout.css b/res/include/style/layout.css index 0cfb64e..56b58b4 100644 --- a/res/include/style/layout.css +++ b/res/include/style/layout.css @@ -34,7 +34,7 @@ font-family: 'Material Icons'; font-weight: normal; font-style: normal; - font-size: 24px; /* Preferred icon size */ + font-size: 1.6em; display: inline-block; line-height: 1; text-transform: none; @@ -45,17 +45,11 @@ text-rendering: optimizeLegibility; vertical-align: middle; } -.icon.small { - font-size: 16px; -} -a > svg { - vertical-align: middle; -} +.icon.small { font-size: 1.2em; } +a > svg { vertical-align: middle; } /* Page rendering configuration */ -html, body { - overflow-x: hidden; -} +html, body { overflow-x: hidden; } body{ background-color: #111111; /* Fallback */ background-color: var(--layer_2_color); @@ -301,10 +295,9 @@ a:hover { table:not(.form) { border-collapse: collapse; width: 100%; - margin: 14px; } tr:not(.form) {border-bottom: 1px var(--layer_2_color_border) solid;} -tr > td, tr > th {padding: 0.3em;} +tr > td, tr > th {padding: 0.4em;} @media(max-width: 30em) { /* Forms will be stacked on small screens */ tr.form > td { @@ -321,15 +314,6 @@ pre { overflow-x: auto; } -.big_button{ - width: 40%; - min-width: 250px; - max-width: 400px; - margin: 10px !important; - border-radius: 5px; - font-size: 1.8em; -} - .file_button{ position: relative; box-sizing: border-box; @@ -413,9 +397,8 @@ select { border: none; margin: 3px; background: linear-gradient(var(--input_color), var(--input_color_dark)); - padding: .4em .5em .4em .5em; + padding: .3em .4em .3em .4em; box-shadow: 2px 2px 6px -3px var(--shadow_color); - font-size: 0.9em; line-height: 1em; overflow: hidden; text-decoration: none; @@ -451,7 +434,7 @@ input[type="color"]:active, select:active{ background: linear-gradient(var(--input_color_dark), var(--input_color)); box-shadow: inset 4px 4px 8px var(--shadow_color); - padding: .6em .3em .2em .7em; /* Exactly .2em offset compared to the inactive padding to give a depth effect */ + padding: .5em .2em .1em .6em; /* Exactly .2em offset compared to the inactive padding to give a depth effect */ } .button_full_width {width: calc(100% - 6px);} .button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark)) !important; color: var(--highlight_text_color) !important;} diff --git a/res/include/style/viewer.css b/res/include/style/viewer.css index 49b4b9d..01a5af9 100644 --- a/res/include/style/viewer.css +++ b/res/include/style/viewer.css @@ -44,15 +44,14 @@ white-space: nowrap; text-overflow: ellipsis; } +.file_viewer > .file_viewer_headerbar > .button_home > svg { + height: 1.6em; + width: 1.6em; + margin: -0.1em 0.2em -0.1em -0.1em; +} .file_viewer > .file_viewer_headerbar > .button_home::after { content: "pixeldrain"; } -.file_viewer > .file_viewer_headerbar > .button_home > svg { - height: 1.7em; - width: 1.7em; - margin: -0.25em; - margin-right: 0.2em; -} @media (max-width: 600px) { .file_viewer > .file_viewer_headerbar > .button_home::after { content: "pd"; diff --git a/res/static/script/behave.js b/res/static/script/behave.js new file mode 100644 index 0000000..f87e833 --- /dev/null +++ b/res/static/script/behave.js @@ -0,0 +1,631 @@ +/* + * Behave.js + * + * Copyright 2013, Jacob Kelley - http://jakiestfu.com/ + * Released under the MIT Licence + * http://opensource.org/licenses/MIT + * + * Github: http://github.com/jakiestfu/Behave.js/ + * Version: 1.5 + */ + +(function(undefined){ + 'use strict'; + + var BehaveHooks = BehaveHooks || (function(){ + var hooks = {}; + + return { + add: function(hookName, fn){ + if(typeof hookName == "object"){ + var i; + for(i=0; i>> 0; + if (typeof func != "function"){ + throw new TypeError(); + } + var res = [], + thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (i in t) { + var val = t[i]; + if (func.call(thisp, val, i, t)) { + res.push(val); + } + } + } + return res; + }; + } + + var defaults = { + textarea: null, + replaceTab: true, + softTabs: true, + tabSize: 4, + autoOpen: true, + overwrite: true, + autoStrip: true, + autoIndent: true, + fence: false + }, + tab, + newLine, + charSettings = { + + keyMap: [ + { open: "\"", close: "\"", canBreak: false }, + { open: "'", close: "'", canBreak: false }, + { open: "(", close: ")", canBreak: false }, + { open: "[", close: "]", canBreak: true }, + { open: "{", close: "}", canBreak: true } + ] + + }, + utils = { + + _callHook: function(hookName, passData){ + var hooks = BehaveHooks.get(hookName); + passData = typeof passData=="boolean" && passData === false ? false : true; + + if(hooks){ + if(passData){ + var theEditor = defaults.textarea, + textVal = theEditor.value, + caretPos = utils.cursor.get(), + i; + + for(i=0; i -1) { + start = end = len; + } else { + start = -textInputRange.moveStart("character", -len); + start += normalizedValue.slice(0, start).split(newLine).length - 1; + + if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) { + end = len; + } else { + end = -textInputRange.moveEnd("character", -len); + end += normalizedValue.slice(0, end).split(newLine).length - 1; + } + } + } + } + + return start==end ? false : { + start: start, + end: end + }; + } + }, + editor: { + getLines: function(textVal){ + return (textVal).split("\n").length; + }, + get: function(){ + return defaults.textarea.value.replace(/\r/g,''); + }, + set: function(data){ + defaults.textarea.value = data; + } + }, + fenceRange: function(){ + if(typeof defaults.fence == "string"){ + + var data = utils.editor.get(), + pos = utils.cursor.get(), + hacked = 0, + matchedFence = data.indexOf(defaults.fence), + matchCase = 0; + + while(matchedFence>=0){ + matchCase++; + if( pos < (matchedFence+hacked) ){ + break; + } + + hacked += matchedFence+defaults.fence.length; + data = data.substring(matchedFence+defaults.fence.length); + matchedFence = data.indexOf(defaults.fence); + + } + + if( (hacked) < pos && ( (matchedFence+hacked) > pos ) && matchCase%2===0){ + return true; + } + return false; + } else { + return true; + } + }, + isEven: function(_this,i){ + return i%2; + }, + levelsDeep: function(){ + var pos = utils.cursor.get(), + val = utils.editor.get(); + + var left = val.substring(0, pos), + levels = 0, + i, j; + + for(i=0; i=0 ? finalLevels : 0; + }, + deepExtend: function(destination, source) { + for (var property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + utils.deepExtend(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; + }, + addEvent: function addEvent(element, eventName, func) { + if (element.addEventListener){ + element.addEventListener(eventName,func,false); + } else if (element.attachEvent) { + element.attachEvent("on"+eventName, func); + } + }, + removeEvent: function addEvent(element, eventName, func){ + if (element.addEventListener){ + element.removeEventListener(eventName,func,false); + } else if (element.attachEvent) { + element.detachEvent("on"+eventName, func); + } + }, + + preventDefaultEvent: function(e){ + if(e.preventDefault){ + e.preventDefault(); + } else { + e.returnValue = false; + } + } + }, + intercept = { + tabKey: function (e) { + + if(!utils.fenceRange()){ return; } + + if (e.keyCode == 9) { + utils.preventDefaultEvent(e); + + var toReturn = true; + utils._callHook('tab:before'); + + var selection = utils.cursor.selection(), + pos = utils.cursor.get(), + val = utils.editor.get(); + + if(selection){ + + var tempStart = selection.start; + while(tempStart--){ + if(val.charAt(tempStart)=="\n"){ + selection.start = tempStart + 1; + break; + } + } + + var toIndent = val.substring(selection.start, selection.end), + lines = toIndent.split("\n"), + i; + + if(e.shiftKey){ + for(i = 0; i
- + {{template `pixeldrain.svg` .}} diff --git a/res/template/home.html b/res/template/home.html index b244a1a..99f19e7 100644 --- a/res/template/home.html +++ b/res/template/home.html @@ -10,7 +10,14 @@ max-width: 800px; margin: 0 auto 50px auto; } - + .big_button{ + width: 40%; + min-width: 250px; + max-width: 400px; + margin: 10px !important; + border-radius: 5px; + font-size: 1.8em; + } .instruction_highlight { border-top: 1px solid var(--layer_2_color_border); border-bottom: 1px solid var(--layer_2_color_border); @@ -108,10 +115,10 @@

@@ -159,10 +166,10 @@
- - - - + + + +

diff --git a/res/template/paste.html b/res/template/paste.html deleted file mode 100644 index eaeced8..0000000 --- a/res/template/paste.html +++ /dev/null @@ -1,74 +0,0 @@ -{{define "paste"}} - - - - {{template "meta_tags" "Text Upload"}} - {{template "user_style" .}} - - - - - -
- - - {{template `pixeldrain.svg` .}} - Home - -

- Tip: Save your file with extension '.md' to use markdown formatting
-
-
- -
- - - - {{template "analytics"}} - - -{{end}} diff --git a/res/template/text_editor.html b/res/template/text_editor.html new file mode 100644 index 0000000..afc0d60 --- /dev/null +++ b/res/template/text_editor.html @@ -0,0 +1,152 @@ +{{define "text_editor"}} + + + + {{template "meta_tags" "Text Upload"}} + {{template "user_style" .}} + + + + + +
+
+ + arrow_back + +
+ + +
+
+ +
+
+ + + + + + + {{template "analytics"}} + + +{{end}}