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