Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Unified Diff: chrome/browser/resources/keyboard/common.js

Issue 7754019: Enable the keyboard to show the popup keyboard for inputting accented characters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 'Review fix' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/keyboard/common.js
diff --git a/chrome/browser/resources/keyboard/common.js b/chrome/browser/resources/keyboard/common.js
index a3dff78eca727ce3e482ba347865a5b989f48d01..ca7ca4cdeb2c825fe5aedf9350da9cad74b09d2c 100644
--- a/chrome/browser/resources/keyboard/common.js
+++ b/chrome/browser/resources/keyboard/common.js
@@ -47,6 +47,18 @@ var REPEAT_DELAY_MSEC = 500;
var REPEAT_INTERVAL_MSEC = 50;
/**
+ * The keyboard layout name currently in use.
+ * @type {string}
+ */
+var currentKeyboardLayout = 'us';
+
+/**
+ * The popup keyboard layout name currently in use.
+ * @type {string}
+ */
+var currentPopupName = '';
+
+/**
* A structure to track the currently repeating key on the keyboard.
*/
var repeatKey = {
@@ -81,6 +93,31 @@ var repeatKey = {
};
/**
+ * An array to track the currently touched keys on the popup keyboard.
+ */
+var touchedKeys = [];
+
+/**
+ * Set the keyboard mode.
+ * @param {string} mode The new mode.
+ * @return {void}
+ */
+function setMode(mode) {
+ var rows = KEYBOARDS[currentKeyboardLayout]['rows'];
+ for (var i = 0; i < rows.length; ++i) {
+ rows[i].showMode(mode);
+ }
+
+ if (!currentPopupName) {
+ return;
+ }
+ var popupRows = KEYBOARDS[currentPopupName]['rows'];
+ for (var i = 0; i < popupRows.length; ++i) {
+ popupRows[i].showMode(mode);
+ }
+}
+
+/**
* Transition the mode according to the given transition.
* @param {string} transition The transition to take.
* @return {void}
@@ -214,8 +251,14 @@ function setupKeyEventHandlers(key, element, handlers) {
}
if (keyLongHandler) {
+ // Copy the current state of event because |evt| can be modified before
+ // |keyLongHandler| is called.
+ var evt2 = {};
+ for (var name in evt) {
+ evt2[name] = evt[name];
+ }
key.longPressTimer = setTimeout(function() {
- keyLongHandler(evt),
+ keyLongHandler(evt2),
clearTimeout(key.longPressTimer);
delete key.longPressTimer;
key.pressed = false;
@@ -252,6 +295,10 @@ function setupKeyEventHandlers(key, element, handlers) {
};
var outHandler = function(evt) {
+ if (evt.target != evt.currentTarget ||
+ evt.toElement.parentNode == evt.fromElement) {
+ return;
+ }
// Reset key press state if the point goes out of the element.
key.pressed = false;
// Reset long-press timer.
@@ -285,12 +332,123 @@ function sendKeyFunction(key) {
}
/**
+ * Dispatch custom events to the elements at the touch points.
+ * touchpointmove events are dispatched responding to a touchmove and
+ * touchpointend events responding to a touchend event respectively.
+ * @param {UIEvent} evt The touch event that contains touch points information.
+ * @return {void}
+ */
+function dispatchTouchPointEvent(evt) {
+ var type = null;
+ var touches = null;
+ if (evt.type == 'touchmove') {
+ type = 'touchpointmove';
+ touches = evt.touches;
+ } else if (evt.type == 'touchend') {
+ type = 'touchpointend';
+ touches = evt.changedTouches;
+ } else {
+ return;
+ }
+
+ for (var i = 0; i < touches.length; ++i) {
+ var dispatchedEvent = document.createEvent('Event');
+ dispatchedEvent.initEvent(type, true, false);
+ var touch = touches[i];
+ var key = document.elementFromPoint(touch.screenX, touch.screenY);
+ if (key) {
+ key.dispatchEvent(dispatchedEvent);
+ }
+ }
+}
+
+/**
+ * Handle a touch move event on the key to make changes to the popup keyboard.
+ * @param {UIEvent} evt The UI event which triggered the touch move.
+ * @return {void}
+*/
+function trackTouchMoveForPopup(evt) {
+ var previous = touchedKeys;
+ touchedKeys = [];
+ dispatchTouchPointEvent(evt);
+ for (var i = 0; i < previous.length; ++i) {
+ if (touchedKeys.indexOf(previous[i]) == -1) {
+ previous[i].classList.remove('highlighted');
+ }
+ }
+ for (var i = 0; i < touchedKeys.length; ++i) {
+ touchedKeys[i].classList.add('highlighted');
+ }
+}
+
+/**
+ * Handle a touch end event on the key to make changes to the popup keyboard.
+ * @param {UIEvent} evt The UI event which triggered the touch end.
+ * @return {void}
+*/
+function trackTouchEndForPopup(evt) {
+ for (var i = 0; i < touchedKeys.length; ++i) {
+ touchedKeys[i].classList.remove('highlighted');
+ }
+ dispatchTouchPointEvent(evt);
+ hidePopupKeyboard();
+
+ touchedKeys = [];
+ evt.target.removeEventListener('touchmove', trackTouchMoveForPopup);
+ evt.target.removeEventListener('touchend', trackTouchEndForPopup);
+}
+
+/**
* Show the popup keyboard.
* @param {string} name The name of the popup keyboard.
+ * @return {void}
*/
-function showPopupKeyboard(name) {
- // TODO(mazda): Implement this function.
- console.warn('Popup keyboard is not implemented yet.');
+function showPopupKeyboard(name, evt) {
+ var popupDiv = document.getElementById('popup');
+ if (popupDiv.style.visibility == 'visible') {
+ return;
+ }
+
+ // Reinitialize the rows of the popup keyboard
+ if (currentPopupName != name) {
+ while (popupDiv.firstChild) {
+ popupDiv.removeChild(popupDiv.firstChild);
+ }
+ if (currentPopupName in KEYBOARDS) {
+ delete KEYBOARDS[currentPopupName].rows;
+ }
+ initRows(name, popupDiv, true);
+ currentPopupName = name;
+ }
+
+ // Set the mode of the popup keyboard
+ var popupRows = KEYBOARDS[currentPopupName]['rows'];
+ for (var i = 0; i < popupRows.length; ++i) {
+ popupRows[i].showMode(currentMode);
+ }
+
+ // Calculate the size of popup keyboard based on the size of the key.
+ var keyElement = evt.currentTarget;
+ var keyboard = KEYBOARDS[name];
+ var rows = keyboard['definition'];
+ var height = keyElement.offsetHeight * rows.length;
+ var aspect = keyboard['aspect'];
+ var width = aspect * height;
+ popupDiv.style.width = width + 'px';
+ popupDiv.style.height = height + 'px';
+
+ // Place the popup keyboard above the key
+ var rect = keyElement.getBoundingClientRect();
+ var left = (rect.left + rect.right) / 2 - width / 2;
+ left = Math.min(Math.max(left, 0), window.innerWidth - width);
+ var top = rect.top - height;
+ top = Math.min(Math.max(top, 0), window.innerHeight - height);
+ popupDiv.style.left = left + 'px';
+ popupDiv.style.top = top + 'px';
+ popupDiv.style.visibility = 'visible';
+
+ keyElement.addEventListener('touchmove', trackTouchMoveForPopup);
+ keyElement.addEventListener('touchend', trackTouchEndForPopup);
}
/**
@@ -299,12 +457,21 @@ function showPopupKeyboard(name) {
* @return {function()} A function which calls showPopupKeyboard(name).
*/
function showPopupKeyboardFunction(name) {
- return function () {
- showPopupKeyboard(name);
+ return function (evt) {
+ showPopupKeyboard(name, evt);
};
}
/**
+ * Hide the popup keyboard.
+ * @return {void}
+ */
+function hidePopupKeyboard() {
+ var popupDiv = document.getElementById('popup');
+ popupDiv.style.visibility = 'hidden';
+}
+
+/**
* Plain-old-data class to represent a character.
* @param {string} display The HTML to be displayed.
* @param {string} id The key identifier for this Character.
@@ -317,10 +484,30 @@ function Character(display, id) {
/**
* Convenience function to make the keyboard data more readable.
- * @param {string} display Both the display and id for the created Character.
+ * @param {string} display The display for the created Character.
+ * @param {string} opt_id The id for the created Character.
+ * @return {Character} A character that contains display and opt_id. If
+ * opt_id is omitted, display is used as the id.
*/
-function C(display) {
- return new Character(display, display);
+function C(display, opt_id) {
+ var id = opt_id || display;
+ return new Character(display, id);
+}
+
+/**
+ * Convenience function to make the keyboard data more readable.
+ * @param {string} display The display for the created Character.
+ * @param {string} opt_id The id for the created Character.
+ * @param {string} opt_popupName The popup keyboard name for this character.
+ * @return {Object} An object that contains a Character and the popup keyboard
+ * name.
+ */
+function CP(display, opt_id, opt_popupName) {
+ var result = { character: C(display, opt_id) };
+ if (opt_popupName) {
+ result['popupName'] = opt_popupName;
+ }
+ return result;
}
/**
@@ -402,6 +589,56 @@ BaseKey.prototype = {
/**
* A simple key which displays Characters.
+ * @param {Object} key The Character and the popup name for KEY_MODE.
+ * @param {Object} shift The Character and the popup name for SHIFT_MODE.
+ * @param {Object} num The Character and the popup name for NUMBER_MODE.
+ * @param {Object} symbol The Character and the popup name for SYMBOL_MODE.
+ * @constructor
+ * @extends {BaseKey}
+ */
+function Key(key, shift, num, symbol) {
+ this.modeElements_ = {};
+ this.cellType_ = '';
+
+ this.modes_ = {};
+ this.modes_[KEY_MODE] = key ? key.character : null;
+ this.modes_[SHIFT_MODE] = shift ? shift.character : null;
+ this.modes_[NUMBER_MODE] = num ? num.character : null;
+ this.modes_[SYMBOL_MODE] = symbol ? symbol.character : null;
+
+ this.popupNames_ = {};
+ this.popupNames_[KEY_MODE] = key ? key.popupName : null;
+ this.popupNames_[SHIFT_MODE] = shift ? shift.popupName : null;
+ this.popupNames_[NUMBER_MODE] = num ? num.popupName : null;
+ this.popupNames_[SYMBOL_MODE] = symbol ? symbol.popupName : null;
+}
+
+Key.prototype = {
+ __proto__: BaseKey.prototype,
+
+ /** @inheritDoc */
+ makeDOM: function(mode) {
+ if (!this.modes_[mode]) {
+ return null;
+ }
+
+ this.modeElements_[mode] = document.createElement('div');
+ var element = this.modeElements_[mode];
+ element.className = 'key';
+
+ addContent(element, this.modes_[mode].display);
+
+ var longHandler = this.popupNames_[mode] ?
+ showPopupKeyboardFunction(this.popupNames_[mode]) : null;
+ setupKeyEventHandlers(this, element,
+ { 'up': sendKeyFunction(this.modes_[mode].keyIdentifier),
+ 'long': longHandler });
+ return element;
+ }
+};
+
+/**
+ * A simple key which displays Characters on the popup keyboard.
* @param {Character} key The Character for KEY_MODE.
* @param {Character} shift The Character for SHIFT_MODE.
* @param {Character} num The Character for NUMBER_MODE.
@@ -409,7 +646,7 @@ BaseKey.prototype = {
* @constructor
* @extends {BaseKey}
*/
-function Key(key, shift, num, symbol) {
+function PopupKey(key, shift, num, symbol) {
this.modeElements_ = {};
this.cellType_ = '';
@@ -420,7 +657,7 @@ function Key(key, shift, num, symbol) {
this.modes_[SYMBOL_MODE] = symbol;
}
-Key.prototype = {
+PopupKey.prototype = {
__proto__: BaseKey.prototype,
/** @inheritDoc */
@@ -430,16 +667,24 @@ Key.prototype = {
}
this.modeElements_[mode] = document.createElement('div');
- this.modeElements_[mode].className = 'key';
- addContent(this.modeElements_[mode], this.modes_[mode].display);
-
- // TODO(mazda): Set the long-press handler only if the key has characters
- // to show on the popup keyboard.
- setupKeyEventHandlers(this, this.modeElements_[mode],
- { 'up': sendKeyFunction(this.modes_[mode].keyIdentifier),
- 'long': showPopupKeyboardFunction('') });
-
- return this.modeElements_[mode];
+ var element = this.modeElements_[mode];
+ element.className = 'key popupkey';
+
+ addContent(element, this.modes_[mode].display);
+
+ var upHandler = sendKeyFunction(this.modes_[mode].keyIdentifier);
+ element.addEventListener('touchpointmove', function(evt) {
+ touchedKeys.push(element);
+ });
+ element.addEventListener('touchpointend', upHandler);
+ element.addEventListener('mouseup', upHandler);
+ element.addEventListener('mouseover', function(evt) {
+ element.classList.add('highlighted');
+ });
+ element.addEventListener('mouseout', function(evt) {
+ element.classList.remove('highlighted');
+ });
+ return element;
}
};
@@ -715,4 +960,12 @@ Row.prototype = {
}
this.modeElements_[mode].style.display = '-webkit-box';
},
+
+ /**
+ * Returns the size of keys this row contains.
+ * @return {number} The size of keys.
+ */
+ get length() {
+ return this.keys_.length;
+ }
};
« no previous file with comments | « no previous file | chrome/browser/resources/keyboard/index.html » ('j') | chrome/browser/resources/keyboard/main.css » ('J')

Powered by Google App Engine
This is Rietveld 408576698