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

Quelle  test_interactive_widget.html   Sprache: HTML

 
 products/Sources/formale Sprachen/C/Firefox/layout/base/tests/test_interactive_widget.html


<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>interactive-widget tests</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
  <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
  <style>
  textarea {
    height: 100px;
    width: 100px;
  }
  </style>
</head>
<body>
<textarea></textarea>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script>
async function getViewportMetrics() {
  return SpecialPowers.spawn(parent, [], () => {
    return [ content.window.innerHeight,
             content.window.visualViewport.height,
             content.window.visualViewport.width ];
  });
}

let initial_window_height, initial_visual_viewport_width, initial_visual_viewport_height;

// setup a meta viewport tag in the top document.
add_setup(async () => {
  // Try to close the software keyboard to invoke `documentElement.focus()`.
  document.documentElement.focus();
  await SimpleTest.promiseWaitForCondition(
    () => document.activeElement == document.documentElement,
    "Waiting for focus");

  await SpecialPowers.spawn(parent, [], async () => {
    const initial_scale = content.window.visualViewport.scale;

    const meta = content.document.createElement("meta");
    meta.setAttribute("id""interactive-widget");
    meta.setAttribute("name""viewport");
    meta.setAttribute("content""width=device-width, initial-scale=1, user-scalable=no");
    content.document.documentElement.appendChild(meta);

    const eventPromise =  new Promise(resolve => content.window.addEventListener("resize", resolve));
    // Flush the viewport change.
    content.document.documentElement.getBoundingClientRect();

    // If this top level content is rendered as `scale < 1.0`, it means there
    // was no meta viewport tag at all, so that adding the above meta viewport
    // tag will fire a resize event, thus we need to wait for the event here.
    // Otherwise, we will wait for the event in the first `resizes-content`
    // test and the test will fail.
    //
    // NOTE: We need this `scale < 1.0` check for --run-until-failure option.
    if (initial_scale < 1.0) {
      await eventPromise;
    }
  });

  SimpleTest.registerCleanupFunction(async () => {
    await SpecialPowers.spawn(parent, [], async () => {
      const meta = content.document.querySelector("#interactive-widget");
      meta.setAttribute("content""");
      // Flush the change above.
      content.document.documentElement.getBoundingClientRect();
      // A dummy Promise to make sure that SpecialPowers.spawn's Promise will
      // never be resolved until this script has run in the parent context.
      await new Promise(resolve => resolve());
    });
  });
  [ initial_window_height,
    initial_visual_viewport_height, initial_visual_viewport_width ] = await getViewportMetrics();
  ok(initial_visual_viewport_width < initial_visual_viewport_height,
     `the visual viewport height (${initial_visual_viewport_height}) is less ` +
     `than the visual viewport width (${initial_visual_viewport_width}), ` +
     `it hightly suspects the virtual keyboard persists there, thus ` +
     `we can't run this interactive-widget tests properly`);
});

async function setupInteractiveWidget(aValue) {
  await SpecialPowers.spawn(parent, [aValue], async (value) => {
    const meta = content.document.querySelector("#interactive-widget");
    meta.setAttribute("content", `width=device-width, initial-scale=1, user-scalable=no, interactive-widget=${value}`);

    // Flush the viewport change.
    content.document.documentElement.getBoundingClientRect();

    // A dummy Promise to make sure that SpecialPowers.spawn's Promise will
    // never be resolved until these script have run in the parent context.
    await new Promise(resolve => resolve());
  });
}

// SpecialPowers.spawn doesn't provide any reasonable way to make sure event
// listeners have been set in the given context (bug 1743857), so here we post
// a message just before setting up a resize event listener and return two
// Promises, one will be resolved when we received the message, the other will
// be resolved when we got a resize event.
function setupResizeEventListener(aInteractiveWidget) {
  const ready = new Promise(resolve => {
    window.addEventListener("message", msg => {
      if (msg.data == "interactive-widget:ready") {
        resolve(msg.data)
      }
    }, { once: true });
  });

  const resizePromise = SpecialPowers.spawn(parent, [aInteractiveWidget], async (interactiveWidget) => {
    // #testframe is the iframe id where our mochitest harness loads each test
    // document, but if this test runs solely just like ./mach test TEST_PATH,
    // the test document gets loaded in the top level content.
    const target = content.document.querySelector("#testframe") ?
      content.document.querySelector("#testframe").contentWindow : content.window;

    let eventPromise;
    if (interactiveWidget == "resizes-content") {
      eventPromise =  new Promise(resolve => content.window.addEventListener("resize", resolve));
    } else if (interactiveWidget == "resizes-visual") {
      eventPromise = new Promise(resolve => content.window.visualViewport.addEventListener("resize", resolve));
    } else {
      ok(false, `Unexpected interactive-widget=${interactiveWidget}`);
    }
    target.postMessage("interactive-widget:ready""*");
    await eventPromise;
  });

  return [ ready, resizePromise ];
}

// A utility function to hide the software keyboard.
// This function needs to be called while the software keyboard is shown on
// `resizes-content' or `resizes-visual` mode.
async function hideKeyboard() {
  const interactiveWidget = await SpecialPowers.spawn(parent, [], () => {
    const meta = content.document.querySelector("#interactive-widget");
    return meta.getAttribute("content").match(/interactive-widget=([\w-].+?)[,\s]*$/)[1];
  });

  let [ readyPromise, resizePromise ] = setupResizeEventListener(interactiveWidget);
  await readyPromise;

  // Tap outside the textarea to hide the software keyboard.
  await synthesizeNativeTap(document.querySelector("textarea"), 150, 50);
  await resizePromise;

  await SimpleTest.promiseWaitForCondition(
    async () => {
      let [ current_window_height, current_visual_viewport_height ] = await getViewportMetrics();
      return current_window_height == initial_window_height &&
             current_visual_viewport_height == initial_visual_viewport_height;
    },
    "Waiting for restoring the initial state");
}

// `resizes-content` test
add_task(async () => {
  await setupInteractiveWidget("resizes-content");

  // Setup a resize event listener in the top level document.
  let [ readyPromise, resizePromise ] = setupResizeEventListener("resizes-content");
  // Make sure the event listener has been set.
  await readyPromise;

  // Tap the textarea to show the software keyboard.
  await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);

  await resizePromise;

  // Now the software keyboard has appeared, before running the next test we
  // need to hide the keyboard.
  SimpleTest.registerCurrentTaskCleanupFunction(async () => await hideKeyboard());

  await promiseAfterPaint();

  await SimpleTest.promiseWaitForCondition(
    () => document.activeElement == document.querySelector("textarea"),
    "Waiting for focus");

  let [ window_height, visual_viewport_height ] = await getViewportMetrics();
  ok(window_height < initial_window_height,
     `The layout viewport got resized to ${window_height} from ${initial_window_height}`);
  ok(visual_viewport_height < initial_visual_viewport_height,
     `The visual viewport got resized to ${visual_viewport_height} from ${initial_visual_viewport_height}`);
});

// `resizes-visual` test
add_task(async () => {
  await setupInteractiveWidget("resizes-visual");

  // Setup a resize event listener in the top level document.
  let [ readyPromise, resizePromise ] = setupResizeEventListener("resizes-visual");
  // Make sure the event listener has been set.
  await readyPromise;

  // Tap the textarea to show the software keyboard.
  await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);

  await resizePromise;

  // Now the software keyboard has appeared, before running the next test we
  // need to hide the keyboard.
  SimpleTest.registerCurrentTaskCleanupFunction(async () => await hideKeyboard());

  await promiseAfterPaint();
  await SimpleTest.promiseWaitForCondition(
    () => document.activeElement == document.querySelector("textarea"),
    "Waiting for focus");

  let [ window_height, visual_viewport_height ] = await getViewportMetrics();
  is(window_height, initial_window_height,
     "The layout viewport is not resized on resizes-visual");
  ok(visual_viewport_height < initial_visual_viewport_height,
     `The visual viewport got resized to ${visual_viewport_height} from ${initial_visual_viewport_height}`);
});

// Append an element in the top level document that the element will be the
// underneath the software keyboard.
async function appendSpacer() {
  await SpecialPowers.spawn(parent, [], async () => {
    const div = content.document.createElement("div");
    div.setAttribute("id""interactive-widget-test-spacer");
    div.style = "height: 200vh; position: absolute; top: 90vh;";
    content.document.body.appendChild(div);

    // Flush the change.
    content.document.documentElement.getBoundingClientRect();

    // A dummy Promise to make sure that SpecialPowers.spawn's Promise will
    // never be resolved until these script have run in the parent context.
    await new Promise(resolve => resolve());
  });

  SimpleTest.registerCurrentTaskCleanupFunction(async () => {
    await SpecialPowers.spawn(parent, [], async () => {
      const div = content.document.querySelector("#interactive-widget-test-spacer");
      div.remove();
      // Flush the change.
      content.document.documentElement.getBoundingClientRect();

      // A dummy Promise to make sure that SpecialPowers.spawn's Promise will
      // never be resolved until these script have run in the parent context.
      await new Promise(resolve => resolve());
    });
  });
}

// `overlays-content` test
add_task(async () => {
  await setupInteractiveWidget("overlays-content");

  await appendSpacer();

  // Tap the textarea to show the software keyboard.
  await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);

  // Now the software keyboard has appeared, before running the next test we
  // need to hide the keyboard.
  SimpleTest.registerCurrentTaskCleanupFunction(async () => {
    // Switch back to `resizes-content` mode so that we can receive a resize
    // event when the keyboard gets hidden.
    await setupInteractiveWidget("resizes-content");
    await hideKeyboard();
  });

  await promiseAfterPaint();
  await SimpleTest.promiseWaitForCondition(
    () => document.activeElement == document.querySelector("textarea"),
    "Waiting for focus");

  let [ window_height, visual_viewport_height ] = await getViewportMetrics();
  is(window_height, initial_window_height,
     "The layout viewport is not resized on overlays-content");
  is(visual_viewport_height, initial_visual_viewport_height,
     "The visual viewport is not resized on overlays-content");

  // Call a scrollIntoView() on an element underneath the keyboard and see if
  // the current scroll position changes.
  const scrollPosition = await SpecialPowers.spawn(parent, [], () => {
    return content.window.scrollY;
  });
  await SpecialPowers.spawn(parent, [], async () => {
    const div = content.document.querySelector("#interactive-widget-test-spacer");
    div.scrollIntoView({ behavior: "instant" });

    // Though two rAFs ensure there's at least one scroll event if there is,
    // we use two additional rAFs just in case.
    await new Promise(resolve => content.window.requestAnimationFrame(resolve));
    await new Promise(resolve => content.window.requestAnimationFrame(resolve));
    await new Promise(resolve => content.window.requestAnimationFrame(resolve));
    await new Promise(resolve => content.window.requestAnimationFrame(resolve));
  });

  const newScrollPosition = await SpecialPowers.spawn(parent, [], () => {
    return content.window.scrollY;
  });
  is(scrollPosition, newScrollPosition, "The scrollIntoView() call has no effect");
});
</script>
</body>
</html>

Messung V0.5
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.24 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.