| OLD | NEW |
| 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 if (focusedElement == document->focusedElement()) | 168 if (focusedElement == document->focusedElement()) |
| 169 focusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOu
t, nullptr); | 169 focusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOu
t, nullptr); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 if (LocalDOMWindow* window = document->domWindow()) | 173 if (LocalDOMWindow* window = document->domWindow()) |
| 174 window->dispatchEvent(Event::create(focused ? EventTypeNames::focus : Ev
entTypeNames::blur)); | 174 window->dispatchEvent(Event::create(focused ? EventTypeNames::focus : Ev
entTypeNames::blur)); |
| 175 if (focused && document->focusedElement()) { | 175 if (focused && document->focusedElement()) { |
| 176 RefPtrWillBeRawPtr<Element> focusedElement(document->focusedElement()); | 176 RefPtrWillBeRawPtr<Element> focusedElement(document->focusedElement()); |
| 177 focusedElement->setFocus(true); | 177 focusedElement->setFocus(true); |
| 178 focusedElement->dispatchFocusEvent(0, FocusTypePage); | 178 focusedElement->dispatchFocusEvent(0, WebFocusTypePage); |
| 179 if (focusedElement == document->focusedElement()) { | 179 if (focusedElement == document->focusedElement()) { |
| 180 document->focusedElement()->dispatchFocusInEvent(EventTypeNames::foc
usin, nullptr, FocusTypePage); | 180 document->focusedElement()->dispatchFocusInEvent(EventTypeNames::foc
usin, nullptr, WebFocusTypePage); |
| 181 if (focusedElement == document->focusedElement()) | 181 if (focusedElement == document->focusedElement()) |
| 182 document->focusedElement()->dispatchFocusInEvent(EventTypeNames:
:DOMFocusIn, nullptr, FocusTypePage); | 182 document->focusedElement()->dispatchFocusInEvent(EventTypeNames:
:DOMFocusIn, nullptr, WebFocusTypePage); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 static inline bool hasCustomFocusLogic(const Element& element) | 187 static inline bool hasCustomFocusLogic(const Element& element) |
| 188 { | 188 { |
| 189 return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic
(); | 189 return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic
(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 #if ENABLE(ASSERT) | 192 #if ENABLE(ASSERT) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 focusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFoc
usOut, nullptr); | 291 focusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFoc
usOut, nullptr); |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 } | 294 } |
| 295 | 295 |
| 296 RefPtrWillBeRawPtr<LocalFrame> newFocusedFrame = (frame && frame->isLocalFra
me()) ? toLocalFrame(frame.get()) : nullptr; | 296 RefPtrWillBeRawPtr<LocalFrame> newFocusedFrame = (frame && frame->isLocalFra
me()) ? toLocalFrame(frame.get()) : nullptr; |
| 297 if (newFocusedFrame && newFocusedFrame->view()) { | 297 if (newFocusedFrame && newFocusedFrame->view()) { |
| 298 RefPtrWillBeRawPtr<Document> document = newFocusedFrame->document(); | 298 RefPtrWillBeRawPtr<Document> document = newFocusedFrame->document(); |
| 299 Element* focusedElement = document ? document->focusedElement() : nullpt
r; | 299 Element* focusedElement = document ? document->focusedElement() : nullpt
r; |
| 300 if (focusedElement) { | 300 if (focusedElement) { |
| 301 focusedElement->dispatchFocusEvent(0, FocusTypePage); | 301 focusedElement->dispatchFocusEvent(0, WebFocusTypePage); |
| 302 if (focusedElement == document->focusedElement()) { | 302 if (focusedElement == document->focusedElement()) { |
| 303 document->focusedElement()->dispatchFocusInEvent(EventTypeNames:
:focusin, nullptr, FocusTypePage); | 303 document->focusedElement()->dispatchFocusInEvent(EventTypeNames:
:focusin, nullptr, WebFocusTypePage); |
| 304 if (focusedElement == document->focusedElement()) | 304 if (focusedElement == document->focusedElement()) |
| 305 document->focusedElement()->dispatchFocusInEvent(EventTypeNa
mes::DOMFocusIn, nullptr, FocusTypePage); | 305 document->focusedElement()->dispatchFocusInEvent(EventTypeNa
mes::DOMFocusIn, nullptr, WebFocusTypePage); |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 } | 308 } |
| 309 | 309 |
| 310 setFocusedFrame(frame); | 310 setFocusedFrame(frame); |
| 311 } | 311 } |
| 312 | 312 |
| 313 Frame* FocusController::focusedOrMainFrame() const | 313 Frame* FocusController::focusedOrMainFrame() const |
| 314 { | 314 { |
| 315 if (Frame* frame = focusedFrame()) | 315 if (Frame* frame = focusedFrame()) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 339 setFocusedFrame(m_page->mainFrame()); | 339 setFocusedFrame(m_page->mainFrame()); |
| 340 | 340 |
| 341 // setFocusedFrame above might reject to update m_focusedFrame, or | 341 // setFocusedFrame above might reject to update m_focusedFrame, or |
| 342 // m_focusedFrame might be changed by blur/focus event handlers. | 342 // m_focusedFrame might be changed by blur/focus event handlers. |
| 343 if (m_focusedFrame && m_focusedFrame->isLocalFrame() && toLocalFrame(m_focus
edFrame.get())->view()) { | 343 if (m_focusedFrame && m_focusedFrame->isLocalFrame() && toLocalFrame(m_focus
edFrame.get())->view()) { |
| 344 toLocalFrame(m_focusedFrame.get())->selection().setFocused(focused); | 344 toLocalFrame(m_focusedFrame.get())->selection().setFocused(focused); |
| 345 dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())-
>document(), focused); | 345 dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())-
>document(), focused); |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 | 348 |
| 349 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusType
type, Node* node) | 349 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(WebFocusT
ype type, Node* node) |
| 350 { | 350 { |
| 351 // The node we found might be a HTMLFrameOwnerElement, so descend down the t
ree until we find either: | 351 // The node we found might be a HTMLFrameOwnerElement, so descend down the t
ree until we find either: |
| 352 // 1) a focusable node, or | 352 // 1) a focusable node, or |
| 353 // 2) the deepest-nested HTMLFrameOwnerElement. | 353 // 2) the deepest-nested HTMLFrameOwnerElement. |
| 354 while (node && node->isFrameOwnerElement()) { | 354 while (node && node->isFrameOwnerElement()) { |
| 355 HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*node); | 355 HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*node); |
| 356 if (!owner.contentFrame() || !owner.contentFrame()->isLocalFrame()) | 356 if (!owner.contentFrame() || !owner.contentFrame()->isLocalFrame()) |
| 357 break; | 357 break; |
| 358 toLocalFrame(owner.contentFrame())->document()->updateLayoutIgnorePendin
gStylesheets(); | 358 toLocalFrame(owner.contentFrame())->document()->updateLayoutIgnorePendin
gStylesheets(); |
| 359 Node* foundNode = findFocusableNode(type, FocusNavigationScope::ownedByI
Frame(owner), nullptr); | 359 Node* foundNode = findFocusableNode(type, FocusNavigationScope::ownedByI
Frame(owner), nullptr); |
| 360 if (!foundNode) | 360 if (!foundNode) |
| 361 break; | 361 break; |
| 362 ASSERT(node != foundNode); | 362 ASSERT(node != foundNode); |
| 363 node = foundNode; | 363 node = foundNode; |
| 364 } | 364 } |
| 365 return node; | 365 return node; |
| 366 } | 366 } |
| 367 | 367 |
| 368 bool FocusController::setInitialFocus(FocusType type) | 368 bool FocusController::setInitialFocus(WebFocusType type) |
| 369 { | 369 { |
| 370 bool didAdvanceFocus = advanceFocus(type, true); | 370 bool didAdvanceFocus = advanceFocus(type, true); |
| 371 | 371 |
| 372 // If focus is being set initially, accessibility needs to be informed that
system focus has moved | 372 // If focus is being set initially, accessibility needs to be informed that
system focus has moved |
| 373 // into the web area again, even if focus did not change within WebCore. Pos
tNotification is called instead | 373 // into the web area again, even if focus did not change within WebCore. Pos
tNotification is called instead |
| 374 // of handleFocusedUIElementChanged, because this will send the notification
even if the element is the same. | 374 // of handleFocusedUIElementChanged, because this will send the notification
even if the element is the same. |
| 375 if (focusedOrMainFrame()->isLocalFrame()) { | 375 if (focusedOrMainFrame()->isLocalFrame()) { |
| 376 Document* document = toLocalFrame(focusedOrMainFrame())->document(); | 376 Document* document = toLocalFrame(focusedOrMainFrame())->document(); |
| 377 if (AXObjectCache* cache = document->existingAXObjectCache()) | 377 if (AXObjectCache* cache = document->existingAXObjectCache()) |
| 378 cache->handleInitialFocus(); | 378 cache->handleInitialFocus(); |
| 379 } | 379 } |
| 380 | 380 |
| 381 return didAdvanceFocus; | 381 return didAdvanceFocus; |
| 382 } | 382 } |
| 383 | 383 |
| 384 bool FocusController::advanceFocus(FocusType type, bool initialFocus) | 384 bool FocusController::advanceFocus(WebFocusType type, bool initialFocus) |
| 385 { | 385 { |
| 386 switch (type) { | 386 switch (type) { |
| 387 case FocusTypeForward: | 387 case WebFocusTypeForward: |
| 388 case FocusTypeBackward: | 388 case WebFocusTypeBackward: |
| 389 return advanceFocusInDocumentOrder(type, initialFocus); | 389 return advanceFocusInDocumentOrder(type, initialFocus); |
| 390 case FocusTypeLeft: | 390 case WebFocusTypeLeft: |
| 391 case FocusTypeRight: | 391 case WebFocusTypeRight: |
| 392 case FocusTypeUp: | 392 case WebFocusTypeUp: |
| 393 case FocusTypeDown: | 393 case WebFocusTypeDown: |
| 394 return advanceFocusDirectionally(type); | 394 return advanceFocusDirectionally(type); |
| 395 default: | 395 default: |
| 396 ASSERT_NOT_REACHED(); | 396 ASSERT_NOT_REACHED(); |
| 397 } | 397 } |
| 398 | 398 |
| 399 return false; | 399 return false; |
| 400 } | 400 } |
| 401 | 401 |
| 402 bool FocusController::advanceFocusInDocumentOrder(FocusType type, bool initialFo
cus) | 402 bool FocusController::advanceFocusInDocumentOrder(WebFocusType type, bool initia
lFocus) |
| 403 { | 403 { |
| 404 // FIXME: Focus advancement won't work with externally rendered frames until
after | 404 // FIXME: Focus advancement won't work with externally rendered frames until
after |
| 405 // inter-frame focus control is moved out of Blink. | 405 // inter-frame focus control is moved out of Blink. |
| 406 if (!focusedOrMainFrame()->isLocalFrame()) | 406 if (!focusedOrMainFrame()->isLocalFrame()) |
| 407 return false; | 407 return false; |
| 408 LocalFrame* frame = toLocalFrame(focusedOrMainFrame()); | 408 LocalFrame* frame = toLocalFrame(focusedOrMainFrame()); |
| 409 ASSERT(frame); | 409 ASSERT(frame); |
| 410 Document* document = frame->document(); | 410 Document* document = frame->document(); |
| 411 | 411 |
| 412 Node* currentNode = document->focusedElement(); | 412 Node* currentNode = document->focusedElement(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 if (caretBrowsing) { | 477 if (caretBrowsing) { |
| 478 Position position = firstPositionInOrBeforeNode(element); | 478 Position position = firstPositionInOrBeforeNode(element); |
| 479 VisibleSelection newSelection(position, position, DOWNSTREAM); | 479 VisibleSelection newSelection(position, position, DOWNSTREAM); |
| 480 frame->selection().setSelection(newSelection); | 480 frame->selection().setSelection(newSelection); |
| 481 } | 481 } |
| 482 | 482 |
| 483 element->focus(false, type); | 483 element->focus(false, type); |
| 484 return true; | 484 return true; |
| 485 } | 485 } |
| 486 | 486 |
| 487 Node* FocusController::findFocusableNodeAcrossFocusScope(FocusType type, const F
ocusNavigationScope& scope, Node* currentNode) | 487 Node* FocusController::findFocusableNodeAcrossFocusScope(WebFocusType type, cons
t FocusNavigationScope& scope, Node* currentNode) |
| 488 { | 488 { |
| 489 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); | 489 ASSERT(!currentNode || !isNonFocusableShadowHost(*currentNode)); |
| 490 Node* found; | 490 Node* found; |
| 491 if (currentNode && type == FocusTypeForward && isKeyboardFocusableShadowHost
(*currentNode)) { | 491 if (currentNode && type == WebFocusTypeForward && isKeyboardFocusableShadowH
ost(*currentNode)) { |
| 492 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByShadowHost(*currentNode), nullptr); | 492 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByShadowHost(*currentNode), nullptr); |
| 493 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableN
odeRecursively(type, scope, currentNode); | 493 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableN
odeRecursively(type, scope, currentNode); |
| 494 } else { | 494 } else { |
| 495 found = findFocusableNodeRecursively(type, scope, currentNode); | 495 found = findFocusableNodeRecursively(type, scope, currentNode); |
| 496 } | 496 } |
| 497 | 497 |
| 498 // If there's no focusable node to advance to, move up the focus scopes unti
l we find one. | 498 // If there's no focusable node to advance to, move up the focus scopes unti
l we find one. |
| 499 FocusNavigationScope currentScope = scope; | 499 FocusNavigationScope currentScope = scope; |
| 500 while (!found) { | 500 while (!found) { |
| 501 Node* owner = currentScope.owner(); | 501 Node* owner = currentScope.owner(); |
| 502 if (!owner) | 502 if (!owner) |
| 503 break; | 503 break; |
| 504 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); | 504 currentScope = FocusNavigationScope::focusNavigationScopeOf(*owner); |
| 505 if (type == FocusTypeBackward && isKeyboardFocusableShadowHost(*owner))
{ | 505 if (type == WebFocusTypeBackward && isKeyboardFocusableShadowHost(*owner
)) { |
| 506 found = owner; | 506 found = owner; |
| 507 break; | 507 break; |
| 508 } | 508 } |
| 509 found = findFocusableNodeRecursively(type, currentScope, owner); | 509 found = findFocusableNodeRecursively(type, currentScope, owner); |
| 510 } | 510 } |
| 511 found = findFocusableNodeDecendingDownIntoFrameDocument(type, found); | 511 found = findFocusableNodeDecendingDownIntoFrameDocument(type, found); |
| 512 return found; | 512 return found; |
| 513 } | 513 } |
| 514 | 514 |
| 515 Node* FocusController::findFocusableNodeRecursively(FocusType type, const FocusN
avigationScope& scope, Node* start) | 515 Node* FocusController::findFocusableNodeRecursively(WebFocusType type, const Foc
usNavigationScope& scope, Node* start) |
| 516 { | 516 { |
| 517 // Starting node is exclusive. | 517 // Starting node is exclusive. |
| 518 Node* foundOrNull = findFocusableNode(type, scope, start); | 518 Node* foundOrNull = findFocusableNode(type, scope, start); |
| 519 if (!foundOrNull) | 519 if (!foundOrNull) |
| 520 return nullptr; | 520 return nullptr; |
| 521 Node& found = *foundOrNull; | 521 Node& found = *foundOrNull; |
| 522 if (type == FocusTypeForward) { | 522 if (type == WebFocusTypeForward) { |
| 523 if (!isNonFocusableFocusScopeOwner(found)) | 523 if (!isNonFocusableFocusScopeOwner(found)) |
| 524 return &found; | 524 return &found; |
| 525 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); | 525 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); |
| 526 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo
deRecursively(type, scope, &found); | 526 return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNo
deRecursively(type, scope, &found); |
| 527 } | 527 } |
| 528 ASSERT(type == FocusTypeBackward); | 528 ASSERT(type == WebFocusTypeBackward); |
| 529 if (isKeyboardFocusableShadowHost(found)) { | 529 if (isKeyboardFocusableShadowHost(found)) { |
| 530 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByShadowHost(found), nullptr); | 530 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByShadowHost(found), nullptr); |
| 531 return foundInInnerFocusScope ? foundInInnerFocusScope : &found; | 531 return foundInInnerFocusScope ? foundInInnerFocusScope : &found; |
| 532 } | 532 } |
| 533 if (isNonFocusableFocusScopeOwner(found)) { | 533 if (isNonFocusableFocusScopeOwner(found)) { |
| 534 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); | 534 Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusN
avigationScope::ownedByNonFocusableFocusScopeOwner(found), nullptr); |
| 535 return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNod
eRecursively(type, scope, &found); | 535 return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNod
eRecursively(type, scope, &found); |
| 536 } | 536 } |
| 537 return &found; | 537 return &found; |
| 538 } | 538 } |
| 539 | 539 |
| 540 Node* FocusController::findFocusableNode(FocusType type, const FocusNavigationSc
ope& scope, Node* node) | 540 Node* FocusController::findFocusableNode(WebFocusType type, const FocusNavigatio
nScope& scope, Node* node) |
| 541 { | 541 { |
| 542 return type == FocusTypeForward ? nextFocusableNode(scope, node) : previousF
ocusableNode(scope, node); | 542 return type == WebFocusTypeForward ? nextFocusableNode(scope, node) : previo
usFocusableNode(scope, node); |
| 543 } | 543 } |
| 544 | 544 |
| 545 Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, Focu
sType type) | 545 Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, WebF
ocusType type) |
| 546 { | 546 { |
| 547 // Search is inclusive of start | 547 // Search is inclusive of start |
| 548 for (Node* node = start; node; node = type == FocusTypeForward ? NodeTravers
al::next(*node) : NodeTraversal::previous(*node)) { | 548 for (Node* node = start; node; node = type == WebFocusTypeForward ? NodeTrav
ersal::next(*node) : NodeTraversal::previous(*node)) { |
| 549 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) | 549 if (shouldVisit(*node) && adjustedTabIndex(*node) == tabIndex) |
| 550 return node; | 550 return node; |
| 551 } | 551 } |
| 552 return nullptr; | 552 return nullptr; |
| 553 } | 553 } |
| 554 | 554 |
| 555 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex) | 555 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex) |
| 556 { | 556 { |
| 557 // Search is inclusive of start | 557 // Search is inclusive of start |
| 558 int winningTabIndex = std::numeric_limits<short>::max() + 1; | 558 int winningTabIndex = std::numeric_limits<short>::max() + 1; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 588 if (start) { | 588 if (start) { |
| 589 int tabIndex = adjustedTabIndex(*start); | 589 int tabIndex = adjustedTabIndex(*start); |
| 590 // If a node is excluded from the normal tabbing cycle, the next focusab
le node is determined by tree order | 590 // If a node is excluded from the normal tabbing cycle, the next focusab
le node is determined by tree order |
| 591 if (tabIndex < 0) { | 591 if (tabIndex < 0) { |
| 592 for (Node& node : NodeTraversal::startsAfter(*start)) { | 592 for (Node& node : NodeTraversal::startsAfter(*start)) { |
| 593 if (shouldVisit(node) && adjustedTabIndex(node) >= 0) | 593 if (shouldVisit(node) && adjustedTabIndex(node) >= 0) |
| 594 return &node; | 594 return &node; |
| 595 } | 595 } |
| 596 } else { | 596 } else { |
| 597 // First try to find a node with the same tabindex as start that com
es after start in the scope. | 597 // First try to find a node with the same tabindex as start that com
es after start in the scope. |
| 598 if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*st
art), tabIndex, FocusTypeForward)) | 598 if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*st
art), tabIndex, WebFocusTypeForward)) |
| 599 return winner; | 599 return winner; |
| 600 } | 600 } |
| 601 if (!tabIndex) { | 601 if (!tabIndex) { |
| 602 // We've reached the last node in the document with a tabindex of 0.
This is the end of the tabbing order. | 602 // We've reached the last node in the document with a tabindex of 0.
This is the end of the tabbing order. |
| 603 return nullptr; | 603 return nullptr; |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| 607 // Look for the first node in the scope that: | 607 // Look for the first node in the scope that: |
| 608 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if
start is null), and | 608 // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if
start is null), and |
| 609 // 2) comes first in the scope, if there's a tie. | 609 // 2) comes first in the scope, if there's a tie. |
| 610 if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adj
ustedTabIndex(*start) : 0)) | 610 if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adj
ustedTabIndex(*start) : 0)) |
| 611 return winner; | 611 return winner; |
| 612 | 612 |
| 613 // There are no nodes with a tabindex greater than start's tabindex, | 613 // There are no nodes with a tabindex greater than start's tabindex, |
| 614 // so find the first node with a tabindex of 0. | 614 // so find the first node with a tabindex of 0. |
| 615 return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusTypeForward); | 615 return findNodeWithExactTabIndex(scope.rootNode(), 0, WebFocusTypeForward); |
| 616 } | 616 } |
| 617 | 617 |
| 618 Node* FocusController::previousFocusableNode(const FocusNavigationScope& scope,
Node* start) | 618 Node* FocusController::previousFocusableNode(const FocusNavigationScope& scope,
Node* start) |
| 619 { | 619 { |
| 620 Node* last = nullptr; | 620 Node* last = nullptr; |
| 621 for (Node* node = scope.rootNode(); node; node = node->lastChild()) | 621 for (Node* node = scope.rootNode(); node; node = node->lastChild()) |
| 622 last = node; | 622 last = node; |
| 623 ASSERT(last); | 623 ASSERT(last); |
| 624 | 624 |
| 625 // First try to find the last node in the scope that comes before start and
has the same tabindex as start. | 625 // First try to find the last node in the scope that comes before start and
has the same tabindex as start. |
| 626 // If start is null, find the last node in the scope with a tabindex of 0. | 626 // If start is null, find the last node in the scope with a tabindex of 0. |
| 627 Node* startingNode; | 627 Node* startingNode; |
| 628 int startingTabIndex; | 628 int startingTabIndex; |
| 629 if (start) { | 629 if (start) { |
| 630 startingNode = NodeTraversal::previous(*start); | 630 startingNode = NodeTraversal::previous(*start); |
| 631 startingTabIndex = adjustedTabIndex(*start); | 631 startingTabIndex = adjustedTabIndex(*start); |
| 632 } else { | 632 } else { |
| 633 startingNode = last; | 633 startingNode = last; |
| 634 startingTabIndex = 0; | 634 startingTabIndex = 0; |
| 635 } | 635 } |
| 636 | 636 |
| 637 // However, if a node is excluded from the normal tabbing cycle, the previou
s focusable node is determined by tree order | 637 // However, if a node is excluded from the normal tabbing cycle, the previou
s focusable node is determined by tree order |
| 638 if (startingTabIndex < 0) { | 638 if (startingTabIndex < 0) { |
| 639 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no
de)) { | 639 for (Node* node = startingNode; node; node = NodeTraversal::previous(*no
de)) { |
| 640 if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0) | 640 if (shouldVisit(*node) && adjustedTabIndex(*node) >= 0) |
| 641 return node; | 641 return node; |
| 642 } | 642 } |
| 643 } else { | 643 } else { |
| 644 if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIn
dex, FocusTypeBackward)) | 644 if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIn
dex, WebFocusTypeBackward)) |
| 645 return winner; | 645 return winner; |
| 646 } | 646 } |
| 647 | 647 |
| 648 // There are no nodes before start with the same tabindex as start, so look
for a node that: | 648 // There are no nodes before start with the same tabindex as start, so look
for a node that: |
| 649 // 1) has the highest non-zero tabindex (that is less than start's tabindex)
, and | 649 // 1) has the highest non-zero tabindex (that is less than start's tabindex)
, and |
| 650 // 2) comes last in the scope, if there's a tie. | 650 // 2) comes last in the scope, if there's a tie. |
| 651 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num
eric_limits<short>::max(); | 651 startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::num
eric_limits<short>::max(); |
| 652 return previousNodeWithLowerTabIndex(last, startingTabIndex); | 652 return previousNodeWithLowerTabIndex(last, startingTabIndex); |
| 653 } | 653 } |
| 654 | 654 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 680 | 680 |
| 681 if (!enclosingTextFormControl(selectionStartNode)) | 681 if (!enclosingTextFormControl(selectionStartNode)) |
| 682 return; | 682 return; |
| 683 | 683 |
| 684 if (selectionStartNode->isInShadowTree() && selectionStartNode->shadowHost()
== newFocusedNode) | 684 if (selectionStartNode->isInShadowTree() && selectionStartNode->shadowHost()
== newFocusedNode) |
| 685 return; | 685 return; |
| 686 | 686 |
| 687 selection.clear(); | 687 selection.clear(); |
| 688 } | 688 } |
| 689 | 689 |
| 690 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr
<Frame> newFocusedFrame, FocusType type) | 690 bool FocusController::setFocusedElement(Element* element, PassRefPtrWillBeRawPtr
<Frame> newFocusedFrame, WebFocusType type) |
| 691 { | 691 { |
| 692 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame()
); | 692 RefPtrWillBeRawPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame()
); |
| 693 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame
->document() : nullptr; | 693 RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame
->document() : nullptr; |
| 694 | 694 |
| 695 Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : n
ullptr; | 695 Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : n
ullptr; |
| 696 if (element && oldFocusedElement == element) | 696 if (element && oldFocusedElement == element) |
| 697 return true; | 697 return true; |
| 698 | 698 |
| 699 // FIXME: Might want to disable this check for caretBrowsing | 699 // FIXME: Might want to disable this check for caretBrowsing |
| 700 if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !reli
nquishesEditingFocus(*oldFocusedElement)) | 700 if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !reli
nquishesEditingFocus(*oldFocusedElement)) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 if (frame->isLocalFrame()) { | 745 if (frame->isLocalFrame()) { |
| 746 // Invalidate all custom scrollbars because they support the CSS | 746 // Invalidate all custom scrollbars because they support the CSS |
| 747 // window-active attribute. This should be applied to the entire page so | 747 // window-active attribute. This should be applied to the entire page so |
| 748 // we invalidate from the root FrameView instead of just the focused. | 748 // we invalidate from the root FrameView instead of just the focused. |
| 749 if (FrameView* view = toLocalFrame(frame)->localFrameRoot()->document()-
>view()) | 749 if (FrameView* view = toLocalFrame(frame)->localFrameRoot()->document()-
>view()) |
| 750 view->invalidateAllCustomScrollbarsOnActiveChanged(); | 750 view->invalidateAllCustomScrollbarsOnActiveChanged(); |
| 751 toLocalFrame(frame)->selection().pageActivationChanged(); | 751 toLocalFrame(frame)->selection().pageActivationChanged(); |
| 752 } | 752 } |
| 753 } | 753 } |
| 754 | 754 |
| 755 static void updateFocusCandidateIfNeeded(FocusType type, const FocusCandidate& c
urrent, FocusCandidate& candidate, FocusCandidate& closest) | 755 static void updateFocusCandidateIfNeeded(WebFocusType type, const FocusCandidate
& current, FocusCandidate& candidate, FocusCandidate& closest) |
| 756 { | 756 { |
| 757 ASSERT(candidate.visibleNode->isElementNode()); | 757 ASSERT(candidate.visibleNode->isElementNode()); |
| 758 ASSERT(candidate.visibleNode->renderer()); | 758 ASSERT(candidate.visibleNode->renderer()); |
| 759 | 759 |
| 760 // Ignore iframes that don't have a src attribute | 760 // Ignore iframes that don't have a src attribute |
| 761 if (frameOwnerElement(candidate) && (!frameOwnerElement(candidate)->contentF
rame() || candidate.rect.isEmpty())) | 761 if (frameOwnerElement(candidate) && (!frameOwnerElement(candidate)->contentF
rame() || candidate.rect.isEmpty())) |
| 762 return; | 762 return; |
| 763 | 763 |
| 764 // Ignore off screen child nodes of containers that do not scroll (overflow:
hidden) | 764 // Ignore off screen child nodes of containers that do not scroll (overflow:
hidden) |
| 765 if (candidate.isOffscreen && !canBeScrolledIntoView(type, candidate)) | 765 if (candidate.isOffscreen && !canBeScrolledIntoView(type, candidate)) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 if (candidate.alignment == closest.alignment) { | 797 if (candidate.alignment == closest.alignment) { |
| 798 if (candidate.distance < closest.distance) | 798 if (candidate.distance < closest.distance) |
| 799 closest = candidate; | 799 closest = candidate; |
| 800 return; | 800 return; |
| 801 } | 801 } |
| 802 | 802 |
| 803 if (candidate.alignment > closest.alignment) | 803 if (candidate.alignment > closest.alignment) |
| 804 closest = candidate; | 804 closest = candidate; |
| 805 } | 805 } |
| 806 | 806 |
| 807 void FocusController::findFocusCandidateInContainer(Node& container, const Layou
tRect& startingRect, FocusType type, FocusCandidate& closest) | 807 void FocusController::findFocusCandidateInContainer(Node& container, const Layou
tRect& startingRect, WebFocusType type, FocusCandidate& closest) |
| 808 { | 808 { |
| 809 Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->d
ocument()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : nullpt
r; | 809 Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->d
ocument()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : nullpt
r; |
| 810 | 810 |
| 811 Element* element = ElementTraversal::firstWithin(container); | 811 Element* element = ElementTraversal::firstWithin(container); |
| 812 FocusCandidate current; | 812 FocusCandidate current; |
| 813 current.rect = startingRect; | 813 current.rect = startingRect; |
| 814 current.focusableNode = focusedElement; | 814 current.focusableNode = focusedElement; |
| 815 current.visibleNode = focusedElement; | 815 current.visibleNode = focusedElement; |
| 816 | 816 |
| 817 for (; element; element = (element->isFrameOwnerElement() || canScrollInDire
ction(element, type)) | 817 for (; element; element = (element->isFrameOwnerElement() || canScrollInDire
ction(element, type)) |
| 818 ? ElementTraversal::nextSkippingChildren(*element, &container) | 818 ? ElementTraversal::nextSkippingChildren(*element, &container) |
| 819 : ElementTraversal::next(*element, &container)) { | 819 : ElementTraversal::next(*element, &container)) { |
| 820 if (element == focusedElement) | 820 if (element == focusedElement) |
| 821 continue; | 821 continue; |
| 822 | 822 |
| 823 if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() &
& !canScrollInDirection(element, type)) | 823 if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() &
& !canScrollInDirection(element, type)) |
| 824 continue; | 824 continue; |
| 825 | 825 |
| 826 FocusCandidate candidate = FocusCandidate(element, type); | 826 FocusCandidate candidate = FocusCandidate(element, type); |
| 827 if (candidate.isNull()) | 827 if (candidate.isNull()) |
| 828 continue; | 828 continue; |
| 829 | 829 |
| 830 candidate.enclosingScrollableBox = &container; | 830 candidate.enclosingScrollableBox = &container; |
| 831 updateFocusCandidateIfNeeded(type, current, candidate, closest); | 831 updateFocusCandidateIfNeeded(type, current, candidate, closest); |
| 832 } | 832 } |
| 833 } | 833 } |
| 834 | 834 |
| 835 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
t LayoutRect& startingRect, FocusType type) | 835 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
t LayoutRect& startingRect, WebFocusType type) |
| 836 { | 836 { |
| 837 if (!container) | 837 if (!container) |
| 838 return false; | 838 return false; |
| 839 | 839 |
| 840 LayoutRect newStartingRect = startingRect; | 840 LayoutRect newStartingRect = startingRect; |
| 841 | 841 |
| 842 if (startingRect.isEmpty()) | 842 if (startingRect.isEmpty()) |
| 843 newStartingRect = virtualRectForDirection(type, nodeRectInAbsoluteCoordi
nates(container)); | 843 newStartingRect = virtualRectForDirection(type, nodeRectInAbsoluteCoordi
nates(container)); |
| 844 | 844 |
| 845 // Find the closest node within current container in the direction of the na
vigation. | 845 // Find the closest node within current container in the direction of the na
vigation. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 } | 895 } |
| 896 | 896 |
| 897 // We found a new focus node, navigate to it. | 897 // We found a new focus node, navigate to it. |
| 898 Element* element = toElement(focusCandidate.focusableNode); | 898 Element* element = toElement(focusCandidate.focusableNode); |
| 899 ASSERT(element); | 899 ASSERT(element); |
| 900 | 900 |
| 901 element->focus(false, type); | 901 element->focus(false, type); |
| 902 return true; | 902 return true; |
| 903 } | 903 } |
| 904 | 904 |
| 905 bool FocusController::advanceFocusDirectionally(FocusType type) | 905 bool FocusController::advanceFocusDirectionally(WebFocusType type) |
| 906 { | 906 { |
| 907 // FIXME: Directional focus changes don't yet work with RemoteFrames. | 907 // FIXME: Directional focus changes don't yet work with RemoteFrames. |
| 908 if (!focusedOrMainFrame()->isLocalFrame()) | 908 if (!focusedOrMainFrame()->isLocalFrame()) |
| 909 return false; | 909 return false; |
| 910 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame()); | 910 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame()); |
| 911 ASSERT(curFrame); | 911 ASSERT(curFrame); |
| 912 | 912 |
| 913 Document* focusedDocument = curFrame->document(); | 913 Document* focusedDocument = curFrame->document(); |
| 914 if (!focusedDocument) | 914 if (!focusedDocument) |
| 915 return false; | 915 return false; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 945 return consumed; | 945 return consumed; |
| 946 } | 946 } |
| 947 | 947 |
| 948 void FocusController::trace(Visitor* visitor) | 948 void FocusController::trace(Visitor* visitor) |
| 949 { | 949 { |
| 950 visitor->trace(m_page); | 950 visitor->trace(m_page); |
| 951 visitor->trace(m_focusedFrame); | 951 visitor->trace(m_focusedFrame); |
| 952 } | 952 } |
| 953 | 953 |
| 954 } // namespace blink | 954 } // namespace blink |
| OLD | NEW |