<!doctype html>
<html>
  <head>
    <title>Lostpointercapture fires on document when target in shadow dom  is removed</title>
    <meta name="viewport" content="width=device-width">
    <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=810882">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/resources/testdriver.js"></script>
    <script src="/resources/testdriver-actions.js"></script>
    <script src="/resources/testdriver-vendor.js"></script>
  </head>
  <body onload="onLoad()">
    <template id="template">
      <style>
          #content{
              height:100px;
              width:100px;
              background-color: lightgrey;
          }
      </style>
      <div id="content"></div>
    </template>
    <h1>Pointer Events - lostpointercapture when capturing element in shadow dom is removed</h1>
    <h4>
        Test Description:
        This test checks if lostpointercapture is fired at the document when the capturing node that is in shadow dom is removed from the shadow dom.
        Complete the following actions:
        <ol>
            <li>Press left mouse button over "Set Capture" button. Pointer should be captured by the gray rectangle which is in shadow dom.</li>
            <li>Gray rectangle will be removed from shadow dom.</li>
            <li>"lostpointercapture" should be received on the document not on the gray rectangle.</li>
        </ol>
    </h4>
    <div id="shadowhost"></div>
    <br>
    <input type="button" id="btnCapture" value="Set Capture">
    <div id="log"></div>
    <script>
      async function onLoad(){
        var logDiv = document.getElementById("log");
        function logMessage(message){
          var log = document.createElement("div");
          var messageNode = document.createTextNode(message);
          log.appendChild(messageNode);
          logDiv.appendChild(log);
        }
        var events = [];

        var host = document.getElementById("shadowhost");
        var shadowRoot = host.attachShadow({mode: "open"});
        var template = document.getElementById("template");
        var node = template.content.cloneNode(true);
        shadowRoot.appendChild(node);

        var content = host.shadowRoot.getElementById("content");
        var captureButton = document.getElementById("btnCapture");

        captureButton.addEventListener("pointerdown", function(event){
          logMessage("Pointer will be captured by the shadow dom gray rectangle.");
          content.setPointerCapture(event.pointerId);
          events.push("pointerdown@captureButton");
        });
        content.addEventListener("gotpointercapture", function(event){
          logMessage("Gray rectangle received pointercapture.");
          logMessage("Removing gray rectangle from shadow dom.")
          content.parentNode.removeChild(content);
          events.push("gotpointercapture@content");
        });
        content.addEventListener("lostpointercapture", function(event){
          logMessage("Test Failed! The element removed from shadow dom should not receive lostpointercapture.")
          events.push("lostpointercapture@content");
          if(window.promise_test && shadow_dom_test){
            shadow_dom_test.step(function(){
              assert_unreached("lostpointercapture must be fired on the document, not the capturing element");
              reject_test("lostpointercapture must not be dispatched on the disconnected node");
              shadow_dom_test.done();
            });
          }
        });
        document.addEventListener("lostpointercapture", function(event){
          logMessage("Test Passed! Document received lostpointercapture.");
          events.push("lostpointercapture@document");
          if(window.promise_test && shadow_dom_test){
            shadow_dom_test.step(function(){
              assert_array_equals(events, ["pointerdown@captureButton",
                "gotpointercapture@content",
                "lostpointercapture@document"]);
              resolve_test();
            });
          }
        });

        var shadow_dom_test = null;
        var resolve_test = null;
        var reject_test = null;

        function cleanup(){
          events = [];
          shadow_dom_test = null;
          resolve_test = null;
          reject_test = null;
        }
        if(window.promise_test){
          promise_test(async function(t){
            var actions_promise;
            return new Promise(async function(resolve, reject){
              shadow_dom_test = t;
              resolve_test = resolve;
              reject_test = reject;
              t.add_cleanup(function(){
                cleanup();
              });
              var actions = new test_driver.Actions();
              actions_promise = actions
                  .pointerMove(0, 0, {origin:captureButton})
                  .pointerDown({button: actions.ButtonType.LEFT})
                  .pointerUp({button: actions.ButtonType.LEFT})
                  .send();
            }).finally(async () => {
              await actions_promise;
              t.done();
            });
          }, "lostpointercapture is dispatched on the document when shadow dom capturing element is removed");
        }
      }
    </script>
  </body>
</html>
