OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> |
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> |
4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
6 * Copyright (C) 2012 University of Szeged | 6 * Copyright (C) 2012 University of Szeged |
7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> | 7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 namespace WebCore { | 52 namespace WebCore { |
53 | 53 |
54 // Animated property definitions | 54 // Animated property definitions |
55 | 55 |
56 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement) | 56 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement) |
57 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) | 57 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) |
58 END_REGISTER_ANIMATED_PROPERTIES | 58 END_REGISTER_ANIMATED_PROPERTIES |
59 | 59 |
60 inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser
) | 60 inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser
) |
61 : SVGGraphicsElement(SVGNames::useTag, document) | 61 : SVGGraphicsElement(SVGNames::useTag, document) |
| 62 , SVGURIReference(this) |
62 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(Len
gthModeWidth))) | 63 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(Len
gthModeWidth))) |
63 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(Len
gthModeHeight))) | 64 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(Len
gthModeHeight))) |
64 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(LengthModeWidth))) | 65 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(LengthModeWidth))) |
65 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(LengthModeHeight))) | 66 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(LengthModeHeight))) |
66 , m_href(SVGAnimatedString::create(this, XLinkNames::hrefAttr, SVGString::cr
eate())) | |
67 , m_wasInsertedByParser(wasInsertedByParser) | 67 , m_wasInsertedByParser(wasInsertedByParser) |
68 , m_haveFiredLoadEvent(false) | 68 , m_haveFiredLoadEvent(false) |
69 , m_needsShadowTreeRecreation(false) | 69 , m_needsShadowTreeRecreation(false) |
70 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) | 70 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) |
71 { | 71 { |
72 ASSERT(hasCustomStyleCallbacks()); | 72 ASSERT(hasCustomStyleCallbacks()); |
73 ScriptWrappable::init(this); | 73 ScriptWrappable::init(this); |
74 | 74 |
75 addToPropertyMap(m_x); | 75 addToPropertyMap(m_x); |
76 addToPropertyMap(m_y); | 76 addToPropertyMap(m_y); |
77 addToPropertyMap(m_width); | 77 addToPropertyMap(m_width); |
78 addToPropertyMap(m_height); | 78 addToPropertyMap(m_height); |
79 addToPropertyMap(m_href); | |
80 registerAnimatedPropertiesForSVGUseElement(); | 79 registerAnimatedPropertiesForSVGUseElement(); |
81 } | 80 } |
82 | 81 |
83 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) | 82 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) |
84 { | 83 { |
85 // Always build a #shadow-root for SVGUseElement. | 84 // Always build a #shadow-root for SVGUseElement. |
86 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); | 85 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); |
87 use->ensureUserAgentShadowRoot(); | 86 use->ensureUserAgentShadowRoot(); |
88 return use.release(); | 87 return use.release(); |
89 } | 88 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 supportedAttributes.add(SVGNames::widthAttr); | 122 supportedAttributes.add(SVGNames::widthAttr); |
124 supportedAttributes.add(SVGNames::heightAttr); | 123 supportedAttributes.add(SVGNames::heightAttr); |
125 } | 124 } |
126 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); | 125 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); |
127 } | 126 } |
128 | 127 |
129 void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString
& value) | 128 void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString
& value) |
130 { | 129 { |
131 SVGParsingError parseError = NoError; | 130 SVGParsingError parseError = NoError; |
132 | 131 |
133 if (!isSupportedAttribute(name)) | 132 if (!isSupportedAttribute(name)) { |
134 SVGGraphicsElement::parseAttribute(name, value); | 133 SVGGraphicsElement::parseAttribute(name, value); |
135 else if (name == SVGNames::xAttr) | 134 } else if (name == SVGNames::xAttr) { |
136 m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError); | 135 m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError); |
137 else if (name == SVGNames::yAttr) | 136 } else if (name == SVGNames::yAttr) { |
138 m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError); | 137 m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError); |
139 else if (name == SVGNames::widthAttr) | 138 } else if (name == SVGNames::widthAttr) { |
140 m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError); | 139 m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError); |
141 else if (name == SVGNames::heightAttr) | 140 } else if (name == SVGNames::heightAttr) { |
142 m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError)
; | 141 m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError)
; |
143 else if (name.matches(XLinkNames::hrefAttr)) | 142 } else if (SVGURIReference::parseAttribute(name, value, parseError)) { |
144 m_href->setBaseValueAsString(value, parseError); | 143 } else { |
145 else | |
146 ASSERT_NOT_REACHED(); | 144 ASSERT_NOT_REACHED(); |
| 145 } |
147 | 146 |
148 reportAttributeParsingError(parseError, name, value); | 147 reportAttributeParsingError(parseError, name, value); |
149 } | 148 } |
150 | 149 |
151 #if !ASSERT_DISABLED | 150 #if !ASSERT_DISABLED |
152 static inline bool isWellFormedDocument(Document* document) | 151 static inline bool isWellFormedDocument(Document* document) |
153 { | 152 { |
154 if (document->isXMLDocument()) | 153 if (document->isXMLDocument()) |
155 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; | 154 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; |
156 return true; | 155 return true; |
(...skipping 20 matching lines...) Expand all Loading... |
177 | 176 |
178 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 177 void SVGUseElement::removedFrom(ContainerNode* rootParent) |
179 { | 178 { |
180 SVGGraphicsElement::removedFrom(rootParent); | 179 SVGGraphicsElement::removedFrom(rootParent); |
181 if (rootParent->inDocument()) | 180 if (rootParent->inDocument()) |
182 clearResourceReferences(); | 181 clearResourceReferences(); |
183 } | 182 } |
184 | 183 |
185 Document* SVGUseElement::referencedDocument() const | 184 Document* SVGUseElement::referencedDocument() const |
186 { | 185 { |
187 if (!isExternalURIReference(m_href->currentValue()->value(), document())) | 186 if (!isExternalURIReference(hrefString(), document())) |
188 return &document(); | 187 return &document(); |
189 return externalDocument(); | 188 return externalDocument(); |
190 } | 189 } |
191 | 190 |
192 Document* SVGUseElement::externalDocument() const | 191 Document* SVGUseElement::externalDocument() const |
193 { | 192 { |
194 if (m_resource && m_resource->isLoaded()) { | 193 if (m_resource && m_resource->isLoaded()) { |
195 // Gracefully handle error condition. | 194 // Gracefully handle error condition. |
196 if (m_resource->errorOccurred()) | 195 if (m_resource->errorOccurred()) |
197 return 0; | 196 return 0; |
(...skipping 17 matching lines...) Expand all Loading... |
215 || attrName == SVGNames::yAttr | 214 || attrName == SVGNames::yAttr |
216 || attrName == SVGNames::widthAttr | 215 || attrName == SVGNames::widthAttr |
217 || attrName == SVGNames::heightAttr) { | 216 || attrName == SVGNames::heightAttr) { |
218 updateRelativeLengthsInformation(); | 217 updateRelativeLengthsInformation(); |
219 if (renderer) | 218 if (renderer) |
220 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); | 219 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); |
221 return; | 220 return; |
222 } | 221 } |
223 | 222 |
224 if (SVGURIReference::isKnownAttribute(attrName)) { | 223 if (SVGURIReference::isKnownAttribute(attrName)) { |
225 bool isExternalReference = isExternalURIReference(m_href->currentValue()
->value(), document()); | 224 bool isExternalReference = isExternalURIReference(hrefString(), document
()); |
226 if (isExternalReference) { | 225 if (isExternalReference) { |
227 KURL url = document().completeURL(m_href->currentValue()->value()); | 226 KURL url = document().completeURL(hrefString()); |
228 if (url.hasFragmentIdentifier()) { | 227 if (url.hasFragmentIdentifier()) { |
229 FetchRequest request(ResourceRequest(url.string()), localName())
; | 228 FetchRequest request(ResourceRequest(url.string()), localName())
; |
230 setDocumentResource(document().fetcher()->fetchSVGDocument(reque
st)); | 229 setDocumentResource(document().fetcher()->fetchSVGDocument(reque
st)); |
231 } | 230 } |
232 } else { | 231 } else { |
233 setDocumentResource(0); | 232 setDocumentResource(0); |
234 } | 233 } |
235 | 234 |
236 if (!m_wasInsertedByParser) | 235 if (!m_wasInsertedByParser) |
237 buildPendingResource(); | 236 buildPendingResource(); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 379 |
381 void SVGUseElement::buildPendingResource() | 380 void SVGUseElement::buildPendingResource() |
382 { | 381 { |
383 if (!referencedDocument() || isInShadowTree()) | 382 if (!referencedDocument() || isInShadowTree()) |
384 return; | 383 return; |
385 clearResourceReferences(); | 384 clearResourceReferences(); |
386 if (!inDocument()) | 385 if (!inDocument()) |
387 return; | 386 return; |
388 | 387 |
389 AtomicString id; | 388 AtomicString id; |
390 Element* target = SVGURIReference::targetElementFromIRIString(m_href->curren
tValue()->value(), document(), &id, externalDocument()); | 389 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(),
document(), &id, externalDocument()); |
391 if (!target || !target->inDocument()) { | 390 if (!target || !target->inDocument()) { |
392 // If we can't find the target of an external element, just give up. | 391 // If we can't find the target of an external element, just give up. |
393 // We can't observe if the target somewhen enters the external document,
nor should we do it. | 392 // We can't observe if the target somewhen enters the external document,
nor should we do it. |
394 if (externalDocument()) | 393 if (externalDocument()) |
395 return; | 394 return; |
396 if (id.isEmpty()) | 395 if (id.isEmpty()) |
397 return; | 396 return; |
398 | 397 |
399 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); | 398 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); |
400 ASSERT(hasPendingResources()); | 399 ASSERT(hasPendingResources()); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 | 614 |
616 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, to
SVGUseElement(target), newTarget); | 615 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, to
SVGUseElement(target), newTarget); |
617 SVGElementInstance* newInstancePtr = newInstance.get(); | 616 SVGElementInstance* newInstancePtr = newInstance.get(); |
618 targetInstance->appendChild(newInstance.release()); | 617 targetInstance->appendChild(newInstance.release()); |
619 buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse); | 618 buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse); |
620 } | 619 } |
621 | 620 |
622 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
e* targetInstance, SVGElement*& newTarget) | 621 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
e* targetInstance, SVGElement*& newTarget) |
623 { | 622 { |
624 ASSERT(referencedDocument()); | 623 ASSERT(referencedDocument()); |
625 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->m_
href->currentValue()->value(), *referencedDocument()); | 624 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hr
efString(), *referencedDocument()); |
626 newTarget = 0; | 625 newTarget = 0; |
627 if (targetElement && targetElement->isSVGElement()) | 626 if (targetElement && targetElement->isSVGElement()) |
628 newTarget = toSVGElement(targetElement); | 627 newTarget = toSVGElement(targetElement); |
629 | 628 |
630 if (!newTarget) | 629 if (!newTarget) |
631 return false; | 630 return false; |
632 | 631 |
633 // Shortcut for self-references | 632 // Shortcut for self-references |
634 if (newTarget == this) | 633 if (newTarget == this) |
635 return true; | 634 return true; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // | 688 // |
690 // Short answer: Because we may miss to expand some elements. Ie. if a <symb
ol> | 689 // Short answer: Because we may miss to expand some elements. Ie. if a <symb
ol> |
691 // contains <use> tags, we'd miss them. So once we're done with settin' up t
he | 690 // contains <use> tags, we'd miss them. So once we're done with settin' up t
he |
692 // actual shadow tree (after the special case modification for svg/symbol) w
e have | 691 // actual shadow tree (after the special case modification for svg/symbol) w
e have |
693 // to walk it completely and expand all <use> elements. | 692 // to walk it completely and expand all <use> elements. |
694 if (element->hasTagName(SVGNames::useTag)) { | 693 if (element->hasTagName(SVGNames::useTag)) { |
695 SVGUseElement* use = toSVGUseElement(element); | 694 SVGUseElement* use = toSVGUseElement(element); |
696 ASSERT(!use->resourceIsStillLoading()); | 695 ASSERT(!use->resourceIsStillLoading()); |
697 | 696 |
698 ASSERT(referencedDocument()); | 697 ASSERT(referencedDocument()); |
699 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->m_href->currentValue()->value(), *referencedDocument()); | 698 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->hrefString(), *referencedDocument()); |
700 SVGElement* target = 0; | 699 SVGElement* target = 0; |
701 if (targetElement && targetElement->isSVGElement()) | 700 if (targetElement && targetElement->isSVGElement()) |
702 target = toSVGElement(targetElement); | 701 target = toSVGElement(targetElement); |
703 | 702 |
704 // Don't ASSERT(target) here, it may be "pending", too. | 703 // Don't ASSERT(target) here, it may be "pending", too. |
705 // Setup sub-shadow tree root node | 704 // Setup sub-shadow tree root node |
706 RefPtr<SVGGElement> cloneParent = SVGGElement::create(*referencedDocumen
t()); | 705 RefPtr<SVGGElement> cloneParent = SVGGElement::create(*referencedDocumen
t()); |
707 use->cloneChildNodes(cloneParent.get()); | 706 use->cloneChildNodes(cloneParent.get()); |
708 | 707 |
709 // Spec: In the generated content, the 'use' will be replaced by 'g', wh
ere all attributes from the | 708 // Spec: In the generated content, the 'use' will be replaced by 'g', wh
ere all attributes from the |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 | 981 |
983 if (m_resource) | 982 if (m_resource) |
984 m_resource->removeClient(this); | 983 m_resource->removeClient(this); |
985 | 984 |
986 m_resource = resource; | 985 m_resource = resource; |
987 if (m_resource) | 986 if (m_resource) |
988 m_resource->addClient(this); | 987 m_resource->addClient(this); |
989 } | 988 } |
990 | 989 |
991 } | 990 } |
OLD | NEW |