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