Docs update

This commit is contained in:
Francisco Hodge
2018-10-24 18:18:24 -04:00
parent 4589ab789d
commit 2e3ca5716b
63 changed files with 257854 additions and 16 deletions
+145
View File
@@ -0,0 +1,145 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../">
<title data-ice="title">src/demo/App.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/demo/App.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import Keyboard from &apos;../lib&apos;;
import &apos;./css/App.css&apos;;
/**
* simple-keyboard demo
*/
class App {
/**
* Instantiates the demo class
*/
constructor(){
document.addEventListener(&apos;DOMContentLoaded&apos;, this.onDOMLoaded);
/**
* Default input name
* @type {string}
*/
this.layoutName = &quot;default&quot;;
}
/**
* Executed when the DOM is ready
*/
onDOMLoaded = () =&gt; {
/**
* Creates a new simple-keyboard instance
*/
this.keyboard = new Keyboard({
debug: true,
layoutName: this.layoutName,
onChange: input =&gt; this.onChange(input),
onKeyPress: button =&gt; this.onKeyPress(button),
newLineOnEnter: true,
physicalKeyboardHighlight: true,
});
/**
* Adding preview (demo only)
*/
document.querySelector(&apos;.simple-keyboard&apos;).insertAdjacentHTML(&apos;beforebegin&apos;, `
&lt;div class=&quot;simple-keyboard-preview&quot;&gt;
&lt;textarea class=&quot;input&quot;&gt;&lt;/textarea&gt;
&lt;/div&gt;
`);
document.querySelector(&apos;.input&apos;).addEventListener(&apos;change&apos;, (event) =&gt; {
this.keyboard.setInput(event.target.value);
});
console.log(this.keyboard);
}
/**
*
*/
handleShiftButton = () =&gt; {
let layoutName = this.layoutName;
let shiftToggle = this.layoutName = layoutName === &quot;default&quot; ? &quot;shift&quot; : &quot;default&quot;;
this.keyboard.setOptions({
layoutName: shiftToggle
});
}
/**
* Called when simple-keyboard input has changed
*/
onChange = input =&gt; {
document.querySelector(&apos;.input&apos;).value = input;
}
/**
* Called when a simple-keyboard key is pressed
*/
onKeyPress = button =&gt; {
console.log(&quot;Button pressed&quot;, button);
/**
* Shift functionality
*/
if(button === &quot;{lock}&quot; || button === &quot;{shift}&quot;)
this.handleShiftButton();
}
}
export default App;</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../">
<title data-ice="title">src/demo/index.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/demo/index.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import App from &apos;./App&apos;;
/**
* Initializing demo
*/
new App();</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
@@ -0,0 +1,655 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../../">
<title data-ice="title">src/lib/components/Keyboard.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/components/Keyboard.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import &apos;./Keyboard.css&apos;;
// Services
import PhysicalKeyboard from &apos;../services/PhysicalKeyboard&apos;;
import KeyboardLayout from &apos;../services/KeyboardLayout&apos;;
import Utilities from &apos;../services/Utilities&apos;;
/**
* Root class for simple-keyboard
* This class:
* - Parses the options
* - Renders the rows and buttons
* - Handles button functionality
*/
class SimpleKeyboard {
/**
* Creates an instance of SimpleKeyboard
* @param {Array} params If first parameter is a string, it is considered the container class. The second parameter is then considered the options object. If first parameter is an object, it is considered the options object.
*/
constructor(...params){
let keyboardDOMQuery = typeof params[0] === &quot;string&quot; ? params[0] : &apos;.simple-keyboard&apos;;
let options = typeof params[0] === &quot;object&quot; ? params[0] : params[1];
if(!options)
options = {};
/**
* Initializing Utilities
*/
this.utilities = new Utilities(this);
/**
* Processing options
*/
this.keyboardDOM = document.querySelector(keyboardDOMQuery);
/**
* @type {object}
* @property {object} layout Modify the keyboard layout.
* @property {string} layoutName Specifies which layout should be used.
* @property {object} display Replaces variable buttons (such as {bksp}) with a human-friendly name (e.g.: &#x201C;backspace&#x201D;).
* @property {boolean} mergeDisplay By default, when you set the display property, you replace the default one. This setting merges them instead.
* @property {string} theme A prop to add your own css classes to the keyboard wrapper. You can add multiple classes separated by a space.
* @property {Array} buttonTheme A prop to add your own css classes to one or several buttons.
* @property {boolean} debug Runs a console.log every time a key is pressed. Displays the buttons pressed and the current input.
* @property {boolean} newLineOnEnter Specifies whether clicking the &#x201C;ENTER&#x201D; button will input a newline (\n) or not.
* @property {boolean} tabCharOnTab Specifies whether clicking the &#x201C;TAB&#x201D; button will input a tab character (\t) or not.
* @property {string} inputName Allows you to use a single simple-keyboard instance for several inputs.
* @property {number} maxLength Restrains all of simple-keyboard inputs to a certain length. This should be used in addition to the input element&#x2019;s maxlengthattribute.
* @property {object} maxLength Restrains simple-keyboard&#x2019;s individual inputs to a certain length. This should be used in addition to the input element&#x2019;s maxlengthattribute.
* @property {boolean} syncInstanceInputs When set to true, this option synchronizes the internal input of every simple-keyboard instance.
* @property {boolean} physicalKeyboardHighlight Enable highlighting of keys pressed on physical keyboard.
* @property {string} physicalKeyboardHighlightTextColor Define the text color that the physical keyboard highlighted key should have.
* @property {string} physicalKeyboardHighlightBgColor Define the background color that the physical keyboard highlighted key should have.
* @property {function(button: string):string} onKeyPress Executes the callback function on key press. Returns button layout name (i.e.: &#x201C;{shift}&#x201D;).
* @property {function(input: string):string} onChange Executes the callback function on input change. Returns the current input&#x2019;s string.
* @property {function} onRender Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
* @property {function} onInit Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
* @property {function(inputs: object):object} onChangeAll Executes the callback function on input change. Returns the input object with all defined inputs.
*/
this.options = options;
this.options.layoutName = this.options.layoutName || &quot;default&quot;;
this.options.theme = this.options.theme || &quot;hg-theme-default&quot;;
this.options.inputName = this.options.inputName || &quot;default&quot;;
/**
* simple-keyboard uses a non-persistent internal input to keep track of the entered string (the variable `keyboard.input`).
* This removes any dependency to input DOM elements. You can type and directly display the value in a div element, for example.
* @example
* // To get entered input
* let input = keyboard.getInput();
*
* // To clear entered input.
* keyboard.clearInput();
*
* @type {object}
* @property {object} default Default SimpleKeyboard internal input.
* @property {object} myInputName Example input that can be set through `options.inputName:&quot;myInputName&quot;`.
*/
this.input = {};
this.input[this.options.inputName] = &apos;&apos;;
/**
* @type {string} DOM class of the keyboard wrapper, normally &quot;simple-keyboard&quot; by default.
*/
this.keyboardDOMClass = keyboardDOMQuery.split(&apos;.&apos;).join(&quot;&quot;);
/**
* @type {object} Contains the DOM elements of every rendered button, the key being the button&apos;s layout name (e.g.: &quot;{enter}&quot;).
*/
this.buttonElements = {};
/**
* Rendering keyboard
*/
if(this.keyboardDOM)
this.render();
else {
console.warn(`&quot;${keyboardDOMQuery}&quot; was not found in the DOM.`);
throw new Error(&quot;KEYBOARD_DOM_ERROR&quot;);
}
/**
* Saving instance
* This enables multiple simple-keyboard support with easier management
*/
if(!window[&apos;SimpleKeyboardInstances&apos;])
window[&apos;SimpleKeyboardInstances&apos;] = {};
window[&apos;SimpleKeyboardInstances&apos;][this.utilities.camelCase(this.keyboardDOMClass)] = this;
/**
* Physical Keyboard support
*/
this.physicalKeyboardInterface = new PhysicalKeyboard(this);
}
/**
* Handles clicks made to keyboard buttons
* @param {string} button The button&apos;s layout name.
*/
handleButtonClicked = (button) =&gt; {
let debug = this.options.debug;
/**
* Ignoring placeholder buttons
*/
if(button === &apos;{//}&apos;)
return false;
/**
* Calling onKeyPress
*/
if(typeof this.options.onKeyPress === &quot;function&quot;)
this.options.onKeyPress(button);
if(!this.input[this.options.inputName])
this.input[this.options.inputName] = &apos;&apos;;
let updatedInput = this.utilities.getUpdatedInput(button, this.input[this.options.inputName], this.options, this.caretPosition);
if(this.input[this.options.inputName] !== updatedInput){
/**
* If maxLength and handleMaxLength yield true, halting
*/
if(this.options.maxLength &amp;&amp; this.utilities.handleMaxLength(this.input, this.options, updatedInput)){
return false;
}
this.input[this.options.inputName] = updatedInput;
if(debug)
console.log(&apos;Input changed:&apos;, this.input);
/**
* Enforce syncInstanceInputs, if set
*/
if(this.options.syncInstanceInputs)
this.syncInstanceInputs(this.input);
/**
* Calling onChange
*/
if(typeof this.options.onChange === &quot;function&quot;)
this.options.onChange(this.input[this.options.inputName]);
}
if(debug){
console.log(&quot;Key pressed:&quot;, button);
}
}
/**
* Send a command to all simple-keyboard instances (if you have several instances).
*/
syncInstanceInputs = () =&gt; {
this.dispatch((instance) =&gt; {
instance.replaceInput(this.input);
});
}
/**
* Clear the keyboard&#x2019;s input.
* @param {string} [inputName] optional - the internal input to select
*/
clearInput = (inputName) =&gt; {
inputName = inputName || this.options.inputName;
this.input[this.options.inputName] = &apos;&apos;;
/**
* Enforce syncInstanceInputs, if set
*/
if(this.options.syncInstanceInputs)
this.syncInstanceInputs(this.input);
}
/**
* Get the keyboard&#x2019;s input (You can also get it from the onChange prop).
* @param {string} [inputName] optional - the internal input to select
*/
getInput = (inputName) =&gt; {
inputName = inputName || this.options.inputName;
/**
* Enforce syncInstanceInputs, if set
*/
if(this.options.syncInstanceInputs)
this.syncInstanceInputs(this.input);
return this.input[this.options.inputName];
}
/**
* Set the keyboard&#x2019;s input.
* @param {string} input the input value
* @param {string} inputName optional - the internal input to select
*/
setInput = (input, inputName) =&gt; {
inputName = inputName || this.options.inputName;
this.input[inputName] = input;
/**
* Enforce syncInstanceInputs, if set
*/
if(this.options.syncInstanceInputs)
this.syncInstanceInputs(this.input);
}
/**
* Replace the input object (`keyboard.input`)
* @param {object} inputObj The input object
*/
replaceInput = (inputObj) =&gt; {
this.input = inputObj;
}
/**
* Set new option or modify existing ones after initialization.
* @param {object} option The option to set
*/
setOptions = option =&gt; {
option = option || {};
this.options = Object.assign(this.options, option);
this.render();
}
/**
* Remove all keyboard rows and reset keyboard values.
* Used interally between re-renders.
*/
clear = () =&gt; {
this.keyboardDOM.innerHTML = &apos;&apos;;
this.keyboardDOM.className = this.keyboardDOMClass;
this.buttonElements = {};
}
/**
* Send a command to all simple-keyboard instances at once (if you have multiple instances).
* @param {function(instance: object, key: string)} callback Function to run on every instance
*/
dispatch = (callback) =&gt; {
if(!window[&apos;SimpleKeyboardInstances&apos;]){
console.warn(`SimpleKeyboardInstances is not defined. Dispatch cannot be called.`);
throw new Error(&quot;INSTANCES_VAR_ERROR&quot;);
}
return Object.keys(window[&apos;SimpleKeyboardInstances&apos;]).forEach((key) =&gt; {
callback(window[&apos;SimpleKeyboardInstances&apos;][key], key);
})
}
/**
* Adds/Modifies an entry to the `buttonTheme`. Basically a way to add a class to a button.
* @param {string} buttons List of buttons to select (separated by a space).
* @param {string} className Classes to give to the selected buttons (separated by space).
*/
addButtonTheme = (buttons, className) =&gt; {
if(!className || !buttons)
return false;
buttons.split(&quot; &quot;).forEach(button =&gt; {
className.split(&quot; &quot;).forEach(classNameItem =&gt; {
if(!this.options.buttonTheme)
this.options.buttonTheme = [];
let classNameFound = false;
/**
* If class is already defined, we add button to class definition
*/
this.options.buttonTheme.map(buttonTheme =&gt; {
if(buttonTheme.class.split(&quot; &quot;).includes(classNameItem)){
classNameFound = true;
let buttonThemeArray = buttonTheme.buttons.split(&quot; &quot;);
if(!buttonThemeArray.includes(button)){
classNameFound = true;
buttonThemeArray.push(button);
buttonTheme.buttons = buttonThemeArray.join(&quot; &quot;);
}
}
return buttonTheme;
});
/**
* If class is not defined, we create a new entry
*/
if(!classNameFound){
this.options.buttonTheme.push({
class: classNameItem,
buttons: buttons
});
}
});
});
this.render();
}
/**
* Removes/Amends an entry to the `buttonTheme`. Basically a way to remove a class previously added to a button through buttonTheme or addButtonTheme.
* @param {string} buttons List of buttons to select (separated by a space).
* @param {string} className Classes to give to the selected buttons (separated by space).
*/
removeButtonTheme = (buttons, className) =&gt; {
/**
* When called with empty parameters, remove all button themes
*/
if(!buttons &amp;&amp; !className){
this.options.buttonTheme = [];
this.render();
return false;
}
/**
* If buttons are passed and buttonTheme has items
*/
if(buttons &amp;&amp; Array.isArray(this.options.buttonTheme) &amp;&amp; this.options.buttonTheme.length){
let buttonArray = buttons.split(&quot; &quot;);
buttonArray.forEach((button, key) =&gt; {
this.options.buttonTheme.map((buttonTheme, index) =&gt; {
/**
* If className is set, we affect the buttons only for that class
* Otherwise, we afect all classes
*/
if(
(className &amp;&amp; className.includes(buttonTheme.class)) ||
!className
){
let filteredButtonArray = buttonTheme.buttons.split(&quot; &quot;).filter(item =&gt; item !== button);
/**
* If buttons left, return them, otherwise, remove button Theme
*/
if(filteredButtonArray.length){
buttonTheme.buttons = filteredButtonArray.join(&quot; &quot;);
} else {
this.options.buttonTheme.splice(index, 1);
buttonTheme = null;
}
}
return buttonTheme;
});
});
this.render();
}
}
/**
* Get the DOM Element of a button. If there are several buttons with the same name, an array of the DOM Elements is returned.
* @param {string} button The button layout name to select
*/
getButtonElement = (button) =&gt; {
let output;
let buttonArr = this.buttonElements[button];
if(buttonArr){
if(buttonArr.length &gt; 1){
output = buttonArr;
} else {
output = buttonArr[0];
}
}
return output;
}
/**
* Retrieves the current cursor position within a input or textarea (if any)
*/
handleCaret = () =&gt; {
if(this.options.debug){
console.log(&quot;Caret handling started&quot;);
}
document.addEventListener(&quot;keyup&quot;, this.caretEventHandler);
document.addEventListener(&quot;mouseup&quot;, this.caretEventHandler);
document.addEventListener(&quot;touchend&quot;, this.caretEventHandler);
}
/**
* Called by {@link handleCaret} when an event that warrants a cursor position update is triggered
*/
caretEventHandler = (event) =&gt; {
let targetTagName = event.target.tagName.toLowerCase();
if(
targetTagName === &quot;textarea&quot; ||
targetTagName === &quot;input&quot;
){
/**
* Tracks current cursor position
* As keys are pressed, text will be added/removed at that position within the input.
*/
this.caretPosition = event.target.selectionStart;
if(this.options.debug){
console.log(&apos;Caret at: &apos;, event.target.selectionStart, event.target.tagName.toLowerCase());
}
}
}
/**
* Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
*/
onInit = () =&gt; {
if(this.options.debug){
console.log(&quot;Initialized&quot;);
}
/**
* Caret handling
*/
this.handleCaret();
if(typeof this.options.onInit === &quot;function&quot;)
this.options.onInit();
}
/**
* Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
*/
onRender = () =&gt; {
if(typeof this.options.onRender === &quot;function&quot;)
this.options.onRender();
}
/**
* Renders rows and buttons as per options
*/
render = () =&gt; {
/**
* Clear keyboard
*/
this.clear();
let layoutClass = this.options.layout ? &quot;hg-layout-custom&quot; : `hg-layout-${this.options.layoutName}`;
let layout = this.options.layout || KeyboardLayout.getDefaultLayout();
/**
* Account for buttonTheme, if set
*/
let buttonThemesParsed = {};
if(Array.isArray(this.options.buttonTheme)){
this.options.buttonTheme.forEach(themeObj =&gt; {
if(themeObj.buttons &amp;&amp; themeObj.class){
let themeButtons;
if(typeof themeObj.buttons === &quot;string&quot;){
themeButtons = themeObj.buttons.split(&apos; &apos;);
}
if(themeButtons){
themeButtons.forEach(themeButton =&gt; {
let themeParsed = buttonThemesParsed[themeButton];
// If the button has already been added
if(themeParsed){
// Making sure we don&apos;t add duplicate classes, even when buttonTheme has duplicates
if(!this.utilities.countInArray(themeParsed.split(&quot; &quot;), themeObj.class)){
buttonThemesParsed[themeButton] = `${themeParsed} ${themeObj.class}`;
}
} else {
buttonThemesParsed[themeButton] = themeObj.class;
}
});
}
} else {
console.warn(`buttonTheme row is missing the &quot;buttons&quot; or the &quot;class&quot;. Please check the documentation.`)
}
});
}
/**
* Adding themeClass, layoutClass to keyboardDOM
*/
this.keyboardDOM.className += ` ${this.options.theme} ${layoutClass}`;
/**
* Iterating through each row
*/
layout[this.options.layoutName].forEach((row, rIndex) =&gt; {
let rowArray = row.split(&apos; &apos;);
/**
* Creating empty row
*/
var rowDOM = document.createElement(&apos;div&apos;);
rowDOM.className += &quot;hg-row&quot;;
/**
* Iterating through each button in row
*/
rowArray.forEach((button, bIndex) =&gt; {
let fctBtnClass = this.utilities.getButtonClass(button);
let buttonThemeClass = buttonThemesParsed[button];
let buttonDisplayName = this.utilities.getButtonDisplayName(button, this.options.display, this.options.mergeDisplay);
/**
* Creating button
*/
var buttonDOM = document.createElement(&apos;div&apos;);
buttonDOM.className += `hg-button ${fctBtnClass}${buttonThemeClass ? &quot; &quot;+buttonThemeClass : &quot;&quot;}`;
buttonDOM.onclick = () =&gt; this.handleButtonClicked(button);
/**
* Adding identifier
*/
buttonDOM.setAttribute(&quot;data-skBtn&quot;, button);
/**
* Adding unique id
* Since there&apos;s no limit on spawning same buttons, the unique id ensures you can style every button
*/
let buttonUID = `${this.options.layoutName}-r${rIndex}b${bIndex}`;
buttonDOM.setAttribute(&quot;data-skBtnUID&quot;, buttonUID);
/**
* Adding display label
*/
buttonDOM.setAttribute(&quot;data-displayLabel&quot;, buttonDisplayName);
/**
* Adding button label to button
*/
var buttonSpanDOM = document.createElement(&apos;span&apos;);
buttonSpanDOM.innerHTML = buttonDisplayName;
buttonDOM.appendChild(buttonSpanDOM);
/**
* Adding to buttonElements
*/
if(!this.buttonElements[button])
this.buttonElements[button] = [];
this.buttonElements[button].push(buttonDOM);
/**
* Appending button to row
*/
rowDOM.appendChild(buttonDOM);
});
/**
* Appending row to keyboard
*/
this.keyboardDOM.appendChild(rowDOM);
});
/**
* Calling onRender
*/
this.onRender();
if(!this.initialized){
/**
* Ensures that onInit is only called once per instantiation
*/
this.initialized = true;
/**
* Calling onInit
*/
this.onInit();
}
}
}
export default SimpleKeyboard;
</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
+61
View File
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../">
<title data-ice="title">src/lib/index.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/index.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import SimpleKeyboard from &apos;./components/Keyboard&apos;;
export default SimpleKeyboard;
</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../../">
<title data-ice="title">src/lib/services/KeyboardLayout.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/services/KeyboardLayout.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">/**
* Keyboard Layout Service
*/
class KeyboardLayout {
/**
* Get default simple-keyboard layout
* @return {object} The default layout (US-QWERTY)
*/
static getDefaultLayout = () =&gt; {
return {
&apos;default&apos;: [
&apos;` 1 2 3 4 5 6 7 8 9 0 - = {bksp}&apos;,
&apos;{tab} q w e r t y u i o p [ ] \\&apos;,
&apos;{lock} a s d f g h j k l ; \&apos; {enter}&apos;,
&apos;{shift} z x c v b n m , . / {shift}&apos;,
&apos;.com @ {space}&apos;
],
&apos;shift&apos;: [
&apos;~ ! @ # $ % ^ &amp; * ( ) _ + {bksp}&apos;,
&apos;{tab} Q W E R T Y U I O P { } |&apos;,
&apos;{lock} A S D F G H J K L : &quot; {enter}&apos;,
&apos;{shift} Z X C V B N M &lt; &gt; ? {shift}&apos;,
&apos;.com @ {space}&apos;
]
}
}
}
export default KeyboardLayout;</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../../">
<title data-ice="title">src/lib/services/PhysicalKeyboard.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/services/PhysicalKeyboard.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">/**
* Physical Keyboard Service
*/
class PhysicalKeyboard {
/**
* Creates an instance of the PhysicalKeyboard service
*/
constructor(simpleKeyboardInstance){
/**
* @type {object} A simple-keyboard instance
*/
this.simpleKeyboardInstance = simpleKeyboardInstance;
this.initKeyboardListener();
}
/**
* Initializes key event listeners
*/
initKeyboardListener = () =&gt; {
// Adding button style on keydown
document.addEventListener(&quot;keydown&quot;, (event) =&gt; {
if(this.simpleKeyboardInstance.options.physicalKeyboardHighlight){
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
this.simpleKeyboardInstance.dispatch(instance =&gt; {
let buttonDOM = instance.getButtonElement(buttonPressed) || instance.getButtonElement(`{${buttonPressed}}`);
if(buttonDOM){
buttonDOM.style.backgroundColor = this.simpleKeyboardInstance.options.physicalKeyboardHighlightBgColor || &quot;#9ab4d0&quot;;
buttonDOM.style.color = this.simpleKeyboardInstance.options.physicalKeyboardHighlightTextColor || &quot;white&quot;;
}
});
}
});
// Removing button style on keyup
document.addEventListener(&quot;keyup&quot;, (event) =&gt; {
if(this.simpleKeyboardInstance.options.physicalKeyboardHighlight){
let buttonPressed = this.getSimpleKeyboardLayoutKey(event);
this.simpleKeyboardInstance.dispatch(instance =&gt; {
let buttonDOM = instance.getButtonElement(buttonPressed) || instance.getButtonElement(`{${buttonPressed}}`);
if(buttonDOM){
buttonDOM.removeAttribute(&quot;style&quot;);
}
});
}
});
}
/**
* Transforms a KeyboardEvent&apos;s &quot;key.code&quot; string into a simple-keyboard layout format
* @param {object} event The KeyboardEvent
*/
getSimpleKeyboardLayoutKey = (event) =&gt; {
if(this.simpleKeyboardInstance.options.debug){
console.log(event);
}
let output;
if(
event.code.includes(&quot;Numpad&quot;) ||
event.code.includes(&quot;Shift&quot;) ||
event.code.includes(&quot;Space&quot;) ||
event.code.includes(&quot;Backspace&quot;) ||
event.code.includes(&quot;Control&quot;) ||
event.code.includes(&quot;Alt&quot;) ||
event.code.includes(&quot;Meta&quot;)
){
output = event.code;
} else {
output = event.key;
}
/**
* If button is not uppercase, casting to lowercase
*/
if (
output !== output.toUpperCase() ||
(event.code[0] === &quot;F&quot; &amp;&amp; Number.isInteger(Number(event.code[1])) &amp;&amp; event.code.length &lt;= 3)
) {
output = output.toLowerCase();
}
return output;
}
}
export default PhysicalKeyboard;</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
@@ -0,0 +1,400 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../../">
<title data-ice="title">src/lib/services/Utilities.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/services/Utilities.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">/**
* Utility Service
*/
class Utilities {
/**
* Creates an instance of the Utility service
*/
constructor(simpleKeyboardInstance){
/**
* @type {object} A simple-keyboard instance
*/
this.simpleKeyboardInstance = simpleKeyboardInstance;
}
/**
* Adds default classes to a given button
*
* @param {string} button The button&apos;s layout name
* @return {string} The classes to be added to the button
*/
getButtonClass = button =&gt; {
let buttonTypeClass = (button.includes(&quot;{&quot;) &amp;&amp; button.includes(&quot;}&quot;) &amp;&amp; button !== &apos;{//}&apos;) ? &quot;functionBtn&quot; : &quot;standardBtn&quot;;
let buttonWithoutBraces = button.replace(&quot;{&quot;, &quot;&quot;).replace(&quot;}&quot;, &quot;&quot;);
let buttonNormalized = &apos;&apos;;
if(buttonTypeClass !== &quot;standardBtn&quot;)
buttonNormalized = ` hg-button-${buttonWithoutBraces}`;
return `hg-${buttonTypeClass}${buttonNormalized}`;
}
/**
* Default button display labels
*/
getDefaultDiplay(){
return {
&apos;{bksp}&apos;: &apos;backspace&apos;,
&apos;{backspace}&apos;: &apos;backspace&apos;,
&apos;{enter}&apos;: &apos;&lt; enter&apos;,
&apos;{shift}&apos;: &apos;shift&apos;,
&apos;{shiftleft}&apos;: &apos;shift&apos;,
&apos;{shiftright}&apos;: &apos;shift&apos;,
&apos;{alt}&apos;: &apos;alt&apos;,
&apos;{s}&apos;: &apos;shift&apos;,
&apos;{tab}&apos;: &apos;tab&apos;,
&apos;{lock}&apos;: &apos;caps&apos;,
&apos;{capslock}&apos;: &apos;caps&apos;,
&apos;{accept}&apos;: &apos;Submit&apos;,
&apos;{space}&apos;: &apos; &apos;,
&apos;{//}&apos;: &apos; &apos;,
&quot;{esc}&quot;: &quot;esc&quot;,
&quot;{escape}&quot;: &quot;esc&quot;,
&quot;{f1}&quot;: &quot;f1&quot;,
&quot;{f2}&quot;: &quot;f2&quot;,
&quot;{f3}&quot;: &quot;f3&quot;,
&quot;{f4}&quot;: &quot;f4&quot;,
&quot;{f5}&quot;: &quot;f5&quot;,
&quot;{f6}&quot;: &quot;f6&quot;,
&quot;{f7}&quot;: &quot;f7&quot;,
&quot;{f8}&quot;: &quot;f8&quot;,
&quot;{f9}&quot;: &quot;f9&quot;,
&quot;{f10}&quot;: &quot;f10&quot;,
&quot;{f11}&quot;: &quot;f11&quot;,
&quot;{f12}&quot;: &quot;f12&quot;,
&apos;{numpaddivide}&apos;: &apos;/&apos;,
&apos;{numlock}&apos;: &apos;lock&apos;,
&quot;{arrowup}&quot;: &quot;&#x2191;&quot;,
&quot;{arrowleft}&quot;: &quot;&#x2190;&quot;,
&quot;{arrowdown}&quot;: &quot;&#x2193;&quot;,
&quot;{arrowright}&quot;: &quot;&#x2192;&quot;,
&quot;{prtscr}&quot;: &quot;print&quot;,
&quot;{scrolllock}&quot;: &quot;scroll&quot;,
&quot;{pause}&quot;: &quot;pause&quot;,
&quot;{insert}&quot;: &quot;ins&quot;,
&quot;{home}&quot;: &quot;home&quot;,
&quot;{pageup}&quot;: &quot;up&quot;,
&quot;{delete}&quot;: &quot;del&quot;,
&quot;{end}&quot;: &quot;end&quot;,
&quot;{pagedown}&quot;: &quot;down&quot;,
&quot;{numpadmultiply}&quot;: &quot;*&quot;,
&quot;{numpadsubtract}&quot;: &quot;-&quot;,
&quot;{numpadadd}&quot;: &quot;+&quot;,
&quot;{numpadenter}&quot;: &quot;enter&quot;,
&quot;{period}&quot;: &quot;.&quot;,
&quot;{numpaddecimal}&quot;: &quot;.&quot;,
&quot;{numpad0}&quot;: &quot;0&quot;,
&quot;{numpad1}&quot;: &quot;1&quot;,
&quot;{numpad2}&quot;: &quot;2&quot;,
&quot;{numpad3}&quot;: &quot;3&quot;,
&quot;{numpad4}&quot;: &quot;4&quot;,
&quot;{numpad5}&quot;: &quot;5&quot;,
&quot;{numpad6}&quot;: &quot;6&quot;,
&quot;{numpad7}&quot;: &quot;7&quot;,
&quot;{numpad8}&quot;: &quot;8&quot;,
&quot;{numpad9}&quot;: &quot;9&quot;,
};
}
/**
* Returns the display (label) name for a given button
*
* @param {string} button The button&apos;s layout name
* @param {object} display The provided display option
* @param {boolean} mergeDisplay Whether the provided param value should be merged with the default one.
*/
getButtonDisplayName = (button, display, mergeDisplay) =&gt; {
if(mergeDisplay){
display = Object.assign({}, this.getDefaultDiplay(), display);
} else {
display = display || this.getDefaultDiplay();
}
return display[button] || button;
}
/**
* Returns the updated input resulting from clicking a given button
*
* @param {string} button The button&apos;s layout name
* @param {string} input The input string
* @param {object} options The simple-keyboard options object
* @param {number} caretPos The cursor&apos;s current position
*/
getUpdatedInput = (button, input, options, caretPos) =&gt; {
let output = input;
if((button === &quot;{bksp}&quot; || button === &quot;{backspace}&quot;) &amp;&amp; output.length &gt; 0){
output = this.removeAt(output, caretPos);
} else if(button === &quot;{space}&quot;)
output = this.addStringAt(output, &quot; &quot;, caretPos);
else if(button === &quot;{tab}&quot; &amp;&amp; !(typeof options.tabCharOnTab === &quot;boolean&quot; &amp;&amp; options.tabCharOnTab === false)){
output = this.addStringAt(output, &quot;\t&quot;, caretPos);
} else if((button === &quot;{enter}&quot; || button === &quot;{numpadenter}&quot;) &amp;&amp; options.newLineOnEnter)
output = this.addStringAt(output, &quot;\n&quot;, caretPos);
else if(button.includes(&quot;numpad&quot;) &amp;&amp; Number.isInteger(Number(button[button.length - 2]))){
output = this.addStringAt(output, button[button.length - 2], caretPos);
}
else if(button === &quot;{numpaddivide}&quot;)
output = this.addStringAt(output, &apos;/&apos;, caretPos);
else if(button === &quot;{numpadmultiply}&quot;)
output = this.addStringAt(output, &apos;*&apos;, caretPos);
else if(button === &quot;{numpadsubtract}&quot;)
output = this.addStringAt(output, &apos;-&apos;, caretPos);
else if(button === &quot;{numpadadd}&quot;)
output = this.addStringAt(output, &apos;+&apos;, caretPos);
else if(button === &quot;{numpaddecimal}&quot;)
output = this.addStringAt(output, &apos;.&apos;, caretPos);
else if(button === &quot;{&quot; || button === &quot;}&quot;)
output = this.addStringAt(output, button, caretPos);
else if(!button.includes(&quot;{&quot;) &amp;&amp; !button.includes(&quot;}&quot;))
output = this.addStringAt(output, button, caretPos);
return output;
}
/**
* Moves the cursor position by a given amount
*
* @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.
*/
updateCaretPos = (length, minus) =&gt; {
if(minus){
if(this.simpleKeyboardInstance.caretPosition &gt; 0)
this.simpleKeyboardInstance.caretPosition = this.simpleKeyboardInstance.caretPosition - length
} else {
this.simpleKeyboardInstance.caretPosition = this.simpleKeyboardInstance.caretPosition + length;
}
}
/**
* Adds a string to the input at a given position
*
* @param {string} source The source input
* @param {string} string The string to add
* @param {number} position The (cursor) position where the string should be added
*/
addStringAt(source, string, position){
let output;
if(this.simpleKeyboardInstance.options.debug){
console.log(&quot;Caret at:&quot;, position);
}
if(!position &amp;&amp; position !== 0){
output = source + string;
} else {
output = [source.slice(0, position), string, source.slice(position)].join(&apos;&apos;);
/**
* Avoid caret position change when maxLength is set
*/
if(!this.isMaxLengthReached()){
this.updateCaretPos(string.length);
}
}
return output;
}
/**
* Removes an amount of characters at a given position
*
* @param {string} source The source input
* @param {number} position The (cursor) position from where the characters should be removed
*/
removeAt(source, position){
if(this.simpleKeyboardInstance.caretPosition === 0){
return source;
}
let output;
let prevTwoChars;
let emojiMatched;
let emojiMatchedReg = /([\uD800-\uDBFF][\uDC00-\uDFFF])/g;
/**
* Emojis are made out of two characters, so we must take a custom approach to trim them.
* For more info: https://mathiasbynens.be/notes/javascript-unicode
*/
if(position &amp;&amp; position &gt;= 0){
prevTwoChars = source.substring(position - 2, position)
emojiMatched = prevTwoChars.match(emojiMatchedReg);
if(emojiMatched){
output = source.substr(0, (position - 2)) + source.substr(position);
this.updateCaretPos(2, true);
} else {
output = source.substr(0, (position - 1)) + source.substr(position);
this.updateCaretPos(1, true);
}
} else {
prevTwoChars = source.slice(-2);
emojiMatched = prevTwoChars.match(emojiMatchedReg);
if(emojiMatched){
output = source.slice(0, -2);
this.updateCaretPos(2, true);
} else {
output = source.slice(0, -1);
this.updateCaretPos(1, true);
}
}
return output;
}
/**
* 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){
let maxLength = options.maxLength;
let currentInput = inputObj[options.inputName];
let condition = currentInput.length === maxLength;
if(
/**
* If pressing this button won&apos;t add more characters
* We exit out of this limiter function
*/
updatedInput.length &lt;= currentInput.length
){
return false;
}
if(Number.isInteger(maxLength)){
if(options.debug){
console.log(&quot;maxLength (num) reached:&quot;, condition);
}
if(condition){
/**
* @type {boolean} Boolean value that shows whether maxLength has been reached
*/
this.maxLengthReached = true;
return true;
} else {
this.maxLengthReached = false;
return false;
}
}
if(typeof maxLength === &quot;object&quot;){
let condition = currentInput.length === maxLength[options.inputName];
if(options.debug){
console.log(&quot;maxLength (obj) reached:&quot;, condition);
}
if(condition){
this.maxLengthReached = true;
return true;
} else {
this.maxLengthReached = false;
return false;
}
}
}
/**
* Gets the current value of maxLengthReached
*/
isMaxLengthReached = () =&gt; {
return Boolean(this.maxLengthReached);
}
/**
* Transforms an arbitrary string to camelCase
*
* @param {string} string The string to transform.
*/
camelCase = (string) =&gt; {
return string.toLowerCase().trim().split(/[.\-_\s]/g).reduce((string, word) =&gt; string + word[0].toUpperCase() + word.slice(1));
};
/**
* Counts the number of duplicates in a given array
*
* @param {Array} array The haystack to search in
* @param {string} value The needle to search for
*/
countInArray = (array, value) =&gt; {
return array.reduce((n, x) =&gt; n + (x === value), 0);
}
}
export default Utilities;</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
+165
View File
@@ -0,0 +1,165 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base data-ice="baseUrl" href="../../../../">
<title data-ice="title">src/lib/tests/TestUtility.js | simple-keyboard</title>
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
<script src="script/prettify/prettify.js"></script>
<script src="script/manual.js"></script>
<meta name="description" content="On-screen Javascript Virtual Keyboard"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="simple-keyboard"><meta property="twitter:description" content="On-screen Javascript Virtual Keyboard"></head>
<body class="layout-container" data-ice="rootContainer">
<header>
<a href="./">Home</a>
<a href="identifiers.html">Reference</a>
<a href="source.html">Source</a>
<div class="search-box">
<span>
<img src="./image/search.png">
<span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
</span>
<ul class="search-result"></ul>
</div>
<a style="position:relative; top:3px;" href="https://github.com/hodgef/simple-keyboard"><img width="20px" src="./image/github.png"></a></header>
<nav class="navigation" data-ice="nav"><div>
<ul>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#demo">demo</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/demo/App.js~App.html">App</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-components">lib/components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/components/Keyboard.js~SimpleKeyboard.html">SimpleKeyboard</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-services">lib/services</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/KeyboardLayout.js~KeyboardLayout.html">KeyboardLayout</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/PhysicalKeyboard.js~PhysicalKeyboard.html">PhysicalKeyboard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/services/Utilities.js~Utilities.html">Utilities</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#lib-tests">lib/tests</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/lib/tests/TestUtility.js~TestUtility.html">TestUtility</a></span></span></li>
</ul>
</div>
</nav>
<div class="content" data-ice="content"><h1 data-ice="title">src/lib/tests/TestUtility.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">/**
* Test Utility Functions
*/
export default class TestUtility {
/**
* Set&apos;s a basic DOM structure to test in
*/
setDOM = (divClass) =&gt; {
this.clear();
const div = document.createElement(&apos;div&apos;);
div.className += divClass || &quot;simple-keyboard&quot;;
document.body.appendChild(div);
}
/**
* Clears DOM structure
*/
clear = () =&gt; {
document.body.innerHTML = &quot;&quot;;
}
/**
* Test if standard buttons respect maxLength and do input a value
*/
testLayoutStdButtons = (keyboard) =&gt; {
let stdBtnCount = 0;
let fullInput = &apos;&apos;;
this.iterateButtons((button) =&gt; {
let label = button.getAttribute(&quot;data-skbtn&quot;);
if(label.includes(&quot;{&quot;))
return false;
// Click all standard buttons, respects maxLength
button.onclick();
// Recording fullInput, bypasses maxLength
fullInput = keyboard.utilities.getUpdatedInput(label, fullInput, keyboard.options, null);
stdBtnCount += label.length;
});
/**
* Check if maxLength is respected
*/
if(
(
typeof keyboard.options.maxLength === &quot;object&quot; &amp;&amp;
keyboard.getInput().length !== keyboard.options.maxLength[keyboard.options.layoutName]
) ||
(
typeof keyboard.options.maxLength !== &quot;object&quot; &amp;&amp;
keyboard.getInput().length !== keyboard.options.maxLength
)
)
throw new Error(&quot;MAX_LENGTH_ISSUE&quot;);
else
console.log(&quot;MAX_LENGTH PASSED:&quot;, keyboard.options.layoutName, keyboard.getInput().length, keyboard.options.maxLength);
/**
* Check if all standard buttons are inputting something
* (Regardless of maxLength)
*/
if(stdBtnCount !== fullInput.length)
throw new Error(&quot;STANDARD_BUTTONS_ISSUE&quot;);
else
console.log(&quot;STANDARD_BUTTONS PASSED:&quot;, keyboard.options.layoutName, stdBtnCount, fullInput.length);
}
/**
* Test if function buttons are interactive (have an onclick)
*/
testLayoutFctButtons = (callback) =&gt; {
let fctBtnCount = 0;
let fctBtnHasOnclickCount = 0;
this.iterateButtons((button) =&gt; {
let label = button.getAttribute(&quot;data-skbtn&quot;);
if(!label.includes(&quot;{&quot;) &amp;&amp; !label.includes(&quot;}&quot;))
return false;
fctBtnCount++;
if(button.onclick){
button.onclick();
fctBtnHasOnclickCount++;
}
callback(fctBtnCount, fctBtnHasOnclickCount);
});
}
/**
* Iterates on the keyboard buttons
*/
iterateButtons = (callback, selector) =&gt; {
let rows = document.body.querySelector(selector || &apos;.simple-keyboard&apos;).children;
Array.from(rows).forEach(row =&gt; {
Array.from(row.children).forEach((button) =&gt; {
callback(button);
});
});
}
}</code></pre>
</div>
<footer class="footer">
Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>
<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>