Bug 621730: Blue Highlighting rect calculation is wrong on google images [r=mfinkle]
authorVivien Nicolas <21@vingtetun.org>
Wed, 29 Dec 2010 05:53:08 +0100
changeset 2559 74276ee973238330c9678559e8c07e9161b1c161
parent 2558 4e3d42d2f37f3bcb35f841876f3a23dd8d89100e
child 2560 741e07985880bec47c38c5b4da81d2423beb7840
push id2150
push uservnicolas@mozilla.com
push dateWed, 29 Dec 2010 04:54:42 +0000
reviewersmfinkle
bugs621730
Bug 621730: Blue Highlighting rect calculation is wrong on google images [r=mfinkle]
chrome/content/content.js
--- a/chrome/content/content.js
+++ b/chrome/content/content.js
@@ -178,16 +178,32 @@ function getBoundingContentRect(aElement
     let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth;
     let top = frame.getComputedStyle(frame.frameElement, "").borderTopWidth;
     offset.add(rect.left + parseInt(left), rect.top + parseInt(top));
   }
 
   return new Rect(r.left + offset.x, r.top + offset.y, r.width, r.height);
 }
 
+function getOverflowContentBoundingRect(aElement) {
+  let r = getBoundingContentRect(aElement);
+
+  // If the overflow is hidden don't bother calculating it
+  let computedStyle = aElement.ownerDocument.defaultView.getComputedStyle(aElement);
+  let blockDisplays = ["block", "inline-block", "list-item"];
+  if (blockDisplays.indexOf(computedStyle.getPropertyValue("display")) != -1 &&
+      computedStyle.getPropertyValue("overflow") == "hidden")
+    return r;
+
+  for (let i = 0; i < aElement.childElementCount; i++)
+    r = r.union(getBoundingContentRect(aElement.children[i]));
+
+  return r;
+}
+
 function getContentClientRects(aElement) {
   let offset = Util.getScrollOffset(content);
   let nativeRects = aElement.getClientRects();
   // step out of iframes and frames, offsetting scroll values
   for (let frame = aElement.ownerDocument.defaultView; frame != content; frame = frame.parent) {
     // adjust client coordinates' origin to be top left of iframe viewport
     let rect = frame.frameElement.getBoundingClientRect();
     let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth;
@@ -202,17 +218,16 @@ function getContentClientRects(aElement)
                   top: r.top + offset.y,
                   width: r.width,
                   height: r.height
                 });
   }
   return result;
 };
 
-
 /**
  * Responsible for sending messages about security, location, and page load state.
  * @param loadingController Object with methods startLoading and stopLoading
  */
 function ProgressController(loadingController) {
   this._webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
   this._overrideService = null;
   this._hostChanged = false;
@@ -424,26 +439,28 @@ Content.prototype = {
       case "Browser:MouseOver": {
         let element = elementFromPoint(x, y);
         if (!element)
           return;
 
         // Sending a mousemove force the dispatching of mouseover/mouseout
         this._sendMouseEvent("mousemove", element, x, y);
 
-        // XXX Could we replace all this javascript code by something CSS based
-        // using a mix on some -moz-focus-ring/-moz-focus-inner rules
-        let highlightRects = null;
+        // Calculate the rect of the active area
+        let targetElement = null;
         if (element.mozMatchesSelector("*:-moz-any-link, *[role=button],button,input,option,select,textarea,label"))
-          highlightRects = getContentClientRects(element);
+          targetElement = element;
         else if (element.mozMatchesSelector("*:-moz-any-link *"))
-          highlightRects = getContentClientRects(element.parentNode);
+          targetElement = element.parentNode;
 
-        if (highlightRects)
+        if (targetElement) {
+          let rect = getOverflowContentBoundingRect(targetElement);
+          let highlightRects = [{ left: rect.x, top: rect.y, width: rect.width, height: rect.height }];
           sendAsyncMessage("Browser:Highlight", { rects: highlightRects, messageId: json.messageId });
+        }
         break;
       }
 
       case "Browser:MouseUp": {
         this._formAssistant.focusSync = true;
         let element = elementFromPoint(x, y);
         if (modifiers == Ci.nsIDOMNSEvent.CONTROL_MASK) {
           let uri = Util.getHrefForElement(element);