fune/toolkit/modules/tests/browser/head.js
Gijs Kruitbosch d2ebbb38df Bug 1358815 - remove sync reflow from find bar initialization, r=jaws
This removes the sync reflow from almost all cases. The only case where we keep it is when a keypress
caught in content triggers a sync message to the parent process. We should clean this up in bug 1371523.

I've tried to fix the tests, but a lot of them seem to be disabled anyway...

MozReview-Commit-ID: 9k36p7q8MKy

--HG--
extra : rebase_source : 311ee41ba9456a5c5d58b81a0cfa999bcef0027e
2018-03-12 14:01:44 +00:00

198 lines
7.1 KiB
JavaScript

"use strict";
ChromeUtils.defineModuleGetter(this, "setTimeout", "resource://gre/modules/Timer.jsm");
const kFixtureBaseURL = "https://example.com/browser/toolkit/modules/tests/browser/";
function removeDupes(list) {
let j = 0;
for (let i = 1; i < list.length; i++) {
if (list[i] != list[j]) {
j++;
if (i != j) {
list[j] = list[i];
}
}
}
list.length = j + 1;
}
function compareLists(list1, list2, kind) {
list1.sort();
removeDupes(list1);
list2.sort();
removeDupes(list2);
is(String(list1), String(list2), `${kind} URLs correct`);
}
async function promiseOpenFindbar(findbar) {
await gBrowser.getFindBar();
findbar.onFindCommand();
return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise;
}
function promiseFindResult(findbar, str = null) {
let highlightFinished = false;
let findFinished = false;
return new Promise(resolve => {
let listener = {
onFindResult({ searchString }) {
if (str !== null && str != searchString) {
return;
}
findFinished = true;
if (highlightFinished) {
findbar.browser.finder.removeResultListener(listener);
resolve();
}
},
onHighlightFinished() {
highlightFinished = true;
if (findFinished) {
findbar.browser.finder.removeResultListener(listener);
resolve();
}
},
onMatchesCountResult: () => {}
};
findbar.browser.finder.addResultListener(listener);
});
}
function promiseEnterStringIntoFindField(findbar, str) {
let promise = promiseFindResult(findbar, str);
for (let i = 0; i < str.length; i++) {
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, str.charCodeAt(i));
findbar._findField.inputField.dispatchEvent(event);
}
return promise;
}
function promiseTestHighlighterOutput(browser, word, expectedResult, extraTest = () => {}) {
return ContentTask.spawn(browser, { word, expectedResult, extraTest: extraTest.toSource() },
async function({ word, expectedResult, extraTest }) {
return new Promise((resolve, reject) => {
let stubbed = {};
let callCounts = {
insertCalls: [],
removeCalls: [],
animationCalls: []
};
let lastMaskNode, lastOutlineNode;
let rects = [];
// Amount of milliseconds to wait after the last time one of our stubs
// was called.
const kTimeoutMs = 1000;
// The initial timeout may wait for a while for results to come in.
let timeout = setTimeout(() => finish(false, "Timeout"), kTimeoutMs * 5);
function finish(ok = true, message = "finished with error") {
// Restore the functions we stubbed out.
try {
content.document.insertAnonymousContent = stubbed.insert;
content.document.removeAnonymousContent = stubbed.remove;
} catch (ex) {}
stubbed = {};
clearTimeout(timeout);
if (expectedResult.rectCount !== 0)
Assert.ok(ok, message);
Assert.greaterOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[0],
`Min. insert calls should match for '${word}'.`);
Assert.lessOrEqual(callCounts.insertCalls.length, expectedResult.insertCalls[1],
`Max. insert calls should match for '${word}'.`);
Assert.greaterOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[0],
`Min. remove calls should match for '${word}'.`);
Assert.lessOrEqual(callCounts.removeCalls.length, expectedResult.removeCalls[1],
`Max. remove calls should match for '${word}'.`);
// We reached the amount of calls we expected, so now we can check
// the amount of rects.
if (!lastMaskNode && expectedResult.rectCount !== 0) {
Assert.ok(false, `No mask node found, but expected ${expectedResult.rectCount} rects.`);
}
Assert.equal(rects.length, expectedResult.rectCount,
`Amount of inserted rects should match for '${word}'.`);
if ("animationCalls" in expectedResult) {
Assert.greaterOrEqual(callCounts.animationCalls.length,
expectedResult.animationCalls[0], `Min. animation calls should match for '${word}'.`);
Assert.lessOrEqual(callCounts.animationCalls.length,
expectedResult.animationCalls[1], `Max. animation calls should match for '${word}'.`);
}
// Allow more specific assertions to be tested in `extraTest`.
// eslint-disable-next-line no-eval
extraTest = eval(extraTest);
extraTest(lastMaskNode, lastOutlineNode, rects);
resolve();
}
function stubAnonymousContentNode(domNode, anonNode) {
let originals = [anonNode.setTextContentForElement,
anonNode.setAttributeForElement, anonNode.removeAttributeForElement,
anonNode.setCutoutRectsForElement, anonNode.setAnimationForElement];
anonNode.setTextContentForElement = (id, text) => {
try {
(domNode.querySelector("#" + id) || domNode).textContent = text;
} catch (ex) {}
return originals[0].call(anonNode, id, text);
};
anonNode.setAttributeForElement = (id, attrName, attrValue) => {
try {
(domNode.querySelector("#" + id) || domNode).setAttribute(attrName, attrValue);
} catch (ex) {}
return originals[1].call(anonNode, id, attrName, attrValue);
};
anonNode.removeAttributeForElement = (id, attrName) => {
try {
let node = domNode.querySelector("#" + id) || domNode;
if (node.hasAttribute(attrName))
node.removeAttribute(attrName);
} catch (ex) {}
return originals[2].call(anonNode, id, attrName);
};
anonNode.setCutoutRectsForElement = (id, cutoutRects) => {
rects = cutoutRects;
return originals[3].call(anonNode, id, cutoutRects);
};
anonNode.setAnimationForElement = (id, keyframes, options) => {
callCounts.animationCalls.push([keyframes, options]);
return originals[4].call(anonNode, id, keyframes, options);
};
}
// Create a function that will stub the original version and collects
// the arguments so we can check the results later.
function stub(which) {
stubbed[which] = content.document[which + "AnonymousContent"];
let prop = which + "Calls";
return function(node) {
callCounts[prop].push(node);
if (which == "insert") {
if (node.outerHTML.indexOf("outlineMask") > -1)
lastMaskNode = node;
else
lastOutlineNode = node;
}
clearTimeout(timeout);
timeout = setTimeout(() => {
finish();
}, kTimeoutMs);
let res = stubbed[which].call(content.document, node);
if (which == "insert")
stubAnonymousContentNode(node, res);
return res;
};
}
content.document.insertAnonymousContent = stub("insert");
content.document.removeAnonymousContent = stub("remove");
});
});
}