| <!DOCTYPE html> | 
 | <style> | 
 |   ::-webkit-scrollbar { | 
 |     width: 0px; | 
 |     height: 0px; | 
 |   } | 
 |  | 
 |   body, html { | 
 |     width: 100%; | 
 |     height: 100%; | 
 |   } | 
 |  | 
 |   body { | 
 |     margin: 0px; | 
 |   } | 
 |  | 
 |   #container { | 
 |     width: 100%; | 
 |     height: 100%; | 
 |     overflow: auto; | 
 |   } | 
 |  | 
 |   #parent { | 
 |     width: 100%; | 
 |     height: 100%; | 
 |     overflow: auto; | 
 |   } | 
 |  | 
 |   .spacer { | 
 |     width: 2000px; | 
 |     height: 2000px; | 
 |   } | 
 |  | 
 |   #rootspacer { | 
 |     width: 1000px; | 
 |     height: 1000px; | 
 |     position: absolute; | 
 |     top: 0px; | 
 |     left: 0px; | 
 |     z-index: -1; | 
 |   } | 
 | </style> | 
 |  | 
 | <div id="parent"> | 
 |   <div id="container"> | 
 |     <div class="spacer"> | 
 |       <span id="spanner">TEST</span> | 
 |     </div> | 
 |   </div> | 
 |   <div class="spacer"></div> | 
 | </div> | 
 | <div id="rootspacer"></div> | 
 |  | 
 | <script src="../resources/testharness.js"></script> | 
 | <script src="../resources/testharnessreport.js"></script> | 
 |  | 
 | <script> | 
 |   var parentScroller = document.querySelector('#parent'); | 
 |   var container = document.querySelector('#container'); | 
 |   var spanner = document.querySelector('#spanner'); | 
 |  | 
 |   test(function() { | 
 |       assert_false(typeof document.rootScroller === 'undefined'); | 
 |   }, 'setRootScroller API enabled'); | 
 |  | 
 |   test(function() { | 
 |       // Setting the container object should succeed. | 
 |       assert_equals(document.rootScroller, null); | 
 |       document.rootScroller = container; | 
 |       assert_equals(document.rootScroller, container); | 
 |       document.rootScroller = null; | 
 |       assert_equals(document.rootScroller, null); | 
 |   }, 'Setter and getter on a valid element works'); | 
 |  | 
 |   test(function() { | 
 |       // Trying to set the <span> should succeed even though it's not a valid | 
 |       // scroller. | 
 |       document.rootScroller = spanner; | 
 |       assert_equals(document.rootScroller, spanner); | 
 |   }, 'Can set a non-scrolling element as the rootScroller'); | 
 |  | 
 |   test(function() { | 
 |       // Scroll the container <div> past the end. The scrolls should not chain | 
 |       // past the rootScroller to the parentScroller element. | 
 |       document.rootScroller = container; | 
 |       if (typeof eventSender !== 'undefined') { | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |  | 
 |           assert_equals(container.scrollTop, 2000 - 600); | 
 |           assert_equals(container.scrollLeft, 2000 - 800); | 
 |  | 
 |           // The container is now fully scrolled. Normally, further scroll | 
 |           // events would chain up to the parent element but, because the | 
 |           // container is the root scroller, we shouldn't chain up past it. | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |  | 
 |           assert_equals(container.scrollTop, 2000 - 600); | 
 |           assert_equals(container.scrollLeft, 2000 - 800); | 
 |           assert_equals(parentScroller.scrollTop, 0); | 
 |           assert_equals(parentScroller.scrollLeft, 0); | 
 |       } | 
 |   }, "Scrolls don't chain past root scroller element"); | 
 |  | 
 |   test(function() { | 
 |       document.rootScroller = container; | 
 |       container.scrollTop = 999; | 
 |       container.scrollLeft = 998; | 
 |  | 
 |       // Window.scrollX and scrollY should reflect the scroll offset of the | 
 |       // rootScroller | 
 |       assert_equals(container.scrollTop, 999); | 
 |       assert_equals(container.scrollLeft, 998); | 
 |       // TODO(bokan): These need to be fixed since landing inert-visual-viewport. crbug.com/505516 | 
 |       // assert_equals(window.scrollY, container.scrollTop, "ScrollY"); | 
 |       // assert_equals(window.scrollX, container.scrollLeft, "ScrollX"); | 
 |       // assert_equals(document.scrollingElement.scrollTop, container.scrollTop, "scrollingElement.scrollTop"); | 
 |       // assert_equals(document.scrollingElement.scrollLeft, container.scrollLeft, "scrollingElement.scrollLeft"); | 
 |  | 
 |   }, "document.scrollingElement and window scroll API reflect rootScroller offsets"); | 
 |  | 
 |   test(function() { | 
 |       // Making the current rootScroller an invalid scroller (by making it not | 
 |       // fill the viewport) should fallback to the default element, the | 
 |       // documentElement, but the rootScroller property should remain the same. | 
 |       document.rootScroller = container; | 
 |       container.style.width = "95%"; | 
 |       assert_equals(document.rootScroller, container); | 
 |  | 
 |       // Reset parentScroller's offsets, make container fully scrolled. | 
 |       parentScroller.scrollTop = 0; | 
 |       parentScroller.scrollLeft = 0; | 
 |       container.scrollTop = 10000; | 
 |       container.scrollLeft = 10000; | 
 |  | 
 |       // Now scrolling over the container should scroll the scrollingElement | 
 |       // since the rootElement is invalid (doesn't fill the viewport). | 
 |       if (typeof eventSender !== 'undefined') { | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |           eventSender.gestureScrollBegin(500, 500); | 
 |           eventSender.gestureScrollUpdate(-300, -300); | 
 |           eventSender.gestureScrollEnd(0, 0); | 
 |  | 
 |           assert_equals(parentScroller.scrollTop, 900); | 
 |           assert_equals(parentScroller.scrollLeft, 900); | 
 |       } | 
 |     }, "Setting an invalid rootScroller should reset to using the documentElement."); | 
 | </script> |