<!DOCTYPE html>
<title>Media Controls: text track menu keyboard navigation</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../media-controls.js"></script>
<body>
</body>
<script>

function testNavigation(root, elements, next, previous) {
  // Internal copy of the array. They are otherwise passed by reference.
  const list = elements.slice(0);

  assert_equals(root.activeElement, list[0]);

  list.forEach(element => {
    if (element == list[0])
      return;

    next();

    assert_equals(root.activeElement, element);
    assert_equals(
        window.getComputedStyle(element).getPropertyValue('background-color'),
        'rgb(224, 224, 224)');
  });

  // Next action after reaching the end is a no-op.
  next();
  assert_equals(root.activeElement, list.pop());
  // pop() will remove the last element which will allow the next iteration to
  // start from n-1.

  list.reverse().forEach(element => {
    previous();

    assert_equals(root.activeElement, element);
    assert_equals(
        window.getComputedStyle(element).getPropertyValue('background-color'),
        'rgb(224, 224, 224)');
  });

  // Previous element after reaching the beginning is a no-op.
  previous();
  assert_equals(root.activeElement, list[list.length - 1]);
}

async_test(t => {
  assert_true('internals' in window);
  assert_true('eventSender' in window);

  const video = document.createElement('video');
  video.controls = true;
  video.src = '../content/test.ogv';
  internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true);

  [ '../track/captions-webvtt/captions-fast.vtt',
    '../track/captions-webvtt/captions-rtl.vtt' ].forEach(source => {
    const track = document.createElement('track');
    track.src = source;
    track.kind = 'captions';
    video.appendChild(track);
  });

  assert_equals(video.textTracks.length, 2);

  document.body.appendChild(video);
  enableTestMode(video);

  video.addEventListener('loadedmetadata', t.step_func(() => {
    assert_true(isVisible(overflowButton(video)));

    openOverflowAndClickButton(video, captionsOverflowItem(video), t.step_func_done(() => {
      const menu = textTrackMenu(video);
      assert_true(isVisible(menu));
      assert_equals(internals.shadowRoot(video).activeElement,
                    menu.lastElementChild);

      const elements = [];
      for (let i = 0; i < menu.children.length; i++)
        elements.unshift(menu.children[i]);

      testNavigation(internals.shadowRoot(video), elements,
                     () => { eventSender.keyDown('ArrowUp'); },
                     () => { eventSender.keyDown('ArrowDown'); });

      testNavigation(internals.shadowRoot(video), elements,
                     () => { eventSender.keyDown('Tab', [ 'shiftKey' ]); },
                     () => { eventSender.keyDown('Tab'); });

      // Navigating with Shift + Arrow Keys should also work.
      testNavigation(internals.shadowRoot(video), elements,
                     () => { eventSender.keyDown('ArrowUp', [ 'shiftKey' ]); },
                     () => { eventSender.keyDown('ArrowDown', [ 'shiftKey' ]); });

      // Closing.
      eventSender.keyDown('Escape');
      assert_false(isVisible(menu));
      assert_equals(internals.shadowRoot(video).activeElement,
                    overflowButton(video));
    }));
  }), { once: true });
});
</script>
