Bug 860546 - [keyboard] Notify keyboard when the content of current input field is changed by JS. r=fabrice

This commit is contained in:
=?UTF-8?q?"Yuan=20Xulei(=E8=A2=81=E5=BE=90=E7=A3=8A)"?= 2013-05-03 15:02:30 +02:00
parent feca6da63d
commit 4cef999701

View File

@ -203,6 +203,8 @@ let FormAssistant = {
scrollIntoViewTimeout: null, scrollIntoViewTimeout: null,
_focusedElement: null, _focusedElement: null,
_documentEncoder: null, _documentEncoder: null,
_editor: null,
_editing: false,
get focusedElement() { get focusedElement() {
if (this._focusedElement && Cu.isDeadWrapper(this._focusedElement)) if (this._focusedElement && Cu.isDeadWrapper(this._focusedElement))
@ -228,6 +230,10 @@ let FormAssistant = {
} }
this._documentEncoder = null; this._documentEncoder = null;
if (this._editor) {
this._editor.removeEditorObserver(this);
this._editor = null;
}
if (element) { if (element) {
element.addEventListener('mousedown', this); element.addEventListener('mousedown', this);
@ -235,6 +241,12 @@ let FormAssistant = {
if (isContentEditable(element)) { if (isContentEditable(element)) {
this._documentEncoder = getDocumentEncoder(element); this._documentEncoder = getDocumentEncoder(element);
} }
this._editor = getPlaintextEditor(element);
if (this._editor) {
// Add a nsIEditorObserver to monitor the text content of the focused
// element.
this._editor.addEditorObserver(this);
}
} }
this.focusedElement = element; this.focusedElement = element;
@ -244,6 +256,15 @@ let FormAssistant = {
return this._documentEncoder; return this._documentEncoder;
}, },
// Implements nsIEditorObserver get notification when the text content of
// current input field has changed.
EditAction: function fa_editAction() {
if (this._editing) {
return;
}
this.sendKeyboardState(this.focusedElement);
},
handleEvent: function fa_handleEvent(evt) { handleEvent: function fa_handleEvent(evt) {
let target = evt.target; let target = evt.target;
@ -331,10 +352,14 @@ let FormAssistant = {
break; break;
case "keydown": case "keydown":
// Don't monitor the text change resulting from key event.
this._editing = true;
// We use 'setTimeout' to wait until the input element accomplishes the // We use 'setTimeout' to wait until the input element accomplishes the
// change in selection range // change in selection range or text content.
content.setTimeout(function() { content.setTimeout(function() {
this.updateSelection(); this.updateSelection();
this._editing = false;
}.bind(this), 0); }.bind(this), 0);
break; break;
} }
@ -346,6 +371,7 @@ let FormAssistant = {
return; return;
} }
this._editing = true;
let json = msg.json; let json = msg.json;
switch (msg.name) { switch (msg.name) {
case "Forms:Input:Value": { case "Forms:Input:Value": {
@ -396,6 +422,8 @@ let FormAssistant = {
break; break;
} }
} }
this._editing = false;
}, },
showKeyboard: function fa_showKeyboard(target) { showKeyboard: function fa_showKeyboard(target) {
@ -724,3 +752,27 @@ function setSelectionRange(element, start, end) {
} }
} }
// Get nsIPlaintextEditor object from an input field
function getPlaintextEditor(element) {
let editor = null;
// Get nsIEditor
if (element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement) {
// Get from the <input> and <textarea> elements
editor = element.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
} else if (isContentEditable(element)) {
// Get from content editable element
let win = element.ownerDocument.defaultView;
let editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession);
if (editingSession) {
editor = editingSession.getEditorForWindow(win);
}
}
if (editor) {
editor.QueryInterface(Ci.nsIPlaintextEditor);
}
return editor;
}