aboutsummaryrefslogtreecommitdiffstats
path: root/theme/admin/static/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'theme/admin/static/main.js')
-rw-r--r--theme/admin/static/main.js191
1 files changed, 191 insertions, 0 deletions
diff --git a/theme/admin/static/main.js b/theme/admin/static/main.js
new file mode 100644
index 0000000..94fc591
--- /dev/null
+++ b/theme/admin/static/main.js
@@ -0,0 +1,191 @@
+//==============================================================================
+// Elements which contains the location of the previous and next site
+//==============================================================================
+const prev = document.getElementById("prev-site");
+const next = document.getElementById("next-site");
+
+//==============================================================================
+// Handle arrow keys and change the location to the desired direction
+//==============================================================================
+document.addEventListener("keyup", function(e) {
+ if(!e.ctrlKey && !e.shiftKey && !e.altKey) {
+ (e.keyCode === 37 && prev) && (window.location.href = prev.getAttribute("href"));
+ (e.keyCode === 39 && next) && (window.location.href = next.getAttribute("href"));
+ }
+}, false);
+
+//==============================================================================
+// Markdown tags to replace
+//==============================================================================
+const markdownTags = {
+ "bold": ["**", "**"],
+ "italic": ["*", "*"],
+ "heading": ["## ", "\n"],
+ "link": ["[", "](href)"],
+ "image": ["![", "](href)"],
+ "code": ["\n~~~\n", "\n~~~\n"],
+ "quote": ["\n> ", ""],
+ "list_ul": ["* ", ""],
+ "list_ol": ["1. ", ""]
+};
+
+//==============================================================================
+// Timeout function for delayed execution of code
+//==============================================================================
+function delayed(callback) {
+ window.setTimeout(callback, 20);
+}
+
+//==============================================================================
+// Set caret position in editor
+//==============================================================================
+function setCaretPosition(position) {
+ document.getElementById("content-editor").setSelectionRange(position, position);
+ document.getElementById("content-editor").focus();
+}
+
+//==============================================================================
+// Insert emoticon after cursor in editor
+//==============================================================================
+function insertEmoticon(target, emoticon) {
+ const selectionStart = target.selectionStart;
+ const selectionEnd = target.selectionEnd;
+
+ const content = target.value;
+ target.value = content.slice(0, selectionStart) + emoticon + content.slice(selectionEnd);
+
+ delayed(function() {
+ setCaretPosition(selectionStart + emoticon.length);
+ });
+}
+
+//==============================================================================
+// Insert markdown around text in editor
+//==============================================================================
+function insertMarkdown(target, markdown) {
+ const selectionStart = target.selectionStart;
+ const selectionEnd = target.selectionEnd;
+
+ const selectedText = target.value.substring(selectionStart, selectionEnd);
+
+ const content = target.value;
+ target.value = content.slice(0, selectionStart) + markdownTags[markdown][0] + selectedText + markdownTags[markdown][1] + content.slice(selectionEnd);
+
+ delayed(function() {
+ setCaretPosition(selectionStart + markdownTags[markdown][0].length + selectedText.length + markdownTags[markdown][1].length);
+ });
+}
+
+//==============================================================================
+// Keep server-side session active if the user is writing a long text
+//==============================================================================
+setInterval(function() {
+ const Request = new XMLHttpRequest();
+ Request.open("HEAD", "", true);
+ Request.send();
+}, 300000);
+
+//==============================================================================
+// Confirmation message for delete button
+//==============================================================================
+if(document.getElementById("delete-button")) {
+ document.getElementById("delete-button").onclick = function(e) {
+ return confirm(e.target.getAttribute("data-text"));
+ };
+}
+
+//==============================================================================
+// Insert or remove tab indent in editor if [<shift>+]<tab> is pressed
+//==============================================================================
+(function() {
+ if(document.getElementById("content-editor")) {
+ const element = document.getElementById("content-editor");
+ element.addEventListener("keydown", function(e) {
+ if(e.keyCode === 9 && !e.ctrlKey) {
+ const selectionStart = element.selectionStart;
+ const selectionEnd = element.selectionEnd;
+
+ const content = element.value;
+
+ if(e.shiftKey) {
+ if(content.substring(selectionStart, selectionStart -1) === "\t") {
+ element.value = content.substring(0, selectionStart - 1) + content.substring(selectionEnd);
+ setCaretPosition(selectionStart - 1);
+ }
+ }
+
+ else {
+ element.value = content.substring(0, selectionStart) + "\t" + content.substring(selectionEnd);
+ setCaretPosition(selectionStart + 1);
+ }
+
+ e.preventDefault();
+ }
+ }, false);
+ }
+})();
+
+//==============================================================================
+// Emoticon button list
+//==============================================================================
+(function() {
+ if(document.getElementById("emoticon-list")) {
+ const list = document.getElementById("emoticon-list");
+ const node = document.getElementById("content-editor");
+ const items = list.getElementsByTagName("li");
+
+ for(let i = 0; i < items.length; ++i) {
+ items[i].onmousedown = function(e) {
+ insertEmoticon(node, e.target.getAttribute("data-emoticon"));
+ };
+ }
+ }
+})();
+
+//==============================================================================
+// Markdown button list
+//==============================================================================
+(function() {
+ if(document.getElementById("markdown-list")) {
+ const list = document.getElementById("markdown-list");
+ const node = document.getElementById("content-editor");
+ const items = list.getElementsByTagName("li");
+
+ for(let i = 0; i < items.length; ++i) {
+ items[i].onmousedown = function(e) {
+ insertMarkdown(node, e.target.getAttribute("data-markdown"));
+ };
+ }
+ }
+})();
+
+//==============================================================================
+// Detect unsaved changes in content editor
+//==============================================================================
+(function() {
+ if(document.getElementById("content-editor")) {
+ const editor = document.getElementById("content-editor");
+ const initialValue = editor.value;
+
+ function showConfirmationPrompt(e) {
+ if(editor.value !== initialValue) {
+ e.returnValue = '';
+ e.preventDefault();
+ }
+ }
+
+ window.addEventListener('beforeunload', showConfirmationPrompt);
+
+ const buttons = [];
+ buttons.push(document.getElementById('insert-button'));
+ buttons.push(document.getElementById('update-button'));
+
+ for(let i = 0; i < buttons.length; ++i) {
+ if(buttons[i] !== null) {
+ buttons[i].addEventListener('click', function() {
+ window.removeEventListener('beforeunload', showConfirmationPrompt);
+ });
+ }
+ }
+ }
+})();