Bug 1544826 - Fix tab navigation when document element is a shadow host. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D27736

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-04-16 17:50:55 +00:00
Родитель ff87bca9a9
Коммит 287baaf1eb
3 изменённых файлов: 43 добавлений и 18 удалений

Просмотреть файл

@ -2992,15 +2992,6 @@ static nsIContent* FindOwner(nsIContent* aContent) {
nsIContent* currentContent = aContent;
while (currentContent) {
nsIContent* parent = currentContent->GetFlattenedTreeParent();
if (!parent) {
// Document root
Document* doc = currentContent->GetUncomposedDoc();
if (doc && doc->GetRootElement() == currentContent) {
return currentContent;
}
break;
}
// Shadow host / Slot
if (IsHostOrSlot(parent)) {
@ -3258,12 +3249,9 @@ nsresult nsFocusManager::GetNextTabbableContent(
}
}
// If aStartContent is not in a scope owned by the root element
// (i.e. aStartContent is already in shadow DOM),
// search from scope including aStartContent
nsIContent* rootElement = aRootContent->OwnerDoc()->GetRootElement();
nsIContent* owner = FindOwner(aStartContent);
if (owner && rootElement != owner) {
// If aStartContent is in a scope owned by Shadow DOM search from scope
// including aStartContent
if (nsIContent* owner = FindOwner(aStartContent)) {
nsIContent* contentToFocus = GetNextTabbableContentInAncestorScopes(
owner, &aStartContent, aOriginalStartContent, aForward,
&aCurrentTabIndex, aIgnoreTabIndex, aForDocumentNavigation);
@ -3277,8 +3265,8 @@ nsresult nsFocusManager::GetNextTabbableContent(
// We need to continue searching in light DOM, starting at the top level
// shadow host in light DOM (updated aStartContent) and its tabindex
// (updated aCurrentTabIndex).
MOZ_ASSERT(FindOwner(aStartContent) == rootElement,
"aStartContent should be owned by the root element at this point");
MOZ_ASSERT(!FindOwner(aStartContent),
"aStartContent should not be owned by Shadow DOM at this point");
nsPresContext* presContext = aPresShell->GetPresContext();
@ -3437,7 +3425,7 @@ nsresult nsFocusManager::GetNextTabbableContent(
// append ELEMENT to NAVIGATION-ORDER."
// and later in "For each element ELEMENT in NAVIGATION-ORDER: "
// hosts and slots are handled before other elements.
if (currentContent && IsHostOrSlot(currentContent)) {
if (IsHostOrSlot(currentContent)) {
bool focusableHostSlot;
int32_t tabIndex =
HostOrSlotTabIndexValue(currentContent, &focusableHostSlot);

Просмотреть файл

@ -668,6 +668,7 @@ skip-if = (toolkit == 'android') # Android: Bug 775227
skip-if = (toolkit == 'android') # Android: Bug 1465387
[test_find_nac.html]
skip-if = (toolkit == 'android') # Android: Bug 1465387
[test_focus_shadow_dom_root.html]
[test_getAttribute_after_createAttribute.html]
[test_getElementById.html]
[test_getTranslationNodes.html]

Просмотреть файл

@ -0,0 +1,36 @@
<!doctype html>
<title>Test for bug 1544826</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<div id="host"><a href="#" id="slotted">This is focusable too</a></div>
<script>
const host = document.getElementById("host");
const shadow = host.attachShadow({ mode: "open" });
shadow.innerHTML = `
<a id="shadow-1" href="#">This is focusable</a>
<slot></slot>
<a id="shadow-2" href="#">So is this</a>
`;
document.documentElement.remove();
document.appendChild(host);
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
is(document.documentElement, host, "Host is the document element");
host.offsetTop;
synthesizeKey("KEY_Tab");
is(shadow.activeElement.id, "shadow-1", "First link in Shadow DOM is focused");
synthesizeKey("KEY_Tab");
is(document.activeElement.id, "slotted", "Slotted link is focused");
synthesizeKey("KEY_Tab");
is(shadow.activeElement.id, "shadow-2", "Second link in Shadow DOM is focused");
// Now backwards.
synthesizeKey("KEY_Tab", {shiftKey: true});
is(document.activeElement.id, "slotted", "Backwards: Slotted link is focused");
synthesizeKey("KEY_Tab", {shiftKey: true});
is(shadow.activeElement.id, "shadow-1", "Backwards: First slotted link is focused");
SimpleTest.finish();
});
</script>