mediawikitampermonkeyuserscripts

Userscript to add characters before and after selection with a shortcut


I tend to use Chrome and MediaWiki's WikiEditor to add internal links, but it requires clicking on the respective button. Is there a way to either insert the characters with a shortcut or activate that button with a shortcut? For example the outcome should look like these examples when the shortcut is pressed on selected text:

[[selectedtext]]
[[selected text]]

Alternatively, the span element of the insert link is

<span class="oo-ui-iconElement-icon oo-ui-icon-wikiText"></span>

Solution

  • This will toggle between selected-text and [[selected-text]] with Ctrl + ] :

    const bounds = ',.;:?!(){}';
    
    const escape = string => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const wordStartRegex = new RegExp(`[^\\s${escape(bounds)}]+$`);
    const wordEndRegex = new RegExp(`^[^\\s${escape(bounds)}]+`)
    
    function toggleSelectionToLink(textarea) {
        let start = textarea.selectionStart;
        let end = textarea.selectionEnd;
        let text = textarea.value;
    
        if (start === end) {
            let match = text.slice(0, start).match(wordStartRegex);
            if (!match) return;
    
            textarea.selectionStart = start = match.index;
            textarea.selectionEnd = end = text.slice(start).match(wordEndRegex)[0].length + start;
        }
    
        let selectedText = text.slice(start, end);
        let newText = selectedText.replace(/\[\[(.*?)\]\]/gs, '$1');
        newText = selectedText !== newText ? newText : selectedText.replace(selectedText.trim(), `[[${selectedText.trim()}]]`);
    
        document.execCommand('insertText', false, newText);
    
        // preserve selection (range):
        textarea.selectionStart = start;
        textarea.selectionEnd = start + newText.length;
    }
    
    window.addEventListener('keypress', e => {
         if (e.ctrlKey && e.code === 'BracketRight' && e.target.tagName === 'TEXTAREA') {
             toggleSelectionToLink(e.target);
         }
    })