Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Bug 858383 - [Keyboard] Integrate the new keyboard manager with switch
Browse files Browse the repository at this point in the history
and show layout list functions in Keyboard app.
 1. Modify keyboard manifest to expose entry points as input methods.
 2. Modify keyboard init logic to interact with new keyboard manager.
 3. Make use of inputContext in keyboard app.
 4. Bug 885692 - To integrate with the new keyboard switching API. for keyboard app
 5. Bug 899073 - inputContext.geText() whould return Promise
r=timdream
  • Loading branch information
RudyLu committed Aug 31, 2013
1 parent f31c3f4 commit e3c6257
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 142 deletions.
226 changes: 130 additions & 96 deletions apps/keyboard/js/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ const defaultInputMethod = {
displaysCandidates: function() { return false; }
};

var inputContext = null;

// The keyboard app can display different layouts for different languages
// We sometimes refer to these different layouts as "keyboards", so this single
// keyboard app can display many different keyboards. The currently displayed
Expand Down Expand Up @@ -234,6 +236,15 @@ const keyboardAlias = {
// XXX: ideally, this should be based on the current language,
const defaultKeyboardNames = ['en'];

const keyboardHashKey = [
'en', 'en-Dvorak', 'es', 'pt-BR', 'pl',
'cz', 'fr', 'de', 'nb', 'sk',
'tr', 'ru', 'sr-Cyrl', 'ar', 'he',
'el',
'zh-Hant-Zhuyin', 'zh-Hans-Pinyin', 'jp-kanji',
'numberLayout'
];

// If we get a focuschange event from mozKeyboard for an element with
// one of these types, we'll just ignore it.
const ignoredFormElementTypes = {
Expand Down Expand Up @@ -265,7 +276,7 @@ var suggestionsEnabled;
var correctionsEnabled;
var clickEnabled;
var vibrationEnabled;
var enabledKeyboardGroups;
var enabledKeyboardGroups = {};
var enabledKeyboardNames;
var isSoundEnabled;

Expand Down Expand Up @@ -313,13 +324,8 @@ function getKeyboardSettings() {
'audio.volume.notification': 7
};

// Add the keyboard group settings to our query, too.
for (var group in keyboardGroups)
settingsQuery['keyboard.layouts.' + group] = false;

// Now query the settings
getSettings(settingsQuery, function gotSettings(values) {

// Copy settings values to the corresponding global variables.
currentKeyboardName = values['keyboard.current'];
suggestionsEnabled = values['keyboard.wordsuggestion'];
Expand All @@ -333,11 +339,17 @@ function getKeyboardSettings() {

handleKeyboardSound();

// Copy the keyboard group settings too
enabledKeyboardGroups = {};
for (var group in keyboardGroups) {
var settingName = 'keyboard.layouts.' + group;
enabledKeyboardGroups[settingName] = values[settingName];
// set default input method with hash value
if (window.location.hash !== '') {
var hashKey = window.location.hash.substring(1);

if (keyboardHashKey.indexOf(hashKey) !== -1) {
keyboardName = hashKey;
} else {
keyboardName = defaultKeyboardName;
}
} else {
keyboardName = defaultKeyboardName;
}

// And create an array of all enabled keyboard layouts from the set
Expand Down Expand Up @@ -390,21 +402,6 @@ function initKeyboard() {
toShowKeyboardFTU = e.settingValue;
});

for (var group in keyboardGroups) {

var settingName = 'keyboard.layouts.' + group;

var createLayoutCallback = function createLayoutCallback(name) {
return function layoutCallback(e) {
enabledKeyboardGroups[name] = e.settingValue;
handleNewKeyboards();
}
};

navigator.mozSettings.addObserver(settingName,
createLayoutCallback(settingName));
}

// Initialize the rendering module
IMERender.init(getUpperCaseValue, isSpecialKeyObj);

Expand Down Expand Up @@ -450,32 +447,38 @@ function initKeyboard() {
attributes: true, attributeFilter: ['class', 'style', 'data-hidden']
});

// Show or hide the keyboard when we get an focuschange event
// from the keyboard
var focusChangeTimeout = 0;
navigator.mozKeyboard.onfocuschange = function onfocuschange(evt) {
var state = evt.detail;
var type = state.type;
window.addEventListener('hashchange', function() {
var inputMethodName = window.location.hash.substring(1);
setKeyboardName(inputMethodName);
resetKeyboard();
showKeyboard();
}, false);

// Skip the <select> element and inputs with type of date/time,
// handled in system app for now
if (!type || type in ignoredFormElementTypes)
return;
// Handle resize events
window.addEventListener('resize', onResize);

// We can get multiple focuschange events in rapid succession
// so wait a bit before responding to see if we get another.
clearTimeout(focusChangeTimeout);
if (type === 'blur') {
focusChangeTimeout = setTimeout(function focusChangeTimeout() {
hideKeyboard();
}, FOCUS_CHANGE_DELAY);
// Need to listen to both mozvisibilitychange and oninputcontextchange,
// because we are not sure which will happen first and we will call
// showKeyboard() when mozHidden is false and we got inputContext
window.addEventListener('mozvisibilitychange', function visibilityHandler() {
var inputMethodName = window.location.hash.substring(1);
setKeyboardName(inputMethodName);

if (!document.mozHidden && inputContext) {
showKeyboard();
} else {
showKeyboard(state);
hideKeyboard();
}
};
});

// Handle resize events
window.addEventListener('resize', onResize);
window.navigator.mozInputMethod.oninputcontextchange = function() {
inputContext = navigator.mozInputMethod.inputcontext;
if (!document.mozHidden && inputContext) {
showKeyboard();
} else {
hideKeyboard();
}
};
}

function handleKeyboardSound() {
Expand Down Expand Up @@ -691,7 +694,7 @@ function modifyLayout(keyboardName) {
}

// switch languages button
if (enabledKeyboardNames.length > 1 && !layout['hidesSwitchKey']) {
if (!layout['hidesSwitchKey']) {
space.ratio -= 1.5;
row.splice(c, 0, {
value: '&#x1f310;',
Expand Down Expand Up @@ -841,8 +844,10 @@ function renderKeyboard(keyboardName) {
var candidatePanel = document.getElementById('keyboard-candidate-panel');
var candidatePanelHeight = (candidatePanel) ?
candidatePanel.scrollHeight : 0;
document.location.hash = 'show=' +
(IMERender.ime.scrollHeight - candidatePanelHeight);

var url = document.location.href + '#keyboard-test=' +
(IMERender.ime.scrollHeight - candidatePanelHeight);
window.open(url);

redrawTimeout = window.setTimeout(drawKeyboard,
CANDIDATE_PANEL_SWITCH_TIMEOUT);
Expand Down Expand Up @@ -907,11 +912,9 @@ function setLayoutPage(newpage) {
// Inform about a change in the displayed application via mutation observer
// http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/
function updateTargetWindowHeight(hide) {
if (IMERender.ime.dataset.hidden || hide) {
document.location.hash = 'hide';
} else {
document.location.hash = 'show=' + IMERender.ime.scrollHeight;
}
var url = document.location.href +
'#keyboard-test=' + IMERender.ime.scrollHeight;
window.open(url);
}

// Sends a delete code to remove last character
Expand Down Expand Up @@ -991,7 +994,7 @@ function showAlternatives(key) {

// Handle languages alternatives
if (keyObj.keyCode === SWITCH_KEYBOARD) {
showKeyboardLayoutMenu(key);
showIMEList();
return;
}

Expand Down Expand Up @@ -1297,7 +1300,6 @@ function startPress(target, coords, touchId) {
}
}


function inMenuLockedArea(lockedArea, coords) {
return (lockedArea &&
coords.pageY >= lockedArea.top &&
Expand Down Expand Up @@ -1461,7 +1463,7 @@ function endPress(target, coords, touchId) {
// If the user selected a new keyboard layout or quickly tapped the
// switch layouts button then switch to a new keyboard layout
if (target.dataset.keyboard || !wasShowingKeyboardLayoutMenu)
switchKeyboard(target);
switchToNextIME();
break;

// Expand / shrink the candidate panel
Expand Down Expand Up @@ -1591,13 +1593,24 @@ function switchKeyboard(target) {
// In practice, just about everything uses the latin input method now
// so this only occurs when the users switches from Hebrew or Arabic
// to a latin or cyrillic alphabet. XXX: See Bug 888076
navigator.mozKeyboard.removeFocus();
navigator.mozInputMethod.mgmt.removeFocus();
}
}

renderKeyboard(keyboardName); // And display it.
}

function switchToNextIME() {
var mgmt = navigator.mozInputMethod.mgmt;
mgmt.next();
}


function showIMEList() {
var mgmt = navigator.mozInputMethod.mgmt;
mgmt.showAll();
}

// Turn to default values
function resetKeyboard() {
// Don't call setLayoutPage because renderKeyboard() should be invoked
Expand All @@ -1609,59 +1622,59 @@ function resetKeyboard() {
isUpperCaseLocked = false;
}

// This is a wrapper around mozKeyboard.sendKey()
// This is a wrapper around inputContext.sendKey()
// We use it in the defaultInputMethod and in the interface object
// we pass to real input methods
function sendKey(keyCode) {
switch (keyCode) {
case KeyEvent.DOM_VK_BACK_SPACE:
case KeyEvent.DOM_VK_RETURN:
window.navigator.mozKeyboard.sendKey(keyCode, 0);
if (inputContext) {
inputContext.sendKey(keyCode, 0, 0);
}
break;

default:
window.navigator.mozKeyboard.sendKey(0, keyCode);
if (inputContext) {
inputContext.sendKey(0, keyCode, 0);
}
break;
}
}

function replaceSurroundingText(text, offset, length) {
if (inputContext) {
inputContext.replaceSurroundingText(text, offset, length);
} else {
console.warn('no inputContext for replaceSurroudingText');
}
}

// Set up the keyboard and its input method.
// This is called when we get an event from mozKeyboard.
// The state argument is the data passed with that event, and includes
// the input field type, its inputmode, its content, and the cursor position.
function showKeyboard(state) {
var newKeyboardName = currentKeyboardName;
// If the keyboard is not initialized or the layout has changed,
// set the new keyboard
if (keyboardName !== currentKeyboardName) {
// Make sure that currentKeyboardName is enabled. If not, use
// the first enabled keyboard as the default.
if (enabledKeyboardNames.indexOf(currentKeyboardName) == -1) {
// Update the keyboard.current setting with the first enabled keyboard
navigator.mozSettings.createLock().set({
'keyboard.current': enabledKeyboardNames[0]
});
newKeyboardName = enabledKeyboardNames[0];
}

// Now initialize that keyboard
setKeyboardName(newKeyboardName);
// If no keyboard has been selected yet, choose the first enabled one.
// This will also set the inputMethod
if (!keyboardName) {
setKeyboardName(defaultKeyboardName);
}

inputContext = navigator.mozInputMethod.inputcontext;
IMERender.showIME();

currentInputMode = state.inputmode;
currentInputType = mapInputType(state.type);
if (inputContext) {
currentInputMode = inputContext.inputMode;
currentInputType = mapInputType(inputContext.inputType);
} else {
console.error('Cannot get inputContext');
currentInputMode = '';
currentInputType = mapInputType('text');
}

resetKeyboard();

if (inputMethod.activate) {
inputMethod.activate(Keyboards[keyboardName].autoCorrectLanguage, state, {
suggest: suggestionsEnabled,
correct: correctionsEnabled
});
}

if (toShowKeyboardFTU) {
var dialog = document.getElementById('confirm-dialog');
dialog.hidden = false;
Expand All @@ -1672,9 +1685,34 @@ function showKeyboard(state) {
});
}

// render the keyboard after activation, which will determine the state
// of uppercase/suggestion, etc.
renderKeyboard(keyboardName);
var state = {
type: inputContext.inputType,
inputmode: inputContext.inputMode,
selectionStart: inputContext.selectionStart,
selectionEnd: inputContext.selectionEnd,
value: ''
};

function doShowKeyboard() {
if (inputMethod.activate) {
inputMethod.activate(Keyboards[keyboardName].autoCorrectLanguage,
state, {
suggest: suggestionsEnabled,
correct: correctionsEnabled
});
}

// render the keyboard after activation, which will determine the state
// of uppercase/suggestion, etc.
renderKeyboard(keyboardName);
}

inputContext.getText().then(function gotText(value) {
state.value = value;
doShowKeyboard();
}, function failedToGetText() {
doShowKeyboard();
});
}

// Hide keyboard
Expand Down Expand Up @@ -1749,14 +1787,10 @@ function loadIMEngine(name) {
},
setLayoutPage: setLayoutPage,
setUpperCase: setUpperCase,
resetUpperCase: resetUpperCase
resetUpperCase: resetUpperCase,
replaceSurroundingText: replaceSurroundingText
};

if (typeof navigator.mozKeyboard.replaceSurroundingText === 'function') {
glue.replaceSurroundingText =
navigator.mozKeyboard.replaceSurroundingText.bind(navigator.mozKeyboard);
}

script.addEventListener('load', function IMEngineLoaded() {
var engine = InputMethods[imEngine];
engine.init(glue);
Expand Down
2 changes: 1 addition & 1 deletion apps/keyboard/js/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ const Keyboards = {
]
}
},
pt_BR: {
'pt-BR': {
label: 'Portuguese',
menuLabel: 'Português',
imEngine: 'latin',
Expand Down
Loading

0 comments on commit e3c6257

Please sign in to comment.