Bug 986992 - Part 1: Merge navigator.mozKeyboard to navigator.mozInputMethod. r=fabrice

This commit is contained in:
Yuan Xulei 2014-03-31 10:38:45 +08:00
parent 0a6789bfc5
commit 5ef8a3a81b
5 changed files with 109 additions and 25 deletions

View File

@ -2258,12 +2258,16 @@ Navigator::HasInputMethodSupport(JSContext* /* unused */,
JSObject* aGlobal)
{
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
if (!win || !Preferences::GetBool("dom.mozInputMethod.enabled", false)) {
return false;
}
if (Preferences::GetBool("dom.mozInputMethod.testing", false)) {
return true;
}
return Preferences::GetBool("dom.mozInputMethod.enabled", false) &&
win && CheckPermission(win, "input");
return CheckPermission(win, "input") ||
CheckPermission(win, "input-manage");
}
/* static */

View File

@ -19,6 +19,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
this.Keyboard = {
_formMM: null, // The current web page message manager.
_keyboardMM: null, // The keyboard app message manager.
_systemMessageName: [
'SetValue', 'RemoveFocus', 'SetSelectedOption', 'SetSelectedOptions'
],
_messageNames: [
'SetValue', 'RemoveFocus', 'SetSelectedOption', 'SetSelectedOptions',
'SetSelectionRange', 'ReplaceSurroundingText', 'ShowInputMethodPicker',
@ -56,8 +60,13 @@ this.Keyboard = {
Services.obs.addObserver(this, 'remote-browser-shown', false);
Services.obs.addObserver(this, 'oop-frameloader-crashed', false);
for (let name of this._messageNames)
for (let name of this._messageNames) {
ppmm.addMessageListener('Keyboard:' + name, this);
}
for (let name of this._systemMessageName) {
ppmm.addMessageListener('System:' + name, this);
}
},
observe: function keyboardObserve(subject, topic, data) {
@ -97,12 +106,13 @@ this.Keyboard = {
},
receiveMessage: function keyboardReceiveMessage(msg) {
// If we get a 'Keyboard:XXX' message, check that the sender has the
// input permission.
// If we get a 'Keyboard:XXX'/'System:XXX' message, check that the sender
// has the required permission.
let mm;
let isKeyboardRegistration = msg.name == "Keyboard:Register" ||
msg.name == "Keyboard:Unregister";
if (msg.name.indexOf("Keyboard:") != -1) {
if (msg.name.indexOf("Keyboard:") === 0 ||
msg.name.indexOf("System:") === 0) {
if (!this.formMM && !isKeyboardRegistration) {
return;
}
@ -125,10 +135,13 @@ this.Keyboard = {
testing = Services.prefs.getBoolPref("dom.mozInputMethod.testing");
} catch (e) {
}
let perm = (msg.name.indexOf("Keyboard:") === 0) ? "input"
: "input-manage";
if (!isKeyboardRegistration && !testing &&
!mm.assertPermission("input")) {
!mm.assertPermission(perm)) {
dump("Keyboard message " + msg.name +
" from a content process with no 'input' privileges.");
" from a content process with no '" + perm + "' privileges.");
return;
}
}
@ -155,15 +168,19 @@ this.Keyboard = {
break;
case 'Keyboard:SetValue':
case 'System:SetValue':
this.setValue(msg);
break;
case 'Keyboard:RemoveFocus':
case 'System:RemoveFocus':
this.removeFocus();
break;
case 'Keyboard:SetSelectedOption':
case 'System:SetSelectedOption':
this.setSelectedOption(msg);
break;
case 'Keyboard:SetSelectedOptions':
case 'System:SetSelectedOptions':
this.setSelectedOption(msg);
break;
case 'Keyboard:SetSelectionRange':

View File

@ -287,12 +287,14 @@ MozInputMethod.prototype = {
_inputcontext: null,
_layouts: {},
_window: null,
_isSystem: false,
classID: Components.ID("{4607330d-e7d2-40a4-9eb8-43967eae0142}"),
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsIObserver
Ci.nsIObserver,
Ci.nsISupportsWeakReference
]),
init: function mozInputMethodInit(win) {
@ -302,20 +304,27 @@ MozInputMethod.prototype = {
.getInterface(Ci.nsIDOMWindowUtils)
.currentInnerWindowID;
let principal = win.document.nodePrincipal;
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
"input-manage");
if (perm === Ci.nsIPermissionManager.ALLOW_ACTION) {
this._isSystem = true;
}
Services.obs.addObserver(this, "inner-window-destroyed", false);
cpmm.addMessageListener('Keyboard:FocusChange', this);
cpmm.addMessageListener('Keyboard:SelectionChange', this);
cpmm.addMessageListener('Keyboard:GetContext:Result:OK', this);
cpmm.addMessageListener('Keyboard:LayoutsChange', this);
cpmm.addWeakMessageListener('Keyboard:FocusChange', this);
cpmm.addWeakMessageListener('Keyboard:SelectionChange', this);
cpmm.addWeakMessageListener('Keyboard:GetContext:Result:OK', this);
cpmm.addWeakMessageListener('Keyboard:LayoutsChange', this);
},
uninit: function mozInputMethodUninit() {
this.setActive(false);
Services.obs.removeObserver(this, "inner-window-destroyed");
cpmm.removeMessageListener('Keyboard:FocusChange', this);
cpmm.removeMessageListener('Keyboard:SelectionChange', this);
cpmm.removeMessageListener('Keyboard:GetContext:Result:OK', this);
cpmm.removeMessageListener('Keyboard:LayoutsChange', this);
cpmm.removeWeakMessageListener('Keyboard:FocusChange', this);
cpmm.removeWeakMessageListener('Keyboard:SelectionChange', this);
cpmm.removeWeakMessageListener('Keyboard:GetContext:Result:OK', this);
cpmm.removeWeakMessageListener('Keyboard:LayoutsChange', this);
this._window = null;
this._mgmt = null;
@ -419,6 +428,39 @@ MozInputMethod.prototype = {
this.setInputContext(null);
}
}
},
setValue: function(value) {
this._ensureIsSystem();
cpmm.sendAsyncMessage('System:SetValue', {
'value': value
});
},
setSelectedOption: function(index) {
this._ensureIsSystem();
cpmm.sendAsyncMessage('System:SetSelectedOption', {
'index': index
});
},
setSelectedOptions: function(indexes) {
this._ensureIsSystem();
cpmm.sendAsyncMessage('System:SetSelectedOptions', {
'indexes': indexes
});
},
removeFocus: function() {
this._ensureIsSystem();
cpmm.sendAsyncMessage('System:RemoveFocus', {});
},
_ensureIsSystem: function() {
if (!this._isSystem) {
throw new this._window.DOMError("Security",
"Should have 'input-manage' permssion.");
}
}
};

View File

@ -224,7 +224,6 @@ let FormAssistant = {
_documentEncoder: null,
_editor: null,
_editing: false,
_ignoreEditActionOnce: false,
get focusedElement() {
if (this._focusedElement && Cu.isDeadWrapper(this._focusedElement))
@ -320,9 +319,6 @@ let FormAssistant = {
EditAction: function fa_editAction() {
if (this._editing) {
return;
} else if (this._ignoreEditActionOnce) {
this._ignoreEditActionOnce = false;
return;
}
this.sendKeyboardState(this.focusedElement);
},
@ -441,9 +437,6 @@ let FormAssistant = {
CompositionManager.endComposition('');
// Don't monitor the text change resulting from key event.
this._ignoreEditActionOnce = true;
// We use 'setTimeout' to wait until the input element accomplishes the
// change in selection range.
content.setTimeout(function() {
@ -458,7 +451,6 @@ let FormAssistant = {
CompositionManager.endComposition('');
this._ignoreEditActionOnce = false;
break;
case "compositionend":

View File

@ -28,6 +28,35 @@ interface MozInputMethod : EventTarget {
[ChromeOnly]
// Activate or decactive current input method window.
void setActive(boolean isActive);
// The following are internal methods for Firefox OS system app only.
// Set the value on the currently focused element. This has to be used
// for special situations where the value had to be chosen amongst a
// list (type=month) or a widget (type=date, time, etc.).
// If the value passed in parameter isn't valid (in the term of HTML5
// Forms Validation), the value will simply be ignored by the element.
[Throws]
void setValue(DOMString value);
// Select the <select> option specified by index.
// If this method is called on a <select> that support multiple
// selection, then the option specified by index will be added to
// the selection.
// If this method is called for a select that does not support multiple
// selection the previous element will be unselected.
[Throws]
void setSelectedOption(long index);
// Select the <select> options specified by indexes. All other options
// will be deselected.
// If this method is called for a <select> that does not support multiple
// selection, then the last index specified in indexes will be selected.
[Throws]
void setSelectedOptions(sequence<long> indexes);
[Throws]
void removeFocus();
};
// Manages the list of IMEs, enables/disables IME and switches to an