| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Nuanti Ltd. | 3 * Copyright (C) 2008 Nuanti Ltd. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 void moveToFirst(); | 81 void moveToFirst(); |
| 82 void moveToLast(); | 82 void moveToLast(); |
| 83 Element* owner() const; | 83 Element* owner() const; |
| 84 static ScopedFocusNavigation createFor(const Element&); | 84 static ScopedFocusNavigation createFor(const Element&); |
| 85 static ScopedFocusNavigation createForDocument(Document&); | 85 static ScopedFocusNavigation createForDocument(Document&); |
| 86 static ScopedFocusNavigation ownedByNonFocusableFocusScopeOwner(Element&); | 86 static ScopedFocusNavigation ownedByNonFocusableFocusScopeOwner(Element&); |
| 87 static ScopedFocusNavigation ownedByShadowHost(const Element&); | 87 static ScopedFocusNavigation ownedByShadowHost(const Element&); |
| 88 static ScopedFocusNavigation ownedByShadowInsertionPoint(HTMLShadowElement&)
; | 88 static ScopedFocusNavigation ownedByShadowInsertionPoint(HTMLShadowElement&)
; |
| 89 static ScopedFocusNavigation ownedByHTMLSlotElement(const HTMLSlotElement&); | 89 static ScopedFocusNavigation ownedByHTMLSlotElement(const HTMLSlotElement&); |
| 90 static ScopedFocusNavigation ownedByIFrame(const HTMLFrameOwnerElement&); | 90 static ScopedFocusNavigation ownedByIFrame(const HTMLFrameOwnerElement&); |
| 91 static HTMLSlotElement* findFallbackScopeOwnerSlot(const Element&); |
| 92 static bool isSlotFallbackScoped(const Element&); |
| 93 static bool isSlotFallbackScopedForThisSlot(const HTMLSlotElement&, const El
ement&); |
| 91 | 94 |
| 92 private: | 95 private: |
| 93 ScopedFocusNavigation(TreeScope&, const Element*); | 96 ScopedFocusNavigation(TreeScope&, const Element*); |
| 94 ScopedFocusNavigation(HTMLSlotElement&, const Element*); | 97 ScopedFocusNavigation(HTMLSlotElement&, const Element*); |
| 95 Member<ContainerNode> m_rootNode; | 98 RawPtrWillBeMember<ContainerNode> m_rootNode; |
| 96 Member<HTMLSlotElement> m_rootSlot; | 99 RawPtrWillBeMember<HTMLSlotElement> m_rootSlot; |
| 97 Member<Element> m_current; | 100 RawPtrWillBeMember<Element> m_current; |
| 101 bool m_slotFallbackTraversal; |
| 98 }; | 102 }; |
| 99 | 103 |
| 100 ScopedFocusNavigation::ScopedFocusNavigation(TreeScope& treeScope, const Element
* current) | 104 ScopedFocusNavigation::ScopedFocusNavigation(TreeScope& treeScope, const Element
* current) |
| 101 : m_rootNode(treeScope.rootNode()) | 105 : m_rootNode(treeScope.rootNode()) |
| 102 , m_rootSlot(nullptr) | 106 , m_rootSlot(nullptr) |
| 103 , m_current(const_cast<Element*>(current)) | 107 , m_current(const_cast<Element*>(current)) |
| 104 { | 108 { |
| 105 } | 109 } |
| 106 | 110 |
| 107 ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Elemen
t* current) | 111 ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Elemen
t* current) |
| 108 : m_rootNode(nullptr) | 112 : m_rootNode(nullptr) |
| 109 , m_rootSlot(&slot) | 113 , m_rootSlot(&slot) |
| 110 , m_current(const_cast<Element*>(current)) | 114 , m_current(const_cast<Element*>(current)) |
| 115 , m_slotFallbackTraversal(slot.getAssignedNodes().isEmpty()) |
| 111 { | 116 { |
| 112 } | 117 } |
| 113 | 118 |
| 114 Element* ScopedFocusNavigation::currentElement() const | 119 Element* ScopedFocusNavigation::currentElement() const |
| 115 { | 120 { |
| 116 return m_current; | 121 return m_current; |
| 117 } | 122 } |
| 118 | 123 |
| 119 void ScopedFocusNavigation::setCurrentElement(Element* element) | 124 void ScopedFocusNavigation::setCurrentElement(Element* element) |
| 120 { | 125 { |
| 121 m_current = element; | 126 m_current = element; |
| 122 } | 127 } |
| 123 | 128 |
| 124 void ScopedFocusNavigation::moveToNext() | 129 void ScopedFocusNavigation::moveToNext() |
| 125 { | 130 { |
| 126 ASSERT(m_current); | 131 ASSERT(m_current); |
| 127 if (m_rootSlot) { | 132 if (m_rootSlot) { |
| 128 m_current = SlotScopedTraversal::next(*m_current); | 133 if (m_slotFallbackTraversal) { |
| 134 m_current = ElementTraversal::next(*m_current, m_rootSlot); |
| 135 while (m_current && !ScopedFocusNavigation::isSlotFallbackScopedForT
hisSlot(*m_rootSlot, *m_current)) |
| 136 m_current = ElementTraversal::next(*m_current, m_rootSlot); |
| 137 } else { |
| 138 m_current = SlotScopedTraversal::next(*m_current); |
| 139 } |
| 129 } else { | 140 } else { |
| 130 m_current = ElementTraversal::next(*m_current); | 141 m_current = ElementTraversal::next(*m_current); |
| 131 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | 142 while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || Sc
opedFocusNavigation::isSlotFallbackScoped(*m_current))) |
| 132 m_current = ElementTraversal::next(*m_current); | 143 m_current = ElementTraversal::next(*m_current); |
| 133 } | 144 } |
| 134 } | 145 } |
| 135 | 146 |
| 136 void ScopedFocusNavigation::moveToPrevious() | 147 void ScopedFocusNavigation::moveToPrevious() |
| 137 { | 148 { |
| 138 ASSERT(m_current); | 149 ASSERT(m_current); |
| 139 if (m_rootSlot) { | 150 if (m_rootSlot) { |
| 140 m_current = SlotScopedTraversal::previous(*m_current); | 151 if (m_slotFallbackTraversal) { |
| 152 m_current = ElementTraversal::previous(*m_current, m_rootSlot); |
| 153 if (m_current == m_rootSlot) |
| 154 m_current = nullptr; |
| 155 while (m_current && !ScopedFocusNavigation::isSlotFallbackScopedForT
hisSlot(*m_rootSlot, *m_current)) |
| 156 m_current = ElementTraversal::previous(*m_current); |
| 157 } else { |
| 158 m_current = SlotScopedTraversal::previous(*m_current); |
| 159 } |
| 141 } else { | 160 } else { |
| 142 m_current = ElementTraversal::previous(*m_current); | 161 m_current = ElementTraversal::previous(*m_current); |
| 143 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | 162 while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || Sc
opedFocusNavigation::isSlotFallbackScoped(*m_current))) |
| 144 m_current = ElementTraversal::previous(*m_current); | 163 m_current = ElementTraversal::previous(*m_current); |
| 145 } | 164 } |
| 146 } | 165 } |
| 147 | 166 |
| 148 void ScopedFocusNavigation::moveToFirst() | 167 void ScopedFocusNavigation::moveToFirst() |
| 149 { | 168 { |
| 150 if (m_rootSlot) { | 169 if (m_rootSlot) { |
| 151 if (!m_rootSlot->getAssignedNodes().isEmpty()) { | 170 if (!m_slotFallbackTraversal) { |
| 152 HeapVector<Member<Node>> assignedNodes = m_rootSlot->getAssignedNode
s(); | 171 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo
t->getAssignedNodes(); |
| 153 for (auto assignedNode : assignedNodes) { | 172 for (auto assignedNode : assignedNodes) { |
| 154 if (assignedNode->isElementNode()) { | 173 if (assignedNode->isElementNode()) { |
| 155 m_current = toElement(assignedNode); | 174 m_current = toElement(assignedNode); |
| 156 break; | 175 break; |
| 157 } | 176 } |
| 158 } | 177 } |
| 159 } else { | 178 } else { |
| 160 m_current = nullptr; | 179 Element* first = ElementTraversal::firstChild(*m_rootSlot); |
| 180 while (first && !ScopedFocusNavigation::isSlotFallbackScopedForThisS
lot(*m_rootSlot, *first)) |
| 181 first = ElementTraversal::next(*first, m_rootSlot); |
| 182 m_current = first; |
| 161 } | 183 } |
| 162 } else { | 184 } else { |
| 163 Element* first = m_rootNode->isElementNode() ? &toElement(*m_rootNode) :
ElementTraversal::next(*m_rootNode); | 185 Element* first = m_rootNode->isElementNode() ? &toElement(*m_rootNode) :
ElementTraversal::next(*m_rootNode); |
| 164 while (first && SlotScopedTraversal::isSlotScoped(*first)) | 186 while (first && (SlotScopedTraversal::isSlotScoped(*first) || ScopedFocu
sNavigation::isSlotFallbackScoped(*first))) |
| 165 first = ElementTraversal::next(*first, m_rootNode); | 187 first = ElementTraversal::next(*first, m_rootNode); |
| 166 m_current = first; | 188 m_current = first; |
| 167 } | 189 } |
| 190 |
| 168 } | 191 } |
| 169 | 192 |
| 170 void ScopedFocusNavigation::moveToLast() | 193 void ScopedFocusNavigation::moveToLast() |
| 171 { | 194 { |
| 172 if (m_rootSlot) { | 195 if (m_rootSlot) { |
| 173 if (!m_rootSlot->getAssignedNodes().isEmpty()) { | 196 if (!m_slotFallbackTraversal) { |
| 174 HeapVector<Member<Node>> assignedNodes = m_rootSlot->getAssignedNode
s(); | 197 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo
t->getAssignedNodes(); |
| 175 for (auto assignedNode = assignedNodes.rbegin(); assignedNode != ass
ignedNodes.rend(); ++assignedNode) { | 198 for (auto assignedNode = assignedNodes.rbegin(); assignedNode != ass
ignedNodes.rend(); ++assignedNode) { |
| 176 if ((*assignedNode)->isElementNode()) { | 199 if ((*assignedNode)->isElementNode()) { |
| 177 m_current = ElementTraversal::lastWithinOrSelf(*toElement(*a
ssignedNode)); | 200 m_current = ElementTraversal::lastWithinOrSelf(*toElement(*a
ssignedNode)); |
| 178 break; | 201 break; |
| 179 } | 202 } |
| 180 } | 203 } |
| 181 } else { | 204 } else { |
| 182 m_current = nullptr; | 205 Element* last = ElementTraversal::lastWithin(*m_rootSlot); |
| 206 while (last && !ScopedFocusNavigation::isSlotFallbackScopedForThisSl
ot(*m_rootSlot, *last)) |
| 207 last = ElementTraversal::previous(*last, m_rootSlot); |
| 208 m_current = last; |
| 183 } | 209 } |
| 184 } else { | 210 } else { |
| 185 Element* last = ElementTraversal::lastWithin(*m_rootNode); | 211 Element* last = ElementTraversal::lastWithin(*m_rootNode); |
| 186 while (last && SlotScopedTraversal::isSlotScoped(*last)) | 212 while (last && (SlotScopedTraversal::isSlotScoped(*last) || ScopedFocusN
avigation::isSlotFallbackScoped(*last))) |
| 187 last = ElementTraversal::previous(*last, m_rootNode); | 213 last = ElementTraversal::previous(*last, m_rootNode); |
| 188 m_current = last; | 214 m_current = last; |
| 189 } | 215 } |
| 190 } | 216 } |
| 191 | 217 |
| 192 Element* ScopedFocusNavigation::owner() const | 218 Element* ScopedFocusNavigation::owner() const |
| 193 { | 219 { |
| 194 if (m_rootSlot) | 220 if (m_rootSlot) |
| 195 return m_rootSlot; | 221 return m_rootSlot; |
| 222 ASSERT(m_rootNode); |
| 196 if (m_rootNode->isShadowRoot()) { | 223 if (m_rootNode->isShadowRoot()) { |
| 197 ShadowRoot& shadowRoot = toShadowRoot(*m_rootNode); | 224 ShadowRoot& shadowRoot = toShadowRoot(*m_rootNode); |
| 198 return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowIn
sertionPointOfYoungerShadowRoot(); | 225 return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowIn
sertionPointOfYoungerShadowRoot(); |
| 199 } | 226 } |
| 200 // FIXME: Figure out the right thing for OOPI here. | 227 // FIXME: Figure out the right thing for OOPI here. |
| 201 if (Frame* frame = m_rootNode->document().frame()) | 228 if (Frame* frame = m_rootNode->document().frame()) |
| 202 return frame->deprecatedLocalOwner(); | 229 return frame->deprecatedLocalOwner(); |
| 203 return nullptr; | 230 return nullptr; |
| 204 } | 231 } |
| 205 | 232 |
| 206 ScopedFocusNavigation ScopedFocusNavigation::createFor(const Element& current) | 233 ScopedFocusNavigation ScopedFocusNavigation::createFor(const Element& current) |
| 207 { | 234 { |
| 208 if (SlotScopedTraversal::isSlotScoped(current)) | 235 if (HTMLSlotElement* slot = SlotScopedTraversal::findScopeOwnerSlot(current)
) |
| 209 return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(cu
rrent), ¤t); | 236 return ScopedFocusNavigation(*slot, ¤t); |
| 237 if (HTMLSlotElement* slot = ScopedFocusNavigation::findFallbackScopeOwnerSlo
t(current)) |
| 238 return ScopedFocusNavigation(*slot, ¤t); |
| 210 return ScopedFocusNavigation(current.treeScope(), ¤t); | 239 return ScopedFocusNavigation(current.treeScope(), ¤t); |
| 211 } | 240 } |
| 212 | 241 |
| 213 ScopedFocusNavigation ScopedFocusNavigation::createForDocument(Document& documen
t) | 242 ScopedFocusNavigation ScopedFocusNavigation::createForDocument(Document& documen
t) |
| 214 { | 243 { |
| 215 return ScopedFocusNavigation(document, nullptr); | 244 return ScopedFocusNavigation(document, nullptr); |
| 216 } | 245 } |
| 217 | 246 |
| 218 ScopedFocusNavigation ScopedFocusNavigation::ownedByNonFocusableFocusScopeOwner(
Element& element) | 247 ScopedFocusNavigation ScopedFocusNavigation::ownedByNonFocusableFocusScopeOwner(
Element& element) |
| 219 { | 248 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 243 { | 272 { |
| 244 ASSERT(isShadowInsertionPointFocusScopeOwner(shadowInsertionPoint)); | 273 ASSERT(isShadowInsertionPointFocusScopeOwner(shadowInsertionPoint)); |
| 245 return ScopedFocusNavigation(*shadowInsertionPoint.olderShadowRoot(), nullpt
r); | 274 return ScopedFocusNavigation(*shadowInsertionPoint.olderShadowRoot(), nullpt
r); |
| 246 } | 275 } |
| 247 | 276 |
| 248 ScopedFocusNavigation ScopedFocusNavigation::ownedByHTMLSlotElement(const HTMLSl
otElement& element) | 277 ScopedFocusNavigation ScopedFocusNavigation::ownedByHTMLSlotElement(const HTMLSl
otElement& element) |
| 249 { | 278 { |
| 250 return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr)
; | 279 return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr)
; |
| 251 } | 280 } |
| 252 | 281 |
| 282 HTMLSlotElement* ScopedFocusNavigation::findFallbackScopeOwnerSlot(const Element
& element) |
| 283 { |
| 284 Element* parent = const_cast<Element*>(element.parentElement()); |
| 285 while (parent) { |
| 286 if (isHTMLSlotElement(parent)) |
| 287 return toHTMLSlotElement(parent)->getAssignedNodes().isEmpty() ? toH
TMLSlotElement(parent) : nullptr; |
| 288 parent = parent->parentElement(); |
| 289 } |
| 290 return nullptr; |
| 291 } |
| 292 |
| 293 bool ScopedFocusNavigation::isSlotFallbackScoped(const Element& element) |
| 294 { |
| 295 return ScopedFocusNavigation::findFallbackScopeOwnerSlot(element); |
| 296 } |
| 297 |
| 298 bool ScopedFocusNavigation::isSlotFallbackScopedForThisSlot(const HTMLSlotElemen
t& slot, const Element& current) |
| 299 { |
| 300 Element* parent = current.parentElement(); |
| 301 while (parent) { |
| 302 if (isHTMLSlotElement(parent) && toHTMLSlotElement(parent)->getAssignedN
odes().isEmpty()) |
| 303 return !SlotScopedTraversal::isSlotScoped(current) && toHTMLSlotElem
ent(parent) == slot; |
| 304 parent = parent->parentElement(); |
| 305 } |
| 306 return false; |
| 307 } |
| 308 |
| 253 inline void dispatchBlurEvent(const Document& document, Element& focusedElement) | 309 inline void dispatchBlurEvent(const Document& document, Element& focusedElement) |
| 254 { | 310 { |
| 255 focusedElement.dispatchBlurEvent(nullptr, WebFocusTypePage); | 311 focusedElement.dispatchBlurEvent(nullptr, WebFocusTypePage); |
| 256 if (focusedElement == document.focusedElement()) { | 312 if (focusedElement == document.focusedElement()) { |
| 257 focusedElement.dispatchFocusOutEvent(EventTypeNames::focusout, nullptr); | 313 focusedElement.dispatchFocusOutEvent(EventTypeNames::focusout, nullptr); |
| 258 if (focusedElement == document.focusedElement()) | 314 if (focusedElement == document.focusedElement()) |
| 259 focusedElement.dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, nu
llptr); | 315 focusedElement.dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, nu
llptr); |
| 260 } | 316 } |
| 261 } | 317 } |
| 262 | 318 |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 current = document->sequentialFocusNavigationStartingPoint(type); | 916 current = document->sequentialFocusNavigationStartingPoint(type); |
| 861 | 917 |
| 862 // FIXME: Not quite correct when it comes to focus transitions leaving/enter
ing the WebView itself | 918 // FIXME: Not quite correct when it comes to focus transitions leaving/enter
ing the WebView itself |
| 863 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn
abled(); | 919 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn
abled(); |
| 864 | 920 |
| 865 if (caretBrowsing && !current) | 921 if (caretBrowsing && !current) |
| 866 current = adjustToElement(frame->selection().start().anchorNode(), type)
; | 922 current = adjustToElement(frame->selection().start().anchorNode(), type)
; |
| 867 | 923 |
| 868 document->updateLayoutIgnorePendingStylesheets(); | 924 document->updateLayoutIgnorePendingStylesheets(); |
| 869 ScopedFocusNavigation scope = current ? ScopedFocusNavigation::createFor(*cu
rrent) : ScopedFocusNavigation::createForDocument(*document); | 925 ScopedFocusNavigation scope = current ? ScopedFocusNavigation::createFor(*cu
rrent) : ScopedFocusNavigation::createForDocument(*document); |
| 870 RawPtr<Element> element = findFocusableElementAcrossFocusScopes(type, scope)
; | 926 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes(
type, scope); |
| 871 | |
| 872 if (!element) { | 927 if (!element) { |
| 873 // If there's a RemoteFrame on the ancestor chain, we need to continue | 928 // If there's a RemoteFrame on the ancestor chain, we need to continue |
| 874 // searching for focusable elements there. | 929 // searching for focusable elements there. |
| 875 if (frame->localFrameRoot() != frame->tree().top()) { | 930 if (frame->localFrameRoot() != frame->tree().top()) { |
| 876 document->clearFocusedElement(); | 931 document->clearFocusedElement(); |
| 877 document->setSequentialFocusNavigationStartingPoint(nullptr); | 932 document->setSequentialFocusNavigationStartingPoint(nullptr); |
| 878 toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocu
s(type, frame->localFrameRoot()); | 933 toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocu
s(type, frame->localFrameRoot()); |
| 879 return true; | 934 return true; |
| 880 } | 935 } |
| 881 | 936 |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 return consumed; | 1309 return consumed; |
| 1255 } | 1310 } |
| 1256 | 1311 |
| 1257 DEFINE_TRACE(FocusController) | 1312 DEFINE_TRACE(FocusController) |
| 1258 { | 1313 { |
| 1259 visitor->trace(m_page); | 1314 visitor->trace(m_page); |
| 1260 visitor->trace(m_focusedFrame); | 1315 visitor->trace(m_focusedFrame); |
| 1261 } | 1316 } |
| 1262 | 1317 |
| 1263 } // namespace blink | 1318 } // namespace blink |
| OLD | NEW |