<!DOCTYPE html>
<html>
  <head>
    <title>Shadow DOM and CSSOM View: Document.prototype.elementFromPoint</title>
    <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
    <meta name="assert" content="DocumentOrShadowRoot must have elementFromPoint and must return retarget the result against the context object.">
    <link rel="help" href="https://www.w3.org/TR/cssom-view-1/#dom-document-elementfrompoint">
    <link rel="help" href="https://www.w3.org/TR/shadow-dom/#extensions-to-the-documentorshadowroot-mixin">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
    <div id="container"></div>
    <style>
test-element { display: block; width: 100px; height: 100px; }
    </style>
    <script>

function pointInElement(node) {
  let x = 5;
  let y = 5;
  do {
    x += node.offsetLeft;
    y += node.offsetTop;
    node = node.offsetParent;
  } while (node);
  return [x, y];
}

const displayValues = ['inline', 'block', 'inline-block'];
var container = document.getElementById('container');
customElements.define('test-element', class extends HTMLElement {
  constructor() {
    super();
  }
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = 'hello';
    container.appendChild(host);
    assert_equals(document.elementFromPoint(...pointInElement(host)), host);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), host);
  }, 'document.elementFromPoint and shadow.ElementFromPoint must return the shadow host of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = 'text';
    container.appendChild(host);
    assert_equals(document.elementFromPoint(...pointInElement(host)), host);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), host);
  }, 'document.elementFromPoint and shadowRoot.elementFromPoint must return the shadow host when the hit-tested text node is assigned to a slot and the host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = '<span>text</span>';
    container.appendChild(host);
    assert_equals(document.elementFromPoint(...pointInElement(host)), host.querySelector('span'));
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), host.querySelector('span'));
  }, 'document.elementFromPoint and shadowRoot.elementFromPoint must return the element assigned to a slot when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<span>text</span>';
    container.appendChild(host);
    assert_equals(document.elementFromPoint(...pointInElement(host)), host);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), shadow.querySelector('span'));
  }, 'document.elementFromPoint must return the shadow host of the hit-tested element under a shadow root and shadowRoot.elementFromPoint must return the element parent of the hit-tested text node under the point when the shadow host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot>fallback</slot>';
    container.appendChild(host);
    assert_equals(document.elementFromPoint(...pointInElement(host)), host);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), shadow.querySelector('slot'));
  }, 'document.elementFromPoint must return the shadow host and shadowRoot.elementFromPoint must return the slot parent of the fallback text when the hit-tested text node is a fallback content and the host has display: ' + displayValue);
});



displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = '<inner-host>hello</inner-host>';
    container.appendChild(host);

    let innerHost = host.querySelector('inner-host');
    let innerShadow = innerHost.attachShadow({mode: 'closed'});
    innerShadow.innerHTML = '<slot></slot>';
    assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerHost);
  }, 'document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element assigned to a slot'
  + ' when the hit-tested text node is assigned to a slot in the shadow tree of the child element and the outer shadow host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = '<inner-host></inner-host>';
    container.appendChild(host);

    let innerHost = host.querySelector('inner-host');
    let innerShadow = innerHost.attachShadow({mode: 'closed'});
    innerShadow.innerHTML = 'hello';
    assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerHost);
  }, 'document.elementFromPoint, shadowRoot.elementFromPoint, innerShadow.elementFromPoint must return a child element with its own shadow tree assigned to a slot'
  + ' when the hit-tested text node is its direct child and the outer shadow host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = '<inner-host></inner-host>';
    container.appendChild(host);

    let innerHost = host.querySelector('inner-host');
    let innerShadow = innerHost.attachShadow({mode: 'closed'});
    innerShadow.innerHTML = '<span>hello</span>';

    assert_equals(document.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(shadow.elementFromPoint(...pointInElement(host)), innerHost);
    assert_equals(innerShadow.elementFromPoint(...pointInElement(host)), innerShadow.querySelector('span'));
  }, 'document.elementFromPoint, shadowRoot.elementFromPoint must return a child element with its own shadow tree assigned to a slot'
  + ' when the hit-tested text node is a child of another element and innerShadow.elementFromPoint must return the parent element of the hit-tested text node under it when the outer shadow host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = 'hello';
    container.appendChild(host);
    assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
    assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
  }, 'document.elementsFromPoint and shadow.elementsFromPoint must return the shadow host and its ancestors of the hit-tested text node when the hit-tested text node is a direct child of the root and the host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<slot></slot>';
    host.innerHTML = 'text';
    container.appendChild(host);
    assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
    assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
  },'document.elementsFromPoint and shadowRoot.elementsFromPoint must return the shadow host and its ancestors when the hit-tested text node is assigned to a slot and the host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<div><slot></slot></div>';
    host.innerHTML = '<span>text</span>';
    container.appendChild(host);
    assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host.querySelector('span'), host, container, document.body, document.documentElement]);
    assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [host.querySelector('span'), shadow.querySelector('div'),  host, container, document.body, document.documentElement]);
  }, 'document.elementsFromPoint and shadowRoot.elementsFromPoint must return the element assigned to a slot and its non-shadow ancestors when hit-tested text node under an element is assigned to a slot in the shadow tree and the shadow host of the slot has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<span>text</span>';
    container.appendChild(host);
    assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
    assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [shadow.querySelector('span'), host, container, document.body, document.documentElement]);
  }, 'document.elementsFromPoint must return the shadow host and its ancestors of the hit-tested element under a shadow root and'
  + 'shadowRoot.elementsFromPoint must return the element parent and its non-shadow ancestors of the hit-tested text node under the point when the shadow host has display: ' + displayValue);
});

displayValues.forEach(function (displayValue) {
  test(function () {
    container.innerHTML = '';
    let host = document.createElement('test-element');
    host.style.display = displayValue;
    let shadow = host.attachShadow({mode: 'closed'});
    shadow.innerHTML = '<div><slot>fallback</slot></div>';
    container.appendChild(host);
    assert_array_equals(document.elementsFromPoint(...pointInElement(host)), [host, container, document.body, document.documentElement]);
    assert_array_equals(shadow.elementsFromPoint(...pointInElement(host)), [shadow.querySelector('slot'), shadow.querySelector('div'), host, container, document.body, document.documentElement]);
  }, 'document.elementsFromPoint must return the shadow host and its ancestors and shadowRoot.elementsFromPoint must return the slot parent of the fallback text and its non-shadow ancestors when the hit-tested text node is a fallback content and the host has display: ' + displayValue);
});

test(function () {
  container.innerHTML = '';
  let host = document.createElement('test-element');
  host.style.display = 'block';
  let shadow = host.attachShadow({mode: 'closed'});
  shadow.innerHTML = '<div style="margin: 2px;">not hit</div>';
  let aboveHost = document.createElement("div");
  aboveHost.appendChild(host);
  container.appendChild(aboveHost);
  document.documentElement.style = 'background-attachment: scroll; height: 2px;';
  let boundingRect = host.getBoundingClientRect();
  assert_array_equals(document.elementsFromPoint(boundingRect.x, boundingRect.y), [host, aboveHost, container, document.body, document.documentElement]);
  assert_array_equals(shadow.elementsFromPoint(boundingRect.x, boundingRect.y), [host, aboveHost, container, document.body, document.documentElement]);
}, 'shadowRoot.elementsFromPoint must behave the same with document.elementsFromPoint regarding HTML element');

container.innerHTML = '';

test(function(t) {
  const container = document.createElement("div");
  const span = document.createElement("span");
  span.innerText = "foo";
  document.body.appendChild(container);
  container.appendChild(span);

  let elements = document.elementsFromPoint(...pointInElement(span));
  assert_equals(elements.length, 4);
  assert_equals(elements[0], span);
  assert_equals(elements[1], container);
  assert_equals(elements[2].nodeName, 'BODY');
  assert_equals(elements[3].nodeName, 'HTML');

  const host = document.createElement("div");
  const shadowRoot = host.attachShadow({ mode: "open" });
  elements = shadowRoot.elementsFromPoint(...pointInElement(span));
  assert_equals(elements.length, 4);
  assert_equals(elements[0], span);
  assert_equals(elements[1], container);
  assert_equals(elements[2].nodeName, 'BODY');
  assert_equals(elements[3].nodeName, 'HTML');
}, "elementsFromPoint should return all elements under a point, even when context object is not connected");
</script>
</body>
</html>

