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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/page/SpatialNavigation.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/page/FocusController.cpp
diff --git a/Source/core/page/FocusController.cpp b/Source/core/page/FocusController.cpp
index 4382f680fb5796be7026505d992dd3478f2ea719..0bf6cb92b6f7e06a875c44cdd0948c776481e67f 100644
--- a/Source/core/page/FocusController.cpp
+++ b/Source/core/page/FocusController.cpp
@@ -787,6 +787,43 @@ static void updateFocusCandidateIfNeeded(FocusType type, const FocusCandidate& c
closest = candidate;
}
+static inline bool hasFocusEventHandler(const Element& element)
+{
+ return element.hasEventListeners(EventTypeNames::focus)
+ || element.hasEventListeners(EventTypeNames::blur)
+ || element.hasEventListeners(EventTypeNames::focusin)
+ || element.hasEventListeners(EventTypeNames::focusout);
+}
+
+static inline NavigationClass classifyNavigationCandidate(const Element& element, FocusType type)
+{
+ if (element.isKeyboardFocusable())
+ return NavigationClassFocusable;
+
+ if (element.isFrameOwnerElement())
+ return NavigationClassFrameOwner;
+
+ if (canScrollInDirection(&element, type))
+ return NavigationClassScrollable;
+
+ // If the element is not "keyboard focusable", apply an extended heuristic,
+ // by checking for the presence of a click/keyboard/focus/blur event
+ // handler.
+ // This way it's possible to navigate to (focus) elements which the web
+ // designer intended to be active (made them respond to mentioned events).
+
+ if (element.hasEventListeners(EventTypeNames::click)
+ || element.hasEventListeners(EventTypeNames::keydown)
+ || element.hasEventListeners(EventTypeNames::keypress)
+ || element.hasEventListeners(EventTypeNames::keyup))
+ return NavigationClassEventHandler;
+
+ if (element.isSVGElement() && hasFocusEventHandler(element))
c.shu 2015/01/07 23:49:48 I would either expand the four focus event listene
+ return NavigationClassEventHandler;
+
+ return NavigationClassNone;
+}
+
void FocusController::findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusType type, FocusCandidate& closest)
{
Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->document()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : nullptr;
@@ -796,6 +833,10 @@ void FocusController::findFocusCandidateInContainer(Node& container, const Layou
current.rect = startingRect;
current.focusableNode = focusedElement;
current.visibleNode = focusedElement;
+ if (focusedElement) {
+ // FIXME: Result the computed class depends on the focus type.
+ current.targetClass = classifyNavigationCandidate(*focusedElement, type);
+ }
for (; element; element = (element->isFrameOwnerElement() || canScrollInDirection(element, type))
? ElementTraversal::nextSkippingChildren(*element, &container)
@@ -803,10 +844,11 @@ void FocusController::findFocusCandidateInContainer(Node& container, const Layou
if (element == focusedElement)
continue;
- if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() && !canScrollInDirection(element, type))
+ NavigationClass navigationClass = classifyNavigationCandidate(*element, type);
+ if (navigationClass == NavigationClassNone)
continue;
- FocusCandidate candidate = FocusCandidate(element, type);
+ FocusCandidate candidate(element, type, navigationClass);
c.shu 2015/01/07 23:49:48 Can we do some additional code refactory here so t
if (candidate.isNull())
continue;
« 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