| 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 |