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

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

Issue 1180843005: Change private API names and return type in FocusController (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: more conversion Created 5 years, 6 months 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 { 65 {
66 return isActiveShadowInsertionPoint(node) && toHTMLShadowElement(node).older ShadowRoot(); 66 return isActiveShadowInsertionPoint(node) && toHTMLShadowElement(node).older ShadowRoot();
67 } 67 }
68 68
69 class FocusNavigationScope { 69 class FocusNavigationScope {
70 STACK_ALLOCATED(); 70 STACK_ALLOCATED();
71 public: 71 public:
72 Node* rootNode() const; 72 Node* rootNode() const;
73 Element* owner() const; 73 Element* owner() const;
74 static FocusNavigationScope focusNavigationScopeOf(const Node&); 74 static FocusNavigationScope focusNavigationScopeOf(const Node&);
75 static FocusNavigationScope ownedByNonFocusableFocusScopeOwner(Node&); 75 static FocusNavigationScope ownedByNonFocusableFocusScopeOwner(Element&);
76 static FocusNavigationScope ownedByShadowHost(const Node&); 76 static FocusNavigationScope ownedByShadowHost(const Element&);
77 static FocusNavigationScope ownedByShadowInsertionPoint(HTMLShadowElement&); 77 static FocusNavigationScope ownedByShadowInsertionPoint(HTMLShadowElement&);
78 static FocusNavigationScope ownedByIFrame(const HTMLFrameOwnerElement&); 78 static FocusNavigationScope ownedByIFrame(const HTMLFrameOwnerElement&);
79 79
80 private: 80 private:
81 explicit FocusNavigationScope(TreeScope*); 81 explicit FocusNavigationScope(TreeScope*);
82 RawPtrWillBeMember<TreeScope> m_rootTreeScope; 82 RawPtrWillBeMember<TreeScope> m_rootTreeScope;
83 }; 83 };
84 84
85 // FIXME: Some of Node* return values and Node* arguments should be Element*. 85 // FIXME: Some of Node* return values and Node* arguments should be Element*.
86 86
(...skipping 24 matching lines...) Expand all
111 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(const Node& no de) 111 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(const Node& no de)
112 { 112 {
113 const Node* root = &node; 113 const Node* root = &node;
114 for (const Node* n = &node; n; n = n->parentNode()) 114 for (const Node* n = &node; n; n = n->parentNode())
115 root = n; 115 root = n;
116 // The result is not always a ShadowRoot nor a DocumentNode since 116 // The result is not always a ShadowRoot nor a DocumentNode since
117 // a starting node is in an orphaned tree in composed shadow tree. 117 // a starting node is in an orphaned tree in composed shadow tree.
118 return FocusNavigationScope(&root->treeScope()); 118 return FocusNavigationScope(&root->treeScope());
119 } 119 }
120 120
121 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(No de& node) 121 FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(El ement& element)
122 { 122 {
123 if (isShadowHost(node)) 123 if (isShadowHost(element))
124 return FocusNavigationScope::ownedByShadowHost(node); 124 return FocusNavigationScope::ownedByShadowHost(element);
125 ASSERT(isShadowInsertionPointFocusScopeOwner(node)); 125 ASSERT(isShadowInsertionPointFocusScopeOwner(element));
126 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (node)); 126 return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement (element));
127 } 127 }
128 128
129 FocusNavigationScope FocusNavigationScope::ownedByShadowHost(const Node& node) 129 FocusNavigationScope FocusNavigationScope::ownedByShadowHost(const Element& elem ent)
130 { 130 {
131 ASSERT(isShadowHost(node)); 131 ASSERT(isShadowHost(element));
132 return FocusNavigationScope(toElement(node).shadow()->youngestShadowRoot()); 132 return FocusNavigationScope(element.shadow()->youngestShadowRoot());
133 } 133 }
134 134
135 FocusNavigationScope FocusNavigationScope::ownedByIFrame(const HTMLFrameOwnerEle ment& frame) 135 FocusNavigationScope FocusNavigationScope::ownedByIFrame(const HTMLFrameOwnerEle ment& frame)
136 { 136 {
137 ASSERT(frame.contentFrame()); 137 ASSERT(frame.contentFrame());
138 ASSERT(frame.contentFrame()->isLocalFrame()); 138 ASSERT(frame.contentFrame()->isLocalFrame());
139 return FocusNavigationScope(toLocalFrame(frame.contentFrame())->document()); 139 return FocusNavigationScope(toLocalFrame(frame.contentFrame())->document());
140 } 140 }
141 141
142 FocusNavigationScope FocusNavigationScope::ownedByShadowInsertionPoint(HTMLShado wElement& shadowInsertionPoint) 142 FocusNavigationScope FocusNavigationScope::ownedByShadowInsertionPoint(HTMLShado wElement& shadowInsertionPoint)
(...skipping 15 matching lines...) Expand all
158 static inline void dispatchFocusEvent(const Document& document, Element& focused Element) 158 static inline void dispatchFocusEvent(const Document& document, Element& focused Element)
159 { 159 {
160 focusedElement.dispatchFocusEvent(0, WebFocusTypePage); 160 focusedElement.dispatchFocusEvent(0, WebFocusTypePage);
161 if (focusedElement == document.focusedElement()) { 161 if (focusedElement == document.focusedElement()) {
162 focusedElement.dispatchFocusInEvent(EventTypeNames::focusin, nullptr, We bFocusTypePage); 162 focusedElement.dispatchFocusInEvent(EventTypeNames::focusin, nullptr, We bFocusTypePage);
163 if (focusedElement == document.focusedElement()) 163 if (focusedElement == document.focusedElement())
164 focusedElement.dispatchFocusInEvent(EventTypeNames::DOMFocusIn, null ptr, WebFocusTypePage); 164 focusedElement.dispatchFocusInEvent(EventTypeNames::DOMFocusIn, null ptr, WebFocusTypePage);
165 } 165 }
166 } 166 }
167 167
168 static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused) 168 static inline void dispatchEventsOnWindowAndFocusedElement(Document* document, b ool focused)
169 { 169 {
170 ASSERT(document); 170 ASSERT(document);
171 // If we have a focused node we should dispatch blur on it before we blur th e window. 171 // If we have a focused element we should dispatch blur on it before we blur the window.
172 // If we have a focused node we should dispatch focus on it after we focus t he window. 172 // If we have a focused element we should dispatch focus on it after we focu s the window.
173 // https://bugs.webkit.org/show_bug.cgi?id=27105 173 // https://bugs.webkit.org/show_bug.cgi?id=27105
174 174
175 if (document->focusedElement() && isHTMLPlugInElement(document->focusedEleme nt())) 175 if (document->focusedElement() && isHTMLPlugInElement(document->focusedEleme nt()))
176 toHTMLPlugInElement(document->focusedElement())->setPluginFocus(focused) ; 176 toHTMLPlugInElement(document->focusedElement())->setPluginFocus(focused) ;
177 177
178 // Do not fire events while modal dialogs are up. See https://bugs.webkit.o rg/show_bug.cgi?id=33962 178 // Do not fire events while modal dialogs are up. See https://bugs.webkit.o rg/show_bug.cgi?id=33962
179 if (Page* page = document->page()) { 179 if (Page* page = document->page()) {
180 if (page->defersLoading()) 180 if (page->defersLoading())
181 return; 181 return;
182 } 182 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 if (!m_isFocused && focusedOrMainFrame()->isLocalFrame()) 339 if (!m_isFocused && focusedOrMainFrame()->isLocalFrame())
340 toLocalFrame(focusedOrMainFrame())->eventHandler().stopAutoscroll(); 340 toLocalFrame(focusedOrMainFrame())->eventHandler().stopAutoscroll();
341 341
342 if (!m_focusedFrame) 342 if (!m_focusedFrame)
343 setFocusedFrame(m_page->mainFrame()); 343 setFocusedFrame(m_page->mainFrame());
344 344
345 // setFocusedFrame above might reject to update m_focusedFrame, or 345 // setFocusedFrame above might reject to update m_focusedFrame, or
346 // m_focusedFrame might be changed by blur/focus event handlers. 346 // m_focusedFrame might be changed by blur/focus event handlers.
347 if (m_focusedFrame && m_focusedFrame->isLocalFrame() && toLocalFrame(m_focus edFrame.get())->view()) { 347 if (m_focusedFrame && m_focusedFrame->isLocalFrame() && toLocalFrame(m_focus edFrame.get())->view()) {
348 toLocalFrame(m_focusedFrame.get())->selection().setFocused(focused); 348 toLocalFrame(m_focusedFrame.get())->selection().setFocused(focused);
349 dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())- >document(), focused); 349 dispatchEventsOnWindowAndFocusedElement(toLocalFrame(m_focusedFrame.get( ))->document(), focused);
350 } 350 }
351 } 351 }
352 352
353 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(WebFocusT ype type, Node* node) 353 Element* FocusController::findFocusableElementDescendingDownIntoFrameDocument(We bFocusType type, Element* element)
354 { 354 {
355 // The node we found might be a HTMLFrameOwnerElement, so descend down the t ree until we find either: 355 // The element we found might be a HTMLFrameOwnerElement, so descend down th e tree until we find either:
356 // 1) a focusable node, or 356 // 1) a focusable element, or
357 // 2) the deepest-nested HTMLFrameOwnerElement. 357 // 2) the deepest-nested HTMLFrameOwnerElement.
358 while (node && node->isFrameOwnerElement()) { 358 while (element && element->isFrameOwnerElement()) {
359 HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*node); 359 HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*element);
360 if (!owner.contentFrame() || !owner.contentFrame()->isLocalFrame()) 360 if (!owner.contentFrame() || !owner.contentFrame()->isLocalFrame())
361 break; 361 break;
362 toLocalFrame(owner.contentFrame())->document()->updateLayoutIgnorePendin gStylesheets(); 362 toLocalFrame(owner.contentFrame())->document()->updateLayoutIgnorePendin gStylesheets();
363 Element* foundElement = findFocusableElement(type, FocusNavigationScope: :ownedByIFrame(owner), nullptr); 363 Element* foundElement = findFocusableElement(type, FocusNavigationScope: :ownedByIFrame(owner), nullptr);
364 if (!foundElement) 364 if (!foundElement)
365 break; 365 break;
366 ASSERT(node != foundElement); 366 ASSERT(element != foundElement);
367 node = foundElement; 367 element = foundElement;
368 } 368 }
369 return node; 369 return element;
370 } 370 }
371 371
372 bool FocusController::setInitialFocus(WebFocusType type) 372 bool FocusController::setInitialFocus(WebFocusType type)
373 { 373 {
374 bool didAdvanceFocus = advanceFocus(type, true); 374 bool didAdvanceFocus = advanceFocus(type, true);
375 375
376 // If focus is being set initially, accessibility needs to be informed that system focus has moved 376 // If focus is being set initially, accessibility needs to be informed that system focus has moved
377 // into the web area again, even if focus did not change within WebCore. Pos tNotification is called instead 377 // into the web area again, even if focus did not change within WebCore. Pos tNotification is called instead
378 // of handleFocusedUIElementChanged, because this will send the notification even if the element is the same. 378 // of handleFocusedUIElementChanged, because this will send the notification even if the element is the same.
379 if (focusedOrMainFrame()->isLocalFrame()) { 379 if (focusedOrMainFrame()->isLocalFrame()) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 415
416 Node* currentNode = document->focusedElement(); 416 Node* currentNode = document->focusedElement();
417 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself 417 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself
418 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); 418 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled();
419 419
420 if (caretBrowsing && !currentNode) 420 if (caretBrowsing && !currentNode)
421 currentNode = frame->selection().start().deprecatedNode(); 421 currentNode = frame->selection().start().deprecatedNode();
422 422
423 document->updateLayoutIgnorePendingStylesheets(); 423 document->updateLayoutIgnorePendingStylesheets();
424 424
425 RefPtrWillBeRawPtr<Node> node = findFocusableNodeAcrossFocusScopes(type, Foc usNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document ), currentNode); 425 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes( type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document), currentNode);
426 426
427 if (!node) { 427 if (!element) {
428 // We didn't find a node to focus, so we should try to pass focus to Chr ome. 428 // We didn't find an element to focus, so we should try to pass focus to Chrome.
429 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) { 429 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) {
430 document->setFocusedElement(nullptr); 430 document->setFocusedElement(nullptr);
431 setFocusedFrame(nullptr); 431 setFocusedFrame(nullptr);
432 m_page->chromeClient().takeFocus(type); 432 m_page->chromeClient().takeFocus(type);
433 return true; 433 return true;
434 } 434 }
435 435
436 // Chrome doesn't want focus, so we should wrap focus. 436 // Chrome doesn't want focus, so we should wrap focus.
437 if (!m_page->mainFrame()->isLocalFrame()) 437 if (!m_page->mainFrame()->isLocalFrame())
438 return false; 438 return false;
439 node = findFocusableElementRecursively(type, FocusNavigationScope::focus NavigationScopeOf(*m_page->deprecatedLocalMainFrame()->document()), nullptr); 439 element = findFocusableElementRecursively(type, FocusNavigationScope::fo cusNavigationScopeOf(*m_page->deprecatedLocalMainFrame()->document()), nullptr);
440 node = findFocusableNodeDecendingDownIntoFrameDocument(type, node.get()) ; 440 element = findFocusableElementDescendingDownIntoFrameDocument(type, elem ent.get());
441 441
442 if (!node) 442 if (!element)
443 return false; 443 return false;
444 } 444 }
445 445
446 ASSERT(node); 446 ASSERT(element);
447 447
448 if (node == document->focusedElement()) 448 if (element == document->focusedElement())
449 // Focus wrapped around to the same node. 449 // Focus wrapped around to the same node.
450 return true; 450 return true;
451 451
452 if (!node->isElementNode())
453 // FIXME: May need a way to focus a document here.
454 return false;
455
456 Element* element = toElement(node);
457 if (element->isFrameOwnerElement() && (!isHTMLPlugInElement(*element) || !el ement->isKeyboardFocusable())) { 452 if (element->isFrameOwnerElement() && (!isHTMLPlugInElement(*element) || !el ement->isKeyboardFocusable())) {
458 // We focus frames rather than frame owners. 453 // We focus frames rather than frame owners.
459 // FIXME: We should not focus frames that have no scrollbars, as focusin g them isn't useful to the user. 454 // FIXME: We should not focus frames that have no scrollbars, as focusin g them isn't useful to the user.
460 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element); 455 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element);
461 if (!owner->contentFrame()) 456 if (!owner->contentFrame())
462 return false; 457 return false;
463 458
464 document->setFocusedElement(nullptr); 459 document->setFocusedElement(nullptr);
465 setFocusedFrame(owner->contentFrame()); 460 setFocusedFrame(owner->contentFrame());
466 return true; 461 return true;
467 } 462 }
468 463
469 // FIXME: It would be nice to just be able to call setFocusedElement(node) 464 // FIXME: It would be nice to just be able to call setFocusedElement(node)
470 // here, but we can't do that because some elements (e.g. HTMLInputElement 465 // here, but we can't do that because some elements (e.g. HTMLInputElement
471 // and HTMLTextAreaElement) do extra work in their focus() methods. 466 // and HTMLTextAreaElement) do extra work in their focus() methods.
472 Document& newDocument = element->document(); 467 Document& newDocument = element->document();
473 468
474 if (&newDocument != document) { 469 if (&newDocument != document) {
475 // Focus is going away from this document, so clear the focused node. 470 // Focus is going away from this document, so clear the focused node.
476 document->setFocusedElement(nullptr); 471 document->setFocusedElement(nullptr);
477 } 472 }
478 473
479 setFocusedFrame(newDocument.frame()); 474 setFocusedFrame(newDocument.frame());
480 475
481 if (caretBrowsing) { 476 if (caretBrowsing) {
482 Position position = firstPositionInOrBeforeNode(element); 477 Position position = firstPositionInOrBeforeNode(element.get());
483 VisibleSelection newSelection(position, position, DOWNSTREAM); 478 VisibleSelection newSelection(position, position, DOWNSTREAM);
484 frame->selection().setSelection(newSelection); 479 frame->selection().setSelection(newSelection);
485 } 480 }
486 481
487 element->focus(false, type); 482 element->focus(false, type);
488 return true; 483 return true;
489 } 484 }
490 485
491 Node* FocusController::findFocusableNodeAcrossFocusScopes(WebFocusType type, con st FocusNavigationScope& scope, Node* currentNode) 486 Element* FocusController::findFocusableElementAcrossFocusScopes(WebFocusType typ e, const FocusNavigationScope& scope, Node* currentNode)
492 { 487 {
493 return (type == WebFocusTypeForward) ? 488 return (type == WebFocusTypeForward) ?
494 findFocusableNodeAcrossFocusScopesForward(scope, currentNode) : 489 findFocusableElementAcrossFocusScopesForward(scope, currentNode) :
495 findFocusableNodeAcrossFocusScopesBackward(scope, currentNode); 490 findFocusableElementAcrossFocusScopesBackward(scope, currentNode);
496 } 491 }
497 492
498 Node* FocusController::findFocusableNodeAcrossFocusScopesForward(const FocusNavi gationScope& scope, Node* currentNode) 493 Element* FocusController::findFocusableElementAcrossFocusScopesForward(const Foc usNavigationScope& scope, Node* currentNode)
499 { 494 {
500 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); 495 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode));
501 Node* found; 496 Element* found;
502 if (currentNode && isShadowHostWithoutCustomFocusLogic(*currentNode)) { 497 if (currentNode && isShadowHostWithoutCustomFocusLogic(*currentNode)) {
503 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos t(*currentNode); 498 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos t(*toElement(currentNode));
504 Node* foundInInnerFocusScope = findFocusableElementRecursivelyForward(in nerScope, nullptr); 499 Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward (innerScope, nullptr);
505 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableE lementRecursivelyForward(scope, currentNode); 500 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableE lementRecursivelyForward(scope, currentNode);
506 } else { 501 } else {
507 found = findFocusableElementRecursivelyForward(scope, currentNode); 502 found = findFocusableElementRecursivelyForward(scope, currentNode);
508 } 503 }
509 504
510 // If there's no focusable node to advance to, move up the focus scopes unti l we find one. 505 // If there's no focusable node to advance to, move up the focus scopes unti l we find one.
511 FocusNavigationScope currentScope = scope; 506 FocusNavigationScope currentScope = scope;
512 while (!found) { 507 while (!found) {
513 Node* owner = currentScope.owner(); 508 Element* owner = currentScope.owner();
514 if (!owner) 509 if (!owner)
515 break; 510 break;
516 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); 511 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner);
517 found = findFocusableElementRecursivelyForward(currentScope, owner); 512 found = findFocusableElementRecursivelyForward(currentScope, owner);
518 } 513 }
519 return findFocusableNodeDecendingDownIntoFrameDocument(WebFocusTypeForward, found); 514 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeForwa rd, found);
520 } 515 }
521 516
522 Node* FocusController::findFocusableNodeAcrossFocusScopesBackward(const FocusNav igationScope& scope, Node* currentNode) 517 Element* FocusController::findFocusableElementAcrossFocusScopesBackward(const Fo cusNavigationScope& scope, Node* currentNode)
523 { 518 {
524 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); 519 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode));
525 Node* found = findFocusableElementRecursivelyBackward(scope, currentNode); 520 Element* found = findFocusableElementRecursivelyBackward(scope, currentNode) ;
526 521
527 // If there's no focusable node to advance to, move up the focus scopes unti l we find one. 522 // If there's no focusable node to advance to, move up the focus scopes unti l we find one.
528 FocusNavigationScope currentScope = scope; 523 FocusNavigationScope currentScope = scope;
529 while (!found) { 524 while (!found) {
530 Node* owner = currentScope.owner(); 525 Element* owner = currentScope.owner();
531 if (!owner) 526 if (!owner)
532 break; 527 break;
533 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); 528 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner);
534 if (isKeyboardFocusableShadowHost(*owner) && !isShadowHostDelegatesFocus (*owner)) { 529 if (isKeyboardFocusableShadowHost(*owner) && !isShadowHostDelegatesFocus (*owner)) {
535 found = owner; 530 found = owner;
536 break; 531 break;
537 } 532 }
538 found = findFocusableElementRecursivelyBackward(currentScope, owner); 533 found = findFocusableElementRecursivelyBackward(currentScope, owner);
539 } 534 }
540 return findFocusableNodeDecendingDownIntoFrameDocument(WebFocusTypeBackward, found); 535 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeBackw ard, found);
541 } 536 }
542 537
543 Element* FocusController::findFocusableElementRecursively(WebFocusType type, con st FocusNavigationScope& scope, Node* start) 538 Element* FocusController::findFocusableElementRecursively(WebFocusType type, con st FocusNavigationScope& scope, Node* start)
544 { 539 {
545 return (type == WebFocusTypeForward) ? 540 return (type == WebFocusTypeForward) ?
546 findFocusableElementRecursivelyForward(scope, start) : 541 findFocusableElementRecursivelyForward(scope, start) :
547 findFocusableElementRecursivelyBackward(scope, start); 542 findFocusableElementRecursivelyBackward(scope, start);
548 } 543 }
549 544
550 Element* FocusController::findFocusableElementRecursivelyForward(const FocusNavi gationScope& scope, Node* start) 545 Element* FocusController::findFocusableElementRecursivelyForward(const FocusNavi gationScope& scope, Node* start)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos t(*found); 583 FocusNavigationScope innerScope = FocusNavigationScope::ownedByShadowHos t(*found);
589 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr); 584 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr);
590 if (foundInInnerFocusScope) 585 if (foundInInnerFocusScope)
591 return foundInInnerFocusScope; 586 return foundInInnerFocusScope;
592 if (isShadowHostDelegatesFocus(*found)) 587 if (isShadowHostDelegatesFocus(*found))
593 found = findFocusableElementRecursivelyBackward(scope, found); 588 found = findFocusableElementRecursivelyBackward(scope, found);
594 return found; 589 return found;
595 } 590 }
596 591
597 // Now |found| is on a non focusable scope owner (either shadow host or <sha dow>). 592 // Now |found| is on a non focusable scope owner (either shadow host or <sha dow>).
598 // Find focusable node in decendant scope. If not found, find next focusable node within the 593 // Find focusable node in descendant scope. If not found, find next focusabl e node within the
599 // current scope. 594 // current scope.
600 if (isNonFocusableFocusScopeOwner(*found)) { 595 if (isNonFocusableFocusScopeOwner(*found)) {
601 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa bleFocusScopeOwner(*found); 596 FocusNavigationScope innerScope = FocusNavigationScope::ownedByNonFocusa bleFocusScopeOwner(*found);
602 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr); 597 Element* foundInInnerFocusScope = findFocusableElementRecursivelyBackwar d(innerScope, nullptr);
603 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableEl ementRecursivelyBackward(scope, found); 598 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableEl ementRecursivelyBackward(scope, found);
604 } 599 }
605 600
606 return !isShadowHostDelegatesFocus(*found) ? found : findFocusableElementRec ursivelyBackward(scope, found); 601 return !isShadowHostDelegatesFocus(*found) ? found : findFocusableElementRec ursivelyBackward(scope, found);
607 } 602 }
608 603
609 static Node* findNodeWithExactTabIndex(Node* start, int tabIndex, WebFocusType t ype) 604 static Element* findElementWithExactTabIndex(Node* start, int tabIndex, WebFocus Type type)
610 { 605 {
611 // Search is inclusive of start 606 // Search is inclusive of start
612 for (Node* node = start; node; node = type == WebFocusTypeForward ? NodeTrav ersal::next(*node) : NodeTraversal::previous(*node)) { 607 for (Node* node = start; node; node = type == WebFocusTypeForward ? NodeTrav ersal::next(*node) : NodeTraversal::previous(*node)) {
613 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) 608 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex)
614 return node; 609 return toElement(node);
615 } 610 }
616 return nullptr; 611 return nullptr;
617 } 612 }
618 613
619 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex) 614 static Element* nextElementWithGreaterTabIndex(Node* start, int tabIndex)
620 { 615 {
621 // Search is inclusive of start 616 // Search is inclusive of start
622 int winningTabIndex = std::numeric_limits<short>::max() + 1; 617 int winningTabIndex = std::numeric_limits<short>::max() + 1;
623 Node* winner = nullptr; 618 Node* winner = nullptr;
624 for (Node& node : NodeTraversal::startsAt(start)) { 619 for (Node& node : NodeTraversal::startsAt(start)) {
625 int currentTabIndex = adjustedTabIndex(node); 620 int currentTabIndex = adjustedTabIndex(node);
626 if (shouldVisit(node) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) { 621 if (shouldVisit(node) && currentTabIndex > tabIndex && currentTabIndex < winningTabIndex) {
627 winner = &node; 622 winner = &node;
628 winningTabIndex = currentTabIndex; 623 winningTabIndex = currentTabIndex;
629 } 624 }
630 } 625 }
631 626 ASSERT(!winner || winner->isElementNode());
632 return winner; 627 return toElement(winner);
633 } 628 }
634 629
635 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex) 630 static Element* previousElementWithLowerTabIndex(Node* start, int tabIndex)
636 { 631 {
637 // Search is inclusive of start 632 // Search is inclusive of start
638 int winningTabIndex = 0; 633 int winningTabIndex = 0;
639 Node* winner = nullptr; 634 Node* winner = nullptr;
640 for (Node* node = start; node; node = NodeTraversal::previous(*node)) { 635 for (Node* node = start; node; node = NodeTraversal::previous(*node)) {
641 int currentTabIndex = adjustedTabIndex(*node); 636 int currentTabIndex = adjustedTabIndex(*node);
642 if (shouldVisit(*node) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) { 637 if (shouldVisit(*node) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {
643 winner = node; 638 winner = node;
644 winningTabIndex = currentTabIndex; 639 winningTabIndex = currentTabIndex;
645 } 640 }
646 } 641 }
647 return winner; 642 ASSERT(!winner || winner->isElementNode());
643 return toElement(winner);
648 } 644 }
649 645
650 static Node* nextFocusableNode(const FocusNavigationScope& scope, Node* start) 646 static Element* nextFocusableElement(const FocusNavigationScope& scope, Node* st art)
651 { 647 {
652 if (start) { 648 if (start) {
653 int tabIndex = adjustedTabIndex(*start); 649 int tabIndex = adjustedTabIndex(*start);
654 // If a node is excluded from the normal tabbing cycle, the next focusab le node is determined by tree order 650 // If a node is excluded from the normal tabbing cycle, the next focusab le node is determined by tree order
655 if (tabIndex < 0) { 651 if (tabIndex < 0) {
656 for (Node& node : NodeTraversal::startsAfter(*start)) { 652 for (Node& node : NodeTraversal::startsAfter(*start)) {
657 if (shouldVisit(node) && adjustedTabIndex(node) >= 0) 653 if (shouldVisit(node) && adjustedTabIndex(node) >= 0)
658 return &node; 654 return &toElement(node);
659 } 655 }
660 } else { 656 } else {
661 // First try to find a node with the same tabindex as start that com es after start in the scope. 657 // First try to find a node with the same tabindex as start that com es after start in the scope.
662 if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*st art), tabIndex, WebFocusTypeForward)) 658 if (Element* winner = findElementWithExactTabIndex(NodeTraversal::ne xt(*start), tabIndex, WebFocusTypeForward))
663 return winner; 659 return winner;
664 } 660 }
665 if (!tabIndex) { 661 if (!tabIndex) {
666 // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order. 662 // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
667 return nullptr; 663 return nullptr;
668 } 664 }
669 } 665 }
670 666
671 // Look for the first node in the scope that: 667 // Look for the first node in the scope that:
672 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and 668 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
673 // 2) comes first in the scope, if there's a tie. 669 // 2) comes first in the scope, if there's a tie.
674 if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adj ustedTabIndex(*start) : 0)) 670 if (Element* winner = nextElementWithGreaterTabIndex(scope.rootNode(), start ? adjustedTabIndex(*start) : 0))
675 return winner; 671 return winner;
676 672
677 // There are no nodes with a tabindex greater than start's tabindex, 673 // There are no nodes with a tabindex greater than start's tabindex,
678 // so find the first node with a tabindex of 0. 674 // so find the first node with a tabindex of 0.
679 return findNodeWithExactTabIndex(scope.rootNode(), 0, WebFocusTypeForward); 675 return findElementWithExactTabIndex(scope.rootNode(), 0, WebFocusTypeForward );
680 } 676 }
681 677
682 static Node* previousFocusableNode(const FocusNavigationScope& scope, Node* star t) 678 static Element* previousFocusableElement(const FocusNavigationScope& scope, Node * start)
683 { 679 {
684 Node* last = nullptr; 680 Node* last = nullptr;
685 for (Node* node = scope.rootNode(); node; node = node->lastChild()) 681 for (Node* node = scope.rootNode(); node; node = node->lastChild())
686 last = node; 682 last = node;
687 ASSERT(last); 683 ASSERT(last);
688 684
689 // First try to find the last node in the scope that comes before start and has the same tabindex as start. 685 // First try to find the last node in the scope that comes before start and has the same tabindex as start.
690 // If start is null, find the last node in the scope with a tabindex of 0. 686 // If start is null, find the last node in the scope with a tabindex of 0.
691 Node* startingNode; 687 Node* startingNode;
692 int startingTabIndex; 688 int startingTabIndex;
693 if (start) { 689 if (start) {
694 startingNode = NodeTraversal::previous(*start); 690 startingNode = NodeTraversal::previous(*start);
695 startingTabIndex = adjustedTabIndex(*start); 691 startingTabIndex = adjustedTabIndex(*start);
696 } else { 692 } else {
697 startingNode = last; 693 startingNode = last;
698 startingTabIndex = 0; 694 startingTabIndex = 0;
699 } 695 }
700 696
701 // However, if a node is excluded from the normal tabbing cycle, the previou s focusable node is determined by tree order 697 // However, if a node is excluded from the normal tabbing cycle, the previou s focusable node is determined by tree order
702 if (startingTabIndex < 0) { 698 if (startingTabIndex < 0) {
703 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no de)) { 699 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no de)) {
704 if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0) 700 if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0)
705 return node; 701 return toElement(node);
706 } 702 }
707 } else { 703 } else {
708 if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIn dex, WebFocusTypeBackward)) 704 if (Element* winner = findElementWithExactTabIndex(startingNode, startin gTabIndex, WebFocusTypeBackward))
709 return winner; 705 return winner;
710 } 706 }
711 707
712 // There are no nodes before start with the same tabindex as start, so look for a node that: 708 // There are no nodes before start with the same tabindex as start, so look for a node that:
713 // 1) has the highest non-zero tabindex (that is less than start's tabindex) , and 709 // 1) has the highest non-zero tabindex (that is less than start's tabindex) , and
714 // 2) comes last in the scope, if there's a tie. 710 // 2) comes last in the scope, if there's a tie.
715 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num eric_limits<short>::max(); 711 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num eric_limits<short>::max();
716 return previousNodeWithLowerTabIndex(last, startingTabIndex); 712 return previousElementWithLowerTabIndex(last, startingTabIndex);
717 } 713 }
718 714
719 Element* FocusController::findFocusableElement(WebFocusType type, Node& node) 715 Element* FocusController::findFocusableElement(WebFocusType type, Node& node)
720 { 716 {
721 // FIXME: No spacial navigation code yet. 717 // FIXME: No spacial navigation code yet.
722 ASSERT(type == WebFocusTypeForward || type == WebFocusTypeBackward); 718 ASSERT(type == WebFocusTypeForward || type == WebFocusTypeBackward);
723 Node* found = findFocusableNodeAcrossFocusScopes(type, FocusNavigationScope: :focusNavigationScopeOf(node), &node); 719 Element* found = findFocusableElementAcrossFocusScopes(type, FocusNavigation Scope::focusNavigationScopeOf(node), &node);
724 ASSERT(!found || found->isElementNode()); 720 return found;
725 return toElement(found);
726 } 721 }
727 722
728 Element* FocusController::findFocusableElement(WebFocusType type, const FocusNav igationScope& scope, Node* node) 723 Element* FocusController::findFocusableElement(WebFocusType type, const FocusNav igationScope& scope, Node* node)
729 { 724 {
730 Node* found = (type == WebFocusTypeForward) ? nextFocusableNode(scope, node) : previousFocusableNode(scope, node); 725 Element* found = (type == WebFocusTypeForward) ? nextFocusableElement(scope, node) : previousFocusableElement(scope, node);
731 ASSERT(!found || found->isElementNode()); 726 return found;
732 return toElement(found);
733 } 727 }
734 728
735 static bool relinquishesEditingFocus(const Element& element) 729 static bool relinquishesEditingFocus(const Element& element)
736 { 730 {
737 ASSERT(element.hasEditableStyle()); 731 ASSERT(element.hasEditableStyle());
738 return element.document().frame() && element.rootEditableElement(); 732 return element.document().frame() && element.rootEditableElement();
739 } 733 }
740 734
741 static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newF ocusedFrame, Node* newFocusedNode) 735 static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newF ocusedFrame, Element* newFocusedElement)
742 { 736 {
743 if (!oldFocusedFrame || !newFocusedFrame) 737 if (!oldFocusedFrame || !newFocusedFrame)
744 return; 738 return;
745 739
746 if (oldFocusedFrame->document() != newFocusedFrame->document()) 740 if (oldFocusedFrame->document() != newFocusedFrame->document())
747 return; 741 return;
748 742
749 FrameSelection& selection = oldFocusedFrame->selection(); 743 FrameSelection& selection = oldFocusedFrame->selection();
750 if (selection.isNone()) 744 if (selection.isNone())
751 return; 745 return;
752 746
753 bool caretBrowsing = oldFocusedFrame->settings()->caretBrowsingEnabled(); 747 bool caretBrowsing = oldFocusedFrame->settings()->caretBrowsingEnabled();
754 if (caretBrowsing) 748 if (caretBrowsing)
755 return; 749 return;
756 750
757 Node* selectionStartNode = selection.selection().start().deprecatedNode(); 751 Node* selectionStartNode = selection.selection().start().deprecatedNode();
758 if (selectionStartNode == newFocusedNode || selectionStartNode->isDescendant Of(newFocusedNode)) 752 if (selectionStartNode == newFocusedElement || selectionStartNode->isDescend antOf(newFocusedElement))
759 return; 753 return;
760 754
761 if (!enclosingTextFormControl(selectionStartNode)) 755 if (!enclosingTextFormControl(selectionStartNode))
762 return; 756 return;
763 757
764 if (selectionStartNode->isInShadowTree() && selectionStartNode->shadowHost() == newFocusedNode) 758 if (selectionStartNode->isInShadowTree() && selectionStartNode->shadowHost() == newFocusedElement)
765 return; 759 return;
766 760
767 selection.clear(); 761 selection.clear();
768 } 762 }
769 763
770 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr <Frame> newFocusedFrame, WebFocusType type) 764 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr <Frame> newFocusedFrame, WebFocusType type)
771 { 765 {
772 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame() ); 766 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame() );
773 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame ->document() : nullptr; 767 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame ->document() : nullptr;
774 768
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 return consumed; 1013 return consumed;
1020 } 1014 }
1021 1015
1022 DEFINE_TRACE(FocusController) 1016 DEFINE_TRACE(FocusController)
1023 { 1017 {
1024 visitor->trace(m_page); 1018 visitor->trace(m_page);
1025 visitor->trace(m_focusedFrame); 1019 visitor->trace(m_focusedFrame);
1026 } 1020 }
1027 1021
1028 } // namespace blink 1022 } // 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