Factor HitTestPoint out of HitTestResult.
[WebKit-https.git] / Source / WebCore / rendering / HitTestResult.h
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.
3  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
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
22 #ifndef HitTestResult_h
23 #define HitTestResult_h
24
25 #include "FloatRect.h"
26 #include "HitTestRequest.h"
27 #include "LayoutTypes.h"
28 #include "TextDirection.h"
29 #include <wtf/Forward.h>
30 #include <wtf/ListHashSet.h>
31 #include <wtf/OwnPtr.h>
32 #include <wtf/RefPtr.h>
33
34 namespace WebCore {
35
36 class Element;
37 class Frame;
38 #if ENABLE(VIDEO)
39 class HTMLMediaElement;
40 #endif
41 class Image;
42 class KURL;
43 class Node;
44 class RenderRegion;
45 class Scrollbar;
46
47 enum ShadowContentFilterPolicy { DoNotAllowShadowContent, AllowShadowContent };
48
49 class HitTestPoint {
50 public:
51
52     HitTestPoint();
53     HitTestPoint(const LayoutPoint&);
54     // Pass non-negative padding values to perform a rect-based hit test.
55     HitTestPoint(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
56     HitTestPoint(const HitTestPoint&);
57     ~HitTestPoint();
58     HitTestPoint& operator=(const HitTestPoint&);
59
60     LayoutPoint point() const { return m_point; }
61     IntPoint roundedPoint() const { return roundedIntPoint(m_point); }
62
63     void setPoint(const LayoutPoint& p) { m_point = p; }
64
65     // Rect-based hit test related methods.
66     bool isRectBasedTest() const { return m_isRectBased; }
67     IntRect rectForPoint(const LayoutPoint&) const;
68     static IntRect rectForPoint(const LayoutPoint&, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
69     int topPadding() const { return m_topPadding; }
70     int rightPadding() const { return m_rightPadding; }
71     int bottomPadding() const { return m_bottomPadding; }
72     int leftPadding() const { return m_leftPadding; }
73
74 private:
75     LayoutPoint m_point;
76
77     int m_topPadding;
78     int m_rightPadding;
79     int m_bottomPadding;
80     int m_leftPadding;
81     bool m_isRectBased;
82 };
83
84 class HitTestResult : public HitTestPoint {
85 public:
86     typedef ListHashSet<RefPtr<Node> > NodeSet;
87
88     HitTestResult();
89     HitTestResult(const LayoutPoint&);
90     // Pass non-negative padding values to perform a rect-based hit test.
91     HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, ShadowContentFilterPolicy);
92     HitTestResult(const HitTestPoint&, ShadowContentFilterPolicy);
93     HitTestResult(const HitTestResult&);
94     ~HitTestResult();
95     HitTestResult& operator=(const HitTestResult&);
96
97     Node* innerNode() const { return m_innerNode.get(); }
98     Node* innerNonSharedNode() const { return m_innerNonSharedNode.get(); }
99     LayoutPoint localPoint() const { return m_localPoint; }
100     Element* URLElement() const { return m_innerURLElement.get(); }
101     Scrollbar* scrollbar() const { return m_scrollbar.get(); }
102     bool isOverWidget() const { return m_isOverWidget; }
103
104     RenderRegion* region() const { return m_region; }
105     void setRegion(RenderRegion* region) { m_region = region; }
106
107     void setToNonShadowAncestor();
108
109     const HitTestPoint& hitTestPoint() const { return *this; }
110     ShadowContentFilterPolicy shadowContentFilterPolicy() const { return m_shadowContentFilterPolicy; }
111
112     void setInnerNode(Node*);
113     void setInnerNonSharedNode(Node*);
114     void setLocalPoint(const LayoutPoint& p) { m_localPoint = p; }
115     void setURLElement(Element*);
116     void setScrollbar(Scrollbar*);
117     void setIsOverWidget(bool b) { m_isOverWidget = b; }
118
119     Frame* targetFrame() const;
120     bool isSelected() const;
121     String spellingToolTip(TextDirection&) const;
122     String replacedString() const;
123     String title(TextDirection&) const;
124     String innerTextIfTruncated(TextDirection&) const;
125     String altDisplayString() const;
126     String titleDisplayString() const;
127     Image* image() const;
128     IntRect imageRect() const;
129     KURL absoluteImageURL() const;
130     KURL absolutePDFURL() const;
131     KURL absoluteMediaURL() const;
132     KURL absoluteLinkURL() const;
133     String textContent() const;
134     bool isLiveLink() const;
135     bool isContentEditable() const;
136     void toggleMediaControlsDisplay() const;
137     void toggleMediaLoopPlayback() const;
138     void enterFullscreenForVideo() const;
139     bool mediaControlsEnabled() const;
140     bool mediaLoopEnabled() const;
141     bool mediaPlaying() const;
142     bool mediaSupportsFullscreen() const;
143     void toggleMediaPlayState() const;
144     bool mediaHasAudio() const;
145     bool mediaIsVideo() const;
146     bool mediaMuted() const;
147     void toggleMediaMuteState() const;
148
149     // Returns true if it is rect-based hit test and needs to continue until the rect is fully
150     // enclosed by the boundaries of a node.
151     bool addNodeToRectBasedTestResult(Node*, const LayoutPoint& pointInContainer, const IntRect& = IntRect());
152     bool addNodeToRectBasedTestResult(Node*, const LayoutPoint& pointInContainer, const FloatRect&);
153     void append(const HitTestResult&);
154
155     // If m_rectBasedTestResult is 0 then set it to a new NodeSet. Return *m_rectBasedTestResult. Lazy allocation makes
156     // sense because the NodeSet is seldom necessary, and it's somewhat expensive to allocate and initialize. This method does
157     // the same thing as mutableRectBasedTestResult(), but here the return value is const.
158     const NodeSet& rectBasedTestResult() const;
159
160 private:
161     NodeSet& mutableRectBasedTestResult(); // See above.
162
163 #if ENABLE(VIDEO)
164     HTMLMediaElement* mediaElement() const;
165 #endif
166
167     RefPtr<Node> m_innerNode;
168     RefPtr<Node> m_innerNonSharedNode;
169     LayoutPoint m_localPoint; // A point in the local coordinate space of m_innerNonSharedNode's renderer. Allows us to efficiently
170                               // determine where inside the renderer we hit on subsequent operations.
171     RefPtr<Element> m_innerURLElement;
172     RefPtr<Scrollbar> m_scrollbar;
173     bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example).
174
175     ShadowContentFilterPolicy m_shadowContentFilterPolicy;
176
177     RenderRegion* m_region; // The region we're inside.
178
179     mutable OwnPtr<NodeSet> m_rectBasedTestResult;
180 };
181
182 // Formula:
183 // x = p.x() - rightPadding
184 // y = p.y() - topPadding
185 // width = leftPadding + rightPadding + 1
186 // height = topPadding + bottomPadding + 1
187 inline IntRect HitTestPoint::rectForPoint(const LayoutPoint& point) const
188 {
189     return rectForPoint(point, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding);
190 }
191
192 String displayString(const String&, const Node*);
193
194 } // namespace WebCore
195
196 #endif // HitTestResult_h