Added rtl option. Fixes #712

This commit is contained in:
Francisco Hodge 2020-10-16 00:09:09 -04:00
parent 11593c33b0
commit 58fad19e21
14 changed files with 222 additions and 15 deletions

View File

@ -1,6 +1,6 @@
/*!
*
* simple-keyboard v2.30.50
* simple-keyboard v2.31.0
* https://github.com/hodgef/simple-keyboard
*
* Copyright (c) Francisco Hodge (https://github.com/hodgef)

File diff suppressed because one or more lines are too long

5
build/index.d.ts vendored
View File

@ -152,6 +152,11 @@ declare module 'simple-keyboard' {
*/
disableButtonHold?: boolean;
/**
* Adds unicode right-to-left control characters to input return values.
*/
rtl?: boolean;
/**
* Executes the callback function on key press. Returns button layout name (i.e.: "{shift}").
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "simple-keyboard",
"version": "2.30.50",
"version": "2.31.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -11203,7 +11203,11 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"html-encoding-sniffer": {
"version": "1.0.2",
@ -20962,7 +20966,11 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"import-local": {
"version": "2.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "simple-keyboard",
"version": "2.30.50",
"version": "2.31.0",
"description": "On-screen Javascript Virtual Keyboard",
"main": "build/index.js",
"types": "build/index.d.ts",

72
src/demo/RTLDemo.js Normal file
View File

@ -0,0 +1,72 @@
import Keyboard from "../lib";
import "./css/RTLDemo.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),
rtl: true,
layout: {
default: [
"\u05e5 1 2 3 4 5 6 7 8 9 0 - = {bksp}",
"{tab} \u05e3 \u05df \u05e7 \u05e8 \u05d0 \u05d8 \u05d5 \u05ea \u05dd \u05e4 ] [ \\",
"{lock} \u05e9 \u05d3 \u05d2 \u05db \u05e2 \u05d9 \u05d7 \u05dc \u05da : ' {enter}",
"{shift} \u05d6 \u05e1 \u05d1 \u05d4 \u05e0 \u05de \u05e6 , . / {shift}",
".com @ {space}"
],
shift: [
"~ ! @ # $ % ^ & * ( ) _ + {bksp}",
"{tab} Q W E R T Y U I O P { } |",
'{lock} A S D F G H J K L : " {enter}',
"{shift} Z X C V B N M < > ? {shift}",
".com @ {space}"
]
}
});
/**
* 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, input.split(""));
}
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() {
const currentLayout = this.keyboard.options.layoutName;
const shiftToggle = currentLayout === "default" ? "shift" : "default";
this.keyboard.setOptions({
layoutName: shiftToggle
});
}
}
export default Demo;

13
src/demo/css/RTLDemo.css Normal file
View File

@ -0,0 +1,13 @@
input {
width: 100%;
height: 100px;
padding: 20px;
font-size: 20px;
border: none;
box-sizing: border-box;
direction: rtl;
}
.simple-keyboard {
max-width: 850px;
}

View File

@ -4,6 +4,7 @@ import "./css/index.css";
* Demos
*/
import BasicDemo from "./BasicDemo";
//import RTLDemo from "./RTLDemo";
//import ButtonThemeDemo from "./ButtonThemeDemo";
//import DOMElementDemo from "./DOMElementDemo";
//import FullKeyboardDemo from "./FullKeyboardDemo";

View File

@ -0,0 +1,72 @@
import { setDOM, removeRTLControls } from '../../utils/TestUtility';
import RTLDemo from '../RTLDemo';
it('Demo will load', () => {
setDOM();
new RTLDemo();
});
it('Demo onDOMLoaded will work', () => {
setDOM();
const demo = new RTLDemo();
expect(demo.keyboard).toBeTruthy();
});
it('Demo onChange will work', () => {
setDOM();
const demo = new RTLDemo();
demo.onChange("test");
expect(removeRTLControls(document.body.querySelector('.input').value)).toBe("test");
});
it('Demo onChange will work', () => {
setDOM();
const demo = new RTLDemo();
demo.keyboard.getButtonElement(".").onclick();
expect(removeRTLControls(document.body.querySelector('.input').value)).toBe(".");
});
it('Demo input change will work', () => {
setDOM();
const demo = new RTLDemo();
document.body.querySelector('.input').value = "test";
document.body.querySelector('.input').dispatchEvent(new Event('input'));
expect(removeRTLControls(demo.keyboard.getInput())).toBe("test");
});
it('Demo handleShiftButton will work', () => {
setDOM();
const demo = new RTLDemo();
demo.keyboard.getButtonElement("{shift}")[0].onclick();
expect(demo.keyboard.options.layoutName).toBe("shift");
demo.keyboard.getButtonElement("{shift}")[0].onclick();
expect(demo.keyboard.options.layoutName).toBe("default");
});
it('RTL control caracters will be added to ', () => {
setDOM();
const demo = new RTLDemo();
demo.keyboard.getButtonElement("פ").onclick();
demo.keyboard.getButtonElement("ם").onclick();
demo.keyboard.getButtonElement("[").onclick();
expect(demo.keyboard.getInput()).toBe("‫פם[");
expect(demo.keyboard.input[demo.keyboard.options.inputName]).toBe("פם[");
});

View File

@ -152,6 +152,11 @@ declare module 'simple-keyboard' {
*/
disableButtonHold?: boolean;
/**
* Adds unicode right-to-left control characters to input return values.
*/
rtl?: boolean;
/**
* Executes the callback function on key press. Returns button layout name (i.e.: "{shift}").
*/

View File

@ -83,6 +83,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 {boolean} rtl Adds unicode right-to-left control characters to input return values.
* @property {function} onKeyReleased Executes the callback function on key release.
* @property {array} modules Module classes to be loaded by simple-keyboard.
*/
@ -292,7 +293,7 @@ class SimpleKeyboard {
true
);
if (debug) console.log("Input changed:", this.input);
if (debug) console.log("Input changed:", this.getAllInputs());
if (this.options.debug) {
console.log(
@ -312,13 +313,13 @@ class SimpleKeyboard {
* Calling onChange
*/
if (typeof this.options.onChange === "function")
this.options.onChange(this.input[this.options.inputName]);
this.options.onChange(this.getInput(this.options.inputName, true));
/**
* Calling onChangeAll
*/
if (typeof this.options.onChangeAll === "function")
this.options.onChangeAll(this.input);
this.options.onChangeAll(this.getAllInputs());
}
if (debug) {
@ -470,15 +471,38 @@ class SimpleKeyboard {
* Get the keyboards input (You can also get it from the onChange prop).
* @param {string} [inputName] optional - the internal input to select
*/
getInput(inputName) {
getInput(inputName, skipSync = false) {
inputName = inputName || this.options.inputName;
/**
* Enforce syncInstanceInputs, if set
*/
if (this.options.syncInstanceInputs) this.syncInstanceInputs();
if (this.options.syncInstanceInputs && !skipSync) this.syncInstanceInputs();
return this.input[inputName];
if (this.options.rtl) {
// Remove existing control chars
const inputWithoutRTLControl = this.input[inputName]
.replace("\u202B", "")
.replace("\u202C", "");
return "\u202B" + inputWithoutRTLControl + "\u202C";
} else {
return this.input[inputName];
}
}
/**
* Get all simple-keyboard inputs
*/
getAllInputs() {
const output = {};
const inputNames = Object.keys(this.input);
inputNames.forEach(inputName => {
output[inputName] = this.getInput(inputName, true);
});
return output;
}
/**

View File

@ -122,3 +122,10 @@
});
});
}
/**
* Remove RTL control chars
*/
export const removeRTLControls = (input) => {
return input.replace("\u202B", "").replace("\u202C", "");
}