| 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 static inline bool isKeyboardFocusableShadowHost(const Node& node) | 224 static inline bool isKeyboardFocusableShadowHost(const Node& node) |
| 225 { | 225 { |
| 226 return isShadowHostWithoutCustomFocusLogic(node) && toElement(node).isKeyboa
rdFocusable(); | 226 return isShadowHostWithoutCustomFocusLogic(node) && toElement(node).isKeyboa
rdFocusable(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 static inline bool isNonFocusableFocusScopeOwner(Node& node) | 229 static inline bool isNonFocusableFocusScopeOwner(Node& node) |
| 230 { | 230 { |
| 231 return isNonKeyboardFocusableShadowHost(node) || isShadowInsertionPointFocus
ScopeOwner(node); | 231 return isNonKeyboardFocusableShadowHost(node) || isShadowInsertionPointFocus
ScopeOwner(node); |
| 232 } | 232 } |
| 233 | 233 |
| 234 static inline bool isShadowHostDelegatesFocus(const Node& node) |
| 235 { |
| 236 return node.isElementNode() && toElement(node).shadowRoot() && toElement(nod
e).shadowRoot()->delegatesFocus(); |
| 237 } |
| 238 |
| 234 static inline int adjustedTabIndex(Node& node) | 239 static inline int adjustedTabIndex(Node& node) |
| 235 { | 240 { |
| 236 return isNonFocusableFocusScopeOwner(node) ? 0 : node.tabIndex(); | 241 return isNonFocusableFocusScopeOwner(node) ? 0 : node.tabIndex(); |
| 237 } | 242 } |
| 238 | 243 |
| 239 static inline bool shouldVisit(Node& node) | 244 static inline bool shouldVisit(Node& node) |
| 240 { | 245 { |
| 241 return (node.isElementNode() && toElement(node).isKeyboardFocusable()) || is
NonFocusableFocusScopeOwner(node); | 246 return (node.isElementNode() && toElement(node).isKeyboardFocusable()) || is
NonFocusableFocusScopeOwner(node); |
| 242 } | 247 } |
| 243 | 248 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); | 524 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); |
| 520 Node* found = findFocusableNodeRecursivelyBackward(scope, currentNode); | 525 Node* found = findFocusableNodeRecursivelyBackward(scope, currentNode); |
| 521 | 526 |
| 522 // If there's no focusable node to advance to, move up the focus scopes unti
l we find one. | 527 // If there's no focusable node to advance to, move up the focus scopes unti
l we find one. |
| 523 FocusNavigationScope currentScope = scope; | 528 FocusNavigationScope currentScope = scope; |
| 524 while (!found) { | 529 while (!found) { |
| 525 Node* owner = currentScope.owner(); | 530 Node* owner = currentScope.owner(); |
| 526 if (!owner) | 531 if (!owner) |
| 527 break; | 532 break; |
| 528 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); | 533 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); |
| 529 if (isKeyboardFocusableShadowHost(*owner)) { | 534 if (isKeyboardFocusableShadowHost(*owner) && !isShadowHostDelegatesFocus
(*owner)) { |
| 530 found = owner; | 535 found = owner; |
| 531 break; | 536 break; |
| 532 } | 537 } |
| 533 found = findFocusableNodeRecursivelyBackward(currentScope, owner); | 538 found = findFocusableNodeRecursivelyBackward(currentScope, owner); |
| 534 } | 539 } |
| 535 return findFocusableNodeDecendingDownIntoFrameDocument(WebFocusTypeBackward,
found); | 540 return findFocusableNodeDecendingDownIntoFrameDocument(WebFocusTypeBackward,
found); |
| 536 } | 541 } |
| 537 | 542 |
| 538 Node* FocusController::findFocusableNodeRecursively(WebFocusType type, const Foc
usNavigationScope& scope, Node* start) | 543 Node* FocusController::findFocusableNodeRecursively(WebFocusType type, const Foc
usNavigationScope& scope, Node* start) |
| 539 { | 544 { |
| 540 return (type == WebFocusTypeForward) ? | 545 return (type == WebFocusTypeForward) ? |
| 541 findFocusableNodeRecursivelyForward(scope, start) : | 546 findFocusableNodeRecursivelyForward(scope, start) : |
| 542 findFocusableNodeRecursivelyBackward(scope, start); | 547 findFocusableNodeRecursivelyBackward(scope, start); |
| 543 } | 548 } |
| 544 | 549 |
| 545 Node* FocusController::findFocusableNodeRecursivelyForward(const FocusNavigation
Scope& scope, Node* start) | 550 Node* FocusController::findFocusableNodeRecursivelyForward(const FocusNavigation
Scope& scope, Node* start) |
| 546 { | 551 { |
| 547 // Starting node is exclusive. | 552 // Starting node is exclusive. |
| 548 Node* found = findFocusableNode(WebFocusTypeForward, scope, start); | 553 Node* found = findFocusableNode(WebFocusTypeForward, scope, start); |
| 549 if (!found) | 554 if (!found) |
| 550 return nullptr; | 555 return nullptr; |
| 556 if (isShadowHostDelegatesFocus(*found)) { |
| 557 if (isShadowHostWithoutCustomFocusLogic(*found)) { |
| 558 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShado
wHost(*found); |
| 559 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyForward(i
nnerScope, nullptr); |
| 560 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusab
leNodeRecursivelyForward(scope, found); |
| 561 } |
| 562 // Skip to the next node. |
| 563 if (!isNonFocusableFocusScopeOwner(*found)) |
| 564 found = findFocusableNodeRecursivelyForward(scope, found); |
| 565 } |
| 551 if (!found || !isNonFocusableFocusScopeOwner(*found)) | 566 if (!found || !isNonFocusableFocusScopeOwner(*found)) |
| 552 return found; | 567 return found; |
| 553 | 568 |
| 554 // Now |found| is on a focusable scope owner (either shadow host or <shadow>
) | 569 // Now |found| is on a focusable scope owner (either shadow host or <shadow>
) |
| 555 // Find inside the inward scope and return it if found. Otherwise continue s
earching in the same | 570 // Find inside the inward scope and return it if found. Otherwise continue s
earching in the same |
| 556 // scope. | 571 // scope. |
| 557 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusableF
ocusScopeOwner(*found); | 572 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusableF
ocusScopeOwner(*found); |
| 558 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyForward(innerScop
e, nullptr); | 573 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyForward(innerScop
e, nullptr); |
| 559 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRe
cursivelyForward(scope, found); | 574 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRe
cursivelyForward(scope, found); |
| 560 } | 575 } |
| 561 | 576 |
| 562 Node* FocusController::findFocusableNodeRecursivelyBackward(const FocusNavigatio
nScope& scope, Node* start) | 577 Node* FocusController::findFocusableNodeRecursivelyBackward(const FocusNavigatio
nScope& scope, Node* start) |
| 563 { | 578 { |
| 564 // Starting node is exclusive. | 579 // Starting node is exclusive. |
| 565 Node* found = findFocusableNode(WebFocusTypeBackward, scope, start); | 580 Node* found = findFocusableNode(WebFocusTypeBackward, scope, start); |
| 566 if (!found) | 581 if (!found) |
| 567 return nullptr; | 582 return nullptr; |
| 568 | 583 |
| 569 // Now |found| is on a focusable shadow host. | 584 // Now |found| is on a focusable shadow host. |
| 570 // Find inside shadow backwards. If any focusable element is found, return i
t, otherwise return | 585 // Find inside shadow backwards. If any focusable element is found, return i
t, otherwise return |
| 571 // the host itself. | 586 // the host itself. |
| 572 if (isKeyboardFocusableShadowHost(*found)) { | 587 if (isKeyboardFocusableShadowHost(*found)) { |
| 573 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos
t(*found); | 588 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos
t(*found); |
| 574 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyBackward(inne
rScope, nullptr); | 589 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyBackward(inne
rScope, nullptr); |
| 575 if (foundInInnerFocusScope) | 590 if (foundInInnerFocusScope) |
| 576 return foundInInnerFocusScope; | 591 return foundInInnerFocusScope; |
| 592 if (isShadowHostDelegatesFocus(*found)) |
| 593 found = findFocusableNodeRecursivelyBackward(scope, found); |
| 577 return found; | 594 return found; |
| 578 } | 595 } |
| 579 | 596 |
| 580 // Now |found| is on a non focusable scope owner (either shadow host or <sha
dow>). | 597 // Now |found| is on a non focusable scope owner (either shadow host or <sha
dow>). |
| 581 // Find focusable node in decendant scope. If not found, find next focusable
node within the | 598 // Find focusable node in decendant scope. If not found, find next focusable
node within the |
| 582 // current scope. | 599 // current scope. |
| 583 if (isNonFocusableFocusScopeOwner(*found)) { | 600 if (isNonFocusableFocusScopeOwner(*found)) { |
| 584 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa
bleFocusScopeOwner(*found); | 601 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa
bleFocusScopeOwner(*found); |
| 585 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyBackward(inne
rScope, nullptr); | 602 Node* foundInInnerFocusScope = findFocusableNodeRecursivelyBackward(inne
rScope, nullptr); |
| 586 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo
deRecursivelyBackward(scope, found); | 603 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo
deRecursivelyBackward(scope, found); |
| 587 } | 604 } |
| 588 | 605 |
| 589 return found; | 606 return found->isElementNode() && !isShadowHostDelegatesFocus(*found) ? found
: findFocusableNodeRecursivelyBackward(scope, found); |
| 590 } | 607 } |
| 591 | 608 |
| 592 static Node* findNodeWithExactTabIndex(Node* start, int tabIndex, WebFocusType t
ype) | 609 static Node* findNodeWithExactTabIndex(Node* start, int tabIndex, WebFocusType t
ype) |
| 593 { | 610 { |
| 594 // Search is inclusive of start | 611 // Search is inclusive of start |
| 595 for (Node* node = start; node; node = type == WebFocusTypeForward ? NodeTrav
ersal::next(*node) : NodeTraversal::previous(*node)) { | 612 for (Node* node = start; node; node = type == WebFocusTypeForward ? NodeTrav
ersal::next(*node) : NodeTraversal::previous(*node)) { |
| 596 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) | 613 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) |
| 597 return node; | 614 return node; |
| 598 } | 615 } |
| 599 return nullptr; | 616 return nullptr; |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 return consumed; | 1015 return consumed; |
| 999 } | 1016 } |
| 1000 | 1017 |
| 1001 DEFINE_TRACE(FocusController) | 1018 DEFINE_TRACE(FocusController) |
| 1002 { | 1019 { |
| 1003 visitor->trace(m_page); | 1020 visitor->trace(m_page); |
| 1004 visitor->trace(m_focusedFrame); | 1021 visitor->trace(m_focusedFrame); |
| 1005 } | 1022 } |
| 1006 | 1023 |
| 1007 } // namespace blink | 1024 } // namespace blink |
| OLD | NEW |