1 /* 2 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2009 Antonio Gomes <tonikitoo (at) 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() : 0; } 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 149