Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(686)

Unified Diff: third_party/WebKit/Source/core/page/FocusController.cpp

Issue 1840333002: Support slots' fallback contents in focus navigation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/page/FocusController.cpp
diff --git a/third_party/WebKit/Source/core/page/FocusController.cpp b/third_party/WebKit/Source/core/page/FocusController.cpp
index 096bdb946d1ec80162dd6c2c1b9d2858ce6b8144..909da9227ba369ce65b69155bdc2875f5079c28a 100644
--- a/third_party/WebKit/Source/core/page/FocusController.cpp
+++ b/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -91,23 +91,26 @@ public:
private:
ScopedFocusNavigation(TreeScope&, const Element*);
- ScopedFocusNavigation(HTMLSlotElement&, const Element*);
+ ScopedFocusNavigation(HTMLSlotElement&, const Element*, bool);
kochi 2016/03/30 06:28:34 Can the third boolean argument be removed? If the
yuzuchan 2016/03/31 07:03:46 Gotcha! Thank you :)
RawPtrWillBeMember<ContainerNode> m_rootNode;
RawPtrWillBeMember<HTMLSlotElement> m_rootSlot;
RawPtrWillBeMember<Element> m_current;
+ bool m_slotFallbackTraversal;
};
ScopedFocusNavigation::ScopedFocusNavigation(TreeScope& treeScope, const Element* current)
: m_rootNode(treeScope.rootNode())
, m_rootSlot(nullptr)
, m_current(const_cast<Element*>(current))
+ , m_slotFallbackTraversal(false)
{
}
-ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Element* current)
+ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Element* current, bool isFallbackScoped)
: m_rootNode(nullptr)
, m_rootSlot(&slot)
, m_current(const_cast<Element*>(current))
+ , m_slotFallbackTraversal(isFallbackScoped)
{
}
@@ -125,10 +128,16 @@ void ScopedFocusNavigation::moveToNext()
{
ASSERT(m_current);
if (m_rootSlot) {
- m_current = SlotScopedTraversal::next(*m_current);
+ if (m_slotFallbackTraversal) {
+ m_current = ElementTraversal::next(*m_current, m_rootSlot);
+ while (m_current && SlotScopedTraversal::isSlotScoped(*m_current))
+ m_current = ElementTraversal::next(*m_current);
+ } else {
+ m_current = SlotScopedTraversal::next(*m_current);
+ }
} else {
m_current = ElementTraversal::next(*m_current);
- while (m_current && SlotScopedTraversal::isSlotScoped(*m_current))
+ while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || SlotScopedTraversal::isSlotFallbackScoped(*m_current)))
m_current = ElementTraversal::next(*m_current);
}
}
@@ -137,10 +146,18 @@ void ScopedFocusNavigation::moveToPrevious()
{
ASSERT(m_current);
if (m_rootSlot) {
- m_current = SlotScopedTraversal::previous(*m_current);
+ if (m_slotFallbackTraversal) {
+ m_current = ElementTraversal::previous(*m_current, m_rootSlot);
+ if (m_current == m_rootSlot)
+ m_current = nullptr;
+ while (m_current && SlotScopedTraversal::isSlotScoped(*m_current))
+ m_current = ElementTraversal::previous(*m_current);
+ } else {
+ m_current = SlotScopedTraversal::previous(*m_current);
+ }
} else {
m_current = ElementTraversal::previous(*m_current);
- while (m_current && SlotScopedTraversal::isSlotScoped(*m_current))
+ while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || SlotScopedTraversal::isSlotFallbackScoped(*m_current)))
m_current = ElementTraversal::previous(*m_current);
}
}
@@ -148,7 +165,7 @@ void ScopedFocusNavigation::moveToPrevious()
void ScopedFocusNavigation::moveToFirst()
{
if (m_rootSlot) {
- if (!m_rootSlot->getAssignedNodes().isEmpty()) {
+ if (!m_slotFallbackTraversal) {
WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlot->getAssignedNodes();
for (auto assignedNode : assignedNodes) {
if (assignedNode->isElementNode()) {
@@ -157,20 +174,24 @@ void ScopedFocusNavigation::moveToFirst()
}
}
} else {
- m_current = nullptr;
+ Element* first = ElementTraversal::firstChild(*m_rootSlot);
+ while (first && SlotScopedTraversal::isSlotScoped(*first))
+ first = ElementTraversal::next(*first, m_rootSlot);
+ m_current = first;
}
} else {
Element* first = m_rootNode->isElementNode() ? &toElement(*m_rootNode) : ElementTraversal::next(*m_rootNode);
- while (first && SlotScopedTraversal::isSlotScoped(*first))
+ while (first && (SlotScopedTraversal::isSlotScoped(*first) || SlotScopedTraversal::isSlotFallbackScoped(*first)))
first = ElementTraversal::next(*first, m_rootNode);
m_current = first;
}
+
}
void ScopedFocusNavigation::moveToLast()
{
if (m_rootSlot) {
- if (!m_rootSlot->getAssignedNodes().isEmpty()) {
+ if (!m_slotFallbackTraversal) {
WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlot->getAssignedNodes();
for (auto assignedNode = assignedNodes.rbegin(); assignedNode != assignedNodes.rend(); ++assignedNode) {
if ((*assignedNode)->isElementNode()) {
@@ -179,11 +200,14 @@ void ScopedFocusNavigation::moveToLast()
}
}
} else {
- m_current = nullptr;
+ Element* last = ElementTraversal::lastWithin(*m_rootSlot);
+ while (last && SlotScopedTraversal::isSlotScoped(*last))
+ last = ElementTraversal::previous(*last, m_rootSlot);
+ m_current = last;
}
} else {
Element* last = ElementTraversal::lastWithin(*m_rootNode);
- while (last && SlotScopedTraversal::isSlotScoped(*last))
+ while (last && (SlotScopedTraversal::isSlotScoped(*last) || SlotScopedTraversal::isSlotFallbackScoped(*last)))
last = ElementTraversal::previous(*last, m_rootNode);
m_current = last;
}
@@ -193,6 +217,7 @@ Element* ScopedFocusNavigation::owner() const
{
if (m_rootSlot)
return m_rootSlot;
+ ASSERT(m_rootNode);
if (m_rootNode->isShadowRoot()) {
ShadowRoot& shadowRoot = toShadowRoot(*m_rootNode);
return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowInsertionPointOfYoungerShadowRoot();
@@ -206,7 +231,9 @@ Element* ScopedFocusNavigation::owner() const
ScopedFocusNavigation ScopedFocusNavigation::createFor(const Element& current)
{
if (SlotScopedTraversal::isSlotScoped(current))
- return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(current), &current);
+ return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(current), &current, false);
+ if (SlotScopedTraversal::isSlotFallbackScoped(current))
+ return ScopedFocusNavigation(*SlotScopedTraversal::findFallbackScopeOwnerSlot(current), &current, true);
return ScopedFocusNavigation(current.treeScope(), &current);
}
@@ -247,7 +274,7 @@ ScopedFocusNavigation ScopedFocusNavigation::ownedByShadowInsertionPoint(HTMLSha
ScopedFocusNavigation ScopedFocusNavigation::ownedByHTMLSlotElement(const HTMLSlotElement& element)
{
- return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr);
+ return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr, element.getAssignedNodes().isEmpty());
}
inline void dispatchBlurEvent(const Document& document, Element& focusedElement)
@@ -422,7 +449,6 @@ Element* nextFocusableElement(ScopedFocusNavigation& scope)
if (Element* winner = nextElementWithGreaterTabIndex(scope, current ? adjustedTabIndex(*current) : 0)) {
return winner;
}
-
// There are no elements with a tabindex greater than start's tabindex,
// so find the first element with a tabindex of 0.
scope.moveToFirst();

Powered by Google App Engine
This is Rietveld 408576698