<title>Select element scrolling when in transformed container</title>
<script>

let elements;
function test()
{
    if (window.testRunner) {
      testRunner.dumpAsText();
      testRunner.waitUntilDone();
    }
  
    var triggers = document.querySelectorAll(".scrollTrigger");
    for (var i=0; i < triggers.length; i++) {
      triggers[i].scrollIntoView();
    }
    document.getElementById("c-inner").scrollIntoView(true);
    document.getElementById("d-inner").scrollIntoView(false);
    
    elements = Array.from(document.querySelectorAll("select"));
    focusNext();
}

function focusNext()
{
    const firstElement = elements.shift();
    if (firstElement) {
        firstElement.focus();
        setTimeout(focusNext, 0);
    } else
        setTimeout(checkResults, 0);
    
}

function checkResults()
{
    var resultString = "";
    var id1, id2, element1, element2, scrollTop1, scrollTop2;
    
    // The test results should be (for scrollTop)
    // a != b
    // b == 0
    // c == d

    id1 = "a";
    id2 = "b";
    id3 = "c";
    id4 = "d";
    element1 = document.getElementById(id1);
    element2 = document.getElementById(id2);
    element3 = document.getElementById(id3);
    element4 = document.getElementById(id4);
    scrollTop1 = element1.scrollTop;
    scrollTop2 = element2.scrollTop;
    scrollTop3 = element3.scrollTop;
    scrollTop4 = element4.scrollTop;
    if (scrollTop1 != scrollTop2) {
      resultString += "PASS - Element " + id1 + " and Element " + id2 + " had different scrollTop<br>";
    } else {
      resultString += "FAIL - Element " + id1 + " and Element " + id2 + " had identical scrollTop<br>";
    }

    if (scrollTop2 == 0) {
      resultString += "PASS - Element " + id2 + " had scrollTop: 0<br>";
    } else {
      resultString += "FAIL - Element " + id2 + " had a non-zero scrollTop: " + scrollTop2 + "<br>";
    }

    if (scrollTop3 == scrollTop4) {
      resultString += "PASS - Element " + id3 + " and Element " + id4 + " had same scrollTop<br>";
    } else {
      resultString += "FAIL - Element " + id3 + " and Element " + id4 + " had different scrollTop<br>";
    }

    var results = document.getElementById("results");
    results.innerHTML = resultString;
    
    if (window.testRunner) {
      testRunner.notifyDone();
    }
}
</script>
<style type="text/css" media="screen">
  body {
     margin: 0;
   }

   .container {
     display: inline-block;
     position: relative;
     left: 0;
     top: 0;
     width: 200px;
     height: 350px;
     overflow: hidden;
     background-color: blue;
   }
   
   .scrolled {
     position: relative;
     left: 0;
     top: 0;
     font-size: 14px;
     background-color: red;
     color: white;
   }

   .padding {
     height: 500px;
   }

   .offset {
     -webkit-transform: translateY(-300px);
   }

   .scaled {
     color: white;
     background-color: red;
     height: 20px;
     -webkit-transform: scaleY(2.0);
   }
</style>
<body onload="test()">
<p id="message">
  Testing the scrolling behaviour of elements when in a normal and transformed container.
  On the left is the normal container. On the right are containers containing transformed elements.
  To test this manually, click on the two select elements. The menu popup should
  appear directly over the element - the content should not move.<br>
  The third and fourth containers tests that scrollIntoView(false) works properly in the presence of a scaled element.  Because the element is at the bottom of the container, scrollIntoView should give the same result regardless of flag.
</p>

<div class="container" id="a">
  <div class="scrolled">
    <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <select>
      <option>one</option>
      <option>two</option>
      <option>three</option>
      <option>four</option>
    </select>
  </div>
</div>

<div class="container" id="b">
  <div class="scrolled offset">
    <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <select>
      <option>one</option>
      <option>two</option>
      <option>three</option>
      <option>four</option>
    </select>
  </div>
</div>

<div class="container" id="c">
  <div class="padding"></div>
  <div class="scaled" id="c-inner">
    <p>This text should not be cut off</p>
  </div>
</div>

<div class="container" id="d">
  <div class="padding"></div>
  <div class="scaled" id="d-inner">
    <p>This text should not be cut off</p>
  </div>
</div>

<br>

<div id="results">
</div>


</body>
