<!DOCTYPE html>
<meta charset="utf-8">
<title>Last remembered size</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#last-remembered">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#content-visibility">
<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
<link rel="help" href="https://drafts.csswg.org/resize-observer-1/#html-event-loop">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7659">
<meta name="assert" content="Tests that the last remembered size is set immediately before invoking ResizeObserver callbacks." />

<style>
.target {
  width: max-content;
  height: max-content;
  border: 1px solid;
}
.target::before {
  content: "";
  display: block;
  width: 100px;
  height: 50px;
}
.cis-auto .target {
  contain-intrinsic-size: auto 40px auto 20px;
}
.skip-contents {
  content-visibility: hidden;
}
</style>

<div id="log"></div>

<div class="target" id="target1"></div>
<div class="target" id="target2"></div>
<div class="target" id="target3"></div>

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function checkSize(target, expectedWidth, expectedHeight, msg) {
  assert_equals(target.clientWidth, expectedWidth, msg + " - clientWidth");
  assert_equals(target.clientHeight, expectedHeight, msg + " - clientHeight");
}

let step = 0;

// Animation frame callbacks are invoked before ResizeObserver callbacks,
// so the last remembered size shouldn't have been set yet.
const test1 = async_test("requestAnimationFrame");
const target1 = document.getElementById("target1");
function step1(entries, ro) {
  assert_equals(++step, 1, "Step 1");
  target1.classList.add("skip-contents");
  checkSize(target1, 40, 20, "No last remembered size");
}
requestAnimationFrame(test1.step_func_done(step1));

// The last remembered size should be set immediately before invoking
// ResizeObserver callbacks, even if the ResizeObserver is created before
// laying out an element that can record a last remembered size.
const test2 = async_test("Early ResizeObserver");
const target2 = document.getElementById("target2");
function step2(entries, ro) {
  assert_equals(++step, 2, "Step 2");
  ro.disconnect();
  target2.classList.add("skip-contents");
  checkSize(target2, 100, 50, "Using last remembered size");
}
new ResizeObserver(test2.step_func_done(step2)).observe(target2);

// Let elements record a last remembered size and force layout.
document.body.classList.add("cis-auto");
document.body.offsetLeft;

// The last remembered size should also have been set in the callback of
// a ResizeObserver creater after laying out an element that can record
// a last remembered size.
const test3 = async_test("Late ResizeObserver");
const target3 = document.getElementById("target3");
function step3(entries, ro) {
  assert_equals(++step, 3, "Step 3");
  ro.disconnect();
  target3.classList.add("skip-contents");
  checkSize(target3, 100, 50, "Using last remembered size");
}
new ResizeObserver(test3.step_func_done(step3)).observe(target3);
</script>
