Extend keyboard navigation to allow directional navigation
https://bugs.webkit.org/show_bug.cgi?id=18662

Reviewed by Simon Fraser, Eric Seidel and Darin Adler.
Patch by Antonio Gomes <tonikitoo@webkit.org>
Based on the initial work of Marco Barisione <marco.barisione@collabora.co.uk>

This patch implements the core logic of the 'Spatial Navigation' feature [1].
It improves the accessibility support of WebCore by extending the basic keyboard
navigation currently available (based on Tab forward and backward) with the
addition of a two-dimensional directional navigation by using Left, Right, Up and
Down arrow keys to move to the "nearest" element in the corresponding direction.

Highlights:
* Feature is turned off by default in Settings. Port specific APIs need to be added
  for toggling it on/off.
* Only elements viewed in the current viewport can have focus move to it. If the
  "nearest" is not in viewport dimensions, then a scroll-in-direction action is
  performed.
* The layout tests added run on Qt's DRT only for now (skipped for Mac, Win and Gtk).

Known issues (to be covered in follow-up bugs):
* Add port specific hooks to each DRT to enable/disable Spatial Navigation.
* Support for spatial navigation through form elements (<input>, <select>, etc)
  is be added.
* Make navigation keys customizable. It currently works with arrows keys only
  (up, down, right and left).
* Make it support modifiers (Alt, Ctrl and Shift).

[1] http://en.wikipedia.org/wiki/Spatial_navigation

* Android.mk:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* page/EventHandler.cpp:
(WebCore::EventHandler::defaultKeyboardEventHandler):
(WebCore::EventHandler::focusDirectionForKey):
(WebCore::EventHandler::defaultArrowEventHandler):
* page/EventHandler.h:
* page/FocusController.cpp:
(WebCore::FocusController::advanceFocus):
(WebCore::FocusController::advanceFocusInDocumentOrder):
(WebCore::FocusController::advanceFocusDirectionally):
(WebCore::updateFocusCandidateIfCloser):
(WebCore::FocusController::findFocusableNodeInDirection):
(WebCore::FocusController::deepFindFocusableNodeInDirection):
* page/FocusController.h:
* page/FocusDirection.h:
(WebCore::):
* page/Settings.cpp:
(WebCore::Settings::Settings):
(WebCore::Settings::setSpatialNavigationEnabled):
* page/Settings.h:
(WebCore::Settings::isSpatialNavigationEnabled):
* page/SpatialNavigation.cpp: Added.
(WebCore::distanceInDirection):
(WebCore::renderRectRelativeToRootDocument):
(WebCore::alignmentForRects):
(WebCore::isHorizontalMove):
(WebCore::areRectsFullyAligned):
(WebCore::areRectsPartiallyAligned):
(WebCore::spatialDistance):
(WebCore::isRectInDirection):
(WebCore::hasOffscreenRect):
(WebCore::scrollInDirection):
(WebCore::isInRootDocument):
(WebCore::deflateIfOverlapped):
* page/SpatialNavigation.h: Added.
(WebCore::):
(WebCore::FocusCandidate::FocusCandidate):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
15 files changed