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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 ScriptWrappable::init(this); | 67 ScriptWrappable::init(this); |
68 | 68 |
69 addToPropertyMap(m_x); | 69 addToPropertyMap(m_x); |
70 addToPropertyMap(m_y); | 70 addToPropertyMap(m_y); |
71 addToPropertyMap(m_width); | 71 addToPropertyMap(m_width); |
72 addToPropertyMap(m_height); | 72 addToPropertyMap(m_height); |
73 } | 73 } |
74 | 74 |
75 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) | 75 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
rtedByParser) |
76 { | 76 { |
77 // Always build a #shadow-root for SVGUseElement. | 77 // Always build a user agent #shadow-root for SVGUseElement. |
78 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); | 78 RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInserted
ByParser)); |
79 use->ensureUserAgentShadowRoot(); | 79 use->ensureUserAgentShadowRoot(); |
80 return use.release(); | 80 return use.release(); |
81 } | 81 } |
82 | 82 |
83 SVGUseElement::~SVGUseElement() | 83 SVGUseElement::~SVGUseElement() |
84 { | 84 { |
85 setDocumentResource(0); | 85 setDocumentResource(0); |
86 | 86 |
87 clearResourceReferences(); | 87 clearResourceReferences(); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 for (Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { | 338 for (Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { |
339 if (subtreeContainsDisallowedElement(cur)) | 339 if (subtreeContainsDisallowedElement(cur)) |
340 return true; | 340 return true; |
341 } | 341 } |
342 | 342 |
343 return false; | 343 return false; |
344 } | 344 } |
345 | 345 |
346 void SVGUseElement::scheduleShadowTreeRecreation() | 346 void SVGUseElement::scheduleShadowTreeRecreation() |
347 { | 347 { |
348 if (!referencedDocument() || isInShadowTree()) | 348 if (!referencedDocument() || isInUserAgentShadowTree()) |
349 return; | 349 return; |
350 m_needsShadowTreeRecreation = true; | 350 m_needsShadowTreeRecreation = true; |
351 document().scheduleUseShadowTreeUpdate(*this); | 351 document().scheduleUseShadowTreeUpdate(*this); |
352 } | 352 } |
353 | 353 |
354 void SVGUseElement::clearResourceReferences() | 354 void SVGUseElement::clearResourceReferences() |
355 { | 355 { |
356 // FIXME: We should try to optimize this, to at least allow partial reclones
. | 356 // FIXME: We should try to optimize this, to at least allow partial reclones
. |
357 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) | 357 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) |
358 shadowTreeRootElement->removeChildren(); | 358 shadowTreeRootElement->removeChildren(); |
359 | 359 |
360 if (m_targetElementInstance) { | 360 if (m_targetElementInstance) { |
361 m_targetElementInstance->detach(); | 361 m_targetElementInstance->detach(); |
362 m_targetElementInstance = nullptr; | 362 m_targetElementInstance = nullptr; |
363 } | 363 } |
364 | 364 |
365 m_needsShadowTreeRecreation = false; | 365 m_needsShadowTreeRecreation = false; |
366 document().unscheduleUseShadowTreeUpdate(*this); | 366 document().unscheduleUseShadowTreeUpdate(*this); |
367 | 367 |
368 document().accessSVGExtensions().removeAllTargetReferencesForElement(this); | 368 document().accessSVGExtensions().removeAllTargetReferencesForElement(this); |
369 } | 369 } |
370 | 370 |
371 void SVGUseElement::buildPendingResource() | 371 void SVGUseElement::buildPendingResource() |
372 { | 372 { |
373 if (!referencedDocument() || isInShadowTree()) | 373 if (!referencedDocument() || isInUserAgentShadowTree()) |
374 return; | 374 return; |
375 clearResourceReferences(); | 375 clearResourceReferences(); |
376 if (!inDocument()) | 376 if (!inDocument()) |
377 return; | 377 return; |
378 | 378 |
379 AtomicString id; | 379 AtomicString id; |
380 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(),
document(), &id, externalDocument()); | 380 Element* target = SVGURIReference::targetElementFromIRIString(hrefString(),
document(), &id, externalDocument()); |
381 if (!target || !target->inDocument()) { | 381 if (!target || !target->inDocument()) { |
382 // If we can't find the target of an external element, just give up. | 382 // If we can't find the target of an external element, just give up. |
383 // We can't observe if the target somewhen enters the external document,
nor should we do it. | 383 // We can't observe if the target somewhen enters the external document,
nor should we do it. |
(...skipping 12 matching lines...) Expand all Loading... |
396 invalidateDependentShadowTrees(); | 396 invalidateDependentShadowTrees(); |
397 } | 397 } |
398 | 398 |
399 ASSERT(!m_needsShadowTreeRecreation); | 399 ASSERT(!m_needsShadowTreeRecreation); |
400 } | 400 } |
401 | 401 |
402 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) | 402 void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) |
403 { | 403 { |
404 ASSERT(!m_targetElementInstance); | 404 ASSERT(!m_targetElementInstance); |
405 | 405 |
406 // Do not build the shadow/instance tree for <use> elements living in a shad
ow tree. | 406 // <use> creates a "user agent" shadow root. Do not build the shadow/instanc
e tree for <use> |
407 // The will be expanded soon anyway - see expandUseElementsInShadowTree(). | 407 // elements living in a user agent shadow tree because they will get expande
d in a second |
408 if (isInShadowTree()) | 408 // pass -- see expandUseElementsInShadowTree(). |
| 409 if (isInUserAgentShadowTree()) |
409 return; | 410 return; |
410 | 411 |
411 // Do not allow self-referencing. | 412 // Do not allow self-referencing. |
412 // 'target' may be null, if it's a non SVG namespaced element. | 413 // 'target' may be null, if it's a non SVG namespaced element. |
413 if (!target || target == this) | 414 if (!target || target == this) |
414 return; | 415 return; |
415 | 416 |
416 // Why a seperated instance/shadow tree? SVG demands it: | 417 // Why a seperated instance/shadow tree? SVG demands it: |
417 // The instance tree is accesable from JavaScript, and has to | 418 // The instance tree is accesable from JavaScript, and has to |
418 // expose a 1:1 copy of the referenced tree, whereas internally we need | 419 // expose a 1:1 copy of the referenced tree, whereas internally we need |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 | 668 |
668 userAgentShadowRoot()->appendChild(newChild.release()); | 669 userAgentShadowRoot()->appendChild(newChild.release()); |
669 } | 670 } |
670 | 671 |
671 void SVGUseElement::expandUseElementsInShadowTree(Node* element) | 672 void SVGUseElement::expandUseElementsInShadowTree(Node* element) |
672 { | 673 { |
673 ASSERT(element); | 674 ASSERT(element); |
674 // Why expand the <use> elements in the shadow tree here, and not just | 675 // Why expand the <use> elements in the shadow tree here, and not just |
675 // do this directly in buildShadowTree, if we encounter a <use> element? | 676 // do this directly in buildShadowTree, if we encounter a <use> element? |
676 // | 677 // |
677 // Short answer: Because we may miss to expand some elements. Ie. if a <symb
ol> | 678 // Short answer: Because we may miss to expand some elements. For example, i
f a <symbol> |
678 // contains <use> tags, we'd miss them. So once we're done with settin' up t
he | 679 // contains <use> tags, we'd miss them. So once we're done with setting up t
he |
679 // actual shadow tree (after the special case modification for svg/symbol) w
e have | 680 // actual shadow tree (after the special case modification for svg/symbol) w
e have |
680 // to walk it completely and expand all <use> elements. | 681 // to walk it completely and expand all <use> elements. |
681 if (isSVGUseElement(*element)) { | 682 if (isSVGUseElement(*element)) { |
682 SVGUseElement* use = toSVGUseElement(element); | 683 SVGUseElement* use = toSVGUseElement(element); |
683 ASSERT(!use->resourceIsStillLoading()); | 684 ASSERT(!use->resourceIsStillLoading()); |
684 | 685 |
685 ASSERT(referencedDocument()); | 686 ASSERT(referencedDocument()); |
686 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->hrefString(), *referencedDocument()); | 687 Element* targetElement = SVGURIReference::targetElementFromIRIString(use
->hrefString(), *referencedDocument()); |
687 SVGElement* target = 0; | 688 SVGElement* target = 0; |
688 if (targetElement && targetElement->isSVGElement()) | 689 if (targetElement && targetElement->isSVGElement()) |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 | 883 |
883 to->cloneDataFromElement(*from); | 884 to->cloneDataFromElement(*from); |
884 | 885 |
885 to->removeAttribute(SVGNames::xAttr); | 886 to->removeAttribute(SVGNames::xAttr); |
886 to->removeAttribute(SVGNames::yAttr); | 887 to->removeAttribute(SVGNames::yAttr); |
887 to->removeAttribute(SVGNames::widthAttr); | 888 to->removeAttribute(SVGNames::widthAttr); |
888 to->removeAttribute(SVGNames::heightAttr); | 889 to->removeAttribute(SVGNames::heightAttr); |
889 to->removeAttribute(XLinkNames::hrefAttr); | 890 to->removeAttribute(XLinkNames::hrefAttr); |
890 } | 891 } |
891 | 892 |
| 893 bool SVGUseElement::isInUserAgentShadowTree() const |
| 894 { |
| 895 if (ShadowRoot* shadowRoot = containingShadowRoot()) |
| 896 return shadowRoot->type() == ShadowRoot::UserAgentShadowRoot; |
| 897 return false; |
| 898 } |
| 899 |
892 bool SVGUseElement::selfHasRelativeLengths() const | 900 bool SVGUseElement::selfHasRelativeLengths() const |
893 { | 901 { |
894 if (m_x->currentValue()->isRelative() | 902 if (m_x->currentValue()->isRelative() |
895 || m_y->currentValue()->isRelative() | 903 || m_y->currentValue()->isRelative() |
896 || m_width->currentValue()->isRelative() | 904 || m_width->currentValue()->isRelative() |
897 || m_height->currentValue()->isRelative()) | 905 || m_height->currentValue()->isRelative()) |
898 return true; | 906 return true; |
899 | 907 |
900 if (!m_targetElementInstance) | 908 if (!m_targetElementInstance) |
901 return false; | 909 return false; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 | 971 |
964 if (m_resource) | 972 if (m_resource) |
965 m_resource->removeClient(this); | 973 m_resource->removeClient(this); |
966 | 974 |
967 m_resource = resource; | 975 m_resource = resource; |
968 if (m_resource) | 976 if (m_resource) |
969 m_resource->addClient(this); | 977 m_resource->addClient(this); |
970 } | 978 } |
971 | 979 |
972 } | 980 } |
OLD | NEW |