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 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 RawPtrWillBeMember<ContainerNode> m_rootNode; | 98 RawPtrWillBeMember<ContainerNode> m_rootNode; |
| 96 RawPtrWillBeMember<HTMLSlotElement> m_rootSlot; | 99 RawPtrWillBeMember<HTMLSlotElement> m_rootSlot; |
| 97 RawPtrWillBeMember<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 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); | 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 WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = m_rootSlo t->getAssignedNodes(); | 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 = const_cast<Element*>(current.parentElement()); | |
|
hayato
2016/04/01 05:45:34
No need to const_cast here, I think.
yuzuchan
2016/04/01 06:26:29
Done.
| |
| 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 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1254 return consumed; | 1310 return consumed; |
| 1255 } | 1311 } |
| 1256 | 1312 |
| 1257 DEFINE_TRACE(FocusController) | 1313 DEFINE_TRACE(FocusController) |
| 1258 { | 1314 { |
| 1259 visitor->trace(m_page); | 1315 visitor->trace(m_page); |
| 1260 visitor->trace(m_focusedFrame); | 1316 visitor->trace(m_focusedFrame); |
| 1261 } | 1317 } |
| 1262 | 1318 |
| 1263 } // namespace blink | 1319 } // namespace blink |
| OLD | NEW |