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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 // Set up root SVG element in shadow tree. | 382 // Set up root SVG element in shadow tree. |
383 RefPtrWillBeRawPtr<Element> newChild = target.cloneElementWithoutChildren(); | 383 RefPtrWillBeRawPtr<Element> newChild = target.cloneElementWithoutChildren(); |
384 m_targetElementInstance = toSVGElement(newChild.get()); | 384 m_targetElementInstance = toSVGElement(newChild.get()); |
385 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | 385 ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); |
386 shadowTreeRootElement->appendChild(newChild.release()); | 386 shadowTreeRootElement->appendChild(newChild.release()); |
387 | 387 |
388 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. | 388 // Clone the target subtree into the shadow tree, not handling <use> and <sy
mbol> yet. |
389 | 389 |
390 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! | 390 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! |
391 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. | 391 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. |
392 buildShadowTree(target, *m_targetElementInstance, false); | 392 buildShadowTree(target, *m_targetElementInstance); |
393 | 393 |
394 if (instanceTreeIsLoading(m_targetElementInstance.get())) { | 394 addReferencesToFirstDegreeNestedUseElements(target); |
| 395 |
| 396 if (instanceTreeIsLoading()) { |
395 cloneNonMarkupEventListeners(); | 397 cloneNonMarkupEventListeners(); |
396 return; | 398 return; |
397 } | 399 } |
398 | 400 |
399 // Assure shadow tree building was successful. | 401 // Assure shadow tree building was successful. |
400 ASSERT(m_targetElementInstance); | 402 ASSERT(m_targetElementInstance); |
401 ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 403 ASSERT(m_targetElementInstance->correspondingUseElement() == this); |
402 ASSERT(m_targetElementInstance->correspondingElement() == &target); | 404 ASSERT(m_targetElementInstance->correspondingElement() == &target); |
403 | 405 |
404 // Expand all <use> elements in the shadow tree. | 406 // Expand all <use> elements in the shadow tree. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 // http://dev.w3.org/fxtf/css-masking-1/#the-clip-path | 475 // http://dev.w3.org/fxtf/css-masking-1/#the-clip-path |
474 if (!isDirectReference(element)) { | 476 if (!isDirectReference(element)) { |
475 // Spec: Indirect references are an error (14.3.5) | 477 // Spec: Indirect references are an error (14.3.5) |
476 document().accessSVGExtensions().reportError("Not allowed to use indirec
t reference in <clip-path>"); | 478 document().accessSVGExtensions().reportError("Not allowed to use indirec
t reference in <clip-path>"); |
477 return nullptr; | 479 return nullptr; |
478 } | 480 } |
479 | 481 |
480 return &toSVGGraphicsElement(element); | 482 return &toSVGGraphicsElement(element); |
481 } | 483 } |
482 | 484 |
483 void SVGUseElement::buildShadowTree(SVGElement& target, SVGElement& targetInstan
ce, bool foundUse) | 485 void SVGUseElement::addReferencesToFirstDegreeNestedUseElements(SVGElement& targ
et) |
| 486 { |
| 487 // Don't track references to external documents. |
| 488 if (isStructurallyExternal()) |
| 489 return; |
| 490 // We only need to track first degree <use> dependencies. Indirect |
| 491 // references are handled as the invalidation bubbles up the dependency |
| 492 // chain. |
| 493 SVGUseElement* useElement = |
| 494 isSVGUseElement(target) ? toSVGUseElement(&target) : Traversal<SVGUseEle
ment>::firstWithin(target); |
| 495 for (; useElement; useElement = Traversal<SVGUseElement>::nextSkippingChildr
en(*useElement, &target)) |
| 496 addReferenceTo(useElement); |
| 497 } |
| 498 |
| 499 void SVGUseElement::buildShadowTree(SVGElement& target, SVGElement& targetInstan
ce) |
484 { | 500 { |
485 ASSERT(!isDisallowedElement(target)); | 501 ASSERT(!isDisallowedElement(target)); |
486 | 502 |
487 // Spec: If the referenced object is itself a 'use', or if there are 'use' s
ubelements within the referenced | |
488 // object, the instance tree will contain recursive expansion of the indirec
t references to form a complete tree. | |
489 if (isSVGUseElement(target)) { | |
490 // We only need to track first degree <use> dependencies. Indirect refer
ences are handled | |
491 // as the invalidation bubbles up the dependency chain. | |
492 if (!foundUse && !isStructurallyExternal()) { | |
493 addReferenceTo(&target); | |
494 foundUse = true; | |
495 } | |
496 } | |
497 | |
498 targetInstance.setCorrespondingElement(&target); | 503 targetInstance.setCorrespondingElement(&target); |
499 | 504 |
500 for (RefPtrWillBeRawPtr<Node> child = target.firstChild(); child; child = ch
ild->nextSibling()) { | 505 for (RefPtrWillBeRawPtr<Node> child = target.firstChild(); child; child = ch
ild->nextSibling()) { |
501 // Skip any disallowed element. | 506 // Skip any disallowed element. |
502 if (isDisallowedElement(*child)) | 507 if (isDisallowedElement(*child)) |
503 continue; | 508 continue; |
504 | 509 |
505 RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); | 510 RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); |
506 targetInstance.appendChild(newChild.get()); | 511 targetInstance.appendChild(newChild.get()); |
507 if (newChild->isSVGElement()) { | 512 if (newChild->isSVGElement()) { |
508 // Enter recursion, appending new instance tree nodes to the "instan
ce" object. | 513 // Enter recursion, appending new instance tree nodes to the "instan
ce" object. |
509 buildShadowTree(toSVGElement(*child), toSVGElement(*newChild), found
Use); | 514 buildShadowTree(toSVGElement(*child), toSVGElement(*newChild)); |
510 } | 515 } |
511 } | 516 } |
512 } | 517 } |
513 | 518 |
514 void SVGUseElement::cloneNonMarkupEventListeners() | 519 void SVGUseElement::cloneNonMarkupEventListeners() |
515 { | 520 { |
516 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { | 521 for (SVGElement& element : Traversal<SVGElement>::descendantsOf(*userAgentSh
adowRoot())) { |
517 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) | 522 if (EventTargetData* data = element.correspondingElement()->eventTargetD
ata()) |
518 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); | 523 data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarge
t(&element); |
519 } | 524 } |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 } | 768 } |
764 | 769 |
765 bool SVGUseElement::resourceIsValid() const | 770 bool SVGUseElement::resourceIsValid() const |
766 { | 771 { |
767 return m_resource | 772 return m_resource |
768 && m_resource->isLoaded() | 773 && m_resource->isLoaded() |
769 && !m_resource->errorOccurred() | 774 && !m_resource->errorOccurred() |
770 && m_resource->document(); | 775 && m_resource->document(); |
771 } | 776 } |
772 | 777 |
773 bool SVGUseElement::instanceTreeIsLoading(const SVGElement* targetInstance) | 778 bool SVGUseElement::instanceTreeIsLoading() const |
774 { | 779 { |
775 for (const SVGElement* element = targetInstance; element; element = Traversa
l<SVGElement>::next(*element, targetInstance)) { | 780 for (const SVGUseElement& useElement : Traversal<SVGUseElement>::descendants
Of(*userAgentShadowRoot())) { |
776 if (isSVGUseElement(*element) && toSVGUseElement(*element).resourceIsSti
llLoading()) | 781 if (useElement.resourceIsStillLoading()) |
777 return true; | 782 return true; |
778 } | 783 } |
779 return false; | 784 return false; |
780 } | 785 } |
781 | 786 |
782 void SVGUseElement::setDocumentResource(PassRefPtrWillBeRawPtr<DocumentResource>
resource) | 787 void SVGUseElement::setDocumentResource(PassRefPtrWillBeRawPtr<DocumentResource>
resource) |
783 { | 788 { |
784 if (m_resource == resource) | 789 if (m_resource == resource) |
785 return; | 790 return; |
786 | 791 |
787 if (m_resource) | 792 if (m_resource) |
788 m_resource->removeClient(this); | 793 m_resource->removeClient(this); |
789 | 794 |
790 m_resource = resource; | 795 m_resource = resource; |
791 if (m_resource) | 796 if (m_resource) |
792 m_resource->addClient(this); | 797 m_resource->addClient(this); |
793 } | 798 } |
794 | 799 |
795 } // namespace blink | 800 } // namespace blink |
OLD | NEW |