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 |