Skip to content

Instantly share code, notes, and snippets.

@mikedeboer
Created June 11, 2016 14:11
Show Gist options
  • Save mikedeboer/6d167d8336e9cda2c273c9ed63475ae8 to your computer and use it in GitHub Desktop.
Save mikedeboer/6d167d8336e9cda2c273c9ed63475ae8 to your computer and use it in GitHub Desktop.
Finder highlighter using HTML and mix-blend-mode
# HG changeset patch
# User Mike de Boer <[email protected]>
# Date 1465654180 -7200
# Sat Jun 11 16:09:40 2016 +0200
# Node ID 1c1bb8d010aa1c474b4c656397b465b83e7e17a5
# Parent ff9fd611d818116cfd47ee7d067c2642368cf3f9
[mq]: highlighterHTML
diff --git a/toolkit/modules/FinderHighlighter.jsm b/toolkit/modules/FinderHighlighter.jsm
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -39,31 +39,44 @@ const kModalStyle = `
margin-inline-end: 0;
margin-bottom: 0;
margin-inline-start: -3px;
padding-top: 2px;
padding-inline-end: 2px;
padding-bottom: 0;
padding-inline-start: 4px;
pointer-events: none;
+ z-index: 2;
}
.findbar-modalHighlight-outline[grow] {
transform: scaleX(1.5) scaleY(1.5)
}
.findbar-modalHighlight-outline[hidden] {
opacity: 0;
display: -moz-box;
}
.findbar-modalHighlight-outline:not([disable-transitions]) {
transition-property: opacity, transform, top, left;
transition-duration: 50ms;
transition-timing-function: linear;
+}
+
+.findbar-modalHighlight-outlineMask {
+ position: absolute;
+ opacity: .2;
+ mix-blend-mode: multiply;
+ z-index: 1;
+}
+
+.findbar-modalHighlight-rect {
+ position: absolute;
+ border: 1px solid #666;
}`;
const kSVGNS = "http://www.w3.org/2000/svg";
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
/**
* 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.
*
@@ -496,16 +509,17 @@ FinderHighlighter.prototype = {
let rects = new Set();
// Absolute positions should include the viewport scroll offset.
let { scrollX, scrollY } = this._getScrollPosition(window);
// A range may consist of multiple rectangles, but since we're cutting them
// out using SVG we can also do these kind of precise cut-outs.
// range.getBoundingClientRect() returns the fully encompassing rectangle,
// which is too much for our purpose here.
+ // dump("SCROLL:: " + scrollY + "\n");
for (let dims of range.getClientRects()) {
rects.add({
height: dims.bottom - dims.top,
width: dims.right - dims.left,
y: dims.top + scrollY,
x: dims.left + scrollX
});
}
@@ -574,44 +588,56 @@ FinderHighlighter.prototype = {
* the ranges that were found.
*
* @param {nsIDOMWindow} window Window to draw in.
*/
_repaintHighlightAllMask(window) {
let document = window.document;
const kMaskId = kModalIdPrefix + "-findbar-modalHighlight-outlineMask";
- let svgNode = document.createElementNS(kSVGNS, "svg");
+ let svgNode = document.createElement("div");
+
+ // let svgNode = document.createElementNS(kSVGNS, "svg");
// Make sure the SVG drawing takes the full width and height that's available.
let {width, height} = this._getWindowDimensions(window);
- svgNode.setAttribute("viewBox", "0 0 " + width + " " + height);
+ // svgNode.setAttribute("viewBox", "0 0 " + width + " " + height);
+ svgNode.setAttribute("id", kMaskId);
+ svgNode.setAttribute("class", kMaskId);
+ svgNode.setAttribute("style", `width: ${width}px; height: ${height}px; background: #000`);
// The mask functions as a sort of inverse clip-path: instead of defining
// what to draw where, we need to do the opposite. We want the rectangles for
// each found range to be cut out of the dimmed-black background. That's why
// the mask is a full white large rectangle with small black rectangles that
// specifies where to let color bleed through and how much.
- let svgContent = [`<mask id="${kMaskId}">
- <rect x="0" y="0" height="${height}" width="${width}" fill="white"/>`];
+ // let svgContent = [`<mask id="${kMaskId}">
+ // <rect x="0" y="0" height="${height}" width="${width}" fill="white"/>`];
+ let svgContent = [];
+ const kRectClassName = kModalIdPrefix + "-findbar-modalHighlight-rect";
if (this._modalHighlightRectsMap) {
for (let rects of this._modalHighlightRectsMap.values()) {
for (let rect of rects) {
// The #666 stroke works to create the effect of blurred edges.
- svgContent.push(`<rect x="${rect.x}" y="${rect.y}"
- height="${rect.height}" width="${rect.width}"
- style="fill: #000; stroke-width: 1; stroke: #666"/>`);
+ // svgContent.push(`<rect x="${rect.x}" y="${rect.y}"
+ // height="${rect.height}" width="${rect.width}"
+ // style="fill: #000; stroke-width: 1; stroke: #666"/>`);
+ svgContent.push(`<div class="${kRectClassName}" style="top: ${rect.y}px;
+ left: ${rect.x}px; height: ${rect.height}px; width: ${rect.width}px;
+ background: #fff">&nbsp;</div>`);
}
}
}
// The big black opaque rectangle to which the mask is applied.
- svgNode.innerHTML = svgContent.join("") + `</mask>
- <rect x="0" y="0" height="${height}" width="${width}" fill="rgba(0,0,0,.2)"
- mask="url(#${kMaskId})"/>`;
+ // svgNode.innerHTML = svgContent.join("") + `</mask>
+ // <rect x="0" y="0" height="${height}" width="${width}" fill="rgba(0,0,0,.2)"
+ // mask="url(#${kMaskId})"/>`;
+ svgNode.innerHTML = svgContent.join("");
+ // dump("CONTENT:: " + svgNode.outerHTML + "\n");
// 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(svgNode);
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment