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 |