File indexing completed on 2024-04-28 15:24:27

0001 /*
0002     Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2007 Rob Buis <buis@kde.org>
0004                   2007 Eric Seidel <eric@webkit.org>
0005 
0006     This file is part of the KDE project
0007 
0008     This library is free software; you can redistribute it and/or
0009     modify it under the terms of the GNU Library General Public
0010     License as published by the Free Software Foundation; either
0011     version 2 of the License, or (at your option) any later version.
0012 
0013     This library is distributed in the hope that it will be useful,
0014     but WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     Library General Public License for more details.
0017 
0018     You should have received a copy of the GNU Library General Public License
0019     along with this library; see the file COPYING.LIB.  If not, write to
0020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021     Boston, MA 02110-1301, USA.
0022 */
0023 
0024 #include "wtf/Platform.h"
0025 
0026 #if ENABLE(SVG)
0027 #include "SVGAElement.h"
0028 
0029 /*#include "Attr.h"
0030 #include "CSSHelper.h"*/
0031 #include "Document.h"
0032 /*#include "EventHandler.h"
0033 #include "EventNames.h"
0034 #include "Frame.h"
0035 #include "FrameLoader.h"
0036 #include "KeyboardEvent.h"
0037 #include "MouseEvent.h"
0038 #include "PlatformMouseEvent.h"*/
0039 #include "RenderSVGTransformableContainer.h"
0040 #include "RenderSVGInline.h"
0041 /*#include "ResourceRequest.h"
0042 #include "SVGSMILElement.h"*/
0043 #include "SVGNames.h"
0044 #include "XLinkNames.h"
0045 
0046 namespace WebCore
0047 {
0048 
0049 //using namespace EventNames;
0050 
0051 SVGAElement::SVGAElement(const QualifiedName &tagName, Document *doc)
0052     : SVGStyledTransformableElement(tagName, doc)
0053     , SVGURIReference()
0054     , SVGTests()
0055     , SVGLangSpace()
0056     , SVGExternalResourcesRequired()
0057 {
0058 }
0059 
0060 SVGAElement::~SVGAElement()
0061 {
0062 }
0063 
0064 String SVGAElement::title() const
0065 {
0066     return getAttribute(XLinkNames::titleAttr);
0067 }
0068 
0069 ANIMATED_PROPERTY_DEFINITIONS(SVGAElement, String, String, string, Target, target, SVGNames::targetAttr, m_target)
0070 
0071 void SVGAElement::parseMappedAttribute(MappedAttribute *attr)
0072 {
0073     if (attr->name() == SVGNames::targetAttr) {
0074         setTargetBaseValue(attr->value());
0075     } else {
0076         if (SVGURIReference::parseMappedAttribute(attr)) {
0077             return;
0078         }
0079         if (SVGTests::parseMappedAttribute(attr)) {
0080             return;
0081         }
0082         if (SVGLangSpace::parseMappedAttribute(attr)) {
0083             return;
0084         }
0085         if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) {
0086             return;
0087         }
0088         SVGStyledTransformableElement::parseMappedAttribute(attr);
0089     }
0090 }
0091 
0092 void SVGAElement::svgAttributeChanged(const QualifiedName &attrName)
0093 {
0094     SVGStyledTransformableElement::svgAttributeChanged(attrName);
0095 
0096     // Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes
0097     // as none of the other properties changes the linking behaviour for our <a> element.
0098     if (SVGURIReference::isKnownAttribute(attrName)) {
0099         /*khtml FIXME bool wasLink = m_isLink;
0100         m_isLink = !href().isNull();
0101 
0102         if (wasLink != m_isLink)
0103             setChanged();*/
0104     }
0105 }
0106 
0107 RenderObject *SVGAElement::createRenderer(RenderArena *arena, RenderStyle *style)
0108 {
0109     Q_UNUSED(style);
0110     if (static_cast<SVGElement *>(parent())->isTextContent()) {
0111         return new(arena) RenderSVGInline(this);
0112     }
0113 
0114     return new(arena) RenderSVGTransformableContainer(this);
0115 }
0116 
0117 void SVGAElement::defaultEventHandler(Event *evt)
0118 {
0119     /*if (m_isLink && (evt->type() == clickEvent || (evt->type() == keydownEvent && m_focused))) {
0120         MouseEvent* e = 0;
0121         if (evt->type() == clickEvent && evt->isMouseEvent())
0122             e = static_cast<MouseEvent*>(evt);
0123 
0124         KeyboardEvent* k = 0;
0125         if (evt->type() == keydownEvent && evt->isKeyboardEvent())
0126             k = static_cast<KeyboardEvent*>(evt);
0127 
0128         if (e && e->button() == RightButton) {
0129             SVGStyledTransformableElement::defaultEventHandler(evt);
0130             return;
0131         }
0132 
0133         if (k) {
0134             if (k->keyIdentifier() != "Enter") {
0135                 SVGStyledTransformableElement::defaultEventHandler(evt);
0136                 return;
0137             }
0138             evt->setDefaultHandled();
0139             dispatchSimulatedClick(evt);
0140             return;
0141         }
0142 
0143         String target = this->target();
0144         if (e && e->button() == MiddleButton)
0145             target = "_blank";
0146         else if (target.isEmpty()) // if target is empty, default to "_self" or use xlink:target if set
0147             target = (getAttribute(XLinkNames::showAttr) == "new") ? "_blank" : "_self";
0148 
0149         if (!evt->defaultPrevented()) {
0150             String url = parseURL(href());
0151     #if ENABLE(SVG_ANIMATION)
0152             if (url.startsWith("#")) {
0153                 Element* targetElement = document()->getElementById(url.substring(1));
0154                 if (SVGSMILElement::isSMILElement(targetElement)) {
0155                     SVGSMILElement* timed = static_cast<SVGSMILElement*>(targetElement);
0156                     timed->beginByLinkActivation();
0157                     evt->setDefaultHandled();
0158                     SVGStyledTransformableElement::defaultEventHandler(evt);
0159                     return;
0160                 }
0161             }
0162     #endif
0163             if (document()->frame())
0164                 document()->frame()->loader()->urlSelected(document()->completeURL(url), target, evt, false, true);
0165         }
0166 
0167         evt->setDefaultHandled();
0168     }*/
0169 
0170     SVGStyledTransformableElement::defaultEventHandler(evt);
0171 }
0172 
0173 bool SVGAElement::supportsFocus() const
0174 {
0175     /*if (isContentEditable())
0176         return SVGStyledTransformableElement::supportsFocus();*/
0177     return isFocusable() || (document() && !document()->haveStylesheetsLoaded());
0178 }
0179 
0180 bool SVGAElement::isFocusableImpl(FocusType ft) const
0181 {
0182     if (ft == FT_Mouse) {
0183         return false;
0184     }
0185 
0186     if (isContentEditable()) {
0187         return SVGStyledTransformableElement::isFocusableImpl(ft);
0188     }
0189 
0190     // TODO: implement focus rules for SVG
0191     return false;
0192 }
0193 
0194 bool SVGAElement::childShouldCreateRenderer(Node *child) const
0195 {
0196     // https://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
0197     // The 'a' element may contain any element that its parent may contain, except itself.
0198     if (child->hasTagName(SVGNames::aTag)) {
0199         return false;
0200     }
0201     if (parent() && parent()->isSVGElement()) {
0202         return static_cast<SVGElement *>(parent())->childShouldCreateRenderer(child);
0203     }
0204 
0205     return SVGElement::childShouldCreateRenderer(child);
0206 }
0207 
0208 } // namespace WebCore
0209 
0210 #endif // ENABLE(SVG)