1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 const Ci = Components.interfaces;
8 const Cu = Components.utils;
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
11 Cu.import("resource://gre/modules/Services.jsm");
12 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
14 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
15 "@mozilla.org/childprocessmessagemanager;1", "nsIMessageSender");
17 XPCOMUtils.defineLazyServiceGetter(this, "tm",
18 "@mozilla.org/thread-manager;1", "nsIThreadManager");
20 // -----------------------------------------------------------------------
22 // -----------------------------------------------------------------------
24 function MozKeyboard() { }
26 MozKeyboard.prototype = {
27 classID: Components.ID("{397a7fdf-2254-47be-b74e-76625a1a66d5}"),
29 QueryInterface: XPCOMUtils.generateQI([
30 Ci.nsIB2GKeyboard, Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIObserver
33 classInfo: XPCOMUtils.generateCI({
34 "classID": Components.ID("{397a7fdf-2254-47be-b74e-76625a1a66d5}"),
35 "contractID": "@mozilla.org/b2g-keyboard;1",
36 "interfaces": [Ci.nsIB2GKeyboard],
37 "flags": Ci.nsIClassInfo.DOM_OBJECT,
38 "classDescription": "B2G Virtual Keyboard"
41 init: function mozKeyboardInit(win) {
42 let principal = win.document.nodePrincipal;
43 let perm = Services.perms
44 .testExactPermissionFromPrincipal(principal, "keyboard");
45 if (perm != Ci.nsIPermissionManager.ALLOW_ACTION) {
46 dump("No permission to use the keyboard API for " +
47 principal.origin + "\n");
51 Services.obs.addObserver(this, "inner-window-destroyed", false);
52 cpmm.addMessageListener('Keyboard:FocusChange', this);
53 cpmm.addMessageListener('Keyboard:SelectionChange', this);
56 this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
57 .getInterface(Ci.nsIDOMWindowUtils);
58 this.innerWindowID = this._utils.currentInnerWindowID;
59 this._focusHandler = null;
60 this._selectionHandler = null;
61 this._selectionStart = -1;
62 this._selectionEnd = -1;
65 uninit: function mozKeyboardUninit() {
66 Services.obs.removeObserver(this, "inner-window-destroyed");
67 cpmm.removeMessageListener('Keyboard:FocusChange', this);
68 cpmm.removeMessageListener('Keyboard:SelectionChange', this);
72 this._focusHandler = null;
73 this._selectionHandler = null;
76 sendKey: function mozKeyboardSendKey(keyCode, charCode) {
77 charCode = (charCode == undefined) ? keyCode : charCode;
79 let mainThread = tm.mainThread;
80 let utils = this._utils;
83 mainThread.dispatch(function() {
84 utils.sendKeyEvent(type, keyCode, charCode, null);
85 }, mainThread.DISPATCH_NORMAL);
93 setSelectedOption: function mozKeyboardSetSelectedOption(index) {
94 cpmm.sendAsyncMessage('Keyboard:SetSelectedOption', {
99 setValue: function mozKeyboardSetValue(value) {
100 cpmm.sendAsyncMessage('Keyboard:SetValue', {
105 setSelectedOptions: function mozKeyboardSetSelectedOptions(indexes) {
106 cpmm.sendAsyncMessage('Keyboard:SetSelectedOptions', {
111 set onselectionchange(val) {
112 this._selectionHandler = val;
115 get onselectionchange() {
116 return this._selectionHandler;
119 get selectionStart() {
120 return this._selectionStart;
124 return this._selectionEnd;
127 setSelectionRange: function mozKeyboardSetSelectionRange(start, end) {
128 cpmm.sendAsyncMessage('Keyboard:SetSelectionRange', {
129 'selectionStart': start,
134 removeFocus: function mozKeyboardRemoveFocus() {
135 cpmm.sendAsyncMessage('Keyboard:RemoveFocus', {});
138 set onfocuschange(val) {
139 this._focusHandler = val;
142 get onfocuschange() {
143 return this._focusHandler;
146 replaceSurroundingText: function mozKeyboardReplaceSurroundingText(
147 text, beforeLength, afterLength) {
148 cpmm.sendAsyncMessage('Keyboard:ReplaceSurroundingText', {
150 'beforeLength': (typeof beforeLength === 'number' ? beforeLength : 0),
151 'afterLength': (typeof afterLength === 'number' ? afterLength: 0)
155 receiveMessage: function mozKeyboardReceiveMessage(msg) {
156 if (msg.name == "Keyboard:FocusChange") {
157 let msgJson = msg.json;
158 if (msgJson.type != "blur") {
159 this._selectionStart = msgJson.selectionStart;
160 this._selectionEnd = msgJson.selectionEnd;
162 this._selectionStart = 0;
163 this._selectionEnd = 0;
166 let handler = this._focusHandler;
167 if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
174 let evt = new this._window.CustomEvent("focuschanged",
175 ObjectWrapper.wrap(detail, this._window));
176 handler.handleEvent(evt);
177 } else if (msg.name == "Keyboard:SelectionChange") {
178 let msgJson = msg.json;
180 this._selectionStart = msgJson.selectionStart;
181 this._selectionEnd = msgJson.selectionEnd;
183 let handler = this._selectionHandler;
184 if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
187 let evt = new this._window.CustomEvent("selectionchange",
188 ObjectWrapper.wrap({}, this._window));
189 handler.handleEvent(evt);
193 observe: function mozKeyboardObserve(subject, topic, data) {
194 let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
195 if (wId == this.innerWindowID)
200 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozKeyboard]);