Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGForeignObjectElement.cpp
1 /*
2  * Copyright (C) 2006 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
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 #include "config.h"
22 #include "core/svg/SVGForeignObjectElement.h"
23
24 #include "core/XLinkNames.h"
25 #include "core/frame/UseCounter.h"
26 #include "core/rendering/svg/RenderSVGForeignObject.h"
27 #include "core/rendering/svg/RenderSVGResource.h"
28 #include "core/svg/SVGLength.h"
29 #include "wtf/Assertions.h"
30
31 namespace blink {
32
33 inline SVGForeignObjectElement::SVGForeignObjectElement(Document& document)
34     : SVGGraphicsElement(SVGNames::foreignObjectTag, document)
35     , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
36     , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
37     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
38     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
39 {
40     addToPropertyMap(m_x);
41     addToPropertyMap(m_y);
42     addToPropertyMap(m_width);
43     addToPropertyMap(m_height);
44
45     UseCounter::count(document, UseCounter::SVGForeignObjectElement);
46 }
47
48 DEFINE_NODE_FACTORY(SVGForeignObjectElement)
49
50 bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName)
51 {
52     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
53     if (supportedAttributes.isEmpty()) {
54         supportedAttributes.add(SVGNames::xAttr);
55         supportedAttributes.add(SVGNames::yAttr);
56         supportedAttributes.add(SVGNames::widthAttr);
57         supportedAttributes.add(SVGNames::heightAttr);
58     }
59     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
60 }
61
62 void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
63 {
64     parseAttributeNew(name, value);
65 }
66
67 bool SVGForeignObjectElement::isPresentationAttribute(const QualifiedName& name) const
68 {
69     if (name == SVGNames::widthAttr || name == SVGNames::heightAttr)
70         return true;
71     return SVGGraphicsElement::isPresentationAttribute(name);
72 }
73
74 void SVGForeignObjectElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
75 {
76     if (name == SVGNames::widthAttr || name == SVGNames::heightAttr) {
77         RefPtr<SVGLength> length = SVGLength::create(LengthModeOther);
78         TrackExceptionState exceptionState;
79         length->setValueAsString(value, exceptionState);
80         if (!exceptionState.hadException()) {
81             if (name == SVGNames::widthAttr)
82                 addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
83             else if (name == SVGNames::heightAttr)
84                 addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
85         }
86     } else {
87         SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
88     }
89 }
90
91 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
92 {
93     if (!isSupportedAttribute(attrName)) {
94         SVGGraphicsElement::svgAttributeChanged(attrName);
95         return;
96     }
97
98     if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
99         invalidateSVGPresentationAttributeStyle();
100         setNeedsStyleRecalc(LocalStyleChange);
101     }
102
103     SVGElement::InvalidationGuard invalidationGuard(this);
104
105     bool isLengthAttribute = attrName == SVGNames::xAttr
106                           || attrName == SVGNames::yAttr
107                           || attrName == SVGNames::widthAttr
108                           || attrName == SVGNames::heightAttr;
109
110     if (isLengthAttribute)
111         updateRelativeLengthsInformation();
112
113     if (RenderObject* renderer = this->renderer())
114         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
115 }
116
117 RenderObject* SVGForeignObjectElement::createRenderer(RenderStyle*)
118 {
119     return new RenderSVGForeignObject(this);
120 }
121
122 bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style)
123 {
124     // Suppress foreignObject renderers in SVG hidden containers.
125     // (https://bugs.webkit.org/show_bug.cgi?id=87297)
126     // Note that we currently do not support foreignObject instantiation via <use>, hence it is safe
127     // to use parentElement() here. If that changes, this method should be updated to use
128     // parentOrShadowHostElement() instead.
129     Element* ancestor = parentElement();
130     while (ancestor && ancestor->isSVGElement()) {
131         if (ancestor->renderer() && ancestor->renderer()->isSVGHiddenContainer())
132             return false;
133
134         ancestor = ancestor->parentElement();
135     }
136
137     return SVGGraphicsElement::rendererIsNeeded(style);
138 }
139
140 bool SVGForeignObjectElement::selfHasRelativeLengths() const
141 {
142     return m_x->currentValue()->isRelative()
143         || m_y->currentValue()->isRelative()
144         || m_width->currentValue()->isRelative()
145         || m_height->currentValue()->isRelative();
146 }
147
148 } // namespace blink