Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: Source/core/page/FocusController.cpp

Issue 810493003: Introduce "navigation target classification" for spatial navigation Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/page/SpatialNavigation.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/page/SpatialNavigation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698