2 Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2007 Rob Buis <buis@kde.org>
4 2007 Eric Seidel <eric@webkit.org>
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.
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.
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., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
25 #include "SVGAElement.h"
28 #include "CSSHelper.h"
30 #include "EventHandler.h"
31 #include "EventNames.h"
33 #include "FrameLoader.h"
34 #include "FrameLoaderTypes.h"
35 #include "KeyboardEvent.h"
36 #include "MappedAttribute.h"
37 #include "MouseEvent.h"
38 #include "PlatformMouseEvent.h"
39 #include "RenderSVGInline.h"
40 #include "RenderSVGTransformableContainer.h"
41 #include "ResourceRequest.h"
43 #include "SVGSMILElement.h"
44 #include "XLinkNames.h"
48 SVGAElement::SVGAElement(const QualifiedName
& tagName
, Document
*doc
)
49 : SVGStyledTransformableElement(tagName
, doc
)
53 , SVGExternalResourcesRequired()
54 , m_target(this, SVGNames::targetAttr
)
55 , m_href(this, XLinkNames::hrefAttr
)
56 , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr
, false)
60 SVGAElement::~SVGAElement()
64 String
SVGAElement::title() const
66 return getAttribute(XLinkNames::titleAttr
);
69 void SVGAElement::parseMappedAttribute(MappedAttribute
* attr
)
71 if (attr
->name() == SVGNames::targetAttr
)
72 setTargetBaseValue(attr
->value());
74 if (SVGURIReference::parseMappedAttribute(attr
))
76 if (SVGTests::parseMappedAttribute(attr
))
78 if (SVGLangSpace::parseMappedAttribute(attr
))
80 if (SVGExternalResourcesRequired::parseMappedAttribute(attr
))
82 SVGStyledTransformableElement::parseMappedAttribute(attr
);
86 void SVGAElement::svgAttributeChanged(const QualifiedName
& attrName
)
88 SVGStyledTransformableElement::svgAttributeChanged(attrName
);
90 // Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes
91 // as none of the other properties changes the linking behaviour for our <a> element.
92 if (SVGURIReference::isKnownAttribute(attrName
)) {
93 bool wasLink
= isLink();
94 setIsLink(!href().isNull());
96 if (wasLink
!= isLink())
97 setNeedsStyleRecalc();
101 RenderObject
* SVGAElement::createRenderer(RenderArena
* arena
, RenderStyle
*)
103 if (static_cast<SVGElement
*>(parent())->isTextContent())
104 return new (arena
) RenderSVGInline(this);
106 return new (arena
) RenderSVGTransformableContainer(this);
109 void SVGAElement::defaultEventHandler(Event
* evt
)
111 if (isLink() && (evt
->type() == eventNames().clickEvent
|| (evt
->type() == eventNames().keydownEvent
&& focused()))) {
113 if (evt
->type() == eventNames().clickEvent
&& evt
->isMouseEvent())
114 e
= static_cast<MouseEvent
*>(evt
);
116 KeyboardEvent
* k
= 0;
117 if (evt
->type() == eventNames().keydownEvent
&& evt
->isKeyboardEvent())
118 k
= static_cast<KeyboardEvent
*>(evt
);
120 if (e
&& e
->button() == RightButton
) {
121 SVGStyledTransformableElement::defaultEventHandler(evt
);
126 if (k
->keyIdentifier() != "Enter") {
127 SVGStyledTransformableElement::defaultEventHandler(evt
);
130 evt
->setDefaultHandled();
131 dispatchSimulatedClick(evt
);
135 String target
= this->target();
136 if (e
&& e
->button() == MiddleButton
)
138 else if (target
.isEmpty()) // if target is empty, default to "_self" or use xlink:target if set
139 target
= (getAttribute(XLinkNames::showAttr
) == "new") ? "_blank" : "_self";
141 if (!evt
->defaultPrevented()) {
142 String url
= deprecatedParseURL(href());
143 #if ENABLE(SVG_ANIMATION)
144 if (url
.startsWith("#")) {
145 Element
* targetElement
= document()->getElementById(url
.substring(1));
146 if (SVGSMILElement::isSMILElement(targetElement
)) {
147 SVGSMILElement
* timed
= static_cast<SVGSMILElement
*>(targetElement
);
148 timed
->beginByLinkActivation();
149 evt
->setDefaultHandled();
150 SVGStyledTransformableElement::defaultEventHandler(evt
);
155 if (document()->frame())
156 document()->frame()->loader()->urlSelected(document()->completeURL(url
), target
, evt
, false, false, true, SendReferrer
);
159 evt
->setDefaultHandled();
162 SVGStyledTransformableElement::defaultEventHandler(evt
);
165 bool SVGAElement::supportsFocus() const
167 if (isContentEditable())
168 return SVGStyledTransformableElement::supportsFocus();
172 bool SVGAElement::isFocusable() const
174 if (renderer() && renderer()->absoluteClippedOverflowRect().isEmpty())
177 return SVGElement::isFocusable();
180 bool SVGAElement::isMouseFocusable() const
185 bool SVGAElement::isKeyboardFocusable(KeyboardEvent
* event
) const
190 if (!document()->frame())
193 return document()->frame()->eventHandler()->tabsToLinks(event
);
196 bool SVGAElement::childShouldCreateRenderer(Node
* child
) const
198 // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
199 // The 'a' element may contain any element that its parent may contain, except itself.
200 if (child
->hasTagName(SVGNames::aTag
))
202 if (parent() && parent()->isSVGElement())
203 return static_cast<SVGElement
*>(parent())->childShouldCreateRenderer(child
);
205 return SVGElement::childShouldCreateRenderer(child
);
208 } // namespace WebCore
210 #endif // ENABLE(SVG)