15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef SpatialNavigation_h
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define SpatialNavigation_h
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFrameOwnerElement.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FocusDirection.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/LayoutRect.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <limits>
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Element;
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Frame;
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class HTMLAreaElement;
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IntRect;
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RenderObject;
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline long long maxDistance()
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return numeric_limits<long long>::max();
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline int fudgeFactor()
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 2;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool isSpatialNavigationEnabled(const Frame*);
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Spatially speaking, two given elements in a web page can be:
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 1) Fully aligned: There is a full intersection between the rects, either
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//    vertically or horizontally.
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Horizontally       * Vertically
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//    _
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|                   _ _ _ _ _ _
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|...... _          |_|_|_|_|_|_|
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|      |_|         .       .
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|......|_|   OR    .       .
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|      |_|         .       .
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|......|_|          _ _ _ _
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|                  |_|_|_|_|
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 2) Partially aligned: There is a partial intersection between the rects, either
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//    vertically or horizontally.
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Horizontally       * Vertically
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//    _                   _ _ _ _ _
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|                 |_|_|_|_|_|
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|.... _      OR           . .
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|    |_|                  . .
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|....|_|                  ._._ _
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//          |_|                  |_|_|_|
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//          |_|
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 3) Or, otherwise, not aligned at all.
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * Horizontally       * Vertically
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//         _              _ _ _ _
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//        |_|            |_|_|_|_|
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//        |_|                    .
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//        |_|                     .
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       .          OR             .
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//    _ .                           ._ _ _ _ _
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|                            |_|_|_|_|_|
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//   |_|
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// "Totally Aligned" elements are preferable candidates to move
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// focus to over "Partially Aligned" ones, that on its turns are
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// more preferable than "Not Aligned".
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum RectsAlignment {
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    None = 0,
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Partial,
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Full
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct FocusCandidate {
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FocusCandidate()
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : visibleNode(0)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , focusableNode(0)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , enclosingScrollableBox(0)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , distance(maxDistance())
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , parentDistance(maxDistance())
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , alignment(None)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , parentAlignment(None)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , isOffscreen(true)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , isOffscreenAfterScrolling(true)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FocusCandidate(Node* n, FocusDirection);
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    explicit FocusCandidate(HTMLAreaElement* area, FocusDirection);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isNull() const { return !visibleNode; }
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool inScrollableContainer() const { return visibleNode && enclosingScrollableBox; }
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isFrameOwnerElement() const { return visibleNode && visibleNode->isFrameOwnerElement(); }
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Document* document() const { return visibleNode ? visibleNode->document() : 0; }
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We handle differently visibleNode and FocusableNode to properly handle the areas of imagemaps,
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // where visibleNode would represent the image element and focusableNode would represent the area element.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In all other cases, visibleNode and focusableNode are one and the same.
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* visibleNode;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* focusableNode;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* enclosingScrollableBox;
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    long long distance;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    long long parentDistance;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RectsAlignment alignment;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RectsAlignment parentAlignment;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect rect;
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isOffscreen;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isOffscreenAfterScrolling;
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool hasOffscreenRect(Node*, FocusDirection direction = FocusDirectionNone);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool scrollInDirection(Frame*, FocusDirection);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool scrollInDirection(Node* container, FocusDirection);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool canScrollInDirection(const Node* container, FocusDirection);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool canScrollInDirection(const Frame*, FocusDirection);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool canBeScrolledIntoView(FocusDirection, const FocusCandidate&);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void distanceDataForNode(FocusDirection, const FocusCandidate& current, FocusCandidate& candidate);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection, Node*);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect frameRectInAbsoluteCoordinates(Frame*);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect virtualRectForDirection(FocusDirection, const LayoutRect& startingRect, LayoutUnit width = 0);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement*, FocusDirection);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namspace WebCore
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // SpatialNavigation_h
156