| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 73     // Always build a user agent #shadow-root for SVGUseElement. | 73     // Always build a user agent #shadow-root for SVGUseElement. | 
| 74     RefPtrWillBeRawPtr<SVGUseElement> use = adoptRefWillBeNoop(new SVGUseElement
     (document)); | 74     RefPtrWillBeRawPtr<SVGUseElement> use = adoptRefWillBeNoop(new SVGUseElement
     (document)); | 
| 75     use->ensureUserAgentShadowRoot(); | 75     use->ensureUserAgentShadowRoot(); | 
| 76     return use.release(); | 76     return use.release(); | 
| 77 } | 77 } | 
| 78 | 78 | 
| 79 SVGUseElement::~SVGUseElement() | 79 SVGUseElement::~SVGUseElement() | 
| 80 { | 80 { | 
| 81     setDocumentResource(0); | 81     setDocumentResource(0); | 
| 82 #if !ENABLE(OILPAN) | 82 #if !ENABLE(OILPAN) | 
| 83     clearResourceReferences(); | 83     clearShadowTree(); | 
|  | 84     cancelShadowTreeRecreation(); | 
| 84 #endif | 85 #endif | 
| 85     svgUseLoadEventSender().cancelEvent(this); | 86     svgUseLoadEventSender().cancelEvent(this); | 
| 86 } | 87 } | 
| 87 | 88 | 
| 88 DEFINE_TRACE(SVGUseElement) | 89 DEFINE_TRACE(SVGUseElement) | 
| 89 { | 90 { | 
| 90     visitor->trace(m_x); | 91     visitor->trace(m_x); | 
| 91     visitor->trace(m_y); | 92     visitor->trace(m_y); | 
| 92     visitor->trace(m_width); | 93     visitor->trace(m_width); | 
| 93     visitor->trace(m_height); | 94     visitor->trace(m_height); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 113         return InsertionDone; | 114         return InsertionDone; | 
| 114     ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); | 115     ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); | 
| 115     ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); | 116     ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); | 
| 116     invalidateShadowTree(); | 117     invalidateShadowTree(); | 
| 117     return InsertionDone; | 118     return InsertionDone; | 
| 118 } | 119 } | 
| 119 | 120 | 
| 120 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 121 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 
| 121 { | 122 { | 
| 122     SVGGraphicsElement::removedFrom(rootParent); | 123     SVGGraphicsElement::removedFrom(rootParent); | 
| 123     if (rootParent->inDocument()) | 124     if (rootParent->inDocument()) { | 
| 124         clearResourceReferences(); | 125         clearShadowTree(); | 
|  | 126         cancelShadowTreeRecreation(); | 
|  | 127     } | 
| 125 } | 128 } | 
| 126 | 129 | 
| 127 TreeScope* SVGUseElement::referencedScope() const | 130 TreeScope* SVGUseElement::referencedScope() const | 
| 128 { | 131 { | 
| 129     if (isStructurallyExternal()) | 132     if (isStructurallyExternal()) | 
| 130         return externalDocument(); | 133         return externalDocument(); | 
| 131     return &treeScope(); | 134     return &treeScope(); | 
| 132 } | 135 } | 
| 133 | 136 | 
| 134 Document* SVGUseElement::externalDocument() const | 137 Document* SVGUseElement::externalDocument() const | 
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 295 } | 298 } | 
| 296 | 299 | 
| 297 void SVGUseElement::scheduleShadowTreeRecreation() | 300 void SVGUseElement::scheduleShadowTreeRecreation() | 
| 298 { | 301 { | 
| 299     if (inUseShadowTree()) | 302     if (inUseShadowTree()) | 
| 300         return; | 303         return; | 
| 301     m_needsShadowTreeRecreation = true; | 304     m_needsShadowTreeRecreation = true; | 
| 302     document().scheduleUseShadowTreeUpdate(*this); | 305     document().scheduleUseShadowTreeUpdate(*this); | 
| 303 } | 306 } | 
| 304 | 307 | 
| 305 void SVGUseElement::clearResourceReferences() | 308 void SVGUseElement::cancelShadowTreeRecreation() | 
|  | 309 { | 
|  | 310     m_needsShadowTreeRecreation = false; | 
|  | 311     document().unscheduleUseShadowTreeUpdate(*this); | 
|  | 312 } | 
|  | 313 | 
|  | 314 void SVGUseElement::clearInstanceRoot() | 
| 306 { | 315 { | 
| 307     if (m_targetElementInstance) | 316     if (m_targetElementInstance) | 
| 308         m_targetElementInstance = nullptr; | 317         m_targetElementInstance = nullptr; | 
|  | 318 } | 
|  | 319 | 
|  | 320 void SVGUseElement::clearShadowTree() | 
|  | 321 { | 
|  | 322     clearInstanceRoot(); | 
| 309 | 323 | 
| 310     // FIXME: We should try to optimize this, to at least allow partial reclones
     . | 324     // FIXME: We should try to optimize this, to at least allow partial reclones
     . | 
| 311     if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) | 325     if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) | 
| 312         shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent); | 326         shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent); | 
| 313 | 327 | 
| 314     m_needsShadowTreeRecreation = false; |  | 
| 315     document().unscheduleUseShadowTreeUpdate(*this); |  | 
| 316 |  | 
| 317     removeAllOutgoingReferences(); | 328     removeAllOutgoingReferences(); | 
| 318 } | 329 } | 
| 319 | 330 | 
| 320 void SVGUseElement::buildPendingResource() | 331 void SVGUseElement::buildPendingResource() | 
| 321 { | 332 { | 
| 322     if (inUseShadowTree()) | 333     if (inUseShadowTree()) | 
| 323         return; | 334         return; | 
| 324     clearResourceReferences(); | 335     clearShadowTree(); | 
|  | 336     cancelShadowTreeRecreation(); | 
| 325     if (!referencedScope() || !inDocument()) | 337     if (!referencedScope() || !inDocument()) | 
| 326         return; | 338         return; | 
| 327 | 339 | 
| 328     AtomicString id; | 340     AtomicString id; | 
| 329     Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), 
     treeScope(), &id, externalDocument()); | 341     Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), 
     treeScope(), &id, externalDocument()); | 
| 330     if (!target || !target->inDocument()) { | 342     if (!target || !target->inDocument()) { | 
| 331         // If we can't find the target of an external element, just give up. | 343         // If we can't find the target of an external element, just give up. | 
| 332         // We can't observe if the target somewhen enters the external document,
      nor should we do it. | 344         // We can't observe if the target somewhen enters the external document,
      nor should we do it. | 
| 333         if (externalDocument()) | 345         if (externalDocument()) | 
| 334             return; | 346             return; | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 361         data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(cl
     one.get()); | 373         data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(cl
     one.get()); | 
| 362     TrackExceptionState exceptionState; | 374     TrackExceptionState exceptionState; | 
| 363     for (Node* node = toClone.firstChild(); node && !exceptionState.hadException
     (); node = node->nextSibling()) | 375     for (Node* node = toClone.firstChild(); node && !exceptionState.hadException
     (); node = node->nextSibling()) | 
| 364         clone->appendChild(cloneNodeAndAssociate(*node), exceptionState); | 376         clone->appendChild(cloneNodeAndAssociate(*node), exceptionState); | 
| 365     return clone.release(); | 377     return clone.release(); | 
| 366 } | 378 } | 
| 367 | 379 | 
| 368 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) | 380 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) | 
| 369 { | 381 { | 
| 370     ASSERT(!m_targetElementInstance); | 382     ASSERT(!m_targetElementInstance); | 
|  | 383     ASSERT(!m_needsShadowTreeRecreation); | 
| 371 | 384 | 
| 372     // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
     e tree for <use> | 385     // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
     e tree for <use> | 
| 373     // elements living in a user agent shadow tree because they will get expande
     d in a second | 386     // elements living in a user agent shadow tree because they will get expande
     d in a second | 
| 374     // pass -- see expandUseElementsInShadowTree(). | 387     // pass -- see expandUseElementsInShadowTree(). | 
| 375     if (inUseShadowTree()) | 388     if (inUseShadowTree()) | 
| 376         return; | 389         return; | 
| 377 | 390 | 
| 378     // Do not allow self-referencing. | 391     // Do not allow self-referencing. | 
| 379     // 'target' may be null, if it's a non SVG namespaced element. | 392     // 'target' may be null, if it's a non SVG namespaced element. | 
| 380     if (!target || target == this || isDisallowedElement(target)) | 393     if (!target || target == this || isDisallowedElement(target)) | 
| 381         return; | 394         return; | 
| 382 | 395 | 
| 383     // Set up root SVG element in shadow tree. | 396     // Set up root SVG element in shadow tree. | 
| 384     RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren()
     ; | 397     RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren()
     ; | 
| 385     m_targetElementInstance = toSVGElement(newChild.get()); | 398     m_targetElementInstance = toSVGElement(newChild.get()); | 
| 386     ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | 399     ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); | 
| 387     shadowTreeRootElement->appendChild(newChild.release()); | 400     shadowTreeRootElement->appendChild(newChild.release()); | 
| 388 | 401 | 
| 389     // Clone the target subtree into the shadow tree, not handling <use> and <sy
     mbol> yet. | 402     // Clone the target subtree into the shadow tree, not handling <use> and <sy
     mbol> yet. | 
| 390 | 403 | 
| 391     // SVG specification does not say a word about <use> & cycles. My view on th
     is is: just ignore it! | 404     // SVG specification does not say a word about <use> & cycles. My view on th
     is is: just ignore it! | 
| 392     // Non-appearing <use> content is easier to debug, then half-appearing conte
     nt. | 405     // Non-appearing <use> content is easier to debug, then half-appearing conte
     nt. | 
| 393     if (!buildShadowTree(target, m_targetElementInstance.get(), false)) { | 406     if (!buildShadowTree(target, m_targetElementInstance.get(), false)) { | 
| 394         clearResourceReferences(); | 407         clearShadowTree(); | 
| 395         return; | 408         return; | 
| 396     } | 409     } | 
| 397 | 410 | 
| 398     if (instanceTreeIsLoading(m_targetElementInstance.get())) | 411     if (instanceTreeIsLoading(m_targetElementInstance.get())) | 
| 399         return; | 412         return; | 
| 400 | 413 | 
| 401     // Assure shadow tree building was successfull | 414     // Assure shadow tree building was successfull | 
| 402     ASSERT(m_targetElementInstance); | 415     ASSERT(m_targetElementInstance); | 
| 403     ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 416     ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 
| 404     ASSERT(m_targetElementInstance->correspondingElement() == target); | 417     ASSERT(m_targetElementInstance->correspondingElement() == target); | 
| 405 | 418 | 
| 406     // Expand all <use> elements in the shadow tree. | 419     // Expand all <use> elements in the shadow tree. | 
| 407     // Expand means: replace the actual <use> element by what it references. | 420     // Expand means: replace the actual <use> element by what it references. | 
| 408     if (!expandUseElementsInShadowTree(m_targetElementInstance.get())) { | 421     if (!expandUseElementsInShadowTree(m_targetElementInstance.get())) { | 
| 409         clearResourceReferences(); | 422         clearShadowTree(); | 
| 410         return; | 423         return; | 
| 411     } | 424     } | 
| 412 | 425 | 
| 413     // Expand all <symbol> elements in the shadow tree. | 426     // Expand all <symbol> elements in the shadow tree. | 
| 414     // Expand means: replace the actual <symbol> element by the <svg> element. | 427     // Expand means: replace the actual <symbol> element by the <svg> element. | 
| 415     expandSymbolElementsInShadowTree(toSVGElement(shadowTreeRootElement->firstCh
     ild())); | 428     expandSymbolElementsInShadowTree(toSVGElement(shadowTreeRootElement->firstCh
     ild())); | 
| 416 | 429 | 
| 417     m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); | 430     m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); | 
| 418     transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_t
     argetElementInstance->correspondingElement()); | 431     transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_t
     argetElementInstance->correspondingElement()); | 
| 419 | 432 | 
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 678     } | 691     } | 
| 679 | 692 | 
| 680     for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChil
     d(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) | 693     for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChil
     d(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) | 
| 681         expandSymbolElementsInShadowTree(child.get()); | 694         expandSymbolElementsInShadowTree(child.get()); | 
| 682 } | 695 } | 
| 683 | 696 | 
| 684 void SVGUseElement::invalidateShadowTree() | 697 void SVGUseElement::invalidateShadowTree() | 
| 685 { | 698 { | 
| 686     if (!inActiveDocument() || m_needsShadowTreeRecreation) | 699     if (!inActiveDocument() || m_needsShadowTreeRecreation) | 
| 687         return; | 700         return; | 
|  | 701     clearInstanceRoot(); | 
| 688     scheduleShadowTreeRecreation(); | 702     scheduleShadowTreeRecreation(); | 
| 689     invalidateDependentShadowTrees(); | 703     invalidateDependentShadowTrees(); | 
| 690 } | 704 } | 
| 691 | 705 | 
| 692 void SVGUseElement::invalidateDependentShadowTrees() | 706 void SVGUseElement::invalidateDependentShadowTrees() | 
| 693 { | 707 { | 
| 694     // Recursively invalidate dependent <use> shadow trees | 708     // Recursively invalidate dependent <use> shadow trees | 
| 695     const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement>>& instances = ins
     tancesForElement(); | 709     const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement>>& instances = ins
     tancesForElement(); | 
| 696     for (SVGElement* instance : instances) { | 710     for (SVGElement* instance : instances) { | 
| 697         if (SVGUseElement* element = instance->correspondingUseElement()) { | 711         if (SVGUseElement* element = instance->correspondingUseElement()) { | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 782 | 796 | 
| 783     if (m_resource) | 797     if (m_resource) | 
| 784         m_resource->removeClient(this); | 798         m_resource->removeClient(this); | 
| 785 | 799 | 
| 786     m_resource = resource; | 800     m_resource = resource; | 
| 787     if (m_resource) | 801     if (m_resource) | 
| 788         m_resource->addClient(this); | 802         m_resource->addClient(this); | 
| 789 } | 803 } | 
| 790 | 804 | 
| 791 } | 805 } | 
| OLD | NEW | 
|---|