• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2000 Simon Hausmann <hausmann@kde.org>
7  * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
8  *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26 
27 #include "config.h"
28 
29 #if ENABLE(WML)
30 #include "WMLAElement.h"
31 
32 #include "DNS.h"
33 #include "Event.h"
34 #include "EventHandler.h"
35 #include "EventNames.h"
36 #include "Frame.h"
37 #include "FrameLoader.h"
38 #include "HTMLNames.h"
39 #include "KeyboardEvent.h"
40 #include "MappedAttribute.h"
41 #include "MouseEvent.h"
42 #include "RenderBox.h"
43 #include "WMLNames.h"
44 
45 namespace WebCore {
46 
47 using namespace WMLNames;
48 
WMLAElement(const QualifiedName & tagName,Document * doc)49 WMLAElement::WMLAElement(const QualifiedName& tagName, Document* doc)
50     : WMLElement(tagName, doc)
51 {
52 }
53 
parseMappedAttribute(MappedAttribute * attr)54 void WMLAElement::parseMappedAttribute(MappedAttribute* attr)
55 {
56     if (attr->name() == HTMLNames::hrefAttr) {
57         bool wasLink = isLink();
58         setIsLink(!attr->isNull());
59         if (wasLink != isLink())
60             setNeedsStyleRecalc();
61         if (isLink() && document()->isDNSPrefetchEnabled()) {
62             String value = attr->value();
63             if (protocolIs(value, "http") || protocolIs(value, "https") || value.startsWith("//"))
64                 prefetchDNS(document()->completeURL(value).host());
65         }
66     } else if (attr->name() == HTMLNames::nameAttr
67                || attr->name() == HTMLNames::titleAttr
68                || attr->name() == HTMLNames::relAttr) {
69         // Do nothing.
70     } else
71         WMLElement::parseMappedAttribute(attr);
72 }
73 
supportsFocus() const74 bool WMLAElement::supportsFocus() const
75 {
76     return isFocusable() || (isLink() && document() && !document()->haveStylesheetsLoaded());
77 }
78 
isFocusable() const79 bool WMLAElement::isFocusable() const
80 {
81     // FIXME: Even if we are not visible, we might have a child that is visible.
82     // Dave wants to fix that some day with a "has visible content" flag or the like.
83     if (!(isLink() && renderer() && renderer()->style()->visibility() == VISIBLE))
84         return false;
85 
86     return true;
87 }
88 
isMouseFocusable() const89 bool WMLAElement::isMouseFocusable() const
90 {
91     return false;
92 }
93 
isKeyboardFocusable(KeyboardEvent * event) const94 bool WMLAElement::isKeyboardFocusable(KeyboardEvent* event) const
95 {
96     if (!isFocusable())
97         return false;
98 
99     if (!document()->frame())
100         return false;
101 
102     if (!document()->frame()->eventHandler()->tabsToLinks(event))
103         return false;
104 
105     if (!renderer() || !renderer()->isBoxModelObject())
106         return false;
107 
108     // Before calling absoluteRects, check for the common case where the renderer
109     // is non-empty, since this is a faster check and almost always returns true.
110     RenderBoxModelObject* box = toRenderBoxModelObject(renderer());
111     if (!box->borderBoundingBox().isEmpty())
112         return true;
113 
114     Vector<IntRect> rects;
115     FloatPoint absPos = renderer()->localToAbsolute();
116     renderer()->absoluteRects(rects, absPos.x(), absPos.y());
117     size_t n = rects.size();
118     for (size_t i = 0; i < n; ++i)
119         if (!rects[i].isEmpty())
120             return true;
121 
122     return false;
123 }
124 
defaultEventHandler(Event * event)125 void WMLAElement::defaultEventHandler(Event* event)
126 {
127     if (isLink() && (event->type() == eventNames().clickEvent || (event->type() == eventNames().keydownEvent && focused()))) {
128         MouseEvent* e = 0;
129         if (event->type() == eventNames().clickEvent && event->isMouseEvent())
130             e = static_cast<MouseEvent*>(event);
131 
132         KeyboardEvent* k = 0;
133         if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent())
134             k = static_cast<KeyboardEvent*>(event);
135 
136         if (e && e->button() == RightButton) {
137             WMLElement::defaultEventHandler(event);
138             return;
139         }
140 
141         if (k) {
142             if (k->keyIdentifier() != "Enter") {
143                 WMLElement::defaultEventHandler(event);
144                 return;
145             }
146 
147             event->setDefaultHandled();
148             dispatchSimulatedClick(event);
149             return;
150         }
151 
152         if (!event->defaultPrevented() && document()->frame()) {
153             KURL url = document()->completeURL(deprecatedParseURL(getAttribute(HTMLNames::hrefAttr)));
154             document()->frame()->loader()->urlSelected(url, target(), event, false, false, true);
155         }
156 
157         event->setDefaultHandled();
158     }
159 
160     WMLElement::defaultEventHandler(event);
161 }
162 
accessKeyAction(bool sendToAnyElement)163 void WMLAElement::accessKeyAction(bool sendToAnyElement)
164 {
165     // send the mouse button events if the caller specified sendToAnyElement
166     dispatchSimulatedClick(0, sendToAnyElement);
167 }
168 
isURLAttribute(Attribute * attr) const169 bool WMLAElement::isURLAttribute(Attribute *attr) const
170 {
171     return attr->name() == HTMLNames::hrefAttr;
172 }
173 
target() const174 String WMLAElement::target() const
175 {
176     return getAttribute(HTMLNames::targetAttr);
177 }
178 
179 }
180 
181 #endif
182