Bug 1177943 - Part 4 - Implement remote nsICommandWithParams. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 01 Apr 2016 15:05:34 +0900
changeset 346486 1a7d78de79a42ef33bad7b498d8ccc1c13c96c14
parent 346485 dd82862c8a12a152f149062006d65e1a8c6d6af1
child 346487 b19dab7bacaa4426d1bf2bd27e8d770d44a913f4
push id14395
push userm_kato@ga2.so-net.ne.jp
push dateFri, 01 Apr 2016 06:23:11 +0000
reviewersmasayuki
bugs1177943
milestone48.0a1
Bug 1177943 - Part 4 - Implement remote nsICommandWithParams. r?masayuki When using content command with params, it doesn't work well. So I implement it for e10s. MozReview-Commit-ID: KHb7HZegreZ
docshell/base/nsDocShell.cpp
docshell/base/nsIDocShell.idl
toolkit/content/browser-child.js
toolkit/modules/RemoteController.jsm
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -13351,16 +13351,30 @@ nsDocShell::DoCommand(const char* aComma
   rv = GetControllerForCommand(aCommand, getter_AddRefs(controller));
   if (controller) {
     rv = controller->DoCommand(aCommand);
   }
 
   return rv;
 }
 
+NS_IMETHODIMP
+nsDocShell::DoCommandWithParams(const char* aCommand, nsICommandParams* aParams)
+{
+  nsCOMPtr<nsIController> controller;
+  nsresult rv = GetControllerForCommand(aCommand, getter_AddRefs(controller));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsICommandController> commandController =
+    do_QueryInterface(controller, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return commandController->DoCommandWithParams(aCommand, aParams);
+}
+
 nsresult
 nsDocShell::EnsureCommandHandler()
 {
   if (!mCommandManager) {
     nsCOMPtr<nsPICommandUpdater> commandUpdater =
       do_CreateInstance("@mozilla.org/embedcomp/command-manager;1");
     if (!commandUpdater) {
       return NS_ERROR_OUT_OF_MEMORY;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -37,16 +37,17 @@ interface nsIScriptGlobalObject;
 interface nsIDOMStorage;
 interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 interface nsIScrollObserver;
 interface nsITabParent;
 interface nsITabChild;
+interface nsICommandParams;
 native TabChildRef(already_AddRefed<nsITabChild>);
 
 typedef unsigned long nsLoadFlags;
 
 [scriptable, builtinclass, uuid(049234fe-da10-478b-bc5d-bc6f9a1ba63d)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
@@ -1009,16 +1010,17 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
     * Cherry picked parts of nsIController.
     * They are here, because we want to call these functions
     * from JS.
     */
   boolean isCommandEnabled(in string command);
   void doCommand(in string command);
+  void doCommandWithParams(in string command, in nsICommandParams aParams);
 
   /**
    * Invisible DocShell are dummy construct to simulate DOM windows
    * without any actual visual representation. They have to be marked
    * at construction time, to avoid any painting activity.
    */
   [noscript, notxpcom] bool IsInvisible();
   [noscript, notxpcom] void SetInvisible(in bool aIsInvisibleDochsell);
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
+var Cr = Components.results;
 
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import("resource://gre/modules/RemoteAddonsChild.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PageThumbUtils",
@@ -346,24 +347,42 @@ var SecurityUI = {
 
     return null;
   }
 };
 
 var ControllerCommands = {
   init: function () {
     addMessageListener("ControllerCommands:Do", this);
+    addMessageListener("ControllerCommands:DoWithParams", this);
   },
 
   receiveMessage: function(message) {
     switch(message.name) {
       case "ControllerCommands:Do":
         if (docShell.isCommandEnabled(message.data))
           docShell.doCommand(message.data);
         break;
+
+      case "ControllerCommands:DoWithParams":
+        var data = JSON.parse(message.data);
+        if (docShell.isCommandEnabled(data.cmd)) {
+          var params = Cc["@mozilla.org/embedcomp/command-params;1"].
+                       createInstance(Ci.nsICommandParams);
+          for (var name in data.params) {
+            var value = data.params[name];
+            if (value.type == "long") {
+              params.setLongValue(name, parseInt(value.value));
+            } else {
+              throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+            }
+          }
+          docShell.doCommandWithParams(data.cmd, params);
+        }
+        break;
     }
   }
 }
 
 ControllerCommands.init()
 
 addEventListener("DOMTitleChanged", function (aEvent) {
   let document = content.document;
--- a/toolkit/modules/RemoteController.jsm
+++ b/toolkit/modules/RemoteController.jsm
@@ -3,43 +3,77 @@
 // 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/.
 
 this.EXPORTED_SYMBOLS = ["RemoteController"];
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cu = Components.utils;
+const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function RemoteController(browser)
 {
   this._browser = browser;
 
   // A map of commands that have had their enabled/disabled state assigned. The
   // value of each key will be true if enabled, and false if disabled.
   this._supportedCommands = { };
 }
 
 RemoteController.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIController]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIController,
+                                         Ci.nsICommandController]),
 
   isCommandEnabled: function(aCommand) {
     return this._supportedCommands[aCommand] || false;
   },
 
   supportsCommand: function(aCommand) {
     return aCommand in this._supportedCommands;
   },
 
   doCommand: function(aCommand) {
     this._browser.messageManager.sendAsyncMessage("ControllerCommands:Do", aCommand);
   },
 
+  getCommandStateWithParams: function(aCommand, aCommandParams) {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  doCommandWithParams: function(aCommand, aCommandParams) {
+    let cmd = {
+      cmd: aCommand,
+      params: null
+    };
+    if (aCommand == "cmd_lookUpDictionary") {
+      let rect = this._browser.getBoundingClientRect();
+      cmd.params = {
+        x:  {
+          type: "long",
+          value: aCommandParams.getLongValue("x") - rect.left
+        },
+        y: {
+          type: "long",
+          value: aCommandParams.getLongValue("y") - rect.top
+        }
+      };
+    } else {
+      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+    }
+    this._browser.messageManager.sendAsyncMessage(
+      "ControllerCommands:DoWithParams", JSON.stringify(cmd));
+  },
+
+  getSupportedCommands: function(aCount, aCommands) {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
   onEvent: function () {},
 
   // This is intended to be called from the remote-browser binding to update
   // the enabled and disabled commands.
   enableDisableCommands: function(aAction,
                                   aEnabledLength, aEnabledCommands,
                                   aDisabledLength, aDisabledCommands) {
     // Clear the list first