Changeset 87874 in webkit


Ignore:
Timestamp:
Jun 1, 2011 7:23:45 PM (13 years ago)
Author:
hayato@chromium.org
Message:

2011-06-01 Hayato Ito <hayato@chromium.org>

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:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r87868 r87874  
     12011-06-01  Hayato Ito  <hayato@chromium.org>
     2
     3        Reviewed by Kent Tamura.
     4
     5        Move {Next,Previous}FocusableNode functions from Document to FocusController.
     6        https://bugs.webkit.org/show_bug.cgi?id=61839
     7
     8        There are some member functions in Document which use 'this'
     9        pointer, but we should use TreeScope instead of Document in some
     10        places to handle focus issues nicely. We have to move these
     11        functions out of Document class so that we can give the TreeScope
     12        as a parameter.
     13
     14        No new tests since no functionality was changed.
     15
     16        * dom/Document.cpp:
     17        * dom/Document.h:
     18        * page/FocusController.cpp:
     19        (WebCore::FocusController::deepFocusableNode):
     20        (WebCore::FocusController::advanceFocusInDocumentOrder):
     21        (WebCore::nextNodeWithExactTabIndex):
     22        (WebCore::previousNodeWithExactTabIndex):
     23        (WebCore::nextNodeWithGreaterTabIndex):
     24        (WebCore::previousNodeWithLowerTabIndex):
     25        (WebCore::FocusController::nextFocusableNode):
     26        (WebCore::FocusController::previousFocusableNode):
     27        * page/FocusController.h:
     28
    1292011-06-01  Adrienne Walker  <enne@google.com>
    230
  • trunk/Source/WebCore/dom/Document.cpp

    r87863 r87874  
    25102510}
    25112511
    2512 static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
    2513 {
    2514     // Search is inclusive of start
    2515     for (Node* n = start; n; n = n->traverseNextNode())
    2516         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
    2517             return n;
    2518    
    2519     return 0;
    2520 }
    2521 
    2522 static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
    2523 {
    2524     // Search is inclusive of start
    2525     for (Node* n = start; n; n = n->traversePreviousNode())
    2526         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
    2527             return n;
    2528    
    2529     return 0;
    2530 }
    2531 
    2532 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
    2533 {
    2534     // Search is inclusive of start
    2535     int winningTabIndex = SHRT_MAX + 1;
    2536     Node* winner = 0;
    2537     for (Node* n = start; n; n = n->traverseNextNode())
    2538         if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
    2539             winner = n;
    2540             winningTabIndex = n->tabIndex();
    2541         }
    2542    
    2543     return winner;
    2544 }
    2545 
    2546 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
    2547 {
    2548     // Search is inclusive of start
    2549     int winningTabIndex = 0;
    2550     Node* winner = 0;
    2551     for (Node* n = start; n; n = n->traversePreviousNode())
    2552         if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
    2553             winner = n;
    2554             winningTabIndex = n->tabIndex();
    2555         }
    2556    
    2557     return winner;
    2558 }
    2559 
    2560 Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
    2561 {
    2562     if (start) {
    2563         // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
    2564         if (start->tabIndex() < 0) {
    2565             for (Node* n = start->traverseNextNode(); n; n = n->traverseNextNode())
    2566                 if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
    2567                     return n;
    2568         }
    2569    
    2570         // First try to find a node with the same tabindex as start that comes after start in the document.
    2571         if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
    2572             return winner;
    2573 
    2574         if (!start->tabIndex())
    2575             // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
    2576             return 0;
    2577     }
    2578 
    2579     // Look for the first node in the document that:
    2580     // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
    2581     // 2) comes first in the document, if there's a tie.
    2582     if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
    2583         return winner;
    2584 
    2585     // There are no nodes with a tabindex greater than start's tabindex,
    2586     // so find the first node with a tabindex of 0.
    2587     return nextNodeWithExactTabIndex(this, 0, event);
    2588 }
    2589 
    2590 Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
    2591 {
    2592     Node* last;
    2593     for (last = this; last->lastChild(); last = last->lastChild()) { }
    2594 
    2595     // First try to find the last node in the document that comes before start and has the same tabindex as start.
    2596     // If start is null, find the last node in the document with a tabindex of 0.
    2597     Node* startingNode;
    2598     int startingTabIndex;
    2599     if (start) {
    2600         startingNode = start->traversePreviousNode();
    2601         startingTabIndex = start->tabIndex();
    2602     } else {
    2603         startingNode = last;
    2604         startingTabIndex = 0;
    2605     }
    2606    
    2607     // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
    2608     if (startingTabIndex < 0) {
    2609         for (Node* n = startingNode; n; n = n->traversePreviousNode())
    2610             if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
    2611                 return n;       
    2612     }
    2613 
    2614     if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
    2615         return winner;
    2616 
    2617     // There are no nodes before start with the same tabindex as start, so look for a node that:
    2618     // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
    2619     // 2) comes last in the document, if there's a tie.
    2620     startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
    2621     return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
    2622 }
    2623 
    26242512int Document::nodeAbsIndex(Node *node)
    26252513{
  • trunk/Source/WebCore/dom/Document.h

    r87802 r87874  
    768768    CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
    769769
    770     /**
    771      * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
    772      * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
    773      * first (from lowest to highest), and then elements without tab indexes (in document order).
    774      *
    775      * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
    776      *
    777      * @return The focus node that comes after fromNode
    778      *
    779      * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
    780      */
    781     Node* nextFocusableNode(Node* start, KeyboardEvent*);
    782 
    783     /**
    784      * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
    785      * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
    786      * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
    787      *
    788      * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
    789      *
    790      * @return The focus node that comes before fromNode
    791      *
    792      * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
    793      */
    794     Node* previousFocusableNode(Node* start, KeyboardEvent*);
    795 
    796770    int nodeAbsIndex(Node*);
    797771    Node* nodeWithAbsIndex(int absIndex);
  • trunk/Source/WebCore/page/FocusController.cpp

    r85864 r87874  
    5757#include "Widget.h"
    5858#include "htmlediting.h" // For firstPositionInOrBeforeNode
     59#include <limits>
    5960
    6061namespace WebCore {
     
    145146}
    146147
    147 static Node* deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)
     148Node* FocusController::deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)
    148149{
    149150    // The node we found might be a HTMLFrameOwnerElement, so descend down the frame tree until we find either:
     
    158159
    159160        node = (direction == FocusDirectionForward)
    160             ? document->nextFocusableNode(0, event)
    161             : document->previousFocusableNode(0, event);
     161            ? nextFocusableNode(document, 0, event)
     162            : previousFocusableNode(document, 0, event);
    162163        if (!node) {
    163164            node = owner;
     
    216217
    217218    Node* node = (direction == FocusDirectionForward)
    218         ? document->nextFocusableNode(currentNode, event)
    219         : document->previousFocusableNode(currentNode, event);
     219        ? nextFocusableNode(document, currentNode, event)
     220        : previousFocusableNode(document, currentNode, event);
    220221           
    221222    // If there's no focusable node to advance to, move up the frame tree until we find one.
     
    232233
    233234        node = (direction == FocusDirectionForward)
    234             ? parentDocument->nextFocusableNode(owner, event)
    235             : parentDocument->previousFocusableNode(owner, event);
     235            ? nextFocusableNode(parentDocument, owner, event)
     236            : previousFocusableNode(parentDocument, owner, event);
    236237
    237238        frame = parentFrame;
     
    252253        Document* d = m_page->mainFrame()->document();
    253254        node = (direction == FocusDirectionForward)
    254             ? d->nextFocusableNode(0, event)
    255             : d->previousFocusableNode(0, event);
     255            ? nextFocusableNode(d, 0, event)
     256            : previousFocusableNode(d, 0, event);
    256257
    257258        node = deepFocusableNode(direction, node, event);
     
    305306    static_cast<Element*>(node)->focus(false);
    306307    return true;
     308}
     309
     310static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     311{
     312    // Search is inclusive of start
     313    for (Node* node = start; node; node = node->traverseNextNode())
     314        if (node->isKeyboardFocusable(event) && node->tabIndex() == tabIndex)
     315            return node;
     316
     317    return 0;
     318}
     319
     320static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     321{
     322    // Search is inclusive of start
     323    for (Node* n = start; n; n = n->traversePreviousNode())
     324        if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
     325            return n;
     326
     327    return 0;
     328}
     329
     330static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     331{
     332    // Search is inclusive of start
     333    int winningTabIndex = std::numeric_limits<short>::max() + 1;
     334    Node* winner = 0;
     335    for (Node* n = start; n; n = n->traverseNextNode())
     336        if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
     337            winner = n;
     338            winningTabIndex = n->tabIndex();
     339        }
     340
     341    return winner;
     342}
     343
     344static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
     345{
     346    // Search is inclusive of start
     347    int winningTabIndex = 0;
     348    Node* winner = 0;
     349    for (Node* n = start; n; n = n->traversePreviousNode())
     350        if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
     351            winner = n;
     352            winningTabIndex = n->tabIndex();
     353        }
     354
     355    return winner;
     356}
     357
     358Node* FocusController::nextFocusableNode(TreeScope* within, Node* start, KeyboardEvent* event)
     359{
     360    if (start) {
     361        // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
     362        if (start->tabIndex() < 0) {
     363            for (Node* n = start->traverseNextNode(); n; n = n->traverseNextNode())
     364                if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
     365                    return n;
     366        }
     367
     368        // First try to find a node with the same tabindex as start that comes after start in the tree scope.
     369        if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
     370            return winner;
     371
     372        if (!start->tabIndex())
     373            // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
     374            return 0;
     375    }
     376
     377    // Look for the first node in the tree scope that:
     378    // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
     379    // 2) comes first in the tree scope, if there's a tie.
     380    if (Node* winner = nextNodeWithGreaterTabIndex(within, start ? start->tabIndex() : 0, event))
     381        return winner;
     382
     383    // There are no nodes with a tabindex greater than start's tabindex,
     384    // so find the first node with a tabindex of 0.
     385    return nextNodeWithExactTabIndex(within, 0, event);
     386}
     387
     388Node* FocusController::previousFocusableNode(TreeScope* within, Node* start, KeyboardEvent* event)
     389{
     390    Node* last;
     391    for (last = within; last->lastChild(); last = last->lastChild()) { }
     392
     393    // First try to find the last node in the tree scope that comes before start and has the same tabindex as start.
     394    // If start is null, find the last node in the tree scope with a tabindex of 0.
     395    Node* startingNode;
     396    int startingTabIndex;
     397    if (start) {
     398        startingNode = start->traversePreviousNode();
     399        startingTabIndex = start->tabIndex();
     400    } else {
     401        startingNode = last;
     402        startingTabIndex = 0;
     403    }
     404
     405    // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
     406    if (startingTabIndex < 0) {
     407        for (Node* n = startingNode; n; n = n->traversePreviousNode())
     408            if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
     409                return n;
     410    }
     411
     412    if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
     413        return winner;
     414
     415    // There are no nodes before start with the same tabindex as start, so look for a node that:
     416    // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
     417    // 2) comes last in the tree scope, if there's a tie.
     418    startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : std::numeric_limits<short>::max();
     419    return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
    307420}
    308421
  • trunk/Source/WebCore/page/FocusController.h

    r86325 r87874  
    4040class Node;
    4141class Page;
     42class TreeScope;
    4243
    4344class FocusController {
     
    6566    bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
    6667
     68    Node* deepFocusableNode(FocusDirection, Node*, KeyboardEvent*);
     69
    6770    bool advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*);
    6871    void findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);
     
    7376    bool m_isFocused;
    7477    bool m_isChangingFocusedFrame;
     78
     79    // Searches through the document, starting from start node, for the next selectable element that comes after start node.
     80    // The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
     81    // first (from lowest to highest), and then elements without tab indexes (in document order).
     82    //
     83    // @param within The tree scope where a search is executed.
     84    // @param start The node from which to start searching. The node before this will be focused. May be null.
     85    //
     86    // @return The focus node that comes after start node.
     87    //
     88    // See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
     89    Node* nextFocusableNode(TreeScope* within, Node* start, KeyboardEvent*);
     90
     91    // Searches through the document, starting from start node, for the previous selectable element that comes before start node.
     92    // The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
     93    // first (from lowest to highest), and then elements without tab indexes (in document order).
     94    //
     95    // @param within The tree scope where a search is executed.
     96    // @param start The node from which to start searching. The node before this will be focused. May be null.
     97    //
     98    // @return The focus node that comes before start node.
     99    //
     100    // See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
     101    Node* previousFocusableNode(TreeScope* within, Node* start, KeyboardEvent*);
    75102};
    76103
Note: See TracChangeset for help on using the changeset viewer.