Chromium Code Reviews| 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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 inline bool hasCustomFocusLogic(const Element& element) | 357 inline bool hasCustomFocusLogic(const Element& element) |
| 358 { | 358 { |
| 359 return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic (); | 359 return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic (); |
| 360 } | 360 } |
| 361 | 361 |
| 362 inline bool isShadowHostWithoutCustomFocusLogic(const Element& element) | 362 inline bool isShadowHostWithoutCustomFocusLogic(const Element& element) |
| 363 { | 363 { |
| 364 return isShadowHost(element) && !hasCustomFocusLogic(element); | 364 return isShadowHost(element) && !hasCustomFocusLogic(element); |
| 365 } | 365 } |
| 366 | 366 |
| 367 #if ENABLE(ASSERT) | |
| 368 inline bool isNonFocusableShadowHost(const Element& element) | |
| 369 { | |
| 370 return isShadowHostWithoutCustomFocusLogic(element) && !element.isFocusable( ); | |
| 371 } | |
| 372 #endif | |
| 373 | |
| 374 inline bool isNonKeyboardFocusableShadowHost(const Element& element) | 367 inline bool isNonKeyboardFocusableShadowHost(const Element& element) |
| 375 { | 368 { |
| 376 return isShadowHostWithoutCustomFocusLogic(element) && !(element.shadowRootI fV1() ? element.isFocusable() : element.isKeyboardFocusable()); | 369 return isShadowHostWithoutCustomFocusLogic(element) && !(element.shadowRootI fV1() ? element.isFocusable() : element.isKeyboardFocusable()); |
| 377 } | 370 } |
| 378 | 371 |
| 379 inline bool isKeyboardFocusableShadowHost(const Element& element) | 372 inline bool isKeyboardFocusableShadowHost(const Element& element) |
| 380 { | 373 { |
| 381 return isShadowHostWithoutCustomFocusLogic(element) && element.isKeyboardFoc usable(); | 374 return isShadowHostWithoutCustomFocusLogic(element) && element.isKeyboardFoc usable(); |
| 382 } | 375 } |
| 383 | 376 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 break; | 632 break; |
| 640 ASSERT(element != foundElement); | 633 ASSERT(element != foundElement); |
| 641 element = foundElement; | 634 element = foundElement; |
| 642 } | 635 } |
| 643 return element; | 636 return element; |
| 644 } | 637 } |
| 645 | 638 |
| 646 Element* findFocusableElementAcrossFocusScopesForward(ScopedFocusNavigation& sco pe) | 639 Element* findFocusableElementAcrossFocusScopesForward(ScopedFocusNavigation& sco pe) |
| 647 { | 640 { |
| 648 Element* current = scope.currentElement(); | 641 Element* current = scope.currentElement(); |
| 649 ASSERT(!current || !isNonFocusableShadowHost(*current)); | |
| 650 Element* found; | 642 Element* found; |
| 651 if (current && isShadowHostWithoutCustomFocusLogic(*current)) { | 643 if (current && isShadowHostWithoutCustomFocusLogic(*current)) { |
| 652 ScopedFocusNavigation innerScope = ScopedFocusNavigation::ownedByShadowH ost(*current); | 644 ScopedFocusNavigation innerScope = ScopedFocusNavigation::ownedByShadowH ost(*current); |
| 653 Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward (innerScope); | 645 Element* foundInInnerFocusScope = findFocusableElementRecursivelyForward (innerScope); |
| 654 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableE lementRecursivelyForward(scope); | 646 found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableE lementRecursivelyForward(scope); |
| 655 } else { | 647 } else { |
| 656 found = findFocusableElementRecursivelyForward(scope); | 648 found = findFocusableElementRecursivelyForward(scope); |
| 657 } | 649 } |
| 658 | 650 |
| 659 // If there's no focusable element to advance to, move up the focus scopes u ntil we find one. | 651 // If there's no focusable element to advance to, move up the focus scopes u ntil we find one. |
| 660 ScopedFocusNavigation currentScope = scope; | 652 ScopedFocusNavigation currentScope = scope; |
| 661 while (!found) { | 653 while (!found) { |
| 662 Element* owner = currentScope.owner(); | 654 Element* owner = currentScope.owner(); |
| 663 if (!owner) | 655 if (!owner) |
| 664 break; | 656 break; |
| 665 currentScope = ScopedFocusNavigation::createFor(*owner); | 657 currentScope = ScopedFocusNavigation::createFor(*owner); |
| 666 found = findFocusableElementRecursivelyForward(currentScope); | 658 found = findFocusableElementRecursivelyForward(currentScope); |
| 667 } | 659 } |
| 668 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeForwa rd, found); | 660 return findFocusableElementDescendingDownIntoFrameDocument(WebFocusTypeForwa rd, found); |
| 669 } | 661 } |
| 670 | 662 |
| 671 Element* findFocusableElementAcrossFocusScopesBackward(ScopedFocusNavigation& sc ope) | 663 Element* findFocusableElementAcrossFocusScopesBackward(ScopedFocusNavigation& sc ope) |
| 672 { | 664 { |
| 673 ASSERT(!scope.currentElement() || !isNonFocusableShadowHost(*scope.currentEl ement())); | |
| 674 Element* found = findFocusableElementRecursivelyBackward(scope); | 665 Element* found = findFocusableElementRecursivelyBackward(scope); |
| 675 | 666 |
| 676 // If there's no focusable element to advance to, move up the focus scopes u ntil we find one. | 667 // If there's no focusable element to advance to, move up the focus scopes u ntil we find one. |
| 677 ScopedFocusNavigation currentScope = scope; | 668 ScopedFocusNavigation currentScope = scope; |
| 678 while (!found) { | 669 while (!found) { |
| 679 Element* owner = currentScope.owner(); | 670 Element* owner = currentScope.owner(); |
| 680 if (!owner) | 671 if (!owner) |
| 681 break; | 672 break; |
| 682 currentScope = ScopedFocusNavigation::createFor(*owner); | 673 currentScope = ScopedFocusNavigation::createFor(*owner); |
| 683 if (isKeyboardFocusableShadowHost(*owner) && !isShadowHostDelegatesFocus (*owner)) { | 674 if (isKeyboardFocusableShadowHost(*owner) && !isShadowHostDelegatesFocus (*owner)) { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 906 } | 897 } |
| 907 | 898 |
| 908 bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Element* st art, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCapabi lities) | 899 bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Element* st art, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCapabi lities) |
| 909 { | 900 { |
| 910 ASSERT(frame); | 901 ASSERT(frame); |
| 911 Document* document = frame->document(); | 902 Document* document = frame->document(); |
| 912 document->updateDistribution(); | 903 document->updateDistribution(); |
| 913 | 904 |
| 914 Element* current = start; | 905 Element* current = start; |
| 915 if (!current && !initialFocus) | 906 if (!current && !initialFocus) |
| 916 current = document->sequentialFocusNavigationStartingPoint(type); | 907 current = document->sequentialFocusNavigationStartingPoint(type); |
|
hayato
2016/05/11 12:44:44
I think we can distinguish special cases, where `c
kochi
2016/05/12 02:09:21
Done.
| |
| 917 | 908 |
| 918 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself | 909 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself |
| 919 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); | 910 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); |
| 920 | 911 |
| 921 if (caretBrowsing && !current) | 912 if (caretBrowsing && !current) |
| 922 current = adjustToElement(frame->selection().start().anchorNode(), type) ; | 913 current = adjustToElement(frame->selection().start().anchorNode(), type) ; |
| 923 | 914 |
| 924 document->updateLayoutIgnorePendingStylesheets(); | 915 document->updateLayoutIgnorePendingStylesheets(); |
| 925 ScopedFocusNavigation scope = current ? ScopedFocusNavigation::createFor(*cu rrent) : ScopedFocusNavigation::createForDocument(*document); | 916 ScopedFocusNavigation scope = current ? ScopedFocusNavigation::createFor(*cu rrent) : ScopedFocusNavigation::createForDocument(*document); |
| 926 Element* element = findFocusableElementAcrossFocusScopes(type, scope); | 917 Element* element = findFocusableElementAcrossFocusScopes(type, scope); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 972 // If contentFrame is remote, continue the search for focusable | 963 // If contentFrame is remote, continue the search for focusable |
| 973 // elements in that frame's process. | 964 // elements in that frame's process. |
| 974 // clearFocusedElement() fires events that might detach the | 965 // clearFocusedElement() fires events that might detach the |
| 975 // contentFrame, hence the need to null-check it again. | 966 // contentFrame, hence the need to null-check it again. |
| 976 if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame()) | 967 if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame()) |
| 977 toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame); | 968 toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame); |
| 978 | 969 |
| 979 return true; | 970 return true; |
| 980 } | 971 } |
| 981 | 972 |
| 973 ASSERT(element->isFocusable()); | |
| 974 | |
| 982 // FIXME: It would be nice to just be able to call setFocusedElement(element ) | 975 // FIXME: It would be nice to just be able to call setFocusedElement(element ) |
| 983 // here, but we can't do that because some elements (e.g. HTMLInputElement | 976 // here, but we can't do that because some elements (e.g. HTMLInputElement |
| 984 // and HTMLTextAreaElement) do extra work in their focus() methods. | 977 // and HTMLTextAreaElement) do extra work in their focus() methods. |
| 985 Document& newDocument = element->document(); | 978 Document& newDocument = element->document(); |
| 986 | 979 |
| 987 if (&newDocument != document) { | 980 if (&newDocument != document) { |
| 988 // Focus is going away from this document, so clear the focused element. | 981 // Focus is going away from this document, so clear the focused element. |
| 989 document->clearFocusedElement(); | 982 document->clearFocusedElement(); |
| 990 } | 983 } |
| 991 | 984 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1306 return consumed; | 1299 return consumed; |
| 1307 } | 1300 } |
| 1308 | 1301 |
| 1309 DEFINE_TRACE(FocusController) | 1302 DEFINE_TRACE(FocusController) |
| 1310 { | 1303 { |
| 1311 visitor->trace(m_page); | 1304 visitor->trace(m_page); |
| 1312 visitor->trace(m_focusedFrame); | 1305 visitor->trace(m_focusedFrame); |
| 1313 } | 1306 } |
| 1314 | 1307 |
| 1315 } // namespace blink | 1308 } // namespace blink |
| OLD | NEW |