<!DOCTYPE html>
<html>
<body>
<p>
Makes sure that document.activeElement returns a shadow host when a element in the correspoinding shadow tree is focused.
</p>
<pre id="console"></pre>
<script>
function describe(obj) {
    if (obj === document)
        return 'top';
    if (obj.defaultView && obj.defaultView.frameElement)
        return describe(obj.defaultView.frameElement);
    return describe(obj.ownerDocument) + '/' + obj.id;
}

function print(s) {
    document.getElementById('console').textContent += s + '\n';
}

function assertActiveElement(doc, expected) {
    if (doc.activeElement === expected)
        print('PASS: ' + describe(doc) + ' document.activeElement is ' + describe(doc.activeElement));
    else
        print('FAIL: ' + describe(doc) + ' document.activeElement is ' + describe(doc.activeElement) + ' but expected ' + describe(expected));
}

if (window.testRunner) {
    testRunner.dumpAsText();

  function shadowRoot(shadowHost) {
    return internals.ensureShadowRoot(shadowHost);
  }

  function appendChildToShadow(shadowHost, child) {
    return shadowRoot(shadowHost).appendChild(child)
  }

  function appendShadowHost(doc, parent) {
    var shadowHost = doc.createElement('p');
    shadowHost.tabIndex = 1;  // Makes sure that the shadow host is focusable.
    parent = parent || doc.body;
    return parent.appendChild(shadowHost);
  }

  // For readability, I noted a DOM tree which is under the test here.
  //
  // - document (doc0)
  //   - shadow0
  //     - input0
  //   - iframe1 (doc1)
  //     - shadow1
  //       - input1
  //   - shadow2
  //     - shadow2_1
  //       - input2
  //   - shadow3
  //     - iframe3 (doc3)
  //       - input3
  //   - iframe4 (doc4)
  //     - iframe4_1 (doc4_1)
  //       - input4
  var doc0 = document;
  var shadow0 = appendShadowHost(doc0);
  var input0 = appendChildToShadow(shadow0, doc0.createElement('input'));

  var iframe1 = doc0.body.appendChild(doc0.createElement('iframe'));
  var doc1 = iframe1.contentDocument;
  var shadow1 = appendShadowHost(doc1);
  var input1 = appendChildToShadow(shadow1, doc1.createElement('input'));

  var shadow2 = appendShadowHost(doc0);
  var shadow2_1 = appendShadowHost(doc0, shadowRoot(shadow2));
  var input2 = appendChildToShadow(shadow2_1, doc0.createElement('input'));

  var shadow3 = appendShadowHost(doc0);
  var iframe3 = appendChildToShadow(shadow3, doc0.createElement('iframe'))
  var doc3 = iframe3.contentDocument;
  var input3 = doc3.body.appendChild(doc3.createElement('input'))

  // Althought this subtree (iframe4) doesn't contain any explicit shadow hosts,
  // this might be useful as a reference.
  var iframe4 = doc0.body.appendChild(doc0.createElement('iframe'));
  var doc4 = iframe4.contentDocument;
  var iframe4_1 = doc4.body.appendChild(doc4.createElement('iframe'));
  var doc4_1 = iframe4_1.contentDocument;
  var input4 = doc4_1.body.appendChild(doc4_1.createElement('input'));

  // Set up IDs for logging.
  var elements = ['shadow0','shadow1', 'shadow2', 'shadow2_1', 'shadow3',
                  'input0', 'input1', 'input2', 'input3', 'input4',
                  'iframe1', 'iframe3', 'iframe4', 'iframe4_1'];
  for (var i = 0; i < elements.length; i++) {
    var id = elements[i];
    window[id].id = id;
  }
  var docs = ['doc0', 'doc1', 'doc3', 'doc4', 'doc4_1'];
  for (var i = 0; i < docs.length; i++) {
    var id = docs[i];
    window[id].body.id = id + '_body';
  }

  print('\nFocusing ' + describe(input0));
  input0.focus();
  assertActiveElement(doc0, shadow0);
  assertActiveElement(doc1, doc1.body);
  assertActiveElement(doc3, doc3.body);
  assertActiveElement(doc4, doc4.body);
  assertActiveElement(doc4_1, doc4_1.body);

  print('\nFocusing ' + describe(input1));
  input1.focus();
  assertActiveElement(doc0, iframe1);
  assertActiveElement(doc1, shadow1);
  assertActiveElement(doc3, doc3.body);
  assertActiveElement(doc4, doc4.body);
  assertActiveElement(doc4_1, doc4_1.body);

  print('\nFocusing ' + describe(input2));
  input2.focus();
  assertActiveElement(doc0, shadow2);
  assertActiveElement(doc1, doc1.body);
  assertActiveElement(doc3, doc3.body);
  assertActiveElement(doc4, doc4.body);
  assertActiveElement(doc4_1, doc4_1.body);

  print('\nFocusing ' + describe(input3));
  input3.focus();
  assertActiveElement(doc0, shadow3);
  assertActiveElement(doc1, doc1.body);
  assertActiveElement(doc3, input3);
  assertActiveElement(doc4, doc4.body);
  assertActiveElement(doc4_1, doc4_1.body);

  print('\nFocusing ' + describe(input4));
  input4.focus();
  assertActiveElement(doc0, iframe4);
  assertActiveElement(doc1, doc1.body);
  assertActiveElement(doc3, doc3.body);
  assertActiveElement(doc4, iframe4_1);
  assertActiveElement(doc4_1, input4);
}
</script>
</body>
</html>
