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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 // Dump SVGElementInstance object tree - useful to debug instanceRoot problems | 46 // Dump SVGElementInstance object tree - useful to debug instanceRoot problems |
47 // #define DUMP_INSTANCE_TREE | 47 // #define DUMP_INSTANCE_TREE |
48 | 48 |
49 // Dump the deep-expanded shadow tree (where the renderers are built from) | 49 // Dump the deep-expanded shadow tree (where the renderers are built from) |
50 // #define DUMP_SHADOW_TREE | 50 // #define DUMP_SHADOW_TREE |
51 | 51 |
52 namespace WebCore { | 52 namespace WebCore { |
53 | 53 |
54 // Animated property definitions | 54 // Animated property definitions |
55 DEFINE_ANIMATED_STRING(SVGUseElement, XLinkNames::hrefAttr, Href, href) | |
56 | 55 |
57 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement) | 56 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement) |
58 REGISTER_LOCAL_ANIMATED_PROPERTY(href) | |
59 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) | 57 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) |
60 END_REGISTER_ANIMATED_PROPERTIES | 58 END_REGISTER_ANIMATED_PROPERTIES |
61 | 59 |
62 inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser
) | 60 inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser
) |
63 : SVGGraphicsElement(SVGNames::useTag, document) | 61 : SVGGraphicsElement(SVGNames::useTag, document) |
64 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(Len
gthModeWidth))) | 62 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(Len
gthModeWidth))) |
65 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(Len
gthModeHeight))) | 63 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(Len
gthModeHeight))) |
66 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(LengthModeWidth))) | 64 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(LengthModeWidth))) |
67 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(LengthModeHeight))) | 65 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(LengthModeHeight))) |
| 66 , m_href(SVGAnimatedString::create(this, XLinkNames::hrefAttr, SVGString::cr
eate())) |
68 , m_wasInsertedByParser(wasInsertedByParser) | 67 , m_wasInsertedByParser(wasInsertedByParser) |
69 , m_haveFiredLoadEvent(false) | 68 , m_haveFiredLoadEvent(false) |
70 , m_needsShadowTreeRecreation(false) | 69 , m_needsShadowTreeRecreation(false) |
71 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) | 70 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) |
72 { | 71 { |
73 ASSERT(hasCustomStyleCallbacks()); | 72 ASSERT(hasCustomStyleCallbacks()); |
74 ScriptWrappable::init(this); | 73 ScriptWrappable::init(this); |
75 | 74 |
76 addToPropertyMap(m_x); | 75 addToPropertyMap(m_x); |
77 addToPropertyMap(m_y); | 76 addToPropertyMap(m_y); |
78 addToPropertyMap(m_width); | 77 addToPropertyMap(m_width); |
79 addToPropertyMap(m_height); | 78 addToPropertyMap(m_height); |
| 79 addToPropertyMap(m_href); |
80 registerAnimatedPropertiesForSVGUseElement(); | 80 registerAnimatedPropertiesForSVGUseElement(); |
81 } | 81 } |
82 | 82 |
83 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) | 83 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) |
84 { | 84 { |
85 // Always build a #shadow-root for SVGUseElement. | 85 // Always build a #shadow-root for SVGUseElement. |
86 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); | 86 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); |
87 use->ensureUserAgentShadowRoot(); | 87 use->ensureUserAgentShadowRoot(); |
88 return use.release(); | 88 return use.release(); |
89 } | 89 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 if (!isSupportedAttribute(name)) | 133 if (!isSupportedAttribute(name)) |
134 SVGGraphicsElement::parseAttribute(name, value); | 134 SVGGraphicsElement::parseAttribute(name, value); |
135 else if (name == SVGNames::xAttr) | 135 else if (name == SVGNames::xAttr) |
136 m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError); | 136 m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError); |
137 else if (name == SVGNames::yAttr) | 137 else if (name == SVGNames::yAttr) |
138 m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError); | 138 m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError); |
139 else if (name == SVGNames::widthAttr) | 139 else if (name == SVGNames::widthAttr) |
140 m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError); | 140 m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError); |
141 else if (name == SVGNames::heightAttr) | 141 else if (name == SVGNames::heightAttr) |
142 m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError)
; | 142 m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError)
; |
143 else if (SVGURIReference::parseAttribute(name, value)) { | 143 else if (name.matches(XLinkNames::hrefAttr)) |
144 } else | 144 m_href->setBaseValueAsString(value, parseError); |
| 145 else |
145 ASSERT_NOT_REACHED(); | 146 ASSERT_NOT_REACHED(); |
146 | 147 |
147 reportAttributeParsingError(parseError, name, value); | 148 reportAttributeParsingError(parseError, name, value); |
148 } | 149 } |
149 | 150 |
150 #if !ASSERT_DISABLED | 151 #if !ASSERT_DISABLED |
151 static inline bool isWellFormedDocument(Document* document) | 152 static inline bool isWellFormedDocument(Document* document) |
152 { | 153 { |
153 if (document->isXMLDocument()) | 154 if (document->isXMLDocument()) |
154 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; | 155 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; |
(...skipping 21 matching lines...) Expand all Loading... |
176 | 177 |
177 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 178 void SVGUseElement::removedFrom(ContainerNode* rootParent) |
178 { | 179 { |
179 SVGGraphicsElement::removedFrom(rootParent); | 180 SVGGraphicsElement::removedFrom(rootParent); |
180 if (rootParent->inDocument()) | 181 if (rootParent->inDocument()) |
181 clearResourceReferences(); | 182 clearResourceReferences(); |
182 } | 183 } |
183 | 184 |
184 Document* SVGUseElement::referencedDocument() const | 185 Document* SVGUseElement::referencedDocument() const |
185 { | 186 { |
186 if (!isExternalURIReference(hrefCurrentValue(), document())) | 187 if (!isExternalURIReference(m_href->currentValue()->value(), document())) |
187 return &document(); | 188 return &document(); |
188 return externalDocument(); | 189 return externalDocument(); |
189 } | 190 } |
190 | 191 |
191 Document* SVGUseElement::externalDocument() const | 192 Document* SVGUseElement::externalDocument() const |
192 { | 193 { |
193 if (m_resource && m_resource->isLoaded()) { | 194 if (m_resource && m_resource->isLoaded()) { |
194 // Gracefully handle error condition. | 195 // Gracefully handle error condition. |
195 if (m_resource->errorOccurred()) | 196 if (m_resource->errorOccurred()) |
196 return 0; | 197 return 0; |
(...skipping 17 matching lines...) Expand all Loading... |
214 || attrName == SVGNames::yAttr | 215 || attrName == SVGNames::yAttr |
215 || attrName == SVGNames::widthAttr | 216 || attrName == SVGNames::widthAttr |
216 || attrName == SVGNames::heightAttr) { | 217 || attrName == SVGNames::heightAttr) { |
217 updateRelativeLengthsInformation(); | 218 updateRelativeLengthsInformation(); |
218 if (renderer) | 219 if (renderer) |
219 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); | 220 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); |
220 return; | 221 return; |
221 } | 222 } |
222 | 223 |
223 if (SVGURIReference::isKnownAttribute(attrName)) { | 224 if (SVGURIReference::isKnownAttribute(attrName)) { |
224 bool isExternalReference = isExternalURIReference(hrefCurrentValue(), do
cument()); | 225 bool isExternalReference = isExternalURIReference(m_href->currentValue()
->value(), document()); |
225 if (isExternalReference) { | 226 if (isExternalReference) { |
226 KURL url = document().completeURL(hrefCurrentValue()); | 227 KURL url = document().completeURL(m_href->currentValue()->value()); |
227 if (url.hasFragmentIdentifier()) { | 228 if (url.hasFragmentIdentifier()) { |
228 FetchRequest request(ResourceRequest(url.string()), localName())
; | 229 FetchRequest request(ResourceRequest(url.string()), localName())
; |
229 setDocumentResource(document().fetcher()->fetchSVGDocument(reque
st)); | 230 setDocumentResource(document().fetcher()->fetchSVGDocument(reque
st)); |
230 } | 231 } |
231 } else { | 232 } else { |
232 setDocumentResource(0); | 233 setDocumentResource(0); |
233 } | 234 } |
234 | 235 |
235 if (!m_wasInsertedByParser) | 236 if (!m_wasInsertedByParser) |
236 buildPendingResource(); | 237 buildPendingResource(); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 | 380 |
380 void SVGUseElement::buildPendingResource() | 381 void SVGUseElement::buildPendingResource() |
381 { | 382 { |
382 if (!referencedDocument() || isInShadowTree()) | 383 if (!referencedDocument() || isInShadowTree()) |
383 return; | 384 return; |
384 clearResourceReferences(); | 385 clearResourceReferences(); |
385 if (!inDocument()) | 386 if (!inDocument()) |
386 return; | 387 return; |
387 | 388 |
388 AtomicString id; | 389 AtomicString id; |
389 Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentVal
ue(), document(), &id, externalDocument()); | 390 Element* target = SVGURIReference::targetElementFromIRIString(m_href->curren
tValue()->value(), document(), &id, externalDocument()); |
390 if (!target || !target->inDocument()) { | 391 if (!target || !target->inDocument()) { |
391 // If we can't find the target of an external element, just give up. | 392 // If we can't find the target of an external element, just give up. |
392 // We can't observe if the target somewhen enters the external document,
nor should we do it. | 393 // We can't observe if the target somewhen enters the external document,
nor should we do it. |
393 if (externalDocument()) | 394 if (externalDocument()) |
394 return; | 395 return; |
395 if (id.isEmpty()) | 396 if (id.isEmpty()) |
396 return; | 397 return; |
397 | 398 |
398 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); | 399 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); |
399 ASSERT(hasPendingResources()); | 400 ASSERT(hasPendingResources()); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 | 615 |
615 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, to
SVGUseElement(target), newTarget); | 616 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, to
SVGUseElement(target), newTarget); |
616 SVGElementInstance* newInstancePtr = newInstance.get(); | 617 SVGElementInstance* newInstancePtr = newInstance.get(); |
617 targetInstance->appendChild(newInstance.release()); | 618 targetInstance->appendChild(newInstance.release()); |
618 buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse); | 619 buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse); |
619 } | 620 } |
620 | 621 |
621 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
e* targetInstance, SVGElement*& newTarget) | 622 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
e* targetInstance, SVGElement*& newTarget) |
622 { | 623 { |
623 ASSERT(referencedDocument()); | 624 ASSERT(referencedDocument()); |
624 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hr
efCurrentValue(), *referencedDocument()); | 625 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->m_
href->currentValue()->value(), *referencedDocument()); |
625 newTarget = 0; | 626 newTarget = 0; |
626 if (targetElement && targetElement->isSVGElement()) | 627 if (targetElement && targetElement->isSVGElement()) |
627 newTarget = toSVGElement(targetElement); | 628 newTarget = toSVGElement(targetElement); |
628 | 629 |
629 if (!newTarget) | 630 if (!newTarget) |
630 return false; | 631 return false; |
631 | 632 |
632 // Shortcut for self-references | 633 // Shortcut for self-references |
633 if (newTarget == this) | 634 if (newTarget == this) |
634 return true; | 635 return true; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 // | 689 // |
689 // Short answer: Because we may miss to expand some elements. Ie. if a <symb
ol> | 690 // Short answer: Because we may miss to expand some elements. Ie. if a <symb
ol> |
690 // contains <use> tags, we'd miss them. So once we're done with settin' up t
he | 691 // contains <use> tags, we'd miss them. So once we're done with settin' up t
he |
691 // actual shadow tree (after the special case modification for svg/symbol) w
e have | 692 // actual shadow tree (after the special case modification for svg/symbol) w
e have |
692 // to walk it completely and expand all <use> elements. | 693 // to walk it completely and expand all <use> elements. |
693 if (element->hasTagName(SVGNames::useTag)) { | 694 if (element->hasTagName(SVGNames::useTag)) { |
694 SVGUseElement* use = toSVGUseElement(element); | 695 SVGUseElement* use = toSVGUseElement(element); |
695 ASSERT(!use->resourceIsStillLoading()); | 696 ASSERT(!use->resourceIsStillLoading()); |
696 | 697 |
697 ASSERT(referencedDocument()); | 698 ASSERT(referencedDocument()); |
698 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->hrefCurrentValue(), *referencedDocument()); | 699 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->m_href->currentValue()->value(), *referencedDocument()); |
699 SVGElement* target = 0; | 700 SVGElement* target = 0; |
700 if (targetElement && targetElement->isSVGElement()) | 701 if (targetElement && targetElement->isSVGElement()) |
701 target = toSVGElement(targetElement); | 702 target = toSVGElement(targetElement); |
702 | 703 |
703 // Don't ASSERT(target) here, it may be "pending", too. | 704 // Don't ASSERT(target) here, it may be "pending", too. |
704 // Setup sub-shadow tree root node | 705 // Setup sub-shadow tree root node |
705 RefPtr<SVGGElement> cloneParent = SVGGElement::create(*referencedDocumen
t()); | 706 RefPtr<SVGGElement> cloneParent = SVGGElement::create(*referencedDocumen
t()); |
706 use->cloneChildNodes(cloneParent.get()); | 707 use->cloneChildNodes(cloneParent.get()); |
707 | 708 |
708 // Spec: In the generated content, the 'use' will be replaced by 'g', wh
ere all attributes from the | 709 // 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... |
981 | 982 |
982 if (m_resource) | 983 if (m_resource) |
983 m_resource->removeClient(this); | 984 m_resource->removeClient(this); |
984 | 985 |
985 m_resource = resource; | 986 m_resource = resource; |
986 if (m_resource) | 987 if (m_resource) |
987 m_resource->addClient(this); | 988 m_resource->addClient(this); |
988 } | 989 } |
989 | 990 |
990 } | 991 } |
OLD | NEW |