Changeset 201832 in webkit
- Timestamp:
- Jun 8, 2016, 2:15:09 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 10 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/dom/fragment-activation-focuses-target-expected.txt (modified) (1 diff)
-
LayoutTests/fast/dom/fragment-activation-focuses-target.html (modified) (1 diff)
-
LayoutTests/fast/events/sequential-focus-navigation-starting-point-expected.txt (added)
-
LayoutTests/fast/events/sequential-focus-navigation-starting-point.html (added)
-
LayoutTests/platform/ios-simulator/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/Document.cpp (modified) (10 diffs)
-
Source/WebCore/dom/Document.h (modified) (3 diffs)
-
Source/WebCore/page/EventHandler.cpp (modified) (2 diffs)
-
Source/WebCore/page/FocusController.cpp (modified) (1 diff)
-
Source/WebCore/page/FrameView.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r201823 r201832 1 2016-06-08 Nan Wang <n_wang@apple.com> 2 3 For keyboard users, activating a fragment URL should transfer focus and caret to the destination 4 https://bugs.webkit.org/show_bug.cgi?id=116046 5 6 Reviewed by Ryosuke Niwa. 7 8 Added a layout test to check that mouse pressing, fragment navigation, focusing an element and removing 9 the focused element will give us the expected focus navigation starting point. 10 11 Also updated the fragment activation test because now that navigating to an unfocusable fragment will 12 unfocus the current focused element. 13 14 * fast/dom/fragment-activation-focuses-target-expected.txt: 15 * fast/dom/fragment-activation-focuses-target.html: 16 * fast/events/sequential-focus-navigation-starting-point-expected.txt: Added. 17 * fast/events/sequential-focus-navigation-starting-point.html: Added. 18 * platform/ios-simulator/TestExpectations: 19 1 20 2016-06-07 Ryosuke Niwa <rniwa@webkit.org> 2 21 -
trunk/LayoutTests/fast/dom/fragment-activation-focuses-target-expected.txt
r200494 r201832 15 15 PASS document.activeElement is document.getElementById('fragment3') 16 16 PASS document.activeElement is document.getElementById('fragment1') 17 Activate a link that does not have a focusable fragment and verify focus does not move.17 Activate a link that does not have a focusable fragment and verify that the currently focused element is unfocused. 18 18 PASS document.activeElement is link2 19 PASS document.activeElement is link219 PASS document.activeElement is document.body 20 20 PASS successfullyParsed is true 21 21 -
trunk/LayoutTests/fast/dom/fragment-activation-focuses-target.html
r200494 r201832 44 44 } 45 45 46 debug("Activate a link that does not have a focusable fragment and verify focus does not move.");46 debug("Activate a link that does not have a focusable fragment and verify that the currently focused element is unfocused."); 47 47 var link2 = document.getElementById("link2"); 48 48 link2.focus(); 49 49 shouldBe("document.activeElement", "link2"); 50 50 link2.click(); 51 shouldBe("document.activeElement", " link2");51 shouldBe("document.activeElement", "document.body"); 52 52 53 53 var successfullyParsed = true; -
trunk/LayoutTests/platform/ios-simulator/TestExpectations
r201736 r201832 264 264 fast/shadow-dom/focus-on-iframe.html [ Failure ] 265 265 fast/shadow-dom/negative-tabindex-on-shadow-host.html [ Failure ] 266 webkit.org/b/116046 fast/events/sequential-focus-navigation-starting-point.html [ Skip ] 266 267 267 268 webkit.org/b/150225 fast/custom-elements [ Pass ] -
trunk/Source/WebCore/ChangeLog
r201831 r201832 1 2016-06-08 Nan Wang <n_wang@apple.com> 2 3 For keyboard users, activating a fragment URL should transfer focus and caret to the destination 4 https://bugs.webkit.org/show_bug.cgi?id=116046 5 6 Reviewed by Ryosuke Niwa. 7 8 Added a sequential focus navigation starting node to document. When TAB or SHIFT-TAB is pressed 9 and there is no focused element, we start searching for next focus candidates at the sequential 10 focus navigation node. 11 Spec: https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point 12 13 Test: fast/events/sequential-focus-navigation-starting-point.html 14 15 * dom/Document.cpp: 16 (WebCore::Document::removedLastRef): 17 (WebCore::Document::destroyRenderTree): 18 (WebCore::Document::styleResolverChanged): 19 (WebCore::isNodeInSubtree): 20 (WebCore::Document::removeFocusedNodeOfSubtree): 21 (WebCore::Document::hoveredElementDidDetach): 22 (WebCore::Document::setFocusedElement): 23 (WebCore::shouldResetFocusNavigationStartingNode): 24 (WebCore::Document::setFocusNavigationStartingNode): 25 (WebCore::Document::focusNavigationStartingNode): 26 (WebCore::Document::setCSSTarget): 27 (WebCore::Document::nodeChildrenWillBeRemoved): 28 (WebCore::Document::nodeWillBeRemoved): 29 (WebCore::fallbackFocusNavigationStartingNodeAfterRemoval): 30 (WebCore::Document::removeFocusNavigationNodeOfSubtree): 31 (WebCore::Document::textInserted): 32 * dom/Document.h: 33 (WebCore::Document::userActionElements): 34 * page/EventHandler.cpp: 35 (WebCore::EventHandler::handleMousePressEvent): 36 * page/FocusController.cpp: 37 (WebCore::FocusController::advanceFocusInDocumentOrder): 38 * page/FrameView.cpp: 39 (WebCore::FrameView::scrollToAnchor): 40 1 41 2016-06-08 Eric Carlson <eric.carlson@apple.com> 2 42 -
trunk/Source/WebCore/dom/Document.cpp
r201799 r201832 681 681 m_titleElement = nullptr; 682 682 m_documentElement = nullptr; 683 m_focusNavigationStartingNode = nullptr; 683 684 m_userActionElements.documentDidRemoveLastRef(); 684 685 #if ENABLE(FULLSCREEN_API) … … 2309 2310 m_focusedElement = nullptr; 2310 2311 m_activeElement = nullptr; 2312 m_focusNavigationStartingNode = nullptr; 2311 2313 2312 2314 if (m_documentElement) … … 3694 3696 } 3695 3697 3698 static bool isNodeInSubtree(Node* node, Node* container, bool amongChildrenOnly) 3699 { 3700 bool nodeInSubtree = false; 3701 if (amongChildrenOnly) 3702 nodeInSubtree = node->isDescendantOf(container); 3703 else 3704 nodeInSubtree = (node == container) || node->isDescendantOf(container); 3705 3706 return nodeInSubtree; 3707 } 3708 3696 3709 void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly) 3697 3710 { … … 3702 3715 if (!focusedElement) 3703 3716 return; 3704 3705 bool nodeInSubtree = false;3706 if (amongChildrenOnly)3707 nodeInSubtree = focusedElement->isDescendantOf(node);3708 else3709 nodeInSubtree = (focusedElement == node) || focusedElement->isDescendantOf(node);3710 3717 3711 if ( nodeInSubtree)3718 if (isNodeInSubtree(focusedElement, node, amongChildrenOnly)) { 3712 3719 setFocusedElement(nullptr, FocusDirectionNone, FocusRemovalEventsMode::DoNotDispatch); 3720 // Set the focus navigation starting node to the previous focused element so that 3721 // we can fallback to the siblings or parent node for the next search. 3722 // Also we need to call removeFocusNavigationNodeOfSubtree after this function because 3723 // setFocusedElement(nullptr) will reset m_focusNavigationStartingNode. 3724 setFocusNavigationStartingNode(focusedElement); 3725 } 3713 3726 } 3714 3727 … … 3770 3783 3771 3784 oldFocusedElement->setFocus(false); 3785 setFocusNavigationStartingNode(nullptr); 3772 3786 3773 3787 if (eventsMode == FocusRemovalEventsMode::Dispatch) { … … 3820 3834 // Set focus on the new node 3821 3835 m_focusedElement = newFocusedElement; 3836 setFocusNavigationStartingNode(m_focusedElement.get()); 3822 3837 3823 3838 // Dispatch the focus event and let the node do any other focus related activities (important for text fields) … … 3886 3901 } 3887 3902 3903 static bool shouldResetFocusNavigationStartingNode(Node& node) 3904 { 3905 // Setting focus navigation starting node to the following nodes means that we should start 3906 // the search from the beginning of the document. 3907 return is<HTMLHtmlElement>(node) || is<HTMLDocument>(node); 3908 } 3909 3910 void Document::setFocusNavigationStartingNode(Node* node) 3911 { 3912 if (!m_frame) 3913 return; 3914 3915 m_focusNavigationStartingNodeIsRemoved = false; 3916 if (!node || shouldResetFocusNavigationStartingNode(*node)) { 3917 m_focusNavigationStartingNode = nullptr; 3918 return; 3919 } 3920 3921 m_focusNavigationStartingNode = node; 3922 } 3923 3924 Element* Document::focusNavigationStartingNode(FocusDirection direction) const 3925 { 3926 if (m_focusedElement) { 3927 if (!m_focusNavigationStartingNode || !m_focusNavigationStartingNode->isDescendantOf(m_focusedElement.get())) 3928 return m_focusedElement.get(); 3929 } 3930 3931 if (!m_focusNavigationStartingNode) 3932 return nullptr; 3933 3934 Node* node = m_focusNavigationStartingNode.get(); 3935 3936 // When the node was removed from the document tree. This case is not specified in the spec: 3937 // https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point 3938 // Current behaivor is to move the sequential navigation node to / after (based on the focus direction) 3939 // the previous sibling of the removed node. 3940 if (m_focusNavigationStartingNodeIsRemoved) { 3941 Node* nextNode = NodeTraversal::next(*node); 3942 if (direction == FocusDirectionForward) 3943 return ElementTraversal::previous(*nextNode); 3944 if (is<Element>(*nextNode)) 3945 return downcast<Element>(nextNode); 3946 return ElementTraversal::next(*nextNode); 3947 } 3948 3949 if (is<Element>(*node)) 3950 return downcast<Element>(node); 3951 if (Element* elementBeforeNextFocusableElement = direction == FocusDirectionForward ? ElementTraversal::previous(*node) : ElementTraversal::next(*node)) 3952 return elementBeforeNextFocusableElement; 3953 return node->parentOrShadowHostElement(); 3954 } 3955 3888 3956 void Document::setCSSTarget(Element* n) 3889 3957 { … … 3983 4051 3984 4052 removeFocusedNodeOfSubtree(&container, true /* amongChildrenOnly */); 4053 removeFocusNavigationNodeOfSubtree(container, true /* amongChildrenOnly */); 3985 4054 3986 4055 #if ENABLE(FULLSCREEN_API) … … 4015 4084 4016 4085 removeFocusedNodeOfSubtree(&n); 4086 removeFocusNavigationNodeOfSubtree(n); 4017 4087 4018 4088 #if ENABLE(FULLSCREEN_API) … … 4034 4104 if (is<Text>(n)) 4035 4105 m_markers->removeMarkers(&n); 4106 } 4107 4108 static Node* fallbackFocusNavigationStartingNodeAfterRemoval(Node& node) 4109 { 4110 return node.previousSibling() ? node.previousSibling() : node.parentNode(); 4111 } 4112 4113 void Document::removeFocusNavigationNodeOfSubtree(Node& node, bool amongChildrenOnly) 4114 { 4115 if (!m_focusNavigationStartingNode) 4116 return; 4117 4118 if (isNodeInSubtree(m_focusNavigationStartingNode.get(), &node, amongChildrenOnly)) { 4119 m_focusNavigationStartingNode = amongChildrenOnly ? &node : fallbackFocusNavigationStartingNodeAfterRemoval(node); 4120 m_focusNavigationStartingNodeIsRemoved = true; 4121 } 4036 4122 } 4037 4123 -
trunk/Source/WebCore/dom/Document.h
r201799 r201832 731 731 const UserActionElementSet& userActionElements() const { return m_userActionElements; } 732 732 733 void setFocusNavigationStartingNode(Node*); 734 Element* focusNavigationStartingNode(FocusDirection) const; 735 733 736 void removeFocusedNodeOfSubtree(Node*, bool amongChildrenOnly = false); 734 737 void hoveredElementDidDetach(Element*); … … 770 773 // nodeWillBeRemoved is only safe when removing one node at a time. 771 774 void nodeWillBeRemoved(Node&); 775 void removeFocusNavigationNodeOfSubtree(Node&, bool amongChildrenOnly = false); 772 776 enum class AcceptChildOperation { Replace, InsertOrAdd }; 773 777 bool canAcceptChild(const Node& newChild, const Node* refChild, AcceptChildOperation) const; … … 1466 1470 Color m_textColor; 1467 1471 1472 bool m_focusNavigationStartingNodeIsRemoved; 1473 RefPtr<Node> m_focusNavigationStartingNode; 1468 1474 RefPtr<Element> m_focusedElement; 1469 1475 RefPtr<Element> m_hoveredElement; -
trunk/Source/WebCore/page/EventHandler.cpp
r201588 r201832 796 796 797 797 m_mousePressNode = event.targetNode(); 798 m_frame.document()->setFocusNavigationStartingNode(event.targetNode()); 798 799 #if ENABLE(DRAG_SUPPORT) 799 800 m_dragStartPos = event.event().position(); … … 1655 1656 1656 1657 m_mousePressNode = mouseEvent.targetNode(); 1658 m_frame.document()->setFocusNavigationStartingNode(mouseEvent.targetNode()); 1657 1659 1658 1660 RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent); -
trunk/Source/WebCore/page/FocusController.cpp
r200964 r201832 455 455 Document* document = frame.document(); 456 456 457 Node* currentNode = document->focus edElement();457 Node* currentNode = document->focusNavigationStartingNode(direction); 458 458 // FIXME: Not quite correct when it comes to focus transitions leaving/entering the WebView itself 459 459 bool caretBrowsing = frame.settings().caretBrowsingEnabled(); -
trunk/Source/WebCore/page/FrameView.cpp
r201673 r201832 2101 2101 2102 2102 // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation. 2103 if (anchorElement && anchorElement->isFocusable()) 2104 document.setFocusedElement(anchorElement); 2103 if (anchorElement) { 2104 if (anchorElement->isFocusable()) 2105 document.setFocusedElement(anchorElement); 2106 else { 2107 document.setFocusedElement(nullptr); 2108 document.setFocusNavigationStartingNode(anchorElement); 2109 } 2110 } 2105 2111 2106 2112 return true;
Note:
See TracChangeset
for help on using the changeset viewer.