Chromium Code Reviews| 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; |