Bug 1316459 - play range outline animations after its properties have been set as the result of a scheduled repaint of the modal highlighter. r?Gijs
MozReview-Commit-ID: 4xLHwB0l4ja
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -426,42 +426,30 @@ FinderHighlighter.prototype = {
if (!dict.visible && !params)
params = {word: data.searchString, linksOnly: data.linksOnly};
if (params)
this.highlight(true, params.word, params.linksOnly);
}
return;
}
+ dict.animateOutline = true;
+ // Immediately finish running animations, if any.
+ this._finishOutlineAnimations(dict);
+
if (foundRange !== dict.currentFoundRange || data.findAgain) {
dict.previousFoundRange = dict.currentFoundRange;
dict.currentFoundRange = foundRange;
if (!dict.visible)
this.show(window);
else
this._maybeCreateModalHighlightNodes(window);
}
- let outlineNode = dict.modalHighlightOutline;
- if (outlineNode && !this._isPageTooBig(dict)) {
- let animation;
- if (dict.animations) {
- for (animation of dict.animations)
- animation.finish();
- }
- dict.animations = [];
- for (let i = dict.previousRangeRectsAndTexts.rectList.length - 1; i >= 0; --i) {
- animation = outlineNode.setAnimationForElement(kModalOutlineId + i,
- Cu.cloneInto(kModalOutlineAnim.keyframes, window), kModalOutlineAnim.duration);
- animation.onfinish = function(idx) { dict.animations.splice(idx, 1); }.bind(null, i);
- dict.animations.push(animation);
- }
- }
-
if (this._highlightAll)
this.highlight(true, data.searchString, data.linksOnly);
},
/**
* Invalidates the list by clearing the map of highlighted ranges that we
* keep to build the mask for.
*/
@@ -471,20 +459,17 @@ FinderHighlighter.prototype = {
for (let win of gWindows.keys())
this.hide(win);
// Reset the Map, because no range references a node anymore.
gWindows.clear();
return;
}
let dict = this.getForWindow(window.top);
- if (dict.animations) {
- for (let animation of dict.animations)
- animation.finish();
- }
+ this._finishOutlineAnimations(dict);
dict.dynamicRangesSet.clear();
dict.frames.clear();
dict.modalHighlightRectsMap.clear();
dict.brightText = null;
},
/**
* When the current page is refreshed or navigated away from, the CanvasFrame
@@ -1001,20 +986,45 @@ FinderHighlighter.prototype = {
if (rebuildOutline) {
dict.modalHighlightOutline = kDebug ?
mockAnonymousContentNode((document.body ||
document.documentElement).appendChild(outlineBox)) :
document.insertAnonymousContent(outlineBox);
}
+ if (dict.animateOutline && !this._isPageTooBig(dict)) {
+ let animation;
+ dict.animations = new Set();
+ for (let i = rectsAndTexts.rectList.length - 1; i >= 0; --i) {
+ animation = dict.modalHighlightOutline.setAnimationForElement(kModalOutlineId + i,
+ Cu.cloneInto(kModalOutlineAnim.keyframes, window), kModalOutlineAnim.duration);
+ animation.onfinish = function() { dict.animations.delete(this); };
+ dict.animations.add(animation);
+ }
+ }
+ dict.animateOutline = false;
+
dict.previousUpdatedRange = range;
},
/**
+ * Finish any currently playing animations on the found range outline node.
+ *
+ * @param {Object} dict Dictionary of properties belonging to the currently
+ * active window
+ */
+ _finishOutlineAnimations(dict) {
+ if (!dict.animations)
+ return;
+ for (let animation of dict.animations)
+ animation.finish();
+ },
+
+ /**
* Safely remove the outline AnoymousContent node from the CanvasFrame.
*
* @param {nsIDOMWindow} window
*/
_removeRangeOutline(window) {
let dict = this.getForWindow(window);
if (!dict.modalHighlightOutline)
return;
--- a/toolkit/modules/tests/browser/browser_FinderHighlighter.js
+++ b/toolkit/modules/tests/browser/browser_FinderHighlighter.js
@@ -194,17 +194,17 @@ add_task(function* setup() {
// Test the results of modal highlighting, which is on by default.
add_task(function* testModalResults() {
let tests = new Map([
["Roland", {
rectCount: 2,
insertCalls: [2, 4],
removeCalls: [0, 1],
- animationCalls: [5, 6]
+ animationCalls: [1, 2]
}],
["their law might propagate their kind", {
rectCount: 2,
insertCalls: [5, 6],
removeCalls: [4, 5],
extraTest(maskNode, outlineNode, rects) {
Assert.equal(outlineNode.getElementsByTagName("div").length, 2,
"There should be multiple rects drawn");