Bug 796080 - Pass inputmode, selectionStart, and selectionEnd to mozKeyboard. r=vingtetun

This commit is contained in:
David Flanagan 2012-10-04 23:21:10 -07:00
Родитель 087efdaacf
Коммит 2190a271e3
1 изменённых файлов: 72 добавлений и 21 удалений

Просмотреть файл

@ -4,10 +4,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
dump("###################################### forms.js loaded\n");
"use strict";
dump("###################################### forms.js loaded\n");
let Ci = Components.interfaces;
let Cc = Components.classes;
let Cu = Components.utils;
@ -37,9 +37,29 @@ let FormAssistant = {
},
isKeyboardOpened: false,
previousTarget : null,
focusedElement : null,
selectionStart: 0,
selectionEnd: 0,
setFocusedElement: function fa_setFocusedElement(element) {
if (element === this.focusedElement)
return;
if (this.focusedElement) {
this.focusedElement.removeEventListener('mousedown', this);
this.focusedElement.removeEventListener('mouseup', this);
}
if (element) {
element.addEventListener('mousedown', this);
element.addEventListener('mouseup', this);
}
this.focusedElement = element;
},
handleEvent: function fa_handleEvent(evt) {
let previousTarget = this.previousTarget;
let focusedElement = this.focusedElement;
let target = evt.target;
switch (evt.type) {
@ -57,27 +77,47 @@ let FormAssistant = {
image: true
};
if (evt.target instanceof HTMLSelectElement) {
if (target instanceof HTMLSelectElement) {
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(evt.target));
sendAsyncMessage("Forms:Input", getJSON(target));
});
this.previousTarget = evt.target;
} else if (evt.target instanceof HTMLOptionElement &&
evt.target.parentNode instanceof HTMLSelectElement) {
this.setFocusedElement(target);
} else if (target instanceof HTMLOptionElement &&
target.parentNode instanceof HTMLSelectElement) {
target = target.parentNode;
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(evt.target.parentNode));
sendAsyncMessage("Forms:Input", getJSON(target));
});
this.setFocusedElement(target);
} else if ((target instanceof HTMLInputElement && !ignore[target.type]) ||
target instanceof HTMLTextAreaElement) {
this.isKeyboardOpened = this.tryShowIme(evt.target);
this.previousTarget = evt.target;
this.isKeyboardOpened = this.tryShowIme(target);
this.setFocusedElement(target);
}
break;
case "blur":
if (this.previousTarget) {
if (this.focusedElement) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.previousTarget = null;
this.setFocusedElement(null);
}
break;
case 'mousedown':
// We only listen for this event on the currently focused element.
// When the mouse goes down, note the cursor/selection position
this.selectionStart = this.focusedElement.selectionStart;
this.selectionEnd = this.focusedElement.selectionEnd;
break;
case 'mouseup':
// We only listen for this event on the currently focused element.
// When the mouse goes up, see if the cursor has moved (or the
// selection changed) since the mouse went down. If it has, we
// need to tell the keyboard about it
if (this.focusedElement.selectionStart !== this.selectionStart ||
this.focusedElement.selectionEnd !== this.selectionEnd) {
this.tryShowIme(this.focusedElement);
}
break;
@ -85,9 +125,8 @@ let FormAssistant = {
if (!this.isKeyboardOpened)
return;
let focusedElement = this.previousTarget;
if (focusedElement) {
focusedElement.scrollIntoView(false);
if (this.focusedElement) {
this.focusedElement.scrollIntoView(false);
}
break;
@ -105,7 +144,7 @@ let FormAssistant = {
},
receiveMessage: function fa_receiveMessage(msg) {
let target = this.previousTarget;
let target = this.focusedElement;
if (!target) {
return;
}
@ -158,10 +197,10 @@ let FormAssistant = {
let target = Services.fm.focusedElement;
if (!target || !this.tryShowIme(target)) {
this.previousTarget = null;
this.setFocusedElement(null);
return;
} else {
this.previousTarget = target;
this.setFocusedElement(target);
}
} else if (!shouldOpen && isOpen) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
@ -173,6 +212,7 @@ let FormAssistant = {
Services.obs.removeObserver(this, "ime-enabled-state-changed", false);
Services.obs.removeObserver(this, "xpcom-shutdown");
removeMessageListener("Forms:Select:Choice", this);
removeMessageListener("Forms:Input:Value", this);
break;
}
},
@ -218,10 +258,21 @@ function getJSON(element) {
}
}
// If Gecko knows about the inputmode attribute, use that value.
// Otherwise, query the attribute explicitly, but be sure to convert
// to lowercase
let inputmode = element.inputmode || element.getAttribute('inputmode');
if (inputmode) {
inputmode = inputmode.toLowerCase();
}
return {
"type": type.toLowerCase(),
"choices": getListForElement(element),
"value": element.value
"value": element.value,
"inputmode": inputmode,
"selectionStart": element.selectionStart,
"selectionEnd": element.selectionEnd
};
}