Bug 1302035 - implement an algorithm to better detect whether a page is dark or bright and use that to toggle the dimming mode of the find toolbar. r=jaws

MozReview-Commit-ID: 2yJsHfivEBO

--HG--
extra : rebase_source : 3ab85f9ccd5aa9a600aa3fbb73d7963ef533237d
This commit is contained in:
Mike de Boer 2016-09-23 15:35:14 +02:00
Родитель 1045a329b8
Коммит 7ec46da176
1 изменённых файлов: 47 добавлений и 7 удалений

Просмотреть файл

@ -20,6 +20,7 @@ XPCOMUtils.defineLazyGetter(this, "kDebug", () => {
});
const kContentChangeThresholdPx = 5;
const kBrightTextSampleSize = 5;
const kModalHighlightRepaintFreqMs = 100;
const kHighlightAllPref = "findbar.highlightAll";
const kModalHighlightPref = "findbar.modalHighlight";
@ -357,7 +358,6 @@ FinderHighlighter.prototype = {
this._removeHighlightAllMask(window);
this._removeModalHighlightListeners(window);
delete dict.brightText;
dict.visible = false;
},
@ -413,11 +413,6 @@ FinderHighlighter.prototype = {
return;
}
let fontStyle = this._getRangeFontStyle(foundRange);
if (typeof dict.brightText == "undefined") {
dict.brightText = this._isColorBright(fontStyle.color);
}
if (data.findAgain)
dict.updateAllRanges = true;
@ -426,7 +421,7 @@ FinderHighlighter.prototype = {
else
this._maybeCreateModalHighlightNodes(window);
this._updateRangeOutline(dict, textContent, fontStyle);
this._updateRangeOutline(dict, textContent);
}
let outlineNode = dict.modalHighlightOutline;
@ -462,6 +457,7 @@ FinderHighlighter.prototype = {
dict.dynamicRangesSet.clear();
dict.frames.clear();
dict.modalHighlightRectsMap.clear();
dict.brightText = null;
},
/**
@ -711,6 +707,48 @@ FinderHighlighter.prototype = {
return new Color(...cssColor).isBright;
},
/**
* Detects if the overall text color in the page can be described as bright.
* This is done according to the following algorithm:
* 1. With the entire set of ranges that we have found thusfar;
* 2. Get an odd-numbered `sampleSize`, with a maximum of `kBrightTextSampleSize`
* ranges,
* 3. Slice the set of ranges into `sampleSize` number of equal parts,
* 4. Grab the first range for each slice and inspect the brightness of the
* color of its text content.
* 5. When the majority of ranges are counted as contain bright colored text,
* the page is considered to contain bright text overall.
*
* @param {Object} dict Dictionary of properties belonging to the
* currently active window. The page text color property
* will be recorded in `dict.brightText` as `true` or `false`.
*/
_detectBrightText(dict) {
let sampleSize = Math.min(dict.modalHighlightRectsMap.size, kBrightTextSampleSize);
let ranges = [...dict.modalHighlightRectsMap.keys()];
let rangesCount = ranges.length;
// Make sure the sample size is an odd number.
if (sampleSize % 2 == 0) {
// Make the currently found range weigh heavier.
if (dict.currentFoundRange) {
ranges.push(dict.currentFoundRange);
++sampleSize;
++rangesCount;
} else {
--sampleSize;
}
}
let brightCount = 0;
for (let i = 0; i < sampleSize; ++i) {
let range = ranges[Math.floor((rangesCount / sampleSize) * i)];
let fontStyle = this._getRangeFontStyle(range);
if (this._isColorBright(fontStyle.color))
++brightCount;
}
dict.brightText = (brightCount >= Math.ceil(sampleSize / 2));
},
/**
* Checks if a range is inside a DOM node that's positioned in a way that it
* doesn't scroll along when the document is scrolled and/ or zoomed. This
@ -1012,6 +1050,8 @@ FinderHighlighter.prototype = {
// Make sure the dimmed mask node takes the full width and height that's available.
let {width, height} = dict.lastWindowDimensions = this._getWindowDimensions(window);
if (typeof dict.brightText != "boolean" || dict.updateAllRanges)
this._detectBrightText(dict);
let maskStyle = this._getStyleString(kModalStyles.maskNode,
[ ["width", width + "px"], ["height", height + "px"] ],
dict.brightText ? kModalStyles.maskNodeBrightText : [],