summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/cssom-view/support/scroll-behavior.js
blob: 0a0968e025bd8604c0765352d3a2e8b3cc1233aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
function observeScrolling(elements, callback) {
  if (!Array.isArray(elements))
      elements = [elements];
  var lastChangedFrame = 0;
  var lastLeft = new Map();
  var lastTop = new Map();
  elements.forEach((element) => {
    lastLeft.set(element, element.scrollLeft);
    lastTop.set(element, element.scrollTop);
  });
  function tick(frames) {
    // We requestAnimationFrame either for 500 frames or until 20 frames with
    // no change have been observed.
    if (frames >= 500 || frames - lastChangedFrame > 20) {
      callback(true);
    } else {
      var scrollHappened = elements.some((element) => {
        return element.scrollLeft != lastLeft.get(element) || element.scrollTop != lastTop.get(element);
      });
      if (scrollHappened) {
        lastChangedFrame = frames;
        elements.forEach((element) => {
          lastLeft.set(element, element.scrollLeft);
          lastTop.set(element, element.scrollTop);
        });
        callback(false);
      }
      requestAnimationFrame(tick.bind(null, frames + 1));
    }
  }
  tick(0);
}

function waitForScrollEnd(elements) {
  return new Promise((resolve) => {
    observeScrolling(elements, (done) => {
      if (done)
        resolve();
    });
  });
}

function resetScroll(scrollingElement) {
  // Try various methods to ensure the element position is reset immediately.
  scrollingElement.scrollLeft = 0;
  scrollingElement.scrollTop = 0;
  scrollingElement.scroll({left: 0, top: 0, behavior: "instant"});
}

function resetScrollForWindow(scrollingWindow) {
  // Try various methods to ensure the element position is reset immediately.
  scrollingWindow.document.scrollingElement.scrollLeft = 0;
  scrollingWindow.document.scrollingElement.scrollTop = 0;
  scrollingWindow.scroll({left: 0, top: 0, behavior: "instant"});
}

function setScrollBehavior(styledElement, className) {
  styledElement.classList.remove("autoBehavior", "smoothBehavior");
  styledElement.classList.add(className);
}

function scrollNode(scrollingElement, scrollFunction, behavior, elementToRevealLeft, elementToRevealTop) {
  var args = {};
  if (behavior)
    args.behavior = behavior;
  switch (scrollFunction) {
    case "scrollIntoView":
      args.inline = "start";
      args.block = "start";
      elementToReveal.scrollIntoView(args);
      break;
    default:
      args.left = elementToRevealLeft;
      args.top = elementToRevealTop;
      scrollingElement[scrollFunction](args);
      break;
  }
}

function scrollWindow(scrollingWindow, scrollFunction, behavior, elementToRevealLeft, elementToRevealTop) {
  var args = {};
  if (behavior)
    args.behavior = behavior;
  args.left = elementToRevealLeft;
  args.top = elementToRevealTop;
  scrollingWindow[scrollFunction](args);
}