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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 clearResourceReferences(); | 103 clearResourceReferences(); |
104 } | 104 } |
105 | 105 |
106 SVGElementInstance* SVGUseElement::instanceRoot() | 106 SVGElementInstance* SVGUseElement::instanceRoot() |
107 { | 107 { |
108 // If there is no element instance tree, force immediate SVGElementInstance
tree | 108 // If there is no element instance tree, force immediate SVGElementInstance
tree |
109 // creation by asking the document to invoke our recalcStyle function - as w
e can't | 109 // creation by asking the document to invoke our recalcStyle function - as w
e can't |
110 // wait for the lazy creation to happen if e.g. JS wants to access the insta
nceRoot | 110 // wait for the lazy creation to happen if e.g. JS wants to access the insta
nceRoot |
111 // object right after creating the element on-the-fly | 111 // object right after creating the element on-the-fly |
112 if (!m_targetElementInstance) | 112 if (!m_targetElementInstance) |
113 document()->updateLayoutIgnorePendingStylesheets(); | 113 document().updateLayoutIgnorePendingStylesheets(); |
114 | 114 |
115 return m_targetElementInstance.get(); | 115 return m_targetElementInstance.get(); |
116 } | 116 } |
117 | 117 |
118 SVGElementInstance* SVGUseElement::animatedInstanceRoot() const | 118 SVGElementInstance* SVGUseElement::animatedInstanceRoot() const |
119 { | 119 { |
120 // FIXME: Implement me. | 120 // FIXME: Implement me. |
121 return 0; | 121 return 0; |
122 } | 122 } |
123 | 123 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; | 165 return static_cast<XMLDocumentParser*>(document->parser())->wellFormed()
; |
166 return true; | 166 return true; |
167 } | 167 } |
168 | 168 |
169 Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* ro
otParent) | 169 Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* ro
otParent) |
170 { | 170 { |
171 // This functions exists to assure assumptions made in the code regarding SV
GElementInstance creation/destruction are satisfied. | 171 // This functions exists to assure assumptions made in the code regarding SV
GElementInstance creation/destruction are satisfied. |
172 SVGGraphicsElement::insertedInto(rootParent); | 172 SVGGraphicsElement::insertedInto(rootParent); |
173 if (!rootParent->inDocument()) | 173 if (!rootParent->inDocument()) |
174 return InsertionDone; | 174 return InsertionDone; |
175 ASSERT(!m_targetElementInstance || !isWellFormedDocument(document())); | 175 ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); |
176 ASSERT(!hasPendingResources() || !isWellFormedDocument(document())); | 176 ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); |
177 if (!m_wasInsertedByParser) | 177 if (!m_wasInsertedByParser) |
178 buildPendingResource(); | 178 buildPendingResource(); |
179 SVGExternalResourcesRequired::insertedIntoDocument(this); | 179 SVGExternalResourcesRequired::insertedIntoDocument(this); |
180 return InsertionDone; | 180 return InsertionDone; |
181 } | 181 } |
182 | 182 |
183 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 183 void SVGUseElement::removedFrom(ContainerNode* rootParent) |
184 { | 184 { |
185 SVGGraphicsElement::removedFrom(rootParent); | 185 SVGGraphicsElement::removedFrom(rootParent); |
186 if (rootParent->inDocument()) | 186 if (rootParent->inDocument()) |
187 clearResourceReferences(); | 187 clearResourceReferences(); |
188 } | 188 } |
189 | 189 |
190 Document* SVGUseElement::referencedDocument() const | 190 Document* SVGUseElement::referencedDocument() const |
191 { | 191 { |
192 if (!isExternalURIReference(hrefCurrentValue(), document())) | 192 if (!isExternalURIReference(hrefCurrentValue(), &document())) |
193 return document(); | 193 return &document(); |
194 return externalDocument(); | 194 return externalDocument(); |
195 } | 195 } |
196 | 196 |
197 Document* SVGUseElement::externalDocument() const | 197 Document* SVGUseElement::externalDocument() const |
198 { | 198 { |
199 if (m_resource && m_resource->isLoaded()) { | 199 if (m_resource && m_resource->isLoaded()) { |
200 // Gracefully handle error condition. | 200 // Gracefully handle error condition. |
201 if (m_resource->errorOccurred()) | 201 if (m_resource->errorOccurred()) |
202 return 0; | 202 return 0; |
203 ASSERT(m_resource->document()); | 203 ASSERT(m_resource->document()); |
(...skipping 19 matching lines...) Expand all Loading... |
223 updateRelativeLengthsInformation(); | 223 updateRelativeLengthsInformation(); |
224 if (renderer) | 224 if (renderer) |
225 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); | 225 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render
er); |
226 return; | 226 return; |
227 } | 227 } |
228 | 228 |
229 if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) | 229 if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) |
230 return; | 230 return; |
231 | 231 |
232 if (SVGURIReference::isKnownAttribute(attrName)) { | 232 if (SVGURIReference::isKnownAttribute(attrName)) { |
233 bool isExternalReference = isExternalURIReference(hrefCurrentValue(), do
cument()); | 233 bool isExternalReference = isExternalURIReference(hrefCurrentValue(), &d
ocument()); |
234 if (isExternalReference) { | 234 if (isExternalReference) { |
235 KURL url = document()->completeURL(hrefCurrentValue()); | 235 KURL url = document().completeURL(hrefCurrentValue()); |
236 if (url.hasFragmentIdentifier()) { | 236 if (url.hasFragmentIdentifier()) { |
237 FetchRequest request(ResourceRequest(url.string()), localName())
; | 237 FetchRequest request(ResourceRequest(url.string()), localName())
; |
238 setDocumentResource(document()->fetcher()->fetchSVGDocument(requ
est)); | 238 setDocumentResource(document().fetcher()->fetchSVGDocument(reque
st)); |
239 } | 239 } |
240 } else { | 240 } else { |
241 setDocumentResource(0); | 241 setDocumentResource(0); |
242 } | 242 } |
243 | 243 |
244 if (!m_wasInsertedByParser) | 244 if (!m_wasInsertedByParser) |
245 buildPendingResource(); | 245 buildPendingResource(); |
246 | 246 |
247 return; | 247 return; |
248 } | 248 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) | 387 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) |
388 shadowTreeRootElement->removeChildren(); | 388 shadowTreeRootElement->removeChildren(); |
389 | 389 |
390 if (m_targetElementInstance) { | 390 if (m_targetElementInstance) { |
391 m_targetElementInstance->detach(); | 391 m_targetElementInstance->detach(); |
392 m_targetElementInstance = 0; | 392 m_targetElementInstance = 0; |
393 } | 393 } |
394 | 394 |
395 m_needsShadowTreeRecreation = false; | 395 m_needsShadowTreeRecreation = false; |
396 | 396 |
397 ASSERT(document()); | 397 document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); |
398 document()->accessSVGExtensions()->removeAllTargetReferencesForElement(this)
; | |
399 } | 398 } |
400 | 399 |
401 void SVGUseElement::buildPendingResource() | 400 void SVGUseElement::buildPendingResource() |
402 { | 401 { |
403 if (!referencedDocument() || isInShadowTree()) | 402 if (!referencedDocument() || isInShadowTree()) |
404 return; | 403 return; |
405 clearResourceReferences(); | 404 clearResourceReferences(); |
406 if (!inDocument()) | 405 if (!inDocument()) |
407 return; | 406 return; |
408 | 407 |
409 String id; | 408 String id; |
410 Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentVal
ue(), document(), &id, externalDocument()); | 409 Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentVal
ue(), &document(), &id, externalDocument()); |
411 if (!target || !target->inDocument()) { | 410 if (!target || !target->inDocument()) { |
412 // If we can't find the target of an external element, just give up. | 411 // If we can't find the target of an external element, just give up. |
413 // We can't observe if the target somewhen enters the external document,
nor should we do it. | 412 // We can't observe if the target somewhen enters the external document,
nor should we do it. |
414 if (externalDocument()) | 413 if (externalDocument()) |
415 return; | 414 return; |
416 if (id.isEmpty()) | 415 if (id.isEmpty()) |
417 return; | 416 return; |
418 | 417 |
419 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); | 418 referencedDocument()->accessSVGExtensions()->addPendingResource(id, this
); |
420 ASSERT(hasPendingResources()); | 419 ASSERT(hasPendingResources()); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 | 545 |
547 void SVGUseElement::toClipPath(Path& path) | 546 void SVGUseElement::toClipPath(Path& path) |
548 { | 547 { |
549 ASSERT(path.isEmpty()); | 548 ASSERT(path.isEmpty()); |
550 | 549 |
551 Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeEleme
nt() : 0; | 550 Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeEleme
nt() : 0; |
552 if (!n) | 551 if (!n) |
553 return; | 552 return; |
554 | 553 |
555 if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) { | 554 if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) { |
556 if (!isDirectReference(n)) | 555 if (!isDirectReference(n)) { |
557 // Spec: Indirect references are an error (14.3.5) | 556 // Spec: Indirect references are an error (14.3.5) |
558 document()->accessSVGExtensions()->reportError("Not allowed to use i
ndirect reference in <clip-path>"); | 557 document().accessSVGExtensions()->reportError("Not allowed to use in
direct reference in <clip-path>"); |
559 else { | 558 } else { |
560 toSVGGraphicsElement(n)->toClipPath(path); | 559 toSVGGraphicsElement(n)->toClipPath(path); |
561 // FIXME: Avoid manual resolution of x/y here. Its potentially harmf
ul. | 560 // FIXME: Avoid manual resolution of x/y here. Its potentially harmf
ul. |
562 SVGLengthContext lengthContext(this); | 561 SVGLengthContext lengthContext(this); |
563 path.translate(FloatSize(xCurrentValue().value(lengthContext), yCurr
entValue().value(lengthContext))); | 562 path.translate(FloatSize(xCurrentValue().value(lengthContext), yCurr
entValue().value(lengthContext))); |
564 path.transform(animatedLocalTransform()); | 563 path.transform(animatedLocalTransform()); |
565 } | 564 } |
566 } | 565 } |
567 } | 566 } |
568 | 567 |
569 RenderObject* SVGUseElement::rendererClipChild() const | 568 RenderObject* SVGUseElement::rendererClipChild() const |
(...skipping 18 matching lines...) Expand all Loading... |
588 bool targetHasUseTag = target->hasTagName(SVGNames::useTag); | 587 bool targetHasUseTag = target->hasTagName(SVGNames::useTag); |
589 SVGElement* newTarget = 0; | 588 SVGElement* newTarget = 0; |
590 if (targetHasUseTag) { | 589 if (targetHasUseTag) { |
591 foundProblem = hasCycleUseReferencing(toSVGUseElement(target), targetIns
tance, newTarget); | 590 foundProblem = hasCycleUseReferencing(toSVGUseElement(target), targetIns
tance, newTarget); |
592 if (foundProblem) | 591 if (foundProblem) |
593 return; | 592 return; |
594 | 593 |
595 // We only need to track first degree <use> dependencies. Indirect refer
ences are handled | 594 // We only need to track first degree <use> dependencies. Indirect refer
ences are handled |
596 // as the invalidation bubbles up the dependency chain. | 595 // as the invalidation bubbles up the dependency chain. |
597 if (!foundUse) { | 596 if (!foundUse) { |
598 ASSERT(document()); | 597 document().accessSVGExtensions()->addElementReferencingTarget(this,
target); |
599 document()->accessSVGExtensions()->addElementReferencingTarget(this,
target); | |
600 foundUse = true; | 598 foundUse = true; |
601 } | 599 } |
602 } else if (isDisallowedElement(target)) { | 600 } else if (isDisallowedElement(target)) { |
603 foundProblem = true; | 601 foundProblem = true; |
604 return; | 602 return; |
605 } | 603 } |
606 | 604 |
607 // A general description from the SVG spec, describing what buildInstanceTre
e() actually does. | 605 // A general description from the SVG spec, describing what buildInstanceTre
e() actually does. |
608 // | 606 // |
609 // Spec: If the 'use' element references a 'g' which contains two 'rect' ele
ments, then the instance tree | 607 // Spec: If the 'use' element references a 'g' which contains two 'rect' ele
ments, then the instance tree |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 | 650 |
653 // Shortcut for self-references | 651 // Shortcut for self-references |
654 if (newTarget == this) | 652 if (newTarget == this) |
655 return true; | 653 return true; |
656 | 654 |
657 AtomicString targetId = newTarget->getIdAttribute(); | 655 AtomicString targetId = newTarget->getIdAttribute(); |
658 SVGElementInstance* instance = targetInstance->parentNode(); | 656 SVGElementInstance* instance = targetInstance->parentNode(); |
659 while (instance) { | 657 while (instance) { |
660 SVGElement* element = instance->correspondingElement(); | 658 SVGElement* element = instance->correspondingElement(); |
661 | 659 |
662 if (element->hasID() && element->getIdAttribute() == targetId && element
->document() == newTarget->document()) | 660 if (element->hasID() && element->getIdAttribute() == targetId && &elemen
t->document() == &newTarget->document()) |
663 return true; | 661 return true; |
664 | 662 |
665 instance = instance->parentNode(); | 663 instance = instance->parentNode(); |
666 } | 664 } |
667 return false; | 665 return false; |
668 } | 666 } |
669 | 667 |
670 static inline void removeDisallowedElementsFromSubtree(Element* subtree) | 668 static inline void removeDisallowedElementsFromSubtree(Element* subtree) |
671 { | 669 { |
672 ASSERT(!subtree->inDocument()); | 670 ASSERT(!subtree->inDocument()); |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 | 990 |
993 if (m_resource) | 991 if (m_resource) |
994 m_resource->removeClient(this); | 992 m_resource->removeClient(this); |
995 | 993 |
996 m_resource = resource; | 994 m_resource = resource; |
997 if (m_resource) | 995 if (m_resource) |
998 m_resource->addClient(this); | 996 m_resource->addClient(this); |
999 } | 997 } |
1000 | 998 |
1001 } | 999 } |
OLD | NEW |