Bug 1437295 - Promise-ify some of the paint/flushing methods. r?botond
This is functionally a no-op but it makes code cleaner, particularly
some of the changes in a future patch.
MozReview-Commit-ID: 5UoT3aNJaPz
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -110,54 +110,62 @@ function isLayerized(elementId) {
if (paint[scrollId]["contentDescription"].includes(elementId)) {
return true;
}
}
}
return false;
}
+function promiseApzRepaintsFlushed(aWindow = window) {
+ return new Promise(function (resolve, reject) {
+ var repaintDone = function() {
+ SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed");
+ setTimeout(resolve, 0);
+ };
+ SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed");
+ if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
+ dump("Flushed APZ repaints, waiting for callback...\n");
+ } else {
+ dump("Flushing APZ repaints was a no-op, triggering callback directly...\n");
+ repaintDone();
+ }
+ });
+}
+
function flushApzRepaints(aCallback, aWindow = window) {
if (!aCallback) {
throw "A callback must be provided!";
}
- var repaintDone = function() {
- SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed");
- setTimeout(aCallback, 0);
- };
- SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed");
- if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
- dump("Flushed APZ repaints, waiting for callback...\n");
- } else {
- dump("Flushing APZ repaints was a no-op, triggering callback directly...\n");
- repaintDone();
- }
+ promiseApzRepaintsFlushed(aWindow).then(aCallback);
}
// Flush repaints, APZ pending repaints, and any repaints resulting from that
// flush. This is particularly useful if the test needs to reach some sort of
-// "idle" state in terms of repaints. Usually just doing waitForAllPaints
+// "idle" state in terms of repaints. Usually just waiting for all paints
// followed by flushApzRepaints is sufficient to flush all APZ state back to
// the main thread, but it can leave a paint scheduled which will get triggered
// at some later time. For tests that specifically test for painting at
// specific times, this method is the way to go. Even if in doubt, this is the
// preferred method as the extra step is "safe" and shouldn't interfere with
// most tests.
function waitForApzFlushedRepaints(aCallback) {
// First flush the main-thread paints and send transactions to the APZ
- waitForAllPaints(function() {
+ promiseAllPaintsDone()
// Then flush the APZ to make sure any repaint requests have been sent
- // back to the main thread
- flushApzRepaints(function() {
- // Then flush the main-thread again to process the repaint requests.
- // Once this is done, we should be in a stable state with nothing
- // pending, so we can trigger the callback.
- waitForAllPaints(aCallback);
- });
- });
+ // back to the main thread. Note that we need a wrapper function around
+ // promiseApzRepaintsFlushed otherwise the rect produced by
+ // promiseAllPaintsDone gets passed to it as the window parameter.
+ .then(() => promiseApzRepaintsFlushed())
+ // Then flush the main-thread again to process the repaint requests.
+ // Once this is done, we should be in a stable state with nothing
+ // pending, so we can trigger the callback.
+ .then(promiseAllPaintsDone)
+ // Then allow the callback to be triggered.
+ .then(aCallback);
}
// This function takes a set of subtests to run one at a time in new top-level
// windows, and returns a Promise that is resolved once all the subtests are
// done running.
//
// The aSubtests array is an array of objects with the following keys:
// file: required, the filename of the subtest.
@@ -262,24 +270,20 @@ function runSubtestsSeriallyInFreshWindo
advanceSubtestExecution();
});
}
function pushPrefs(prefs) {
return SpecialPowers.pushPrefEnv({'set': prefs});
}
-function waitUntilApzStable() {
- return new Promise(function(resolve, reject) {
- SimpleTest.waitForFocus(function() {
- waitForAllPaints(function() {
- flushApzRepaints(resolve);
- });
- }, window);
- });
+async function waitUntilApzStable() {
+ await SimpleTest.promiseFocus(window);
+ await promiseAllPaintsDone();
+ await promiseApzRepaintsFlushed();
}
function isApzEnabled() {
var enabled = SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled;
if (!enabled) {
// All tests are required to have at least one assertion. Since APZ is
// disabled, and the main test is presumably not going to run, we stick in
// a dummy assertion here to keep the test passing.
--- a/testing/mochitest/tests/SimpleTest/paint_listener.js
+++ b/testing/mochitest/tests/SimpleTest/paint_listener.js
@@ -79,9 +79,18 @@
window.waitForAllPaintsFlushed = function(callback, subdoc) {
waitForPaints(callback, subdoc, FlushModes.FLUSH);
};
window.waitForAllPaints = function(callback) {
waitForPaints(callback, null, FlushModes.NOFLUSH);
};
+
+ window.promiseAllPaintsDone = function(subdoc = null, flush = false) {
+ var flushmode = flush ? FlushModes.FLUSH : FlushModes.NOFLUSH;
+ return new Promise(function (resolve, reject) {
+ // The callback is given the components of the rect, but resolve() can
+ // only be given one arg, so we turn it back into an array.
+ waitForPaints((l, r, t, b) => resolve([l, r, t, b]), subdoc, flushmode);
+ });
+ }
})();