Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/base/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  browser_promiseDocumentFlushed.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */


"use strict";

/**
 * Dirties style and layout on the current browser window.
 *
 * @param {Number} Optional factor by which to modify the DOM. Useful for
 *        when multiple calls to dirtyTheDOM may occur, and you need them
 *        to dirty the DOM differently from one another. If you only need
 *        to dirty the DOM once, this can be omitted.
 */

function dirtyStyleAndLayout(factor = 1) {
  gNavToolbox.style.padding = factor + "px";
}

/**
 * Dirties style of the current browser window, but NOT layout.
 */

function dirtyStyle() {
  gNavToolbox.style.color = "red";
}

const gWindowUtils = window.windowUtils;

/**
 * Asserts that no style or layout flushes are required by the
 * current window.
 */

function assertNoFlushesRequired() {
  Assert.ok(
    !gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
    "No style flushes are required."
  );
  Assert.ok(
    !gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
    "No layout flushes are required."
  );
}

/**
 * Asserts that the DOM has been dirtied, and so style and layout flushes
 * are required.
 */

function assertFlushesRequired() {
  Assert.ok(
    gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
    "Style flush required."
  );
  Assert.ok(
    gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
    "Layout flush required."
  );
}

/**
 * Removes style changes from dirtyTheDOM() from the browser window,
 * and resolves once the refresh driver ticks.
 */

async function cleanTheDOM() {
  gNavToolbox.style.padding = "";
  gNavToolbox.style.color = "";
  await window.promiseDocumentFlushed(() => {});
}

add_setup(async function () {
  registerCleanupFunction(cleanTheDOM);
});

/**
 * Tests that if the DOM is dirty, that promiseDocumentFlushed will
 * resolve once layout and style have been flushed.
 */

add_task(async function test_basic() {
  info("Dirtying style / layout");
  dirtyStyleAndLayout();
  assertFlushesRequired();

  info("Waiting");
  await window.promiseDocumentFlushed(() => {});
  assertNoFlushesRequired();

  info("Dirtying style");
  dirtyStyle();
  assertFlushesRequired();

  info("Waiting");
  await window.promiseDocumentFlushed(() => {});
  assertNoFlushesRequired();

  // The DOM should be clean already, but we'll do this anyway to isolate
  // failures from other tests.
  info("Cleaning up");
  await cleanTheDOM();
});

/**
 * Test that values returned by the callback passed to promiseDocumentFlushed
 * get passed down through the Promise resolution.
 */

add_task(async function test_can_get_results_from_callback() {
  const NEW_PADDING = "2px";

  gNavToolbox.style.padding = NEW_PADDING;

  assertFlushesRequired();

  let paddings = await window.promiseDocumentFlushed(() => {
    let style = window.getComputedStyle(gNavToolbox);
    return {
      left: style.paddingLeft,
      right: style.paddingRight,
      top: style.paddingTop,
      bottom: style.paddingBottom,
    };
  });

  for (let prop in paddings) {
    Assert.equal(paddings[prop], NEW_PADDING, "Got expected padding");
  }

  await cleanTheDOM();

  gNavToolbox.style.padding = NEW_PADDING;

  assertFlushesRequired();

  let rect = await window.promiseDocumentFlushed(() => {
    let observer = {
      reflow() {
        Assert.ok(false"A reflow should not have occurred.");
      },
      reflowInterruptible() {},
      QueryInterface: ChromeUtils.generateQI([
        "nsIReflowObserver",
        "nsISupportsWeakReference",
      ]),
    };

    let docShell = window.docShell;
    docShell.addWeakReflowObserver(observer);

    let toolboxRect = gNavToolbox.getBoundingClientRect();

    docShell.removeWeakReflowObserver(observer);
    return toolboxRect;
  });

  // The actual values of this rect aren't super important for
  // the purposes of this test - we just want to know that a valid
  // rect was returned, so checking for properties being greater than
  // 0 is sufficient.
  for (let property of ["width""height"]) {
    Assert.ok(
      rect[property] > 0,
      `Rect property ${property} > 0 (${rect[property]})`
    );
  }

  await cleanTheDOM();
});

/**
 * Test that if promiseDocumentFlushed is requested on a window
 * that closes before it gets a chance to do a refresh driver
 * tick, the promiseDocumentFlushed Promise is still resolved, and
 * the callback is still called.
 */

add_task(async function test_resolved_in_window_close() {
  let win = await BrowserTestUtils.openNewBrowserWindow();

  await win.promiseDocumentFlushed(() => {});

  // Use advanceTimeAndRefresh to pause paints in the window:
  let utils = win.windowUtils;
  utils.advanceTimeAndRefresh(0);

  win.gNavToolbox.style.padding = "5px";

  const EXPECTED = 1234;
  let promise = win.promiseDocumentFlushed(() => {
    // Despite the window not painting before closing, this
    // callback should be fired when the window gets torn
    // down and should stil be able to return a result.
    return EXPECTED;
  });

  await BrowserTestUtils.closeWindow(win);
  Assert.equal(await promise, EXPECTED);
});

/**
 * Test that re-entering promiseDocumentFlushed is not possible
 * from within a promiseDocumentFlushed callback. Doing so will
 * result in the outer Promise rejecting with InvalidStateError.
 */

add_task(async function test_reentrancy() {
  dirtyStyleAndLayout();
  assertFlushesRequired();

  let promise = window.promiseDocumentFlushed(() => {
    return window.promiseDocumentFlushed(() => {
      Assert.ok(false"Should never run this.");
    });
  });

  await Assert.rejects(promise, ex => ex.name == "InvalidStateError");
});

/**
 * Tests the expected execution order of a series of promiseDocumentFlushed
 * calls, their callbacks, and the resolutions of their Promises.
 *
 * When multiple promiseDocumentFlushed callbacks are queued, the callbacks
 * should always been run first before any of the Promises are resolved.
 *
 * The callbacks should run in the order that they were queued in via
 * promiseDocumentFlushed. The Promise resolutions should similarly run
 * in the order that promiseDocumentFlushed was called in.
 */

add_task(async function test_execution_order() {
  let result = [];

  dirtyStyleAndLayout(1);
  let promise1 = window
    .promiseDocumentFlushed(() => {
      result.push(0);
    })
    .then(() => {
      result.push(2);
    });

  let promise2 = window
    .promiseDocumentFlushed(() => {
      result.push(1);
    })
    .then(() => {
      result.push(3);
    });

  await Promise.all([promise1, promise2]);

  Assert.equal(result.length, 4, "Should have run all callbacks and Promises.");

  let promise3 = window
    .promiseDocumentFlushed(() => {
      result.push(4);
    })
    .then(() => {
      result.push(6);
    });

  let promise4 = window
    .promiseDocumentFlushed(() => {
      result.push(5);
    })
    .then(() => {
      result.push(7);
    });

  await Promise.all([promise3, promise4]);

  Assert.equal(result.length, 8, "Should have run all callbacks and Promises.");

  for (let i = 0; i < result.length; ++i) {
    Assert.equal(
      result[i],
      i,
      "Callbacks and Promises should have run in the expected order."
    );
  }

  await cleanTheDOM();
});

/**
 * Tests that modifying the DOM within a promiseDocumentFlushed callback
 * will result in the Promise being rejected.
 */

add_task(async function test_reject_on_modification() {
  dirtyStyleAndLayout(1);
  assertFlushesRequired();

  let promise = window.promiseDocumentFlushed(() => {
    dirtyStyleAndLayout(2);
  });

  await Assert.rejects(promise, /NoModificationAllowedError/);

  await cleanTheDOM();
});

Messung V0.5
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.