Compare commits

...

13 Commits

Author SHA1 Message Date
Francisco Hodge
652084cabb npm update 2019-03-09 21:47:49 -05:00
Francisco Hodge
39c4acba85 Tests update 2019-03-09 21:47:39 -05:00
Francisco Hodge
69b830c632 Added row button grouping functionality 2019-03-09 21:47:31 -05:00
Francisco Hodge
cd909cffa8 Build update 2019-03-07 21:30:17 -05:00
Francisco Hodge
92d2b381db npm update 2019-03-07 21:26:43 -05:00
Francisco Hodge
96206d1b47 Remove PointerEvents debug message when useMouseEvents is enabled 2019-03-07 21:26:22 -05:00
Francisco Hodge
19f6ac9ac1 Build update 2019-03-07 20:53:23 -05:00
Francisco Hodge
90b67ec416 Support Utilities access through Typescript 2019-03-07 20:53:07 -05:00
Francisco Hodge
6208d5f7e1 Fixed getInput output when inputName is passed 2019-03-07 20:52:40 -05:00
Francisco Hodge
bd0274415b Fixed onChangeAll callback 2019-03-07 20:51:57 -05:00
Francisco Hodge
30941f4ba0 Adding useMouseEvents option 2019-03-07 20:51:29 -05:00
Francisco Hodge
48a15e6715 Disable devDependency tracking 2019-03-07 20:49:34 -05:00
Francisco Hodge
f8ee859bb0 Build update 2019-03-07 07:36:08 -05:00
14 changed files with 323 additions and 21 deletions

View File

@@ -6,7 +6,6 @@
<a href="https://travis-ci.org/hodgef/simple-keyboard" target="_blank"><img src="https://travis-ci.org/hodgef/simple-keyboard.svg?branch=master" alt="Build Status"></a>
<a href="https://codecov.io/gh/hodgef/simple-keyboard" target="_blank"><img src="https://img.shields.io/codecov/c/github/hodgef/simple-keyboard/master.svg?style=flat" alt="Coverage Status"></a>
<a href="https://doc.esdoc.org/github.com/hodgef/simple-keyboard" target="_blank"><img src="https://doc.esdoc.org/github.com/hodgef/simple-keyboard/badge.svg" alt="Documentation Status"></a>
<img src="https://img.shields.io/david/dev/hodgef/simple-keyboard.svg" alt="Dev dependencies">
<a href="https://www.codacy.com/app/hodgef/simple-keyboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=hodgef/simple-keyboard&amp;utm_campaign=Badge_Grade" target="_blank"><img src="https://api.codacy.com/project/badge/Grade/5778fccc6a894701853d9a1f2fb44a76" alt="Codacy Badge"></a>
</p>
</div>

View File

@@ -1,6 +1,6 @@
/*!
*
* simple-keyboard v2.17.0
* simple-keyboard v2.18.1
* 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

View File

@@ -1,6 +1,6 @@
/*!
*
* simple-keyboard v2.17.0 (Non-minified build)
* simple-keyboard v2.18.1 (Non-minified build)
* https://github.com/hodgef/simple-keyboard
*
* Copyright (c) Francisco Hodge (https://github.com/hodgef)

10
build/index.d.ts vendored
View File

@@ -10,6 +10,11 @@ declare module 'simple-keyboard' {
}
interface KeyboardOptions {
/**
* Utilities
*/
utilities?: any;
/**
* Modify the keyboard layout.
*/
@@ -121,6 +126,11 @@ declare module 'simple-keyboard' {
*/
autoUseTouchEvents?: boolean;
/**
* Opt out of PointerEvents handling, falling back to the prior mouse event logic.
*/
useMouseEvents?: 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

View File

@@ -1,6 +1,6 @@
/*!
*
* simple-keyboard v2.17.0 (Non-minified build)
* simple-keyboard v2.18.1 (Non-minified build)
* https://github.com/hodgef/simple-keyboard
*
* Copyright (c) Francisco Hodge (https://github.com/hodgef)
@@ -849,6 +849,7 @@
* @property {object} inputPattern Restrains input(s) change to the defined regular expression pattern.
* @property {boolean} useTouchEvents Instructs simple-keyboard to use touch events instead of click events.
* @property {boolean} autoUseTouchEvents Enable useTouchEvents automatically when touch device is detected.
* @property {boolean} useMouseEvents Opt out of PointerEvents handling, falling back to the prior mouse event logic.
*/ this.options = options;
this.options.layoutName = this.options.layoutName || "default";
this.options.theme = this.options.theme || "hg-theme-default";
@@ -948,6 +949,11 @@
*/ }
if (typeof this.options.onChange === "function") {
this.options.onChange(this.input[this.options.inputName]);
/**
* Calling onChangeAll
*/ }
if (typeof this.options.onChangeAll === "function") {
this.options.onChangeAll(this.input);
}
}
if (debug) {
@@ -1047,7 +1053,7 @@
*/ if (this.options.syncInstanceInputs) {
this.syncInstanceInputs(this.input);
}
return this.input[this.options.inputName];
return this.input[inputName];
}
/**
* Set the keyboards input.
@@ -1373,7 +1379,7 @@
/**
* Notify about PointerEvents usage
*/ }
if (this.utilities.pointerEventsSupported() && !this.options.useTouchEvents) {
if (this.utilities.pointerEventsSupported() && !this.options.useTouchEvents && !this.options.useMouseEvents) {
if (this.options.debug) {
console.log("Using PointerEvents as it is supported by this browser");
}
@@ -1458,6 +1464,7 @@
var layout = this.options.layout || services_KeyboardLayout.getDefaultLayout();
var useTouchEvents = this.options.useTouchEvents || false;
var useTouchEventsClass = useTouchEvents ? "hg-touch-events" : "";
var useMouseEvents = this.options.useMouseEvents || false;
/**
* Account for buttonTheme, if set
*/ var buttonThemesParsed = Array.isArray(this.options.buttonTheme) ? this.getButtonTheme() : {};
@@ -1485,7 +1492,7 @@
buttonDOM.className += "hg-button ".concat(fctBtnClass).concat(buttonThemeClass ? " " + buttonThemeClass : "");
/**
* Handle button click event
*/ /* istanbul ignore next */ if (_this9.utilities.pointerEventsSupported() && !useTouchEvents) {
*/ /* istanbul ignore next */ if (_this9.utilities.pointerEventsSupported() && !useTouchEvents && !useMouseEvents) {
/**
* PointerEvents support
*/ buttonDOM.onpointerdown = function(e) {

4
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "simple-keyboard",
"version": "2.17.0",
"version": "2.18.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -5312,7 +5312,7 @@
},
"duplexer": {
"version": "0.1.1",
"resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},

View File

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

View File

@@ -10,6 +10,11 @@ declare module 'simple-keyboard' {
}
interface KeyboardOptions {
/**
* Utilities
*/
utilities?: any;
/**
* Modify the keyboard layout.
*/
@@ -121,6 +126,11 @@ declare module 'simple-keyboard' {
*/
autoUseTouchEvents?: boolean;
/**
* Opt out of PointerEvents handling, falling back to the prior mouse event logic.
*/
useMouseEvents?: boolean;
/**
* Executes the callback function on key press. Returns button layout name (i.e.: "{shift}").
*/

View File

@@ -26,6 +26,18 @@ html {
margin-right: 5px;
}
.simple-keyboard .hg-row .hg-button-container {
margin-right: 5px;
}
.simple-keyboard .hg-row > div:last-child {
margin-right: 0;
}
.simple-keyboard .hg-row .hg-button-container {
display: flex;
}
.simple-keyboard .hg-button {
display: inline-block;
flex-grow: 1;

View File

@@ -63,6 +63,7 @@ class SimpleKeyboard {
* @property {object} inputPattern Restrains input(s) change to the defined regular expression pattern.
* @property {boolean} useTouchEvents Instructs simple-keyboard to use touch events instead of click events.
* @property {boolean} autoUseTouchEvents Enable useTouchEvents automatically when touch device is detected.
* @property {boolean} useMouseEvents Opt out of PointerEvents handling, falling back to the prior mouse event logic.
*/
this.options = options;
this.options.layoutName = this.options.layoutName || "default";
@@ -207,6 +208,12 @@ class SimpleKeyboard {
*/
if (typeof this.options.onChange === "function")
this.options.onChange(this.input[this.options.inputName]);
/**
* Calling onChangeAll
*/
if (typeof this.options.onChangeAll === "function")
this.options.onChangeAll(this.input);
}
if (debug) {
@@ -312,7 +319,7 @@ class SimpleKeyboard {
*/
if (this.options.syncInstanceInputs) this.syncInstanceInputs(this.input);
return this.input[this.options.inputName];
return this.input[inputName];
}
/**
@@ -723,7 +730,8 @@ class SimpleKeyboard {
*/
if (
this.utilities.pointerEventsSupported() &&
!this.options.useTouchEvents
!this.options.useTouchEvents &&
!this.options.useMouseEvents
) {
if (this.options.debug) {
console.log("Using PointerEvents as it is supported by this browser");
@@ -805,18 +813,104 @@ class SimpleKeyboard {
/**
* Get module prop
*/
getModuleProp = (name, prop) => {
getModuleProp(name, prop) {
if (!this.modules[name]) return false;
return this.modules[name][prop];
};
}
/**
* getModulesList
*/
getModulesList = () => {
getModulesList() {
return Object.keys(this.modules);
};
}
/**
* Parse Row DOM containers
*/
parseRowDOMContainers(
rowDOM,
rowIndex,
containerStartIndexes,
containerEndIndexes
) {
let rowDOMArray = Array.from(rowDOM.children);
let removedElements = 0;
if (rowDOMArray.length) {
containerStartIndexes.forEach((startIndex, arrIndex) => {
let endIndex = containerEndIndexes[arrIndex];
/**
* If there exists a respective end index
* if end index comes after start index
*/
if (!endIndex || !(endIndex > startIndex)) {
return false;
}
/**
* Updated startIndex, endIndex
* This is since the removal of buttons to place a single button container
* results in a modified array size
*/
let updated_startIndex = startIndex - removedElements;
let updated_endIndex = endIndex - removedElements;
/**
* Create button container
*/
let containerDOM = document.createElement("div");
containerDOM.className += "hg-button-container";
let containerUID = `${
this.options.layoutName
}-r${rowIndex}c${arrIndex}`;
containerDOM.setAttribute("data-skUID", containerUID);
/**
* Taking elements due to be inserted into container
*/
let containedElements = rowDOMArray.splice(
updated_startIndex,
updated_endIndex - updated_startIndex + 1
);
removedElements = updated_endIndex - updated_startIndex;
/**
* Inserting elements to container
*/
containedElements.forEach(element => containerDOM.appendChild(element));
/**
* Adding container at correct position within rowDOMArray
*/
rowDOMArray.splice(updated_startIndex, 0, containerDOM);
/**
* Clearing old rowDOM children structure
*/
rowDOM.innerHTML = "";
/**
* Appending rowDOM new children list
*/
rowDOMArray.forEach(element => rowDOM.appendChild(element));
if (this.options.debug) {
console.log(
"rowDOMContainer",
containedElements,
updated_startIndex,
updated_endIndex,
removedElements + 1
);
}
});
}
return rowDOM;
}
/**
* Renders rows and buttons as per options
@@ -843,6 +937,8 @@ class SimpleKeyboard {
let layout = this.options.layout || KeyboardLayout.getDefaultLayout();
let useTouchEvents = this.options.useTouchEvents || false;
let useTouchEventsClass = useTouchEvents ? "hg-touch-events" : "";
let useMouseEvents = this.options.useMouseEvents || false;
let disableRowButtonContainers = this.options.disableRowButtonContainers;
/**
* Account for buttonTheme, if set
@@ -870,10 +966,52 @@ class SimpleKeyboard {
let rowDOM = document.createElement("div");
rowDOM.className += "hg-row";
/**
* Tracking container indicators in rows
*/
let containerStartIndexes = [];
let containerEndIndexes = [];
/**
* Iterating through each button in row
*/
rowArray.forEach((button, bIndex) => {
/**
* Check if button has a container indicator
*/
let buttonHasContainerStart =
!disableRowButtonContainers &&
button.includes("[") &&
button.length > 1;
let buttonHasContainerEnd =
!disableRowButtonContainers &&
button.includes("]") &&
button.length > 1;
/**
* Save container start index, if applicable
*/
if (buttonHasContainerStart) {
containerStartIndexes.push(bIndex);
/**
* Removing indicator
*/
button = button.replace(/\[/g, "");
}
if (buttonHasContainerEnd) {
containerEndIndexes.push(bIndex);
/**
* Removing indicator
*/
button = button.replace(/\]/g, "");
}
/**
* Processing button options
*/
let fctBtnClass = this.utilities.getButtonClass(button);
let buttonThemeClass = buttonThemesParsed[button];
let buttonDisplayName = this.utilities.getButtonDisplayName(
@@ -895,7 +1033,11 @@ class SimpleKeyboard {
* Handle button click event
*/
/* istanbul ignore next */
if (this.utilities.pointerEventsSupported() && !useTouchEvents) {
if (
this.utilities.pointerEventsSupported() &&
!useTouchEvents &&
!useMouseEvents
) {
/**
* PointerEvents support
*/
@@ -969,6 +1111,16 @@ class SimpleKeyboard {
rowDOM.appendChild(buttonDOM);
});
/**
* Parse containers in row
*/
rowDOM = this.parseRowDOMContainers(
rowDOM,
rIndex,
containerStartIndexes,
containerEndIndexes
);
/**
* Appending row to keyboard
*/

View File

@@ -186,6 +186,22 @@ it('Keyboard onChange will work', () => {
expect(output).toBe("q");
});
it('Keyboard onChangeAll will work', () => {
testUtil.setDOM();
let output;
let keyboard = new Keyboard({
onChangeAll: (input) => {
output = input ? input.default : null;
}
});
keyboard.getButtonElement("q").onclick();
expect(output).toBe("q");
});
it('Keyboard clearInput will work', () => {
testUtil.setDOM();
@@ -1059,4 +1075,100 @@ it('Keyboard beforeRender method will work', () => {
});
expect(timesCalled).toBe(2);
});
it('Keyboard parseRowDOMContainers will work', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
layout: {
'default': [
'` [1 2 3 4 5 6 7 8 9] 0 - = {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} {arrowleft} [{arrowup} {arrowdown}] {arrowright}'
],
'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}'
]
}
});
let containers = Array.from(document.querySelectorAll(".hg-button-container"));
expect(containers.length).toBe(5);
keyboard.setOptions({
debug: true
});
expect(containers.length).toBe(5);
});
it('Keyboard parseRowDOMContainers will ignore empty rows', () => {
testUtil.setDOM();
let failed = false;
try {
let keyboard = new Keyboard();
keyboard.parseRowDOMContainers({
children: []
});
} catch (e) {
failed = true;
}
expect(failed).toBeFalsy();
});
it('Keyboard parseRowDOMContainers will ignore missing endIndex or endIndex before startIndex', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
layout: {
'default': [
'` [1 2 3 4 5 6 7 8 9 0 - = {bksp}',
'` 1 2 3] 4 5 6 7 8 9 [0 - = {bksp}',
]
}
});
let containers = Array.from(document.querySelectorAll(".hg-button-container"));
expect(containers.length).toBe(0);
});
it('Keyboard disableRowButtonContainers will bypass parseRowDOMContainers', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
disableRowButtonContainers: true,
layout: {
'default': [
'` [1 2 3 4 5 6 7 8 9] 0 - = {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} {arrowleft} [{arrowup} {arrowdown}] {arrowright}'
],
'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}'
]
}
});
let containers = Array.from(document.querySelectorAll(".hg-button-container"));
expect(containers.length).toBe(0);
});