| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |