Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / page / SpatialNavigation.h
1 /*
2  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifndef SpatialNavigation_h
22 #define SpatialNavigation_h
23
24 #include "core/dom/Node.h"
25 #include "core/page/FocusType.h"
26 #include "platform/geometry/LayoutRect.h"
27
28 #include <limits>
29
30 namespace blink {
31
32 class LocalFrame;
33 class HTMLAreaElement;
34 class HTMLFrameOwnerElement;
35
36 inline long long maxDistance()
37 {
38     return std::numeric_limits<long long>::max();
39 }
40
41 inline int fudgeFactor()
42 {
43     return 2;
44 }
45
46 bool isSpatialNavigationEnabled(const LocalFrame*);
47
48 // Spatially speaking, two given elements in a web page can be:
49 // 1) Fully aligned: There is a full intersection between the rects, either
50 //    vertically or horizontally.
51 //
52 // * Horizontally       * Vertically
53 //    _
54 //   |_|                   _ _ _ _ _ _
55 //   |_|...... _          |_|_|_|_|_|_|
56 //   |_|      |_|         .       .
57 //   |_|......|_|   OR    .       .
58 //   |_|      |_|         .       .
59 //   |_|......|_|          _ _ _ _
60 //   |_|                  |_|_|_|_|
61 //
62 //
63 // 2) Partially aligned: There is a partial intersection between the rects, either
64 //    vertically or horizontally.
65 //
66 // * Horizontally       * Vertically
67 //    _                   _ _ _ _ _
68 //   |_|                 |_|_|_|_|_|
69 //   |_|.... _      OR           . .
70 //   |_|    |_|                  . .
71 //   |_|....|_|                  ._._ _
72 //          |_|                  |_|_|_|
73 //          |_|
74 //
75 // 3) Or, otherwise, not aligned at all.
76 //
77 // * Horizontally       * Vertically
78 //         _              _ _ _ _
79 //        |_|            |_|_|_|_|
80 //        |_|                    .
81 //        |_|                     .
82 //       .          OR             .
83 //    _ .                           ._ _ _ _ _
84 //   |_|                            |_|_|_|_|_|
85 //   |_|
86 //   |_|
87 //
88 // "Totally Aligned" elements are preferable candidates to move
89 // focus to over "Partially Aligned" ones, that on its turns are
90 // more preferable than "Not Aligned".
91 enum RectsAlignment {
92     None = 0,
93     Partial,
94     Full
95 };
96
97 struct FocusCandidate {
98     STACK_ALLOCATED();
99 public:
100     FocusCandidate()
101         : visibleNode(nullptr)
102         , focusableNode(nullptr)
103         , enclosingScrollableBox(nullptr)
104         , distance(maxDistance())
105         , alignment(None)
106         , isOffscreen(true)
107         , isOffscreenAfterScrolling(true)
108     {
109     }
110
111     FocusCandidate(Node*, FocusType);
112     explicit FocusCandidate(HTMLAreaElement*, FocusType);
113     bool isNull() const { return !visibleNode; }
114     bool inScrollableContainer() const { return visibleNode && enclosingScrollableBox; }
115     bool isFrameOwnerElement() const { return visibleNode && visibleNode->isFrameOwnerElement(); }
116     Document* document() const { return visibleNode ? &visibleNode->document() : nullptr; }
117
118     // We handle differently visibleNode and FocusableNode to properly handle the areas of imagemaps,
119     // where visibleNode would represent the image element and focusableNode would represent the area element.
120     // In all other cases, visibleNode and focusableNode are one and the same.
121     RawPtrWillBeMember<Node> visibleNode;
122     RawPtrWillBeMember<Node> focusableNode;
123     RawPtrWillBeMember<Node> enclosingScrollableBox;
124     long long distance;
125     RectsAlignment alignment;
126     LayoutRect rect;
127     bool isOffscreen;
128     bool isOffscreenAfterScrolling;
129 };
130
131 bool hasOffscreenRect(Node*, FocusType = FocusTypeNone);
132 bool scrollInDirection(LocalFrame*, FocusType);
133 bool scrollInDirection(Node* container, FocusType);
134 bool canScrollInDirection(const Node* container, FocusType);
135 bool canScrollInDirection(const LocalFrame*, FocusType);
136 bool canBeScrolledIntoView(FocusType, const FocusCandidate&);
137 bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate);
138 void distanceDataForNode(FocusType, const FocusCandidate& current, FocusCandidate&);
139 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType, Node*);
140 LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false);
141 LayoutRect frameRectInAbsoluteCoordinates(LocalFrame*);
142 LayoutRect virtualRectForDirection(FocusType, const LayoutRect& startingRect, LayoutUnit width = 0);
143 LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement&, FocusType);
144 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&);
145
146 } // namespace blink
147
148 #endif // SpatialNavigation_h