Merge pull request #347 from typerqeo/caps-lock-backspace

Adds caps lock backspace mode and fixes some caps lock bugs.
This commit is contained in:
Jack 2020-09-09 14:49:20 +01:00 committed by GitHub
commit 50741f20e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 19 deletions

View file

@ -1705,6 +1705,20 @@
</div>
</div>
</div>
<div class="section capsLockBackspace">
<h1>caps lock backspace</h1>
<div class="text">
Makes caps lock act like backspace.
</div>
<div class="buttons">
<div class="button off" tabindex="0" onclick="this.blur();">
off
</div>
<div class="button on" tabindex="0" onclick="this.blur();">
on
</div>
</div>
</div>
<div class="section layout">
<h1>layout override</h1>
<div class="buttons"></div>

View file

@ -281,6 +281,13 @@ let commands = {
showCommandLine();
},
},
{
id: "toggleCapsLockBackspace",
display: "Toggle caps lock backspace",
exec: () => {
toggleCapsLockBackspace();
},
},
{
id: "changeLayout",
display: "Change layout...",

View file

@ -190,6 +190,10 @@ function capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function isASCIILetter(c) {
return c.length === 1 && /[a-z]/i.test(c);
}
function kogasa(cov) {
return (
100 * (1 - Math.tanh(cov + Math.pow(cov, 3) / 3 + Math.pow(cov, 5) / 5))

View file

@ -563,7 +563,34 @@ function setToggleSettings(state) {
}
function emulateLayout(event) {
if (config.layout == "default" || event.key === " ") return event;
function emulatedLayoutShouldShiftKey(event, newKeyPreview) {
if (config.capsLockBackspace) return event.shiftKey;
const isCapsLockHeld = event.originalEvent.getModifierState("CapsLock");
if (isCapsLockHeld) return isASCIILetter(newKeyPreview) !== event.shiftKey;
return event.shiftKey;
}
function replaceEventKey(event, keyCode) {
const newKey = String.fromCharCode(keyCode);
event.keyCode = keyCode;
event.charCode = keyCode;
event.which = keyCode;
event.key = newKey;
event.code = "Key" + newKey.toUpperCase();
}
if (event.key === " " || event.key === "Enter")
return event;
if (config.layout === "default") {
//override the caps lock modifier for the default layout if needed
if (config.capsLockBackspace && isASCIILetter(event.key)) {
replaceEventKey(
event,
event.shiftKey
? event.key.toUpperCase().charCodeAt(0)
: event.key.toLowerCase().charCodeAt(0)
);
}
return event;
}
const qwertyMasterLayout = {
Backquote: "`~",
Digit1: "1!",
@ -614,29 +641,22 @@ function emulateLayout(event) {
Slash: "/?",
Space: " ",
};
let layoutMap = layouts[config.layout];
let qwertyMap = layouts["qwerty"];
const layoutMap = layouts[config.layout];
const qwertyMap = layouts["qwerty"];
let qwertyKey = qwertyMasterLayout[event.code];
const qwertyKey = qwertyMasterLayout[event.code];
let mapIndex;
let newKey;
let shift = event.shiftKey ? 1 : 0;
for (let i = 0; i < qwertyMap.length; i++) {
const key = qwertyMap[i];
let keyIndex = key.indexOf(qwertyKey);
const keyIndex = key.indexOf(qwertyKey);
if (keyIndex != -1) {
mapIndex = i;
}
}
if (!shift && /[A-Z]/gm.test(event.key)) {
shift = 1;
}
newKey = layoutMap[mapIndex][shift];
event.keyCode = newKey.charCodeAt(0);
event.charCode = newKey.charCodeAt(0);
event.which = newKey.charCodeAt(0);
event.key = newKey;
event.code = "Key" + newKey.toUpperCase();
const newKeyPreview = layoutMap[mapIndex][0];
const shift = emulatedLayoutShouldShiftKey(event, newKeyPreview) ? 1 : 0;
const newKey = layoutMap[mapIndex][shift];
replaceEventKey(event, newKey.charCodeAt(0));
return event;
}
@ -3808,7 +3828,10 @@ $(document).keydown((event) => {
keypressStats.duration.current = performance.now();
if ($("#wordsInput").is(":focus")) {
try {
if (event.originalEvent.getModifierState("CapsLock")) {
if (
!config.capsLockBackspace &&
event.originalEvent.getModifierState("CapsLock")
) {
showCapsWarning();
} else {
hideCapsWarning();
@ -3873,8 +3896,10 @@ $(document).keydown((event) => {
//only for the typing test
if ($("#wordsInput").is(":focus")) {
//backspace
if (event["keyCode"] == 8) {
const isBackspace =
event["keyCode"] === 8 ||
(config.capsLockBackspace && event.key === "CapsLock");
if (isBackspace) {
event.preventDefault();
if (!testActive) return;
if (

View file

@ -182,6 +182,10 @@ settingsGroups.smoothLineScroll = new SettingsGroup(
"smoothLineScroll",
setSmoothLineScroll
);
settingsGroups.capsLockBackspace = new SettingsGroup(
"capsLockBackspace",
setCapsLockBackspace
);
settingsGroups.layout = new SettingsGroup("layout", changeLayout);
settingsGroups.language = new SettingsGroup("language", changeLanguage);
settingsGroups.fontSize = new SettingsGroup("fontSize", changeFontSize);

View file

@ -33,6 +33,7 @@ let defaultConfig = {
// readAheadMode: false,
caretStyle: "default",
flipTestColors: false,
capsLockBackspace: false,
layout: "default",
confidenceMode: "off",
timerStyle: "text",
@ -144,6 +145,7 @@ function applyConfig(configObj) {
changeWordCount(configObj.words, true);
changeMode(configObj.mode, true);
changeLanguage(configObj.language, true);
setCapsLockBackspace(configObj.capsLockBackspace, true);
changeLayout(configObj.layout, true);
changeFontSize(configObj.fontSize, true);
setFreedomMode(configObj.freedomMode, true);
@ -870,6 +872,18 @@ function changeLanguage(language, nosave) {
if (!nosave) saveConfigToCookie();
}
function setCapsLockBackspace(capsLockBackspace, nosave) {
if (capsLockBackspace === null || capsLockBackspace === undefined) {
capsLockBackspace = false;
}
config.capsLockBackspace = capsLockBackspace;
if (!nosave) saveConfigToCookie();
}
function toggleCapsLockBackspace() {
setCapsLockBackspace(!config.capsLockBackspace, false);
}
function changeLayout(layout, nosave) {
if (layout == null || layout == undefined) {
layout = "qwerty";