Created
June 11, 2016 14:11
-
-
Save mikedeboer/6d167d8336e9cda2c273c9ed63475ae8 to your computer and use it in GitHub Desktop.
Finder highlighter using HTML and mix-blend-mode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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"> </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