Title: [201832] trunk
Revision
201832
Author
n_w...@apple.com
Date
2016-06-08 14:15:09 -0700 (Wed, 08 Jun 2016)

Log Message

For keyboard users, activating a fragment URL should transfer focus and caret to the destination
https://bugs.webkit.org/show_bug.cgi?id=116046

Reviewed by Ryosuke Niwa.

Source/WebCore:

Added a sequential focus navigation starting node to document. When TAB or SHIFT-TAB is pressed
and there is no focused element, we start searching for next focus candidates at the sequential
focus navigation node.
Spec: https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point

Test: fast/events/sequential-focus-navigation-starting-point.html

* dom/Document.cpp:
(WebCore::Document::removedLastRef):
(WebCore::Document::destroyRenderTree):
(WebCore::Document::styleResolverChanged):
(WebCore::isNodeInSubtree):
(WebCore::Document::removeFocusedNodeOfSubtree):
(WebCore::Document::hoveredElementDidDetach):
(WebCore::Document::setFocusedElement):
(WebCore::shouldResetFocusNavigationStartingNode):
(WebCore::Document::setFocusNavigationStartingNode):
(WebCore::Document::focusNavigationStartingNode):
(WebCore::Document::setCSSTarget):
(WebCore::Document::nodeChildrenWillBeRemoved):
(WebCore::Document::nodeWillBeRemoved):
(WebCore::fallbackFocusNavigationStartingNodeAfterRemoval):
(WebCore::Document::removeFocusNavigationNodeOfSubtree):
(WebCore::Document::textInserted):
* dom/Document.h:
(WebCore::Document::userActionElements):
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent):
* page/FocusController.cpp:
(WebCore::FocusController::advanceFocusInDocumentOrder):
* page/FrameView.cpp:
(WebCore::FrameView::scrollToAnchor):

LayoutTests:

Added a layout test to check that mouse pressing, fragment navigation, focusing an element and removing
the focused element will give us the expected focus navigation starting point.

Also updated the fragment activation test because now that navigating to an unfocusable fragment will
unfocus the current focused element.

* fast/dom/fragment-activation-focuses-target-expected.txt:
* fast/dom/fragment-activation-focuses-target.html:
* fast/events/sequential-focus-navigation-starting-point-expected.txt: Added.
* fast/events/sequential-focus-navigation-starting-point.html: Added.
* platform/ios-simulator/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (201831 => 201832)


--- trunk/LayoutTests/ChangeLog	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/LayoutTests/ChangeLog	2016-06-08 21:15:09 UTC (rev 201832)
@@ -1,3 +1,22 @@
+2016-06-08  Nan Wang  <n_w...@apple.com>
+
+        For keyboard users, activating a fragment URL should transfer focus and caret to the destination
+        https://bugs.webkit.org/show_bug.cgi?id=116046
+
+        Reviewed by Ryosuke Niwa.
+
+        Added a layout test to check that mouse pressing, fragment navigation, focusing an element and removing
+        the focused element will give us the expected focus navigation starting point.
+
+        Also updated the fragment activation test because now that navigating to an unfocusable fragment will
+        unfocus the current focused element.
+
+        * fast/dom/fragment-activation-focuses-target-expected.txt:
+        * fast/dom/fragment-activation-focuses-target.html:
+        * fast/events/sequential-focus-navigation-starting-point-expected.txt: Added.
+        * fast/events/sequential-focus-navigation-starting-point.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
 2016-06-07  Ryosuke Niwa  <rn...@webkit.org>
 
         REGRESSION (r201667): ASSERTION FAILED: !m_anchorNode || !editingIgnoresContent(*m_anchorNode)

Modified: trunk/LayoutTests/fast/dom/fragment-activation-focuses-target-expected.txt (201831 => 201832)


--- trunk/LayoutTests/fast/dom/fragment-activation-focuses-target-expected.txt	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/LayoutTests/fast/dom/fragment-activation-focuses-target-expected.txt	2016-06-08 21:15:09 UTC (rev 201832)
@@ -14,9 +14,9 @@
 Verify Tab behaves correctly after following the link.
 PASS document.activeElement is document.getElementById('fragment3')
 PASS document.activeElement is document.getElementById('fragment1')
-Activate a link that does not have a focusable fragment and verify focus does not move.
+Activate a link that does not have a focusable fragment and verify that the currently focused element is unfocused.
 PASS document.activeElement is link2
-PASS document.activeElement is link2
+PASS document.activeElement is document.body
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/fragment-activation-focuses-target.html (201831 => 201832)


--- trunk/LayoutTests/fast/dom/fragment-activation-focuses-target.html	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/LayoutTests/fast/dom/fragment-activation-focuses-target.html	2016-06-08 21:15:09 UTC (rev 201832)
@@ -43,12 +43,12 @@
   shouldBe("document.activeElement", "document.getElementById('fragment1')");
 }
 
-debug("Activate a link that does not have a focusable fragment and verify focus does not move.");
+debug("Activate a link that does not have a focusable fragment and verify that the currently focused element is unfocused.");
 var link2 = document.getElementById("link2");
 link2.focus();
 shouldBe("document.activeElement", "link2");
 link2.click();
-shouldBe("document.activeElement", "link2");
+shouldBe("document.activeElement", "document.body");
 
 var successfullyParsed = true;
 

Added: trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point-expected.txt (0 => 201832)


--- trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point-expected.txt	2016-06-08 21:15:09 UTC (rev 201832)
@@ -0,0 +1,19 @@
+Mouse press should update sequential focus navigation starting point.
+PASS container.innerHTML = '<input id=prev><div style="height:200px;"><span>text</span></div><input id=next>'; focusSpan(); moveFocus('forward'); document.activeElement.id is 'next'
+PASS container.innerHTML = '<input id=prev><div style="height:200px;"><span>text</span></div><input id=next>'; focusSpan(); moveFocus('backward'); document.activeElement.id is 'prev'
+PASS container.innerHTML = '<span style="font-size:60px;"><input id=prev>Text Text<input id=next></span>'; focusSpan(); moveFocus('forward'); document.activeElement.id is 'next'
+PASS container.innerHTML = '<span style="font-size:60px;"><input id=prev>Text Text<input id=next></span>'; focusSpan(); moveFocus('backward'); document.activeElement.id is 'prev'
+
+Fragment navigation should update sequential focus navigation starting point.
+PASS container.innerHTML = '<a href="" id=prev><a name="fragment"></a><input id=next>'; clickLink(); moveFocus('forward'); document.activeElement.id is 'next'
+
+Focusing an element should update sequential focus navigation starting point.
+PASS container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); moveFocus('forward'); document.activeElement.id is 'next'
+
+After removing a focused element from the document tree, sequential focus navigation should start at a place where the focused element was.
+PASS container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); removeStart(); moveFocus('forward'); document.activeElement.id is 'next'
+PASS container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); removeStart(); moveFocus('backward'); document.activeElement.id is 'prev'
+PASS container.innerHTML = '<input id=prev><div><input id=start></div><input id=next>'; focusStart(); removeDiv(); moveFocus('forward'); document.activeElement.id is 'next'
+PASS container.innerHTML = '<div><input id=start><input id=prev></div><input id=next>'; focusStart(); removeStart(); moveFocus('forward'); document.activeElement.id is 'prev'
+
+

Added: trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point.html (0 => 201832)


--- trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/sequential-focus-navigation-starting-point.html	2016-06-08 21:15:09 UTC (rev 201832)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<body _onload_="runTest();">
+<script src=""
+<script src=""
+<div id="log"></div>
+<div id="container"></div>
+<script>
+if (!window.eventSender)
+    document.body.textContent = 'This test requires window.eventSender.';
+
+function focusSpan() { 
+    hoverOverElement(container.querySelector('span')); 
+    eventSender.mouseDown();
+}
+
+function focusDiv() { 
+    hoverOverElement(container.querySelector('div')); 
+    eventSender.mouseDown();
+}
+
+function moveFocus(direction) { 
+    eventSender.keyDown('\t', direction == 'forward' ? [] : ['shiftKey']); 
+}
+
+function clickLink() {
+    container.querySelector('a').click();
+}
+
+function focusStart() {
+    container.querySelector('#start').focus();
+}
+
+function removeStart() {
+    container.querySelector('#start').remove();
+}
+
+function removeDiv() {
+    container.querySelector('div').remove();
+}
+
+function runTest() {
+    
+    debug("Mouse press should update sequential focus navigation starting point.");
+    var container = document.querySelector('#container');
+    
+    shouldBe("container.innerHTML = '<input id=prev><div style=\"height:200px;\"><span>text</span></div><input id=next>'; focusSpan(); moveFocus('forward'); document.activeElement.id", "'next'");
+    eventSender.mouseUp();
+    shouldBe("container.innerHTML = '<input id=prev><div style=\"height:200px;\"><span>text</span></div><input id=next>'; focusSpan(); moveFocus('backward'); document.activeElement.id", "'prev'");
+    eventSender.mouseUp();
+    shouldBe("container.innerHTML = '<span style=\"font-size:60px;\"><input id=prev>Text Text<input id=next></span>'; focusSpan(); moveFocus('forward'); document.activeElement.id", "'next'");
+    eventSender.mouseUp();
+    shouldBe("container.innerHTML = '<span style=\"font-size:60px;\"><input id=prev>Text Text<input id=next></span>'; focusSpan(); moveFocus('backward'); document.activeElement.id", "'prev'");
+    eventSender.mouseUp();
+    
+    debug("\nFragment navigation should update sequential focus navigation starting point.");
+    shouldBe("container.innerHTML = '<a href="" id=prev><a name=\"fragment\"></a><input id=next>'; clickLink(); moveFocus('forward'); document.activeElement.id", "'next'");
+    
+    debug("\nFocusing an element should update sequential focus navigation starting point.");
+    shouldBe("container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); moveFocus('forward'); document.activeElement.id", "'next'");
+    
+    debug("\nAfter removing a focused element from the document tree, sequential focus navigation should start at a place where the focused element was.");
+    shouldBe("container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); removeStart(); moveFocus('forward'); document.activeElement.id", "'next'");
+    shouldBe("container.innerHTML = '<input id=prev><input id=start><input id=next>'; focusStart(); removeStart(); moveFocus('backward'); document.activeElement.id", "'prev'");
+    shouldBe("container.innerHTML = '<input id=prev><div><input id=start></div><input id=next>'; focusStart(); removeDiv(); moveFocus('forward'); document.activeElement.id", "'next'");
+    shouldBe("container.innerHTML = '<div><input id=start><input id=prev></div><input id=next>'; focusStart(); removeStart(); moveFocus('forward'); document.activeElement.id", "'prev'");
+}
+
+</script>
+</body>
\ No newline at end of file

Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (201831 => 201832)


--- trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-06-08 21:15:09 UTC (rev 201832)
@@ -263,6 +263,7 @@
 fast/shadow-dom/focus-navigation-across-slots.html [ Failure ]
 fast/shadow-dom/focus-on-iframe.html [ Failure ]
 fast/shadow-dom/negative-tabindex-on-shadow-host.html [ Failure ]
+webkit.org/b/116046 fast/events/sequential-focus-navigation-starting-point.html [ Skip ]
 
 webkit.org/b/150225 fast/custom-elements [ Pass ]
 

Modified: trunk/Source/WebCore/ChangeLog (201831 => 201832)


--- trunk/Source/WebCore/ChangeLog	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/ChangeLog	2016-06-08 21:15:09 UTC (rev 201832)
@@ -1,3 +1,43 @@
+2016-06-08  Nan Wang  <n_w...@apple.com>
+
+        For keyboard users, activating a fragment URL should transfer focus and caret to the destination
+        https://bugs.webkit.org/show_bug.cgi?id=116046
+
+        Reviewed by Ryosuke Niwa.
+
+        Added a sequential focus navigation starting node to document. When TAB or SHIFT-TAB is pressed
+        and there is no focused element, we start searching for next focus candidates at the sequential
+        focus navigation node.
+        Spec: https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point
+
+        Test: fast/events/sequential-focus-navigation-starting-point.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::removedLastRef):
+        (WebCore::Document::destroyRenderTree):
+        (WebCore::Document::styleResolverChanged):
+        (WebCore::isNodeInSubtree):
+        (WebCore::Document::removeFocusedNodeOfSubtree):
+        (WebCore::Document::hoveredElementDidDetach):
+        (WebCore::Document::setFocusedElement):
+        (WebCore::shouldResetFocusNavigationStartingNode):
+        (WebCore::Document::setFocusNavigationStartingNode):
+        (WebCore::Document::focusNavigationStartingNode):
+        (WebCore::Document::setCSSTarget):
+        (WebCore::Document::nodeChildrenWillBeRemoved):
+        (WebCore::Document::nodeWillBeRemoved):
+        (WebCore::fallbackFocusNavigationStartingNodeAfterRemoval):
+        (WebCore::Document::removeFocusNavigationNodeOfSubtree):
+        (WebCore::Document::textInserted):
+        * dom/Document.h:
+        (WebCore::Document::userActionElements):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleMousePressEvent):
+        * page/FocusController.cpp:
+        (WebCore::FocusController::advanceFocusInDocumentOrder):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollToAnchor):
+
 2016-06-08  Eric Carlson  <eric.carl...@apple.com>
 
         HTMLMediaElement.prototype.canPlayType accounting for 250-750ms first loading theverge.com

Modified: trunk/Source/WebCore/dom/Document.cpp (201831 => 201832)


--- trunk/Source/WebCore/dom/Document.cpp	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/dom/Document.cpp	2016-06-08 21:15:09 UTC (rev 201832)
@@ -680,6 +680,7 @@
         m_activeElement = nullptr;
         m_titleElement = nullptr;
         m_documentElement = nullptr;
+        m_focusNavigationStartingNode = nullptr;
         m_userActionElements.documentDidRemoveLastRef();
 #if ENABLE(FULLSCREEN_API)
         m_fullScreenElement = nullptr;
@@ -2308,6 +2309,7 @@
     m_hoveredElement = nullptr;
     m_focusedElement = nullptr;
     m_activeElement = nullptr;
+    m_focusNavigationStartingNode = nullptr;
 
     if (m_documentElement)
         RenderTreeUpdater::tearDownRenderers(*m_documentElement);
@@ -3693,6 +3695,17 @@
     evaluateMediaQueryList();
 }
 
+static bool isNodeInSubtree(Node* node, Node* container, bool amongChildrenOnly)
+{
+    bool nodeInSubtree = false;
+    if (amongChildrenOnly)
+        nodeInSubtree = node->isDescendantOf(container);
+    else
+        nodeInSubtree = (node == container) || node->isDescendantOf(container);
+    
+    return nodeInSubtree;
+}
+
 void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly)
 {
     if (!m_focusedElement || this->inPageCache()) // If the document is in the page cache, then we don't need to clear out the focused node.
@@ -3701,15 +3714,15 @@
     Element* focusedElement = node->treeScope().focusedElement();
     if (!focusedElement)
         return;
-
-    bool nodeInSubtree = false;
-    if (amongChildrenOnly)
-        nodeInSubtree = focusedElement->isDescendantOf(node);
-    else
-        nodeInSubtree = (focusedElement == node) || focusedElement->isDescendantOf(node);
     
-    if (nodeInSubtree)
+    if (isNodeInSubtree(focusedElement, node, amongChildrenOnly)) {
         setFocusedElement(nullptr, FocusDirectionNone, FocusRemovalEventsMode::DoNotDispatch);
+        // Set the focus navigation starting node to the previous focused element so that
+        // we can fallback to the siblings or parent node for the next search.
+        // Also we need to call removeFocusNavigationNodeOfSubtree after this function because
+        // setFocusedElement(nullptr) will reset m_focusNavigationStartingNode.
+        setFocusNavigationStartingNode(focusedElement);
+    }
 }
 
 void Document::hoveredElementDidDetach(Element* element)
@@ -3769,6 +3782,7 @@
             oldFocusedElement->setActive(false);
 
         oldFocusedElement->setFocus(false);
+        setFocusNavigationStartingNode(nullptr);
 
         if (eventsMode == FocusRemovalEventsMode::Dispatch) {
             // Dispatch a change event for form control elements that have been edited.
@@ -3819,6 +3833,7 @@
         }
         // Set focus on the new node
         m_focusedElement = newFocusedElement;
+        setFocusNavigationStartingNode(m_focusedElement.get());
 
         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
         m_focusedElement->dispatchFocusEvent(oldFocusedElement.copyRef(), direction);
@@ -3885,6 +3900,59 @@
     return !focusChangeBlocked;
 }
 
+static bool shouldResetFocusNavigationStartingNode(Node& node)
+{
+    // Setting focus navigation starting node to the following nodes means that we should start
+    // the search from the beginning of the document.
+    return is<HTMLHtmlElement>(node) || is<HTMLDocument>(node);
+}
+
+void Document::setFocusNavigationStartingNode(Node* node)
+{
+    if (!m_frame)
+        return;
+
+    m_focusNavigationStartingNodeIsRemoved = false;
+    if (!node || shouldResetFocusNavigationStartingNode(*node)) {
+        m_focusNavigationStartingNode = nullptr;
+        return;
+    }
+
+    m_focusNavigationStartingNode = node;
+}
+
+Element* Document::focusNavigationStartingNode(FocusDirection direction) const
+{
+    if (m_focusedElement) {
+        if (!m_focusNavigationStartingNode || !m_focusNavigationStartingNode->isDescendantOf(m_focusedElement.get()))
+            return m_focusedElement.get();
+    }
+
+    if (!m_focusNavigationStartingNode)
+        return nullptr;
+
+    Node* node = m_focusNavigationStartingNode.get();
+    
+    // When the node was removed from the document tree. This case is not specified in the spec:
+    // https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point
+    // Current behaivor is to move the sequential navigation node to / after (based on the focus direction)
+    // the previous sibling of the removed node.
+    if (m_focusNavigationStartingNodeIsRemoved) {
+        Node* nextNode = NodeTraversal::next(*node);
+        if (direction == FocusDirectionForward)
+            return ElementTraversal::previous(*nextNode);
+        if (is<Element>(*nextNode))
+            return downcast<Element>(nextNode);
+        return ElementTraversal::next(*nextNode);
+    }
+
+    if (is<Element>(*node))
+        return downcast<Element>(node);
+    if (Element* elementBeforeNextFocusableElement = direction == FocusDirectionForward ? ElementTraversal::previous(*node) : ElementTraversal::next(*node))
+        return elementBeforeNextFocusableElement;
+    return node->parentOrShadowHostElement();
+}
+
 void Document::setCSSTarget(Element* n)
 {
     if (m_cssTarget)
@@ -3982,6 +4050,7 @@
     NoEventDispatchAssertion assertNoEventDispatch;
 
     removeFocusedNodeOfSubtree(&container, true /* amongChildrenOnly */);
+    removeFocusNavigationNodeOfSubtree(container, true /* amongChildrenOnly */);
 
 #if ENABLE(FULLSCREEN_API)
     removeFullScreenElementOfSubtree(&container, true /* amongChildrenOnly */);
@@ -4014,6 +4083,7 @@
     NoEventDispatchAssertion assertNoEventDispatch;
 
     removeFocusedNodeOfSubtree(&n);
+    removeFocusNavigationNodeOfSubtree(n);
 
 #if ENABLE(FULLSCREEN_API)
     removeFullScreenElementOfSubtree(&n);
@@ -4035,6 +4105,22 @@
         m_markers->removeMarkers(&n);
 }
 
+static Node* fallbackFocusNavigationStartingNodeAfterRemoval(Node& node)
+{
+    return node.previousSibling() ? node.previousSibling() : node.parentNode();
+}
+
+void Document::removeFocusNavigationNodeOfSubtree(Node& node, bool amongChildrenOnly)
+{
+    if (!m_focusNavigationStartingNode)
+        return;
+
+    if (isNodeInSubtree(m_focusNavigationStartingNode.get(), &node, amongChildrenOnly)) {
+        m_focusNavigationStartingNode = amongChildrenOnly ? &node : fallbackFocusNavigationStartingNodeAfterRemoval(node);
+        m_focusNavigationStartingNodeIsRemoved = true;
+    }
+}
+
 void Document::textInserted(Node* text, unsigned offset, unsigned length)
 {
     if (!m_ranges.isEmpty()) {

Modified: trunk/Source/WebCore/dom/Document.h (201831 => 201832)


--- trunk/Source/WebCore/dom/Document.h	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/dom/Document.h	2016-06-08 21:15:09 UTC (rev 201832)
@@ -730,6 +730,9 @@
     UserActionElementSet& userActionElements()  { return m_userActionElements; }
     const UserActionElementSet& userActionElements() const { return m_userActionElements; }
 
+    void setFocusNavigationStartingNode(Node*);
+    Element* focusNavigationStartingNode(FocusDirection) const;
+
     void removeFocusedNodeOfSubtree(Node*, bool amongChildrenOnly = false);
     void hoveredElementDidDetach(Element*);
     void elementInActiveChainDidDetach(Element*);
@@ -769,6 +772,7 @@
     void nodeChildrenWillBeRemoved(ContainerNode&);
     // nodeWillBeRemoved is only safe when removing one node at a time.
     void nodeWillBeRemoved(Node&);
+    void removeFocusNavigationNodeOfSubtree(Node&, bool amongChildrenOnly = false);
     enum class AcceptChildOperation { Replace, InsertOrAdd };
     bool canAcceptChild(const Node& newChild, const Node* refChild, AcceptChildOperation) const;
 
@@ -1465,6 +1469,8 @@
 
     Color m_textColor;
 
+    bool m_focusNavigationStartingNodeIsRemoved;
+    RefPtr<Node> m_focusNavigationStartingNode;
     RefPtr<Element> m_focusedElement;
     RefPtr<Element> m_hoveredElement;
     RefPtr<Element> m_activeElement;

Modified: trunk/Source/WebCore/page/EventHandler.cpp (201831 => 201832)


--- trunk/Source/WebCore/page/EventHandler.cpp	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2016-06-08 21:15:09 UTC (rev 201832)
@@ -795,6 +795,7 @@
         focusDocumentView();
 
     m_mousePressNode = event.targetNode();
+    m_frame.document()->setFocusNavigationStartingNode(event.targetNode());
 #if ENABLE(DRAG_SUPPORT)
     m_dragStartPos = event.event().position();
 #endif
@@ -1654,6 +1655,7 @@
     }
 
     m_mousePressNode = mouseEvent.targetNode();
+    m_frame.document()->setFocusNavigationStartingNode(mouseEvent.targetNode());
 
     RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent);
     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe.get())) {

Modified: trunk/Source/WebCore/page/FocusController.cpp (201831 => 201832)


--- trunk/Source/WebCore/page/FocusController.cpp	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/page/FocusController.cpp	2016-06-08 21:15:09 UTC (rev 201832)
@@ -454,7 +454,7 @@
     Frame& frame = focusedOrMainFrame();
     Document* document = frame.document();
 
-    Node* currentNode = document->focusedElement();
+    Node* currentNode = document->focusNavigationStartingNode(direction);
     // FIXME: Not quite correct when it comes to focus transitions leaving/entering the WebView itself
     bool caretBrowsing = frame.settings().caretBrowsingEnabled();
 

Modified: trunk/Source/WebCore/page/FrameView.cpp (201831 => 201832)


--- trunk/Source/WebCore/page/FrameView.cpp	2016-06-08 21:07:42 UTC (rev 201831)
+++ trunk/Source/WebCore/page/FrameView.cpp	2016-06-08 21:15:09 UTC (rev 201832)
@@ -2100,8 +2100,14 @@
     maintainScrollPositionAtAnchor(scrollPositionAnchor);
     
     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
-    if (anchorElement && anchorElement->isFocusable())
-        document.setFocusedElement(anchorElement);
+    if (anchorElement) {
+        if (anchorElement->isFocusable())
+            document.setFocusedElement(anchorElement);
+        else {
+            document.setFocusedElement(nullptr);
+            document.setFocusNavigationStartingNode(anchorElement);
+        }
+    }
     
     return true;
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to