loleaflet/src/control/Control.LokDialog.js | 92 ++++++++++++++++++++++------- loleaflet/src/map/handler/Map.Keyboard.js | 9 +- 2 files changed, 76 insertions(+), 25 deletions(-)
New commits: commit 8227c6853a4f0b59a84d61ddd537f79232f868dc Author: Pranav Kant <pran...@collabora.co.uk> Date: Wed Feb 14 18:11:31 2018 +0530 Use real input element for user input instead of canvas This allows moving the IME candidate window according to where the cursor in the lok dialog is. Change-Id: Icf17f1fc1d3f6af619c8e0037c32109d2b4721fc (cherry picked from commit 199b582e06a3234a1803553bf5be88c4d462ffc6) Reviewed-on: https://gerrit.libreoffice.org/49778 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js index d30e2411..7b43848b 100644 --- a/loleaflet/src/control/Control.LokDialog.js +++ b/loleaflet/src/control/Control.LokDialog.js @@ -2,7 +2,7 @@ * L.Control.LokDialog used for displaying LOK dialogs */ -/* global vex $ map */ +/* global vex $ map L */ L.Control.LokDialog = L.Control.extend({ dialogIdPrefix: 'lokdialog-', @@ -145,12 +145,7 @@ L.Control.LokDialog = L.Control.extend({ var y = parseInt(rectangle[1]); var height = parseInt(rectangle[3]); - var dialogCursor = L.DomUtil.get(strDlgId + '-cursor'); - L.DomUtil.setStyle(dialogCursor, 'height', height + 'px'); - L.DomUtil.setStyle(dialogCursor, 'display', this._dialogs[e.id].cursorVisible ? 'block' : 'none'); - // set the position of the cursor container element - L.DomUtil.setStyle(this._dialogs[e.id].cursor, 'left', x + 'px'); - L.DomUtil.setStyle(this._dialogs[e.id].cursor, 'top', y + 'px'); + this._updateDialogCursor(e.id, x, y, height); } } else if (e.action === 'title_changed') { if (e.title && this._dialogs[parseInt(e.id)]) { @@ -174,7 +169,20 @@ L.Control.LokDialog = L.Control.extend({ this._map.sendUnoCommand(e.uno); }, - _launchDialogCursor: function(dialogId) { + _updateDialogCursor: function(dlgId, x, y, height) { + var strDlgId = this._toDlgPrefix(dlgId); + var dialogCursor = L.DomUtil.get(strDlgId + '-cursor'); + L.DomUtil.setStyle(dialogCursor, 'height', height + 'px'); + L.DomUtil.setStyle(dialogCursor, 'display', this._dialogs[dlgId].cursorVisible ? 'block' : 'none'); + // set the position of the cursor container element + L.DomUtil.setStyle(this._dialogs[dlgId].cursor, 'left', x + 'px'); + L.DomUtil.setStyle(this._dialogs[dlgId].cursor, 'top', y + 'px'); + + // update the input as well + this._updateDialogInput(dlgId); + }, + + _createDialogCursor: function(dialogId) { var id = this._toRawDlgId(dialogId); this._dialogs[id].cursor = L.DomUtil.create('div', 'leaflet-cursor-container', L.DomUtil.get(dialogId)); var cursor = L.DomUtil.create('div', 'leaflet-cursor lokdialog-cursor', this._dialogs[id].cursor); @@ -182,6 +190,39 @@ L.Control.LokDialog = L.Control.extend({ L.DomUtil.addClass(cursor, 'blinking-cursor'); }, + _createDialogInput: function(dialogId) { + var id = this._toRawDlgId(dialogId); + var clipDlgContainer = L.DomUtil.create('div', 'clipboard-container', L.DomUtil.get(dialogId)); + clipDlgContainer.id = dialogId + '-clipboard-container'; + var dlgTextArea = L.DomUtil.create('input', 'clipboard', clipDlgContainer); + dlgTextArea.setAttribute('type', 'text'); + dlgTextArea.setAttribute('autocorrect', 'off'); + dlgTextArea.setAttribute('autocapitalize', 'off'); + dlgTextArea.setAttribute('autocomplete', 'off'); + dlgTextArea.setAttribute('spellcheck', 'false'); + this._dialogs[id].input = dlgTextArea; + + return dlgTextArea; + }, + + _updateDialogInput: function(dlgId) { + if (!this._dialogs[dlgId].input) + return; + + var strDlgId = this._toDlgPrefix(dlgId); + var left = parseInt(L.DomUtil.getStyle(this._dialogs[dlgId].cursor, 'left')); + var top = parseInt(L.DomUtil.getStyle(this._dialogs[dlgId].cursor, 'top')); + var dlgContainer = L.DomUtil.get(strDlgId + '-clipboard-container'); + L.DomUtil.setPosition(dlgContainer, new L.Point(left, top)); + }, + + focus: function(dlgId) { + if (!this._isOpen(dlgId) || !this._dialogs[dlgId].input) + return; + + this._dialogs[dlgId].input.focus(); + }, + _launchDialog: function(strDlgId, width, height, title) { var dialogContainer = L.DomUtil.create('div', 'lokdialog', document.body); L.DomUtil.setStyle(dialogContainer, 'padding', '0px'); @@ -192,8 +233,6 @@ L.Control.LokDialog = L.Control.extend({ var dialogCanvas = L.DomUtil.create('canvas', 'lokdialog_canvas', dialogContainer); dialogCanvas.width = width; dialogCanvas.height = height; - dialogCanvas.tabIndex = '0'; - dialogCanvas.contentEditable = true; dialogCanvas.id = strDlgId + '-canvas'; L.DomEvent.on(dialogCanvas, 'contextmenu', L.DomEvent.preventDefault); @@ -223,31 +262,38 @@ L.Control.LokDialog = L.Control.extend({ // don't make 'TAB' focus on this button; we want to cycle focus in the lok dialog with each TAB $('.lokdialog_container button.ui-dialog-titlebar-close').attr('tabindex', '-1').blur(); + this._createDialogCursor(strDlgId); + var dlgInput = this._createDialogInput(strDlgId); + L.DomEvent.on(dialogCanvas, 'mousedown mouseup', function(e) { var buttons = 0; buttons |= e.button === map['mouse'].JSButtons.left ? map['mouse'].LOButtons.left : 0; buttons |= e.button === map['mouse'].JSButtons.middle ? map['mouse'].LOButtons.middle : 0; buttons |= e.button === map['mouse'].JSButtons.right ? map['mouse'].LOButtons.right : 0; + // 'mousedown' -> 'buttondown' var lokEventType = e.type.replace('mouse', 'button'); this._postWindowMouseEvent(lokEventType, this._toRawDlgId(strDlgId), e.offsetX, e.offsetY, 1, buttons, 0); + dlgInput.focus(); }, this); - L.DomEvent.on(dialogCanvas, - 'keyup keypress keydown compositionstart compositionupdate compositionend', + L.DomEvent.on(dlgInput, + 'keyup keypress keydown compositionstart compositionupdate compositionend textInput', function(e) { e.originalEvent = e; // _onKeyDown fn below requires real event in e.originalEvent - var fn = this._postWindowKeyboardEvent; - if (e.type.startsWith('composition')) { - fn = this._postWindowCompositionEvent; - } - map['keyboard']._onKeyDown(e, L.bind(fn, - this, - this._toRawDlgId(strDlgId))); + map['keyboard']._onKeyDown(e, + L.bind(this._postWindowKeyboardEvent, + this, + this._toRawDlgId(strDlgId)), + L.bind(this._postWindowCompositionEvent, + this, + this._toRawDlgId(strDlgId)), + dlgInput); + + // keep map active while user is playing with dialog + this._map.lastActiveTime = Date.now(); }, this); - L.DomEvent.on(dialogCanvas, 'contextmenu', function() { + L.DomEvent.on(dlgInput, 'contextmenu', function() { return false; }); - - this._launchDialogCursor(strDlgId); }, _postWindowCompositionEvent: function(winid, type, text) { @@ -281,6 +327,7 @@ L.Control.LokDialog = L.Control.extend({ var img = new Image(); var canvas = document.getElementById(strDlgId + '-canvas'); var ctx = canvas.getContext('2d'); + var that = this; img.onload = function() { var x = 0; var y = 0; @@ -295,6 +342,7 @@ L.Control.LokDialog = L.Control.extend({ // if dialog is hidden, show it var dialogContainer = L.DomUtil.get(strDlgId); $(dialogContainer).parent().show(); + that.focus(dialogId); }; img.src = imgData; }, diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js index b1e25a2d..c7161535 100644 --- a/loleaflet/src/map/handler/Map.Keyboard.js +++ b/loleaflet/src/map/handler/Map.Keyboard.js @@ -237,7 +237,7 @@ L.Map.Keyboard = L.Handler.extend({ return this.keymap[keyCode] || keyCode; }, - _onKeyDown: function (e, keyEventFn, compEventFn) { + _onKeyDown: function (e, keyEventFn, compEventFn, inputEle) { if (this._map.slideShow && this._map.slideShow.fullscreen) { return; } @@ -250,6 +250,9 @@ L.Map.Keyboard = L.Handler.extend({ // document has winid=0 compEventFn = L.bind(docLayer._postCompositionEvent, docLayer, 0 /* winid */); } + if (!inputEle) { + inputEle = this._map._textArea; + } this.modifier = 0; var shift = e.originalEvent.shiftKey ? this.keyModifier.shift : 0; var ctrl = e.originalEvent.ctrlKey ? this.keyModifier.ctrl : 0; @@ -308,13 +311,13 @@ L.Map.Keyboard = L.Handler.extend({ // get the composited char codes // clear the input now - best to do this ASAP so the input // is clear for the next word - this._map._textArea.value = ''; + inputEle.value = ''; } if (!this._isComposing && e.type === 'keyup') { // not compositing and keyup, clear the input so it is ready // for next word (or char only) - this._map._textArea.value = ''; + inputEle.value = ''; } var unoKeyCode = this._toUNOKeyCode(keyCode); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits