Bug 1287012 - [mortar][PDF] Enable select all feature. f=lchang, r=evelyn draft
authorRex Lee <rexboy@mozilla.com>
Fri, 10 Mar 2017 19:48:58 +0800
changeset 499127 85bd36dd5f580ee94b5191e2776a9709dead4f98
parent 496313 35398cae65c1526ce45c23a5f8b5568c5ada4762
child 502164 564ee834041bd200af06a71e2a8750d3182da969
child 502732 6f900c6df5122665ce54e1bc4f7d5a22804810f1
child 502791 f705011e9b7745551956b9b59119d6693d1e3978
push id49333
push userbmo:rexboy@mozilla.com
push dateWed, 15 Mar 2017 11:51:17 +0000
reviewersevelyn
bugs1287012
milestone55.0a1
Bug 1287012 - [mortar][PDF] Enable select all feature. f=lchang, r=evelyn Achieved by handling XUL command from sandbox side, to ensure commands from menu bar and other places all runs correctly. Text copy is changed to be handled there for the same reason. MozReview-Commit-ID: 34aCjNsBKYs
browser/extensions/mortar/host/common/ppapi-runtime.jsm
browser/extensions/mortar/host/pdf/chrome/js/viewport.js
browser/extensions/mortar/host/pdf/ppapi-content-sandbox.js
--- a/browser/extensions/mortar/host/common/ppapi-runtime.jsm
+++ b/browser/extensions/mortar/host/common/ppapi-runtime.jsm
@@ -1546,16 +1546,23 @@ class PPAPIInstance {
         type: "fullscreenChange",
         fullscreen: evt.data.fullscreen
       });
     });
 
     this.mm.addMessageListener("ppapipdf.js:hashchange", (evt) => {
       this.notifyHashChange(evt.data.url);
     });
+
+    this.mm.addMessageListener("ppapipdf.js:oncommand", (evt) => {
+      this.viewport.notify({
+        type: "command",
+        name: evt.data.name
+      });
+    });
   }
 
   notifyHashChange(url) {
     let location = new URL(url);
     if (location.hash) {
       this.viewport.notify({
         type: "hashChange",
         // substring(1) for getting rid of the first '#' character
--- a/browser/extensions/mortar/host/pdf/chrome/js/viewport.js
+++ b/browser/extensions/mortar/host/pdf/chrome/js/viewport.js
@@ -589,16 +589,31 @@ class Viewport {
   _handleHashChange(hash) {
     if (!this._documentDimensions) {
       this._initPosition = hash;
     } else {
       this._jumpToBookmark(hash);
     }
   }
 
+  _handleCommand(name) {
+    switch(name) {
+      case 'cmd_selectAll':
+        this._doAction({
+          type: 'selectAll'
+        });
+        break;
+      case 'cmd_copy':
+        this._doAction({
+          type: 'getSelectedText'
+        })
+        break;
+    }
+  }
+
   verifyPassword(password) {
     this._doAction({
       type: 'getPasswordComplete',
       password: password
     });
   }
 
   handleEvent(evt) {
@@ -609,22 +624,16 @@ class Viewport {
       case 'scroll':
         this._nextPosition = null;
         let position = this.getScrollOffset();
         if (this._runtimePosition.x != position.x ||
             this._runtimePosition.y != position.y) {
           this._refresh();
         }
         break;
-      case 'copy':
-        this._doAction({
-          type: 'getSelectedText'
-        })
-        evt.preventDefault();
-        break;
     }
   }
 
   invokeResize() {
     if (this._fullscreenStatus == 'changing') {
       return;
     }
     this._resize();
@@ -751,11 +760,14 @@ class Viewport {
       case 'getSelectedTextReply':
         // For now this message is used only by text copy so we handle just
         // that case.
         this._copyToClipboard(message.selectedText);
         break;
       case 'hashChange':
         this._handleHashChange(message.hash);
         break;
+      case 'command':
+        this._handleCommand(message.name);
+        break;
     }
   }
 }
--- a/browser/extensions/mortar/host/pdf/ppapi-content-sandbox.js
+++ b/browser/extensions/mortar/host/pdf/ppapi-content-sandbox.js
@@ -178,9 +178,40 @@ mm.addMessageListener("ppapipdf.js:save"
           .onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
       }
     };
 
     channel.asyncOpen2(listener);
   });
 });
 
+// This class is created to transfer global XUL commands event we needed.
+// The main reason we need to transfer it from sandbox side is that commands
+// triggered from menu bar targets only the outmost iframe (which is sandbox
+// itself) so we need to propagate it manually into the plugin's iframe.
+class CommandController {
+  constructor() {
+    this.SUPPORTED_COMMANDS = ['cmd_copy', 'cmd_selectAll'];
+    containerWindow.controllers.insertControllerAt(0, this);
+    containerWindow.addEventListener('unload', this.terminate.bind(this));
+  }
+
+  terminate() {
+    containerWindow.controllers.removeController(this);
+  }
+
+  supportsCommand(cmd) {
+    return this.SUPPORTED_COMMANDS.includes(cmd);
+  }
+
+  isCommandEnabled(cmd) {
+    return this.SUPPORTED_COMMANDS.includes(cmd);
+  }
+
+  doCommand(cmd) {
+    mm.sendAsyncMessage("ppapipdf.js:oncommand", {name: cmd});
+  }
+
+  onEvent(evt) {}
+};
+var commandController = new CommandController();
+
 mm.loadFrameScript("resource://ppapi.js/ppapi-instance.js", true);