Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: Source/core/page/FocusController.cpp

Issue 704963002: Make some arguments of FocusController functions references. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/page/FocusController.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nuanti Ltd. 3 * Copyright (C) 2008 Nuanti Ltd.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 if (root->isShadowRoot()) { 87 if (root->isShadowRoot()) {
88 ShadowRoot* shadowRoot = toShadowRoot(root); 88 ShadowRoot* shadowRoot = toShadowRoot(root);
89 return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shado wInsertionPointOfYoungerShadowRoot(); 89 return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shado wInsertionPointOfYoungerShadowRoot();
90 } 90 }
91 // FIXME: Figure out the right thing for OOPI here. 91 // FIXME: Figure out the right thing for OOPI here.
92 if (Frame* frame = root->document().frame()) 92 if (Frame* frame = root->document().frame())
93 return frame->deprecatedLocalOwner(); 93 return frame->deprecatedLocalOwner();
94 return nullptr; 94 return nullptr;
95 } 95 }
96 96
97 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node* node) 97 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node& node)
98 { 98 {
99 ASSERT(node); 99 Node* root = &node;
100 Node* root = node; 100 for (Node* n = &node; n; n = n->parentNode())
101 for (Node* n = node; n; n = n->parentNode())
102 root = n; 101 root = n;
103 // The result is not always a ShadowRoot nor a DocumentNode since 102 // The result is not always a ShadowRoot nor a DocumentNode since
104 // a starting node is in an orphaned tree in composed shadow tree. 103 // a starting node is in an orphaned tree in composed shadow tree.
105 return FocusNavigationScope(&root->treeScope()); 104 return FocusNavigationScope(&root->treeScope());
106 } 105 }
107 106
108 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(No de* node) 107 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(No de& node)
109 { 108 {
110 ASSERT(node);
111 if (isShadowHost(node)) 109 if (isShadowHost(node))
112 return FocusNavigationScope::ownedByShadowHost(node); 110 return FocusNavigationScope::ownedByShadowHost(node);
113 ASSERT(isShadowInsertionPointFocusScopeOwner(*node)); 111 ASSERT(isShadowInsertionPointFocusScopeOwner(node));
114 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (node)); 112 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (node));
115 } 113 }
116 114
117 FocusNavigationScope FocusNavigationScope::ownedByShadowHost(Node* node) 115 FocusNavigationScope FocusNavigationScope::ownedByShadowHost(Node& node)
118 { 116 {
119 ASSERT(isShadowHost(node)); 117 ASSERT(isShadowHost(node));
120 return FocusNavigationScope(toElement(node)->shadow()->youngestShadowRoot()) ; 118 return FocusNavigationScope(toElement(node).shadow()->youngestShadowRoot());
121 } 119 }
122 120
123 FocusNavigationScope FocusNavigationScope::ownedByIFrame(HTMLFrameOwnerElement* frame) 121 FocusNavigationScope FocusNavigationScope::ownedByIFrame(HTMLFrameOwnerElement& frame)
124 { 122 {
125 ASSERT(frame && frame->contentFrame() && frame->contentFrame()->isLocalFrame ()); 123 ASSERT(frame.contentFrame());
126 return FocusNavigationScope(toLocalFrame(frame->contentFrame())->document()) ; 124 ASSERT(frame.contentFrame()->isLocalFrame());
125 return FocusNavigationScope(toLocalFrame(frame.contentFrame())->document());
127 } 126 }
128 127
129 FocusNavigationScope FocusNavigationScope::ownedByShadowInsertionPoint(HTMLShado wElement* shadowInsertionPoint) 128 FocusNavigationScope FocusNavigationScope::ownedByShadowInsertionPoint(HTMLShado wElement& shadowInsertionPoint)
130 { 129 {
131 ASSERT(isShadowInsertionPointFocusScopeOwner(*shadowInsertionPoint)); 130 ASSERT(isShadowInsertionPointFocusScopeOwner(shadowInsertionPoint));
132 return FocusNavigationScope(shadowInsertionPoint->olderShadowRoot()); 131 return FocusNavigationScope(shadowInsertionPoint.olderShadowRoot());
133 } 132 }
134 133
135 static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused) 134 static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused)
136 { 135 {
137 // If we have a focused node we should dispatch blur on it before we blur th e window. 136 // If we have a focused node we should dispatch blur on it before we blur th e window.
138 // If we have a focused node we should dispatch focus on it after we focus t he window. 137 // If we have a focused node we should dispatch focus on it after we focus t he window.
139 // https://bugs.webkit.org/show_bug.cgi?id=27105 138 // https://bugs.webkit.org/show_bug.cgi?id=27105
140 139
141 // Do not fire events while modal dialogs are up. See https://bugs.webkit.o rg/show_bug.cgi?id=33962 140 // Do not fire events while modal dialogs are up. See https://bugs.webkit.o rg/show_bug.cgi?id=33962
142 if (Page* page = document->page()) { 141 if (Page* page = document->page()) {
(...skipping 19 matching lines...) Expand all
162 focusedElement->setFocus(true); 161 focusedElement->setFocus(true);
163 focusedElement->dispatchFocusEvent(0, FocusTypePage); 162 focusedElement->dispatchFocusEvent(0, FocusTypePage);
164 if (focusedElement == document->focusedElement()) { 163 if (focusedElement == document->focusedElement()) {
165 document->focusedElement()->dispatchFocusInEvent(EventTypeNames::foc usin, nullptr, FocusTypePage); 164 document->focusedElement()->dispatchFocusInEvent(EventTypeNames::foc usin, nullptr, FocusTypePage);
166 if (focusedElement == document->focusedElement()) 165 if (focusedElement == document->focusedElement())
167 document->focusedElement()->dispatchFocusInEvent(EventTypeNames: :DOMFocusIn, nullptr, FocusTypePage); 166 document->focusedElement()->dispatchFocusInEvent(EventTypeNames: :DOMFocusIn, nullptr, FocusTypePage);
168 } 167 }
169 } 168 }
170 } 169 }
171 170
172 static inline bool hasCustomFocusLogic(Element* element) 171 static inline bool hasCustomFocusLogic(const Element& element)
173 { 172 {
174 return element->isHTMLElement() && toHTMLElement(element)->hasCustomFocusLog ic(); 173 return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic ();
175 } 174 }
176 175
177 #if ENABLE(ASSERT) 176 #if ENABLE(ASSERT)
178 static inline bool isNonFocusableShadowHost(Node* node) 177 static inline bool isNonFocusableShadowHost(const Node& node)
179 { 178 {
180 ASSERT(node); 179 if (!node.isElementNode())
181 if (!node->isElementNode())
182 return false; 180 return false;
183 Element* element = toElement(node); 181 const Element& element = toElement(node);
184 return !element->isFocusable() && isShadowHost(element) && !hasCustomFocusLo gic(element); 182 return !element.isFocusable() && isShadowHost(element) && !hasCustomFocusLog ic(element);
185 } 183 }
186 #endif 184 #endif
187 185
188 static inline bool isNonKeyboardFocusableShadowHost(Node* node) 186 static inline bool isNonKeyboardFocusableShadowHost(const Node& node)
189 { 187 {
190 ASSERT(node); 188 if (!node.isElementNode())
191 if (!node->isElementNode())
192 return false; 189 return false;
193 Element* element = toElement(node); 190 const Element& element = toElement(node);
194 return !element->isKeyboardFocusable() && isShadowHost(element) && !hasCusto mFocusLogic(element); 191 return !element.isKeyboardFocusable() && isShadowHost(element) && !hasCustom FocusLogic(element);
195 } 192 }
196 193
197 static inline bool isKeyboardFocusableShadowHost(Node* node) 194 static inline bool isKeyboardFocusableShadowHost(const Node& node)
198 { 195 {
199 ASSERT(node); 196 if (!node.isElementNode())
200 if (!node->isElementNode())
201 return false; 197 return false;
202 Element* element = toElement(node); 198 const Element& element = toElement(node);
203 return element->isKeyboardFocusable() && isShadowHost(element) && !hasCustom FocusLogic(element); 199 return element.isKeyboardFocusable() && isShadowHost(element) && !hasCustomF ocusLogic(element);
204 } 200 }
205 201
206 static inline bool isNonFocusableFocusScopeOwner(Node* node) 202 static inline bool isNonFocusableFocusScopeOwner(Node& node)
207 { 203 {
208 ASSERT(node); 204 return isNonKeyboardFocusableShadowHost(node) || isShadowInsertionPointFocus ScopeOwner(node);
209 return isNonKeyboardFocusableShadowHost(node) || isShadowInsertionPointFocus ScopeOwner(*node);
210 } 205 }
211 206
212 static inline int adjustedTabIndex(Node* node) 207 static inline int adjustedTabIndex(Node& node)
213 { 208 {
214 ASSERT(node); 209 return isNonFocusableFocusScopeOwner(node) ? 0 : node.tabIndex();
215 return isNonFocusableFocusScopeOwner(node) ? 0 : node->tabIndex();
216 } 210 }
217 211
218 static inline bool shouldVisit(Node* node) 212 static inline bool shouldVisit(Node& node)
219 { 213 {
220 ASSERT(node); 214 return (node.isElementNode() && toElement(node).isKeyboardFocusable()) || is NonFocusableFocusScopeOwner(node);
221 return (node->isElementNode() && toElement(node)->isKeyboardFocusable()) || isNonFocusableFocusScopeOwner(node);
222 } 215 }
223 216
224 FocusController::FocusController(Page* page) 217 FocusController::FocusController(Page* page)
225 : m_page(page) 218 : m_page(page)
226 , m_isActive(false) 219 , m_isActive(false)
227 , m_isFocused(false) 220 , m_isFocused(false)
228 , m_isChangingFocusedFrame(false) 221 , m_isChangingFocusedFrame(false)
229 { 222 {
230 } 223 }
231 224
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())- >document(), focused); 329 dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())- >document(), focused);
337 } 330 }
338 } 331 }
339 332
340 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusType type, Node* node) 333 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusType type, Node* node)
341 { 334 {
342 // The node we found might be a HTMLFrameOwnerElement, so descend down the t ree until we find either: 335 // The node we found might be a HTMLFrameOwnerElement, so descend down the t ree until we find either:
343 // 1) a focusable node, or 336 // 1) a focusable node, or
344 // 2) the deepest-nested HTMLFrameOwnerElement. 337 // 2) the deepest-nested HTMLFrameOwnerElement.
345 while (node && node->isFrameOwnerElement()) { 338 while (node && node->isFrameOwnerElement()) {
346 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(node); 339 HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*node);
347 if (!owner->contentFrame() || !owner->contentFrame()->isLocalFrame()) 340 if (!owner.contentFrame() || !owner.contentFrame()->isLocalFrame())
348 break; 341 break;
349 Node* foundNode = findFocusableNode(type, FocusNavigationScope::ownedByI Frame(owner), nullptr); 342 Node* foundNode = findFocusableNode(type, FocusNavigationScope::ownedByI Frame(owner), nullptr);
350 if (!foundNode) 343 if (!foundNode)
351 break; 344 break;
352 ASSERT(node != foundNode); 345 ASSERT(node != foundNode);
353 node = foundNode; 346 node = foundNode;
354 } 347 }
355 return node; 348 return node;
356 } 349 }
357 350
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 394
402 Node* currentNode = document->focusedElement(); 395 Node* currentNode = document->focusedElement();
403 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself 396 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself
404 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); 397 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled();
405 398
406 if (caretBrowsing && !currentNode) 399 if (caretBrowsing && !currentNode)
407 currentNode = frame->selection().start().deprecatedNode(); 400 currentNode = frame->selection().start().deprecatedNode();
408 401
409 document->updateLayoutIgnorePendingStylesheets(); 402 document->updateLayoutIgnorePendingStylesheets();
410 403
411 RefPtrWillBeRawPtr<Node> node = findFocusableNodeAcrossFocusScope(type, Focu sNavigationScope::focusNavigationScopeOf(currentNode ? currentNode : document), currentNode); 404 RefPtrWillBeRawPtr<Node> node = findFocusableNodeAcrossFocusScope(type, Focu sNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document) , currentNode);
412 405
413 if (!node) { 406 if (!node) {
414 // We didn't find a node to focus, so we should try to pass focus to Chr ome. 407 // We didn't find a node to focus, so we should try to pass focus to Chr ome.
415 if (!initialFocus && m_page->chrome().canTakeFocus(type)) { 408 if (!initialFocus && m_page->chrome().canTakeFocus(type)) {
416 document->setFocusedElement(nullptr); 409 document->setFocusedElement(nullptr);
417 setFocusedFrame(nullptr); 410 setFocusedFrame(nullptr);
418 m_page->chrome().takeFocus(type); 411 m_page->chrome().takeFocus(type);
419 return true; 412 return true;
420 } 413 }
421 414
422 // Chrome doesn't want focus, so we should wrap focus. 415 // Chrome doesn't want focus, so we should wrap focus.
423 if (!m_page->mainFrame()->isLocalFrame()) 416 if (!m_page->mainFrame()->isLocalFrame())
424 return false; 417 return false;
425 node = findFocusableNodeRecursively(type, FocusNavigationScope::focusNav igationScopeOf(m_page->deprecatedLocalMainFrame()->document()), nullptr); 418 node = findFocusableNodeRecursively(type, FocusNavigationScope::focusNav igationScopeOf(*m_page->deprecatedLocalMainFrame()->document()), nullptr);
426 node = findFocusableNodeDecendingDownIntoFrameDocument(type, node.get()) ; 419 node = findFocusableNodeDecendingDownIntoFrameDocument(type, node.get()) ;
427 420
428 if (!node) 421 if (!node)
429 return false; 422 return false;
430 } 423 }
431 424
432 ASSERT(node); 425 ASSERT(node);
433 426
434 if (node == document->focusedElement()) 427 if (node == document->focusedElement())
435 // Focus wrapped around to the same node. 428 // Focus wrapped around to the same node.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 VisibleSelection newSelection(position, position, DOWNSTREAM); 462 VisibleSelection newSelection(position, position, DOWNSTREAM);
470 frame->selection().setSelection(newSelection); 463 frame->selection().setSelection(newSelection);
471 } 464 }
472 465
473 element->focus(false, type); 466 element->focus(false, type);
474 return true; 467 return true;
475 } 468 }
476 469
477 Node* FocusController::findFocusableNodeAcrossFocusScope(FocusType type, FocusNa vigationScope scope, Node* currentNode) 470 Node* FocusController::findFocusableNodeAcrossFocusScope(FocusType type, FocusNa vigationScope scope, Node* currentNode)
478 { 471 {
479 ASSERT(!currentNode || !isNonFocusableShadowHost(currentNode)); 472 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode));
480 Node* found; 473 Node* found;
481 if (currentNode && type == FocusTypeForward && isKeyboardFocusableShadowHost (currentNode)) { 474 if (currentNode && type == FocusTypeForward && isKeyboardFocusableShadowHost (*currentNode)) {
482 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByShadowHost(currentNode), nullptr); 475 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByShadowHost(*currentNode), nullptr);
483 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableN odeRecursively(type, scope, currentNode); 476 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableN odeRecursively(type, scope, currentNode);
484 } else { 477 } else {
485 found = findFocusableNodeRecursively(type, scope, currentNode); 478 found = findFocusableNodeRecursively(type, scope, currentNode);
486 } 479 }
487 480
488 // If there's no focusable node to advance to, move up the focus scopes unti l we find one. 481 // If there's no focusable node to advance to, move up the focus scopes unti l we find one.
489 while (!found) { 482 while (!found) {
490 Node* owner = scope.owner(); 483 Node* owner = scope.owner();
491 if (!owner) 484 if (!owner)
492 break; 485 break;
493 scope = FocusNavigationScope::focusNavigationScopeOf(owner); 486 scope = FocusNavigationScope::focusNavigationScopeOf(*owner);
494 if (type == FocusTypeBackward && isKeyboardFocusableShadowHost(owner)) { 487 if (type == FocusTypeBackward && isKeyboardFocusableShadowHost(*owner)) {
495 found = owner; 488 found = owner;
496 break; 489 break;
497 } 490 }
498 found = findFocusableNodeRecursively(type, scope, owner); 491 found = findFocusableNodeRecursively(type, scope, owner);
499 } 492 }
500 found = findFocusableNodeDecendingDownIntoFrameDocument(type, found); 493 found = findFocusableNodeDecendingDownIntoFrameDocument(type, found);
501 return found; 494 return found;
502 } 495 }
503 496
504 Node* FocusController::findFocusableNodeRecursively(FocusType type, FocusNavigat ionScope scope, Node* start) 497 Node* FocusController::findFocusableNodeRecursively(FocusType type, FocusNavigat ionScope scope, Node* start)
505 { 498 {
506 // Starting node is exclusive. 499 // Starting node is exclusive.
507 Node* found = findFocusableNode(type, scope, start); 500 Node* foundOrNull = findFocusableNode(type, scope, start);
508 if (!found) 501 if (!foundOrNull)
509 return nullptr; 502 return nullptr;
503 Node& found = *foundOrNull;
510 if (type == FocusTypeForward) { 504 if (type == FocusTypeForward) {
511 if (!isNonFocusableFocusScopeOwner(found)) 505 if (!isNonFocusableFocusScopeOwner(found))
512 return found; 506 return &found;
513 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); 507 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr);
514 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo deRecursively(type, scope, found); 508 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo deRecursively(type, scope, &found);
515 } 509 }
516 ASSERT(type == FocusTypeBackward); 510 ASSERT(type == FocusTypeBackward);
517 if (isKeyboardFocusableShadowHost(found)) { 511 if (isKeyboardFocusableShadowHost(found)) {
518 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByShadowHost(found), nullptr); 512 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByShadowHost(found), nullptr);
519 return foundInInnerFocusScope ? foundInInnerFocusScope : found; 513 return foundInInnerFocusScope ? foundInInnerFocusScope : &found;
520 } 514 }
521 if (isNonFocusableFocusScopeOwner(found)) { 515 if (isNonFocusableFocusScopeOwner(found)) {
522 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); 516 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr);
523 return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNod eRecursively(type, scope, found); 517 return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNod eRecursively(type, scope, &found);
524 } 518 }
525 return found; 519 return &found;
526 } 520 }
527 521
528 Node* FocusController::findFocusableNode(FocusType type, FocusNavigationScope sc ope, Node* node) 522 Node* FocusController::findFocusableNode(FocusType type, FocusNavigationScope sc ope, Node* node)
529 { 523 {
530 return type == FocusTypeForward ? nextFocusableNode(scope, node) : previousF ocusableNode(scope, node); 524 return type == FocusTypeForward ? nextFocusableNode(scope, node) : previousF ocusableNode(scope, node);
531 } 525 }
532 526
533 Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, Focu sType type) 527 Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, Focu sType type)
534 { 528 {
535 // Search is inclusive of start 529 // Search is inclusive of start
536 for (Node* node = start; node; node = type == FocusTypeForward ? NodeTravers al::next(*node) : NodeTraversal::previous(*node)) { 530 for (Node* node = start; node; node = type == FocusTypeForward ? NodeTravers al::next(*node) : NodeTraversal::previous(*node)) {
537 if (shouldVisit(node) && adjustedTabIndex(node) == tabIndex) 531 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex)
538 return node; 532 return node;
539 } 533 }
540 return nullptr; 534 return nullptr;
541 } 535 }
542 536
543 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex) 537 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex)
544 { 538 {
545 // Search is inclusive of start 539 // Search is inclusive of start
546 int winningTabIndex = std::numeric_limits<short>::max() + 1; 540 int winningTabIndex = std::numeric_limits<short>::max() + 1;
547 Node* winner = nullptr; 541 Node* winner = nullptr;
548 for (Node& node : NodeTraversal::startsAt(start)) { 542 for (Node& node : NodeTraversal::startsAt(start)) {
549 int currentTabIndex = adjustedTabIndex(&node); 543 int currentTabIndex = adjustedTabIndex(node);
550 if (shouldVisit(&node) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) { 544 if (shouldVisit(node) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) {
551 winner = &node; 545 winner = &node;
552 winningTabIndex = currentTabIndex; 546 winningTabIndex = currentTabIndex;
553 } 547 }
554 } 548 }
555 549
556 return winner; 550 return winner;
557 } 551 }
558 552
559 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex) 553 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex)
560 { 554 {
561 // Search is inclusive of start 555 // Search is inclusive of start
562 int winningTabIndex = 0; 556 int winningTabIndex = 0;
563 Node* winner = nullptr; 557 Node* winner = nullptr;
564 for (Node* node = start; node; node = NodeTraversal::previous(*node)) { 558 for (Node* node = start; node; node = NodeTraversal::previous(*node)) {
565 int currentTabIndex = adjustedTabIndex(node); 559 int currentTabIndex = adjustedTabIndex(*node);
566 if (shouldVisit(node) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) { 560 if (shouldVisit(*node) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {
567 winner = node; 561 winner = node;
568 winningTabIndex = currentTabIndex; 562 winningTabIndex = currentTabIndex;
569 } 563 }
570 } 564 }
571 return winner; 565 return winner;
572 } 566 }
573 567
574 Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start ) 568 Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start )
575 { 569 {
576 if (start) { 570 if (start) {
577 int tabIndex = adjustedTabIndex(start); 571 int tabIndex = adjustedTabIndex(*start);
578 // If a node is excluded from the normal tabbing cycle, the next focusab le node is determined by tree order 572 // If a node is excluded from the normal tabbing cycle, the next focusab le node is determined by tree order
579 if (tabIndex < 0) { 573 if (tabIndex < 0) {
580 for (Node& node : NodeTraversal::startsAfter(*start)) { 574 for (Node& node : NodeTraversal::startsAfter(*start)) {
581 if (shouldVisit(&node) && adjustedTabIndex(&node) >= 0) 575 if (shouldVisit(node) && adjustedTabIndex(node) >= 0)
582 return &node; 576 return &node;
583 } 577 }
584 } else { 578 } else {
585 // First try to find a node with the same tabindex as start that com es after start in the scope. 579 // First try to find a node with the same tabindex as start that com es after start in the scope.
586 if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*st art), tabIndex, FocusTypeForward)) 580 if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*st art), tabIndex, FocusTypeForward))
587 return winner; 581 return winner;
588 } 582 }
589 if (!tabIndex) { 583 if (!tabIndex) {
590 // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order. 584 // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
591 return nullptr; 585 return nullptr;
592 } 586 }
593 } 587 }
594 588
595 // Look for the first node in the scope that: 589 // Look for the first node in the scope that:
596 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and 590 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
597 // 2) comes first in the scope, if there's a tie. 591 // 2) comes first in the scope, if there's a tie.
598 if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adj ustedTabIndex(start) : 0)) 592 if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adj ustedTabIndex(*start) : 0))
599 return winner; 593 return winner;
600 594
601 // There are no nodes with a tabindex greater than start's tabindex, 595 // There are no nodes with a tabindex greater than start's tabindex,
602 // so find the first node with a tabindex of 0. 596 // so find the first node with a tabindex of 0.
603 return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusTypeForward); 597 return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusTypeForward);
604 } 598 }
605 599
606 Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* s tart) 600 Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* s tart)
607 { 601 {
608 Node* last = nullptr; 602 Node* last = nullptr;
609 for (Node* node = scope.rootNode(); node; node = node->lastChild()) 603 for (Node* node = scope.rootNode(); node; node = node->lastChild())
610 last = node; 604 last = node;
611 ASSERT(last); 605 ASSERT(last);
612 606
613 // First try to find the last node in the scope that comes before start and has the same tabindex as start. 607 // First try to find the last node in the scope that comes before start and has the same tabindex as start.
614 // If start is null, find the last node in the scope with a tabindex of 0. 608 // If start is null, find the last node in the scope with a tabindex of 0.
615 Node* startingNode; 609 Node* startingNode;
616 int startingTabIndex; 610 int startingTabIndex;
617 if (start) { 611 if (start) {
618 startingNode = NodeTraversal::previous(*start); 612 startingNode = NodeTraversal::previous(*start);
619 startingTabIndex = adjustedTabIndex(start); 613 startingTabIndex = adjustedTabIndex(*start);
620 } else { 614 } else {
621 startingNode = last; 615 startingNode = last;
622 startingTabIndex = 0; 616 startingTabIndex = 0;
623 } 617 }
624 618
625 // However, if a node is excluded from the normal tabbing cycle, the previou s focusable node is determined by tree order 619 // However, if a node is excluded from the normal tabbing cycle, the previou s focusable node is determined by tree order
626 if (startingTabIndex < 0) { 620 if (startingTabIndex < 0) {
627 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no de)) { 621 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no de)) {
628 if (shouldVisit(node) && adjustedTabIndex(node) >= 0) 622 if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0)
629 return node; 623 return node;
630 } 624 }
631 } else { 625 } else {
632 if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIn dex, FocusTypeBackward)) 626 if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIn dex, FocusTypeBackward))
633 return winner; 627 return winner;
634 } 628 }
635 629
636 // There are no nodes before start with the same tabindex as start, so look for a node that: 630 // There are no nodes before start with the same tabindex as start, so look for a node that:
637 // 1) has the highest non-zero tabindex (that is less than start's tabindex) , and 631 // 1) has the highest non-zero tabindex (that is less than start's tabindex) , and
638 // 2) comes last in the scope, if there's a tie. 632 // 2) comes last in the scope, if there's a tie.
639 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num eric_limits<short>::max(); 633 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num eric_limits<short>::max();
640 return previousNodeWithLowerTabIndex(last, startingTabIndex); 634 return previousNodeWithLowerTabIndex(last, startingTabIndex);
641 } 635 }
642 636
643 static bool relinquishesEditingFocus(Node *node) 637 static bool relinquishesEditingFocus(const Element& element)
644 { 638 {
645 ASSERT(node); 639 ASSERT(element.hasEditableStyle());
646 ASSERT(node->hasEditableStyle()); 640 return element.document().frame() && element.rootEditableElement();
647 return node->document().frame() && node->rootEditableElement();
648 } 641 }
649 642
650 static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newF ocusedFrame, Node* newFocusedNode) 643 static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newF ocusedFrame, Node* newFocusedNode)
651 { 644 {
652 if (!oldFocusedFrame || !newFocusedFrame) 645 if (!oldFocusedFrame || !newFocusedFrame)
653 return; 646 return;
654 647
655 if (oldFocusedFrame->document() != newFocusedFrame->document()) 648 if (oldFocusedFrame->document() != newFocusedFrame->document())
656 return; 649 return;
657 650
(...skipping 21 matching lines...) Expand all
679 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr <Frame> newFocusedFrame, FocusType type) 672 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr <Frame> newFocusedFrame, FocusType type)
680 { 673 {
681 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame() ); 674 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame() );
682 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame ->document() : nullptr; 675 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame ->document() : nullptr;
683 676
684 Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : n ullptr; 677 Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : n ullptr;
685 if (element && oldFocusedElement == element) 678 if (element && oldFocusedElement == element)
686 return true; 679 return true;
687 680
688 // FIXME: Might want to disable this check for caretBrowsing 681 // FIXME: Might want to disable this check for caretBrowsing
689 if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !reli nquishesEditingFocus(oldFocusedElement)) 682 if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !reli nquishesEditingFocus(*oldFocusedElement))
690 return false; 683 return false;
691 684
692 m_page->chrome().client().willSetInputMethodState(); 685 m_page->chrome().client().willSetInputMethodState();
693 686
694 RefPtrWillBeRawPtr<Document> newDocument = nullptr; 687 RefPtrWillBeRawPtr<Document> newDocument = nullptr;
695 if (element) 688 if (element)
696 newDocument = &element->document(); 689 newDocument = &element->document();
697 else if (newFocusedFrame && newFocusedFrame->isLocalFrame()) 690 else if (newFocusedFrame && newFocusedFrame->isLocalFrame())
698 newDocument = toLocalFrame(newFocusedFrame.get())->document(); 691 newDocument = toLocalFrame(newFocusedFrame.get())->document();
699 692
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 return consumed; 921 return consumed;
929 } 922 }
930 923
931 void FocusController::trace(Visitor* visitor) 924 void FocusController::trace(Visitor* visitor)
932 { 925 {
933 visitor->trace(m_page); 926 visitor->trace(m_page);
934 visitor->trace(m_focusedFrame); 927 visitor->trace(m_focusedFrame);
935 } 928 }
936 929
937 } // namespace blink 930 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/page/FocusController.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698