bug 666977 - Panning ends selection in progress r=mbrubeck
authorBrad Lassey <blassey@mozilla.com>
Thu, 18 Aug 2011 16:54:34 -0400
changeset 75508 00f9b3304811a191188521cc29ff1cc9034470c2
parent 75507 636d0e651d5e610c0c30a511e16d0ac98cc49223
child 75509 9cc3a0162863e70bff1d5c9b358580c40c41ce9e
push id21031
push usermak77@bonardo.net
push dateFri, 19 Aug 2011 09:40:40 +0000
treeherdermozilla-central@1881f9b5f8b5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs666977
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 666977 - Panning ends selection in progress r=mbrubeck
mobile/chrome/content/common-ui.js
mobile/chrome/content/content.js
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -1338,31 +1338,51 @@ var SelectionHelper = {
     window.removeEventListener("keypress", this, true);
     Elements.browsers.removeEventListener("URLChanged", this, true);
     Elements.browsers.removeEventListener("SizeChanged", this, true);
     Elements.browsers.removeEventListener("ZoomChanged", this, true);
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
+      case "PanBegin":
+        window.removeEventListener("PanBegin", this, true);
+        window.addEventListener("PanFinished", this, true);
+        this._start.hidden = true;
+        this._end.hidden = true;
+        break;
+      case "PanFinished":
+        window.removeEventListener("PanFinished", this, true);
+        try {
+          this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {});
+        } catch (e) {
+          Cu.reportError(e);
+        }
+        break
       case "TapDown":
         if (aEvent.target == this._start || aEvent.target == this._end) {
           this.target = aEvent.target;
           this.deltaX = (aEvent.clientX - this.target.left);
           this.deltaY = (aEvent.clientY - this.target.top);
           window.addEventListener("TapMove", this, true);
         } else {
-          this.hide(aEvent);
+          window.addEventListener("PanBegin", this, true);
+          this.target = null;
         }
         break;
       case "TapUp":
-        window.removeEventListener("TapMove", this, true);
-        this.target = null;
-        this.deltaX = -1;
-        this.deltaY = -1;
+        if (this.target) {
+          window.removeEventListener("TapMove", this, true);
+          this.target = null;
+          this.deltaX = -1;
+          this.deltaY = -1;
+        } else {
+          window.removeEventListener("PanBegin", self, true);
+          self.hide(aEvent);
+        }
         break;
       case "TapMove":
         if (this.target) {
           this.target.left = aEvent.clientX - this.deltaX;
           this.target.top = aEvent.clientY - this.deltaY;
           let rect = this.target.getBoundingClientRect();
           let data = this.target == this._start ? { x: rect.right, y: rect.top, type: "start" } : { x: rect.left, y: rect.top, type: "end" };
           let pos = this.popupState.target.transformClientToBrowser(data.x || 0, data.y || 0);
@@ -1370,20 +1390,28 @@ var SelectionHelper = {
             type: data.type,
             x: pos.x,
             y: pos.y
           };
           this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMove", json);
         }
         break;
       case "resize":
-      case "keypress":
-      case "URLChanged":
       case "SizeChanged":
       case "ZoomChanged":
+      {
+        try {
+          this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {});
+        } catch (e) {
+          Cu.reportError(e);
+        }
+        break        
+      }
+      case "URLChanged":
+      case "keypress":
         this.hide(aEvent);
         break;
     }
   },
 
   receiveMessage: function sh_receiveMessage(aMessage) {
     let json = aMessage.json;
     switch (aMessage.name) {
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1346,16 +1346,17 @@ var SelectionHandler = {
   cache: {},
   selectedText: "",
   contentWindow: null,
   
   init: function sh_init() {
     addMessageListener("Browser:SelectionStart", this);
     addMessageListener("Browser:SelectionEnd", this);
     addMessageListener("Browser:SelectionMove", this);
+    addMessageListener("Browser:SelectionMeasure", this);
   },
 
   getCurrentWindowAndOffset: function(x, y, offset) {
     let utils = Util.getWindowUtils(content);
     let elem = utils.elementFromPoint(x, y, true, false);
     while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
       // adjust client coordinates' origin to be top left of iframe viewport
       let rect = elem.getBoundingClientRect();
@@ -1496,16 +1497,36 @@ var SelectionHandler = {
         // Cache the selected text since the selection might be gone by the time we get the "end" message
         let selection = this.contentWindow.getSelection()
         this.selectedText = selection.toString().trim();
 
         // Update the rect we use to test when finishing the clipboard operation
         let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
         this.cache.rect = this._extractFromRange(range, this.cache.offset).rect;
         break;
+      case "Browser:SelectionMeasure": {
+        let selection = this.contentWindow.getSelection();
+        let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
+        if (!range)
+          return;
+
+        // Cache the selected text since the selection might be gone by the time we get the "end" message
+        this.selectedText = selection.toString().trim();
+
+        // If the range didn't have any text, let's bail
+        if (!this.selectedText.length) {
+          selection.removeAllRanges();
+          return;
+        }
+
+        this.cache = this._extractFromRange(range, this.cache.offset);
+
+        sendAsyncMessage("Browser:SelectionRange", this.cache);
+        break;
+      }
     }
   },
 
   _extractFromRange: function sh_extractFromRange(aRange, aOffset) {
     let cache = { start: {}, end: {}, rect: { left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0 } };
     let rects = aRange.getClientRects();
     for (let i=0; i<rects.length; i++) {
       if (i == 0) {