Title: [87874] trunk/Source/WebCore
Revision
87874
Author
[email protected]
Date
2011-06-01 19:23:45 -0700 (Wed, 01 Jun 2011)

Log Message

2011-06-01  Hayato Ito  <[email protected]>

        Reviewed by Kent Tamura.

        Move {Next,Previous}FocusableNode functions from Document to FocusController.
        https://bugs.webkit.org/show_bug.cgi?id=61839

        There are some member functions in Document which use 'this'
        pointer, but we should use TreeScope instead of Document in some
        places to handle focus issues nicely. We have to move these
        functions out of Document class so that we can give the TreeScope
        as a parameter.

        No new tests since no functionality was changed.

        * dom/Document.cpp:
        * dom/Document.h:
        * page/FocusController.cpp:
        (WebCore::FocusController::deepFocusableNode):
        (WebCore::FocusController::advanceFocusInDocumentOrder):
        (WebCore::nextNodeWithExactTabIndex):
        (WebCore::previousNodeWithExactTabIndex):
        (WebCore::nextNodeWithGreaterTabIndex):
        (WebCore::previousNodeWithLowerTabIndex):
        (WebCore::FocusController::nextFocusableNode):
        (WebCore::FocusController::previousFocusableNode):
        * page/FocusController.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (87873 => 87874)


--- trunk/Source/WebCore/ChangeLog	2011-06-02 02:09:39 UTC (rev 87873)
+++ trunk/Source/WebCore/ChangeLog	2011-06-02 02:23:45 UTC (rev 87874)
@@ -1,3 +1,31 @@
+2011-06-01  Hayato Ito  <[email protected]>
+
+        Reviewed by Kent Tamura.
+
+        Move {Next,Previous}FocusableNode functions from Document to FocusController.
+        https://bugs.webkit.org/show_bug.cgi?id=61839
+
+        There are some member functions in Document which use 'this'
+        pointer, but we should use TreeScope instead of Document in some
+        places to handle focus issues nicely. We have to move these
+        functions out of Document class so that we can give the TreeScope
+        as a parameter.
+
+        No new tests since no functionality was changed.
+
+        * dom/Document.cpp:
+        * dom/Document.h:
+        * page/FocusController.cpp:
+        (WebCore::FocusController::deepFocusableNode):
+        (WebCore::FocusController::advanceFocusInDocumentOrder):
+        (WebCore::nextNodeWithExactTabIndex):
+        (WebCore::previousNodeWithExactTabIndex):
+        (WebCore::nextNodeWithGreaterTabIndex):
+        (WebCore::previousNodeWithLowerTabIndex):
+        (WebCore::FocusController::nextFocusableNode):
+        (WebCore::FocusController::previousFocusableNode):
+        * page/FocusController.h:
+
 2011-06-01  Adrienne Walker  <[email protected]>
 
         Reviewed by James Robinson.

Modified: trunk/Source/WebCore/dom/Document.cpp (87873 => 87874)


--- trunk/Source/WebCore/dom/Document.cpp	2011-06-02 02:09:39 UTC (rev 87873)
+++ trunk/Source/WebCore/dom/Document.cpp	2011-06-02 02:23:45 UTC (rev 87874)
@@ -2509,118 +2509,6 @@
     return m_mappedElementSheet.get();
 }
 
-static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
-{
-    // Search is inclusive of start
-    for (Node* n = start; n; n = n->traverseNextNode())
-        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
-            return n;
-    
-    return 0;
-}
-
-static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
-{
-    // Search is inclusive of start
-    for (Node* n = start; n; n = n->traversePreviousNode())
-        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
-            return n;
-    
-    return 0;
-}
-
-static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
-{
-    // Search is inclusive of start
-    int winningTabIndex = SHRT_MAX + 1;
-    Node* winner = 0;
-    for (Node* n = start; n; n = n->traverseNextNode())
-        if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
-            winner = n;
-            winningTabIndex = n->tabIndex();
-        }
-    
-    return winner;
-}
-
-static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
-{
-    // Search is inclusive of start
-    int winningTabIndex = 0;
-    Node* winner = 0;
-    for (Node* n = start; n; n = n->traversePreviousNode())
-        if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
-            winner = n;
-            winningTabIndex = n->tabIndex();
-        }
-    
-    return winner;
-}
-
-Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
-{
-    if (start) {
-        // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
-        if (start->tabIndex() < 0) {
-            for (Node* n = start->traverseNextNode(); n; n = n->traverseNextNode())
-                if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
-                    return n;
-        }
-    
-        // First try to find a node with the same tabindex as start that comes after start in the document.
-        if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
-            return winner;
-
-        if (!start->tabIndex())
-            // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
-            return 0;
-    }
-
-    // Look for the first node in the document that:
-    // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
-    // 2) comes first in the document, if there's a tie.
-    if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
-        return winner;
-
-    // There are no nodes with a tabindex greater than start's tabindex,
-    // so find the first node with a tabindex of 0.
-    return nextNodeWithExactTabIndex(this, 0, event);
-}
-
-Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
-{
-    Node* last;
-    for (last = this; last->lastChild(); last = last->lastChild()) { }
-
-    // First try to find the last node in the document that comes before start and has the same tabindex as start.
-    // If start is null, find the last node in the document with a tabindex of 0.
-    Node* startingNode;
-    int startingTabIndex;
-    if (start) {
-        startingNode = start->traversePreviousNode();
-        startingTabIndex = start->tabIndex();
-    } else {
-        startingNode = last;
-        startingTabIndex = 0;
-    }
-    
-    // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
-    if (startingTabIndex < 0) {
-        for (Node* n = startingNode; n; n = n->traversePreviousNode())
-            if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
-                return n;        
-    }
-
-    if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
-        return winner;
-
-    // There are no nodes before start with the same tabindex as start, so look for a node that:
-    // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
-    // 2) comes last in the document, if there's a tie.
-    startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
-    return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
-}
-
 int Document::nodeAbsIndex(Node *node)
 {
     ASSERT(node->document() == this);

Modified: trunk/Source/WebCore/dom/Document.h (87873 => 87874)


--- trunk/Source/WebCore/dom/Document.h	2011-06-02 02:09:39 UTC (rev 87873)
+++ trunk/Source/WebCore/dom/Document.h	2011-06-02 02:23:45 UTC (rev 87874)
@@ -767,32 +767,6 @@
 
     CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
 
-    /**
-     * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
-     * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
-     * first (from lowest to highest), and then elements without tab indexes (in document order).
-     *
-     * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
-     *
-     * @return The focus node that comes after fromNode
-     *
-     * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
-     */
-    Node* nextFocusableNode(Node* start, KeyboardEvent*);
-
-    /**
-     * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
-     * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
-     * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
-     *
-     * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
-     *
-     * @return The focus node that comes before fromNode
-     *
-     * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
-     */
-    Node* previousFocusableNode(Node* start, KeyboardEvent*);
-
     int nodeAbsIndex(Node*);
     Node* nodeWithAbsIndex(int absIndex);
 

Modified: trunk/Source/WebCore/page/FocusController.cpp (87873 => 87874)


--- trunk/Source/WebCore/page/FocusController.cpp	2011-06-02 02:09:39 UTC (rev 87873)
+++ trunk/Source/WebCore/page/FocusController.cpp	2011-06-02 02:23:45 UTC (rev 87874)
@@ -56,6 +56,7 @@
 #include "SpatialNavigation.h"
 #include "Widget.h"
 #include "htmlediting.h" // For firstPositionInOrBeforeNode
+#include <limits>
 
 namespace WebCore {
 
@@ -144,7 +145,7 @@
     }
 }
 
-static Node* deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)
+Node* FocusController::deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)
 {
     // The node we found might be a HTMLFrameOwnerElement, so descend down the frame tree until we find either:
     // 1) a focusable node, or
@@ -157,8 +158,8 @@
         Document* document = owner->contentFrame()->document();
 
         node = (direction == FocusDirectionForward)
-            ? document->nextFocusableNode(0, event)
-            : document->previousFocusableNode(0, event);
+            ? nextFocusableNode(document, 0, event)
+            : previousFocusableNode(document, 0, event);
         if (!node) {
             node = owner;
             break;
@@ -215,8 +216,8 @@
     document->updateLayoutIgnorePendingStylesheets();
 
     Node* node = (direction == FocusDirectionForward)
-        ? document->nextFocusableNode(currentNode, event)
-        : document->previousFocusableNode(currentNode, event);
+        ? nextFocusableNode(document, currentNode, event)
+        : previousFocusableNode(document, currentNode, event);
             
     // If there's no focusable node to advance to, move up the frame tree until we find one.
     while (!node && frame) {
@@ -231,8 +232,8 @@
             break;
 
         node = (direction == FocusDirectionForward)
-            ? parentDocument->nextFocusableNode(owner, event)
-            : parentDocument->previousFocusableNode(owner, event);
+            ? nextFocusableNode(parentDocument, owner, event)
+            : previousFocusableNode(parentDocument, owner, event);
 
         frame = parentFrame;
     }
@@ -251,8 +252,8 @@
         // Chrome doesn't want focus, so we should wrap focus.
         Document* d = m_page->mainFrame()->document();
         node = (direction == FocusDirectionForward)
-            ? d->nextFocusableNode(0, event)
-            : d->previousFocusableNode(0, event);
+            ? nextFocusableNode(d, 0, event)
+            : previousFocusableNode(d, 0, event);
 
         node = deepFocusableNode(direction, node, event);
 
@@ -306,6 +307,118 @@
     return true;
 }
 
+static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
+{
+    // Search is inclusive of start
+    for (Node* node = start; node; node = node->traverseNextNode())
+        if (node->isKeyboardFocusable(event) && node->tabIndex() == tabIndex)
+            return node;
+
+    return 0;
+}
+
+static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
+{
+    // Search is inclusive of start
+    for (Node* n = start; n; n = n->traversePreviousNode())
+        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
+            return n;
+
+    return 0;
+}
+
+static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
+{
+    // Search is inclusive of start
+    int winningTabIndex = std::numeric_limits<short>::max() + 1;
+    Node* winner = 0;
+    for (Node* n = start; n; n = n->traverseNextNode())
+        if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
+            winner = n;
+            winningTabIndex = n->tabIndex();
+        }
+
+    return winner;
+}
+
+static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
+{
+    // Search is inclusive of start
+    int winningTabIndex = 0;
+    Node* winner = 0;
+    for (Node* n = start; n; n = n->traversePreviousNode())
+        if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
+            winner = n;
+            winningTabIndex = n->tabIndex();
+        }
+
+    return winner;
+}
+
+Node* FocusController::nextFocusableNode(TreeScope* within, Node* start, KeyboardEvent* event)
+{
+    if (start) {
+        // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
+        if (start->tabIndex() < 0) {
+            for (Node* n = start->traverseNextNode(); n; n = n->traverseNextNode())
+                if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
+                    return n;
+        }
+
+        // First try to find a node with the same tabindex as start that comes after start in the tree scope.
+        if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
+            return winner;
+
+        if (!start->tabIndex())
+            // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
+            return 0;
+    }
+
+    // Look for the first node in the tree scope that:
+    // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
+    // 2) comes first in the tree scope, if there's a tie.
+    if (Node* winner = nextNodeWithGreaterTabIndex(within, start ? start->tabIndex() : 0, event))
+        return winner;
+
+    // There are no nodes with a tabindex greater than start's tabindex,
+    // so find the first node with a tabindex of 0.
+    return nextNodeWithExactTabIndex(within, 0, event);
+}
+
+Node* FocusController::previousFocusableNode(TreeScope* within, Node* start, KeyboardEvent* event)
+{
+    Node* last;
+    for (last = within; last->lastChild(); last = last->lastChild()) { }
+
+    // First try to find the last node in the tree scope that comes before start and has the same tabindex as start.
+    // If start is null, find the last node in the tree scope with a tabindex of 0.
+    Node* startingNode;
+    int startingTabIndex;
+    if (start) {
+        startingNode = start->traversePreviousNode();
+        startingTabIndex = start->tabIndex();
+    } else {
+        startingNode = last;
+        startingTabIndex = 0;
+    }
+
+    // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
+    if (startingTabIndex < 0) {
+        for (Node* n = startingNode; n; n = n->traversePreviousNode())
+            if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
+                return n;
+    }
+
+    if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
+        return winner;
+
+    // There are no nodes before start with the same tabindex as start, so look for a node that:
+    // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
+    // 2) comes last in the tree scope, if there's a tie.
+    startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : std::numeric_limits<short>::max();
+    return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
+}
+
 static bool relinquishesEditingFocus(Node *node)
 {
     ASSERT(node);

Modified: trunk/Source/WebCore/page/FocusController.h (87873 => 87874)


--- trunk/Source/WebCore/page/FocusController.h	2011-06-02 02:09:39 UTC (rev 87873)
+++ trunk/Source/WebCore/page/FocusController.h	2011-06-02 02:23:45 UTC (rev 87874)
@@ -39,6 +39,7 @@
 class KeyboardEvent;
 class Node;
 class Page;
+class TreeScope;
 
 class FocusController {
     WTF_MAKE_NONCOPYABLE(FocusController); WTF_MAKE_FAST_ALLOCATED;
@@ -64,6 +65,8 @@
     bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*);
     bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
 
+    Node* deepFocusableNode(FocusDirection, Node*, KeyboardEvent*);
+
     bool advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*);
     void findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);
 
@@ -72,6 +75,30 @@
     bool m_isActive;
     bool m_isFocused;
     bool m_isChangingFocusedFrame;
+
+    // Searches through the document, starting from start node, for the next selectable element that comes after start node.
+    // The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
+    // first (from lowest to highest), and then elements without tab indexes (in document order).
+    //
+    // @param within The tree scope where a search is executed.
+    // @param start The node from which to start searching. The node before this will be focused. May be null.
+    //
+    // @return The focus node that comes after start node.
+    //
+    // See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
+    Node* nextFocusableNode(TreeScope* within, Node* start, KeyboardEvent*);
+
+    // Searches through the document, starting from start node, for the previous selectable element that comes before start node.
+    // The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
+    // first (from lowest to highest), and then elements without tab indexes (in document order).
+    //
+    // @param within The tree scope where a search is executed.
+    // @param start The node from which to start searching. The node before this will be focused. May be null.
+    //
+    // @return The focus node that comes before start node.
+    //
+    // See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
+    Node* previousFocusableNode(TreeScope* within, Node* start, KeyboardEvent*);
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to