Switch to a diffrent keyboard and timepicker
these should hopefully work better on mobile browsers
This commit is contained in:
parent
b6dfba391c
commit
0eada46ece
27 changed files with 8074 additions and 3643 deletions
3
web_app/css/external/images/disabled.svg
vendored
Normal file
3
web_app/css/external/images/disabled.svg
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="#111">
|
||||||
|
<path d="M7.4 4.4V2.5c0-1.4-1.1-2.5-2.5-2.5c-1.4 0-2.5 1.1-2.5 2.5v1.9 c-0.7 0-1.2 0.5-1.2 1.2v3.1C1.3 9.4 1.8 10 2.5 10h4.9c0.7 0 1.2-0.6 1.2-1.2V5.6 C8.7 4.9 8.1 4.4 7.4 4.4z M5.3 7.4v1.0c0 0.2-0.1 0.3-0.3 0.3c-0.2 0-0.3-0.1-0.3-0.3V7.4 c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3 0.3-0.6 0.6-0.6c0.3 0 0.6 0.3 0.6 0.6 C5.6 7.1 5.5 7.3 5.3 7.4z M6.2 4.4H3.7V2.5c0-0.7 0.5-1.2 1.2-1.2c0.7 0 1.2 0.6 1.2 1.2 V4.4z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 489 B |
3
web_app/css/external/images/enabled.svg
vendored
Normal file
3
web_app/css/external/images/enabled.svg
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="#111">
|
||||||
|
<path d="M8.7,4.4H7.5H5.0v-1.9c0-1.4-1.1-2.5-2.5-2.5c-1.4,0-2.5,1.1-2.5,2.5v1.9h1.2 v-1.9c0-0.7,0.6-1.2,1.2-1.2s1.2,0.6,1.2,1.2v1.9c-0.7,0-1.2,0.6-1.2,1.2V8.8 c0,0.7,0.6,1.2,1.2,1.2h5.0C9.4,10,10,9.4,10,8.8V5.6C10,5.0,9.4,4.4,8.8,4.4z M6.6,7.4v1.0 c0,0.2-0.1,0.3-0.3,0.3S6.0,8.6,6.0,8.4V7.4c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3,0.3-0.6,0.6-0.6 S6.9,6.6,6.9,6.9C6.9,7.1,6.8,7.3,6.6,7.4z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 468 B |
15
web_app/css/external/images/keyboard.svg
vendored
Normal file
15
web_app/css/external/images/keyboard.svg
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="fill:#888">
|
||||||
|
<g>
|
||||||
|
<path style="fill:none;stroke:#888" d="M 0.5,4.5 15.5,4.5 15.5,15.5 0.5,15.5 Z"></path>
|
||||||
|
<rect width="2" height="2" x="2" y="6"></rect>
|
||||||
|
<rect width="2" height="2" x="5" y="6"></rect>
|
||||||
|
<rect width="2" height="2" x="8" y="6"></rect>
|
||||||
|
<path d="m 11,6 3,0 0,5 -2,0 0,-3 -1,0 z"></path>
|
||||||
|
<rect width="2" height="2" x="12" y="12"></rect>
|
||||||
|
<rect width="6" height="2" x="5" y="12"></rect>
|
||||||
|
<rect width="2" height="2" x="9" y="9"></rect>
|
||||||
|
<rect width="2" height="2" x="6" y="9"></rect>
|
||||||
|
<rect width="2" height="2" x="2" y="12"></rect>
|
||||||
|
<rect width="3" height="2" x="2" y="9"></rect>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 686 B |
106
web_app/css/external/jquery.keypad.css
vendored
106
web_app/css/external/jquery.keypad.css
vendored
|
@ -1,106 +0,0 @@
|
||||||
/* Main style sheet for jQuery Keypad v2.0.0 */
|
|
||||||
button.keypad-trigger {
|
|
||||||
width: 25px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
img.keypad-trigger {
|
|
||||||
margin: 2px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.keypad-popup, .keypad-inline, .keypad-key, .keypad-special {
|
|
||||||
font-family: Arial,Helvetica,sans-serif;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
.keypad-popup {
|
|
||||||
display: none;
|
|
||||||
z-index: 10;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #000;
|
|
||||||
border: 1px solid #888;
|
|
||||||
-moz-border-radius: 0.25em;
|
|
||||||
-webkit-border-radius: 0.25em;
|
|
||||||
border-radius: 0.25em;
|
|
||||||
}
|
|
||||||
.keypad-keyentry {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.keypad-inline {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #888;
|
|
||||||
-moz-border-radius: 0.25em;
|
|
||||||
-webkit-border-radius: 0.25em;
|
|
||||||
border-radius: 0.25em;
|
|
||||||
}
|
|
||||||
.keypad-disabled {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 100;
|
|
||||||
background-color: white;
|
|
||||||
opacity: 0.5;
|
|
||||||
filter: alpha(opacity=50);
|
|
||||||
}
|
|
||||||
.keypad-rtl {
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
.keypad-prompt {
|
|
||||||
clear: both;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.keypad-prompt.ui-widget-header {
|
|
||||||
margin: 0.125em;
|
|
||||||
}
|
|
||||||
.keypad-row {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.keypad-space {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0.125em;
|
|
||||||
width: 2em;
|
|
||||||
}
|
|
||||||
.keypad-half-space {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0.125em 0.0625em;
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
.keypad-key, .keypad-special {
|
|
||||||
margin: 0.125em;
|
|
||||||
padding: 0em;
|
|
||||||
width: 2em;
|
|
||||||
background-color: #f4f4f4;
|
|
||||||
-moz-border-radius: 0.25em;
|
|
||||||
-webkit-border-radius: 0.25em;
|
|
||||||
border-radius: 0.25em;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.keypad-key[disabled] {
|
|
||||||
border: 0.125em outset;
|
|
||||||
}
|
|
||||||
.keypad-key-down {
|
|
||||||
}
|
|
||||||
.keypad-special {
|
|
||||||
width: 4.25em;
|
|
||||||
}
|
|
||||||
.keypad-spacebar {
|
|
||||||
width: 13.25em;
|
|
||||||
}
|
|
||||||
.keypad-tab {
|
|
||||||
width: 2em;
|
|
||||||
}
|
|
||||||
.keypad-clear, .keypad-back, .keypad-close, .keypad-shift {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.keypad-clear {
|
|
||||||
background-color: #a00;
|
|
||||||
}
|
|
||||||
.keypad-back {
|
|
||||||
background-color: #00a;
|
|
||||||
}
|
|
||||||
.keypad-close {
|
|
||||||
background-color: #0a0;
|
|
||||||
}
|
|
||||||
.keypad-shift {
|
|
||||||
background-color: #0aa;
|
|
||||||
}
|
|
72
web_app/css/external/jquery.timepicker.css
vendored
Executable file
72
web_app/css/external/jquery.timepicker.css
vendored
Executable file
|
@ -0,0 +1,72 @@
|
||||||
|
.ui-timepicker-wrapper {
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 150px;
|
||||||
|
width: 6.5em;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);
|
||||||
|
-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);
|
||||||
|
box-shadow:0 5px 10px rgba(0,0,0,0.2);
|
||||||
|
outline: none;
|
||||||
|
z-index: 10001;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration {
|
||||||
|
width: 13em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
|
||||||
|
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
|
||||||
|
width: 11em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-duration {
|
||||||
|
margin-left: 5px; color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list:hover .ui-timepicker-duration {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list li {
|
||||||
|
padding: 3px 0 3px 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #000;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list:hover .ui-timepicker-selected {
|
||||||
|
background: #fff; color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.ui-timepicker-selected,
|
||||||
|
.ui-timepicker-list li:hover,
|
||||||
|
.ui-timepicker-list .ui-timepicker-selected:hover {
|
||||||
|
background: #1980EC; color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.ui-timepicker-selected .ui-timepicker-duration,
|
||||||
|
.ui-timepicker-list li:hover .ui-timepicker-duration {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list li.ui-timepicker-disabled,
|
||||||
|
.ui-timepicker-list li.ui-timepicker-disabled:hover,
|
||||||
|
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
|
||||||
|
color: #888;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-timepicker-list li.ui-timepicker-disabled:hover,
|
||||||
|
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
170
web_app/css/external/keyboard-basic.css
vendored
Normal file
170
web_app/css/external/keyboard-basic.css
vendored
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/* *** keyboard light theme ***
|
||||||
|
for when jQuery UI themes are not being used
|
||||||
|
See http://jsfiddle.net/Mottie/jsh0377k/
|
||||||
|
*/
|
||||||
|
.ui-keyboard {
|
||||||
|
/* adjust overall keyboard size using "font-size" */
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
/* include the following setting to place the
|
||||||
|
keyboard at the bottom of the browser window */
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
left: 0px;
|
||||||
|
top: auto;
|
||||||
|
bottom: 0px;
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
.ui-keyboard {
|
||||||
|
background: #fefefe;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.ui-keyboard-button {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
margin: 1px;
|
||||||
|
min-width: 3em;
|
||||||
|
height: 3em;
|
||||||
|
line-height: 3em;
|
||||||
|
vertical-align: top;
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
-webkit-box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
-moz-box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
background: white;
|
||||||
|
background-image: -moz-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||||
|
background-image: -webkit-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||||
|
background-image: -o-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||||
|
background-image: -ms-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
-moz-user-focus: ignore;
|
||||||
|
}
|
||||||
|
.ui-keyboard-button span {
|
||||||
|
/* padding: 0; margin: 0; white-space:nowrap; display: inline-block; */
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 1.2em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
/* make action keys extra-wide */
|
||||||
|
.ui-keyboard-actionkey:not(.ui-keyboard-dec) {
|
||||||
|
min-width: 6em;
|
||||||
|
}
|
||||||
|
.ui-keyboard-space {
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
.ui-keyboard-actionkey:not(.ui-keyboard-dec) span {
|
||||||
|
font-size: 0.8em;
|
||||||
|
position: relative;
|
||||||
|
top: -1em;
|
||||||
|
left: -1.6em;
|
||||||
|
}
|
||||||
|
.ui-keyboard-placeholder {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
/* disabled or readonly inputs, or use input[disabled='disabled'] { color: #f00; } */
|
||||||
|
.ui-keyboard-nokeyboard {
|
||||||
|
color: #888;
|
||||||
|
border-color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* combo key styling - toggles diacritics on/off */
|
||||||
|
.ui-keyboard-button.ui-keyboard-combo.ui-state-default {
|
||||||
|
border-color: #375a7f;
|
||||||
|
}
|
||||||
|
/* (in)valid inputs */
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-valid-input {
|
||||||
|
background: #008966;
|
||||||
|
border-color: #007f5e;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-valid-input:hover {
|
||||||
|
background: #00bc8c;
|
||||||
|
border-color: #00bc8c;
|
||||||
|
}
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-invalid-input {
|
||||||
|
background: #d62c1a;
|
||||||
|
border-color: #cd2a19;;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-invalid-input:hover {
|
||||||
|
background: #e74c3c;
|
||||||
|
border-color: #e74c3c;
|
||||||
|
}
|
||||||
|
/* unlocked icon (keyboard enabled) */
|
||||||
|
button.ui-keyboard-toggle span {
|
||||||
|
width: .9em;
|
||||||
|
height: .9em;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
/* light theme unlocked icon - fill: #111 */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==');
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-toggle span {
|
||||||
|
/* dark theme unlocked icon - fill: #eee */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==');
|
||||||
|
}
|
||||||
|
/* locked icon (keyboard disabled) */
|
||||||
|
button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||||
|
/* light theme locked icon - fill: #111 */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=');
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||||
|
/* dark theme locked icon - fill: #eee */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=');
|
||||||
|
}
|
||||||
|
.ui-keyboard.ui-keyboard-disabled button:not(.ui-keyboard-toggle), .ui-keyboard.ui-keyboard-disabled input {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Alt-Keys Popup extension ***/
|
||||||
|
/* clickable overlay on top of keyboard to hide the popup */
|
||||||
|
.ui-keyboard-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
/* the actual popup styling, class names from the css.container option are also added */
|
||||||
|
.ui-keyboard-popup {
|
||||||
|
display: inline-block;
|
||||||
|
/* default buttons are 2em wide + .1em margin on either side (set in .ui-keyboard-button definition);
|
||||||
|
so use multiples of 2.2em for a max-width if you don't want any extra white space on the sides,
|
||||||
|
e.g. 5 buttons * 2.2em = 11em, 6 buttons * 2.2em = 13.2em, etc */
|
||||||
|
max-width: 22em;
|
||||||
|
/* 10 buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Extender keyboard extension ***/
|
||||||
|
div.ui-keyboard-extender {
|
||||||
|
float: right;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
button.ui-keyboard-extender span {
|
||||||
|
width: .9em;
|
||||||
|
height: .9em;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
/* light theme extender icon - fill: #111 */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6IzExMSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzExMSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+');
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-extender span {
|
||||||
|
/* dark theme extender icon - fill: #eee */
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6I2VlZSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2VlZSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+');
|
||||||
|
}
|
44
web_app/css/external/keyboard-previewkeyset.css
vendored
Normal file
44
web_app/css/external/keyboard-previewkeyset.css
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/* basic previewKeyset setup - modify as desired */
|
||||||
|
.ui-keyboard-keyset .ui-keyboard-button {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
/* show mini-shift keyset with normal keyset */
|
||||||
|
.ui-keyboard-keyset-normal .ui-keyboard-button::after {
|
||||||
|
content: attr(data-shift);
|
||||||
|
font-size: 0.6em;
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
left: 2px;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
/* show mini-normal keyset with shift keyset */
|
||||||
|
.ui-keyboard-keyset-shift .ui-keyboard-button::after {
|
||||||
|
content: attr(data-normal);
|
||||||
|
font-size: 0.6em;
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
left: 2px;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
/* show mini-normal keyset with alt keyset */
|
||||||
|
.ui-keyboard-keyset-alt .ui-keyboard-button::after {
|
||||||
|
content: attr(data-alt-shift);
|
||||||
|
font-size: 0.6em;
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
left: 2px;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
||||||
|
/* show mini-alt-shift keyset with alt-shift keyset */
|
||||||
|
.ui-keyboard-keyset-alt-shift .ui-keyboard-button::after {
|
||||||
|
content: attr(data-alt);
|
||||||
|
font-size: 0.6em;
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
left: 2px;
|
||||||
|
z-index: 200;
|
||||||
|
}
|
161
web_app/css/external/keyboard.css
vendored
Normal file
161
web_app/css/external/keyboard.css
vendored
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/* keyboard - jQuery UI Widget */
|
||||||
|
.ui-keyboard { padding: .3em; position: absolute; left: 0; top: 0; z-index: 16000; }
|
||||||
|
.ui-keyboard-has-focus { z-index: 16001; }
|
||||||
|
.ui-keyboard div { font-size: 1.1em; }
|
||||||
|
.ui-keyboard-button { height: 2em; min-width: 2em; margin: .1em; cursor: pointer; overflow: hidden; line-height: 2em; -moz-user-focus: ignore; }
|
||||||
|
.ui-keyboard-button span { padding: 0; margin: 0; white-space:nowrap; display: inline-block; }
|
||||||
|
.ui-keyboard-button-endrow { clear: left; }
|
||||||
|
.ui-keyboard-space { width: 15em; }
|
||||||
|
/* see http://nicolasgallagher.com/another-css-image-replacement-technique/ */
|
||||||
|
.ui-keyboard-space span, .ui-keyboard-empty span { font: 0/0 a; text-shadow: none; color: transparent; }
|
||||||
|
.ui-keyboard-preview-wrapper { text-align: center; position: relative; overflow: hidden; }
|
||||||
|
/* width is calculated in IE, since 99% = 99% full browser width =( */
|
||||||
|
.ui-keyboard-preview { text-align: left; margin: 0 0 3px 0; display: inline; width: 99%;}
|
||||||
|
.ui-keyboard-keyset { text-align: center; white-space: nowrap; }
|
||||||
|
.ui-keyboard-input { text-align: left; }
|
||||||
|
.ui-keyboard-input-current { -moz-box-shadow: 0 0 5px #4d90fe; -webkit-box-shadow: 0 0 5px #4d90fe; box-shadow: 0 0 5px #4d90fe; }
|
||||||
|
.ui-keyboard-placeholder { color: #888; }
|
||||||
|
/* disabled or readonly inputs, or use input[disabled='disabled'] { color: #f00; } */
|
||||||
|
.ui-keyboard-nokeyboard { color: #888; border-color: #888; }
|
||||||
|
.ui-keyboard-spacer { display: inline-block; width: 1px; height: 0; cursor: default; }
|
||||||
|
|
||||||
|
.ui-keyboard-NBSP span, .ui-keyboard-ZWSP span, .ui-keyboard-ZWNJ span, .ui-keyboard-ZWJ span, .ui-keyboard-LRM span, .ui-keyboard-RLM span {
|
||||||
|
font-size: 0.5em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* combo key styling - toggles diacritics on/off */
|
||||||
|
.ui-keyboard-button.ui-keyboard-combo.ui-state-default { border-color: #ffaf0f; }
|
||||||
|
|
||||||
|
/* (in)valid inputs */
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-valid-input { border-color: #0c0; background: #080; color: #fff; }
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-valid-input:hover { background: #0a0; }
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-invalid-input { border-color: #c00; background: #800; color: #fff; opacity: 0.5; filter: alpha(opacity=50); }
|
||||||
|
button.ui-keyboard-accept.ui-keyboard-invalid-input:hover { background: #a00; }
|
||||||
|
|
||||||
|
/*** Caret extension definition ***/
|
||||||
|
/* margin-top => is added to the caret height (top & bottom) */
|
||||||
|
.ui-keyboard-caret { background: #c00; width: 1px; margin-top: 3px; }
|
||||||
|
|
||||||
|
/*** jQuery Mobile definitions ***/
|
||||||
|
/* jQuery Mobile styles - need wider buttons because of font size and text-overflow:ellipsis */
|
||||||
|
div.ui-body.ui-keyboard button.ui-keyboard-button.ui-btn { padding: 0.5em 1em; border-color: transparent; }
|
||||||
|
.ui-body .ui-keyboard-button { width: 3em; height: 3em; display: inline-block; }
|
||||||
|
.ui-body .ui-keyboard-widekey { width: 5.5em; }
|
||||||
|
.ui-body .ui-keyboard-space { width: 15em; }
|
||||||
|
.ui-body .ui-keyboard-space span { visibility: hidden; } /* hides the ellipsis */
|
||||||
|
.ui-body .ui-keyboard-keyset { line-height: 0.5em; }
|
||||||
|
.ui-body input.ui-input-text, .ui-body textarea.ui-input-text { width: 95%; }
|
||||||
|
|
||||||
|
/* over-ride padding set by mobile ui theme - needed because the mobile script wraps button text with several more spans */
|
||||||
|
.ui-body .ui-btn-inner { height: 2em; padding: 0.2em 0; margin: 0; }
|
||||||
|
.ui-body .ui-btn { margin: 0; font-size: 13px; } /* mobile default size is 13px */
|
||||||
|
|
||||||
|
/* override Bootstrap excessive button padding */
|
||||||
|
button.ui-keyboard-button.btn { padding: 1px 6px; }
|
||||||
|
|
||||||
|
/* enable/disable icons */
|
||||||
|
button.ui-keyboard-toggle span {
|
||||||
|
width: .8em;
|
||||||
|
height: .8em;
|
||||||
|
display: inline-block;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
/* unlocked icon (keyboard enabled) */
|
||||||
|
button.ui-keyboard-toggle span {
|
||||||
|
/* light theme unlocked icon - fill: #111 */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==);
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-toggle span {
|
||||||
|
/* dark theme unlocked icon - fill: #eee */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* locked icon (keyboard disabled) */
|
||||||
|
button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||||
|
/* light theme locked icon - fill: #111 */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=);
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||||
|
/* dark theme locked icon - fill: #eee */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-keyboard.ui-keyboard-disabled button:not(.ui-keyboard-toggle),
|
||||||
|
.ui-keyboard.ui-keyboard-disabled input {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Alt-Keys Popup extension ***/
|
||||||
|
/* clickable overlay on top of keyboard to hide the popup */
|
||||||
|
.ui-keyboard-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
/* the actual popup styling, class names from the css.container option are also added */
|
||||||
|
.ui-keyboard-popup {
|
||||||
|
display: inline-block;
|
||||||
|
/* default buttons are 2em wide + .1em margin on either side (set in .ui-keyboard-button definition);
|
||||||
|
so use multiples of 2.2em for a max-width if you don't want any extra white space on the sides,
|
||||||
|
e.g. 5 buttons * 2.2em = 11em, 6 buttons * 2.2em = 13.2em, etc */
|
||||||
|
max-width: 22em; /* 10 buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Extender keyboard extension ***/
|
||||||
|
div.ui-keyboard-extender { float: right; margin-left: 5px; }
|
||||||
|
button.ui-keyboard-extender span {
|
||||||
|
width: .9em;
|
||||||
|
height: .9em;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
/* light theme extender icon - fill: #111 */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6IzExMSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzExMSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+);
|
||||||
|
}
|
||||||
|
.ui-keyboard-dark-theme button.ui-keyboard-extender span {
|
||||||
|
/* dark theme extender icon - fill: #eee */
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6I2VlZSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2VlZSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media Queries (optimized for jQuery UI themes; may be slightly off in jQuery Mobile themes) */
|
||||||
|
/* 240 x 320 (small phone) */
|
||||||
|
@media all and (max-width: 319px) {
|
||||||
|
.ui-keyboard div { font-size: 9px; }
|
||||||
|
.ui-keyboard .ui-keyboard-input { font-size: 12px; }
|
||||||
|
/* I don't own an iPhone so I have no idea how small this really is... is it even clickable with your finger? */
|
||||||
|
.ui-body .ui-btn { margin: 0; font-size: 9px; }
|
||||||
|
.ui-body .ui-keyboard-button { width: 1.8em; height: 2.5em; }
|
||||||
|
.ui-body .ui-keyboard-widekey { width: 4em; }
|
||||||
|
.ui-body .ui-keyboard-space { width: 8em; }
|
||||||
|
.ui-body .ui-btn-inner { height: 2.5em; padding: 0.3em 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 320 x 480 (iPhone) */
|
||||||
|
@media all and (min-width: 320px) and (max-width: 479px) {
|
||||||
|
.ui-keyboard div { font-size: 9px; }
|
||||||
|
.ui-keyboard .ui-keyboard-input { font-size: 14px; }
|
||||||
|
/* I don't own an iPhone so I have no idea how small this really is... is it even clickable with your finger? */
|
||||||
|
.ui-body .ui-btn { margin: 0; font-size: 11px; }
|
||||||
|
.ui-body .ui-keyboard-button { width: 1.8em; height: 3em; }
|
||||||
|
.ui-body .ui-keyboard-widekey { width: 4.5em; }
|
||||||
|
.ui-body .ui-keyboard-space { width: 10em; }
|
||||||
|
.ui-body .ui-btn-inner { height: 3em; padding: 0.7em 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 480 x 640 (small tablet) */
|
||||||
|
@media all and (min-width: 480px) and (max-width: 767px) {
|
||||||
|
.ui-keyboard div { font-size: 13px; }
|
||||||
|
.ui-keyboard .ui-keyboard-input { font-size: 14px; }
|
||||||
|
.ui-body .ui-btn { margin: 0; font-size: 10px; }
|
||||||
|
.ui-body .ui-keyboard-button { height: 2.5em; }
|
||||||
|
.ui-body .ui-btn-inner { height: 2.5em; padding: 0.5em 0; }
|
||||||
|
}
|
2251
web_app/js/external/jquery-ui-timepicker-addon.js
vendored
2251
web_app/js/external/jquery-ui-timepicker-addon.js
vendored
File diff suppressed because it is too large
Load diff
1959
web_app/js/external/jquery.keyboard.extension-all.js
vendored
Normal file
1959
web_app/js/external/jquery.keyboard.extension-all.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
209
web_app/js/external/jquery.keyboard.extension-altkeyspopup.js
vendored
Normal file
209
web_app/js/external/jquery.keyboard.extension-altkeyspopup.js
vendored
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Alt Key Popup v1.0.1 *//*
|
||||||
|
* for Keyboard v1.18+ only (7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;( function( factory ) {
|
||||||
|
if ( typeof define === 'function' && define.amd ) {
|
||||||
|
define( [ 'jquery' ], factory );
|
||||||
|
} else if ( typeof module === 'object' && typeof module.exports === 'object' ) {
|
||||||
|
module.exports = factory( require( 'jquery' ) );
|
||||||
|
} else {
|
||||||
|
factory( jQuery );
|
||||||
|
}
|
||||||
|
}( function( $ ) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var $keyboard = $.keyboard;
|
||||||
|
|
||||||
|
$.extend( $keyboard.css, {
|
||||||
|
altKeyPopup : 'ui-keyboard-popup',
|
||||||
|
altKeyOverlay : 'ui-keyboard-overlay'
|
||||||
|
});
|
||||||
|
|
||||||
|
$keyboard.altKeys = $.extend({
|
||||||
|
a : '\u00e5 \u00e6 \u0101 \u0103 \u0105 \u00e0 \u00e1 \u00e2 \u00e3 \u00e4', // å æ ā ă ą à á â ã ä
|
||||||
|
A : '\u00c5 \u00c6 \u0100 \u0102 \u0104 \u00c0 \u00c1 \u00c2 \u00c3 \u00c4', // Å Æ Ā Ă Ą À Á Â Ã Ä
|
||||||
|
c : '\u00e7 \u0107 \u0109 \u010b \u010d', // ç ć ĉ ċ č
|
||||||
|
C : '\u00c7 \u0106 \u0108 \u010a \u010c', // Ç Ć Ĉ Ċ Č
|
||||||
|
d : '\u010f \u00f0 \u010f', // ď ð ď
|
||||||
|
D : '\u010e \u00d0 \u010e', // Ď Ð Ď
|
||||||
|
e : '\u0117 \u0119 \u0115 \u011b \u0259 \u00e8 \u00e9 \u00ea \u00eb \u0113', // ė ę ĕ ě ə è é ê ë ē
|
||||||
|
E : '\u0116 \u0118 \u0114 \u011a \u018e \u00c8 \u00c9 \u00ca \u00cb \u0112', // Ė Ę Ĕ Ě Ǝ È É Ê Ë Ē
|
||||||
|
g : '\u0123 \u011f \u011d \u0121', // ģ ğ ĝ ġ
|
||||||
|
G : '\u0122 \u011e \u011c \u0120', // Ģ Ğ Ĝ Ġ
|
||||||
|
h : '\u0125 \u0127', // ĥ ħ
|
||||||
|
H : '\u0124 \u0126', // Ĥ Ħ
|
||||||
|
i : '\u0131 \u012f \u012b \u00ef \u00ee \u00ed \u00ec \u0129 \u012d', // ı į ī ï î í ì ĩ ĭ
|
||||||
|
I : '\u0130 \u012e \u012a \u00cf \u00ce \u00cd \u00cc \u0128 \u012c', // İ Į Ī Ï Î Í Ì Ĩ Ĭ
|
||||||
|
j : '\u0135', // ĵ
|
||||||
|
J : '\u0134', // Ĵ
|
||||||
|
k : '\u0137', // ķ
|
||||||
|
K : '\u0136', // Ķ
|
||||||
|
l : '\u0141 \u013d \u013b \u0139 \u013f', // Ł Ľ Ļ Ĺ Ŀ
|
||||||
|
L : '\u0142 \u013e \u013c \u013a \u0140', // ł ľ ļ ĺ ŀ
|
||||||
|
n : '\u0149 \u0148 \u0146 \u0144 \u00f1', // ʼn ň ņ ń ñ
|
||||||
|
N : '\u0149 \u0147 \u0145 \u0143 \u00d1', // ʼn Ň Ņ Ń Ñ
|
||||||
|
o : '\u0153 \u0151 \u00f8 \u00f6 \u00f5 \u00f4 \u00f3 \u00f2 \u014d \u014f', // œ ő ø ö õ ô ó ò ō ŏ
|
||||||
|
O : '\u0152 \u0150 \u00d8 \u00d6 \u00d5 \u00d4 \u00d3 \u00d2 \u014c \u014e', // Œ Ő Ø Ö Õ Ô Ó Ò Ō Ŏ
|
||||||
|
r : '\u0155 \u0159 \u0157', // ŕ ř ŗ
|
||||||
|
R : '\u0154 \u0158 \u0156', // Ŕ Ř Ŗ
|
||||||
|
s : '\u015b \u0161 \u015f \u00df \u00a7 \u015d', // ś š ş ß § ŝ
|
||||||
|
S : '\u015a \u0160 \u015e \u1e9e \u00a7 \u015c', // Ś Š Ş ẞ § Ŝ
|
||||||
|
t : '\u00fe \u0165 \u021b \u0163 \u0167', // þ ť ț ţ ŧ
|
||||||
|
T : '\u00de \u0164 \u021a \u0162 \u0166', // Þ Ť Ț Ţ Ŧ
|
||||||
|
u : '\u0173 \u0171 \u016f \u016b \u00fc \u00fb \u00fa \u00f9 \u0169 \u016d', // ų ű ů ū ü û ú ù ũ ŭ
|
||||||
|
U : '\u0172 \u0170 \u016e \u016a \u00dc \u00db \u00da \u00d9 \u0168 \u016c', // Ų Ű Ů Ū Ü Û Ú Ù Ũ Ŭ
|
||||||
|
w : '\u0175', // ŵ
|
||||||
|
W : '\u0174', // Ŵ
|
||||||
|
y : '\u00fd', // ý
|
||||||
|
Y : '\u00dd', // Ý
|
||||||
|
z : '\u017a \u017c \u017e', // ź ż ž
|
||||||
|
Z : '\u0179 \u017b \u017d', // Ź Ż Ž
|
||||||
|
'!' : '\u00a1', // ¡
|
||||||
|
'$' : '\u20ac \u00a3 \u00a4 \u00a5 \u00a2 \u20a1 \u20b1 \u20a9 \u20b9 \u20aa \u20ad \u20ae \u20a6 \u20a4', // €£¤¥¢₡₱₩₹₪₭₮₦₤
|
||||||
|
'?' : '\u00bf', // ¿
|
||||||
|
"'" : '\u3008 \u300c \u300e \u201c', // 〈 「 『 “
|
||||||
|
'"' : '\u3009 \u300d \u300f \u201d', // 〉 」 』 ”
|
||||||
|
'(' : '\u300a \u3010 \u3014', // « 【 〔
|
||||||
|
')' : '\u300b \u3011 \u3015' // » 】 〕
|
||||||
|
}, $keyboard.altKeys );
|
||||||
|
|
||||||
|
$.fn.addAltKeyPopup = function( options ) {
|
||||||
|
//Set the default values, use comma to separate the settings, example:
|
||||||
|
var defaults = {
|
||||||
|
// time to hold down a button in ms to trigger a popup
|
||||||
|
holdTime : 500,
|
||||||
|
// event triggered when popup is visible
|
||||||
|
popupVisible : 'popup-visible'
|
||||||
|
};
|
||||||
|
return this.each( function() {
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var namespace,
|
||||||
|
base = $( this ).data( 'keyboard' );
|
||||||
|
if (!base) { return; }
|
||||||
|
|
||||||
|
// variables
|
||||||
|
base.altkeypopup_options = $.extend( {}, defaults, options );
|
||||||
|
namespace = base.altkeypopup_namespace = base.namespace + 'AltKeyPopup';
|
||||||
|
base.extensionNamespace.push( namespace );
|
||||||
|
|
||||||
|
base.altkeypopup_setup = function() {
|
||||||
|
var timer,
|
||||||
|
start = 'mousedown touchstart '.split( ' ' ).join( namespace + ' ' ),
|
||||||
|
end = 'mouseup touchend touchcancel '.split( ' ' ).join( namespace + ' ' );
|
||||||
|
|
||||||
|
// force disable repeat keys
|
||||||
|
base.options.repeatRate = 0;
|
||||||
|
|
||||||
|
// add hold key functionality for popups
|
||||||
|
base.$allKeys
|
||||||
|
.bind( start, function() {
|
||||||
|
clearTimeout( timer );
|
||||||
|
var $key = $( this ),
|
||||||
|
key = $key.attr( 'data-action' ) || '';
|
||||||
|
if ( key in $keyboard.altKeys ) {
|
||||||
|
timer = setTimeout( function() {
|
||||||
|
base.altKeyPopup_popup( key, $key );
|
||||||
|
}, base.altkeypopup_options.holdTime );
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bind( end, function() {
|
||||||
|
clearTimeout( timer );
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
base.altKeyPopup_popup = function( key, $key ) {
|
||||||
|
var keys, $keys, positionHoriz, positionVert, top,
|
||||||
|
kbcss = $keyboard.css,
|
||||||
|
kbWidth = base.$keyboard.outerWidth(),
|
||||||
|
kbHeight = base.$keyboard.outerHeight();
|
||||||
|
// overlay keyboard
|
||||||
|
base.altKeyPopup_$overlay = $( '<div class="' + kbcss.altKeyOverlay + '" />' )
|
||||||
|
.css({
|
||||||
|
width : kbWidth,
|
||||||
|
height: kbHeight
|
||||||
|
})
|
||||||
|
.appendTo( base.$keyboard )
|
||||||
|
.bind( 'click touchstart', function() {
|
||||||
|
base.altKeyPopup_$overlay.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove character added when key was initially pressed, unless it was a backspace key
|
||||||
|
if ( key !== 'bksp' ) {
|
||||||
|
$keyboard.keyaction.bksp( base );
|
||||||
|
}
|
||||||
|
|
||||||
|
// make popup; use the same classes as the keyboard container
|
||||||
|
$keys = $( '<div class="' + kbcss.altKeyPopup + ' ' + base.options.css.container + '" />' );
|
||||||
|
keys = $keyboard.altKeys[ key ].split( /\s+/ );
|
||||||
|
// make popup keys
|
||||||
|
base.buildRow( $keys, 0, keys, [] );
|
||||||
|
// add popup & add bindings
|
||||||
|
$keys
|
||||||
|
.appendTo( base.altKeyPopup_$overlay )
|
||||||
|
.children()
|
||||||
|
.bind( 'mousedown touchstart', function( event ) {
|
||||||
|
var action = $( this ).attr( 'data-action' );
|
||||||
|
// make action keys work in popup
|
||||||
|
if ( action in $keyboard.keyaction && $.isFunction($keyboard.keyaction[ action ] ) ) {
|
||||||
|
$keyboard.keyaction[ action ]( base, this, event );
|
||||||
|
} else {
|
||||||
|
base.insertText( action );
|
||||||
|
}
|
||||||
|
base.altKeyPopup_$overlay.remove();
|
||||||
|
})
|
||||||
|
.bind( 'mouseover mouseleave', function( event ){
|
||||||
|
$( this ).toggleClass( base.options.css.buttonHover, event.type === 'mouseover' );
|
||||||
|
});
|
||||||
|
|
||||||
|
// position popup within $keyboard container
|
||||||
|
positionHoriz = $key.position().left - ( $keys.outerWidth() / 2 ) + ( $key.outerWidth() / 2 );
|
||||||
|
if ( positionHoriz + $keys.outerWidth() > kbWidth ) {
|
||||||
|
positionHoriz = kbWidth - $keys.outerWidth();
|
||||||
|
if ( positionHoriz < 0 ) {
|
||||||
|
$keys.css({
|
||||||
|
width : kbWidth,
|
||||||
|
height : 'auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
positionVert = $key.position().top - $key.outerHeight() - 5;
|
||||||
|
top = base.$keyboard.find( '.' + kbcss.keySet ).position().top;
|
||||||
|
if ( positionVert + $keys.outerHeight() > kbHeight ) {
|
||||||
|
positionVert = kbHeight - $keys.outerHeight();
|
||||||
|
if ( positionVert < top ) {
|
||||||
|
$keys.css({
|
||||||
|
height : kbHeight - top,
|
||||||
|
width : 'auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$keys.css({
|
||||||
|
position : 'relative',
|
||||||
|
top : positionVert < top ? top : positionVert,
|
||||||
|
left : positionHoriz < 0 ? 0 : positionHoriz
|
||||||
|
});
|
||||||
|
// trigger popup visible event
|
||||||
|
base.$el.trigger( base.altkeypopup_options.popupVisible, [ base ] );
|
||||||
|
};
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if ( base.options.alwaysOpen && base.isVisible() ) {
|
||||||
|
base.altkeypopup_setup();
|
||||||
|
}
|
||||||
|
// setup altkey popup
|
||||||
|
base.$el
|
||||||
|
.unbind( $keyboard.events.kbBeforeVisible + namespace )
|
||||||
|
.bind( $keyboard.events.kbBeforeVisible + namespace, function() {
|
||||||
|
base.altkeypopup_setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
147
web_app/js/external/jquery.keyboard.extension-autocomplete.js
vendored
Normal file
147
web_app/js/external/jquery.keyboard.extension-autocomplete.js
vendored
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Autocomplete v1.9.2 *//*
|
||||||
|
* for Keyboard v1.18+ only (8/17/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to get
|
||||||
|
* the jQuery UI Autocomplete widget to work seamlessly
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery
|
||||||
|
* jQuery UI & css
|
||||||
|
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .autocomplete(options)
|
||||||
|
* .addAutoComplete();
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options) // keyboard plugin
|
||||||
|
* .autocomplete(options) // jQuery UI autocomplete
|
||||||
|
* .addAutoComplete(); // this keyboard extension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
'use strict';
|
||||||
|
$.fn.addAutocomplete = function(options){
|
||||||
|
var defaults = {
|
||||||
|
position : {
|
||||||
|
of : null,
|
||||||
|
my : 'right top',
|
||||||
|
at : 'left top',
|
||||||
|
collision: 'flip'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.each(function(){
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o, base = $(this).data('keyboard');
|
||||||
|
if (!base) { return; }
|
||||||
|
|
||||||
|
base.autocomplete_namespace = base.namespace + 'Autocomplete';
|
||||||
|
base.extensionNamespace.push( base.autocomplete_namespace );
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
base.autocomplete_init = function(){
|
||||||
|
|
||||||
|
// variables
|
||||||
|
o = base.autocomplete_options = $.extend( true, {}, defaults, options );
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible()) {
|
||||||
|
base.autocomplete_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.$el
|
||||||
|
.unbind(base.autocomplete_namespace)
|
||||||
|
.bind($.keyboard.events.kbVisible + base.autocomplete_namespace,function(){
|
||||||
|
base.autocomplete_setup();
|
||||||
|
})
|
||||||
|
.bind($.keyboard.events.kbChange + base.autocomplete_namespace,function(){
|
||||||
|
if (base.hasAutocomplete && base.isVisible()) {
|
||||||
|
base.$el
|
||||||
|
.val(base.$preview.val())
|
||||||
|
.trigger('keydown.autocomplete');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bind($.keyboard.events.kbHidden + base.autocomplete_namespace, function(){
|
||||||
|
base.$el.autocomplete('close');
|
||||||
|
})
|
||||||
|
.bind('autocompleteopen' + base.autocomplete_namespace, function() {
|
||||||
|
if (base.hasAutocomplete){
|
||||||
|
// default to $keyboard if no position.of defined
|
||||||
|
var position = $.extend( {}, o.position );
|
||||||
|
// refresh base.$keyboard (it gets destroyed after use); fixes #382
|
||||||
|
position.of = position.of || base.$keyboard;
|
||||||
|
// reposition autocomplete window next to the keyboard
|
||||||
|
base.$autocomplete.menu.element.position( position );
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bind('autocompleteselect' + base.autocomplete_namespace, function(e, ui){
|
||||||
|
var v = ui.item && ui.item.value || '';
|
||||||
|
if (base.hasAutocomplete && v !== ''){
|
||||||
|
base.$preview
|
||||||
|
.val( v )
|
||||||
|
.focus();
|
||||||
|
// see issue #95 - thanks banku!
|
||||||
|
base.last.start = v.length;
|
||||||
|
base.last.end = v.length;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// set up after keyboard is visible
|
||||||
|
base.autocomplete_setup = function(){
|
||||||
|
// look for autocomplete
|
||||||
|
base.$autocomplete = base.$el.data('autocomplete') || base.$el.data('uiAutocomplete') || base.$el.data('ui-autocomplete');
|
||||||
|
base.hasAutocomplete = (typeof(base.$autocomplete) === 'undefined') ? false : (base.$autocomplete.options.disabled) ? false : true;
|
||||||
|
// only bind to keydown once
|
||||||
|
if (base.hasAutocomplete) {
|
||||||
|
base.$preview.bind('keydown' + base.autocomplete_namespace, function(e){
|
||||||
|
// send keys to the autocomplete widget (arrow, pageup/down, etc)
|
||||||
|
base.$el.val( base.$preview.val() ).triggerHandler(e);
|
||||||
|
});
|
||||||
|
base.$allKeys.bind('mouseup mousedown mouseleave touchstart touchend touchcancel '.split(' ').join(base.autocomplete_namespace + ' '),function(event){
|
||||||
|
clearTimeout( base.$autocomplete.searching );
|
||||||
|
var evt = event;
|
||||||
|
base.$autocomplete.searching = setTimeout(function() {
|
||||||
|
// only search if the value has changed
|
||||||
|
if ( base.$autocomplete.term !== base.$autocomplete.element.val() ) {
|
||||||
|
base.$autocomplete.selectedItem = null;
|
||||||
|
base.$autocomplete.search( null, evt );
|
||||||
|
}
|
||||||
|
}, base.$autocomplete.options.delay );
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
base.origEscClose = base.escClose;
|
||||||
|
|
||||||
|
// replace original function with this one
|
||||||
|
base.escClose = function(e){
|
||||||
|
// prevent selecting an item in autocomplete from closing keyboard
|
||||||
|
if ( base.hasAutocomplete && (e.target.id === 'ui-active-menuitem' || $(e.target).closest('ul').hasClass('ui-autocomplete')) ) { return; }
|
||||||
|
base.origEscClose(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
base.autocomplete_init();
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
197
web_app/js/external/jquery.keyboard.extension-caret.js
vendored
Normal file
197
web_app/js/external/jquery.keyboard.extension-caret.js
vendored
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Virtual Caret v1.1.3 (beta) *//*
|
||||||
|
* for Keyboard v1.18+ only (9/24/2015)
|
||||||
|
* modified from https://github.com/component/textarea-caret-position
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* CSS changes
|
||||||
|
* NOTE: caret margin-top => is added to the caret height (top & bottom)
|
||||||
|
* .ui-keyboard-preview-wrapper { position: relative; overflow: hidden; }
|
||||||
|
* .ui-keyboard-caret { background: red; width: 1px; margin-top: 3px; }
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;( function( factory ) {
|
||||||
|
if ( typeof define === 'function' && define.amd ) {
|
||||||
|
define( [ 'jquery' ], factory );
|
||||||
|
} else if ( typeof module === 'object' && typeof module.exports === 'object' ) {
|
||||||
|
module.exports = factory( require( 'jquery' ) );
|
||||||
|
} else {
|
||||||
|
factory( jQuery );
|
||||||
|
}
|
||||||
|
}( function( $ ) {
|
||||||
|
'use strict';
|
||||||
|
var $keyboard = $.keyboard;
|
||||||
|
|
||||||
|
$keyboard.firefox = typeof window.mozInnerScreenX !== 'undefined';
|
||||||
|
|
||||||
|
$.extend( $keyboard.css, {
|
||||||
|
caret : 'ui-keyboard-caret'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.fn.addCaret = function( options ) {
|
||||||
|
var defaults = {
|
||||||
|
caretClass : '',
|
||||||
|
// *** for future use ***
|
||||||
|
// data-attribute containing the character(s) next to the caret
|
||||||
|
charAttr : 'data-character',
|
||||||
|
// # character(s) next to the caret (can be negative for RTL)
|
||||||
|
charIndex : 1,
|
||||||
|
offsetX : 0,
|
||||||
|
offsetY : 0,
|
||||||
|
adjustHt : 0
|
||||||
|
};
|
||||||
|
return this.each( function() {
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o, namespace,
|
||||||
|
kbevents = $keyboard.events,
|
||||||
|
base = $( this ).data( 'keyboard' );
|
||||||
|
if ( !base ) { return; }
|
||||||
|
|
||||||
|
// variables
|
||||||
|
o = base.caret_options = $.extend( {}, defaults, options );
|
||||||
|
namespace = base.caret_namespace = base.namespace + 'caret';
|
||||||
|
base.extensionNamespace.push( namespace );
|
||||||
|
|
||||||
|
// modified from https://github.com/component/textarea-caret-position
|
||||||
|
// The properties that we copy into a mirrored div.
|
||||||
|
// Note that some browsers, such as Firefox,
|
||||||
|
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
|
||||||
|
// so we have to do every single property specifically.
|
||||||
|
base.textareaCaretProperties = [
|
||||||
|
'direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY',
|
||||||
|
'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderStyle',
|
||||||
|
'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
|
||||||
|
'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust',
|
||||||
|
'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration',
|
||||||
|
'letterSpacing', 'wordSpacing', 'tabSize', 'MozTabSize'
|
||||||
|
];
|
||||||
|
|
||||||
|
base.caret_setup = function() {
|
||||||
|
var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' ),
|
||||||
|
style = 'position:absolute;visibility:hidden;top:-9999em;left:-9999em;' +
|
||||||
|
'white-space:pre-wrap;' +
|
||||||
|
( base.preview.nodeName === 'INPUT' ? '' : 'word-wrap:break-word;' );
|
||||||
|
// add mirrored div
|
||||||
|
base.caret_$div = $( '<div class="ui-keyboard-mirror-div" style="' + style + '">' )
|
||||||
|
.appendTo( base.$keyboard );
|
||||||
|
|
||||||
|
// remove caret, just-in-case
|
||||||
|
if (base.$caret) { base.$caret.remove(); }
|
||||||
|
base.$caret = $( '<div class="ui-keyboard-caret ' + o.caretClass + '" style="position:absolute;">' )
|
||||||
|
.insertAfter( base.$preview );
|
||||||
|
|
||||||
|
base.$el
|
||||||
|
.unbind( kbevents.kbChange + namespace )
|
||||||
|
.bind( kbevents.kbChange + namespace, function() {
|
||||||
|
base.findCaretPos();
|
||||||
|
});
|
||||||
|
base.$preview
|
||||||
|
.unbind( events )
|
||||||
|
.bind( events, function() {
|
||||||
|
base.findCaretPos();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// getCaretCoordinatesFn = function (element, position, recalculate) {
|
||||||
|
base.findCaretPos = function() {
|
||||||
|
if ( !base.caret_$div ) { return; }
|
||||||
|
var style, computed, margin, pos, position, txt, span, offset,
|
||||||
|
element = base.preview,
|
||||||
|
isInput = element.nodeName === 'INPUT',
|
||||||
|
div = base.caret_$div[0];
|
||||||
|
|
||||||
|
style = div.style;
|
||||||
|
// getComputedStyle with null - fixes #384
|
||||||
|
computed = window.getComputedStyle ? getComputedStyle( element, null ) : element.currentStyle;
|
||||||
|
// get caret position based on text-direction
|
||||||
|
pos = $keyboard.caret( base.$preview );
|
||||||
|
position = Math[ computed.direction === 'ltr' ? 'max' : 'min' ]( pos.start, pos.end );
|
||||||
|
|
||||||
|
// transfer the element's properties to the div
|
||||||
|
base.textareaCaretProperties.forEach(function ( prop ) {
|
||||||
|
style[ prop ] = computed[ prop ];
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( $keyboard.firefox ) {
|
||||||
|
// Firefox adds 2 pixels to the padding - https://bugzilla.mozilla.org/show_bug.cgi?id=753662
|
||||||
|
style.width = parseInt( computed.width, 10 ) - 2 + 'px';
|
||||||
|
// Firefox lies about the overflow property for textareas:
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=984275
|
||||||
|
if ( element.scrollHeight > parseInt( computed.height, 10 ) ) {
|
||||||
|
style.overflowY = 'scroll';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
|
||||||
|
// style.overflow = 'hidden';
|
||||||
|
style.width = parseInt( isInput ? element.scrollWidth : computed.width, 10 ) +
|
||||||
|
// add 50 extra px if it's an input to prevent wrap
|
||||||
|
( isInput ? 50 : 0 ) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
div.textContent = element.value.substring( 0, position );
|
||||||
|
// the second special handling for input type="text" vs textarea:
|
||||||
|
// spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
|
||||||
|
if ( element.nodeName === 'INPUT' ) {
|
||||||
|
div.textContent = div.textContent.replace( /\x20/g, '\xa0' );
|
||||||
|
}
|
||||||
|
|
||||||
|
span = document.createElement( 'span' );
|
||||||
|
// Wrapping must be replicated *exactly*, including when a long word gets
|
||||||
|
// onto the next line, with whitespace at the end of the line before (#7).
|
||||||
|
// The *only* reliable way to do that is to copy the *entire* rest of the
|
||||||
|
// textarea's content into the <span> created at the caret position.
|
||||||
|
// for inputs, just '.' would be enough, but why bother?
|
||||||
|
// || because a completely empty faux span doesn't render at all
|
||||||
|
span.textContent = element.value.substring( position ) || '.';
|
||||||
|
div.appendChild( span );
|
||||||
|
|
||||||
|
offset = $(span).position();
|
||||||
|
base.caretPos = {
|
||||||
|
top: offset.top + parseInt( computed.borderTopWidth, 10 ) + o.offsetY,
|
||||||
|
left: offset.left + parseInt( computed.borderLeftWidth, 10 ) + o.offsetX
|
||||||
|
};
|
||||||
|
|
||||||
|
// make caret height = font-size + any margin-top x2 added by the css
|
||||||
|
margin = parseInt( base.$caret.css( 'margin-top' ), 10 );
|
||||||
|
style = Math.round( parseFloat( base.$preview.css( 'font-size' ) ) + margin * 2 ) + o.adjustHt;
|
||||||
|
offset = base.$preview.position();
|
||||||
|
|
||||||
|
base.$caret.css({
|
||||||
|
top: offset.top - element.scrollTop + base.caretPos.top - margin,
|
||||||
|
left: offset.left - element.scrollLeft + base.caretPos.left,
|
||||||
|
height: style
|
||||||
|
});
|
||||||
|
txt = element.value.substring( position, position + o.charIndex ).replace(/\s/, '\xa0' ) || '\xa0';
|
||||||
|
base.$caret.attr( o.charAttr, txt );
|
||||||
|
};
|
||||||
|
|
||||||
|
// setup caret when keyboard is visible
|
||||||
|
base.$el
|
||||||
|
.unbind( namespace )
|
||||||
|
.bind( kbevents.kbBeforeVisible + namespace, function() {
|
||||||
|
base.caret_setup();
|
||||||
|
})
|
||||||
|
.bind( kbevents.kbVisible + namespace, function() {
|
||||||
|
base.findCaretPos();
|
||||||
|
})
|
||||||
|
.bind( kbevents.kbHidden + namespace, function() {
|
||||||
|
// unbind events in case usePreview: false; see #376
|
||||||
|
var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' );
|
||||||
|
base.$preview.unbind( events );
|
||||||
|
base.$caret.remove();
|
||||||
|
base.$caret = null;
|
||||||
|
base.caret_$div = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if ( base.options.alwaysOpen && base.isVisible() ) {
|
||||||
|
base.caret_setup();
|
||||||
|
base.findCaretPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
119
web_app/js/external/jquery.keyboard.extension-extender.js
vendored
Normal file
119
web_app/js/external/jquery.keyboard.extension-extender.js
vendored
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Extender v1.0.1 *//*
|
||||||
|
* for Keyboard v1.18+ only (7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var $keyboard = $.keyboard;
|
||||||
|
|
||||||
|
$.extend( $keyboard.css, {
|
||||||
|
extender : 'ui-keyboard-extender'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend( $keyboard.layouts, {
|
||||||
|
'numpad' : {
|
||||||
|
'normal' : [
|
||||||
|
'{clear} / * -',
|
||||||
|
'7 8 9 +',
|
||||||
|
'4 5 6 %',
|
||||||
|
'1 2 3 =',
|
||||||
|
'0 {dec} {left} {right}'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// add {extender} keyaction
|
||||||
|
$.extend( $keyboard.keyaction, {
|
||||||
|
extender: function( base, el ) {
|
||||||
|
base.extender_toggle();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.fn.addExtender = function(options) {
|
||||||
|
//Set the default values, use comma to separate the settings, example:
|
||||||
|
var defaults = {
|
||||||
|
layout : 'numpad',
|
||||||
|
showing : false,
|
||||||
|
reposition : true
|
||||||
|
};
|
||||||
|
return this.each( function() {
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o, base = $( this ).data( 'keyboard' );
|
||||||
|
if (!base) { return; }
|
||||||
|
|
||||||
|
// variables
|
||||||
|
o = base.extender_options = $.extend( {}, defaults, options );
|
||||||
|
$.extend( true, $keyboard.language.en, {
|
||||||
|
display : {
|
||||||
|
'extender' : ' '
|
||||||
|
}
|
||||||
|
});
|
||||||
|
base.extender_namespace = base.namespace + 'extender';
|
||||||
|
base.extensionNamespace.push( base.extender_namespace );
|
||||||
|
|
||||||
|
base.extender_setup = function() {
|
||||||
|
var $kb,
|
||||||
|
layout = o.layout;
|
||||||
|
if ( typeof $keyboard.builtLayouts[ layout ] === 'undefined' ) {
|
||||||
|
base.buildKeyboard( layout );
|
||||||
|
}
|
||||||
|
$kb = $keyboard.builtLayouts[ layout ].$keyboard.find( '.' + $keyboard.css.keySet + '-normal' ).clone();
|
||||||
|
$kb
|
||||||
|
.removeClass()
|
||||||
|
.removeAttr('name')
|
||||||
|
.addClass( $keyboard.css.extender )
|
||||||
|
.toggle( o.showing )
|
||||||
|
.children('button')
|
||||||
|
.removeAttr('data-pos');
|
||||||
|
base.$keyboard.append( $kb );
|
||||||
|
base.extender_toggle( base.extender_options.showing );
|
||||||
|
base.bindKeys();
|
||||||
|
};
|
||||||
|
|
||||||
|
base.extender_toggle = function(set) {
|
||||||
|
base.extender_options.showing = typeof set === 'undefined' ? !base.extender_options.showing : set;
|
||||||
|
base.$keyboard
|
||||||
|
.find( 'div.' + $keyboard.css.extender )
|
||||||
|
.toggle( base.extender_options.showing )
|
||||||
|
.end()
|
||||||
|
.find( '.' + $keyboard.css.keySet )
|
||||||
|
.css('float', base.extender_options.showing ? 'left' : 'none')
|
||||||
|
.end()
|
||||||
|
.find( 'button.' + $keyboard.css.extender )
|
||||||
|
.toggleClass( base.options.css.buttonActive, base.extender_options.showing );
|
||||||
|
// force keyboard reposition
|
||||||
|
if (base.extender_options.reposition) {
|
||||||
|
$(window).trigger('resize');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible()) {
|
||||||
|
base.extender_setup();
|
||||||
|
}
|
||||||
|
// setup extender
|
||||||
|
base.$el
|
||||||
|
.unbind( $keyboard.events.kbBeforeVisible + base.extender_namespace )
|
||||||
|
.bind( $keyboard.events.kbBeforeVisible + base.extender_namespace, function() {
|
||||||
|
base.extender_setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
188
web_app/js/external/jquery.keyboard.extension-mobile.js
vendored
Normal file
188
web_app/js/external/jquery.keyboard.extension-mobile.js
vendored
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard for jQuery Mobile Themes v1.4.1 *//*
|
||||||
|
* for Keyboard v1.18+ (updated 7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to apply
|
||||||
|
* the necessary themes to make the keyboard compatible with
|
||||||
|
* jQuery Mobile themes
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery - http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js
|
||||||
|
* jQuery Mobile - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js
|
||||||
|
* jQuery Mobile themes - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .addMobile(mobile-options);
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options) // keyboard plugin
|
||||||
|
* .addMobile(mobile-options); // this keyboard extension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
$.fn.addMobile = function(options){
|
||||||
|
|
||||||
|
var o, defaults = {
|
||||||
|
// keyboard wrapper theme
|
||||||
|
container : { theme:'b', cssClass:'ui-body' },
|
||||||
|
// keyboard duplicate input
|
||||||
|
input : { theme:'b', cssClass:'' },
|
||||||
|
// theme added to all regular buttons
|
||||||
|
buttonMarkup : { theme:'b', cssClass:'ui-btn', shadow:'true', corners:'true' },
|
||||||
|
// theme added to all buttons when they are being hovered
|
||||||
|
buttonHover : { theme:'b', cssClass:'ui-btn-hover' },
|
||||||
|
// theme added to action buttons (e.g. tab, shift, accept, cancel);
|
||||||
|
// parameters here will override the settings in the buttonMarkup
|
||||||
|
buttonAction : { theme:'b', cssClass:'ui-btn-active' },
|
||||||
|
// theme added to button when it is active (e.g. shift is down)
|
||||||
|
// All extra parameters will be ignored
|
||||||
|
buttonActive : { theme:'b', cssClass:'ui-btn-active' },
|
||||||
|
// if more than 3 mobile themes are used, add them here
|
||||||
|
allThemes : 'a b c'
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.each(function(){
|
||||||
|
var base = $(this).data('keyboard');
|
||||||
|
|
||||||
|
// Stop if no keyboard attached or if jQuery Mobile isn't loaded
|
||||||
|
if (!base || typeof($.fn.textinput) === 'undefined') { return; }
|
||||||
|
|
||||||
|
base.mobile_options = o = $.extend(true, {}, defaults, options);
|
||||||
|
// create a list of theme class names to remove
|
||||||
|
base.mobile_themes = $.trim(
|
||||||
|
(' ' + o.allThemes).split(' ').join(' ' + o.buttonMarkup.cssClass + '-') +
|
||||||
|
(' ' + o.allThemes).split(' ').join(' ' + o.buttonAction.cssClass + '-') +
|
||||||
|
(' ' + o.allThemes).split(' ').join(' ' + o.buttonActive.cssClass + '-')
|
||||||
|
);
|
||||||
|
|
||||||
|
// save original action class because it gets removed when this theme switches swatches
|
||||||
|
if (typeof base.options.mobile_savedActiveClass === 'undefined') {
|
||||||
|
base.options.mobile_savedActiveClass = '' + base.options.css.buttonActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
base.mobile_init = function() {
|
||||||
|
|
||||||
|
var namespace = base.namespace + 'Mobile';
|
||||||
|
|
||||||
|
// Add theme to input - if not already done through the markup
|
||||||
|
$('.' + $.keyboard.css.input).textinput();
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible) {
|
||||||
|
base.mobile_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.extensionNamespace.push( namespace );
|
||||||
|
|
||||||
|
// Setup mobile theme on keyboard once it is visible.
|
||||||
|
// Note: There is a 10ms delay after the keyboard is displayed before it actually fires 'visible.keyboard'.
|
||||||
|
// Since we are restyling here, the user will experience FlashOfUnstyledContent (FOUC).
|
||||||
|
// This is avoided by first setting the visibility to hidden, then after the mobile styles are applied we
|
||||||
|
// set it visible.
|
||||||
|
base.$el
|
||||||
|
.unbind(namespace)
|
||||||
|
.bind($.keyboard.events.kbBeforeVisible + namespace, function() {
|
||||||
|
if ( base && base.el.active && base.$keyboard.length ) {
|
||||||
|
base.$keyboard.css('visibility', 'hidden');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bind($.keyboard.events.kbVisible + namespace, function() {
|
||||||
|
if ( base && base.el.active && base.$keyboard.length ) {
|
||||||
|
base.mobile_setup();
|
||||||
|
base.$keyboard.css('visibility', 'visible');
|
||||||
|
base.$preview.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
base.mobile_setup = function(){
|
||||||
|
var p,
|
||||||
|
kbcss = $.keyboard.css,
|
||||||
|
opts = base.options,
|
||||||
|
themes = base.mobile_themes;
|
||||||
|
|
||||||
|
base.mobile_$actionKeys = base.$keyboard.find('.' + base.options.css.buttonAction);
|
||||||
|
|
||||||
|
opts.css.buttonActive = opts.mobile_savedActiveClass + ' ' + base.modOptions(o.buttonActive, o.buttonMarkup);
|
||||||
|
|
||||||
|
base.$keyboard
|
||||||
|
// 'ui-body ui-body-a' classes to apply swatch theme
|
||||||
|
.addClass( base.modOptions(o.container, o.container) )
|
||||||
|
// preview input
|
||||||
|
.find('.' + kbcss.preview)
|
||||||
|
// removing 'ui-widget-content' will prevent jQuery UI theme from applying to the keyboard
|
||||||
|
.removeClass('ui-widget ui-widget-content')
|
||||||
|
.addClass( base.modOptions(o.input, o.input) ).end()
|
||||||
|
// apply jQuery Mobile button markup
|
||||||
|
// removed call to jQuery Mobile buttonMarkup function; replaced with base.modOptions
|
||||||
|
.find('button')
|
||||||
|
.removeClass( $.trim('ui-corner-all ui-state-default ' + themes) )
|
||||||
|
.addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) )
|
||||||
|
.not( base.mobile_$actionKeys )
|
||||||
|
.hover(function(){
|
||||||
|
$(this)
|
||||||
|
.removeClass( themes )
|
||||||
|
.addClass( base.modOptions(o.buttonHover, o.buttonMarkup) );
|
||||||
|
},function(){
|
||||||
|
$(this)
|
||||||
|
.removeClass( themes + ' ' + o.buttonHover.cssClass )
|
||||||
|
.addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) );
|
||||||
|
});
|
||||||
|
|
||||||
|
base.mobile_$actionKeys
|
||||||
|
.removeClass( themes )
|
||||||
|
.addClass( base.modOptions(o.buttonAction, o.buttonMarkup) );
|
||||||
|
|
||||||
|
// update keyboard width if preview is showing... after applying mobile theme
|
||||||
|
if (base.msie && base.$preview[0] !== base.el) {
|
||||||
|
base.$preview.hide();
|
||||||
|
base.$keyboard.css('width','');
|
||||||
|
base.width = base.$keyboard.outerWidth();
|
||||||
|
// add about 1em to input width for extra padding
|
||||||
|
base.$keyboard.width(base.width + parseInt(base.$preview.css('fontSize'),10));
|
||||||
|
base.$preview.width(base.width);
|
||||||
|
base.$preview.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust keyboard position after applying mobile theme
|
||||||
|
if ($.ui && $.ui.position) {
|
||||||
|
p = opts.position;
|
||||||
|
p.of = p.of || base.$el.data('keyboardPosition') || base.$el;
|
||||||
|
p.collision = p.collision || 'flipfit flipfit';
|
||||||
|
base.$keyboard.position(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
base.modOptions = function(t, btn){
|
||||||
|
var css = ' ' + ( t.cssClass || '' );
|
||||||
|
// Using this instead of the jQuery Mobile buttonMarkup because it is expecting <a>'s instead of <button>
|
||||||
|
// theme:'a', shadow:'true', inline:'true', corners:'false'
|
||||||
|
return css + ' ' + (btn && btn.cssClass ? btn.cssClass + '-' + (t.theme || '') : '') +
|
||||||
|
(t.shadow == 'true' ? ' ui-shadow' : '') +
|
||||||
|
(t.corners == 'true' ? ' ui-corner-all' : '');
|
||||||
|
};
|
||||||
|
|
||||||
|
base.mobile_init();
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
218
web_app/js/external/jquery.keyboard.extension-navigation.js
vendored
Normal file
218
web_app/js/external/jquery.keyboard.extension-navigation.js
vendored
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Navigation v1.6.1 *//*
|
||||||
|
* for Keyboard v1.18+ only (updated 7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to navigate
|
||||||
|
* the virtual keyboard keys using the arrow, page, home and end keys
|
||||||
|
* Using this extension WILL prevent keyboard navigation inside of all
|
||||||
|
* input and textareas
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery
|
||||||
|
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .addNavigation();
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options) // keyboard plugin
|
||||||
|
* .addNavigation(); // this keyboard extension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
'use strict';
|
||||||
|
$.keyboard = $.keyboard || {};
|
||||||
|
|
||||||
|
$.keyboard.navigationKeys = {
|
||||||
|
// all keys
|
||||||
|
toggle : 112, // toggle key; F1 = 112 (event.which value for function 1 key)
|
||||||
|
enter : 13,
|
||||||
|
pageup : 33,
|
||||||
|
pagedown : 34,
|
||||||
|
end : 35,
|
||||||
|
home : 36,
|
||||||
|
left : 37,
|
||||||
|
up : 38,
|
||||||
|
right : 39,
|
||||||
|
down : 40,
|
||||||
|
// move caret WITH navigate toggle active
|
||||||
|
caretrt : 45, // Insert key
|
||||||
|
caretlt : 46, // delete key
|
||||||
|
|
||||||
|
// ** custom navigationKeys functions **
|
||||||
|
// move caret without navigate toggle active
|
||||||
|
caretright : function(kb){
|
||||||
|
$.keyboard.keyaction.right(kb);
|
||||||
|
},
|
||||||
|
caretleft : function(kb){
|
||||||
|
$.keyboard.keyaction.left(kb);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.addNavigation = function(options){
|
||||||
|
return this.each(function(){
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o, k,
|
||||||
|
base = $(this).data('keyboard'),
|
||||||
|
opts = base.options,
|
||||||
|
defaults = {
|
||||||
|
position : [0,0], // set start position [row-number, key-index]
|
||||||
|
toggleMode : false, // true = navigate the virtual keyboard, false = navigate in input/textarea
|
||||||
|
focusClass : 'hasFocus',// css class added when toggle mode is on
|
||||||
|
toggleKey : null // defaults to $.keyboard.navigationKeys.toggle value
|
||||||
|
},
|
||||||
|
kbevents = $.keyboard.events;
|
||||||
|
if (!base) { return; }
|
||||||
|
|
||||||
|
base.navigation_options = o = $.extend({}, defaults, options);
|
||||||
|
base.navigation_keys = k = $.extend({}, $.keyboard.navigationKeys);
|
||||||
|
base.navigation_namespace = base.namespace + 'Nav';
|
||||||
|
base.extensionNamespace.push( base.navigation_namespace );
|
||||||
|
|
||||||
|
// save navigation settings - disabled when the toggled
|
||||||
|
base.saveNav = [ base.options.tabNavigation, base.options.enterNavigation ];
|
||||||
|
base.allNavKeys = $.map(k, function(v,i){ return v; });
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
base.navigation_init = function(){
|
||||||
|
var kbcss = $.keyboard.css;
|
||||||
|
base.$keyboard.toggleClass(o.focusClass, o.toggleMode)
|
||||||
|
.find('.' + kbcss.keySet + ':visible')
|
||||||
|
.find('.' + kbcss.keyButton + '[data-pos="' + o.position[0] + ',' + o.position[1] + '"]')
|
||||||
|
.addClass(opts.css.buttonHover);
|
||||||
|
|
||||||
|
base.$preview
|
||||||
|
.unbind(base.navigation_namespace)
|
||||||
|
.bind('keydown' + base.navigation_namespace,function(e){
|
||||||
|
return base.checkKeys(e.which);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
base.checkKeys = function(key, disable){
|
||||||
|
if (typeof(key) === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var k = base.navigation_keys,
|
||||||
|
kbcss = $.keyboard.css;
|
||||||
|
if (key === ( o.toggleKey || k.toggle ) || disable) {
|
||||||
|
o.toggleMode = (disable) ? false : !o.toggleMode;
|
||||||
|
base.options.tabNavigation = (o.toggleMode) ? false : base.saveNav[0];
|
||||||
|
base.options.enterNavigation = (o.toggleMode) ? false : base.saveNav[1];
|
||||||
|
}
|
||||||
|
base.$keyboard.toggleClass(o.focusClass, o.toggleMode);
|
||||||
|
if ( o.toggleMode && key === k.enter ) {
|
||||||
|
base.$keyboard
|
||||||
|
.find('.' + kbcss.keySet + ':visible')
|
||||||
|
.find('.' + kbcss.keyButton + '[data-pos="' + o.position[0] + ',' + o.position[1] + '"]')
|
||||||
|
.trigger(kbevents.kbRepeater);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( o.toggleMode && $.inArray(key, base.allNavKeys) >= 0 ) {
|
||||||
|
base.navigateKeys(key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
base.navigateKeys = function(key, row, indx){
|
||||||
|
indx = typeof indx === 'number' ? indx : o.position[1];
|
||||||
|
row = typeof row === 'number' ? row : o.position[0];
|
||||||
|
var kbcss = $.keyboard.css,
|
||||||
|
vis = base.$keyboard.find('.' + kbcss.keySet + ':visible'),
|
||||||
|
maxRow = vis.find('.' + kbcss.endRow).length - 1,
|
||||||
|
maxIndx = vis.find('.' + kbcss.keyButton + '[data-pos^="' + row + ',"]').length - 1,
|
||||||
|
p = base.last,
|
||||||
|
l = base.$preview.val().length,
|
||||||
|
k = base.navigation_keys;
|
||||||
|
|
||||||
|
switch(key){
|
||||||
|
case k.pageup : row = 0; break; // pageUp
|
||||||
|
case k.pagedown : row = maxRow; break; // pageDown
|
||||||
|
case k.end : indx = maxIndx; break; // End
|
||||||
|
case k.home : indx = 0; break; // Home
|
||||||
|
case k.left : indx += (indx > 0) ? -1 : 0; break; // Left
|
||||||
|
case k.up : row += (row > 0) ? -1 : 0; break; // Up
|
||||||
|
case k.right : indx += 1; break; // Right
|
||||||
|
case k.down : row += (row + 1 > maxRow) ? 0 : 1; break; // Down
|
||||||
|
case k.caretrt : p.start++; break; // caret right
|
||||||
|
case k.caretlt : p.start--; break; // caret left
|
||||||
|
}
|
||||||
|
|
||||||
|
// move caret
|
||||||
|
if (key === k.caretrt || key === k.caretlt) {
|
||||||
|
p.start = p.start < 0 ? 0 : p.start > l ? l : p.start;
|
||||||
|
base.last.start = base.last.end = p.end = p.start;
|
||||||
|
$.keyboard.caret( base.$preview, base.last );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get max index of new row
|
||||||
|
maxIndx = vis.find('.' + kbcss.keyButton + '[data-pos^="' + row + ',"]').length - 1;
|
||||||
|
if (indx > maxIndx) { indx = maxIndx; }
|
||||||
|
|
||||||
|
vis.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||||
|
vis.find('.' + kbcss.keyButton + '[data-pos="' + row + ',' + indx + '"]').addClass(opts.css.buttonHover);
|
||||||
|
o.position = [ row, indx ];
|
||||||
|
};
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible) {
|
||||||
|
base.$keyboard.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||||
|
base.navigation_init();
|
||||||
|
}
|
||||||
|
// navigation bindings
|
||||||
|
base.$el
|
||||||
|
.unbind(base.navigation_namespace)
|
||||||
|
.bind(kbevents.kbVisible, function(){
|
||||||
|
base.$keyboard.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||||
|
base.navigation_init();
|
||||||
|
})
|
||||||
|
.bind(kbevents.kbInactive + ' ' + kbevents.kbHidden, function(e){
|
||||||
|
base.checkKeys(e.which, true); // disable toggle mode & revert navigation options
|
||||||
|
})
|
||||||
|
.bind(kbevents.kbKeysetChange, function(){
|
||||||
|
base.navigateKeys(null);
|
||||||
|
})
|
||||||
|
.bind('navigate navigateTo', function(e, row, indx){
|
||||||
|
var key;
|
||||||
|
// no row given, check if it's a navigation key or keyaction
|
||||||
|
row = isNaN(row) ? row.toLowerCase() : row;
|
||||||
|
if (row in base.navigation_keys) {
|
||||||
|
key = base.navigation_keys[row];
|
||||||
|
if (isNaN(key) && key in $.keyboard.keyaction) {
|
||||||
|
// defined navigation_keys string name is a defined keyaction
|
||||||
|
$.keyboard.keyaction[key]( base, this, e );
|
||||||
|
} else if ($.isFunction(key)) {
|
||||||
|
// custom function defined in navigation_keys
|
||||||
|
key(base);
|
||||||
|
} else {
|
||||||
|
// key (e.which value) is defined in navigation_keys
|
||||||
|
base.checkKeys(key);
|
||||||
|
}
|
||||||
|
} else if ( typeof row === 'string' && row in $.keyboard.keyaction ) {
|
||||||
|
// navigate called directly with a keyaction name
|
||||||
|
$.keyboard.keyaction[row]( base, this, e );
|
||||||
|
} else {
|
||||||
|
base.navigateKeys(null, row, indx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
91
web_app/js/external/jquery.keyboard.extension-previewkeyset.js
vendored
Normal file
91
web_app/js/external/jquery.keyboard.extension-previewkeyset.js
vendored
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard previewKeyset v1.1.1 *//*
|
||||||
|
* for Keyboard v1.18+ only (updated 7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to add a preview
|
||||||
|
* of other keysets to the main keyboard.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery
|
||||||
|
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .previewKeyset();
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options) // keyboard plugin
|
||||||
|
* .previewKeyset(); // this keyboard extension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
'use strict';
|
||||||
|
$.keyboard = $.keyboard || {};
|
||||||
|
|
||||||
|
$.fn.previewKeyset = function( options ) {
|
||||||
|
return this.each( function() {
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var base = $( this ).data( 'keyboard' ),
|
||||||
|
namespace = base.namespace + 'Preview',
|
||||||
|
defaults = {
|
||||||
|
sets : [ 'normal', 'shift', 'alt', 'alt-shift' ]
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( !base ) { return; }
|
||||||
|
|
||||||
|
base.previewKeyset_options = $.extend( {}, defaults, options );
|
||||||
|
base.extensionNamespace.push( namespace );
|
||||||
|
|
||||||
|
base.previewKeyset = function() {
|
||||||
|
var kbcss = $.keyboard.css,
|
||||||
|
sets = base.previewKeyset_options.sets,
|
||||||
|
// only target option defined sets
|
||||||
|
$sets = base.$keyboard.find( '.' + kbcss.keySet ).filter( '[name="' + sets.join('"],[name="') + '"]' );
|
||||||
|
if ( $sets.length > 1 ) {
|
||||||
|
// start with normal keyset & find all non-action buttons
|
||||||
|
$sets.eq( 0 ).find( '.' + kbcss.keyButton ).not( '.' + kbcss.keyAction ).each(function(){
|
||||||
|
var indx, nam,
|
||||||
|
data = {},
|
||||||
|
len = sets.length,
|
||||||
|
// find all keys with the same position
|
||||||
|
$sibs = $sets.find( 'button[data-pos="' + $(this).attr('data-pos') + '"]' );
|
||||||
|
for ( indx = 0; indx < len; indx++ ) {
|
||||||
|
nam = $sibs.eq( indx ).parent().attr( 'name' );
|
||||||
|
if ( $.inArray( nam, sets ) >= 0 ) {
|
||||||
|
data[ 'data-' + nam ] = $sibs.eq( indx ).find( '.' + kbcss.keyText ).text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sibs.attr( data );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible()) {
|
||||||
|
base.previewKeyset();
|
||||||
|
} else {
|
||||||
|
base.$el
|
||||||
|
.unbind($.keyboard.events.kbBeforeVisible + namespace)
|
||||||
|
.bind($.keyboard.events.kbBeforeVisible + namespace, function() {
|
||||||
|
base.previewKeyset();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
230
web_app/js/external/jquery.keyboard.extension-scramble.js
vendored
Normal file
230
web_app/js/external/jquery.keyboard.extension-scramble.js
vendored
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* jQuery UI Virtual Keyboard Scramble Extension v1.6.1 for Keyboard v1.18+ (updated 7/7/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to scramble the
|
||||||
|
* specified keyboard keys
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery v1.4.4+
|
||||||
|
* Keyboard v1.17.14+ - https://github.com/Mottie/Keyboard
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .addScramble();
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options) // keyboard plugin
|
||||||
|
* .addScramble(); // this keyboard extension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
'use strict';
|
||||||
|
$.keyboard = $.keyboard || {};
|
||||||
|
|
||||||
|
$.fn.addScramble = function(options) {
|
||||||
|
//Set the default values, use comma to separate the settings, example:
|
||||||
|
var savedLayout,
|
||||||
|
defaults = {
|
||||||
|
targetKeys : /[a-z\d]/i, // keys to randomize
|
||||||
|
byRow : true, // randomize by row, otherwise randomize all keys
|
||||||
|
byKeySet : false, // if true, randomize one keyset & duplicate
|
||||||
|
randomizeOnce : true, // if true, randomize only once on keyboard visible
|
||||||
|
sameForAll : false, // use the same scrambled keyboard for all targetted keyboards - not fully implemented!
|
||||||
|
init : null // function(keyboard){}
|
||||||
|
};
|
||||||
|
return this.each(function() {
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o,
|
||||||
|
base = $(this).data('keyboard'),
|
||||||
|
namespace = base.namespace + 'Scramble',
|
||||||
|
opts = base.options;
|
||||||
|
|
||||||
|
if (!base || base.scramble_options) { return; }
|
||||||
|
o = base.scramble_options = $.extend({}, defaults, options);
|
||||||
|
base.extensionNamespace.push( namespace );
|
||||||
|
|
||||||
|
// save create callback
|
||||||
|
o.orig_create = opts.create;
|
||||||
|
|
||||||
|
base.scramble_setup = function($keyboard) {
|
||||||
|
var $sets, set, $keys, key, index, tmp,
|
||||||
|
rowIndex, keyboardmap, map, keyboard, row;
|
||||||
|
$sets = $keyboard.find('.' + $.keyboard.css.keySet);
|
||||||
|
if ($keyboard.length) {
|
||||||
|
if (o.byKeySet) {
|
||||||
|
$sets = $sets.eq(0);
|
||||||
|
}
|
||||||
|
for (set = 0; set < $sets.length; set++) {
|
||||||
|
/*jshint loopfunc:true */
|
||||||
|
$keys = $sets.eq(set);
|
||||||
|
rowIndex = 0;
|
||||||
|
row = [];
|
||||||
|
map = [];
|
||||||
|
keyboardmap = [];
|
||||||
|
keyboard = [];
|
||||||
|
$keys.children('button, span, br').each(function() {
|
||||||
|
if (this.tagName === 'BR') {
|
||||||
|
if (o.byRow) {
|
||||||
|
row.push(this);
|
||||||
|
map.push(false);
|
||||||
|
keyboard[rowIndex] = row;
|
||||||
|
keyboardmap[rowIndex] = map;
|
||||||
|
row = [];
|
||||||
|
map = [];
|
||||||
|
rowIndex++;
|
||||||
|
} else {
|
||||||
|
keyboard[rowIndex] = this;
|
||||||
|
keyboardmap[rowIndex] = false;
|
||||||
|
rowIndex++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp = $(this).attr('data-value') || '';
|
||||||
|
tmp = tmp.length === 1 && o.targetKeys.test(tmp) ? tmp : false;
|
||||||
|
if (o.byRow) {
|
||||||
|
row.push( this );
|
||||||
|
map.push ( tmp );
|
||||||
|
} else {
|
||||||
|
keyboard[rowIndex] = this;
|
||||||
|
keyboardmap[rowIndex] = tmp;
|
||||||
|
rowIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// remove original <br> elements
|
||||||
|
$keys.find('.' + $.keyboard.css.endRow).remove();
|
||||||
|
// re-map keys
|
||||||
|
if (!o.byRow) {
|
||||||
|
row = base.shuffle( keyboard, keyboardmap );
|
||||||
|
for (key = 0; key < row.length; key++) {
|
||||||
|
$keys.append(row[key]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (index = 0; index < keyboard.length; index++) {
|
||||||
|
row = base.shuffle( keyboard[index], keyboardmap[index] );
|
||||||
|
for (key = 0; key < row.length; key++) {
|
||||||
|
$keys.append(row[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o.byKeySet) {
|
||||||
|
$keyboard = base.realign($keyboard);
|
||||||
|
}
|
||||||
|
return $keyboard;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// modified from Fisher-Yates shuffle ( http://bost.ocks.org/mike/shuffle/ )
|
||||||
|
// to allow not shuffling specifically mapped array elements
|
||||||
|
base.shuffle = function(array, map) {
|
||||||
|
var swap, random,
|
||||||
|
index = array.length;
|
||||||
|
// While there remain elements to shuffle...
|
||||||
|
while (index > 0) {
|
||||||
|
// Pick a remaining element...
|
||||||
|
random = Math.floor(Math.random() * index);
|
||||||
|
if (map[index - 1] === false) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
// skip elements that are mapped to false
|
||||||
|
if (map[index - 1] !== false && map[random] !== false) {
|
||||||
|
// And swap it with the current element
|
||||||
|
index--;
|
||||||
|
swap = array[index];
|
||||||
|
array[index] = array[random];
|
||||||
|
array[random] = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
|
||||||
|
// make other keysets "line-up" with scrambled keyset
|
||||||
|
base.realign = function($keyboard) {
|
||||||
|
var selector, typ, pos,
|
||||||
|
$sets = $keyboard.find('.' + $.keyboard.css.keySet),
|
||||||
|
$orig = $sets.eq(0);
|
||||||
|
$sets = $sets.filter(':gt(0)');
|
||||||
|
$orig.children().each(function(i, cell){
|
||||||
|
typ = cell.tagName === 'BR';
|
||||||
|
pos = $(cell).attr('data-pos');
|
||||||
|
/*jshint loopfunc:true */
|
||||||
|
$sets.each(function(j, k){
|
||||||
|
selector = typ ? 'br:first' : 'button[data-pos="' + pos + '"]';
|
||||||
|
$(k).find(selector).appendTo( k );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return $keyboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
// create scrambled keyboard layout
|
||||||
|
opts.create = function() {
|
||||||
|
var layout = opts.layout;
|
||||||
|
$.keyboard.builtLayouts[layout] = {
|
||||||
|
mappedKeys : {},
|
||||||
|
acceptedKeys : [],
|
||||||
|
$keyboard: null
|
||||||
|
};
|
||||||
|
if ( typeof $.keyboard.builtLayouts[base.orig_layout] === 'undefined' ) {
|
||||||
|
base.layout = opts.layout = base.orig_layout;
|
||||||
|
// build original layout, if not already built, e.g. "qwerty"
|
||||||
|
base.buildKeyboard( base.layout, true );
|
||||||
|
base.layout = opts.layout = layout;
|
||||||
|
}
|
||||||
|
// clone, scramble then save layout
|
||||||
|
$.keyboard.builtLayouts[layout] = $.extend(true, {}, $.keyboard.builtLayouts[base.orig_layout]);
|
||||||
|
if (o.randomizeOnce) {
|
||||||
|
$.keyboard.builtLayouts[layout].$keyboard = base.scramble_setup( $.keyboard.builtLayouts[base.orig_layout].$keyboard.clone() );
|
||||||
|
}
|
||||||
|
base.$keyboard = $.keyboard.builtLayouts[layout].$keyboard;
|
||||||
|
if ( !o.randomizeOnce ) {
|
||||||
|
base.$el
|
||||||
|
.unbind($.keyboard.events.kbBeforeVisible + namespace)
|
||||||
|
.bind($.keyboard.events.kbBeforeVisible + namespace, function(e, kb) {
|
||||||
|
kb.$keyboard = kb.scramble_setup(kb.$keyboard);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ( $.isFunction( o.orig_create ) ) {
|
||||||
|
o.orig_create( base );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// scrambled layout already initialized
|
||||||
|
if (!/^scrambled/.test(opts.layout)) {
|
||||||
|
base.orig_layout = opts.layout;
|
||||||
|
savedLayout = savedLayout || 'scrambled' + Math.round(Math.random() * 10000);
|
||||||
|
opts.layout = o.sameForAll ? savedLayout : 'scrambled' + Math.round(Math.random() * 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case when keyboard is set to always be open
|
||||||
|
if (opts.alwaysOpen && base.$keyboard.length) {
|
||||||
|
setTimeout(function(){
|
||||||
|
base.$keyboard = base.scramble_setup(base.$keyboard);
|
||||||
|
if ($.isFunction(o.init)) {
|
||||||
|
o.init(base);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
} else {
|
||||||
|
if ($.isFunction(o.init)) {
|
||||||
|
o.init(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
323
web_app/js/external/jquery.keyboard.extension-typing.js
vendored
Normal file
323
web_app/js/external/jquery.keyboard.extension-typing.js
vendored
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
/*! jQuery UI Virtual Keyboard Typing Simulator v1.10.0 *//*
|
||||||
|
* for Keyboard v1.18+ only (9/14/2015)
|
||||||
|
*
|
||||||
|
* By Rob Garrison (aka Mottie & Fudgey)
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Use this extension with the Virtual Keyboard to simulate
|
||||||
|
* typing for tutorials or whatever else use you can find
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* jQuery
|
||||||
|
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||||
|
*
|
||||||
|
* Setup:
|
||||||
|
* $('.ui-keyboard-input')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .addTyping(typing-options);
|
||||||
|
*
|
||||||
|
* // or if targeting a specific keyboard
|
||||||
|
* $('#keyboard1')
|
||||||
|
* .keyboard(options)
|
||||||
|
* .addTyping(typing-options);
|
||||||
|
*
|
||||||
|
* Basic Usage:
|
||||||
|
* // To disable manual typing on the virtual keyboard, just set "showTyping" option to false
|
||||||
|
* $('#keyboard-input').keyboard(options).addTyping({ showTyping: false });
|
||||||
|
*
|
||||||
|
* // Change the default typing delay (time the virtual keyboard highlights the manually typed key) - default = 250 milliseconds
|
||||||
|
* $('#keyboard-input').keyboard(options).addTyping({ delay: 500 });
|
||||||
|
*
|
||||||
|
* // get keyboard object, open it, then start typing simulation
|
||||||
|
* $('#keyboard-input').getkeyboard().reveal().typeIn('Hello World', 700);
|
||||||
|
*
|
||||||
|
* // get keyboard object, open it, type in "This is a test" with 700ms delay between types, then accept & close the keyboard
|
||||||
|
* $('#keyboard-input').getkeyboard().reveal().typeIn('This is a test', 700, function(){ $('#keyboard-input').getkeyboard().close(true); });
|
||||||
|
*/
|
||||||
|
|
||||||
|
// EXAMPLES:
|
||||||
|
// $('#inter').getkeyboard().reveal().typeIn('\tHello \b\n\tWorld', 500);
|
||||||
|
// $('#meta').getkeyboard().reveal().typeIn('abCDd11123\u2648\u2649\u264A\u264B', 700, function(){ alert('all done!'); });
|
||||||
|
/*jshint browser:true, jquery:true, unused:false */
|
||||||
|
/*global require:false, define:false, module:false */
|
||||||
|
;(function(factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function($) {
|
||||||
|
$.fn.addTyping = function(options){
|
||||||
|
//Set the default values, use comma to separate the settings, example:
|
||||||
|
var defaults = {
|
||||||
|
showTyping : true,
|
||||||
|
lockTypeIn : false,
|
||||||
|
delay : 250
|
||||||
|
},
|
||||||
|
$keyboard = $.keyboard;
|
||||||
|
return this.each(function(){
|
||||||
|
// make sure a keyboard is attached
|
||||||
|
var o, base = $(this).data('keyboard');
|
||||||
|
if (!base) { return; }
|
||||||
|
|
||||||
|
// variables
|
||||||
|
o = base.typing_options = $.extend({}, defaults, options);
|
||||||
|
base.typing_keymap = {
|
||||||
|
' ' : 'space',
|
||||||
|
'"' : '34',
|
||||||
|
"'" : '39',
|
||||||
|
' ' : 'space',
|
||||||
|
'\b' : 'bksp', // delete character to the left
|
||||||
|
'{b}' : 'bksp',
|
||||||
|
'{d}' : 'del', // delete character to the right
|
||||||
|
'{l}' : 'left', // move caret left
|
||||||
|
'{r}' : 'right', // move caret right
|
||||||
|
'\n' : 'enter',
|
||||||
|
'\r' : 'enter',
|
||||||
|
'{e}' : 'enter',
|
||||||
|
'\t' : 'tab',
|
||||||
|
'{t}' : 'tab'
|
||||||
|
};
|
||||||
|
base.typing_xref = {
|
||||||
|
8 : 'bksp',
|
||||||
|
9 : 'tab',
|
||||||
|
13 : 'enter',
|
||||||
|
32 : 'space',
|
||||||
|
46 : 'del'
|
||||||
|
};
|
||||||
|
base.typing_event = false;
|
||||||
|
base.typing_namespace = base.namespace + 'typing';
|
||||||
|
base.extensionNamespace.push( base.typing_namespace );
|
||||||
|
// save lockInput setting
|
||||||
|
o.savedLockInput = base.options.lockInput;
|
||||||
|
|
||||||
|
base.typing_setup = function(){
|
||||||
|
var kbevents = $keyboard.events,
|
||||||
|
namespace = base.typing_namespace;
|
||||||
|
base.$el.add( base.$preview ).unbind(namespace);
|
||||||
|
base.$el
|
||||||
|
.bind([ kbevents.kbHidden, kbevents.kbInactive, '' ].join( namespace + ' ' ), function(e){
|
||||||
|
base.typing_reset();
|
||||||
|
})
|
||||||
|
.bind( $keyboard.events.kbBeforeVisible + namespace, function(){
|
||||||
|
base.typing_setup();
|
||||||
|
});
|
||||||
|
base.$allKeys
|
||||||
|
.bind('mousedown' + namespace, function(){
|
||||||
|
base.typing_reset();
|
||||||
|
});
|
||||||
|
base.$preview
|
||||||
|
.bind('keyup' + namespace, function(e){
|
||||||
|
if (o.init && o.lockTypeIn) { return false; }
|
||||||
|
if (e.which >= 37 && e.which <=40) { return; } // ignore arrow keys
|
||||||
|
if (e.which === 16) { base.shiftActive = false; }
|
||||||
|
if (e.which === 18) { base.altActive = false; }
|
||||||
|
if (e.which === 16 || e.which === 18) {
|
||||||
|
base.showSet();
|
||||||
|
// Alt key will shift focus to the menu - doesn't work in Windows
|
||||||
|
setTimeout(function(){ base.$preview.focus(); }, 200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// change keyset when either shift or alt is held down
|
||||||
|
.bind('keydown' + namespace, function(e){
|
||||||
|
if (o.init && o.lockTypeIn) { return false; }
|
||||||
|
e.temp = false; // prevent repetitive calls while keydown repeats.
|
||||||
|
if (e.which === 16) { e.temp = !base.shiftActive; base.shiftActive = true; }
|
||||||
|
// it should be ok to reset e.temp, since both alt and shift will call this function separately
|
||||||
|
if (e.which === 18) { e.temp = !base.altActive; base.altActive = true; }
|
||||||
|
if (e.temp) {
|
||||||
|
base.showSet();
|
||||||
|
base.$preview.focus(); // Alt shift focus to the menu
|
||||||
|
}
|
||||||
|
base.typing_event = true;
|
||||||
|
// Simulate key press for tab and backspace since they don't fire the keypress event
|
||||||
|
if (e.which === 8 || e.which === 9) {
|
||||||
|
base.typing_findKey( '', e ); // pass event object
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.bind('keypress' + namespace, function(e){
|
||||||
|
if (o.init && o.lockTypeIn) { return false; }
|
||||||
|
// Simulate key press on virtual keyboard
|
||||||
|
if (base.typing_event && !base.options.lockInput) {
|
||||||
|
base.typing_reset();
|
||||||
|
base.typing_event = true;
|
||||||
|
base.typing_findKey( '', e ); // pass event object
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
base.typing_reset = function(){
|
||||||
|
base.typing_event = o.init = false;
|
||||||
|
o.text = '';
|
||||||
|
o.len = o.current = 0;
|
||||||
|
base.options.lockInput = o.savedLockInput;
|
||||||
|
// clearTimeout(base.typing_timer);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store typing text
|
||||||
|
base.typeIn = function(txt, delay, callback, e){
|
||||||
|
if (!base.isVisible()) {
|
||||||
|
// keyboard was closed
|
||||||
|
clearTimeout(base.typing_timer);
|
||||||
|
base.typing_reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!base.typing_event){
|
||||||
|
|
||||||
|
if (o.init !== true) {
|
||||||
|
o.init = true;
|
||||||
|
base.options.lockInput = o.lockTypeIn;
|
||||||
|
o.text = txt || o.text || '';
|
||||||
|
o.len = o.text.length;
|
||||||
|
o.delay = delay || 300;
|
||||||
|
o.current = 0; // position in text string
|
||||||
|
if (callback) {
|
||||||
|
o.callback = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// function that loops through and types each character
|
||||||
|
txt = o.text.substring( o.current, ++o.current );
|
||||||
|
// add support for curly-wrapped single character: {l}, {r}, {d}, etc.
|
||||||
|
if ( txt === '{' && o.text.substring( o.current + 1, o.current + 2 ) === '}' ) {
|
||||||
|
txt += o.text.substring( o.current, o.current += 2 );
|
||||||
|
}
|
||||||
|
base.typing_findKey( txt, e );
|
||||||
|
} else if (typeof txt === 'undefined') {
|
||||||
|
// typeIn called by user input
|
||||||
|
base.typing_event = false;
|
||||||
|
base.options.lockInput = o.savedLockInput;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
base.typing_findKey = function(txt, e){
|
||||||
|
var tar, m, n, k, key, ks, meta, set,
|
||||||
|
kbcss = $keyboard.css,
|
||||||
|
mappedKeys = $keyboard.builtLayouts[base.layout].mappedKeys;
|
||||||
|
// stop if keyboard is closed
|
||||||
|
if ( !base.isOpen || !base.$keyboard.length ) { return; }
|
||||||
|
ks = base.$keyboard.find('.' + kbcss.keySet);
|
||||||
|
k = txt in base.typing_keymap ? base.typing_keymap[txt] : txt;
|
||||||
|
// typing_event is true when typing on the actual keyboard - look for actual key
|
||||||
|
// All of this breaks when the CapLock is on... unable to find a cross-browser method that works.
|
||||||
|
tar = '.' + kbcss.keyButton + '[data-action="' + k + '"]';
|
||||||
|
if (base.typing_event && e) {
|
||||||
|
if (base.typing_xref.hasOwnProperty(e.keyCode || e.which)) {
|
||||||
|
// special named keys: bksp, tab and enter
|
||||||
|
tar = '.' + kbcss.keyPrefix + base.typing_xref[e.keyCode || e.which];
|
||||||
|
} else {
|
||||||
|
m = String.fromCharCode(e.charCode || e.which);
|
||||||
|
tar = (mappedKeys.hasOwnProperty(m)) ?
|
||||||
|
'.' + kbcss.keyButton + '[data-action="' + mappedKeys[m] + '"]' :
|
||||||
|
'.' + kbcss.keyPrefix + m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// find key
|
||||||
|
key = ks.filter(':visible').find(tar);
|
||||||
|
if (key.length) {
|
||||||
|
// key is visible, simulate typing
|
||||||
|
base.typing_simulateKey(key, txt, e);
|
||||||
|
} else {
|
||||||
|
// key not found, check if it is in the keymap (tab, space, enter, etc)
|
||||||
|
if (base.typing_event) {
|
||||||
|
key = ks.find(tar);
|
||||||
|
} else {
|
||||||
|
// key not found, check if it is in the keymap (tab, space, enter, etc)
|
||||||
|
n = txt in base.typing_keymap ? base.typing_keymap[txt] : base.processName( txt );
|
||||||
|
// find actual key on keyboard
|
||||||
|
key = ks.find('.' + kbcss.keyPrefix + n);
|
||||||
|
}
|
||||||
|
// find the keyset
|
||||||
|
set = key.closest('.' + kbcss.keySet);
|
||||||
|
// figure out which keyset the key is in then simulate clicking on that meta key, then on the key
|
||||||
|
if (set.attr('name')) {
|
||||||
|
// get meta key name
|
||||||
|
meta = set.attr('name');
|
||||||
|
// show correct key set
|
||||||
|
base.shiftActive = /shift/.test(meta);
|
||||||
|
base.altActive = /alt/.test(meta);
|
||||||
|
base.metaActive = base.last.keyset[2] = (meta).match(/meta\d+/) || false;
|
||||||
|
// make the plugin think we're passing it a jQuery object with a name
|
||||||
|
base.showSet( base.metaActive );
|
||||||
|
// Add the key
|
||||||
|
base.typing_simulateKey(key, txt, e);
|
||||||
|
} else {
|
||||||
|
if (!base.typing_event) {
|
||||||
|
// Key doesn't exist on the keyboard, so just enter it
|
||||||
|
if (txt in base.typing_keymap && base.typing_keymap[txt] in $keyboard.keyaction) {
|
||||||
|
$keyboard.keyaction[base.typing_keymap[txt]](base, key, e);
|
||||||
|
} else {
|
||||||
|
base.insertText(txt);
|
||||||
|
}
|
||||||
|
base.checkCombos();
|
||||||
|
base.$el.trigger( $keyboard.events.kbChange, [ base, base.el ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.current <= o.len && o.len !== 0){
|
||||||
|
if (!base.isVisible()) { return; } // keyboard was closed, abort!!
|
||||||
|
setTimeout(function(){ base.typeIn(); }, o.delay);
|
||||||
|
} else if (o.len !== 0){
|
||||||
|
// o.len is zero when the user typed on the actual keyboard during simulation
|
||||||
|
base.typing_reset();
|
||||||
|
if ($.isFunction(o.callback)) {
|
||||||
|
// ensure all typing animation is done before the callback
|
||||||
|
setTimeout(function(){
|
||||||
|
// if the user typed during the key simulation, the "o" variable may sometimes be undefined
|
||||||
|
if ($.isFunction(o.callback)) {
|
||||||
|
o.callback(base);
|
||||||
|
}
|
||||||
|
}, o.delay);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
base.typing_reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// mouseover the key, add the text directly, then mouseout on the key
|
||||||
|
base.typing_simulateKey = function(el, txt, e){
|
||||||
|
var len = el.length;
|
||||||
|
if (len) { el.filter(':visible').trigger('mouseenter' + base.namespace); }
|
||||||
|
base.typing_timer = setTimeout(function(){
|
||||||
|
var len = el.length;
|
||||||
|
if (len) { setTimeout(function(){ el.trigger('mouseleave' + base.namespace); }, o.delay/3); }
|
||||||
|
if (!base.isVisible()) { return; }
|
||||||
|
if (!base.typing_event) {
|
||||||
|
if (txt in base.typing_keymap && base.typing_keymap[txt] in $keyboard.keyaction) {
|
||||||
|
e = e || $.Event('keypress');
|
||||||
|
e.target = el; // "Enter" checks for the e.target
|
||||||
|
$keyboard.keyaction[base.typing_keymap[txt]](base, el, e );
|
||||||
|
} else {
|
||||||
|
base.insertText(txt);
|
||||||
|
}
|
||||||
|
base.checkCombos();
|
||||||
|
base.$el.trigger( $keyboard.events.kbChange, [ base, base.el ] );
|
||||||
|
}
|
||||||
|
}, o.delay/3);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (o.showTyping) {
|
||||||
|
// visible event is fired before this extension is initialized, so check!
|
||||||
|
if (base.options.alwaysOpen && base.isVisible()) {
|
||||||
|
base.typing_setup();
|
||||||
|
}
|
||||||
|
// capture and simulate typing
|
||||||
|
base.$el
|
||||||
|
.unbind( $keyboard.events.kbBeforeVisible + base.typing_namespace )
|
||||||
|
.bind( $keyboard.events.kbBeforeVisible + base.typing_namespace, function(){
|
||||||
|
base.typing_setup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
2460
web_app/js/external/jquery.keyboard.js
vendored
Normal file
2460
web_app/js/external/jquery.keyboard.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
920
web_app/js/external/jquery.keypad.js
vendored
920
web_app/js/external/jquery.keypad.js
vendored
|
@ -1,920 +0,0 @@
|
||||||
/* http://keith-wood.name/keypad.html
|
|
||||||
Keypad field entry extension for jQuery v2.0.1.
|
|
||||||
Written by Keith Wood (kbwood{at}iinet.com.au) August 2008.
|
|
||||||
Available under the MIT (https://github.com/jquery/jquery/blob/master/LICENSE.txt) license.
|
|
||||||
Please attribute the author if you use it. */
|
|
||||||
|
|
||||||
(function($) { // hide the namespace
|
|
||||||
|
|
||||||
var pluginName = 'keypad';
|
|
||||||
|
|
||||||
var layoutStandard = [' BSCECA', '_1_2_3_+@X', '_4_5_6_-@U', '_7_8_9_*@E', '_0_._=_/'];
|
|
||||||
|
|
||||||
/** Create the keypad plugin.
|
|
||||||
<p>Sets an input field to popup a keypad for keystroke entry,
|
|
||||||
or creates an inline keypad in a <code>div</code> or <code>span</code>.</p>
|
|
||||||
<p>Expects HTML like:</p>
|
|
||||||
<pre><input type="text"> or
|
|
||||||
<div></div></pre>
|
|
||||||
<p>Provide inline configuration like:</p>
|
|
||||||
<pre><input type="text" data-keypad="name: 'value'"/></pre>
|
|
||||||
@module Keypad
|
|
||||||
@augments JQPlugin
|
|
||||||
@example $(selector).keypad() */
|
|
||||||
$.JQPlugin.createPlugin({
|
|
||||||
|
|
||||||
/** The name of the plugin. */
|
|
||||||
name: pluginName,
|
|
||||||
|
|
||||||
/** Keypad before show callback.
|
|
||||||
Triggered before the keypad is shown.
|
|
||||||
@callback beforeShowCallback
|
|
||||||
@param div {jQuery} The div to be shown.
|
|
||||||
@param inst {object} The current instance settings. */
|
|
||||||
|
|
||||||
/** Keypad on keypress callback.
|
|
||||||
Triggered when a key on the keypad is pressed.
|
|
||||||
@callback keypressCallback
|
|
||||||
@param key {string} The key just pressed.
|
|
||||||
@param value {string} The full value entered so far.
|
|
||||||
@param inst {object} The current instance settings. */
|
|
||||||
|
|
||||||
/** Keypad on close callback.
|
|
||||||
Triggered when the keypad is closed.
|
|
||||||
@callback closeCallback
|
|
||||||
@param value {string} The full value entered so far.
|
|
||||||
@param inst {object} The current instance settings. */
|
|
||||||
|
|
||||||
/** Keypad is alphabetic callback.
|
|
||||||
Triggered when an alphabetic key needs to be identified.
|
|
||||||
@callback isAlphabeticCallback
|
|
||||||
@param ch {string} The key to check.
|
|
||||||
@return {boolean} True if this key is alphabetic, false if not.
|
|
||||||
@example isAlphabetic: function(ch) {
|
|
||||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
|
||||||
} */
|
|
||||||
|
|
||||||
/** Keypad is numeric callback.
|
|
||||||
Triggered when an numeric key needs to be identified.
|
|
||||||
@callback isNumericCallback
|
|
||||||
@param ch {string} The key to check.
|
|
||||||
@return {boolean} True if this key is numeric, false if not.
|
|
||||||
@example isNumeric: function(ch) {
|
|
||||||
return (ch >= '0' && ch <= '9');
|
|
||||||
} */
|
|
||||||
|
|
||||||
/** Keypad to upper callback.
|
|
||||||
Triggered to convert keys to upper case.
|
|
||||||
@callback toUpperCallback
|
|
||||||
@param ch {string} The key to convert.
|
|
||||||
@return {string} The upper case version of this key.
|
|
||||||
@example toUpper: function(ch) {
|
|
||||||
return ch.toUpperCase();
|
|
||||||
} */
|
|
||||||
|
|
||||||
/** Default settings for the plugin.
|
|
||||||
@property [showOn='focus'] {string} 'focus' for popup on focus, 'button' for trigger button, or 'both' for either.
|
|
||||||
@property [buttonImage=''] {string} URL for trigger button image.
|
|
||||||
@property [buttonImageOnly=false] {boolean} True if the image appears alone, false if it appears on a button.
|
|
||||||
@property [showAnim='show'] {string} Name of jQuery animation for popup.
|
|
||||||
@property [showOptions=null] {object} Options for enhanced animations.
|
|
||||||
@property [duration='normal'] {string|number} Duration of display/closure.
|
|
||||||
@property [appendText=''] {string} Display text following the text field, e.g. showing the format.
|
|
||||||
@property [useThemeRoller=false] {boolean} True to add ThemeRoller classes.
|
|
||||||
@property [keypadClass=''] {string} Additional CSS class for the keypad for an instance.
|
|
||||||
@property [prompt=''] {string} Display text at the top of the keypad.
|
|
||||||
@property [layout=this.numericLayout] {string} Layout of keys.
|
|
||||||
@property [separator=''] {string} Separator character between keys.
|
|
||||||
@property [target=null] {string|jQuery|Element} Input target for an inline keypad.
|
|
||||||
@property [keypadOnly=true] {boolean} True for entry only via the keypad, false for real keyboard too.
|
|
||||||
@property [randomiseAlphabetic=false] {boolean} True to randomise the alphabetic key positions, false to keep in order.
|
|
||||||
@property [randomiseNumeric=false] {boolean} True to randomise the numeric key positions, false to keep in order.
|
|
||||||
@property [randomiseOther=false] {boolean} True to randomise the other key positions, false to keep in order.
|
|
||||||
@property [randomiseAll=false] {boolean} True to randomise all key positions, false to keep in order.
|
|
||||||
@property [beforeShow=null] {beforeShowCallback} Callback before showing the keypad.
|
|
||||||
@property [onKeypress=null] {keypressCallback} Callback when a key is selected.
|
|
||||||
@property [onClose=null] {closeCallback} Callback when the panel is closed. */
|
|
||||||
defaultOptions: {
|
|
||||||
showOn: 'focus',
|
|
||||||
buttonImage: '',
|
|
||||||
buttonImageOnly: false,
|
|
||||||
showAnim: 'show',
|
|
||||||
showOptions: null,
|
|
||||||
duration: 'normal',
|
|
||||||
appendText: '',
|
|
||||||
useThemeRoller: false,
|
|
||||||
keypadClass: '',
|
|
||||||
prompt: '',
|
|
||||||
layout: [], // Set at the end
|
|
||||||
separator: '',
|
|
||||||
target: null,
|
|
||||||
keypadOnly: true,
|
|
||||||
randomiseAlphabetic: false,
|
|
||||||
randomiseNumeric: false,
|
|
||||||
randomiseOther: false,
|
|
||||||
randomiseAll: false,
|
|
||||||
beforeShow: null,
|
|
||||||
onKeypress: null,
|
|
||||||
onClose: null
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Localisations for the plugin.
|
|
||||||
Entries are objects indexed by the language code ('' being the default US/English).
|
|
||||||
Each object has the following attributes.
|
|
||||||
@property [buttonText='...'] {string} Display text for trigger button.
|
|
||||||
@property [buttonStatus='Open the keypad'] {string} Status text for trigger button.
|
|
||||||
@property [closeText='Close'] {string} Display text for close link.
|
|
||||||
@property [closeStatus='Close the keypad'] {string} Status text for close link.
|
|
||||||
@property [clearText='Clear'] {string} Display text for clear link.
|
|
||||||
@property [clearStatus='Erase all the text'] {string} Status text for clear link.
|
|
||||||
@property [backText='Back'] {string} Display text for back link.
|
|
||||||
@property [backStatus='Erase the previous character'] {string} Status text for back link.
|
|
||||||
@property [spacebarText=' '] {string} Display text for space bar.
|
|
||||||
@property [spacebarStatus='Space'] {string} Status text for space bar.
|
|
||||||
@property [enterText='Enter'] {string} Display text for carriage return.
|
|
||||||
@property [enterStatus='Carriage return'] {string} Status text for carriage return.
|
|
||||||
@property [tabText='→'] {string} Display text for tab.
|
|
||||||
@property [tabStatus='Horizontal tab'] {string} Status text for tab.
|
|
||||||
@property [shiftText='Shift'] {string} Display text for shift link.
|
|
||||||
@property [shiftStatus='Toggle upper/lower case characters'] {string} Status text for shift link.
|
|
||||||
@property [alphabeticLayout=this.qwertyAlphabetic] {string} Default layout for alphabetic characters.
|
|
||||||
@property [fullLayout=this.qwertyLayout] {string} Default layout for full keyboard.
|
|
||||||
@property [isAlphabetic=this.isAlphabetic] {isAlphabeticCallback} Function to determine if character is alphabetic.
|
|
||||||
@property [isNumeric=this.isNumeric] {isNumericCallback} Function to determine if character is numeric.
|
|
||||||
@property [toUpper=this.toUpper] {toUpperCallback} Function to convert characters to upper case.
|
|
||||||
@property [isRTL=false] {boolean} True if right-to-left language, false if left-to-right. */
|
|
||||||
regionalOptions: { // Available regional settings, indexed by language/country code
|
|
||||||
'': { // Default regional settings - English/US
|
|
||||||
buttonText: '...',
|
|
||||||
buttonStatus: 'Open the keypad',
|
|
||||||
closeText: 'Close',
|
|
||||||
closeStatus: 'Close the keypad',
|
|
||||||
clearText: 'Clear',
|
|
||||||
clearStatus: 'Erase all the text',
|
|
||||||
backText: 'Back',
|
|
||||||
backStatus: 'Erase the previous character',
|
|
||||||
spacebarText: ' ',
|
|
||||||
spacebarStatus: 'Space',
|
|
||||||
enterText: 'Enter',
|
|
||||||
enterStatus: 'Carriage return',
|
|
||||||
tabText: '→',
|
|
||||||
tabStatus: 'Horizontal tab',
|
|
||||||
shiftText: 'Shift',
|
|
||||||
shiftStatus: 'Toggle upper/lower case characters',
|
|
||||||
alphabeticLayout: [], // Set at the end
|
|
||||||
fullLayout: [],
|
|
||||||
isAlphabetic: null,
|
|
||||||
isNumeric: null,
|
|
||||||
toUpper: null,
|
|
||||||
isRTL: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Names of getter methods - those that can't be chained. */
|
|
||||||
_getters: ['isDisabled'],
|
|
||||||
|
|
||||||
_curInst: null, // The current instance in use
|
|
||||||
_disabledFields: [], // List of keypad fields that have been disabled
|
|
||||||
_keypadShowing: false, // True if the popup panel is showing , false if not
|
|
||||||
_keyCode: 0,
|
|
||||||
_specialKeys: [],
|
|
||||||
|
|
||||||
_mainDivClass: pluginName + '-popup', // The main keypad division class
|
|
||||||
_inlineClass: pluginName + '-inline', // The inline marker class
|
|
||||||
_appendClass: pluginName + '-append', // The append marker class
|
|
||||||
_triggerClass: pluginName + '-trigger', // The trigger marker class
|
|
||||||
_disableClass: pluginName + '-disabled', // The disabled covering marker class
|
|
||||||
_inlineEntryClass: pluginName + '-keyentry', // The inline entry marker class
|
|
||||||
_rtlClass: pluginName + '-rtl', // The right-to-left marker class
|
|
||||||
_rowClass: pluginName + '-row', // The keypad row marker class
|
|
||||||
_promptClass: pluginName + '-prompt', // The prompt marker class
|
|
||||||
_specialClass: pluginName + '-special', // The special key marker class
|
|
||||||
_namePrefixClass: pluginName + '-', // The key name marker class prefix
|
|
||||||
_keyClass: pluginName + '-key', // The key marker class
|
|
||||||
_keyDownClass: pluginName + '-key-down', // The key down marker class
|
|
||||||
|
|
||||||
// Standard US keyboard alphabetic layout
|
|
||||||
qwertyAlphabetic: ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'],
|
|
||||||
// Standard US keyboard layout
|
|
||||||
qwertyLayout: ['!@#$%^&*()_=' + this.HALF_SPACE + this.SPACE + this.CLOSE,
|
|
||||||
this.HALF_SPACE + '`~[]{}<>\\|/' + this.SPACE + '789',
|
|
||||||
'qwertyuiop\'"' + this.HALF_SPACE + '456',
|
|
||||||
this.HALF_SPACE + 'asdfghjkl;:' + this.SPACE + '123',
|
|
||||||
this.SPACE + 'zxcvbnm,.?' + this.SPACE + this.HALF_SPACE + '-0+',
|
|
||||||
'' + this.TAB + this.ENTER + this.SPACE_BAR + this.SHIFT +
|
|
||||||
this.HALF_SPACE + this.BACK + this.CLEAR],
|
|
||||||
|
|
||||||
/** Add the definition of a special key.
|
|
||||||
@param id {string} The identifier for this key - access via <code>$.keypad.xxx</code>.<id>.
|
|
||||||
@param name {string} The prefix for localisation strings and the suffix for a class name.
|
|
||||||
@param action {function} The action performed for this key - receives <code>inst</code> as a parameter.
|
|
||||||
@param noHighlight {boolean} True to suppress highlight when using ThemeRoller.
|
|
||||||
@return {Keypad} The keypad object for chaining further calls.
|
|
||||||
@example $.keypad.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); }); */
|
|
||||||
addKeyDef: function(id, name, action, noHighlight) {
|
|
||||||
if (this._keyCode == 32) {
|
|
||||||
throw 'Only 32 special keys allowed';
|
|
||||||
}
|
|
||||||
this[id] = String.fromCharCode(this._keyCode++);
|
|
||||||
this._specialKeys.push({code: this[id], id: id, name: name,
|
|
||||||
action: action, noHighlight: noHighlight});
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Additional setup for the keypad.
|
|
||||||
Create popup div. */
|
|
||||||
_init: function() {
|
|
||||||
this.mainDiv = $('<div class="' + this._mainDivClass + '" style="display: none;"></div>');
|
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
|
|
||||||
_instSettings: function(elem, options) {
|
|
||||||
var inline = !elem[0].nodeName.toLowerCase().match(/input|textarea/);
|
|
||||||
return {_inline: inline, ucase: false,
|
|
||||||
_mainDiv: (inline ? $('<div class="' + this._inlineClass + '"></div>') : plugin.mainDiv)};
|
|
||||||
},
|
|
||||||
|
|
||||||
_postAttach: function(elem, inst) {
|
|
||||||
if (inst._inline) {
|
|
||||||
elem.append(inst._mainDiv).
|
|
||||||
on('click.' + inst.name, function() { inst._input.focus(); });
|
|
||||||
this._updateKeypad(inst);
|
|
||||||
}
|
|
||||||
else if (elem.is(':disabled')) {
|
|
||||||
this.disable(elem);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Determine the input field for the keypad.
|
|
||||||
@private
|
|
||||||
@param elem {jQuery} The target control.
|
|
||||||
@param inst {object} The instance settings. */
|
|
||||||
_setInput: function(elem, inst) {
|
|
||||||
inst._input = $(!inst._inline ? elem : inst.options.target ||
|
|
||||||
'<input type="text" class="' + this._inlineEntryClass + '" disabled/>');
|
|
||||||
if (inst._inline) {
|
|
||||||
elem.find('input').remove();
|
|
||||||
if (!inst.options.target) {
|
|
||||||
elem.append(inst._input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_optionsChanged: function(elem, inst, options) {
|
|
||||||
$.extend(inst.options, options);
|
|
||||||
elem.off('.' + inst.name).
|
|
||||||
siblings('.' + this._appendClass).remove().end().
|
|
||||||
siblings('.' + this._triggerClass).remove();
|
|
||||||
var appendText = inst.options.appendText;
|
|
||||||
if (appendText) {
|
|
||||||
elem[inst.options.isRTL ? 'before' : 'after'](
|
|
||||||
'<span class="' + this._appendClass + '">' + appendText + '</span>');
|
|
||||||
}
|
|
||||||
if (!inst._inline) {
|
|
||||||
if (inst.options.showOn == 'focus' || inst.options.showOn == 'both') {
|
|
||||||
// pop-up keypad when in the marked field
|
|
||||||
elem.on('focus.' + inst.name, this.show).
|
|
||||||
on('keydown.' + inst.name, this._doKeyDown);
|
|
||||||
}
|
|
||||||
if (inst.options.showOn == 'button' || inst.options.showOn == 'both') {
|
|
||||||
// pop-up keypad when button clicked
|
|
||||||
var buttonStatus = inst.options.buttonStatus;
|
|
||||||
var buttonImage = inst.options.buttonImage;
|
|
||||||
var trigger = $(inst.options.buttonImageOnly ?
|
|
||||||
$('<img src="' + buttonImage + '" alt="' +
|
|
||||||
buttonStatus + '" title="' + buttonStatus + '"/>') :
|
|
||||||
$('<button type="button" title="' + buttonStatus + '"></button>').
|
|
||||||
html(buttonImage == '' ? inst.options.buttonText :
|
|
||||||
$('<img src="' + buttonImage + '" alt="' +
|
|
||||||
buttonStatus + '" title="' + buttonStatus + '"/>')));
|
|
||||||
elem[inst.options.isRTL ? 'before' : 'after'](trigger);
|
|
||||||
trigger.addClass(this._triggerClass).click(function() {
|
|
||||||
if (plugin._keypadShowing && plugin._lastField == elem[0]) {
|
|
||||||
plugin.hide();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
plugin.show(elem[0]);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inst.saveReadonly = elem.attr('readonly');
|
|
||||||
elem[inst.options.keypadOnly ? 'attr' : 'removeAttr']('readonly', true).
|
|
||||||
on('setData.' + inst.name, function(event, key, value) {
|
|
||||||
inst.options[key] = value;
|
|
||||||
}).
|
|
||||||
on('getData.' + inst.name, function(event, key) {
|
|
||||||
return inst.options[key];
|
|
||||||
});
|
|
||||||
this._setInput(elem, inst);
|
|
||||||
this._updateKeypad(inst);
|
|
||||||
},
|
|
||||||
|
|
||||||
_preDestroy: function(elem, inst) {
|
|
||||||
if (this._curInst == inst) {
|
|
||||||
this.hide();
|
|
||||||
}
|
|
||||||
elem.siblings('.' + this._appendClass).remove().end().
|
|
||||||
siblings('.' + this._triggerClass).remove().end().
|
|
||||||
prev('.' + this._inlineEntryClass).remove();
|
|
||||||
elem.empty().off('.' + inst.name)
|
|
||||||
[inst.saveReadonly ? 'attr' : 'removeAttr']('readonly', true);
|
|
||||||
inst._input.removeData(inst.name);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Enable the keypad for a jQuery selection.
|
|
||||||
@param elem {Element} The target text field.
|
|
||||||
@example $(selector).keypad('enable'); */
|
|
||||||
enable: function(elem) {
|
|
||||||
elem = $(elem);
|
|
||||||
if (!elem.hasClass(this._getMarker())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var nodeName = elem[0].nodeName.toLowerCase();
|
|
||||||
if (nodeName.match(/input|textarea/)) {
|
|
||||||
elem.prop('disabled', false).
|
|
||||||
siblings('button.' + this._triggerClass).prop('disabled', false).end().
|
|
||||||
siblings('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''});
|
|
||||||
}
|
|
||||||
else if (nodeName.match(/div|span/)) {
|
|
||||||
elem.children('.' + this._disableClass).remove();
|
|
||||||
this._getInst(elem)._mainDiv.find('button').prop('disabled', false);
|
|
||||||
}
|
|
||||||
this._disabledFields = $.map(this._disabledFields,
|
|
||||||
function(value) { return (value == elem[0] ? null : value); }); // delete entry
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Disable the keypad for a jQuery selection.
|
|
||||||
@param elem {Element} The target text field.
|
|
||||||
@example $(selector).keypad('disable'); */
|
|
||||||
disable: function(elem) {
|
|
||||||
elem = $(elem);
|
|
||||||
if (!elem.hasClass(this._getMarker())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var nodeName = elem[0].nodeName.toLowerCase();
|
|
||||||
if (nodeName.match(/input|textarea/)) {
|
|
||||||
elem.prop('disabled', true).
|
|
||||||
siblings('button.' + this._triggerClass).prop('disabled', true).end().
|
|
||||||
siblings('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'});
|
|
||||||
}
|
|
||||||
else if (nodeName.match(/div|span/)) {
|
|
||||||
var inline = elem.children('.' + this._inlineClass);
|
|
||||||
var offset = inline.offset();
|
|
||||||
var relOffset = {left: 0, top: 0};
|
|
||||||
inline.parents().each(function() {
|
|
||||||
if ($(this).css('position') == 'relative') {
|
|
||||||
relOffset = $(this).offset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
elem.prepend('<div class="' + this._disableClass + '" style="width: ' +
|
|
||||||
inline.outerWidth() + 'px; height: ' + inline.outerHeight() +
|
|
||||||
'px; left: ' + (offset.left - relOffset.left) +
|
|
||||||
'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
|
|
||||||
this._getInst(elem)._mainDiv.find('button').prop('disabled', true);
|
|
||||||
}
|
|
||||||
this._disabledFields = $.map(this._disabledFields,
|
|
||||||
function(value) { return (value == elem[0] ? null : value); }); // delete entry
|
|
||||||
this._disabledFields[this._disabledFields.length] = elem[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Is the text field disabled as a keypad?
|
|
||||||
@param elem {Element} The target text field.
|
|
||||||
@return {boolean} True if disabled, false if enabled.
|
|
||||||
@example var disabled = $(selector).keypad('isDisabled'); */
|
|
||||||
isDisabled: function(elem) {
|
|
||||||
return (elem && $.inArray(elem, this._disabledFields) > -1);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Pop-up the keypad for a given text field.
|
|
||||||
@param elem {Element|Event} The text field attached to the keypad or event if triggered by focus.
|
|
||||||
@example $(selector).keypad('show'); */
|
|
||||||
show: function(elem) {
|
|
||||||
elem = elem.target || elem;
|
|
||||||
if (plugin.isDisabled(elem) || plugin._lastField == elem) { // already here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var inst = plugin._getInst(elem);
|
|
||||||
plugin.hide(null, '');
|
|
||||||
plugin._lastField = elem;
|
|
||||||
plugin._pos = plugin._findPos(elem);
|
|
||||||
plugin._pos[1] += elem.offsetHeight; // add the height
|
|
||||||
var isFixed = false;
|
|
||||||
$(elem).parents().each(function() {
|
|
||||||
isFixed |= $(this).css('position') == 'fixed';
|
|
||||||
return !isFixed;
|
|
||||||
});
|
|
||||||
var offset = {left: plugin._pos[0], top: plugin._pos[1]};
|
|
||||||
plugin._pos = null;
|
|
||||||
// determine sizing offscreen
|
|
||||||
inst._mainDiv.css({position: 'absolute', display: 'block', top: '-1000px', width: 'auto'});
|
|
||||||
plugin._updateKeypad(inst);
|
|
||||||
// and adjust position before showing
|
|
||||||
offset = plugin._checkOffset(inst, offset, isFixed);
|
|
||||||
inst._mainDiv.css({position: (isFixed ? 'fixed' : 'absolute'), display: 'none',
|
|
||||||
left: offset.left + 'px', top: offset.top + 'px'});
|
|
||||||
var duration = inst.options.duration;
|
|
||||||
var showAnim = inst.options.showAnim;
|
|
||||||
var postProcess = function() {
|
|
||||||
plugin._keypadShowing = true;
|
|
||||||
};
|
|
||||||
if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {
|
|
||||||
var data = inst._mainDiv.data(); // Update old effects data
|
|
||||||
for (var key in data) {
|
|
||||||
if (key.match(/^ec\.storage\./)) {
|
|
||||||
data[key] = inst._mainDiv.css(key.replace(/ec\.storage\./, ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inst._mainDiv.data(data).show(showAnim,
|
|
||||||
inst.options.showOptions || {}, duration, postProcess);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
inst._mainDiv[showAnim || 'show']((showAnim ? duration : 0), postProcess);
|
|
||||||
}
|
|
||||||
if (inst._input[0].type != 'hidden') {
|
|
||||||
inst._input[0].focus();
|
|
||||||
}
|
|
||||||
plugin._curInst = inst;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Generate the keypad content.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings. */
|
|
||||||
_updateKeypad: function(inst) {
|
|
||||||
var borders = this._getBorders(inst._mainDiv);
|
|
||||||
inst._mainDiv.empty().append(this._generateHTML(inst)).
|
|
||||||
removeClass().addClass(inst.options.keypadClass +
|
|
||||||
(inst.options.useThemeRoller ? ' ui-widget ui-widget-content' : '') +
|
|
||||||
(inst.options.isRTL ? ' ' + this._rtlClass : '') + ' ' +
|
|
||||||
(inst._inline ? this._inlineClass : this._mainDivClass));
|
|
||||||
if ($.isFunction(inst.options.beforeShow)) {
|
|
||||||
inst.options.beforeShow.apply((inst._input ? inst._input[0] : null),
|
|
||||||
[inst._mainDiv, inst]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Retrieve the size of left and top borders for an element.
|
|
||||||
@private
|
|
||||||
@param elem {jQuery} The element of interest.
|
|
||||||
@return {number[]} The left and top borders. */
|
|
||||||
_getBorders: function(elem) {
|
|
||||||
var convert = function(value) {
|
|
||||||
return {thin: 1, medium: 3, thick: 5}[value] || value;
|
|
||||||
};
|
|
||||||
return [parseFloat(convert(elem.css('border-left-width'))),
|
|
||||||
parseFloat(convert(elem.css('border-top-width')))];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Check positioning to remain on screen.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@param offset {object} The current offset.
|
|
||||||
@param isFixed {boolean} True if the text field is fixed in position.
|
|
||||||
@return {object} The updated offset. */
|
|
||||||
_checkOffset: function(inst, offset, isFixed) {
|
|
||||||
var pos = inst._input ? this._findPos(inst._input[0]) : null;
|
|
||||||
var browserWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
||||||
var browserHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
||||||
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
|
|
||||||
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
|
|
||||||
// recalculate width as otherwise set to 100%
|
|
||||||
var width = 0;
|
|
||||||
inst._mainDiv.find(':not(div)').each(function() {
|
|
||||||
width = Math.max(width, this.offsetLeft + $(this).outerWidth(true));
|
|
||||||
});
|
|
||||||
inst._mainDiv.css('width', width + 1);
|
|
||||||
// reposition keypad panel horizontally if outside the browser window
|
|
||||||
if (inst.options.isRTL ||
|
|
||||||
(offset.left + inst._mainDiv.outerWidth() - scrollX) > browserWidth) {
|
|
||||||
offset.left = Math.max((isFixed ? 0 : scrollX),
|
|
||||||
pos[0] + (inst._input ? inst._input.outerWidth() : 0) -
|
|
||||||
(isFixed ? scrollX : 0) - inst._mainDiv.outerWidth());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
offset.left = Math.max((isFixed ? 0 : scrollX), offset.left - (isFixed ? scrollX : 0));
|
|
||||||
}
|
|
||||||
// reposition keypad panel vertically if outside the browser window
|
|
||||||
if ((offset.top + inst._mainDiv.outerHeight() - scrollY) > browserHeight) {
|
|
||||||
offset.top = Math.max((isFixed ? 0 : scrollY),
|
|
||||||
pos[1] - (isFixed ? scrollY : 0) - inst._mainDiv.outerHeight());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
offset.top = Math.max((isFixed ? 0 : scrollY), offset.top - (isFixed ? scrollY : 0));
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Find an object's position on the screen.
|
|
||||||
@private
|
|
||||||
@param obj {Element} The element to find the position for.
|
|
||||||
@return {number[]} The element's position. */
|
|
||||||
_findPos: function(obj) {
|
|
||||||
while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
|
|
||||||
obj = obj.nextSibling;
|
|
||||||
}
|
|
||||||
var position = $(obj).offset();
|
|
||||||
return [position.left, position.top];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Hide the keypad from view.
|
|
||||||
@param elem {Element} The text field attached to the keypad.
|
|
||||||
@param duration {string} The duration over which to close the keypad.
|
|
||||||
@example $(selector).keypad('hide') */
|
|
||||||
hide: function(elem, duration) {
|
|
||||||
var inst = this._curInst;
|
|
||||||
if (!inst || (elem && inst != $.data(elem, this.name))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._keypadShowing) {
|
|
||||||
duration = (duration != null ? duration : inst.options.duration);
|
|
||||||
var showAnim = inst.options.showAnim;
|
|
||||||
if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {
|
|
||||||
inst._mainDiv.hide(showAnim, inst.options.showOptions || {}, duration);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
inst._mainDiv[(showAnim == 'slideDown' ? 'slideUp' :
|
|
||||||
(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))](showAnim ? duration : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($.isFunction(inst.options.onClose)) {
|
|
||||||
inst.options.onClose.apply((inst._input ? inst._input[0] : null), // trigger custom callback
|
|
||||||
[inst._input.val(), inst]);
|
|
||||||
}
|
|
||||||
if (this._keypadShowing) {
|
|
||||||
this._keypadShowing = false;
|
|
||||||
this._lastField = null;
|
|
||||||
}
|
|
||||||
if (inst._inline) {
|
|
||||||
inst._input.val('');
|
|
||||||
}
|
|
||||||
this._curInst = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Handle keystrokes.
|
|
||||||
@private
|
|
||||||
@param event {Event} The key event. */
|
|
||||||
_doKeyDown: function(event) {
|
|
||||||
if (event.keyCode == 9) { // Tab out
|
|
||||||
plugin.mainDiv.stop(true, true);
|
|
||||||
plugin.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Close keypad if clicked elsewhere.
|
|
||||||
@private
|
|
||||||
@param event {Event} The mouseclick details. */
|
|
||||||
_checkExternalClick: function(event) {
|
|
||||||
if (!plugin._curInst) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var target = $(event.target);
|
|
||||||
if (target.closest('.' + plugin._mainDivClass).length === 0 &&
|
|
||||||
!target.hasClass(plugin._getMarker()) &&
|
|
||||||
target.closest('.' + plugin._triggerClass).length === 0 &&
|
|
||||||
plugin._keypadShowing) {
|
|
||||||
plugin.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Toggle between upper and lower case.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings. */
|
|
||||||
_shiftKeypad: function(inst) {
|
|
||||||
inst.ucase = !inst.ucase;
|
|
||||||
this._updateKeypad(inst);
|
|
||||||
inst._input.focus(); // for further typing
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Erase the text field.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings. */
|
|
||||||
_clearValue: function(inst) {
|
|
||||||
this._setValue(inst, '', 0);
|
|
||||||
this._notifyKeypress(inst, plugin.DEL);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Erase the last character.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings. */
|
|
||||||
_backValue: function(inst) {
|
|
||||||
var elem = inst._input[0];
|
|
||||||
var value = inst._input.val();
|
|
||||||
var range = [value.length, value.length];
|
|
||||||
range = (inst._input.prop('readonly') || inst._input.prop('disabled') ? range :
|
|
||||||
(elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
|
|
||||||
(elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
|
|
||||||
this._setValue(inst, (value.length == 0 ? '' :
|
|
||||||
value.substr(0, range[0] - 1) + value.substr(range[1])), range[0] - 1);
|
|
||||||
this._notifyKeypress(inst, plugin.BS);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Update the text field with the selected value.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@param value {string} The new character to add. */
|
|
||||||
_selectValue: function(inst, value) {
|
|
||||||
this.insertValue(inst._input[0], value);
|
|
||||||
this._setValue(inst, inst._input.val());
|
|
||||||
this._notifyKeypress(inst, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Update the text field with the selected value.
|
|
||||||
@param input {string|Element|jQuery} The jQuery selector, input field, or jQuery collection.
|
|
||||||
@param value {string} The new character to add.
|
|
||||||
@example $.keypad.insertValue(field, 'abc'); */
|
|
||||||
insertValue: function(input, value) {
|
|
||||||
input = (input.jquery ? input : $(input));
|
|
||||||
var elem = input[0];
|
|
||||||
var newValue = input.val();
|
|
||||||
var range = [newValue.length, newValue.length];
|
|
||||||
range = (input.attr('readonly') || input.attr('disabled') ? range :
|
|
||||||
(elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
|
|
||||||
(elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
|
|
||||||
input.val(newValue.substr(0, range[0]) + value + newValue.substr(range[1]));
|
|
||||||
pos = range[0] + value.length;
|
|
||||||
if (input.is(':visible')) {
|
|
||||||
input.focus(); // for further typing
|
|
||||||
}
|
|
||||||
if (elem.setSelectionRange) { // Mozilla
|
|
||||||
if (input.is(':visible')) {
|
|
||||||
elem.setSelectionRange(pos, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (elem.createTextRange) { // IE
|
|
||||||
range = elem.createTextRange();
|
|
||||||
range.move('character', pos);
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Get the coordinates for the selected area in the text field in IE.
|
|
||||||
@private
|
|
||||||
@param elem {Element} The target text field.
|
|
||||||
@return {number[]} The start and end positions of the selection. */
|
|
||||||
_getIERange: function(elem) {
|
|
||||||
elem.focus();
|
|
||||||
var selectionRange = document.selection.createRange().duplicate();
|
|
||||||
// Use two ranges: before and selection
|
|
||||||
var beforeRange = this._getIETextRange(elem);
|
|
||||||
beforeRange.setEndPoint('EndToStart', selectionRange);
|
|
||||||
// Check each range for trimmed newlines by shrinking the range by one
|
|
||||||
// character and seeing if the text property has changed. If it has not
|
|
||||||
// changed then we know that IE has trimmed a \r\n from the end.
|
|
||||||
var checkCRLF = function(range) {
|
|
||||||
var origText = range.text;
|
|
||||||
var text = origText;
|
|
||||||
var finished = false;
|
|
||||||
while (true) {
|
|
||||||
if (range.compareEndPoints('StartToEnd', range) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range.moveEnd('character', -1);
|
|
||||||
if (range.text == origText) {
|
|
||||||
text += '\r\n';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
var beforeText = checkCRLF(beforeRange);
|
|
||||||
var selectionText = checkCRLF(selectionRange);
|
|
||||||
return [beforeText.length, beforeText.length + selectionText.length];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Create an IE text range for the text field.
|
|
||||||
@private
|
|
||||||
@param elem {Element} The target text field.
|
|
||||||
@return {object} The corresponding text range. */
|
|
||||||
_getIETextRange: function(elem) {
|
|
||||||
var isInput = (elem.nodeName.toLowerCase() == 'input');
|
|
||||||
var range = (isInput ? elem.createTextRange() : document.body.createTextRange());
|
|
||||||
if (!isInput) {
|
|
||||||
range.moveToElementText(elem); // Selects all the text for a textarea
|
|
||||||
}
|
|
||||||
return range;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Set the text field to the selected value, and trigger any on change event.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@param value {string} The new value for the text field. */
|
|
||||||
_setValue: function(inst, value) {
|
|
||||||
var maxlen = inst._input.attr('maxlength');
|
|
||||||
if (maxlen > -1) {
|
|
||||||
value = value.substr(0, maxlen);
|
|
||||||
}
|
|
||||||
inst._input.val(value);
|
|
||||||
if (!$.isFunction(inst.options.onKeypress)) {
|
|
||||||
inst._input.trigger('change'); // fire the change event
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Notify clients of a keypress.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@param key {string} The character pressed. */
|
|
||||||
_notifyKeypress: function(inst, key) {
|
|
||||||
if ($.isFunction(inst.options.onKeypress)) { // trigger custom callback
|
|
||||||
inst.options.onKeypress.apply((inst._input ? inst._input[0] : null),
|
|
||||||
[key, inst._input.val(), inst]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Generate the HTML for the current state of the keypad.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@return {jQuery} The HTML for this keypad. */
|
|
||||||
_generateHTML: function(inst) {
|
|
||||||
var html = (!inst.options.prompt ? '' : '<div class="' + this._promptClass +
|
|
||||||
(inst.options.useThemeRoller ? ' ui-widget-header ui-corner-all' : '') + '">' +
|
|
||||||
inst.options.prompt + '</div>');
|
|
||||||
var layout = this._randomiseLayout(inst);
|
|
||||||
for (var i = 0; i < layout.length; i++) {
|
|
||||||
html += '<div class="' + this._rowClass + '">';
|
|
||||||
var keys = layout[i].split(inst.options.separator);
|
|
||||||
for (var j = 0; j < keys.length; j++) {
|
|
||||||
if (inst.ucase) {
|
|
||||||
keys[j] = inst.options.toUpper(keys[j]);
|
|
||||||
}
|
|
||||||
var keyDef = this._specialKeys[keys[j].charCodeAt(0)];
|
|
||||||
if (keyDef) {
|
|
||||||
html += (keyDef.action ? '<button type="button" class="' +
|
|
||||||
this._specialClass + ' ' + this._namePrefixClass + keyDef.name +
|
|
||||||
(inst.options.useThemeRoller ? ' ui-corner-all ui-state-default' +
|
|
||||||
(keyDef.noHighlight ? '' : ' ui-state-highlight') : '') +
|
|
||||||
'" title="' + inst.options[keyDef.name + 'Status'] + '">' +
|
|
||||||
(inst.options[keyDef.name + 'Text'] || ' ') + '</button>' :
|
|
||||||
'<div class="' + this._namePrefixClass + keyDef.name + '"></div>');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
html += '<button type="button" class="' + this._keyClass +
|
|
||||||
(inst.options.useThemeRoller ? ' ui-corner-all ui-state-default' : '') +
|
|
||||||
'">' + (keys[j] == ' ' ? ' ' : keys[j]) + '</button>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
html = $(html);
|
|
||||||
var thisInst = inst;
|
|
||||||
var activeClasses = this._keyDownClass +
|
|
||||||
(inst.options.useThemeRoller ? ' ui-state-active' : '');
|
|
||||||
html.find('button').mousedown(function() { $(this).addClass(activeClasses); }).
|
|
||||||
mouseup(function() { $(this).removeClass(activeClasses); }).
|
|
||||||
mouseout(function() { $(this).removeClass(activeClasses); }).
|
|
||||||
filter('.' + this._keyClass).
|
|
||||||
click(function() { plugin._selectValue(thisInst, $(this).text()); });
|
|
||||||
$.each(this._specialKeys, function(i, keyDef) {
|
|
||||||
html.find('.' + plugin._namePrefixClass + keyDef.name).click(function() {
|
|
||||||
keyDef.action.apply(thisInst._input, [thisInst]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return html;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Check whether characters should be randomised, and, if so, produce the randomised layout.
|
|
||||||
@private
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@return {string[]} The layout with any requested randomisations applied. */
|
|
||||||
_randomiseLayout: function(inst) {
|
|
||||||
if (!inst.options.randomiseNumeric && !inst.options.randomiseAlphabetic &&
|
|
||||||
!inst.options.randomiseOther && !inst.options.randomiseAll) {
|
|
||||||
return inst.options.layout;
|
|
||||||
}
|
|
||||||
var numerics = [];
|
|
||||||
var alphas = [];
|
|
||||||
var others = [];
|
|
||||||
var newLayout = [];
|
|
||||||
// Find characters of different types
|
|
||||||
for (var i = 0; i < inst.options.layout.length; i++) {
|
|
||||||
newLayout[i] = '';
|
|
||||||
var keys = inst.options.layout[i].split(inst.options.separator);
|
|
||||||
for (var j = 0; j < keys.length; j++) {
|
|
||||||
if (this._isControl(keys[j])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (inst.options.randomiseAll) {
|
|
||||||
others.push(keys[j]);
|
|
||||||
}
|
|
||||||
else if (inst.options.isNumeric(keys[j])) {
|
|
||||||
numerics.push(keys[j]);
|
|
||||||
}
|
|
||||||
else if (inst.options.isAlphabetic(keys[j])) {
|
|
||||||
alphas.push(keys[j]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
others.push(keys[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Shuffle them
|
|
||||||
if (inst.options.randomiseNumeric) {
|
|
||||||
this._shuffle(numerics);
|
|
||||||
}
|
|
||||||
if (inst.options.randomiseAlphabetic) {
|
|
||||||
this._shuffle(alphas);
|
|
||||||
}
|
|
||||||
if (inst.options.randomiseOther || inst.options.randomiseAll) {
|
|
||||||
this._shuffle(others);
|
|
||||||
}
|
|
||||||
var n = 0;
|
|
||||||
var a = 0;
|
|
||||||
var o = 0;
|
|
||||||
// And replace them in the layout
|
|
||||||
for (var i = 0; i < inst.options.layout.length; i++) {
|
|
||||||
var keys = inst.options.layout[i].split(inst.options.separator);
|
|
||||||
for (var j = 0; j < keys.length; j++) {
|
|
||||||
newLayout[i] += (this._isControl(keys[j]) ? keys[j] :
|
|
||||||
(inst.options.randomiseAll ? others[o++] :
|
|
||||||
(inst.options.isNumeric(keys[j]) ? numerics[n++] :
|
|
||||||
(inst.options.isAlphabetic(keys[j]) ? alphas[a++] :
|
|
||||||
others[o++])))) + inst.options.separator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newLayout;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Is a given character a control character?
|
|
||||||
@private
|
|
||||||
@param ch {string} The character to test.
|
|
||||||
@return {boolean} True if a control character, false if not. */
|
|
||||||
_isControl: function(ch) {
|
|
||||||
return ch < ' ';
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Is a given character alphabetic?
|
|
||||||
@param ch {string} The character to test.
|
|
||||||
@return {boolean} True if alphabetic, false if not. */
|
|
||||||
isAlphabetic: function(ch) {
|
|
||||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Is a given character numeric?
|
|
||||||
@param ch {string} The character to test.
|
|
||||||
@return {boolean} True if numeric, false if not. */
|
|
||||||
isNumeric: function(ch) {
|
|
||||||
return (ch >= '0' && ch <= '9');
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Convert a character to upper case.
|
|
||||||
@param ch {string} The character to convert.
|
|
||||||
@return {string} Its uppercase version. */
|
|
||||||
toUpper: function(ch) {
|
|
||||||
return ch.toUpperCase();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Randomise the contents of an array.
|
|
||||||
@private
|
|
||||||
@param values {string[]} The array to rearrange. */
|
|
||||||
_shuffle: function(values) {
|
|
||||||
for (var i = values.length - 1; i > 0; i--) {
|
|
||||||
var j = Math.floor(Math.random() * values.length);
|
|
||||||
var ch = values[i];
|
|
||||||
values[i] = values[j];
|
|
||||||
values[j] = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var plugin = $.keypad;
|
|
||||||
|
|
||||||
// Initialise the key definitions
|
|
||||||
plugin.addKeyDef('CLOSE', 'close', function(inst) {
|
|
||||||
plugin._curInst = (inst._inline ? inst : plugin._curInst);
|
|
||||||
plugin.hide();
|
|
||||||
});
|
|
||||||
plugin.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); });
|
|
||||||
plugin.addKeyDef('BACK', 'back', function(inst) { plugin._backValue(inst); });
|
|
||||||
plugin.addKeyDef('SHIFT', 'shift', function(inst) { plugin._shiftKeypad(inst); });
|
|
||||||
plugin.addKeyDef('SPACE_BAR', 'spacebar', function(inst) { plugin._selectValue(inst, ' '); }, true);
|
|
||||||
plugin.addKeyDef('SPACE', 'space');
|
|
||||||
plugin.addKeyDef('HALF_SPACE', 'half-space');
|
|
||||||
plugin.addKeyDef('ENTER', 'enter', function(inst) { plugin._selectValue(inst, '\x0D'); }, true);
|
|
||||||
plugin.addKeyDef('TAB', 'tab', function(inst) { plugin._selectValue(inst, '\x09'); }, true);
|
|
||||||
|
|
||||||
// Initialise the layouts and settings
|
|
||||||
plugin.numericLayout = ['123' + plugin.CLOSE, '456' + plugin.CLEAR, '789' + plugin.BACK, plugin.SPACE + '0'];
|
|
||||||
plugin.qwertyLayout = ['!@#$%^&*()_=' + plugin.HALF_SPACE + plugin.SPACE + plugin.CLOSE,
|
|
||||||
plugin.HALF_SPACE + '`~[]{}<>\\|/' + plugin.SPACE + '789',
|
|
||||||
'qwertyuiop\'"' + plugin.HALF_SPACE + '456',
|
|
||||||
plugin.HALF_SPACE + 'asdfghjkl;:' + plugin.SPACE + '123',
|
|
||||||
plugin.SPACE + 'zxcvbnm,.?' + plugin.SPACE + plugin.HALF_SPACE + '-0+',
|
|
||||||
'' + plugin.TAB + plugin.ENTER + plugin.SPACE_BAR + plugin.SHIFT +
|
|
||||||
plugin.HALF_SPACE + plugin.BACK + plugin.CLEAR],
|
|
||||||
$.extend(plugin.regionalOptions[''],
|
|
||||||
{alphabeticLayout: plugin.qwertyAlphabetic, fullLayout: plugin.qwertyLayout,
|
|
||||||
isAlphabetic: plugin.isAlphabetic, isNumeric: plugin.isNumeric, toUpper: plugin.toUpper});
|
|
||||||
plugin.setDefaults($.extend({layout: plugin.numericLayout}, plugin.regionalOptions['']));
|
|
||||||
|
|
||||||
// Add the keypad division and external click check
|
|
||||||
$(function() {
|
|
||||||
$(document.body).append(plugin.mainDiv).
|
|
||||||
on('mousedown.' + pluginName, plugin._checkExternalClick);
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery);
|
|
221
web_app/js/external/jquery.mousewheel.js
vendored
Normal file
221
web_app/js/external/jquery.mousewheel.js
vendored
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
/* Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
|
||||||
|
* Licensed under the MIT License (LICENSE.txt).
|
||||||
|
*
|
||||||
|
* Version: 3.1.12
|
||||||
|
*
|
||||||
|
* Requires: jQuery 1.2.2+
|
||||||
|
*/
|
||||||
|
/*! Mousewheel version: 3.1.12 * (c) 2014 Brandon Aaron * MIT License */
|
||||||
|
(function (factory) {
|
||||||
|
if ( typeof define === 'function' && define.amd ) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node/CommonJS style for Browserify
|
||||||
|
module.exports = factory;
|
||||||
|
} else {
|
||||||
|
// Browser globals
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function ($) {
|
||||||
|
|
||||||
|
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
|
||||||
|
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
|
||||||
|
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
|
||||||
|
slice = Array.prototype.slice,
|
||||||
|
nullLowestDeltaTimeout, lowestDelta;
|
||||||
|
|
||||||
|
if ( $.event.fixHooks ) {
|
||||||
|
for ( var i = toFix.length; i; ) {
|
||||||
|
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var special = $.event.special.mousewheel = {
|
||||||
|
version: '3.1.12',
|
||||||
|
|
||||||
|
setup: function() {
|
||||||
|
if ( this.addEventListener ) {
|
||||||
|
for ( var i = toBind.length; i; ) {
|
||||||
|
this.addEventListener( toBind[--i], handler, false );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onmousewheel = handler;
|
||||||
|
}
|
||||||
|
// Store the line height and page height for this particular element
|
||||||
|
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
|
||||||
|
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
teardown: function() {
|
||||||
|
if ( this.removeEventListener ) {
|
||||||
|
for ( var i = toBind.length; i; ) {
|
||||||
|
this.removeEventListener( toBind[--i], handler, false );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onmousewheel = null;
|
||||||
|
}
|
||||||
|
// Clean up the data we added to the element
|
||||||
|
$.removeData(this, 'mousewheel-line-height');
|
||||||
|
$.removeData(this, 'mousewheel-page-height');
|
||||||
|
},
|
||||||
|
|
||||||
|
getLineHeight: function(elem) {
|
||||||
|
var $elem = $(elem),
|
||||||
|
$parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
|
||||||
|
if (!$parent.length) {
|
||||||
|
$parent = $('body');
|
||||||
|
}
|
||||||
|
return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
|
||||||
|
},
|
||||||
|
|
||||||
|
getPageHeight: function(elem) {
|
||||||
|
return $(elem).height();
|
||||||
|
},
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
|
||||||
|
normalizeOffset: true // calls getBoundingClientRect for each event
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.extend({
|
||||||
|
mousewheel: function(fn) {
|
||||||
|
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
|
||||||
|
},
|
||||||
|
|
||||||
|
unmousewheel: function(fn) {
|
||||||
|
return this.unbind('mousewheel', fn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function handler(event) {
|
||||||
|
var orgEvent = event || window.event,
|
||||||
|
args = slice.call(arguments, 1),
|
||||||
|
delta = 0,
|
||||||
|
deltaX = 0,
|
||||||
|
deltaY = 0,
|
||||||
|
absDelta = 0,
|
||||||
|
offsetX = 0,
|
||||||
|
offsetY = 0;
|
||||||
|
event = $.event.fix(orgEvent);
|
||||||
|
event.type = 'mousewheel';
|
||||||
|
|
||||||
|
// Old school scrollwheel delta
|
||||||
|
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
|
||||||
|
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
|
||||||
|
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
|
||||||
|
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
|
||||||
|
|
||||||
|
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
|
||||||
|
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||||
|
deltaX = deltaY * -1;
|
||||||
|
deltaY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
|
||||||
|
delta = deltaY === 0 ? deltaX : deltaY;
|
||||||
|
|
||||||
|
// New school wheel delta (wheel event)
|
||||||
|
if ( 'deltaY' in orgEvent ) {
|
||||||
|
deltaY = orgEvent.deltaY * -1;
|
||||||
|
delta = deltaY;
|
||||||
|
}
|
||||||
|
if ( 'deltaX' in orgEvent ) {
|
||||||
|
deltaX = orgEvent.deltaX;
|
||||||
|
if ( deltaY === 0 ) { delta = deltaX * -1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// No change actually happened, no reason to go any further
|
||||||
|
if ( deltaY === 0 && deltaX === 0 ) { return; }
|
||||||
|
|
||||||
|
// Need to convert lines and pages to pixels if we aren't already in pixels
|
||||||
|
// There are three delta modes:
|
||||||
|
// * deltaMode 0 is by pixels, nothing to do
|
||||||
|
// * deltaMode 1 is by lines
|
||||||
|
// * deltaMode 2 is by pages
|
||||||
|
if ( orgEvent.deltaMode === 1 ) {
|
||||||
|
var lineHeight = $.data(this, 'mousewheel-line-height');
|
||||||
|
delta *= lineHeight;
|
||||||
|
deltaY *= lineHeight;
|
||||||
|
deltaX *= lineHeight;
|
||||||
|
} else if ( orgEvent.deltaMode === 2 ) {
|
||||||
|
var pageHeight = $.data(this, 'mousewheel-page-height');
|
||||||
|
delta *= pageHeight;
|
||||||
|
deltaY *= pageHeight;
|
||||||
|
deltaX *= pageHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store lowest absolute delta to normalize the delta values
|
||||||
|
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
|
||||||
|
|
||||||
|
if ( !lowestDelta || absDelta < lowestDelta ) {
|
||||||
|
lowestDelta = absDelta;
|
||||||
|
|
||||||
|
// Adjust older deltas if necessary
|
||||||
|
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||||
|
lowestDelta /= 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust older deltas if necessary
|
||||||
|
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||||
|
// Divide all the things by 40!
|
||||||
|
delta /= 40;
|
||||||
|
deltaX /= 40;
|
||||||
|
deltaY /= 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a whole, normalized value for the deltas
|
||||||
|
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
|
||||||
|
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
|
||||||
|
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
|
||||||
|
|
||||||
|
// Normalise offsetX and offsetY properties
|
||||||
|
if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
|
||||||
|
var boundingRect = this.getBoundingClientRect();
|
||||||
|
offsetX = event.clientX - boundingRect.left;
|
||||||
|
offsetY = event.clientY - boundingRect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add information to the event object
|
||||||
|
event.deltaX = deltaX;
|
||||||
|
event.deltaY = deltaY;
|
||||||
|
event.deltaFactor = lowestDelta;
|
||||||
|
event.offsetX = offsetX;
|
||||||
|
event.offsetY = offsetY;
|
||||||
|
// Go ahead and set deltaMode to 0 since we converted to pixels
|
||||||
|
// Although this is a little odd since we overwrite the deltaX/Y
|
||||||
|
// properties with normalized deltas.
|
||||||
|
event.deltaMode = 0;
|
||||||
|
|
||||||
|
// Add event and delta to the front of the arguments
|
||||||
|
args.unshift(event, delta, deltaX, deltaY);
|
||||||
|
|
||||||
|
// Clearout lowestDelta after sometime to better
|
||||||
|
// handle multiple device types that give different
|
||||||
|
// a different lowestDelta
|
||||||
|
// Ex: trackpad = 3 and mouse wheel = 120
|
||||||
|
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
|
||||||
|
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
|
||||||
|
|
||||||
|
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
function nullLowestDelta() {
|
||||||
|
lowestDelta = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldAdjustOldDeltas(orgEvent, absDelta) {
|
||||||
|
// If this is an older event and the delta is divisable by 120,
|
||||||
|
// then we are assuming that the browser is treating this as an
|
||||||
|
// older mouse wheel event and that we should divide the deltas
|
||||||
|
// by 40 to try and get a more usable deltaFactor.
|
||||||
|
// Side note, this actually impacts the reported scroll distance
|
||||||
|
// in older browsers and can cause scrolling to be slower than native.
|
||||||
|
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
|
||||||
|
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
344
web_app/js/external/jquery.plugin.js
vendored
344
web_app/js/external/jquery.plugin.js
vendored
|
@ -1,344 +0,0 @@
|
||||||
/* Simple JavaScript Inheritance
|
|
||||||
* By John Resig http://ejohn.org/
|
|
||||||
* MIT Licensed.
|
|
||||||
*/
|
|
||||||
// Inspired by base2 and Prototype
|
|
||||||
(function(){
|
|
||||||
var initializing = false;
|
|
||||||
|
|
||||||
// The base JQClass implementation (does nothing)
|
|
||||||
window.JQClass = function(){};
|
|
||||||
|
|
||||||
// Collection of derived classes
|
|
||||||
JQClass.classes = {};
|
|
||||||
|
|
||||||
// Create a new JQClass that inherits from this class
|
|
||||||
JQClass.extend = function extender(prop) {
|
|
||||||
var base = this.prototype;
|
|
||||||
|
|
||||||
// Instantiate a base class (but only create the instance,
|
|
||||||
// don't run the init constructor)
|
|
||||||
initializing = true;
|
|
||||||
var prototype = new this();
|
|
||||||
initializing = false;
|
|
||||||
|
|
||||||
// Copy the properties over onto the new prototype
|
|
||||||
for (var name in prop) {
|
|
||||||
// Check if we're overwriting an existing function
|
|
||||||
prototype[name] = typeof prop[name] == 'function' &&
|
|
||||||
typeof base[name] == 'function' ?
|
|
||||||
(function(name, fn){
|
|
||||||
return function() {
|
|
||||||
var __super = this._super;
|
|
||||||
|
|
||||||
// Add a new ._super() method that is the same method
|
|
||||||
// but on the super-class
|
|
||||||
this._super = function(args) {
|
|
||||||
return base[name].apply(this, args || []);
|
|
||||||
};
|
|
||||||
|
|
||||||
var ret = fn.apply(this, arguments);
|
|
||||||
|
|
||||||
// The method only need to be bound temporarily, so we
|
|
||||||
// remove it when we're done executing
|
|
||||||
this._super = __super;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
})(name, prop[name]) :
|
|
||||||
prop[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
// The dummy class constructor
|
|
||||||
function JQClass() {
|
|
||||||
// All construction is actually done in the init method
|
|
||||||
if (!initializing && this._init) {
|
|
||||||
this._init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate our constructed prototype object
|
|
||||||
JQClass.prototype = prototype;
|
|
||||||
|
|
||||||
// Enforce the constructor to be what we expect
|
|
||||||
JQClass.prototype.constructor = JQClass;
|
|
||||||
|
|
||||||
// And make this class extendable
|
|
||||||
JQClass.extend = extender;
|
|
||||||
|
|
||||||
return JQClass;
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function($) { // Ensure $, encapsulate
|
|
||||||
|
|
||||||
/** Abstract base class for collection plugins v1.0.1.
|
|
||||||
Written by Keith Wood (kbwood{at}iinet.com.au) December 2013.
|
|
||||||
Licensed under the MIT (https://github.com/jquery/jquery/blob/master/LICENSE.txt) license.
|
|
||||||
@module $.JQPlugin
|
|
||||||
@abstract */
|
|
||||||
JQClass.classes.JQPlugin = JQClass.extend({
|
|
||||||
|
|
||||||
/** Name to identify this plugin.
|
|
||||||
@example name: 'tabs' */
|
|
||||||
name: 'plugin',
|
|
||||||
|
|
||||||
/** Default options for instances of this plugin (default: {}).
|
|
||||||
@example defaultOptions: {
|
|
||||||
selectedClass: 'selected',
|
|
||||||
triggers: 'click'
|
|
||||||
} */
|
|
||||||
defaultOptions: {},
|
|
||||||
|
|
||||||
/** Options dependent on the locale.
|
|
||||||
Indexed by language and (optional) country code, with '' denoting the default language (English/US).
|
|
||||||
@example regionalOptions: {
|
|
||||||
'': {
|
|
||||||
greeting: 'Hi'
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
regionalOptions: {},
|
|
||||||
|
|
||||||
/** Names of getter methods - those that can't be chained (default: []).
|
|
||||||
@example _getters: ['activeTab'] */
|
|
||||||
_getters: [],
|
|
||||||
|
|
||||||
/** Retrieve a marker class for affected elements.
|
|
||||||
@private
|
|
||||||
@return {string} The marker class. */
|
|
||||||
_getMarker: function() {
|
|
||||||
return 'is-' + this.name;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Initialise the plugin.
|
|
||||||
Create the jQuery bridge - plugin name <code>xyz</code>
|
|
||||||
produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */
|
|
||||||
_init: function() {
|
|
||||||
// Apply default localisations
|
|
||||||
$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});
|
|
||||||
// Camel-case the name
|
|
||||||
var jqName = camelCase(this.name);
|
|
||||||
// Expose jQuery singleton manager
|
|
||||||
$[jqName] = this;
|
|
||||||
// Expose jQuery collection plugin
|
|
||||||
$.fn[jqName] = function(options) {
|
|
||||||
var otherArgs = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if ($[jqName]._isNotChained(options, otherArgs)) {
|
|
||||||
return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));
|
|
||||||
}
|
|
||||||
return this.each(function() {
|
|
||||||
if (typeof options === 'string') {
|
|
||||||
if (options[0] === '_' || !$[jqName][options]) {
|
|
||||||
throw 'Unknown method: ' + options;
|
|
||||||
}
|
|
||||||
$[jqName][options].apply($[jqName], [this].concat(otherArgs));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$[jqName]._attach(this, options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Set default values for all subsequent instances.
|
|
||||||
@param options {object} The new default options.
|
|
||||||
@example $.plugin.setDefauls({name: value}) */
|
|
||||||
setDefaults: function(options) {
|
|
||||||
$.extend(this.defaultOptions, options || {});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Determine whether a method is a getter and doesn't permit chaining.
|
|
||||||
@private
|
|
||||||
@param name {string} The method name.
|
|
||||||
@param otherArgs {any[]} Any other arguments for the method.
|
|
||||||
@return {boolean} True if this method is a getter, false otherwise. */
|
|
||||||
_isNotChained: function(name, otherArgs) {
|
|
||||||
if (name === 'option' && (otherArgs.length === 0 ||
|
|
||||||
(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return $.inArray(name, this._getters) > -1;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Initialise an element. Called internally only.
|
|
||||||
Adds an instance object as data named for the plugin.
|
|
||||||
@param elem {Element} The element to enhance.
|
|
||||||
@param options {object} Overriding settings. */
|
|
||||||
_attach: function(elem, options) {
|
|
||||||
elem = $(elem);
|
|
||||||
if (elem.hasClass(this._getMarker())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
elem.addClass(this._getMarker());
|
|
||||||
options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});
|
|
||||||
var inst = $.extend({name: this.name, elem: elem, options: options},
|
|
||||||
this._instSettings(elem, options));
|
|
||||||
elem.data(this.name, inst); // Save instance against element
|
|
||||||
this._postAttach(elem, inst);
|
|
||||||
this.option(elem, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Retrieve additional instance settings.
|
|
||||||
Override this in a sub-class to provide extra settings.
|
|
||||||
@param elem {jQuery} The current jQuery element.
|
|
||||||
@param options {object} The instance options.
|
|
||||||
@return {object} Any extra instance values.
|
|
||||||
@example _instSettings: function(elem, options) {
|
|
||||||
return {nav: elem.find(options.navSelector)};
|
|
||||||
} */
|
|
||||||
_instSettings: function(elem, options) {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Plugin specific post initialisation.
|
|
||||||
Override this in a sub-class to perform extra activities.
|
|
||||||
@param elem {jQuery} The current jQuery element.
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@example _postAttach: function(elem, inst) {
|
|
||||||
elem.on('click.' + this.name, function() {
|
|
||||||
...
|
|
||||||
});
|
|
||||||
} */
|
|
||||||
_postAttach: function(elem, inst) {
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Retrieve metadata configuration from the element.
|
|
||||||
Metadata is specified as an attribute:
|
|
||||||
<code>data-<plugin name>="<setting name>: '<value>', ..."</code>.
|
|
||||||
Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
|
|
||||||
@private
|
|
||||||
@param elem {jQuery} The source element.
|
|
||||||
@return {object} The inline configuration or {}. */
|
|
||||||
_getMetadata: function(elem) {
|
|
||||||
try {
|
|
||||||
var data = elem.data(this.name.toLowerCase()) || '';
|
|
||||||
data = data.replace(/'/g, '"');
|
|
||||||
data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) {
|
|
||||||
var count = data.substring(0, i).match(/"/g); // Handle embedded ':'
|
|
||||||
return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':');
|
|
||||||
});
|
|
||||||
data = $.parseJSON('{' + data + '}');
|
|
||||||
for (var name in data) { // Convert dates
|
|
||||||
var value = data[name];
|
|
||||||
if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) {
|
|
||||||
data[name] = eval(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Retrieve the instance data for element.
|
|
||||||
@param elem {Element} The source element.
|
|
||||||
@return {object} The instance data or {}. */
|
|
||||||
_getInst: function(elem) {
|
|
||||||
return $(elem).data(this.name) || {};
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Retrieve or reconfigure the settings for a plugin.
|
|
||||||
@param elem {Element} The source element.
|
|
||||||
@param name {object|string} The collection of new option values or the name of a single option.
|
|
||||||
@param [value] {any} The value for a single named option.
|
|
||||||
@return {any|object} If retrieving a single value or all options.
|
|
||||||
@example $(selector).plugin('option', 'name', value)
|
|
||||||
$(selector).plugin('option', {name: value, ...})
|
|
||||||
var value = $(selector).plugin('option', 'name')
|
|
||||||
var options = $(selector).plugin('option') */
|
|
||||||
option: function(elem, name, value) {
|
|
||||||
elem = $(elem);
|
|
||||||
var inst = elem.data(this.name);
|
|
||||||
if (!name || (typeof name === 'string' && value == null)) {
|
|
||||||
var options = (inst || {}).options;
|
|
||||||
return (options && name ? options[name] : options);
|
|
||||||
}
|
|
||||||
if (!elem.hasClass(this._getMarker())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var options = name || {};
|
|
||||||
if (typeof name === 'string') {
|
|
||||||
options = {};
|
|
||||||
options[name] = value;
|
|
||||||
}
|
|
||||||
this._optionsChanged(elem, inst, options);
|
|
||||||
$.extend(inst.options, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Plugin specific options processing.
|
|
||||||
Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>.
|
|
||||||
Override this in a sub-class to perform extra activities.
|
|
||||||
@param elem {jQuery} The current jQuery element.
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@param options {object} The new options.
|
|
||||||
@example _optionsChanged: function(elem, inst, options) {
|
|
||||||
if (options.name != inst.options.name) {
|
|
||||||
elem.removeClass(inst.options.name).addClass(options.name);
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
_optionsChanged: function(elem, inst, options) {
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Remove all trace of the plugin.
|
|
||||||
Override <code>_preDestroy</code> for plugin-specific processing.
|
|
||||||
@param elem {Element} The source element.
|
|
||||||
@example $(selector).plugin('destroy') */
|
|
||||||
destroy: function(elem) {
|
|
||||||
elem = $(elem);
|
|
||||||
if (!elem.hasClass(this._getMarker())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._preDestroy(elem, this._getInst(elem));
|
|
||||||
elem.removeData(this.name).removeClass(this._getMarker());
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Plugin specific pre destruction.
|
|
||||||
Override this in a sub-class to perform extra activities and undo everything that was
|
|
||||||
done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions.
|
|
||||||
@param elem {jQuery} The current jQuery element.
|
|
||||||
@param inst {object} The instance settings.
|
|
||||||
@example _preDestroy: function(elem, inst) {
|
|
||||||
elem.off('.' + this.name);
|
|
||||||
} */
|
|
||||||
_preDestroy: function(elem, inst) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Convert names from hyphenated to camel-case.
|
|
||||||
@private
|
|
||||||
@param value {string} The original hyphenated name.
|
|
||||||
@return {string} The camel-case version. */
|
|
||||||
function camelCase(name) {
|
|
||||||
return name.replace(/-([a-z])/g, function(match, group) {
|
|
||||||
return group.toUpperCase();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Expose the plugin base.
|
|
||||||
@namespace "$.JQPlugin" */
|
|
||||||
$.JQPlugin = {
|
|
||||||
|
|
||||||
/** Create a new collection plugin.
|
|
||||||
@memberof "$.JQPlugin"
|
|
||||||
@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.
|
|
||||||
@param overrides {object} The property/function overrides for the new class.
|
|
||||||
@example $.JQPlugin.createPlugin({
|
|
||||||
name: 'tabs',
|
|
||||||
defaultOptions: {selectedClass: 'selected'},
|
|
||||||
_initSettings: function(elem, options) { return {...}; },
|
|
||||||
_postAttach: function(elem, inst) { ... }
|
|
||||||
}); */
|
|
||||||
createPlugin: function(superClass, overrides) {
|
|
||||||
if (typeof superClass === 'object') {
|
|
||||||
overrides = superClass;
|
|
||||||
superClass = 'JQPlugin';
|
|
||||||
}
|
|
||||||
superClass = camelCase(superClass);
|
|
||||||
var className = camelCase(overrides.name);
|
|
||||||
JQClass.classes[className] = JQClass.classes[superClass].extend(overrides);
|
|
||||||
new JQClass.classes[className]();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery);
|
|
1195
web_app/js/external/jquery.timepicker.js
vendored
Normal file
1195
web_app/js/external/jquery.timepicker.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
7
web_app/js/external/jquery.timepicker.min.js
vendored
Normal file
7
web_app/js/external/jquery.timepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -69,20 +69,38 @@ function setup_ui_elements()
|
||||||
});
|
});
|
||||||
|
|
||||||
// set up keypads
|
// set up keypads
|
||||||
|
/*
|
||||||
$( "#current_rank" ).keypad(); // {prompt: 'Enter here'}
|
$( "#current_rank" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#current_exp" ).keypad(); // {prompt: 'Enter here'}
|
$( "#current_exp" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#desired_rank" ).keypad(); // {prompt: 'Enter here'}
|
$( "#desired_rank" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#current_gems" ).keypad(); // {prompt: 'Enter here'}
|
$( "#current_gems" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#gem_desired_gems" ).keypad(); // {prompt: 'Enter here'}
|
$( "#" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#card_current_level" ).keypad(); // {prompt: 'Enter here'}
|
$( "#" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#card_current_exp" ).keypad(); // {prompt: 'Enter here'}
|
$( "#" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#card_desired_level" ).keypad(); // {prompt: 'Enter here'}
|
$( "#" ).keypad(); // {prompt: 'Enter here'}
|
||||||
$( "#card_feed_exp" ).keypad(); // {prompt: 'Enter here'}
|
$( "#" ).keypad(); // {prompt: 'Enter here'}
|
||||||
|
*/
|
||||||
|
["current_rank", "current_exp", "desired_rank", "current_gems", "gem_desired_gems", "card_current_level", "card_current_exp", "card_desired_level", "card_feed_exp"].forEach(function(entry) {
|
||||||
|
var selector = "#" + entry;
|
||||||
|
LOG(1, "setting up " + selector);
|
||||||
|
// $(selector).keypad()
|
||||||
|
$(selector)
|
||||||
|
.keyboard({
|
||||||
|
layout : 'custom',
|
||||||
|
customLayout: { 'default': ['1 2 3', '4 5 6', '7 8 9', '{empty} 0 {empty}', '{b} {c} {a}'] },
|
||||||
|
restrictInput : true, // Prevent keys not in the displayed keyboard from being typed in
|
||||||
|
preventPaste : true, // prevent ctrl-v and right click
|
||||||
|
autoAccept : true
|
||||||
|
})
|
||||||
|
.addTyping();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// set up date/time pickers
|
// set up date/time pickers
|
||||||
$( "#gem_desired_date" ).datepicker();
|
$( "#gem_desired_date" ).datepicker();
|
||||||
$( "#event_end_date" ).datepicker();
|
$( "#event_end_date" ).datepicker();
|
||||||
$( "#event_end_time" ).timepicker();
|
// $( "#event_end_time" ).timepicker();
|
||||||
|
$('#event_end_time').timepicker({ 'timeFormat': 'H:i' });
|
||||||
|
|
||||||
// set up buttons
|
// set up buttons
|
||||||
["calculate-rank", "reset-rank", "calculate-gems", "reset-gems", "calculate-card", "reset-card", "start-stop-timer", "clear-timer"].forEach(function(entry) {
|
["calculate-rank", "reset-rank", "calculate-gems", "reset-gems", "calculate-card", "reset-card", "start-stop-timer", "clear-timer"].forEach(function(entry) {
|
||||||
|
|
|
@ -7,13 +7,15 @@
|
||||||
<title>SIF Tools</title>
|
<title>SIF Tools</title>
|
||||||
<link href="css/external/jquery-ui.css" rel="stylesheet">
|
<link href="css/external/jquery-ui.css" rel="stylesheet">
|
||||||
<link href="css/external/jquery-ui-timepicker-addon.css" rel="stylesheet">
|
<link href="css/external/jquery-ui-timepicker-addon.css" rel="stylesheet">
|
||||||
<link type="text/css" href="css/external/jquery.keypad.css" rel="stylesheet">
|
<link href="css/external/keyboard.css" rel="stylesheet">
|
||||||
|
<link href="css/external/keyboard-previewkeyset.css" rel="stylesheet">
|
||||||
|
<link href="css/external/jquery.timepicker.css" rel="stylesheet">
|
||||||
<link href="css/sif-tools.css" rel="stylesheet">
|
<link href="css/sif-tools.css" rel="stylesheet">
|
||||||
<script src="js/external/jquery.js"></script>
|
<script src="js/external/jquery.js"></script>
|
||||||
<script type="text/javascript" src="js/external/jquery.plugin.js"></script>
|
<script src="js/external/jquery.keyboard.js"></script>
|
||||||
<script type="text/javascript" src="js/external/jquery.keypad.js"></script>
|
<script src="js/external/jquery.keyboard.extension-all.js"></script>
|
||||||
<script src="js/external/jquery-ui.js"></script>
|
<script src="js/external/jquery-ui.js"></script>
|
||||||
<script src="js/external/jquery-ui-timepicker-addon.js"></script>
|
<script src="js/external/jquery.timepicker.js"></script>
|
||||||
<script src="js/external/jquery-ui-sliderAccess.js"></script>
|
<script src="js/external/jquery-ui-sliderAccess.js"></script>
|
||||||
<script src="js/external/moment.js"></script>
|
<script src="js/external/moment.js"></script>
|
||||||
<script src="js/external/sprintf.js"></script>
|
<script src="js/external/sprintf.js"></script>
|
||||||
|
@ -36,11 +38,11 @@
|
||||||
|
|
||||||
<div id="tab-rank">
|
<div id="tab-rank">
|
||||||
<div id="the-form" align="center">
|
<div id="the-form" align="center">
|
||||||
Current Rank: <input type="text" readonly="true" size="5" id="current_rank" name="current_rank" placeholder="rank" value="" />
|
Current Rank: <input type="text" size="5" id="current_rank" name="current_rank" placeholder="rank" value="" />
|
||||||
<br />
|
<br />
|
||||||
Current EXP: <input type="text" readonly="true" size="5" id="current_exp" name="current_exp" placeholder="optional" value="" />
|
Current EXP: <input type="text" size="5" id="current_exp" name="current_exp" placeholder="optional" value="" />
|
||||||
<br />
|
<br />
|
||||||
Desired Rank: <input type="text" readonly="true" size="5" id="desired_rank" name="desired_rank" placeholder="rank" value="" />
|
Desired Rank: <input type="text" size="5" id="desired_rank" name="desired_rank" placeholder="rank" value="" />
|
||||||
<br />
|
<br />
|
||||||
Game Version:
|
Game Version:
|
||||||
<select id="game_version" name="game_version">
|
<select id="game_version" name="game_version">
|
||||||
|
@ -65,16 +67,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="tab-love-gem">
|
<div id="tab-love-gem">
|
||||||
<div id="love-gem-form" align="center">
|
<div id="love-gem-form" align="center">
|
||||||
Current Gems: <input type="text" readonly="true" size="5" id="current_gems" name="current_gems" placeholder="optional" value="" />
|
Current Gems: <input type="text" size="5" id="current_gems" name="current_gems" placeholder="optional" value="" />
|
||||||
<br /><br />
|
<br /><br />
|
||||||
Mode:<br />
|
Mode:<br />
|
||||||
<input type="radio" name="gem-mode" id="gem-mode" value="DATE" checked />Number of gems on date?<br />
|
<input type="radio" name="gem-mode" id="gem-mode" value="DATE" checked />Number of gems on date?<br />
|
||||||
<input type="radio" name="gem-mode" id="gem-mode" value="GEMS" />Date when you get <i>x</i> gems?<br /><br />
|
<input type="radio" name="gem-mode" id="gem-mode" value="GEMS" />Date when you get <i>x</i> gems?<br /><br />
|
||||||
<div id="gem-date-area">
|
<div id="gem-date-area">
|
||||||
Date: <input type="text" size="10" id="gem_desired_date" name="gem_desired_date" readonly="true" placeholder="MM/DD/YYYY" value="" />
|
Date: <input type="text" size="10" id="gem_desired_date" name="gem_desired_date" placeholder="MM/DD/YYYY" value="" />
|
||||||
</div>
|
</div>
|
||||||
<div id="gem-desired-gems-area">
|
<div id="gem-desired-gems-area">
|
||||||
Desired gems: <input type="text" readonly="true" size="5" id="gem_desired_gems" name="gem_desired_gems" placeholder="gems" value="" />
|
Desired gems: <input type="text" size="5" id="gem_desired_gems" name="gem_desired_gems" placeholder="gems" value="" />
|
||||||
</div>
|
</div>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<input type="checkbox" name="gems_verbose" id="gems_verbose" value="YES" />Verbose Mode<br />
|
<input type="checkbox" name="gems_verbose" id="gems_verbose" value="YES" />Verbose Mode<br />
|
||||||
|
@ -102,18 +104,18 @@
|
||||||
<option value="UR">UR</option>
|
<option value="UR">UR</option>
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
Current Level: <input type="text" readonly="true" size="5" id="card_current_level" name="card_current_level" placeholder="level" value="" />
|
Current Level: <input type="text" size="5" id="card_current_level" name="card_current_level" placeholder="level" value="" />
|
||||||
<br />
|
<br />
|
||||||
Current EXP: <input type="text" readonly="true" size="5" id="card_current_exp" name="card_current_exp" placeholder="optional" value="" />
|
Current EXP: <input type="text" size="5" id="card_current_exp" name="card_current_exp" placeholder="optional" value="" />
|
||||||
<br /><br />
|
<br /><br />
|
||||||
Mode:<br />
|
Mode:<br />
|
||||||
<input type="radio" name="card-mode" id="card-mode" value="LEVEL" checked />EXP needed to level?<br />
|
<input type="radio" name="card-mode" id="card-mode" value="LEVEL" checked />EXP needed to level?<br />
|
||||||
<input type="radio" name="card-mode" id="card-mode" value="EXP" />Final level after feeding?<br /><br />
|
<input type="radio" name="card-mode" id="card-mode" value="EXP" />Final level after feeding?<br /><br />
|
||||||
<div id="card-level-area">
|
<div id="card-level-area">
|
||||||
Desired level: <input type="text" readonly="true" size="5" id="card_desired_level" name="card_desired_level" placeholder="level" value="" />
|
Desired level: <input type="text" size="5" id="card_desired_level" name="card_desired_level" placeholder="level" value="" />
|
||||||
</div>
|
</div>
|
||||||
<div id="card-exp-area">
|
<div id="card-exp-area">
|
||||||
EXP: <input type="text" readonly="true" size="5" id="card_feed_exp" name="card_feed_exp" placeholder="exp" value="" />
|
EXP: <input type="text" size="5" id="card_feed_exp" name="card_feed_exp" placeholder="exp" value="" />
|
||||||
</div>
|
</div>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<div id="button-calculate-card">Calculate</div>
|
<div id="button-calculate-card">Calculate</div>
|
||||||
|
@ -129,8 +131,8 @@
|
||||||
<div id="tab-event">
|
<div id="tab-event">
|
||||||
<div id="event-timer-form" align="center">
|
<div id="event-timer-form" align="center">
|
||||||
<h3>Enter Event End Date/Time (in UTC):</h3><br />
|
<h3>Enter Event End Date/Time (in UTC):</h3><br />
|
||||||
<input type="text" size="10" id="event_end_date" name="event_end_date" readonly="true" placeholder="MM/DD/YYYY" value="" />
|
<input type="text" size="10" id="event_end_date" name="event_end_date" placeholder="MM/DD/YYYY" value="" />
|
||||||
<input type="text" size="5" id="event_end_time" name="event_end_time" readonly="true" placeholder="HH:MM" value="" />
|
<input type="text" size="5" id="event_end_time" name="event_end_time" placeholder="HH:MM" value="" />
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<div id="button-start-stop-timer">Start Timer</div>
|
<div id="button-start-stop-timer">Start Timer</div>
|
||||||
<div id="timer_output_area" align="center">
|
<div id="timer_output_area" align="center">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue