| <!DOCTYPE html> |
| <script src='../resources/testharness.js'></script> |
| <script src='../resources/testharnessreport.js'></script> |
| <script src='resources/shadow-dom.js'></script> |
| <script src='resources/focus-utils.js'></script> |
| <input id='defaultFocus'> |
| <div id='sandbox'></div> |
| <script> |
| 'use strict'; |
| |
| function prepareDOMTree(parent, delegatesFocus) |
| { |
| parent.innerHTML = ''; |
| let host = document.createElement('div'); |
| host.id = 'shadowHost'; |
| host.setAttribute('tabindex', '0'); |
| var root = host.attachShadow({mode: 'open', delegatesFocus: delegatesFocus}); |
| root.innerHTML = '<div id="innerDiv">Blink</div><input id="inputA"><input id="inputB">'; |
| parent.appendChild(host); |
| } |
| |
| var host; |
| var innerDiv; |
| var inputA; |
| var inputB; |
| |
| function clickOn(el) { |
| eventSender.mouseMoveTo(el.offsetLeft + 8, el.offsetTop + 8); |
| eventSender.mouseDown(); |
| eventSender.mouseUp(); |
| } |
| |
| function resetFocus() { |
| document.querySelector('#defaultFocus').focus(); |
| } |
| |
| function assert_innermost_active_element(path) { |
| assert_true(isInnermostActiveElement(path), 'innermost active element should be ' + path); |
| } |
| |
| test(() => { |
| prepareDOMTree(sandbox, false); |
| resetFocus(); |
| |
| let host = getNodeInComposedTree('shadowHost'); |
| let innerDiv = getNodeInComposedTree('shadowHost/innerDiv'); |
| let inputA = getNodeInComposedTree('shadowHost/inputA'); |
| let inputB = getNodeInComposedTree('shadowHost/inputB'); |
| |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost'); |
| |
| inputA.focus(); |
| assert_innermost_active_element('shadowHost/inputA'); |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost'); |
| |
| inputB.focus(); |
| assert_innermost_active_element('shadowHost/inputB'); |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost'); |
| }, 'click on inner div should focus shadow host (with delegatesFocus = false).'); |
| |
| test(() => { |
| prepareDOMTree(sandbox, true); |
| resetFocus(); |
| |
| let host = getNodeInComposedTree('shadowHost'); |
| let innerDiv = getNodeInComposedTree('shadowHost/innerDiv'); |
| let inputA = getNodeInComposedTree('shadowHost/inputA'); |
| let inputB = getNodeInComposedTree('shadowHost/inputB'); |
| |
| inputA.value = 'wonderful'; // len = 9 |
| inputB.value = 'beautiful'; |
| |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost/inputA'); |
| |
| // If focus slides from shadow host, all the content will be selected. |
| assert_equals(inputA.selectionStart, 0); |
| assert_equals(inputA.selectionEnd, 9); |
| |
| // Clicking on non-focusable area inside shadow should not change the focus state. |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost/inputA'); |
| assert_equals(inputA.selectionStart, 0); |
| assert_equals(inputA.selectionEnd, 9); |
| |
| // Clicking on focusable directly will cause the element to be focused. |
| clickOn(inputA); |
| assert_innermost_active_element('shadowHost/inputA'); |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost/inputA'); |
| assert_equals(inputA.selectionStart, 1); |
| assert_equals(inputA.selectionEnd, 1); |
| |
| clickOn(inputB); |
| assert_innermost_active_element('shadowHost/inputB'); |
| clickOn(innerDiv); |
| assert_innermost_active_element('shadowHost/inputB'); |
| assert_equals(inputB.selectionStart, 1); |
| assert_equals(inputB.selectionEnd, 1); |
| }, 'click on inner div should focus inner focusable (with delegatesFocus = true).'); |
| </script> |