Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
340 lines
8.2 KiB
JavaScript
Executable file
340 lines
8.2 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
var Base = require('./base');
|
|
var Marionette = require('marionette-client');
|
|
|
|
|
|
function Keyboard(client) {
|
|
Base.call(this, client);
|
|
|
|
this.actions = new Marionette.Actions(client);
|
|
this.currentLayout = null;
|
|
}
|
|
|
|
module.exports = Keyboard;
|
|
|
|
Keyboard.Selectors = Object.freeze({
|
|
currentPanel:
|
|
'.keyboard-type-container[data-active]',
|
|
imeSwitchingKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.keyboard-key[data-keycode="-3"]',
|
|
backspaceKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.keyboard-key[data-keycode="8"]',
|
|
returnKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.keyboard-key[data-l10n-id="returnKey2"]',
|
|
spaceBarKey: '.keyboard-type-container[data-active]' +
|
|
' .keyboard-key[data-keycode="32"]',
|
|
dismissSuggestionsKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.dismiss-suggestions-button',
|
|
shiftKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'button.keyboard-key[data-l10n-id="upperCaseKey2"]',
|
|
autoCorrectWord:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.autocorrect',
|
|
});
|
|
|
|
Keyboard.Templates = Object.freeze({
|
|
key:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'button.keyboard-key[data-keycode="%s"], ' +
|
|
'.keyboard-type-container[data-active] ' +
|
|
'button.keyboard-key[data-keycode-upper="%s"]',
|
|
upperCaseKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'button.keyboard-key[data-keycode-upper="%s"]',
|
|
pageSwitchingKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'button.keyboard-key[data-target-page="%s"]',
|
|
suggestionKey:
|
|
'.keyboard-type-container[data-active] ' +
|
|
'.suggestions-container span[data-data="%s"]',
|
|
});
|
|
|
|
Keyboard.LONGPRESS_CHARS = Object.freeze({
|
|
'0': 'º',
|
|
'?': '¿',
|
|
'$': '€£¥',
|
|
'!': '¡',
|
|
'a': 'áàâäåãāæ',
|
|
'c': 'çćč',
|
|
'e': 'éèêëēę€ɛ',
|
|
'i': 'įīîìíï',
|
|
'l': '£ł',
|
|
'n': 'ńñ',
|
|
'o': 'ɵøœōôòóö',
|
|
's': 'ßśš$',
|
|
'u': 'ūûùúü',
|
|
'y': '¥ÿ',
|
|
'z': 'žźż',
|
|
'A': 'ÁÀÂÄÅÃĀÆ',
|
|
'C': 'ÇĆČ',
|
|
'E': 'ÉÈÊËĒĘ€Ɛ',
|
|
'I': 'ĮĪÎÌÍÏ',
|
|
'L': '£Ł',
|
|
'N': 'ŃÑ',
|
|
'O': 'ƟØŒŌÔÒÓÖ',
|
|
'S': 'ŚŠŞ',
|
|
'U': 'ŪÛÙÚÜ',
|
|
'Y': '¥Ÿ',
|
|
'Z': 'ŽŹŻ'
|
|
});
|
|
|
|
Keyboard.TypeGroupMap = Object.freeze({
|
|
'text': 'text',
|
|
'textarea': 'text',
|
|
'url': 'url',
|
|
'email': 'email',
|
|
'password': 'password',
|
|
'search': 'text',
|
|
'number': 'number',
|
|
'tel': 'number'
|
|
});
|
|
|
|
Keyboard.prototype = {
|
|
__proto__: Base.prototype,
|
|
|
|
get currentPanel() {
|
|
return this.client.findElement(Keyboard.Selectors.currentPanel);
|
|
},
|
|
|
|
get imeSwitchingKey() {
|
|
return this.client.findElement(Keyboard.Selectors.imeSwitchingKey);
|
|
},
|
|
|
|
get backspaceKey() {
|
|
return this.client.findElement(Keyboard.Selectors.backspaceKey);
|
|
},
|
|
|
|
get returnKey() {
|
|
return this.client.findElement(Keyboard.Selectors.returnKey);
|
|
},
|
|
|
|
get spaceBarKey() {
|
|
return this.client.findElement(Keyboard.Selectors.spaceBarKey);
|
|
},
|
|
|
|
get shiftKey() {
|
|
return this.client.findElement(Keyboard.Selectors.shiftKey);
|
|
},
|
|
|
|
get dismissSuggestionsKey() {
|
|
return this.client.findElement(Keyboard.Selectors.dismissSuggestionsKey);
|
|
},
|
|
|
|
get autoCorrectWord() {
|
|
return this.client.findElement(Keyboard.Selectors.autoCorrectWord);
|
|
},
|
|
|
|
getKey: function(char) {
|
|
var selector = Keyboard.Templates.key.replace(/%s/g, char.charCodeAt(0));
|
|
return this.client.findElement(selector);
|
|
},
|
|
|
|
getPageSwitchingKey: function(index) {
|
|
var selector = Keyboard.Templates.pageSwitchingKey.replace(/%s/g, index);
|
|
return this.client.findElement(selector);
|
|
},
|
|
|
|
getSuggestionKey: function(word) {
|
|
var selector = Keyboard.Templates.suggestionKey.replace(/%s/, word);
|
|
return this.client.findElement(selector);
|
|
},
|
|
|
|
getLongPressCharMiddleKey: function(char) {
|
|
var chars = Keyboard.LONGPRESS_CHARS;
|
|
|
|
for (var middleChar in chars) {
|
|
if (chars[middleChar].indexOf(char) !== -1) {
|
|
return middleChar;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
},
|
|
|
|
getCurrentInputType: function() {
|
|
return this.client.executeScript(
|
|
'return window.wrappedJSObject.app.getBasicInputType();');
|
|
},
|
|
|
|
getCurrentInputMode: function() {
|
|
return this.client.executeScript(
|
|
'return window.wrappedJSObject.app.inputContext.inputMode;');
|
|
},
|
|
|
|
getCurrentPageIndex: function() {
|
|
return this.client.executeScript(
|
|
'return window.wrappedJSObject.app.layoutManager.currentPageIndex;');
|
|
},
|
|
|
|
getCurrentKeyboardLayout: function() {
|
|
var keyboardFrame;
|
|
|
|
this.client.switchToFrame();
|
|
|
|
keyboardFrame = this.client.findElement(
|
|
'#keyboards .inputWindow.active iframe');
|
|
this.currentLayout = keyboardFrame.getAttribute('data-frame-name');
|
|
this.switchTo();
|
|
|
|
return this.currentLayout;
|
|
},
|
|
|
|
getSymbolPageIndex: function(key) {
|
|
this.switchToPage(1);
|
|
|
|
if (this.isKeyPresent(key)) {
|
|
return 1;
|
|
}
|
|
return 2;
|
|
},
|
|
|
|
tapBackspaceKey: function(word) {
|
|
this.backspaceKey.tap();
|
|
},
|
|
|
|
tapAutoCorrectWord: function() {
|
|
this.client.waitFor(() => {
|
|
return this.autoCorrectWord.displayed();
|
|
});
|
|
this.autoCorrectWord.tap();
|
|
},
|
|
|
|
tapSuggestionWord: function(word) {
|
|
this.getSuggestionKey(word).tap();
|
|
},
|
|
|
|
isUpperCase: function() {
|
|
return this.client.executeScript(
|
|
'return ' +
|
|
'window.wrappedJSObject.app.upperCaseStateManager.isUpperCase;');
|
|
},
|
|
|
|
isElementPresent: function(selector) {
|
|
var pollClient = this.client.scope({ searchTimeout: 50 });
|
|
|
|
try {
|
|
pollClient.findElement(selector);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
isKeyPresent: function(key) {
|
|
var keyTemplate = Keyboard.Templates.key;
|
|
|
|
return this.isElementPresent(keyTemplate.replace(/%s/g, key.charCodeAt(0)));
|
|
},
|
|
|
|
switchCase: function(isUpperCase) {
|
|
if (isUpperCase === undefined || this.isUpperCase() === isUpperCase) {
|
|
return;
|
|
}
|
|
|
|
this.shiftKey.tap();
|
|
this.client.waitFor(() => {
|
|
var expected = isUpperCase ? 'true' : 'false';
|
|
|
|
return (this.shiftKey.getAttribute('aria-pressed') === expected);
|
|
});
|
|
},
|
|
|
|
switchToPage: function(index) {
|
|
var pageIndex = this.getCurrentPageIndex();
|
|
|
|
if (index === undefined || pageIndex === index) {
|
|
return;
|
|
}
|
|
|
|
this.getPageSwitchingKey(index).tap();
|
|
this.client.waitFor(() => {
|
|
return (this.getCurrentPageIndex() === index);
|
|
});
|
|
this.waitForPageReady();
|
|
},
|
|
|
|
switchToKeyLayout: function(key) {
|
|
var page;
|
|
var upperCase;
|
|
var currentLayout = this.currentLayout || this.getCurrentKeyboardLayout();
|
|
|
|
if (['number'].indexOf(currentLayout) !== -1) {
|
|
return;
|
|
}
|
|
|
|
if (key >= '0' && key <= '9') {
|
|
page = 1;
|
|
} else if (key >= 'A' && key <='Z') {
|
|
page = 0;
|
|
upperCase = true;
|
|
} else if (key >= 'a' && key <= 'z') {
|
|
page = 0;
|
|
upperCase = false;
|
|
} else if (key === ' ' || key === '\u0008' || key === '\u000d') {
|
|
|
|
} else {
|
|
page = this.getSymbolPageIndex(key);
|
|
}
|
|
|
|
this.switchToPage(page);
|
|
this.switchCase(upperCase);
|
|
},
|
|
|
|
type: function(string) {
|
|
string.split('').forEach((char) => {
|
|
var middleChar = this.getLongPressCharMiddleKey(char);
|
|
var lookingForKey = middleChar || char;
|
|
var keyElement;
|
|
|
|
this.switchToKeyLayout(lookingForKey);
|
|
|
|
if (!middleChar) {
|
|
keyElement = this.getKey(char);
|
|
|
|
this.actions.wait(0.1).tap(keyElement).perform();
|
|
} else {
|
|
keyElement = this.getKey(middleChar);
|
|
|
|
this.actions
|
|
.press(keyElement).wait(1.5).perform()
|
|
.move(this.getKey(char)).wait(0.2).release().perform();
|
|
}
|
|
});
|
|
},
|
|
|
|
longPressSpaceBar: function(time) {
|
|
this.actions.longPress(this.spaceBarKey, time).perform();
|
|
},
|
|
|
|
switchTo: function() {
|
|
var systemInputMgmt = this.client.loader.getAppClass(
|
|
'system', 'input_management');
|
|
|
|
systemInputMgmt.waitForKeyboardFrameDisplayed();
|
|
systemInputMgmt.switchToActiveKeyboardFrame();
|
|
|
|
this.waitForPageReady();
|
|
},
|
|
|
|
waitForPageReady: function() {
|
|
this.client.waitFor(() => {
|
|
return this.currentPanel.displayed();
|
|
});
|
|
},
|
|
|
|
waitForKeyboardReady: function() {
|
|
this.client.switchToFrame();
|
|
|
|
this.client.waitFor(() => {
|
|
return this.client.findElement(
|
|
'#keyboards .inputWindow .browser-container');
|
|
});
|
|
}
|
|
};
|