Changeset 87874 in webkit
- Timestamp:
- Jun 1, 2011 7:23:45 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r87868 r87874 1 2011-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 1 29 2011-06-01 Adrienne Walker <enne@google.com> 2 30 -
trunk/Source/WebCore/dom/Document.cpp
r87863 r87874 2510 2510 } 2511 2511 2512 static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)2513 {2514 // Search is inclusive of start2515 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 start2525 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 start2535 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 start2549 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 order2564 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), and2581 // 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 order2608 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), and2619 // 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 2624 2512 int Document::nodeAbsIndex(Node *node) 2625 2513 { -
trunk/Source/WebCore/dom/Document.h
r87802 r87874 768 768 CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt); 769 769 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 indexes773 * 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 fromNode778 *779 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1780 */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 tab786 * 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 fromNode791 *792 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1793 */794 Node* previousFocusableNode(Node* start, KeyboardEvent*);795 796 770 int nodeAbsIndex(Node*); 797 771 Node* nodeWithAbsIndex(int absIndex); -
trunk/Source/WebCore/page/FocusController.cpp
r85864 r87874 57 57 #include "Widget.h" 58 58 #include "htmlediting.h" // For firstPositionInOrBeforeNode 59 #include <limits> 59 60 60 61 namespace WebCore { … … 145 146 } 146 147 147 static Node*deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event)148 Node* FocusController::deepFocusableNode(FocusDirection direction, Node* node, KeyboardEvent* event) 148 149 { 149 150 // The node we found might be a HTMLFrameOwnerElement, so descend down the frame tree until we find either: … … 158 159 159 160 node = (direction == FocusDirectionForward) 160 ? document->nextFocusableNode(0, event)161 : document->previousFocusableNode(0, event);161 ? nextFocusableNode(document, 0, event) 162 : previousFocusableNode(document, 0, event); 162 163 if (!node) { 163 164 node = owner; … … 216 217 217 218 Node* node = (direction == FocusDirectionForward) 218 ? document->nextFocusableNode(currentNode, event)219 : document->previousFocusableNode(currentNode, event);219 ? nextFocusableNode(document, currentNode, event) 220 : previousFocusableNode(document, currentNode, event); 220 221 221 222 // If there's no focusable node to advance to, move up the frame tree until we find one. … … 232 233 233 234 node = (direction == FocusDirectionForward) 234 ? parentDocument->nextFocusableNode(owner, event)235 : p arentDocument->previousFocusableNode(owner, event);235 ? nextFocusableNode(parentDocument, owner, event) 236 : previousFocusableNode(parentDocument, owner, event); 236 237 237 238 frame = parentFrame; … … 252 253 Document* d = m_page->mainFrame()->document(); 253 254 node = (direction == FocusDirectionForward) 254 ? d->nextFocusableNode(0, event)255 : d->previousFocusableNode(0, event);255 ? nextFocusableNode(d, 0, event) 256 : previousFocusableNode(d, 0, event); 256 257 257 258 node = deepFocusableNode(direction, node, event); … … 305 306 static_cast<Element*>(node)->focus(false); 306 307 return true; 308 } 309 310 static 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 320 static 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 330 static 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 344 static 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 358 Node* 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 388 Node* 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); 307 420 } 308 421 -
trunk/Source/WebCore/page/FocusController.h
r86325 r87874 40 40 class Node; 41 41 class Page; 42 class TreeScope; 42 43 43 44 class FocusController { … … 65 66 bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus); 66 67 68 Node* deepFocusableNode(FocusDirection, Node*, KeyboardEvent*); 69 67 70 bool advanceFocusDirectionallyInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*); 68 71 void findFocusCandidateInContainer(Node* container, const IntRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest); … … 73 76 bool m_isFocused; 74 77 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*); 75 102 }; 76 103
Note: See TracChangeset
for help on using the changeset viewer.