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

Side by Side Diff: third_party/WebKit/Source/core/page/FocusController.cpp

Issue 2432293002: Fix focus navigation for nested slot case (Closed)
Patch Set: More proper fix Created 4 years, 2 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 unified diff | Download patch
OLDNEW
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 64
65 using namespace HTMLNames; 65 using namespace HTMLNames;
66 66
67 namespace { 67 namespace {
68 68
69 inline bool isShadowInsertionPointFocusScopeOwner(Element& element) { 69 inline bool isShadowInsertionPointFocusScopeOwner(Element& element) {
70 return isActiveShadowInsertionPoint(element) && 70 return isActiveShadowInsertionPoint(element) &&
71 toHTMLShadowElement(element).olderShadowRoot(); 71 toHTMLShadowElement(element).olderShadowRoot();
72 } 72 }
73 73
74 inline bool hasCustomFocusLogic(const Element& element) {
75 return element.isHTMLElement() &&
76 toHTMLElement(element).hasCustomFocusLogic();
77 }
78
79 inline bool isShadowHostWithoutCustomFocusLogic(const Element& element) {
80 return isShadowHost(element) && !hasCustomFocusLogic(element);
81 }
82
83 inline bool isNonKeyboardFocusableShadowHost(const Element& element) {
84 return isShadowHostWithoutCustomFocusLogic(element) &&
85 !(element.shadowRootIfV1() ? element.isFocusable()
86 : element.isKeyboardFocusable());
87 }
88
89 inline bool isKeyboardFocusableShadowHost(const Element& element) {
90 return isShadowHostWithoutCustomFocusLogic(element) &&
91 element.isKeyboardFocusable();
92 }
93
94 inline bool isNonFocusableFocusScopeOwner(Element& element) {
95 return isNonKeyboardFocusableShadowHost(element) ||
96 isShadowInsertionPointFocusScopeOwner(element) ||
97 isHTMLSlotElement(element);
98 }
99
100 inline bool isShadowHostDelegatesFocus(const Element& element) {
101 return element.authorShadowRoot() &&
102 element.authorShadowRoot()->delegatesFocus();
103 }
104
74 class ScopedFocusNavigation { 105 class ScopedFocusNavigation {
75 STACK_ALLOCATED(); 106 STACK_ALLOCATED();
76 107
77 public: 108 public:
78 Element* currentElement() const; 109 Element* currentElement() const;
79 void setCurrentElement(Element*); 110 void setCurrentElement(Element*);
80 void moveToNext(); 111 void moveToNext();
81 void moveToPrevious(); 112 void moveToPrevious();
82 void moveToFirst(); 113 void moveToFirst();
83 void moveToLast(); 114 void moveToLast();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 m_current = first; 227 m_current = first;
197 } 228 }
198 } 229 }
199 230
200 void ScopedFocusNavigation::moveToLast() { 231 void ScopedFocusNavigation::moveToLast() {
201 if (m_rootSlot) { 232 if (m_rootSlot) {
202 if (!m_slotFallbackTraversal) { 233 if (!m_slotFallbackTraversal) {
203 HeapVector<Member<Node>> assignedNodes = m_rootSlot->assignedNodes(); 234 HeapVector<Member<Node>> assignedNodes = m_rootSlot->assignedNodes();
204 for (auto assignedNode = assignedNodes.rbegin(); 235 for (auto assignedNode = assignedNodes.rbegin();
205 assignedNode != assignedNodes.rend(); ++assignedNode) { 236 assignedNode != assignedNodes.rend(); ++assignedNode) {
206 if ((*assignedNode)->isElementNode()) { 237 if (!(*assignedNode)->isElementNode())
207 m_current = 238 continue;
208 ElementTraversal::lastWithinOrSelf(*toElement(*assignedNode)); 239
209 break; 240 Element* last = ElementTraversal::lastWithin(*toElement(*assignedNode));
241 if (!last) {
242 m_current = toElement(*assignedNode);
243 } else {
244 while (last) {
245 Element* ancestor =
246 SlotScopedTraversal::nearestAncestorAssignedToSlot(*last);
247 DCHECK(ancestor);
248 if (ancestor == *assignedNode)
249 break;
250 last = ancestor->parentElement();
251 }
252 DCHECK(last);
253 m_current = last;
210 } 254 }
255 break;
211 } 256 }
212 } else { 257 } else {
213 Element* last = ElementTraversal::lastWithin(*m_rootSlot); 258 Element* last = ElementTraversal::lastWithin(*m_rootSlot);
214 while (last && 259 while (last &&
215 !ScopedFocusNavigation::isSlotFallbackScopedForThisSlot( 260 !ScopedFocusNavigation::isSlotFallbackScopedForThisSlot(
216 *m_rootSlot, *last)) 261 *m_rootSlot, *last))
217 last = ElementTraversal::previous(*last, m_rootSlot); 262 last = ElementTraversal::previous(*last, m_rootSlot);
218 m_current = last; 263 m_current = last;
219 } 264 }
220 } else { 265 } else {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 if (LocalDOMWindow* window = document->domWindow()) 418 if (LocalDOMWindow* window = document->domWindow())
374 window->dispatchEvent( 419 window->dispatchEvent(
375 Event::create(focused ? EventTypeNames::focus : EventTypeNames::blur)); 420 Event::create(focused ? EventTypeNames::focus : EventTypeNames::blur));
376 if (focused && document->focusedElement()) { 421 if (focused && document->focusedElement()) {
377 Element* focusedElement(document->focusedElement()); 422 Element* focusedElement(document->focusedElement());
378 focusedElement->setFocused(true); 423 focusedElement->setFocused(true);
379 dispatchFocusEvent(*document, *focusedElement); 424 dispatchFocusEvent(*document, *focusedElement);
380 } 425 }
381 } 426 }
382 427
383 inline bool hasCustomFocusLogic(const Element& element) {
384 return element.isHTMLElement() &&
385 toHTMLElement(element).hasCustomFocusLogic();
386 }
387
388 inline bool isShadowHostWithoutCustomFocusLogic(const Element& element) {
389 return isShadowHost(element) && !hasCustomFocusLogic(element);
390 }
391
392 inline bool isNonKeyboardFocusableShadowHost(const Element& element) {
393 return isShadowHostWithoutCustomFocusLogic(element) &&
394 !(element.shadowRootIfV1() ? element.isFocusable()
395 : element.isKeyboardFocusable());
396 }
397
398 inline bool isKeyboardFocusableShadowHost(const Element& element) {
399 return isShadowHostWithoutCustomFocusLogic(element) &&
400 element.isKeyboardFocusable();
401 }
402
403 inline bool isNonFocusableFocusScopeOwner(Element& element) {
404 return isNonKeyboardFocusableShadowHost(element) ||
405 isShadowInsertionPointFocusScopeOwner(element) ||
406 isHTMLSlotElement(element);
407 }
408
409 inline bool isShadowHostDelegatesFocus(const Element& element) {
410 return element.authorShadowRoot() &&
411 element.authorShadowRoot()->delegatesFocus();
412 }
413
414 inline int adjustedTabIndex(Element& element) { 428 inline int adjustedTabIndex(Element& element) {
415 return (isNonKeyboardFocusableShadowHost(element) || 429 return (isNonKeyboardFocusableShadowHost(element) ||
416 isShadowInsertionPointFocusScopeOwner(element)) 430 isShadowInsertionPointFocusScopeOwner(element))
417 ? 0 431 ? 0
418 : element.tabIndex(); 432 : element.tabIndex();
419 } 433 }
420 434
421 inline bool shouldVisit(Element& element) { 435 inline bool shouldVisit(Element& element) {
422 return element.isKeyboardFocusable() || 436 return element.isKeyboardFocusable() ||
423 isNonFocusableFocusScopeOwner(element); 437 isNonFocusableFocusScopeOwner(element);
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1439
1426 return consumed; 1440 return consumed;
1427 } 1441 }
1428 1442
1429 DEFINE_TRACE(FocusController) { 1443 DEFINE_TRACE(FocusController) {
1430 visitor->trace(m_page); 1444 visitor->trace(m_page);
1431 visitor->trace(m_focusedFrame); 1445 visitor->trace(m_focusedFrame);
1432 } 1446 }
1433 1447
1434 } // namespace blink 1448 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698