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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if (m_resource && m_resource->isLoaded()) { | 187 if (m_resource && m_resource->isLoaded()) { |
188 // Gracefully handle error condition. | 188 // Gracefully handle error condition. |
189 if (m_resource->errorOccurred()) | 189 if (m_resource->errorOccurred()) |
190 return 0; | 190 return 0; |
191 ASSERT(m_resource->document()); | 191 ASSERT(m_resource->document()); |
192 return m_resource->document(); | 192 return m_resource->document(); |
193 } | 193 } |
194 return 0; | 194 return 0; |
195 } | 195 } |
196 | 196 |
| 197 void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* sha
dowElement, const SVGElement& originalElement) |
| 198 { |
| 199 ASSERT(shadowElement); |
| 200 if (isSVGSymbolElement(*shadowElement)) { |
| 201 // Spec (<use> on <symbol>): This generated 'svg' will always have expli
cit values for attributes width and height. |
| 202 // If attributes width and/or height are provided on the 'use' element,
then these attributes |
| 203 // will be transferred to the generated 'svg'. If attributes width and/o
r height are not specified, |
| 204 // the generated 'svg' element will use values of 100% for these attribu
tes. |
| 205 shadowElement->setAttribute(SVGNames::widthAttr, use.width()->isSpecifie
d() ? AtomicString(use.width()->currentValue()->valueAsString()) : "100%"); |
| 206 shadowElement->setAttribute(SVGNames::heightAttr, use.height()->isSpecif
ied() ? AtomicString(use.height()->currentValue()->valueAsString()) : "100%"); |
| 207 } else if (isSVGSVGElement(*shadowElement)) { |
| 208 // Spec (<use> on <svg>): If attributes width and/or height are provided
on the 'use' element, then these |
| 209 // values will override the corresponding attributes on the 'svg' in the
generated tree. |
| 210 if (use.width()->isSpecified()) |
| 211 shadowElement->setAttribute(SVGNames::widthAttr, AtomicString(use.wi
dth()->currentValue()->valueAsString())); |
| 212 else |
| 213 shadowElement->setAttribute(SVGNames::widthAttr, originalElement.get
Attribute(SVGNames::widthAttr)); |
| 214 if (use.height()->isSpecified()) |
| 215 shadowElement->setAttribute(SVGNames::heightAttr, AtomicString(use.h
eight()->currentValue()->valueAsString())); |
| 216 else |
| 217 shadowElement->setAttribute(SVGNames::heightAttr, originalElement.ge
tAttribute(SVGNames::heightAttr)); |
| 218 } |
| 219 } |
| 220 |
197 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) | 221 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) |
198 { | 222 { |
199 if (!isSupportedAttribute(attrName)) { | 223 if (!isSupportedAttribute(attrName)) { |
200 SVGGraphicsElement::svgAttributeChanged(attrName); | 224 SVGGraphicsElement::svgAttributeChanged(attrName); |
201 return; | 225 return; |
202 } | 226 } |
203 | 227 |
204 SVGElementInstance::InvalidationGuard invalidationGuard(this); | 228 SVGElementInstance::InvalidationGuard invalidationGuard(this); |
205 | 229 |
206 RenderObject* renderer = this->renderer(); | 230 RenderObject* renderer = this->renderer(); |
207 if (attrName == SVGNames::xAttr | 231 if (attrName == SVGNames::xAttr |
208 || attrName == SVGNames::yAttr | 232 || attrName == SVGNames::yAttr |
209 || attrName == SVGNames::widthAttr | 233 || attrName == SVGNames::widthAttr |
210 || attrName == SVGNames::heightAttr) { | 234 || attrName == SVGNames::heightAttr) { |
211 updateRelativeLengthsInformation(); | 235 updateRelativeLengthsInformation(); |
| 236 if (m_targetElementInstance) { |
| 237 ASSERT(m_targetElementInstance->correspondingElement()); |
| 238 transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance->sh
adowTreeElement(), *m_targetElementInstance->correspondingElement()); |
| 239 } |
212 if (renderer) | 240 if (renderer) |
213 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); | 241 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); |
214 return; | 242 return; |
215 } | 243 } |
216 | 244 |
217 if (SVGURIReference::isKnownAttribute(attrName)) { | 245 if (SVGURIReference::isKnownAttribute(attrName)) { |
218 bool isExternalReference = isExternalURIReference(hrefString(), document
()); | 246 bool isExternalReference = isExternalURIReference(hrefString(), document
()); |
219 if (isExternalReference) { | 247 if (isExternalReference) { |
220 KURL url = document().completeURL(hrefString()); | 248 KURL url = document().completeURL(hrefString()); |
221 if (url.hasFragmentIdentifier()) { | 249 if (url.hasFragmentIdentifier()) { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 expandUseElementsInShadowTree(shadowTreeRootElement); | 488 expandUseElementsInShadowTree(shadowTreeRootElement); |
461 | 489 |
462 // Expand all <symbol> elements in the shadow tree. | 490 // Expand all <symbol> elements in the shadow tree. |
463 // Expand means: replace the actual <symbol> element by the <svg> element. | 491 // Expand means: replace the actual <symbol> element by the <svg> element. |
464 expandSymbolElementsInShadowTree(shadowTreeRootElement); | 492 expandSymbolElementsInShadowTree(shadowTreeRootElement); |
465 | 493 |
466 // Now that the shadow tree is completly expanded, we can associate | 494 // Now that the shadow tree is completly expanded, we can associate |
467 // shadow tree elements <-> instances in the instance tree. | 495 // shadow tree elements <-> instances in the instance tree. |
468 associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild()
, m_targetElementInstance.get()); | 496 associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild()
, m_targetElementInstance.get()); |
469 | 497 |
| 498 ASSERT(m_targetElementInstance->correspondingElement()); |
| 499 transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance->shadowTree
Element(), *m_targetElementInstance->correspondingElement()); |
| 500 |
470 // If no shadow tree element is present, this means that the reference root | 501 // If no shadow tree element is present, this means that the reference root |
471 // element was removed, as it is disallowed (ie. <use> on <foreignObject>) | 502 // element was removed, as it is disallowed (ie. <use> on <foreignObject>) |
472 // Do NOT leave an inconsistent instance tree around, instead destruct it. | 503 // Do NOT leave an inconsistent instance tree around, instead destruct it. |
473 if (!m_targetElementInstance->shadowTreeElement()) { | 504 if (!m_targetElementInstance->shadowTreeElement()) { |
474 clearResourceReferences(); | 505 clearResourceReferences(); |
475 return; | 506 return; |
476 } | 507 } |
477 | 508 |
478 ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowT
reeRootElement); | 509 ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowT
reeRootElement); |
479 | 510 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 RefPtr<SVGGElement> cloneParent = SVGGElement::create(referencedScope()-
>document()); | 726 RefPtr<SVGGElement> cloneParent = SVGGElement::create(referencedScope()-
>document()); |
696 use->cloneChildNodes(cloneParent.get()); | 727 use->cloneChildNodes(cloneParent.get()); |
697 | 728 |
698 // Spec: In the generated content, the 'use' will be replaced by 'g', wh
ere all attributes from the | 729 // Spec: In the generated content, the 'use' will be replaced by 'g', wh
ere all attributes from the |
699 // 'use' element except for x, y, width, height and xlink:href are trans
ferred to the generated 'g' element. | 730 // 'use' element except for x, y, width, height and xlink:href are trans
ferred to the generated 'g' element. |
700 transferUseAttributesToReplacedElement(use, cloneParent.get()); | 731 transferUseAttributesToReplacedElement(use, cloneParent.get()); |
701 | 732 |
702 if (target && !isDisallowedElement(target)) { | 733 if (target && !isDisallowedElement(target)) { |
703 RefPtr<Element> newChild = target->cloneElementWithChildren(); | 734 RefPtr<Element> newChild = target->cloneElementWithChildren(); |
704 ASSERT(newChild->isSVGElement()); | 735 ASSERT(newChild->isSVGElement()); |
| 736 transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get())
, *target); |
705 cloneParent->appendChild(newChild.release()); | 737 cloneParent->appendChild(newChild.release()); |
706 } | 738 } |
707 | 739 |
708 // We don't walk the target tree element-by-element, and clone each elem
ent, | 740 // We don't walk the target tree element-by-element, and clone each elem
ent, |
709 // but instead use cloneElementWithChildren(). This is an optimization f
or the common | 741 // but instead use cloneElementWithChildren(). This is an optimization f
or the common |
710 // case where <use> doesn't contain disallowed elements (ie. <foreignObj
ect>). | 742 // case where <use> doesn't contain disallowed elements (ie. <foreignObj
ect>). |
711 // Though if there are disallowed elements in the subtree, we have to re
move them. | 743 // Though if there are disallowed elements in the subtree, we have to re
move them. |
712 // For instance: <use> on <g> containing <foreignObject> (indirect case)
. | 744 // For instance: <use> on <g> containing <foreignObject> (indirect case)
. |
713 if (subtreeContainsDisallowedElement(cloneParent.get())) | 745 if (subtreeContainsDisallowedElement(cloneParent.get())) |
714 removeDisallowedElementsFromSubtree(*cloneParent); | 746 removeDisallowedElementsFromSubtree(*cloneParent); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 | 997 |
966 if (m_resource) | 998 if (m_resource) |
967 m_resource->removeClient(this); | 999 m_resource->removeClient(this); |
968 | 1000 |
969 m_resource = resource; | 1001 m_resource = resource; |
970 if (m_resource) | 1002 if (m_resource) |
971 m_resource->addClient(this); | 1003 m_resource->addClient(this); |
972 } | 1004 } |
973 | 1005 |
974 } | 1006 } |
OLD | NEW |