# HG changeset patch # User Kartikaya Gupta # Date 1520742387 18000 # Node ID e2d541a790ea4419dc366ac9dc5d76a7ece662fc # Parent 55cc0de11809d013b7b76d94f67db146272b59b0 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 diff --git a/gfx/layers/apz/test/mochitest/apz_test_utils.js b/gfx/layers/apz/test/mochitest/apz_test_utils.js --- 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. diff --git a/testing/mochitest/tests/SimpleTest/paint_listener.js b/testing/mochitest/tests/SimpleTest/paint_listener.js --- 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); + }); + } })();