~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/rendering/HitTestResult.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of the HTML rendering engine for KDE.
 
3
 *
 
4
 * Copyright (C) 2006 Apple Computer, Inc.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Library General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Library General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Library General Public License
 
17
 * along with this library; see the file COPYING.LIB.  If not, write to
 
18
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
19
 * Boston, MA 02111-1307, USA.
 
20
 *
 
21
*/
 
22
 
 
23
#include "config.h"
 
24
#include "HitTestResult.h"
 
25
 
 
26
#include "CSSHelper.h"
 
27
#include "Document.h"
 
28
#include "Frame.h"
 
29
#include "FrameTree.h"
 
30
#include "HTMLAnchorElement.h"
 
31
#include "HTMLElement.h"
 
32
#include "HTMLImageElement.h"
 
33
#include "HTMLInputElement.h"
 
34
#include "HTMLNames.h"
 
35
#include "KURL.h"
 
36
#include "PlatformScrollBar.h"
 
37
#include "RenderImage.h"
 
38
#include "RenderObject.h"
 
39
#include "SelectionController.h"
 
40
 
 
41
#if ENABLE(SVG)
 
42
#include "SVGNames.h"
 
43
#include "XLinkNames.h"
 
44
#endif
 
45
 
 
46
namespace WebCore {
 
47
 
 
48
using namespace HTMLNames;
 
49
 
 
50
HitTestResult::HitTestResult(const IntPoint& point)
 
51
    : m_point(point)
 
52
{
 
53
}
 
54
 
 
55
HitTestResult::HitTestResult(const HitTestResult& other)
 
56
    : m_innerNode(other.innerNode())
 
57
    , m_innerNonSharedNode(other.innerNonSharedNode())
 
58
    , m_point(other.point())
 
59
    , m_localPoint(other.localPoint())
 
60
    , m_innerURLElement(other.URLElement())
 
61
    , m_scrollbar(other.scrollbar())
 
62
{
 
63
}
 
64
 
 
65
HitTestResult::~HitTestResult()
 
66
{
 
67
}
 
68
 
 
69
HitTestResult& HitTestResult::operator=(const HitTestResult& other)
 
70
{
 
71
    m_innerNode = other.innerNode();
 
72
    m_innerNonSharedNode = other.innerNonSharedNode();
 
73
    m_point = other.point();
 
74
    m_innerURLElement = other.URLElement();
 
75
    m_scrollbar = other.scrollbar();
 
76
    return *this;
 
77
}
 
78
 
 
79
void HitTestResult::setToNonShadowAncestor()
 
80
{
 
81
    Node* node = innerNode();
 
82
    if (node)
 
83
        node = node->shadowAncestorNode();
 
84
    setInnerNode(node);
 
85
    node = innerNonSharedNode();
 
86
    if (node)
 
87
        node = node->shadowAncestorNode();
 
88
    setInnerNonSharedNode(node);
 
89
}
 
90
 
 
91
void HitTestResult::setInnerNode(Node* n)
 
92
{
 
93
    m_innerNode = n;
 
94
}
 
95
    
 
96
void HitTestResult::setInnerNonSharedNode(Node* n)
 
97
{
 
98
    m_innerNonSharedNode = n;
 
99
}
 
100
 
 
101
void HitTestResult::setURLElement(Element* n) 
 
102
 
103
    m_innerURLElement = n; 
 
104
}
 
105
 
 
106
void HitTestResult::setScrollbar(PlatformScrollbar* s)
 
107
{
 
108
    m_scrollbar = s;
 
109
}
 
110
 
 
111
Frame* HitTestResult::targetFrame() const
 
112
{
 
113
    if (!m_innerURLElement)
 
114
        return 0;
 
115
 
 
116
    Frame* frame = m_innerURLElement->document()->frame();
 
117
    if (!frame)
 
118
        return 0;
 
119
 
 
120
    return frame->tree()->find(m_innerURLElement->target());
 
121
}
 
122
 
 
123
IntRect HitTestResult::boundingBox() const
 
124
{
 
125
    if (m_innerNonSharedNode) {
 
126
        RenderObject* renderer = m_innerNonSharedNode->renderer();
 
127
        if (renderer)
 
128
            return renderer->absoluteBoundingBoxRect();
 
129
    }
 
130
    
 
131
    return IntRect();
 
132
}
 
133
 
 
134
bool HitTestResult::isSelected() const
 
135
{
 
136
    if (!m_innerNonSharedNode)
 
137
        return false;
 
138
 
 
139
    Frame* frame = m_innerNonSharedNode->document()->frame();
 
140
    if (!frame)
 
141
        return false;
 
142
 
 
143
    return frame->selectionController()->contains(m_point);
 
144
}
 
145
 
 
146
String HitTestResult::spellingToolTip() const
 
147
{
 
148
    // Return the tool tip string associated with this point, if any. Only markers associated with bad grammar
 
149
    // currently supply strings, but maybe someday markers associated with misspelled words will also.
 
150
    if (!m_innerNonSharedNode)
 
151
        return String();
 
152
    
 
153
     DocumentMarker* marker = m_innerNonSharedNode->document()->markerContainingPoint(m_point, DocumentMarker::Grammar);
 
154
    if (!marker)
 
155
        return String();
 
156
 
 
157
    return marker->description;
 
158
}
 
159
 
 
160
String HitTestResult::title() const
 
161
{
 
162
    // Find the title in the nearest enclosing DOM node.
 
163
    // For <area> tags in image maps, walk the tree for the <area>, not the <img> using it.
 
164
    for (Node* titleNode = m_innerNode.get(); titleNode; titleNode = titleNode->parentNode()) {
 
165
        if (titleNode->isElementNode()) {
 
166
            String title = static_cast<Element*>(titleNode)->title();
 
167
            if (!title.isEmpty())
 
168
                return title;
 
169
        }
 
170
    }
 
171
    return String();
 
172
}
 
173
 
 
174
String displayString(const String& string, const Node* node)
 
175
{
 
176
    if (!node)
 
177
        return string;
 
178
    String copy(string);
 
179
    copy.replace('\\', node->document()->backslashAsCurrencySymbol());
 
180
    return copy;
 
181
}
 
182
 
 
183
String HitTestResult::altDisplayString() const
 
184
{
 
185
    if (!m_innerNonSharedNode)
 
186
        return String();
 
187
    
 
188
    if (m_innerNonSharedNode->hasTagName(imgTag)) {
 
189
        HTMLImageElement* image = static_cast<HTMLImageElement*>(m_innerNonSharedNode.get());
 
190
        return displayString(image->alt(), m_innerNonSharedNode.get());
 
191
    }
 
192
    
 
193
    if (m_innerNonSharedNode->hasTagName(inputTag)) {
 
194
        HTMLInputElement* input = static_cast<HTMLInputElement*>(m_innerNonSharedNode.get());
 
195
        return displayString(input->alt(), m_innerNonSharedNode.get());
 
196
    }
 
197
    
 
198
    return String();
 
199
}
 
200
 
 
201
Image* HitTestResult::image() const
 
202
{
 
203
    if (!m_innerNonSharedNode)
 
204
        return 0;
 
205
    
 
206
    RenderObject* renderer = m_innerNonSharedNode->renderer();
 
207
    if (renderer && renderer->isImage()) {
 
208
        RenderImage* image = static_cast<WebCore::RenderImage*>(renderer);
 
209
        if (image->cachedImage() && !image->cachedImage()->errorOccurred())
 
210
            return image->cachedImage()->image();
 
211
    }
 
212
 
 
213
    return 0;
 
214
}
 
215
 
 
216
IntRect HitTestResult::imageRect() const
 
217
{
 
218
    if (!image())
 
219
        return IntRect();
 
220
    return m_innerNonSharedNode->renderer()->absoluteContentBox();
 
221
}
 
222
 
 
223
KURL HitTestResult::absoluteImageURL() const
 
224
{
 
225
    if (!(m_innerNonSharedNode && m_innerNonSharedNode->document()))
 
226
        return KURL();
 
227
 
 
228
    if (!(m_innerNonSharedNode->renderer() && m_innerNonSharedNode->renderer()->isImage()))
 
229
        return KURL();
 
230
 
 
231
    AtomicString urlString;
 
232
    if (m_innerNonSharedNode->hasTagName(imgTag) || m_innerNonSharedNode->hasTagName(inputTag))
 
233
        urlString = static_cast<Element*>(m_innerNonSharedNode.get())->getAttribute(srcAttr);
 
234
#if ENABLE(SVG)
 
235
    else if (m_innerNonSharedNode->hasTagName(SVGNames::imageTag))
 
236
        urlString = static_cast<Element*>(m_innerNonSharedNode.get())->getAttribute(XLinkNames::hrefAttr);
 
237
#endif
 
238
    else if (m_innerNonSharedNode->hasTagName(objectTag))
 
239
        urlString = static_cast<Element*>(m_innerNonSharedNode.get())->getAttribute(dataAttr);
 
240
    else
 
241
        return KURL();
 
242
    
 
243
    return KURL(m_innerNonSharedNode->document()->completeURL(parseURL(urlString).deprecatedString()));
 
244
}
 
245
 
 
246
KURL HitTestResult::absoluteLinkURL() const
 
247
{
 
248
    if (!(m_innerURLElement && m_innerURLElement->document()))
 
249
        return KURL();
 
250
 
 
251
    AtomicString urlString;
 
252
    if (m_innerURLElement->hasTagName(aTag) || m_innerURLElement->hasTagName(areaTag) || m_innerURLElement->hasTagName(linkTag))
 
253
        urlString = m_innerURLElement->getAttribute(hrefAttr);
 
254
#if ENABLE(SVG)
 
255
    else if (m_innerURLElement->hasTagName(SVGNames::aTag))
 
256
        urlString = m_innerURLElement->getAttribute(XLinkNames::hrefAttr);
 
257
#endif
 
258
    else
 
259
        return KURL();
 
260
 
 
261
    return KURL(m_innerURLElement->document()->completeURL(parseURL(urlString).deprecatedString()));
 
262
}
 
263
 
 
264
bool HitTestResult::isLiveLink() const
 
265
{
 
266
    if (!(m_innerURLElement && m_innerURLElement->document()))
 
267
        return false;
 
268
 
 
269
    if (m_innerURLElement->hasTagName(aTag))
 
270
        return static_cast<HTMLAnchorElement*>(m_innerURLElement.get())->isLiveLink();
 
271
#if ENABLE(SVG)
 
272
    if (m_innerURLElement->hasTagName(SVGNames::aTag))
 
273
        return m_innerURLElement->isLink();
 
274
#endif
 
275
    
 
276
    return false;
 
277
}
 
278
 
 
279
String HitTestResult::titleDisplayString() const
 
280
{
 
281
    if (!m_innerURLElement)
 
282
        return String();
 
283
    
 
284
    return displayString(m_innerURLElement->title(), m_innerURLElement.get());
 
285
}
 
286
 
 
287
String HitTestResult::textContent() const
 
288
{
 
289
    if (!m_innerURLElement)
 
290
        return String();
 
291
    return m_innerURLElement->textContent();
 
292
}
 
293
 
 
294
// FIXME: This function needs a better name and may belong in a different class. It's not
 
295
// really isContentEditable(); it's more like needsEditingContextMenu(). In many ways, this
 
296
// function would make more sense in the ContextMenu class, except that WebElementDictionary 
 
297
// hooks into it. Anyway, we should architect this better. 
 
298
bool HitTestResult::isContentEditable() const
 
299
{
 
300
    if (!m_innerNonSharedNode)
 
301
        return false;
 
302
 
 
303
    if (m_innerNonSharedNode->hasTagName(textareaTag) || m_innerNonSharedNode->hasTagName(isindexTag))
 
304
        return true;
 
305
 
 
306
    if (m_innerNonSharedNode->hasTagName(inputTag))
 
307
        return static_cast<HTMLInputElement*>(m_innerNonSharedNode.get())->isTextField();
 
308
 
 
309
    return m_innerNonSharedNode->isContentEditable();
 
310
}
 
311
 
 
312
} // namespace WebCore