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 30namespace blink { 31 32class LocalFrame; 33class HTMLAreaElement; 34class HTMLFrameOwnerElement; 35 36inline long long maxDistance() 37{ 38 return std::numeric_limits<long long>::max(); 39} 40 41inline int fudgeFactor() 42{ 43 return 2; 44} 45 46bool 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". 91enum RectsAlignment { 92 None = 0, 93 Partial, 94 Full 95}; 96 97struct FocusCandidate { 98 STACK_ALLOCATED(); 99public: 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 131bool hasOffscreenRect(Node*, FocusType = FocusTypeNone); 132bool scrollInDirection(LocalFrame*, FocusType); 133bool scrollInDirection(Node* container, FocusType); 134bool canScrollInDirection(const Node* container, FocusType); 135bool canScrollInDirection(const LocalFrame*, FocusType); 136bool canBeScrolledIntoView(FocusType, const FocusCandidate&); 137bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate); 138void distanceDataForNode(FocusType, const FocusCandidate& current, FocusCandidate&); 139Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType, Node*); 140LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false); 141LayoutRect frameRectInAbsoluteCoordinates(LocalFrame*); 142LayoutRect virtualRectForDirection(FocusType, const LayoutRect& startingRect, LayoutUnit width = 0); 143LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement&, FocusType); 144HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&); 145 146} // namespace blink 147 148#endif // SpatialNavigation_h 149