| 1602 | // This code is required since some browsers on Android are inconsistent in |
| 1603 | // sending keyCodes in the normal keyboard events when using on screen keyboards. |
| 1604 | keyInput(event) { |
| 1605 | |
| 1606 | if (!UI.rfb) return; |
| 1607 | |
| 1608 | const newValue = event.target.value; |
| 1609 | |
| 1610 | if (!UI.lastKeyboardinput) { |
| 1611 | UI.keyboardinputReset(); |
| 1612 | } |
| 1613 | const oldValue = UI.lastKeyboardinput; |
| 1614 | |
| 1615 | let newLen; |
| 1616 | try { |
| 1617 | // Try to check caret position since whitespace at the end |
| 1618 | // will not be considered by value.length in some browsers |
| 1619 | newLen = Math.max(event.target.selectionStart, newValue.length); |
| 1620 | } catch (err) { |
| 1621 | // selectionStart is undefined in Google Chrome |
| 1622 | newLen = newValue.length; |
| 1623 | } |
| 1624 | const oldLen = oldValue.length; |
| 1625 | |
| 1626 | let inputs = newLen - oldLen; |
| 1627 | let backspaces = inputs < 0 ? -inputs : 0; |
| 1628 | |
| 1629 | // Compare the old string with the new to account for |
| 1630 | // text-corrections or other input that modify existing text |
| 1631 | for (let i = 0; i < Math.min(oldLen, newLen); i++) { |
| 1632 | if (newValue.charAt(i) != oldValue.charAt(i)) { |
| 1633 | inputs = newLen - i; |
| 1634 | backspaces = oldLen - i; |
| 1635 | break; |
| 1636 | } |
| 1637 | } |
| 1638 | |
| 1639 | // Send the key events |
| 1640 | for (let i = 0; i < backspaces; i++) { |
| 1641 | UI.rfb.sendKey(KeyTable.XK_BackSpace, "Backspace"); |
| 1642 | } |
| 1643 | for (let i = newLen - inputs; i < newLen; i++) { |
| 1644 | UI.rfb.sendKey(keysyms.lookup(newValue.charCodeAt(i))); |
| 1645 | } |
| 1646 | |
| 1647 | // Control the text content length in the keyboardinput element |
| 1648 | if (newLen > 2 * UI.defaultKeyboardinputLen) { |
| 1649 | UI.keyboardinputReset(); |
| 1650 | } else if (newLen < 1) { |
| 1651 | // There always have to be some text in the keyboardinput |
| 1652 | // element with which backspace can interact. |
| 1653 | UI.keyboardinputReset(); |
| 1654 | // This sometimes causes the keyboard to disappear for a second |
| 1655 | // but it is required for the android keyboard to recognize that |
| 1656 | // text has been added to the field |
| 1657 | event.target.blur(); |
| 1658 | // This has to be ran outside of the input handler in order to work |
| 1659 | setTimeout(event.target.focus.bind(event.target), 0); |
| 1660 | } else { |
| 1661 | UI.lastKeyboardinput = newValue; |