Bug 1281171 - implement a debug mode for the finder highlighter. r?jaws draft
authorMike de Boer <mdeboer@mozilla.com>
Thu, 28 Jul 2016 17:53:20 +0200
changeset 393866 daed672af29211198ca3a03e6ebadb69ca7af0e9
parent 393862 2d6fced8b624ce179cef1053d9e3952dae7c726b
child 526682 da88da13d1d64388858a096f67f4fdf0f33e7745
push id24428
push usermdeboer@mozilla.com
push dateThu, 28 Jul 2016 15:55:20 +0000
reviewersjaws
bugs1281171
milestone50.0a1
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;
   },
 
@@ -586,26 +630,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.
    *
@@ -615,17 +661,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) {
@@ -637,28 +683,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;
     }
   },
 
   /**