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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 132 |
133 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 133 void SVGUseElement::removedFrom(ContainerNode* rootParent) |
134 { | 134 { |
135 SVGGraphicsElement::removedFrom(rootParent); | 135 SVGGraphicsElement::removedFrom(rootParent); |
136 if (rootParent->inDocument()) { | 136 if (rootParent->inDocument()) { |
137 clearShadowTree(); | 137 clearShadowTree(); |
138 cancelShadowTreeRecreation(); | 138 cancelShadowTreeRecreation(); |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 TreeScope* SVGUseElement::referencedScope() const | |
143 { | |
144 if (isStructurallyExternal()) | |
145 return externalDocument(); | |
146 return &treeScope(); | |
147 } | |
148 | |
149 Document* SVGUseElement::externalDocument() const | 142 Document* SVGUseElement::externalDocument() const |
150 { | 143 { |
151 // Gracefully handle error condition. | 144 // Gracefully handle error condition. |
152 if (!resourceIsValid()) | 145 if (!resourceIsValid()) |
153 return nullptr; | 146 return nullptr; |
154 ASSERT(m_resource->document()); | 147 ASSERT(m_resource->document()); |
155 return m_resource->document(); | 148 return m_resource->document(); |
156 } | 149 } |
157 | 150 |
158 static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGEleme
nt& shadowElement, const SVGElement& originalElement) | 151 static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGEleme
nt& shadowElement, const SVGElement& originalElement) |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 316 |
324 removeAllOutgoingReferences(); | 317 removeAllOutgoingReferences(); |
325 } | 318 } |
326 | 319 |
327 void SVGUseElement::buildPendingResource() | 320 void SVGUseElement::buildPendingResource() |
328 { | 321 { |
329 if (inUseShadowTree()) | 322 if (inUseShadowTree()) |
330 return; | 323 return; |
331 clearShadowTree(); | 324 clearShadowTree(); |
332 cancelShadowTreeRecreation(); | 325 cancelShadowTreeRecreation(); |
333 if (!referencedScope() || !inDocument()) | 326 if (!inDocument()) |
| 327 return; |
| 328 Document* externalDocument = this->externalDocument(); |
| 329 if (isStructurallyExternal() && !externalDocument) |
334 return; | 330 return; |
335 | 331 |
336 AtomicString id; | 332 AtomicString id; |
337 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(),
treeScope(), &id, externalDocument()); | 333 Element* target = targetElementFromIRIString(hrefString(), treeScope(), &id,
externalDocument); |
338 if (!target || !target->inDocument()) { | 334 if (!target || !target->inDocument()) { |
339 // If we can't find the target of an external element, just give up. | 335 // If we can't find the target of an external element, just give up. |
340 // We can't observe if the target somewhen enters the external document,
nor should we do it. | 336 // We can't observe if the target somewhen enters the external document,
nor should we do it. |
341 if (externalDocument()) | 337 if (externalDocument) |
342 return; | 338 return; |
343 if (id.isEmpty()) | 339 if (id.isEmpty()) |
344 return; | 340 return; |
345 | 341 |
346 referencedScope()->document().accessSVGExtensions().addPendingResource(i
d, this); | 342 document().accessSVGExtensions().addPendingResource(id, this); |
347 ASSERT(hasPendingResources()); | 343 ASSERT(hasPendingResources()); |
348 return; | 344 return; |
349 } | 345 } |
350 | 346 |
351 if (target->isSVGElement()) { | 347 if (target->isSVGElement()) { |
352 buildShadowAndInstanceTree(toSVGElement(*target)); | 348 buildShadowAndInstanceTree(toSVGElement(*target)); |
353 invalidateDependentShadowTrees(); | 349 invalidateDependentShadowTrees(); |
354 } | 350 } |
355 | 351 |
356 ASSERT(!m_needsShadowTreeRecreation); | 352 ASSERT(!m_needsShadowTreeRecreation); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 void SVGUseElement::cloneNonMarkupEventListeners() | 514 void SVGUseElement::cloneNonMarkupEventListeners() |
519 { | 515 { |
520 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { | 516 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { |
521 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) | 517 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) |
522 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); | 518 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); |
523 } | 519 } |
524 } | 520 } |
525 | 521 |
526 bool SVGUseElement::hasCycleUseReferencing(const SVGUseElement& use, const Conta
inerNode& targetInstance, SVGElement*& newTarget) const | 522 bool SVGUseElement::hasCycleUseReferencing(const SVGUseElement& use, const Conta
inerNode& targetInstance, SVGElement*& newTarget) const |
527 { | 523 { |
528 ASSERT(referencedScope()); | 524 Element* targetElement = targetElementFromIRIString(use.hrefString(), use.tr
eeScope()); |
529 Element* targetElement = SVGURIReference::targetElementFromIRIString(use.hre
fString(), *referencedScope()); | |
530 newTarget = 0; | 525 newTarget = 0; |
531 if (targetElement && targetElement->isSVGElement()) | 526 if (targetElement && targetElement->isSVGElement()) |
532 newTarget = toSVGElement(targetElement); | 527 newTarget = toSVGElement(targetElement); |
533 | 528 |
534 if (!newTarget) | 529 if (!newTarget) |
535 return false; | 530 return false; |
536 | 531 |
537 // Shortcut for self-references | 532 // Shortcut for self-references |
538 if (newTarget == this) | 533 if (newTarget == this) |
539 return true; | 534 return true; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 // do this directly in buildShadowTree, if we encounter a <use> element? | 595 // do this directly in buildShadowTree, if we encounter a <use> element? |
601 // | 596 // |
602 // Short answer: Because we may miss to expand some elements. For example, i
f a <symbol> | 597 // Short answer: Because we may miss to expand some elements. For example, i
f a <symbol> |
603 // contains <use> tags, we'd miss them. So once we're done with setting up t
he | 598 // contains <use> tags, we'd miss them. So once we're done with setting up t
he |
604 // actual shadow tree (after the special case modification for svg/symbol) w
e have | 599 // actual shadow tree (after the special case modification for svg/symbol) w
e have |
605 // to walk it completely and expand all <use> elements. | 600 // to walk it completely and expand all <use> elements. |
606 ShadowRoot* shadowRoot = userAgentShadowRoot(); | 601 ShadowRoot* shadowRoot = userAgentShadowRoot(); |
607 for (RefPtrWillBeRawPtr<SVGUseElement> use = Traversal<SVGUseElement>::first
Within(*shadowRoot); use; ) { | 602 for (RefPtrWillBeRawPtr<SVGUseElement> use = Traversal<SVGUseElement>::first
Within(*shadowRoot); use; ) { |
608 ASSERT(!use->resourceIsStillLoading()); | 603 ASSERT(!use->resourceIsStillLoading()); |
609 | 604 |
610 SVGElement* target = 0; | 605 SVGUseElement& originalUse = toSVGUseElement(*use->correspondingElement(
)); |
611 if (hasCycleUseReferencing(toSVGUseElement(*use->correspondingElement())
, *use, target)) | 606 SVGElement* target = nullptr; |
| 607 if (hasCycleUseReferencing(originalUse, *use, target)) |
612 return false; | 608 return false; |
613 | 609 |
614 if (target && isDisallowedElement(*target)) | 610 if (target && isDisallowedElement(*target)) |
615 return false; | 611 return false; |
616 // Don't ASSERT(target) here, it may be "pending", too. | 612 // Don't ASSERT(target) here, it may be "pending", too. |
617 // Setup sub-shadow tree root node | 613 // Setup sub-shadow tree root node |
618 RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(refere
ncedScope()->document()); | 614 RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(origin
alUse.document()); |
619 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. | 615 // Transfer all data (attributes, etc.) from <use> to the new <g> elemen
t. |
620 cloneParent->cloneDataFromElement(*use); | 616 cloneParent->cloneDataFromElement(*use); |
621 cloneParent->setCorrespondingElement(use->correspondingElement()); | 617 cloneParent->setCorrespondingElement(&originalUse); |
622 | 618 |
623 removeAttributesFromReplacementElement(*cloneParent); | 619 removeAttributesFromReplacementElement(*cloneParent); |
624 | 620 |
625 // Move already cloned elements to the new <g> element. | 621 // Move already cloned elements to the new <g> element. |
626 moveChildrenToReplacementElement(*use, *cloneParent); | 622 moveChildrenToReplacementElement(*use, *cloneParent); |
627 | 623 |
628 if (target) { | 624 if (target) { |
629 RefPtrWillBeRawPtr<Element> instanceRoot = target->cloneElementWithC
hildren(); | 625 RefPtrWillBeRawPtr<Element> instanceRoot = target->cloneElementWithC
hildren(); |
630 ASSERT(instanceRoot->isSVGElement()); | 626 ASSERT(instanceRoot->isSVGElement()); |
631 associateCorrespondingElements(*target, toSVGElement(*instanceRoot))
; | 627 associateCorrespondingElements(*target, toSVGElement(*instanceRoot))
; |
(...skipping 15 matching lines...) Expand all Loading... |
647 void SVGUseElement::expandSymbolElementsInShadowTree() | 643 void SVGUseElement::expandSymbolElementsInShadowTree() |
648 { | 644 { |
649 ShadowRoot* shadowRoot = userAgentShadowRoot(); | 645 ShadowRoot* shadowRoot = userAgentShadowRoot(); |
650 for (RefPtrWillBeRawPtr<SVGSymbolElement> symbol = Traversal<SVGSymbolElemen
t>::firstWithin(*shadowRoot); symbol; ) { | 646 for (RefPtrWillBeRawPtr<SVGSymbolElement> symbol = Traversal<SVGSymbolElemen
t>::firstWithin(*shadowRoot); symbol; ) { |
651 // Spec: The referenced 'symbol' and its contents are deep-cloned into t
he generated tree, | 647 // Spec: The referenced 'symbol' and its contents are deep-cloned into t
he generated tree, |
652 // with the exception that the 'symbol' is replaced by an 'svg'. This ge
nerated 'svg' will | 648 // with the exception that the 'symbol' is replaced by an 'svg'. This ge
nerated 'svg' will |
653 // always have explicit values for attributes width and height. If attri
butes width and/or | 649 // always have explicit values for attributes width and height. If attri
butes width and/or |
654 // height are provided on the 'use' element, then these attributes will
be transferred to | 650 // height are provided on the 'use' element, then these attributes will
be transferred to |
655 // the generated 'svg'. If attributes width and/or height are not specif
ied, the generated | 651 // the generated 'svg'. If attributes width and/or height are not specif
ied, the generated |
656 // 'svg' element will use values of 100% for these attributes. | 652 // 'svg' element will use values of 100% for these attributes. |
657 ASSERT(referencedScope()); | 653 SVGElement& originalSymbol = *symbol->correspondingElement(); |
658 RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(ref
erencedScope()->document()); | 654 RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(ori
ginalSymbol.document()); |
659 // Transfer all data (attributes, etc.) from <symbol> to the new <svg> e
lement. | 655 // Transfer all data (attributes, etc.) from <symbol> to the new <svg> e
lement. |
660 svgElement->cloneDataFromElement(*symbol); | 656 svgElement->cloneDataFromElement(*symbol); |
661 svgElement->setCorrespondingElement(symbol->correspondingElement()); | 657 svgElement->setCorrespondingElement(&originalSymbol); |
662 | 658 |
663 // Move already cloned elements to the new <svg> element. | 659 // Move already cloned elements to the new <svg> element. |
664 moveChildrenToReplacementElement(*symbol, *svgElement); | 660 moveChildrenToReplacementElement(*symbol, *svgElement); |
665 | 661 |
666 removeDisallowedElementsFromSubtree(*svgElement); | 662 removeDisallowedElementsFromSubtree(*svgElement); |
667 | 663 |
668 RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); | 664 RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); |
669 | 665 |
670 // Replace <symbol> with <svg>. | 666 // Replace <symbol> with <svg>. |
671 symbol->parentNode()->replaceChild(svgElement.release(), symbol); | 667 symbol->parentNode()->replaceChild(svgElement.release(), symbol); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 786 |
791 if (m_resource) | 787 if (m_resource) |
792 m_resource->removeClient(this); | 788 m_resource->removeClient(this); |
793 | 789 |
794 m_resource = resource; | 790 m_resource = resource; |
795 if (m_resource) | 791 if (m_resource) |
796 m_resource->addClient(this); | 792 m_resource->addClient(this); |
797 } | 793 } |
798 | 794 |
799 } // namespace blink | 795 } // namespace blink |
OLD | NEW |