Code optimization, added onKeyReleased. Fixes #144, #145

This commit is contained in:
Francisco Hodge
2019-07-14 11:27:18 -04:00
parent b0a7748351
commit 8ba6f879d0
27 changed files with 1024 additions and 584 deletions
-87
View File
@@ -1,87 +0,0 @@
import Keyboard from "../lib";
import "./css/App.css";
/**
* simple-keyboard demo
*/
class App {
/**
* Instantiates the demo class
*/
constructor() {
document.addEventListener("DOMContentLoaded", this.onDOMLoaded);
/**
* Default input name
* @type {string}
*/
this.layoutName = "default";
}
/**
* Executed when the DOM is ready
*/
onDOMLoaded = () => {
/**
* Creates a new simple-keyboard instance
*/
this.keyboard = new Keyboard({
debug: true,
layoutName: this.layoutName,
onChange: input => this.onChange(input),
onKeyPress: button => this.onKeyPress(button),
newLineOnEnter: true,
physicalKeyboardHighlight: true
});
/**
* Adding preview (demo only)
*/
document.querySelector(".simple-keyboard").insertAdjacentHTML(
"beforebegin",
`
<div class="simple-keyboard-preview">
<textarea class="input"></textarea>
</div>
`
);
document.querySelector(".input").addEventListener("input", event => {
this.keyboard.setInput(event.target.value);
});
};
/**
* Handles shift functionality
*/
handleShiftButton = () => {
let layoutName = this.layoutName;
let shiftToggle = (this.layoutName =
layoutName === "default" ? "shift" : "default");
this.keyboard.setOptions({
layoutName: shiftToggle
});
};
/**
* Called when simple-keyboard input has changed
*/
onChange = input => {
document.querySelector(".input").value = input;
};
/**
* Called when a simple-keyboard key is pressed
*/
onKeyPress = button => {
console.log("Button pressed", button);
/**
* Shift functionality
*/
if (button === "{lock}" || button === "{shift}") this.handleShiftButton();
};
}
export default App;
+55
View File
@@ -0,0 +1,55 @@
import Keyboard from "../lib";
import "./css/BasicDemo.css";
const setDOM = () => {
document.querySelector("#root").innerHTML = `
<input class="input" placeholder="Tap on the virtual keyboard to start" />
<div class="simple-keyboard"></div>
`;
};
class Demo {
constructor() {
setDOM();
/**
* Demo Start
*/
this.keyboard = new Keyboard({
onChange: input => this.onChange(input),
onKeyPress: button => this.onKeyPress(button)
});
/**
* Update simple-keyboard when input is changed directly
*/
document.querySelector(".input").addEventListener("input", event => {
this.keyboard.setInput(event.target.value);
});
}
onChange(input) {
document.querySelector(".input").value = input;
console.log("Input changed", input);
}
onKeyPress(button) {
console.log("Button pressed", button);
/**
* If you want to handle the shift and caps lock buttons
*/
if (button === "{shift}" || button === "{lock}") this.handleShift();
}
handleShift() {
let currentLayout = this.keyboard.options.layoutName;
let shiftToggle = currentLayout === "default" ? "shift" : "default";
this.keyboard.setOptions({
layoutName: shiftToggle
});
}
}
export default Demo;
+157
View File
@@ -0,0 +1,157 @@
import Keyboard from "../lib";
import "./css/FullKeyboardDemo.css";
const setDOM = () => {
document.querySelector("#root").innerHTML = `
<input class="input" placeholder="Tap on the virtual keyboard to start" />
<div class="keyboardContainer">
<div class="simple-keyboard-main"></div>
<div class="controlArrows">
<div class="simple-keyboard-control"></div>
<div class="simple-keyboard-arrows"></div>
</div>
<div class="numPad">
<div class="simple-keyboard-numpad"></div>
<div class="simple-keyboard-numpadEnd"></div>
</div>
</div>
`;
};
class Demo {
constructor() {
setDOM();
/**
* Demo Start
*/
let commonKeyboardOptions = {
onChange: input => this.onChange(input),
onKeyPress: button => this.onKeyPress(button),
theme: "simple-keyboard hg-theme-default hg-layout-default",
physicalKeyboardHighlight: true,
syncInstanceInputs: true,
mergeDisplay: true,
debug: true
};
this.keyboard = new Keyboard(".simple-keyboard-main", {
...commonKeyboardOptions,
/**
* Layout by:
* Sterling Butters (https://github.com/SterlingButters)
*/
layout: {
default: [
"{escape} {f1} {f2} {f3} {f4} {f5} {f6} {f7} {f8} {f9} {f10} {f11} {f12}",
"` 1 2 3 4 5 6 7 8 9 0 - = {backspace}",
"{tab} q w e r t y u i o p [ ] \\",
"{capslock} a s d f g h j k l ; ' {enter}",
"{shiftleft} z x c v b n m , . / {shiftright}",
"{controlleft} {altleft} {metaleft} {space} {metaright} {altright}"
],
shift: [
"{escape} {f1} {f2} {f3} {f4} {f5} {f6} {f7} {f8} {f9} {f10} {f11} {f12}",
"~ ! @ # $ % ^ & * ( ) _ + {backspace}",
"{tab} Q W E R T Y U I O P { } |",
'{capslock} A S D F G H J K L : " {enter}',
"{shiftleft} Z X C V B N M < > ? {shiftright}",
"{controlleft} {altleft} {metaleft} {space} {metaright} {altright}"
]
},
display: {
"{escape}": "esc ⎋",
"{tab}": "tab ⇥",
"{backspace}": "backspace ⌫",
"{enter}": "enter ↵",
"{capslock}": "caps lock ⇪",
"{shiftleft}": "shift ⇧",
"{shiftright}": "shift ⇧",
"{controlleft}": "ctrl ⌃",
"{controlright}": "ctrl ⌃",
"{altleft}": "alt ⌥",
"{altright}": "alt ⌥",
"{metaleft}": "cmd ⌘",
"{metaright}": "cmd ⌘"
}
});
this.keyboardControlPad = new Keyboard(".simple-keyboard-control", {
...commonKeyboardOptions,
layout: {
default: [
"{prtscr} {scrolllock} {pause}",
"{insert} {home} {pageup}",
"{delete} {end} {pagedown}"
]
}
});
this.keyboardArrows = new Keyboard(".simple-keyboard-arrows", {
...commonKeyboardOptions,
layout: {
default: ["{arrowup}", "{arrowleft} {arrowdown} {arrowright}"]
}
});
this.keyboardNumPad = new Keyboard(".simple-keyboard-numpad", {
...commonKeyboardOptions,
layout: {
default: [
"{numlock} {numpaddivide} {numpadmultiply}",
"{numpad7} {numpad8} {numpad9}",
"{numpad4} {numpad5} {numpad6}",
"{numpad1} {numpad2} {numpad3}",
"{numpad0} {numpaddecimal}"
]
}
});
this.keyboardNumPadEnd = new Keyboard(".simple-keyboard-numpadEnd", {
...commonKeyboardOptions,
layout: {
default: ["{numpadsubtract}", "{numpadadd}", "{numpadenter}"]
}
});
document.querySelector(".input").addEventListener("input", event => {
let input = document.querySelector(".input").value;
this.keyboard.setInput(input);
});
}
onChange(input) {
document.querySelector(".input").value = input;
this.keyboard.setInput(input);
console.log("Input changed", input);
}
onKeyPress(button) {
console.log("Button pressed", button);
/**
* If you want to handle the shift and caps lock buttons
*/
if (
button === "{shift}" ||
button === "{shiftleft}" ||
button === "{shiftright}" ||
button === "{capslock}"
)
this.handleShift();
}
handleShift() {
let currentLayout = this.keyboard.options.layoutName;
let shiftToggle = currentLayout === "default" ? "shift" : "default";
this.keyboard.setOptions({
layoutName: shiftToggle
});
}
}
export default Demo;
-33
View File
@@ -1,33 +0,0 @@
#root {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue",
Helvetica, Arial, "Lucida Grande", sans-serif;
max-width: 850px;
margin: 0 auto;
padding-top: 20px;
}
#root .simple-keyboard-preview {
background: rgba(0, 0, 0, 0.8);
border: 20px solid rgba(0, 0, 0, 0.1);
height: 200px;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
padding: 10px;
box-sizing: border-box;
}
#root .input {
color: rgba(255, 255, 255, 0.9);
background: transparent;
border: none;
outline: none;
font-family: monospace;
width: 100%;
height: 100%;
font-size: 18px;
}
.simple-keyboard.hg-layout-custom {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
+12
View File
@@ -0,0 +1,12 @@
input {
width: 100%;
height: 100px;
padding: 20px;
font-size: 20px;
border: none;
box-sizing: border-box;
}
.simple-keyboard {
max-width: 850px;
}
+132
View File
@@ -0,0 +1,132 @@
input {
width: 100%;
height: 100px;
padding: 20px;
font-size: 20px;
border: none;
box-sizing: border-box;
}
.keyboardContainer {
display: flex;
background-color: rgba(0, 0, 0, 0.1);
justify-content: center;
width: 1024px;
border-radius: 5px;
}
.simple-keyboard.hg-theme-default {
display: inline-block;
}
.simple-keyboard-main.simple-keyboard {
width: 640px;
min-width: 640px;
background: none;
}
.simple-keyboard-main.simple-keyboard .hg-row:first-child {
margin-bottom: 10px;
}
.simple-keyboard-arrows.simple-keyboard {
align-self: flex-end;
background: none;
}
.simple-keyboard .hg-button.selectedButton {
background: rgba(5, 25, 70, 0.53);
color: white;
}
.simple-keyboard .hg-button.emptySpace {
pointer-events: none;
background: none;
border: none;
box-shadow: none;
}
.simple-keyboard-arrows .hg-row {
justify-content: center;
}
.simple-keyboard-arrows .hg-button {
width: 50px;
flex-grow: 0;
justify-content: center;
display: flex;
align-items: center;
}
.controlArrows {
display: flex;
align-items: center;
justify-content: space-between;
flex-flow: column;
}
.simple-keyboard-control.simple-keyboard {
background: none;
}
.simple-keyboard-control.simple-keyboard .hg-row:first-child {
margin-bottom: 10px;
}
.simple-keyboard-control .hg-button {
width: 50px;
flex-grow: 0;
justify-content: center;
display: flex;
align-items: center;
}
.numPad {
display: flex;
align-items: flex-end;
}
.simple-keyboard-numpad.simple-keyboard {
background: none;
}
.simple-keyboard-numpad.simple-keyboard {
width: 160px;
}
.simple-keyboard-numpad.simple-keyboard .hg-button {
width: 50px;
justify-content: center;
display: flex;
align-items: center;
}
.simple-keyboard-numpadEnd.simple-keyboard {
width: 50px;
background: none;
margin: 0;
padding: 5px 5px 5px 0;
}
.simple-keyboard-numpadEnd.simple-keyboard .hg-button {
align-items: center;
justify-content: center;
display: flex;
}
.simple-keyboard-numpadEnd .hg-button.hg-standardBtn.hg-button-plus {
height: 85px;
}
.simple-keyboard-numpadEnd.simple-keyboard .hg-button.hg-button-enter {
height: 85px;
}
.simple-keyboard.hg-theme-default .hg-button.hg-selectedButton {
background: rgba(5, 25, 70, 0.53);
color: white;
}
.hg-button.hg-functionBtn.hg-button-space {
width: 350px;
}
+3
View File
@@ -0,0 +1,3 @@
#root {
padding: 0px 40px;
}
+14 -3
View File
@@ -1,6 +1,17 @@
import App from "./App";
import "./css/index.css";
/**
* Initializing demo
* Demos
*/
new App();
import BasicDemo from "./BasicDemo";
//import FullKeyboardDemo from "./FullKeyboardDemo";
/**
* Selected demo
*/
const SELECTED_DEMO = BasicDemo;
/**
* Bootstrap
*/
new SELECTED_DEMO();
@@ -1,20 +1,18 @@
import TestUtility from '../../utils/TestUtility';
import Index from '../index';
import App from '../App';
import BasicDemo from '../BasicDemo';
let testUtil = new TestUtility();
it('Demo will load', () => {
testUtil.setDOM();
let demo = new App();
let demo = new BasicDemo();
});
it('Demo onDOMLoaded will work', () => {
testUtil.setDOM();
let demo = new App();
demo.onDOMLoaded();
let demo = new BasicDemo();
expect(demo.keyboard).toBeTruthy();
});
@@ -22,8 +20,7 @@ it('Demo onDOMLoaded will work', () => {
it('Demo onChange will work', () => {
testUtil.setDOM();
let demo = new App();
demo.onDOMLoaded();
let demo = new BasicDemo();
demo.onChange("test");
@@ -33,8 +30,7 @@ it('Demo onChange will work', () => {
it('Demo onChange will work', () => {
testUtil.setDOM();
let demo = new App();
demo.onDOMLoaded();
let demo = new BasicDemo();
demo.keyboard.getButtonElement("q").onclick();
@@ -44,8 +40,7 @@ it('Demo onChange will work', () => {
it('Demo input change will work', () => {
testUtil.setDOM();
let demo = new App();
demo.onDOMLoaded();
let demo = new BasicDemo();
document.body.querySelector('.input').value = "test";
document.body.querySelector('.input').dispatchEvent(new Event('input'));
@@ -56,8 +51,7 @@ it('Demo input change will work', () => {
it('Demo handleShiftButton will work', () => {
testUtil.setDOM();
let demo = new App();
demo.onDOMLoaded();
let demo = new BasicDemo();
demo.keyboard.getButtonElement("{shift}")[0].onclick();
expect(demo.keyboard.options.layoutName).toBe("shift");
+62
View File
@@ -0,0 +1,62 @@
import TestUtility from '../../utils/TestUtility';
import FullKeyboardDemo from '../FullKeyboardDemo';
let testUtil = new TestUtility();
it('Demo will load', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
});
it('Demo onDOMLoaded will work', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
expect(demo.keyboard).toBeTruthy();
});
it('Demo onChange will work', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
demo.onChange("test");
expect(document.body.querySelector('.input').value).toBe("test");
});
it('Demo onChange will work', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
demo.keyboard.getButtonElement("q").onclick();
expect(document.body.querySelector('.input').value).toBe("q");
});
it('Demo input change will work', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
document.body.querySelector('.input').value = "test";
document.body.querySelector('.input').dispatchEvent(new Event('input'));
expect(demo.keyboard.getInput()).toBe("test");
expect(demo.keyboardNumPad.getInput()).toBe("test");
});
it('Demo handleShiftButton will work', () => {
testUtil.setDOM();
let demo = new FullKeyboardDemo();
demo.keyboard.getButtonElement("{shiftleft}").onclick();
expect(demo.keyboard.options.layoutName).toBe("shift");
demo.keyboard.getButtonElement("{shiftright}").onclick();
expect(demo.keyboard.options.layoutName).toBe("default");
});
+5
View File
@@ -162,6 +162,11 @@ declare module 'simple-keyboard' {
* Executes the callback function on input change. Returns the input object with all defined inputs.
*/
onChangeAll?: (inputs: any) => any;
/**
* Executes the callback function on key release.
*/
onKeyReleased?: () => void;
}
class Keyboard {
+100 -36
View File
@@ -27,7 +27,16 @@ class SimpleKeyboard {
/**
* Initializing Utilities
*/
this.utilities = new Utilities(this);
this.utilities = new Utilities({
getOptions: this.getOptions,
getCaretPosition: this.getCaretPosition,
dispatch: this.dispatch
});
/**
* Caret position
*/
this.caretPosition = null;
/**
* Processing options
@@ -66,6 +75,7 @@ class SimpleKeyboard {
* @property {boolean} useMouseEvents Opt out of PointerEvents handling, falling back to the prior mouse event logic.
* @property {function} destroy Clears keyboard listeners and DOM elements.
* @property {boolean} disableButtonHold Disable button hold action.
* @property {function} onKeyReleased Executes the callback function on key release.
*/
this.options = options;
this.options.layoutName = this.options.layoutName || "default";
@@ -112,16 +122,7 @@ class SimpleKeyboard {
this.buttonElements = {};
/**
* Rendering keyboard
*/
if (this.keyboardDOM) this.render();
else {
console.warn(`"${keyboardDOMQuery}" was not found in the DOM.`);
throw new Error("KEYBOARD_DOM_ERROR");
}
/**
* Saving instance
* Simple-keyboard Instances
* This enables multiple simple-keyboard support with easier management
*/
if (!window["SimpleKeyboardInstances"])
@@ -131,10 +132,31 @@ class SimpleKeyboard {
this.utilities.camelCase(this.keyboardDOMClass)
] = this;
/**
* Instance vars
*/
this.allKeyboardInstances = window["SimpleKeyboardInstances"];
this.currentInstanceName = this.utilities.camelCase(this.keyboardDOMClass);
this.keyboardInstanceNames = Object.keys(window["SimpleKeyboardInstances"]);
this.isFirstKeyboardInstance =
this.keyboardInstanceNames[0] === this.currentInstanceName;
/**
* Physical Keyboard support
*/
this.physicalKeyboardInterface = new PhysicalKeyboard(this);
this.physicalKeyboard = new PhysicalKeyboard({
dispatch: this.dispatch,
getOptions: this.getOptions
});
/**
* Rendering keyboard
*/
if (this.keyboardDOM) this.render();
else {
console.warn(`"${keyboardDOMQuery}" was not found in the DOM.`);
throw new Error("KEYBOARD_DOM_ERROR");
}
/**
* Modules
@@ -143,6 +165,12 @@ class SimpleKeyboard {
this.loadModules();
}
/**
* Getters
*/
getOptions = () => this.options;
getCaretPosition = () => this.caretPosition;
/**
* Handles clicks made to keyboard buttons
* @param {string} button The button's layout name.
@@ -167,7 +195,6 @@ class SimpleKeyboard {
let updatedInput = this.utilities.getUpdatedInput(
button,
this.input[this.options.inputName],
this.options,
this.caretPosition
);
@@ -185,7 +212,7 @@ class SimpleKeyboard {
*/
if (
this.options.maxLength &&
this.utilities.handleMaxLength(this.input, this.options, updatedInput)
this.utilities.handleMaxLength(this.input, updatedInput)
) {
return false;
}
@@ -193,7 +220,6 @@ class SimpleKeyboard {
this.input[this.options.inputName] = this.utilities.getUpdatedInput(
button,
this.input[this.options.inputName],
this.options,
this.caretPosition,
true
);
@@ -272,6 +298,12 @@ class SimpleKeyboard {
handleButtonMouseUp() {
this.isMouseHold = false;
if (this.holdInteractionTimeout) clearTimeout(this.holdInteractionTimeout);
/**
* Calling onKeyReleased
*/
if (typeof this.options.onKeyReleased === "function")
this.options.onKeyReleased();
}
/**
@@ -584,33 +616,63 @@ class SimpleKeyboard {
}
/**
* Retrieves the current cursor position within a input or textarea (if any)
* Handles simple-keyboard event listeners
*/
handleCaret() {
setEventListeners() {
/**
* Only first instance should insall the caret handling events
* Only first instance should set the event listeners
*/
this.caretPosition = null;
let simpleKeyboardInstances = window["SimpleKeyboardInstances"];
if (
(simpleKeyboardInstances &&
Object.keys(simpleKeyboardInstances)[0] ===
this.utilities.camelCase(this.keyboardDOMClass)) ||
!simpleKeyboardInstances
) {
if (this.isFirstKeyboardInstance || !this.allKeyboardInstances) {
if (this.options.debug) {
console.log(`Caret handling started (${this.keyboardDOMClass})`);
}
document.addEventListener("keyup", this.caretEventHandler);
document.addEventListener("mouseup", this.caretEventHandler);
document.addEventListener("touchend", this.caretEventHandler);
/**
* Event Listeners
*/
document.addEventListener("keyup", this.handleKeyUp);
document.addEventListener("keydown", this.handleKeyDown);
document.addEventListener("mouseup", this.handleMouseUp);
document.addEventListener("touchend", this.handleTouchEnd);
}
}
/**
* Called by {@link handleCaret} when an event that warrants a cursor position update is triggered
* Event Handler: KeyUp
*/
handleKeyUp(event) {
this.caretEventHandler(event);
if (this.options.physicalKeyboardHighlight) {
this.physicalKeyboard.handleHighlightKeyUp(event);
}
}
/**
* Event Handler: KeyDown
*/
handleKeyDown(event) {
if (this.options.physicalKeyboardHighlight) {
this.physicalKeyboard.handleHighlightKeyDown(event);
}
}
/**
* Event Handler: MouseUp
*/
handleMouseUp(event) {
this.caretEventHandler(event);
}
/**
* Event Handler: TouchEnd
*/
handleTouchEnd(event) {
this.caretEventHandler(event);
}
/**
* Called by {@link caretEventHandler} when an event that warrants a cursor position update is triggered
*/
caretEventHandler(event) {
let targetTagName;
@@ -657,9 +719,10 @@ class SimpleKeyboard {
/**
* Remove listeners
*/
document.removeEventListener("keyup", this.caretEventHandler);
document.removeEventListener("mouseup", this.caretEventHandler);
document.removeEventListener("touchend", this.caretEventHandler);
document.removeEventListener("keyup", this.handleKeyUp);
document.removeEventListener("keydown", this.handleKeyDown);
document.removeEventListener("mouseup", this.handleMouseUp);
document.removeEventListener("touchend", this.handleTouchEnd);
/**
* Clear DOM
@@ -763,9 +826,9 @@ class SimpleKeyboard {
}
/**
* Caret handling
* setEventListeners
*/
this.handleCaret();
this.setEventListeners();
if (typeof this.options.onInit === "function") this.options.onInit();
}
@@ -788,6 +851,7 @@ class SimpleKeyboard {
* Notify about PointerEvents usage
*/
if (
this.isFirstKeyboardInstance &&
this.utilities.pointerEventsSupported() &&
!this.options.useTouchEvents &&
!this.options.useMouseEvents
+53
View File
@@ -1242,4 +1242,57 @@ it('Keyboard disableButtonHold will work', () => {
});
expect(keyboard.options.disableButtonHold).toBe(true);
});
it('Keyboard caretEventHandler will be triggered on mouseup and ontouchend', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
disableCaretPositioning: true
});
keyboard.caretPosition = 6;
document.dispatchEvent(new MouseEvent('mouseup', {
target: {
tagName: "input"
}
}));
expect(keyboard.caretPosition).toBe(null);
keyboard.setOptions({
disableCaretPositioning: false
})
keyboard.caretPosition = 10;
document.dispatchEvent(new TouchEvent('touchend', {
target: {
tagName: "input"
}
}));
expect(keyboard.caretPosition).toBe(10);
});
it('Keyboard onKeyReleased will work', () => {
testUtil.setDOM();
let pressed = false;
let firedTimes = 0;
let keyboard = new Keyboard({
onKeyReleased: () => {
pressed = true;
firedTimes++;
},
debug: true
});
keyboard.getButtonElement("q").onpointerdown();
keyboard.getButtonElement("q").onpointerup();
expect(pressed).toBeTruthy();
expect(firedTimes).toBe(1);
});
+27 -44
View File
@@ -1,3 +1,5 @@
import Utilities from "../services/Utilities";
/**
* Physical Keyboard Service
*/
@@ -5,66 +7,47 @@ class PhysicalKeyboard {
/**
* Creates an instance of the PhysicalKeyboard service
*/
constructor(simpleKeyboardInstance) {
constructor({ dispatch, getOptions }) {
/**
* @type {object} A simple-keyboard instance
*/
this.simpleKeyboardInstance = simpleKeyboardInstance;
this.dispatch = dispatch;
this.getOptions = getOptions;
/**
* Bindings
*/
this.initKeyboardListener = this.initKeyboardListener.bind(this);
this.getSimpleKeyboardLayoutKey = this.getSimpleKeyboardLayoutKey.bind(
this
);
/**
* Initialize key listeners
*/
this.initKeyboardListener();
Utilities.bindMethods(PhysicalKeyboard, this);
}
/**
* Initializes key event listeners
*/
initKeyboardListener() {
// Adding button style on keydown
document.addEventListener("keydown", event => {
if (this.simpleKeyboardInstance.options.physicalKeyboardHighlight) {
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
handleHighlightKeyDown(event) {
let options = this.getOptions();
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
this.simpleKeyboardInstance.dispatch(instance => {
let buttonDOM =
instance.getButtonElement(buttonPressed) ||
instance.getButtonElement(`{${buttonPressed}}`);
this.dispatch(instance => {
let buttonDOM =
instance.getButtonElement(buttonPressed) ||
instance.getButtonElement(`{${buttonPressed}}`);
if (buttonDOM) {
buttonDOM.style.backgroundColor =
this.simpleKeyboardInstance.options
.physicalKeyboardHighlightBgColor || "#9ab4d0";
buttonDOM.style.color =
this.simpleKeyboardInstance.options
.physicalKeyboardHighlightTextColor || "white";
}
});
if (buttonDOM) {
buttonDOM.style.backgroundColor =
options.physicalKeyboardHighlightBgColor || "#9ab4d0";
buttonDOM.style.color =
options.physicalKeyboardHighlightTextColor || "white";
}
});
}
// Removing button style on keyup
document.addEventListener("keyup", event => {
if (this.simpleKeyboardInstance.options.physicalKeyboardHighlight) {
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
handleHighlightKeyUp(event) {
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
this.simpleKeyboardInstance.dispatch(instance => {
let buttonDOM =
instance.getButtonElement(buttonPressed) ||
instance.getButtonElement(`{${buttonPressed}}`);
this.dispatch(instance => {
let buttonDOM =
instance.getButtonElement(buttonPressed) ||
instance.getButtonElement(`{${buttonPressed}}`);
if (buttonDOM && buttonDOM.removeAttribute) {
buttonDOM.removeAttribute("style");
}
});
if (buttonDOM && buttonDOM.removeAttribute) {
buttonDOM.removeAttribute("style");
}
});
}
+26 -32
View File
@@ -5,11 +5,10 @@ class Utilities {
/**
* Creates an instance of the Utility service
*/
constructor(simpleKeyboardInstance) {
/**
* @type {object} A simple-keyboard instance
*/
this.simpleKeyboardInstance = simpleKeyboardInstance;
constructor({ getOptions, getCaretPosition, dispatch }) {
this.getOptions = getOptions;
this.getCaretPosition = getCaretPosition;
this.dispatch = dispatch;
/**
* Bindings
@@ -125,11 +124,11 @@ class Utilities {
*
* @param {string} button The button's layout name
* @param {string} input The input string
* @param {object} options The simple-keyboard options object
* @param {number} caretPos The cursor's current position
* @param {boolean} moveCaret Whether to update simple-keyboard's cursor
*/
getUpdatedInput(button, input, options, caretPos, moveCaret) {
getUpdatedInput(button, input, caretPos, moveCaret) {
let options = this.getOptions();
let output = input;
if (
@@ -187,43 +186,34 @@ class Utilities {
* @param {boolean} minus Whether the cursor should be moved to the left or not.
*/
updateCaretPos(length, minus) {
let newCaretPos = this.updateCaretPosAction(
this.simpleKeyboardInstance,
length,
minus
);
let newCaretPos = this.updateCaretPosAction(length, minus);
if (this.simpleKeyboardInstance.options.syncInstanceInputs) {
this.simpleKeyboardInstance.dispatch(instance => {
instance.caretPosition = newCaretPos;
});
}
this.dispatch(instance => {
instance.caretPosition = newCaretPos;
});
}
/**
* Action method of updateCaretPos
*
* @param {object} instance The instance whose position should be updated
* @param {number} length Represents by how many characters the input should be moved
* @param {boolean} minus Whether the cursor should be moved to the left or not.
*/
updateCaretPosAction(instance, length, minus) {
updateCaretPosAction(length, minus) {
let options = this.getOptions();
let caretPosition = this.getCaretPosition();
if (minus) {
if (instance.caretPosition > 0)
instance.caretPosition = instance.caretPosition - length;
if (caretPosition > 0) caretPosition = caretPosition - length;
} else {
instance.caretPosition = instance.caretPosition + length;
caretPosition = caretPosition + length;
}
if (this.simpleKeyboardInstance.options.debug) {
console.log(
"Caret at:",
instance.caretPosition,
`(${instance.keyboardDOMClass})`
);
if (options.debug) {
console.log("Caret at:", caretPosition, `(${this.keyboardDOMClass})`);
}
return instance.caretPosition;
return caretPosition;
}
/**
@@ -263,7 +253,9 @@ class Utilities {
* @param {boolean} moveCaret Whether to update simple-keyboard's cursor
*/
removeAt(source, position, moveCaret) {
if (this.simpleKeyboardInstance.caretPosition === 0) {
let caretPosition = this.getCaretPosition();
if (caretPosition === 0) {
return source;
}
@@ -306,10 +298,10 @@ class Utilities {
* Determines whether the maxLength has been reached. This function is called when the maxLength option it set.
*
* @param {object} inputObj
* @param {object} options
* @param {string} updatedInput
*/
handleMaxLength(inputObj, options, updatedInput) {
handleMaxLength(inputObj, updatedInput) {
let options = this.getOptions();
let maxLength = options.maxLength;
let currentInput = inputObj[options.inputName];
let condition = currentInput.length === maxLength;
@@ -399,6 +391,8 @@ class Utilities {
* @param {string} string The string to transform.
*/
camelCase(string) {
if (!string) return false;
return string
.toLowerCase()
.trim()
+35 -28
View File
@@ -31,7 +31,7 @@ it('Keyboard {bksp} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{bksp}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{bksp}", "test");
expect(output).toBe("tes");
});
@@ -41,7 +41,7 @@ it('Keyboard {space} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{space}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{space}", "test");
expect(output).toBe("test ");
});
@@ -51,7 +51,7 @@ it('Keyboard {tab} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{tab}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{tab}", "test");
expect(output).toBe("test\t");
});
@@ -63,7 +63,7 @@ it('Keyboard {tab} button will work with tabCharOnTab:false', () => {
tabCharOnTab: false
});
let output = keyboard.utilities.getUpdatedInput("{tab}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{tab}", "test");
expect(output).toBe("test");
});
@@ -73,7 +73,7 @@ it('Keyboard {enter} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{enter}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{enter}", "test");
expect(output).toBe("test");
});
@@ -85,7 +85,7 @@ it('Keyboard {enter} button will work with newLineOnEnter:true', () => {
newLineOnEnter: true
});
let output = keyboard.utilities.getUpdatedInput("{enter}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{enter}", "test");
expect(output).toBe("test\n");
});
@@ -96,7 +96,7 @@ it('Keyboard {numpadX} buttons will work', () => {
let keyboard = new Keyboard();
for(let i = 0;i<=9;i++){
let output = keyboard.utilities.getUpdatedInput(`{numpad${i}}`, "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput(`{numpad${i}}`, "test");
expect(output).toBe(`test${i}`);
}
});
@@ -106,7 +106,7 @@ it('Keyboard {numpaddivide} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpaddivide}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpaddivide}", "test");
expect(output).toBe("test/");
});
@@ -116,7 +116,7 @@ it('Keyboard {numpadmultiply} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpadmultiply}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpadmultiply}", "test");
expect(output).toBe("test*");
});
@@ -126,7 +126,7 @@ it('Keyboard {numpadsubtract} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpadsubtract}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpadsubtract}", "test");
expect(output).toBe("test-");
});
@@ -136,7 +136,7 @@ it('Keyboard {numpadadd} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpadadd}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpadadd}", "test");
expect(output).toBe("test+");
});
@@ -146,7 +146,7 @@ it('Keyboard {numpadadd} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpadadd}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpadadd}", "test");
expect(output).toBe("test+");
});
@@ -156,7 +156,7 @@ it('Keyboard {numpaddecimal} button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{numpaddecimal}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{numpaddecimal}", "test");
expect(output).toBe("test.");
});
@@ -172,7 +172,7 @@ it('Keyboard custom function buttons will work', () => {
}
});
let output = keyboard.utilities.getUpdatedInput("{randombuttontest}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{randombuttontest}", "test");
expect(output).toBe("test");
expect(keyboard.getButtonElement("{randombuttontest}").onclick).toBeTruthy();
@@ -183,7 +183,7 @@ it('Keyboard "{" button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("{", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("{", "test");
expect(output).toBe("test{");
});
@@ -193,7 +193,7 @@ it('Keyboard "}" button will work', () => {
let keyboard = new Keyboard();
let output = keyboard.utilities.getUpdatedInput("}", "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput("}", "test");
expect(output).toBe("test}");
});
@@ -205,7 +205,7 @@ it('Keyboard standard button will affect input', () => {
for (let i = 65; i <= 90; i++) {
let char = String.fromCharCode(i);
let output = keyboard.utilities.getUpdatedInput(char, "test", keyboard.options);
let output = keyboard.utilities.getUpdatedInput(char, "test");
expect(output).toBe(`test${char}`);
}
});
@@ -213,8 +213,9 @@ it('Keyboard standard button will affect input', () => {
it('Keyboard updateCaretPos will work with minus', () => {
testUtil.setDOM();
let keyboard = new Keyboard();
keyboard.options.syncInstanceInputs = true;
let keyboard = new Keyboard({
syncInstanceInputs: true
});
keyboard.caretPosition = 5;
keyboard.utilities.updateCaretPos(2, true);
@@ -282,7 +283,7 @@ it('Keyboard addStringAt will respect maxLength', () => {
keyboard.setInput("test");
keyboard.caretPosition = 4;
keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq")
keyboard.utilities.handleMaxLength(keyboard.input, "testq")
keyboard.utilities.addStringAt("test", "q", 4);
expect(keyboard.caretPosition).toBe(4);
@@ -297,7 +298,7 @@ it('Keyboard handleMaxLength will exit out on same updatedInput', () => {
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "test")
let output = keyboard.utilities.handleMaxLength(keyboard.input, "test")
expect(output).toBeFalsy();
});
@@ -313,7 +314,7 @@ it('Keyboard handleMaxLength will work with object maxLength', () => {
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeTruthy();
});
@@ -330,7 +331,7 @@ it('Keyboard handleMaxLength will work with object maxLength and debug', () => {
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeTruthy();
});
@@ -346,7 +347,7 @@ it('Keyboard handleMaxLength will return false if obj maxLength not reached', ()
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeFalsy();
});
@@ -361,7 +362,7 @@ it('Keyboard handleMaxLength will work without debug', () => {
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeTruthy();
});
@@ -376,7 +377,7 @@ it('Keyboard handleMaxLength will work with numeric maxLength', () => {
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeFalsy();
});
@@ -390,7 +391,7 @@ it('Keyboard handleMaxLength wont work with non numeric or object maxLength', ()
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeFalsy();
});
@@ -405,7 +406,7 @@ it('Keyboard handleMaxLength wont work with non numeric or object maxLength (wit
keyboard.setInput("test");
let output = keyboard.utilities.handleMaxLength(keyboard.input, keyboard.options, "testq");
let output = keyboard.utilities.handleMaxLength(keyboard.input, "testq");
expect(output).toBeFalsy();
});
@@ -483,4 +484,10 @@ it('Keyboard will work with custom (and weird) class', () => {
testUtil.setDOM("my--weird--class");
let keyboard = new Keyboard(".my--weird--class");
expect(keyboard.keyboardDOMClass).toBe("my--weird--class");
});
it('Keyboard camelCase will work with empty strings', () => {
testUtil.setDOM();
let keyboard = new Keyboard();
expect(keyboard.utilities.camelCase()).toBeFalsy();
});
+8 -3
View File
@@ -7,9 +7,14 @@ export default class TestUtility {
*/
setDOM = (divClass) => {
this.clear();
const div = document.createElement('div');
div.className += divClass || "simple-keyboard";
document.body.appendChild(div);
const wrapperDOM = document.createElement('div');
wrapperDOM.setAttribute("id", "root");
const keyboardDOM = document.createElement('div');
keyboardDOM.className = divClass || "simple-keyboard";
wrapperDOM.appendChild(keyboardDOM);
document.body.appendChild(wrapperDOM);
}
/**