Bug 766878 - IME prototype doesn't work with <iframe mozbrowser remote>. r=cjones

This commit is contained in:
Vivien Nicolas 2012-06-26 16:01:53 +02:00
parent 1e74489d3e
commit 4159ace448
3 changed files with 61 additions and 55 deletions

View File

@ -13,6 +13,7 @@ let Cc = Components.classes;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyServiceGetter(Services, "fm",
"@mozilla.org/focus-manager;1",
"nsIFocusManager");
@ -26,11 +27,9 @@ let HTMLOptionElement = Ci.nsIDOMHTMLOptionElement;
let FormAssistant = {
init: function fa_init() {
addEventListener("focus", this, true, false);
addEventListener("keypress", this, true, false);
addEventListener("mousedown", this, true, false);
addEventListener("resize", this, true, false);
addEventListener("click", this, true, false);
addEventListener("blur", this, true, false);
addEventListener("keypress", this, true, false);
addEventListener("resize", this, true, false);
addMessageListener("Forms:Select:Choice", this);
addMessageListener("Forms:Input:Value", this);
Services.obs.addObserver(this, "ime-enabled-state-changed", false);
@ -45,48 +44,49 @@ let FormAssistant = {
switch (evt.type) {
case "focus":
this.previousTarget = Services.fm.focusedElement;
break;
case "blur":
if (!target)
return;
this.previousTarget = null;
if (target instanceof HTMLSelectElement ||
(target instanceof HTMLOptionElement && target.parentNode instanceof HTMLSelectElement)) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
}
break;
case 'resize':
if (!this.isKeyboardOpened)
return;
Services.fm.focusedElement.scrollIntoView(false);
break;
case "mousedown":
if (evt.target != target || this.isKeyboardOpened)
if (this.isKeyboardOpened)
return;
let ignore = {
button: true,
checkbox: true,
file: true,
checkbox: true,
radio: true,
reset: true,
submit: true
};
if ((target instanceof HTMLInputElement && ignore[target.type]) ||
!(target instanceof HTMLInputElement ||
target instanceof HTMLTextAreaElement)) {
return;
if (evt.target instanceof HTMLSelectElement) {
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(evt.target));
});
} else if (evt.target instanceof HTMLOptionElement &&
evt.target.parentNode instanceof HTMLSelectElement) {
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(evt.target.parentNode));
});
} else if ((target instanceof HTMLInputElement && !ignore[target.type]) ||
target instanceof HTMLTextAreaElement) {
this.isKeyboardOpened = this.tryShowIme(evt.target);
this.previousTarget = evt.target;
}
break;
this.isKeyboardOpened = this.tryShowIme(evt.target);
case "blur":
if (this.previousTarget) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.previousTarget = null;
}
break;
case "resize":
if (!this.isKeyboardOpened)
return;
let focusedElement = this.previousTarget;
if (focusedElement) {
focusedElement.scrollIntoView(false);
}
break;
case "keypress":
@ -99,24 +99,14 @@ let FormAssistant = {
evt.preventDefault();
evt.stopPropagation();
break;
case "click":
content.setTimeout(function showIMEForSelect() {
if (evt.target instanceof HTMLSelectElement) {
sendAsyncMessage("Forms:Input", getJSON(evt.target));
} else if (evt.target instanceof HTMLOptionElement &&
evt.target.parentNode instanceof HTMLSelectElement) {
sendAsyncMessage("Forms:Input", getJSON(evt.target.parentNode));
}
});
break;
}
},
receiveMessage: function fa_receiveMessage(msg) {
let target = Services.fm.focusedElement;
if (!target)
let target = this.previousTarget;
if (!target) {
return;
}
let json = msg.json;
switch (msg.name) {
@ -169,8 +159,9 @@ let FormAssistant = {
// FIXME/bug 729623: work around apparent bug in the IME manager
// in gecko.
let readonly = element.getAttribute("readonly");
if (readonly)
if (readonly) {
return false;
}
sendAsyncMessage("Forms:Input", getJSON(element));
return true;
@ -181,7 +172,8 @@ FormAssistant.init();
function getJSON(element) {
let type = element.type;
let type = element.type || "";
// FIXME/bug 344616 is input type="number"
// Until then, let's return 'number' even if the platform returns 'text'
let attributeType = element.getAttribute("type") || "";

View File

@ -13,10 +13,6 @@ Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/Geometry.jsm');
XPCOMUtils.defineLazyServiceGetter(Services, 'fm',
'@mozilla.org/focus-manager;1',
'nsIFocusManager');
const ContentPanning = {
init: function cp_init() {
['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {

View File

@ -7,6 +7,7 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const kFormsFrameScript = "chrome://browser/content/forms.js";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -37,10 +38,12 @@ MozKeyboard.prototype = {
}),
init: function mozKeyboardInit(win) {
messageManager.loadFrameScript("chrome://browser/content/forms.js", true);
messageManager.loadFrameScript(kFormsFrameScript, true);
messageManager.addMessageListener("Forms:Input", this);
Services.obs.addObserver(this, "inner-window-destroyed", false);
Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
this._window = win;
this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
@ -105,11 +108,26 @@ MozKeyboard.prototype = {
},
observe: function mozKeyboardObserve(subject, topic, data) {
if (topic == "inner-window-destroyed") {
switch (topic) {
case "inner-window-destroyed": {
let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
this.uninit();
}
break;
}
case 'remote-browser-frame-shown':
case 'in-process-browser-frame-shown': {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
mm.addMessageListener("Forms:Input", this);
try {
mm.loadFrameScript(kFormsFrameScript, true);
} catch (e) {
dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
}
break;
}
}
}
};