diff options
Diffstat (limited to 'third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js')
-rw-r--r-- | third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js | 192 |
1 files changed, 145 insertions, 47 deletions
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js index 3dd9499..9759a65 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/altdataview.js @@ -17,17 +17,35 @@ goog.require('goog.array'); goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('goog.dom.classlist'); +goog.require('goog.math.Coordinate'); goog.require('goog.style'); +goog.require('i18n.input.chrome.inputview.Accents'); goog.require('i18n.input.chrome.inputview.Css'); goog.require('i18n.input.chrome.inputview.elements.Element'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); goog.require('i18n.input.chrome.inputview.util'); - goog.scope(function() { +var ElementType = i18n.input.chrome.inputview.elements.ElementType; +/** + * Converts cooridnate in the keyboard window to coordinate in screen. + * + * @param {goog.math.Coordinate} coordinate The coordinate in keyboard window. + * @return {goog.math.Coordinate} The cooridnate in screen. + */ +function convertToScreenCoordinate(coordinate) { + var screenCoordinate = coordinate.clone(); + // This is a hack. Ideally, we should be able to use window.screenX/Y to get + // cooridnate of the top left corner of VK window. But VK window is special + // and the values are set to 0 all the time. We should fix the problem in + // Chrome. + screenCoordinate.y += screen.height - window.innerHeight; + return screenCoordinate; +}; + /** * The view for alt data. @@ -38,8 +56,7 @@ goog.scope(function() { */ i18n.input.chrome.inputview.elements.content.AltDataView = function( opt_eventTarget) { - goog.base(this, '', i18n.input.chrome.inputview.elements.ElementType. - ALTDATA_VIEW, opt_eventTarget); + goog.base(this, '', ElementType.ALTDATA_VIEW, opt_eventTarget); /** * The alternative elements. @@ -48,6 +65,14 @@ i18n.input.chrome.inputview.elements.content.AltDataView = function( * @private */ this.altdataElements_ = []; + + /** + * The window that shows accented characters. + * + * @type {Object} + * @private + */ + this.altdataWindow_ = null; }; goog.inherits(i18n.input.chrome.inputview.elements.content.AltDataView, i18n.input.chrome.inputview.elements.Element); @@ -64,6 +89,25 @@ AltDataView.PADDING_ = 6; /** + * The URL of the window which displays accented characters. + * + * @type {string} + * @private + */ +AltDataView.ACCENTS_WINDOW_URL_ = 'imewindows/accents.html'; + + +/** + * Index of highlighted accent. Use this index to represent no highlighted + * accent. + * + * @type {number} + * @private + */ +AltDataView.INVALIDINDEX_ = -1; + + +/** * The distance between finger to altdata view which will cancel the altdata * view. * @@ -90,7 +134,7 @@ AltDataView.prototype.coverElement_; * @type {number} * @private */ -AltDataView.prototype.highlightIndex_ = 0; +AltDataView.prototype.highlightIndex_ = AltDataView.INVALIDINDEX_; /** @@ -101,6 +145,15 @@ AltDataView.prototype.highlightIndex_ = 0; AltDataView.prototype.triggeredBy; +/** + * True if create IME window to show accented characters. + * + * @type {boolean} + * @private + */ +AltDataView.prototype.enableIMEWindow_ = false; + + /** @override */ AltDataView.prototype.createDom = function() { goog.base(this, 'createDom'); @@ -131,15 +184,17 @@ AltDataView.prototype.enterDocument = function() { * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key The key * triggerred this altdata view. * @param {boolean} isRTL Whether to show the key characters as RTL. + * @param {boolean} enableIMEWindow Whether to enable IME window for accented + * characters. */ -AltDataView.prototype.show = function(key, isRTL) { +AltDataView.prototype.show = function(key, isRTL, enableIMEWindow) { this.triggeredBy = key; + this.enableIMEWindow_ = enableIMEWindow; var coordinate = goog.style.getClientPosition(key.getElement()); var x = coordinate.x; var y = coordinate.y; var width = key.availableWidth; var height = key.availableHeight; - var ElementType = i18n.input.chrome.inputview.elements.ElementType; var characters; if (key.type == ElementType.CHARACTER_KEY) { key = /** @type {!i18n.input.chrome.inputview.elements.content. @@ -162,33 +217,58 @@ AltDataView.prototype.show = function(key, isRTL) { // The total width of the characters + the separators, every separator has // width = 1. var altDataWidth = width * characters.length; - var showingLeft = (x + altDataWidth) > screen.width; - if (showingLeft) { + + var left = coordinate.x; + if ((left + altDataWidth) > screen.width) { + // If no enough space at the right, then make it to the left. + left = coordinate.x + width - altDataWidth; characters.reverse(); } - for (var i = 0; i < characters.length; i++) { - var keyElem = this.addKey_(characters[i], isRTL); - goog.style.setSize(keyElem, width, height); - this.altdataElements_.push(keyElem); - if (i != characters.length - 1) { - this.addSeparator_(height); - } - } - var left = x; - if (showingLeft) { - // If no enough space at the right, then make it to the left. - left = x + width - altDataWidth; - this.highlightIndex_ = this.altdataElements_.length - 1; - this.setElementBackground_(this.altdataElements_[this.highlightIndex_], - true); + + var elemTop = coordinate.y - height - AltDataView.PADDING_; + + if (this.enableIMEWindow_) { + var screenCoordinate = convertToScreenCoordinate( + new goog.math.Coordinate(left, elemTop)); + if (this.altdataWindow_) + this.altdataWindow_.close(); + var self = this; + var screenBounds = goog.object.create('left', screenCoordinate.x, + 'top', screenCoordinate.y, 'width', altDataWidth, 'height', height); + inputview.createWindow( + chrome.runtime.getURL(AltDataView.ACCENTS_WINDOW_URL_), + goog.object.create('outerBounds', screenBounds, 'frame', 'none', + 'hidden', true), + function(newWindow) { + self.altdataWindow_ = newWindow; + var contentWindow = self.altdataWindow_.contentWindow; + contentWindow.addEventListener('load', function() { + contentWindow.accents.setAccents(characters); + contentWindow.accents.highlightItem( + Math.ceil(coordinate.x + width / 2), + Math.ceil(coordinate.y + height / 2)); + self.altdataWindow_.show(); + }); + }); } else { - this.setElementBackground_(this.altdataElements_[0], true); - } - var elemTop = y - height - AltDataView.PADDING_; - if (elemTop < 0) { - elemTop = y + height + AltDataView.PADDING_; + if (elemTop < 0) { + // If no enough top space, then display below the key. + elemTop = coordinate.y + height + AltDataView.PADDING_; + } + + for (var i = 0; i < characters.length; i++) { + var keyElem = this.addKey_(characters[i], isRTL); + goog.style.setSize(keyElem, width, height); + this.altdataElements_.push(keyElem); + if (i != characters.length - 1) { + this.addSeparator_(height); + } + } + goog.style.setPosition(this.getElement(), left, elemTop); + this.highlightItem(Math.ceil(coordinate.x + width / 2), + Math.ceil(coordinate.y + height / 2)); } - goog.style.setPosition(this.getElement(), left, elemTop); + goog.style.setElementShown(this.coverElement_, true); this.triggeredBy.setHighlighted(true); }; @@ -198,11 +278,16 @@ AltDataView.prototype.show = function(key, isRTL) { * Hides the alt data view. */ AltDataView.prototype.hide = function() { - this.altdataElements_ = []; - this.highlightIndex_ = 0; + if (this.enableIMEWindow_) { + this.altdataWindow_.close(); + this.altdataWindow_ = null; + } else { + this.altdataElements_ = []; + } + this.triggeredBy.setHighlighted(false); goog.style.setElementShown(this.getElement(), false); goog.style.setElementShown(this.coverElement_, false); - this.triggeredBy.setHighlighted(false); + this.highlightIndex_ = AltDataView.INVALIDINDEX_; }; @@ -213,21 +298,30 @@ AltDataView.prototype.hide = function() { * @param {number} y . */ AltDataView.prototype.highlightItem = function(x, y) { - for (var i = 0; i < this.altdataElements_.length; i++) { - var elem = this.altdataElements_[i]; - var coordinate = goog.style.getClientPosition(elem); - var size = goog.style.getSize(elem); - if (coordinate.x < x && (coordinate.x + size.width) > x) { - this.highlightIndex_ = i; - this.clearAllHighlights_(); - this.setElementBackground_(elem, true); + if (this.enableIMEWindow_) { + if (this.altdataWindow_) { + var screenCoordinate = convertToScreenCoordinate( + new goog.math.Coordinate(x, y)); + this.altdataWindow_.contentWindow.accents.highlightItem( + screenCoordinate.x, screenCoordinate.y); } - var verticalDist = Math.min(Math.abs(y - coordinate.y), - Math.abs(y - coordinate.y - size.height)); - if (verticalDist > AltDataView. - FINGER_DISTANCE_TO_CANCEL_ALTDATA_) { - this.hide(); - return; + } else { + for (var i = 0; i < this.altdataElements_.length; i++) { + var elem = this.altdataElements_[i]; + var coordinate = goog.style.getClientPosition(elem); + var size = goog.style.getSize(elem); + if (coordinate.x < x && (coordinate.x + size.width) > x) { + this.highlightIndex_ = i; + this.clearAllHighlights_(); + this.setElementBackground_(elem, true); + } + var verticalDist = Math.min(Math.abs(y - coordinate.y), + Math.abs(y - coordinate.y - size.height)); + if (verticalDist > AltDataView. + FINGER_DISTANCE_TO_CANCEL_ALTDATA_) { + this.hide(); + return; + } } } }; @@ -271,7 +365,11 @@ AltDataView.prototype.setElementBackground_ = * @return {string} The character. */ AltDataView.prototype.getHighlightedCharacter = function() { - return goog.dom.getTextContent(this.altdataElements_[this.highlightIndex_]); + if (this.enableIMEWindow_) { + return this.altdataWindow_.contentWindow.accents.highlightedAccent(); + } else { + return goog.dom.getTextContent(this.altdataElements_[this.highlightIndex_]); + } }; |