chromium/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/snap-area-capturing-add-scroll-container.html

<!DOCTYPE html>
<title>
  Adding a scrollable element should make it start capturing snap points.
</title>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions"/>
<meta name="viewport" content="user-scalable=no">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
div {
  position: absolute;
  margin: 0px;
}

html {
  scroll-snap-type: y mandatory;
}

body {
  margin: 0px;
}

#middle-scroller {
  top: 100px;
  height: 500px;
  width: 500px;
  overflow: visible;
  background-color: rgb(12, 61, 2);
  scroll-snap-type: none;
}

#inner-scroller {
  top: 200px;
  height: 400px;
  width: 400px;
  overflow: visible;
  background-color: rgb(65, 139, 50);
  scroll-snap-type: y mandatory;
}

.space {
  width: 2000px;
  height: 2000px;
}

#inner-snap-area {
  top: 300px;
  width: 200px;
  height: 200px;
  background-color: blue;
  scroll-snap-align: start;
}

#document-snap-area {
  top: 500px;
  width: 200px;
  height: 200px;
  background-color: lightblue;
  scroll-snap-align: start;
}

#inserted-snap-container {
  top: 400px;
  height: 600px;
  width: 400px;
  overflow: scroll;
  scroll-snap-type: y mandatory;
}
</style>

<div class="space"></div>
  <div id="middle-scroller">
    <div class="space"></div>
    <div id="inner-scroller">
        <div class="space"></div>
        <div id="inner-snap-area"></div>
    </div>
  </div>
</div>
<div id="document-snap-area"></div>
<script>

const inner_scroller = document.getElementById("inner-scroller");
const middle_scroller = document.getElementById("middle-scroller");
const document_scroller = document.scrollingElement;

// This tests that making an element scrollable will reassign the correct snap
// areas to itself, per spec [1].
// [1] https://drafts.csswg.org/css-scroll-snap/#captures-snap-positions
test(() => {
  // Confirm that the document-level scroller is the snap container for all of
  // the snap areas.
  document_scroller.scrollTo(0, 10);
  assert_equals(document_scroller.scrollTop, 500);
  // Snaps to the inner snap area.
  document_scroller.scrollBy(0, 75);
  assert_equals(document_scroller.scrollTop, 600);

  // The middle scroller should now have the inner snap area assigned to it.
  // Per spec, even if the snap-type is 'none', it should still capture snap
  // points.
  middle_scroller.style.setProperty("overflow", "scroll");

  // The middle scroller has snap-type 'none' so it should not snap.
  middle_scroller.scrollBy(0, 10);
  assert_equals(middle_scroller.scrollTop, 10);

  // The document scroller should only snap to the document-level snap area.
  document_scroller.scrollTo(0, 600);
  assert_equals(document_scroller.scrollTop, 500);

  // The inner scroller should now have the innermost snap area assigned to it.
  inner_scroller.style.setProperty("overflow", "scroll");
  inner_scroller.scrollBy(0, 10);
  assert_equals(inner_scroller.scrollTop, 300);

  document_scroller.scrollTo(0, 600);
  assert_equals(document_scroller.scrollTop, 500);

}, "Making an element scrollable should make it capture the correct descendant\
 snap areas' snap points.");

 // Test that attaching a new snap container also properly assigns snap areas.
 test(() => {
  // All containers should capture snap areas.
  middle_scroller.style.setProperty("overflow", "scroll");
  inner_scroller.style.setProperty("overflow", "scroll");

  // Sanity check that the scrollers still snap to the snap areas.
  document_scroller.scrollTo(0, 10);
  inner_scroller.scrollTo(0,10);
  assert_equals(inner_scroller.scrollTop, 300);
  assert_equals(document_scroller.scrollTop, 500);

  // Create new snap container and append thedocument-level snap area as its
  // child.
  const inserted_scroller = document.createElement("div");
  inserted_scroller.id = "inserted-snap-container";
  const space = document.createElement("div");
  space.classList.add("space");
  inserted_scroller.appendChild(space);
  inserted_scroller.appendChild(document.getElementById("document-snap-area"));
  document_scroller.appendChild(inserted_scroller);

  // Document scroller no longer snaps.
  document_scroller.scrollTo(0, 400);
  assert_equals(document_scroller.scrollTop, 400);

  // Inserted scroller snaps.
  inserted_scroller.scrollTo(0, 10);
  assert_equals(inserted_scroller.scrollTop, 500);
 }, "Attaching a new element that is scrollable should assign the correct snap\
 areas to it.");
</script>