From 09c3bd9e42bb3dcdbbc562a5e5dc504a8def88e6 Mon Sep 17 00:00:00 2001 From: gldrk Date: Wed, 29 Nov 2023 08:18:10 +0000 Subject: [PATCH] Improve behavior of formatting buttons * Synthesize an input event to trigger a preview update. * Slightly tweak the algorithm. --- files/assets/js/formatting.js | 112 +++++++++++++++++----------------- 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/files/assets/js/formatting.js b/files/assets/js/formatting.js index ca6c4b0af..9605ba61c 100644 --- a/files/assets/js/formatting.js +++ b/files/assets/js/formatting.js @@ -1,57 +1,55 @@ - -function makeBold(form) { - var text = document.getElementById(form); - var startIndex = text.selectionStart, - endIndex = text.selectionEnd; - var selectedText = text.value.substring(startIndex, endIndex); - - var format = '**' - - if (selectedText.includes('**')) { - text.value = selectedText.replace(/\*/g, ''); - } - else if (selectedText.length == 0) { - text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex); - } - else { - text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex); - } -} - -function makeItalics(form) { - var text = document.getElementById(form); - var startIndex = text.selectionStart, - endIndex = text.selectionEnd; - var selectedText = text.value.substring(startIndex, endIndex); - - var format = '*' - - if (selectedText.includes('*')) { - text.value = selectedText.replace(/\*/g, ''); - } - else if (selectedText.length == 0) { - text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex); - } - else { - text.value = text.value.substring(0, startIndex) + format + selectedText + format + text.value.substring(endIndex); - } -} - -function makeQuote(form) { - var text = document.getElementById(form); - var startIndex = text.selectionStart, - endIndex = text.selectionEnd; - var selectedText = text.value.substring(startIndex, endIndex); - - var format = '>' - - if (selectedText.includes('>')) { - text.value = text.value.substring(0, startIndex) + selectedText.replace(/\>/g, '') + text.value.substring(endIndex); - } - else if (selectedText.length == 0) { - text.value = text.value.substring(0, startIndex) + selectedText + text.value.substring(endIndex); - } - else { - text.value = text.value.substring(0, startIndex) + format + selectedText + text.value.substring(endIndex); - } -} +(function() { + var event = InputEvent + ? function(type, attrs) { + return new InputEvent(type, attrs); + } + : function(type) { + e = document.createEvent('event'); + e.initEvent(type, false, false); + return e; + }; + var escape = function(str) { + return str.replace(/./g, '[$&]').replace(/[\\^]|]]/g, '\\$&'); + }; + var wrap = function(cb) { + return function(id) { + var form = document.getElementById(id); + if (cb(form)) { + var e = event('input', { inputType: 'insertReplacementText' }); + form.dispatchEvent(e); + } + } + }; + var select = function(cb) { + return function(form) { + var begin = form.selectionStart, end = form.selectionEnd; + if (begin == end) + return false; + form.value = form.value.substring(0, begin) + + cb(form.value.substring(begin, end)) + + form.value.substring(end); + return true; + }; + }; + var enclose = function(mark) { + var re = new RegExp(escape(mark) + '(\\S.*?\\S|\\S)' + escape(mark), 'g'); + return select(function(selection) { + var replacement = selection.replace(re, '$1'); + if (replacement.length == selection.length) + replacement = mark + replacement + mark; + return replacement; + }); + }; + var quote = select(function(selection) { + var lines = selection.split('\n'); + if (lines.some(function(line) { return /^\s*[^\s>]/.test(line) })) + return '>' + lines.join('\n>'); + else + return lines.map(function(line) { + return line.substring(line.indexOf('>') + 1); + }).join('\n'); + }); + makeItalics = wrap(enclose('*')); + makeBold = wrap(enclose('**')); + makeQuote = wrap(quote); +})()