Bug 1281171 - implement a debug mode for the finder highlighter. r=jaws
authorMike de Boer <mdeboer@mozilla.com>
Thu, 28 Jul 2016 17:53:20 +0200
changeset 349145 915257f0f74c8f124904cbcf8ca8204ada4370c7
parent 349144 54eb32559af3c72a14593fdcea471ecae7001da2
child 349146 c70e8c8d0a79ff6cb88d2fcffd165506a1fd388e
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1281171
milestone50.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 1281171 - implement a debug mode for the finder highlighter. r=jaws MozReview-Commit-ID: Ay0yNw94qsS
toolkit/modules/FinderHighlighter.jsm
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -8,16 +8,20 @@ this.EXPORTED_SYMBOLS = ["FinderHighligh
 
 const { interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Color", "resource://gre/modules/Color.jsm");
+XPCOMUtils.defineLazyGetter(this, "kDebug", () => {
+  const kDebugPref = "findbar.modalHighlight.debug";
+  return Services.prefs.getPrefType(kDebugPref) && Services.prefs.getBoolPref(kDebugPref);
+});
 
 const kModalHighlightRepaintFreqMs = 10;
 const kModalHighlightPref = "findbar.modalHighlight";
 const kFontPropsCSS = ["color", "font-family", "font-kerning", "font-size",
   "font-size-adjust", "font-stretch", "font-variant", "font-weight", "letter-spacing",
   "text-emphasis", "text-orientation", "text-transform", "word-spacing"];
 const kFontPropsCamelCase = kFontPropsCSS.map(prop => {
   let parts = prop.split("-");
@@ -45,16 +49,20 @@ const kModalStyle = `
   padding-top: 2px;
   padding-inline-end: 2px;
   padding-bottom: 0;
   padding-inline-start: 4px;
   pointer-events: none;
   z-index: 2;
 }
 
+.findbar-modalHighlight-outline.findbar-debug {
+  z-index: 2147483647;
+}
+
 .findbar-modalHighlight-outline[grow] {
   transform: scaleX(1.5) scaleY(1.5)
 }
 
 .findbar-modalHighlight-outline[hidden] {
   opacity: 0;
   display: -moz-box;
 }
@@ -68,31 +76,65 @@ const kModalStyle = `
 .findbar-modalHighlight-outlineMask {
   background: #000;
   mix-blend-mode: multiply;
   opacity: .2;
   position: absolute;
   z-index: 1;
 }
 
+.findbar-modalHighlight-outlineMask.findbar-debug {
+  z-index: 2147483646;
+  top: 0;
+  left: 0;
+}
+
 .findbar-modalHighlight-outlineMask[brighttext] {
   background: #fff;
 }
 
 .findbar-modalHighlight-rect {
   background: #fff;
   border: 1px solid #666;
   position: absolute;
 }
 
 .findbar-modalHighlight-outlineMask[brighttext] > .findbar-modalHighlight-rect {
   background: #000;
 }`;
 const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
+function mockAnonymousContentNode(domNode) {
+  return {
+    setTextContentForElement(id, text) {
+      (domNode.querySelector("#" + id) || domNode).textContent = text;
+    },
+    getAttributeForElement(id, attrName) {
+      let node = domNode.querySelector("#" + id) || domNode;
+      if (!node.hasAttribute(attrName))
+        return undefined;
+      return node.getAttribute(attrName);
+    },
+    setAttributeForElement(id, attrName, attrValue) {
+      (domNode.querySelector("#" + id) || domNode).setAttribute(attrName, attrValue);
+    },
+    removeAttributeForElement(id, attrName) {
+      let node = domNode.querySelector("#" + id) || domNode;
+      if (!node.hasAttribute(attrName))
+        return;
+      node.removeAttribute(attrName);
+    },
+    remove() {
+      try {
+        domNode.parentNode.removeChild(domNode);
+      } catch (ex) {}
+    }
+  };
+}
+
 /**
  * FinderHighlighter class that is used by Finder.jsm to take care of the
  * 'Highlight All' feature, which can highlight all find occurrences in a page.
  *
  * @param {Finder} finder Finder.jsm instance
  */
 function FinderHighlighter(finder) {
   this.finder = finder;
@@ -362,16 +404,18 @@ FinderHighlighter.prototype = {
    * contents is not valid anymore, i.e. all anonymous content is destroyed.
    * We need to clear the references we keep, which'll make sure we redraw
    * everything when the user starts to find in page again.
    */
   onLocationChange() {
     if (!this._modalHighlightOutline)
       return;
 
+    if (kDebug)
+      this._modalHighlightOutline.remove();
     try {
       this.finder._getWindow().document
         .removeAnonymousContent(this._modalHighlightOutline);
     } catch(ex) {}
 
     this._modalHighlightOutline = null;
   },
 
@@ -573,26 +617,28 @@ FinderHighlighter.prototype = {
 
     // The outline needs to be sitting inside a container, otherwise the anonymous
     // content API won't find it by its ID later...
     let container = document.createElement("div");
 
     // Create the main (yellow) highlight outline box.
     let outlineBox = document.createElement("div");
     outlineBox.setAttribute("id", kModalOutlineId);
-    outlineBox.className = kModalOutlineId;
+    outlineBox.className = kModalOutlineId + (kDebug ? ` ${kModalIdPrefix}-findbar-debug` : "");
     let outlineBoxText = document.createElement("span");
     outlineBoxText.setAttribute("id", kModalOutlineId + "-text");
     outlineBox.appendChild(outlineBoxText);
 
     container.appendChild(outlineBox);
 
     this._repaintHighlightAllMask(window);
 
-    this._modalHighlightOutline = document.insertAnonymousContent(container);
+    this._modalHighlightOutline = kDebug ?
+      mockAnonymousContentNode(document.body.appendChild(container.firstChild)) :
+      document.insertAnonymousContent(container);
     return this._modalHighlightOutline;
   },
 
   /**
    * Build and draw the mask that takes care of the dimmed background that
    * overlays the current page and the mask that cuts out all the rectangles of
    * the ranges that were found.
    *
@@ -602,17 +648,17 @@ FinderHighlighter.prototype = {
     let document = window.document;
 
     const kMaskId = kModalIdPrefix + "-findbar-modalHighlight-outlineMask";
     let maskNode = document.createElement("div");
 
     // Make sure the dimmed mask node takes the full width and height that's available.
     let {width, height} = this._getWindowDimensions(window);
     maskNode.setAttribute("id", kMaskId);
-    maskNode.setAttribute("class", kMaskId);
+    maskNode.setAttribute("class", kMaskId + (kDebug ? ` ${kModalIdPrefix}-findbar-debug` : ""));
     maskNode.setAttribute("style", `width: ${width}px; height: ${height}px;`);
     if (this._brightText)
       maskNode.setAttribute("brighttext", "true");
 
     // Create a DOM node for each rectangle representing the ranges we found.
     let maskContent = [];
     const kRectClassName = kModalIdPrefix + "-findbar-modalHighlight-rect";
     if (this._modalHighlightRectsMap) {
@@ -624,28 +670,32 @@ FinderHighlighter.prototype = {
       }
     }
     maskNode.innerHTML = maskContent.join("");
 
     // Always remove the current mask and insert it a-fresh, because we're not
     // free to alter DOM nodes inside the CanvasFrame.
     this._removeHighlightAllMask(window);
 
-    this._modalHighlightAllMask = document.insertAnonymousContent(maskNode);
+    this._modalHighlightAllMask = kDebug ?
+      mockAnonymousContentNode(document.body.appendChild(maskNode)) :
+      document.insertAnonymousContent(maskNode);
   },
 
   /**
    * Safely remove the mask AnoymousContent node from the CanvasFrame.
    *
    * @param {nsIDOMWindow} window
    */
   _removeHighlightAllMask(window) {
     if (this._modalHighlightAllMask) {
       // If the current window isn't the one the content was inserted into, this
       // will fail, but that's fine.
+      if (kDebug)
+        this._modalHighlightAllMask.remove();
       try {
         window.document.removeAnonymousContent(this._modalHighlightAllMask);
       } catch(ex) {}
       this._modalHighlightAllMask = null;
     }
   },
 
   /**