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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 if (candidate.alignment == closest.alignment) { | 780 if (candidate.alignment == closest.alignment) { |
| 781 if (candidate.distance < closest.distance) | 781 if (candidate.distance < closest.distance) |
| 782 closest = candidate; | 782 closest = candidate; |
| 783 return; | 783 return; |
| 784 } | 784 } |
| 785 | 785 |
| 786 if (candidate.alignment > closest.alignment) | 786 if (candidate.alignment > closest.alignment) |
| 787 closest = candidate; | 787 closest = candidate; |
| 788 } | 788 } |
| 789 | 789 |
| 790 static inline bool hasFocusEventHandler(const Element& element) | |
| 791 { | |
| 792 return element.hasEventListeners(EventTypeNames::focus) | |
| 793 || element.hasEventListeners(EventTypeNames::blur) | |
| 794 || element.hasEventListeners(EventTypeNames::focusin) | |
| 795 || element.hasEventListeners(EventTypeNames::focusout); | |
| 796 } | |
| 797 | |
| 798 static inline NavigationClass classifyNavigationCandidate(const Element& element , FocusType type) | |
| 799 { | |
| 800 if (element.isKeyboardFocusable()) | |
| 801 return NavigationClassFocusable; | |
| 802 | |
| 803 if (element.isFrameOwnerElement()) | |
| 804 return NavigationClassFrameOwner; | |
| 805 | |
| 806 if (canScrollInDirection(&element, type)) | |
| 807 return NavigationClassScrollable; | |
| 808 | |
| 809 // If the element is not "keyboard focusable", apply an extended heuristic, | |
| 810 // by checking for the presence of a click/keyboard/focus/blur event | |
| 811 // handler. | |
| 812 // This way it's possible to navigate to (focus) elements which the web | |
| 813 // designer intended to be active (made them respond to mentioned events). | |
| 814 | |
| 815 if (element.hasEventListeners(EventTypeNames::click) | |
| 816 || element.hasEventListeners(EventTypeNames::keydown) | |
| 817 || element.hasEventListeners(EventTypeNames::keypress) | |
| 818 || element.hasEventListeners(EventTypeNames::keyup)) | |
| 819 return NavigationClassEventHandler; | |
| 820 | |
| 821 if (element.isSVGElement() && hasFocusEventHandler(element)) | |
|
c.shu
2015/01/07 23:49:48
I would either expand the four focus event listene
| |
| 822 return NavigationClassEventHandler; | |
| 823 | |
| 824 return NavigationClassNone; | |
| 825 } | |
| 826 | |
| 790 void FocusController::findFocusCandidateInContainer(Node& container, const Layou tRect& startingRect, FocusType type, FocusCandidate& closest) | 827 void FocusController::findFocusCandidateInContainer(Node& container, const Layou tRect& startingRect, FocusType type, FocusCandidate& closest) |
| 791 { | 828 { |
| 792 Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->d ocument()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : nullpt r; | 829 Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->d ocument()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : nullpt r; |
| 793 | 830 |
| 794 Element* element = ElementTraversal::firstWithin(container); | 831 Element* element = ElementTraversal::firstWithin(container); |
| 795 FocusCandidate current; | 832 FocusCandidate current; |
| 796 current.rect = startingRect; | 833 current.rect = startingRect; |
| 797 current.focusableNode = focusedElement; | 834 current.focusableNode = focusedElement; |
| 798 current.visibleNode = focusedElement; | 835 current.visibleNode = focusedElement; |
| 836 if (focusedElement) { | |
| 837 // FIXME: Result the computed class depends on the focus type. | |
| 838 current.targetClass = classifyNavigationCandidate(*focusedElement, type) ; | |
| 839 } | |
| 799 | 840 |
| 800 for (; element; element = (element->isFrameOwnerElement() || canScrollInDire ction(element, type)) | 841 for (; element; element = (element->isFrameOwnerElement() || canScrollInDire ction(element, type)) |
| 801 ? ElementTraversal::nextSkippingChildren(*element, &container) | 842 ? ElementTraversal::nextSkippingChildren(*element, &container) |
| 802 : ElementTraversal::next(*element, &container)) { | 843 : ElementTraversal::next(*element, &container)) { |
| 803 if (element == focusedElement) | 844 if (element == focusedElement) |
| 804 continue; | 845 continue; |
| 805 | 846 |
| 806 if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() & & !canScrollInDirection(element, type)) | 847 NavigationClass navigationClass = classifyNavigationCandidate(*element, type); |
| 848 if (navigationClass == NavigationClassNone) | |
| 807 continue; | 849 continue; |
| 808 | 850 |
| 809 FocusCandidate candidate = FocusCandidate(element, type); | 851 FocusCandidate candidate(element, type, navigationClass); |
|
c.shu
2015/01/07 23:49:48
Can we do some additional code refactory here so t
| |
| 810 if (candidate.isNull()) | 852 if (candidate.isNull()) |
| 811 continue; | 853 continue; |
| 812 | 854 |
| 813 candidate.enclosingScrollableBox = &container; | 855 candidate.enclosingScrollableBox = &container; |
| 814 updateFocusCandidateIfNeeded(type, current, candidate, closest); | 856 updateFocusCandidateIfNeeded(type, current, candidate, closest); |
| 815 } | 857 } |
| 816 } | 858 } |
| 817 | 859 |
| 818 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons t LayoutRect& startingRect, FocusType type) | 860 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons t LayoutRect& startingRect, FocusType type) |
| 819 { | 861 { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 928 return consumed; | 970 return consumed; |
| 929 } | 971 } |
| 930 | 972 |
| 931 void FocusController::trace(Visitor* visitor) | 973 void FocusController::trace(Visitor* visitor) |
| 932 { | 974 { |
| 933 visitor->trace(m_page); | 975 visitor->trace(m_page); |
| 934 visitor->trace(m_focusedFrame); | 976 visitor->trace(m_focusedFrame); |
| 935 } | 977 } |
| 936 | 978 |
| 937 } // namespace blink | 979 } // namespace blink |
| OLD | NEW |