Bug 667062 - Content text selection highlight should match Gingerbread theming style [r=wjohnston]
authorMark Finkle <mfinkle@mozilla.com>
Wed, 13 Jul 2011 14:59:38 -0400
changeset 72780 225932c41c03953d4434d7d3b874ce9a09be65a4
parent 72742 800657b3354bea0a09d63d56a4e911d9534516ee
child 72781 b5ea2677daf60020ae6d4068139f4a987b08a61a
push id20772
push usereakhgari@mozilla.com
push dateThu, 14 Jul 2011 16:20:50 +0000
treeherdermozilla-central@89b5fccb0514 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswjohnston
bugs667062
milestone8.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 667062 - Content text selection highlight should match Gingerbread theming style [r=wjohnston]
mobile/chrome/content/content.js
mobile/themes/core/gingerbread/content.css
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1326,30 +1326,33 @@ var TouchEventHandler = {
     return aElement.dispatchEvent(evt);
   }
 };
 
 TouchEventHandler.init();
 
 var SelectionHandler = {
   cache: {},
+  selectedText: "",
   
   init: function() {
     addMessageListener("Browser:SelectionStart", this);
     addMessageListener("Browser:SelectionEnd", this);
     addMessageListener("Browser:SelectionMove", this);
   },
 
   receiveMessage: function(aMessage) {
     let scrollOffset = ContentScroll.getScrollOffset(content);
     let utils = Util.getWindowUtils(content);
     let json = aMessage.json;
 
     switch (aMessage.name) {
       case "Browser:SelectionStart": {
+        this.selectedText = "";
+
         // Position the caret using a fake mouse click
         utils.sendMouseEventToWindow("mousedown", json.x - scrollOffset.x, json.y - scrollOffset.y, 0, 1, 0, true);
         utils.sendMouseEventToWindow("mouseup", json.x - scrollOffset.x, json.y - scrollOffset.y, 0, 1, 0, true);
 
         // Select the word nearest the caret
         try {
           let selcon = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
           selcon.wordMove(false, false);
@@ -1360,58 +1363,80 @@ var SelectionHandler = {
         }
 
         // Find the selected text rect and send it back so the handles can position correctly
         let selection = content.getSelection();
         if (selection.rangeCount == 0)
           return;
 
         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.collapseToStart();
+          return;
+        }
+
         this.cache = { start: {}, end: {} };
         let rects = range.getClientRects();
         for (let i=0; i<rects.length; i++) {
           if (i == 0) {
             this.cache.start.x = rects[i].left + scrollOffset.x;
             this.cache.start.y = rects[i].bottom + scrollOffset.y;
           }
           this.cache.end.x = rects[i].right + scrollOffset.x;
           this.cache.end.y = rects[i].bottom + scrollOffset.y;
         }
 
         sendAsyncMessage("Browser:SelectionRange", this.cache);
         break;
       }
 
       case "Browser:SelectionEnd": {
-        let selection = content.getSelection();
-        let str = selection.toString();
-        selection.collapseToStart();
-        if (str.length) {
+        try {
+          // The selection might already be gone
+          content.getSelection().collapseToStart();
+        } catch(e) {}
+
+        if (this.selectedText.length) {
           let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
-          clipboard.copyString(str);
+          clipboard.copyString(this.selectedText);
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: true });
         } else {
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: false });
         }
         break;
       }
 
       case "Browser:SelectionMove":
+        // Hack to avoid setting focus in a textbox [Bugs 654352 & 667243]
+        let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
+        if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement)
+          return;
+
         if (json.type == "end") {
           this.cache.end.x = json.x - scrollOffset.x;
           this.cache.end.y = json.y - scrollOffset.y;
           utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
           utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
         } else {
           this.cache.start.x = json.x - scrollOffset.x;
           this.cache.start.y = json.y - scrollOffset.y;
           utils.sendMouseEventToWindow("mousedown", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
           // Don't cause a click. A mousedown is enough to move the caret
           //utils.sendMouseEventToWindow("mouseup", this.cache.start.x, this.cache.start.y, 0, 1, 0, true);
           utils.sendMouseEventToWindow("mousedown", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
           utils.sendMouseEventToWindow("mouseup", this.cache.end.x, this.cache.end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
         }
+
+        // Cache the selected text since the selection might be gone by the time we get the "end" message
+        this.selectedText = content.getSelection().toString().trim();
         break;
     }
   }
 };
 
 SelectionHandler.init();
--- a/mobile/themes/core/gingerbread/content.css
+++ b/mobile/themes/core/gingerbread/content.css
@@ -50,16 +50,21 @@
     outline-color: -moz-mac-focusring !important;
   */
 }
 
 *:-moz-any-link:focus {
   outline-offset: -2px;
 }
 
+::-moz-selection {
+  background-color: @color_background_highlight@;
+  color: @color_text_highlight@;
+}
+
 /* Style the scrollbars */
 html xul|scrollbar {
   display: none;
 }
 
 xul|window xul|scrollbar {
   display: block;
 }