Case converter

swap the case of the selected text

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name     Case converter
// @version  0.2
// @author   Noneangel
// @description swap the case of the selected text
// @include http://*
// @include https://*
// @namespace https://gist.github.com/Noneangel/a865645a27e04fbff2843df560ca1dbb
// ==/UserScript==
/* do modify */
// test if one of the key code is pressed
var keyCodes = [114]; //F3
// with the following modifier key pressed
//(note : set to false if modifier should not be pressed)
var modifierKey = {
    shiftKey: true
}; // {altKey: false, shiftKey: true, ctrlKey = false}
//which transformation to apply to the text
var transform = invertCase; // invertCase, upperCase, lowerCase


/* modify at your own risk */

/* case transformation */
function invertCase(text) {
    return text.split('').map(function(c) {
        return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()
    }).join('');
}

function upperCase(text) {
    return text.toUpperCase();
}

function lowerCase(text) {
    return text.toLowerCase();
}

/* get active selection */
//source https://stackoverflow.com/questions/5379120/get-the-highlighted-selected-text
function getSelectionText(activeEl) {
    var text = "";
    var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
    if (
        (activeElTagName == "textarea") || (activeElTagName == "input" &&
            /^(?:text|search|password|tel|url)$/i.test(activeEl.type)) &&
        (typeof activeEl.selectionStart == "number")
    ) {
        text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
    } else if (window.getSelection) {
        text = window.getSelection().toString();
    }
    return text;
}

/* repalce selected text with a replacementText */
//source https://stackoverflow.com/questions/3997659/replace-selected-text-in-contenteditable-div
function replaceSelectedText(replacementText) {
    var sel, range;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            range.insertNode(document.createTextNode(replacementText));
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.text = replacementText;
    }
}
// same but for textarea only
function setInputSelection(elem, text) {
    var activeElTagName = elem ? elem.tagName.toLowerCase() : null;
    if (
        (activeElTagName == "textarea") || (activeElTagName == "input" &&
            /^(?:text|search|password|tel|url)$/i.test(elem.type)) &&
        (typeof elem.selectionStart == "number")
    ) {
        var indiceStart = elem.selectionStart;
        var indiceEnd = elem.selectionEnd;
        var s = elem.selectionStart;
        var e = elem.selectionEnd;
        elem.value = elem.value.substring(0, s) + text + elem.value.substring(e);
        elem.setSelectionRange(indiceStart, indiceEnd);
    }
}

/* test if obj has the every member of option with the same value */
function validate(option, obj) {
    for (var member in option) {
        if (option[member] !== obj[member]) {
            return false;
        }
    }
    return true;
}

function into(e, array) {
    return array.reduce(function(acc, val) {
        return acc || (e == val)
    }, false);
}


function shortcut(e) {
    if (validate(modifierKey, e) && into(e.keyCode, keyCodes)) {
        var id = document.activeElement;
        var selection = getSelectionText(id);
        var transformed = transform(selection);
        replaceSelectedText(transformed);
        setInputSelection(id, transformed);
        e.stopPropagation();
        e.preventDefault();
    }
}

document.addEventListener('keydown', shortcut, true);