Chromium Code Reviews| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 | 91 |
| 92 private: | 92 private: |
| 93 ScopedFocusNavigation(TreeScope&, const Element*); | 93 ScopedFocusNavigation(TreeScope&, const Element*); |
| 94 ScopedFocusNavigation(HTMLSlotElement&, const Element*); | 94 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 :)
| |
| 95 RawPtrWillBeMember<ContainerNode> m_rootNode; | 95 RawPtrWillBeMember<ContainerNode> m_rootNode; |
| 96 RawPtrWillBeMember<HTMLSlotElement> m_rootSlot; | 96 RawPtrWillBeMember<HTMLSlotElement> m_rootSlot; |
| 97 RawPtrWillBeMember<Element> m_current; | 97 RawPtrWillBeMember<Element> m_current; |
| 98 bool m_slotFallbackTraversal; | |
| 98 }; | 99 }; |
| 99 | 100 |
| 100 ScopedFocusNavigation::ScopedFocusNavigation(TreeScope& treeScope, const Element * current) | 101 ScopedFocusNavigation::ScopedFocusNavigation(TreeScope& treeScope, const Element * current) |
| 101 : m_rootNode(treeScope.rootNode()) | 102 : m_rootNode(treeScope.rootNode()) |
| 102 , m_rootSlot(nullptr) | 103 , m_rootSlot(nullptr) |
| 103 , m_current(const_cast<Element*>(current)) | 104 , m_current(const_cast<Element*>(current)) |
| 105 , m_slotFallbackTraversal(false) | |
| 104 { | 106 { |
| 105 } | 107 } |
| 106 | 108 |
| 107 ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Elemen t* current) | 109 ScopedFocusNavigation::ScopedFocusNavigation(HTMLSlotElement& slot, const Elemen t* current, bool isFallbackScoped) |
| 108 : m_rootNode(nullptr) | 110 : m_rootNode(nullptr) |
| 109 , m_rootSlot(&slot) | 111 , m_rootSlot(&slot) |
| 110 , m_current(const_cast<Element*>(current)) | 112 , m_current(const_cast<Element*>(current)) |
| 113 , m_slotFallbackTraversal(isFallbackScoped) | |
| 111 { | 114 { |
| 112 } | 115 } |
| 113 | 116 |
| 114 Element* ScopedFocusNavigation::currentElement() const | 117 Element* ScopedFocusNavigation::currentElement() const |
| 115 { | 118 { |
| 116 return m_current; | 119 return m_current; |
| 117 } | 120 } |
| 118 | 121 |
| 119 void ScopedFocusNavigation::setCurrentElement(Element* element) | 122 void ScopedFocusNavigation::setCurrentElement(Element* element) |
| 120 { | 123 { |
| 121 m_current = element; | 124 m_current = element; |
| 122 } | 125 } |
| 123 | 126 |
| 124 void ScopedFocusNavigation::moveToNext() | 127 void ScopedFocusNavigation::moveToNext() |
| 125 { | 128 { |
| 126 ASSERT(m_current); | 129 ASSERT(m_current); |
| 127 if (m_rootSlot) { | 130 if (m_rootSlot) { |
| 128 m_current = SlotScopedTraversal::next(*m_current); | 131 if (m_slotFallbackTraversal) { |
| 132 m_current = ElementTraversal::next(*m_current, m_rootSlot); | |
| 133 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | |
| 134 m_current = ElementTraversal::next(*m_current); | |
| 135 } else { | |
| 136 m_current = SlotScopedTraversal::next(*m_current); | |
| 137 } | |
| 129 } else { | 138 } else { |
| 130 m_current = ElementTraversal::next(*m_current); | 139 m_current = ElementTraversal::next(*m_current); |
| 131 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | 140 while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || Sl otScopedTraversal::isSlotFallbackScoped(*m_current))) |
| 132 m_current = ElementTraversal::next(*m_current); | 141 m_current = ElementTraversal::next(*m_current); |
| 133 } | 142 } |
| 134 } | 143 } |
| 135 | 144 |
| 136 void ScopedFocusNavigation::moveToPrevious() | 145 void ScopedFocusNavigation::moveToPrevious() |
| 137 { | 146 { |
| 138 ASSERT(m_current); | 147 ASSERT(m_current); |
| 139 if (m_rootSlot) { | 148 if (m_rootSlot) { |
| 140 m_current = SlotScopedTraversal::previous(*m_current); | 149 if (m_slotFallbackTraversal) { |
| 150 m_current = ElementTraversal::previous(*m_current, m_rootSlot); | |
| 151 if (m_current == m_rootSlot) | |
| 152 m_current = nullptr; | |
| 153 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | |
| 154 m_current = ElementTraversal::previous(*m_current); | |
| 155 } else { | |
| 156 m_current = SlotScopedTraversal::previous(*m_current); | |
| 157 } | |
| 141 } else { | 158 } else { |
| 142 m_current = ElementTraversal::previous(*m_current); | 159 m_current = ElementTraversal::previous(*m_current); |
| 143 while (m_current && SlotScopedTraversal::isSlotScoped(*m_current)) | 160 while (m_current && (SlotScopedTraversal::isSlotScoped(*m_current) || Sl otScopedTraversal::isSlotFallbackScoped(*m_current))) |
| 144 m_current = ElementTraversal::previous(*m_current); | 161 m_current = ElementTraversal::previous(*m_current); |
| 145 } | 162 } |
| 146 } | 163 } |
| 147 | 164 |
| 148 void ScopedFocusNavigation::moveToFirst() | 165 void ScopedFocusNavigation::moveToFirst() |
| 149 { | 166 { |
| 150 if (m_rootSlot) { | 167 if (m_rootSlot) { |
| 151 if (!m_rootSlot->getAssignedNodes().isEmpty()) { | 168 if (!m_slotFallbackTraversal) { |
| 152 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); | 169 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); |
| 153 for (auto assignedNode : assignedNodes) { | 170 for (auto assignedNode : assignedNodes) { |
| 154 if (assignedNode->isElementNode()) { | 171 if (assignedNode->isElementNode()) { |
| 155 m_current = toElement(assignedNode); | 172 m_current = toElement(assignedNode); |
| 156 break; | 173 break; |
| 157 } | 174 } |
| 158 } | 175 } |
| 159 } else { | 176 } else { |
| 160 m_current = nullptr; | 177 Element* first = ElementTraversal::firstChild(*m_rootSlot); |
| 178 while (first && SlotScopedTraversal::isSlotScoped(*first)) | |
| 179 first = ElementTraversal::next(*first, m_rootSlot); | |
| 180 m_current = first; | |
| 161 } | 181 } |
| 162 } else { | 182 } else { |
| 163 Element* first = m_rootNode->isElementNode() ? &toElement(*m_rootNode) : ElementTraversal::next(*m_rootNode); | 183 Element* first = m_rootNode->isElementNode() ? &toElement(*m_rootNode) : ElementTraversal::next(*m_rootNode); |
| 164 while (first && SlotScopedTraversal::isSlotScoped(*first)) | 184 while (first && (SlotScopedTraversal::isSlotScoped(*first) || SlotScoped Traversal::isSlotFallbackScoped(*first))) |
| 165 first = ElementTraversal::next(*first, m_rootNode); | 185 first = ElementTraversal::next(*first, m_rootNode); |
| 166 m_current = first; | 186 m_current = first; |
| 167 } | 187 } |
| 188 | |
| 168 } | 189 } |
| 169 | 190 |
| 170 void ScopedFocusNavigation::moveToLast() | 191 void ScopedFocusNavigation::moveToLast() |
| 171 { | 192 { |
| 172 if (m_rootSlot) { | 193 if (m_rootSlot) { |
| 173 if (!m_rootSlot->getAssignedNodes().isEmpty()) { | 194 if (!m_slotFallbackTraversal) { |
| 174 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); | 195 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); |
| 175 for (auto assignedNode = assignedNodes.rbegin(); assignedNode != ass ignedNodes.rend(); ++assignedNode) { | 196 for (auto assignedNode = assignedNodes.rbegin(); assignedNode != ass ignedNodes.rend(); ++assignedNode) { |
| 176 if ((*assignedNode)->isElementNode()) { | 197 if ((*assignedNode)->isElementNode()) { |
| 177 m_current = ElementTraversal::lastWithinOrSelf(*toElement(*a ssignedNode)); | 198 m_current = ElementTraversal::lastWithinOrSelf(*toElement(*a ssignedNode)); |
| 178 break; | 199 break; |
| 179 } | 200 } |
| 180 } | 201 } |
| 181 } else { | 202 } else { |
| 182 m_current = nullptr; | 203 Element* last = ElementTraversal::lastWithin(*m_rootSlot); |
| 204 while (last && SlotScopedTraversal::isSlotScoped(*last)) | |
| 205 last = ElementTraversal::previous(*last, m_rootSlot); | |
| 206 m_current = last; | |
| 183 } | 207 } |
| 184 } else { | 208 } else { |
| 185 Element* last = ElementTraversal::lastWithin(*m_rootNode); | 209 Element* last = ElementTraversal::lastWithin(*m_rootNode); |
| 186 while (last && SlotScopedTraversal::isSlotScoped(*last)) | 210 while (last && (SlotScopedTraversal::isSlotScoped(*last) || SlotScopedTr aversal::isSlotFallbackScoped(*last))) |
| 187 last = ElementTraversal::previous(*last, m_rootNode); | 211 last = ElementTraversal::previous(*last, m_rootNode); |
| 188 m_current = last; | 212 m_current = last; |
| 189 } | 213 } |
| 190 } | 214 } |
| 191 | 215 |
| 192 Element* ScopedFocusNavigation::owner() const | 216 Element* ScopedFocusNavigation::owner() const |
| 193 { | 217 { |
| 194 if (m_rootSlot) | 218 if (m_rootSlot) |
| 195 return m_rootSlot; | 219 return m_rootSlot; |
| 220 ASSERT(m_rootNode); | |
| 196 if (m_rootNode->isShadowRoot()) { | 221 if (m_rootNode->isShadowRoot()) { |
| 197 ShadowRoot& shadowRoot = toShadowRoot(*m_rootNode); | 222 ShadowRoot& shadowRoot = toShadowRoot(*m_rootNode); |
| 198 return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowIn sertionPointOfYoungerShadowRoot(); | 223 return shadowRoot.isYoungest() ? shadowRoot.host() : shadowRoot.shadowIn sertionPointOfYoungerShadowRoot(); |
| 199 } | 224 } |
| 200 // FIXME: Figure out the right thing for OOPI here. | 225 // FIXME: Figure out the right thing for OOPI here. |
| 201 if (Frame* frame = m_rootNode->document().frame()) | 226 if (Frame* frame = m_rootNode->document().frame()) |
| 202 return frame->deprecatedLocalOwner(); | 227 return frame->deprecatedLocalOwner(); |
| 203 return nullptr; | 228 return nullptr; |
| 204 } | 229 } |
| 205 | 230 |
| 206 ScopedFocusNavigation ScopedFocusNavigation::createFor(const Element& current) | 231 ScopedFocusNavigation ScopedFocusNavigation::createFor(const Element& current) |
| 207 { | 232 { |
| 208 if (SlotScopedTraversal::isSlotScoped(current)) | 233 if (SlotScopedTraversal::isSlotScoped(current)) |
| 209 return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(cu rrent), ¤t); | 234 return ScopedFocusNavigation(*SlotScopedTraversal::findScopeOwnerSlot(cu rrent), ¤t, false); |
| 235 if (SlotScopedTraversal::isSlotFallbackScoped(current)) | |
| 236 return ScopedFocusNavigation(*SlotScopedTraversal::findFallbackScopeOwne rSlot(current), ¤t, true); | |
| 210 return ScopedFocusNavigation(current.treeScope(), ¤t); | 237 return ScopedFocusNavigation(current.treeScope(), ¤t); |
| 211 } | 238 } |
| 212 | 239 |
| 213 ScopedFocusNavigation ScopedFocusNavigation::createForDocument(Document& documen t) | 240 ScopedFocusNavigation ScopedFocusNavigation::createForDocument(Document& documen t) |
| 214 { | 241 { |
| 215 return ScopedFocusNavigation(document, nullptr); | 242 return ScopedFocusNavigation(document, nullptr); |
| 216 } | 243 } |
| 217 | 244 |
| 218 ScopedFocusNavigation ScopedFocusNavigation::ownedByNonFocusableFocusScopeOwner( Element& element) | 245 ScopedFocusNavigation ScopedFocusNavigation::ownedByNonFocusableFocusScopeOwner( Element& element) |
| 219 { | 246 { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 240 } | 267 } |
| 241 | 268 |
| 242 ScopedFocusNavigation ScopedFocusNavigation::ownedByShadowInsertionPoint(HTMLSha dowElement& shadowInsertionPoint) | 269 ScopedFocusNavigation ScopedFocusNavigation::ownedByShadowInsertionPoint(HTMLSha dowElement& shadowInsertionPoint) |
| 243 { | 270 { |
| 244 ASSERT(isShadowInsertionPointFocusScopeOwner(shadowInsertionPoint)); | 271 ASSERT(isShadowInsertionPointFocusScopeOwner(shadowInsertionPoint)); |
| 245 return ScopedFocusNavigation(*shadowInsertionPoint.olderShadowRoot(), nullpt r); | 272 return ScopedFocusNavigation(*shadowInsertionPoint.olderShadowRoot(), nullpt r); |
| 246 } | 273 } |
| 247 | 274 |
| 248 ScopedFocusNavigation ScopedFocusNavigation::ownedByHTMLSlotElement(const HTMLSl otElement& element) | 275 ScopedFocusNavigation ScopedFocusNavigation::ownedByHTMLSlotElement(const HTMLSl otElement& element) |
| 249 { | 276 { |
| 250 return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr) ; | 277 return ScopedFocusNavigation(const_cast<HTMLSlotElement&>(element), nullptr, element.getAssignedNodes().isEmpty()); |
| 251 } | 278 } |
| 252 | 279 |
| 253 inline void dispatchBlurEvent(const Document& document, Element& focusedElement) | 280 inline void dispatchBlurEvent(const Document& document, Element& focusedElement) |
| 254 { | 281 { |
| 255 focusedElement.dispatchBlurEvent(nullptr, WebFocusTypePage); | 282 focusedElement.dispatchBlurEvent(nullptr, WebFocusTypePage); |
| 256 if (focusedElement == document.focusedElement()) { | 283 if (focusedElement == document.focusedElement()) { |
| 257 focusedElement.dispatchFocusOutEvent(EventTypeNames::focusout, nullptr); | 284 focusedElement.dispatchFocusOutEvent(EventTypeNames::focusout, nullptr); |
| 258 if (focusedElement == document.focusedElement()) | 285 if (focusedElement == document.focusedElement()) |
| 259 focusedElement.dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, nu llptr); | 286 focusedElement.dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, nu llptr); |
| 260 } | 287 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 } | 442 } |
| 416 } | 443 } |
| 417 | 444 |
| 418 // Look for the first element in the scope that: | 445 // Look for the first element in the scope that: |
| 419 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and | 446 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and |
| 420 // 2) comes first in the scope, if there's a tie. | 447 // 2) comes first in the scope, if there's a tie. |
| 421 scope.moveToFirst(); | 448 scope.moveToFirst(); |
| 422 if (Element* winner = nextElementWithGreaterTabIndex(scope, current ? adjust edTabIndex(*current) : 0)) { | 449 if (Element* winner = nextElementWithGreaterTabIndex(scope, current ? adjust edTabIndex(*current) : 0)) { |
| 423 return winner; | 450 return winner; |
| 424 } | 451 } |
| 425 | |
| 426 // There are no elements with a tabindex greater than start's tabindex, | 452 // There are no elements with a tabindex greater than start's tabindex, |
| 427 // so find the first element with a tabindex of 0. | 453 // so find the first element with a tabindex of 0. |
| 428 scope.moveToFirst(); | 454 scope.moveToFirst(); |
| 429 return findElementWithExactTabIndex(scope, 0, WebFocusTypeForward); | 455 return findElementWithExactTabIndex(scope, 0, WebFocusTypeForward); |
| 430 } | 456 } |
| 431 | 457 |
| 432 Element* previousFocusableElement(ScopedFocusNavigation& scope) | 458 Element* previousFocusableElement(ScopedFocusNavigation& scope) |
| 433 { | 459 { |
| 434 // First try to find the last element in the scope that comes before start a nd has the same tabindex as start. | 460 // First try to find the last element in the scope that comes before start a nd has the same tabindex as start. |
| 435 // If start is null, find the last element in the scope with a tabindex of 0 . | 461 // If start is null, find the last element in the scope with a tabindex of 0 . |
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1257 return consumed; | 1283 return consumed; |
| 1258 } | 1284 } |
| 1259 | 1285 |
| 1260 DEFINE_TRACE(FocusController) | 1286 DEFINE_TRACE(FocusController) |
| 1261 { | 1287 { |
| 1262 visitor->trace(m_page); | 1288 visitor->trace(m_page); |
| 1263 visitor->trace(m_focusedFrame); | 1289 visitor->trace(m_focusedFrame); |
| 1264 } | 1290 } |
| 1265 | 1291 |
| 1266 } // namespace blink | 1292 } // namespace blink |
| OLD | NEW |