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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 inline bool isShadowInsertionPointFocusScopeOwner(Element& element) | 67 inline bool isShadowInsertionPointFocusScopeOwner(Element& element) |
| 68 { | 68 { |
| 69 return isActiveShadowInsertionPoint(element) && toHTMLShadowElement(element) .olderShadowRoot(); | 69 return isActiveShadowInsertionPoint(element) && toHTMLShadowElement(element) .olderShadowRoot(); |
| 70 } | 70 } |
| 71 | 71 |
| 72 class FocusNavigationScope { | 72 class FocusNavigationScope { |
| 73 STACK_ALLOCATED(); | 73 STACK_ALLOCATED(); |
| 74 public: | 74 public: |
| 75 Node* rootNode() const; | 75 Node* rootNode() const; |
| 76 Element* owner() const; | 76 Element* owner() const; |
| 77 static FocusNavigationScope focusNavigationScopeOf(const Node&); | 77 static FocusNavigationScope focusNavigationScopeOf(const Element&); |
| 78 static FocusNavigationScope ownedByNonFocusableFocusScopeOwner(Element&); | 78 static FocusNavigationScope ownedByNonFocusableFocusScopeOwner(Element&); |
| 79 static FocusNavigationScope ownedByShadowHost(const Element&); | 79 static FocusNavigationScope ownedByShadowHost(const Element&); |
| 80 static FocusNavigationScope ownedByShadowInsertionPoint(HTMLShadowElement&); | 80 static FocusNavigationScope ownedByShadowInsertionPoint(HTMLShadowElement&); |
| 81 static FocusNavigationScope ownedByIFrame(const HTMLFrameOwnerElement&); | 81 static FocusNavigationScope ownedByIFrame(const HTMLFrameOwnerElement&); |
| 82 | 82 |
| 83 private: | 83 private: |
| 84 explicit FocusNavigationScope(TreeScope*); | 84 explicit FocusNavigationScope(TreeScope*); |
| 85 RawPtrWillBeMember<TreeScope> m_rootTreeScope; | 85 RawPtrWillBeMember<TreeScope> m_rootTreeScope; |
| 86 }; | 86 }; |
| 87 | 87 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 102 if (root->isShadowRoot()) { | 102 if (root->isShadowRoot()) { |
| 103 ShadowRoot* shadowRoot = toShadowRoot(root); | 103 ShadowRoot* shadowRoot = toShadowRoot(root); |
| 104 return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shado wInsertionPointOfYoungerShadowRoot(); | 104 return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shado wInsertionPointOfYoungerShadowRoot(); |
| 105 } | 105 } |
| 106 // FIXME: Figure out the right thing for OOPI here. | 106 // FIXME: Figure out the right thing for OOPI here. |
| 107 if (Frame* frame = root->document().frame()) | 107 if (Frame* frame = root->document().frame()) |
| 108 return frame->deprecatedLocalOwner(); | 108 return frame->deprecatedLocalOwner(); |
| 109 return nullptr; | 109 return nullptr; |
| 110 } | 110 } |
| 111 | 111 |
| 112 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(const Node& no de) | 112 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(const Element& element) |
| 113 { | 113 { |
| 114 return FocusNavigationScope(&node.treeScope()); | 114 return FocusNavigationScope(&element.treeScope()); |
| 115 } | 115 } |
| 116 | 116 |
| 117 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(El ement& element) | 117 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(El ement& element) |
| 118 { | 118 { |
| 119 if (isShadowHost(element)) | 119 if (isShadowHost(element)) |
| 120 return FocusNavigationScope::ownedByShadowHost(element); | 120 return FocusNavigationScope::ownedByShadowHost(element); |
| 121 ASSERT(isShadowInsertionPointFocusScopeOwner(element)); | 121 ASSERT(isShadowInsertionPointFocusScopeOwner(element)); |
| 122 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (element)); | 122 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (element)); |
| 123 } | 123 } |
| 124 | 124 |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeBackw ard, found); | 522 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeBackw ard, found); |
| 523 } | 523 } |
| 524 | 524 |
| 525 Element* findFocusableElementAcrossFocusScopes(WebFocusType type, const FocusNav igationScope& scope, Node* currentNode) | 525 Element* findFocusableElementAcrossFocusScopes(WebFocusType type, const FocusNav igationScope& scope, Node* currentNode) |
| 526 { | 526 { |
| 527 return (type == WebFocusTypeForward) ? | 527 return (type == WebFocusTypeForward) ? |
| 528 findFocusableElementAcrossFocusScopesForward(scope, currentNode) : | 528 findFocusableElementAcrossFocusScopesForward(scope, currentNode) : |
| 529 findFocusableElementAcrossFocusScopesBackward(scope, currentNode); | 529 findFocusableElementAcrossFocusScopesBackward(scope, currentNode); |
| 530 } | 530 } |
| 531 | 531 |
| 532 inline Element* adjustToElement(Node* node, WebFocusType type) | |
| 533 { | |
| 534 ASSERT(type == WebFocusTypeForward || type == WebFocusTypeBackward); | |
| 535 if (!node) | |
| 536 return nullptr; | |
| 537 if (node->isElementNode()) | |
| 538 return toElement(node); | |
| 539 return (type == WebFocusTypeForward) ? ElementTraversal::next(*node) : Eleme ntTraversal::previous(*node); | |
|
tkent
2016/02/22 06:07:07
If ElementTraversal::next(*node) is focusable, the
| |
| 540 } | |
| 541 | |
| 532 } // anonymous namespace | 542 } // anonymous namespace |
| 533 | 543 |
| 534 FocusController::FocusController(Page* page) | 544 FocusController::FocusController(Page* page) |
| 535 : m_page(page) | 545 : m_page(page) |
| 536 , m_isActive(false) | 546 , m_isActive(false) |
| 537 , m_isFocused(false) | 547 , m_isFocused(false) |
| 538 , m_isChangingFocusedFrame(false) | 548 , m_isChangingFocusedFrame(false) |
| 539 { | 549 { |
| 540 } | 550 } |
| 541 | 551 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 707 | 717 |
| 708 return false; | 718 return false; |
| 709 } | 719 } |
| 710 | 720 |
| 711 bool FocusController::advanceFocusAcrossFrames(WebFocusType type, RemoteFrame* f rom, LocalFrame* to, InputDeviceCapabilities* sourceCapabilities) | 721 bool FocusController::advanceFocusAcrossFrames(WebFocusType type, RemoteFrame* f rom, LocalFrame* to, InputDeviceCapabilities* sourceCapabilities) |
| 712 { | 722 { |
| 713 // If we are shifting focus from a child frame to its parent, the | 723 // If we are shifting focus from a child frame to its parent, the |
| 714 // child frame has no more focusable elements, and we should continue | 724 // child frame has no more focusable elements, and we should continue |
| 715 // looking for focusable elements in the parent, starting from the <iframe> | 725 // looking for focusable elements in the parent, starting from the <iframe> |
| 716 // element of the child frame. | 726 // element of the child frame. |
| 717 Node* startingNode = nullptr; | 727 Element* start = nullptr; |
| 718 if (from->tree().parent() == to) { | 728 if (from->tree().parent() == to) { |
| 719 ASSERT(from->owner()->isLocal()); | 729 ASSERT(from->owner()->isLocal()); |
| 720 startingNode = toHTMLFrameOwnerElement(from->owner()); | 730 start = toHTMLFrameOwnerElement(from->owner()); |
| 721 } | 731 } |
| 722 | 732 |
| 723 return advanceFocusInDocumentOrder(to, startingNode, type, false, sourceCapa bilities); | 733 return advanceFocusInDocumentOrder(to, start, type, false, sourceCapabilitie s); |
| 724 } | 734 } |
| 725 | 735 |
| 726 bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Node* start ingNode, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCa pabilities) | 736 bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Element* st art, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCapabi lities) |
| 727 { | 737 { |
| 728 ASSERT(frame); | 738 ASSERT(frame); |
| 729 Document* document = frame->document(); | 739 Document* document = frame->document(); |
| 740 ASSERT(document->documentElement()); | |
|
hayato
2016/03/15 07:08:16
I guess this assertion is not always true and this
| |
| 730 | 741 |
| 731 Node* currentNode = startingNode; | 742 Element* current = start; |
| 732 if (!currentNode) | 743 if (!current) |
| 733 currentNode = document->focusedElement(); | 744 current = document->focusedElement(); |
| 734 | 745 |
| 735 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself | 746 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself |
| 736 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); | 747 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); |
| 737 | 748 |
| 738 if (caretBrowsing && !currentNode) | 749 if (caretBrowsing && !current) |
| 739 currentNode = frame->selection().start().anchorNode(); | 750 current = adjustToElement(frame->selection().start().anchorNode(), type) ; |
| 740 | 751 |
| 741 document->updateLayoutIgnorePendingStylesheets(); | 752 document->updateLayoutIgnorePendingStylesheets(); |
| 742 | 753 |
| 743 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes( type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document), currentNode); | 754 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes( type, FocusNavigationScope::focusNavigationScopeOf(current ? *current : *documen t->documentElement()), current); |
| 744 | 755 |
| 745 if (!element) { | 756 if (!element) { |
| 746 // If there's a RemoteFrame on the ancestor chain, we need to continue | 757 // If there's a RemoteFrame on the ancestor chain, we need to continue |
| 747 // searching for focusable elements there. | 758 // searching for focusable elements there. |
| 748 if (frame->localFrameRoot() != frame->tree().top()) { | 759 if (frame->localFrameRoot() != frame->tree().top()) { |
| 749 document->clearFocusedElement(); | 760 document->clearFocusedElement(); |
| 750 toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocu s(type, frame->localFrameRoot()); | 761 toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocu s(type, frame->localFrameRoot()); |
| 751 return true; | 762 return true; |
| 752 } | 763 } |
| 753 | 764 |
| 754 // We didn't find an element to focus, so we should try to pass focus to Chrome. | 765 // We didn't find an element to focus, so we should try to pass focus to Chrome. |
| 755 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) { | 766 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) { |
| 756 document->clearFocusedElement(); | 767 document->clearFocusedElement(); |
| 757 setFocusedFrame(nullptr); | 768 setFocusedFrame(nullptr); |
| 758 m_page->chromeClient().takeFocus(type); | 769 m_page->chromeClient().takeFocus(type); |
| 759 return true; | 770 return true; |
| 760 } | 771 } |
| 761 | 772 |
| 762 // Chrome doesn't want focus, so we should wrap focus. | 773 // Chrome doesn't want focus, so we should wrap focus. |
| 763 element = findFocusableElementRecursively(type, FocusNavigationScope::fo cusNavigationScopeOf(*toLocalFrame(m_page->mainFrame())->document()), nullptr); | 774 element = findFocusableElementRecursively(type, FocusNavigationScope::fo cusNavigationScopeOf(*toLocalFrame(m_page->mainFrame())->document()->documentEle ment()), nullptr); |
| 764 element = findFocusableElementDescendingDownIntoFrameDocument(type, elem ent.get()); | 775 element = findFocusableElementDescendingDownIntoFrameDocument(type, elem ent.get()); |
| 765 | 776 |
| 766 if (!element) | 777 if (!element) |
| 767 return false; | 778 return false; |
| 768 } | 779 } |
| 769 | 780 |
| 770 ASSERT(element); | 781 ASSERT(element); |
| 771 | 782 |
| 772 if (element == document->focusedElement()) { | 783 if (element == document->focusedElement()) { |
| 773 // Focus wrapped around to the same node. | 784 // Focus wrapped around to the same node. |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1122 return consumed; | 1133 return consumed; |
| 1123 } | 1134 } |
| 1124 | 1135 |
| 1125 DEFINE_TRACE(FocusController) | 1136 DEFINE_TRACE(FocusController) |
| 1126 { | 1137 { |
| 1127 visitor->trace(m_page); | 1138 visitor->trace(m_page); |
| 1128 visitor->trace(m_focusedFrame); | 1139 visitor->trace(m_focusedFrame); |
| 1129 } | 1140 } |
| 1130 | 1141 |
| 1131 } // namespace blink | 1142 } // namespace blink |
| OLD | NEW |