Chromium Code Reviews| 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), ¤t); |
| + return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(current), ¤t, false); |
| + if (SlotScopedTraversal::isSlotFallbackScoped(current)) |
| + return ScopedFocusNavigation(*SlotScopedTraversal::findFallbackScopeOwnerSlot(current), ¤t, true); |
| return ScopedFocusNavigation(current.treeScope(), ¤t); |
| } |
| @@ -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(); |