| 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 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 { | 123 { |
| 124 // This functions exists to assure assumptions made in the code regarding SV
GElementInstance creation/destruction are satisfied. | 124 // This functions exists to assure assumptions made in the code regarding SV
GElementInstance creation/destruction are satisfied. |
| 125 SVGStyledTransformableElement::insertedIntoDocument(); | 125 SVGStyledTransformableElement::insertedIntoDocument(); |
| 126 ASSERT(!m_targetElementInstance || ((document()->isSVGDocument() || document
()->isXHTMLDocument()) && !static_cast<XMLDocumentParser*>(document()->parser())
->wellFormed())); | 126 ASSERT(!m_targetElementInstance || ((document()->isSVGDocument() || document
()->isXHTMLDocument()) && !static_cast<XMLDocumentParser*>(document()->parser())
->wellFormed())); |
| 127 ASSERT(!m_isPendingResource); | 127 ASSERT(!m_isPendingResource); |
| 128 } | 128 } |
| 129 | 129 |
| 130 void SVGUseElement::removedFromDocument() | 130 void SVGUseElement::removedFromDocument() |
| 131 { | 131 { |
| 132 SVGStyledTransformableElement::removedFromDocument(); | 132 SVGStyledTransformableElement::removedFromDocument(); |
| 133 m_targetElementInstance = 0; | 133 detachInstance(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) | 136 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) |
| 137 { | 137 { |
| 138 SVGStyledTransformableElement::svgAttributeChanged(attrName); | 138 SVGStyledTransformableElement::svgAttributeChanged(attrName); |
| 139 | 139 |
| 140 bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yA
ttr; | 140 bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yA
ttr; |
| 141 bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName ==
SVGNames::heightAttr; | 141 bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName ==
SVGNames::heightAttr; |
| 142 | 142 |
| 143 if (isXYAttribute || isWidthHeightAttribute) | 143 if (isXYAttribute || isWidthHeightAttribute) |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 if (parent->isShadowNode()) | 489 if (parent->isShadowNode()) |
| 490 return; | 490 return; |
| 491 | 491 |
| 492 parent = parent->parentNode(); | 492 parent = parent->parentNode(); |
| 493 } | 493 } |
| 494 | 494 |
| 495 SVGElement* target = 0; | 495 SVGElement* target = 0; |
| 496 if (targetElement && targetElement->isSVGElement()) | 496 if (targetElement && targetElement->isSVGElement()) |
| 497 target = static_cast<SVGElement*>(targetElement); | 497 target = static_cast<SVGElement*>(targetElement); |
| 498 | 498 |
| 499 if (m_targetElementInstance) | 499 detachInstance(); |
| 500 m_targetElementInstance = 0; | |
| 501 | 500 |
| 502 // Do not allow self-referencing. | 501 // Do not allow self-referencing. |
| 503 // 'target' may be null, if it's a non SVG namespaced element. | 502 // 'target' may be null, if it's a non SVG namespaced element. |
| 504 if (!target || target == this) | 503 if (!target || target == this) |
| 505 return; | 504 return; |
| 506 | 505 |
| 507 // Why a seperated instance/shadow tree? SVG demands it: | 506 // Why a seperated instance/shadow tree? SVG demands it: |
| 508 // The instance tree is accesable from JavaScript, and has to | 507 // The instance tree is accesable from JavaScript, and has to |
| 509 // expose a 1:1 copy of the referenced tree, whereas internally we need | 508 // expose a 1:1 copy of the referenced tree, whereas internally we need |
| 510 // to alter the tree for correct "use-on-symbol", "use-on-svg" support. | 509 // to alter the tree for correct "use-on-symbol", "use-on-svg" support. |
| 511 | 510 |
| 512 // Build instance tree. Create root SVGElementInstance object for the first
sub-tree node. | 511 // Build instance tree. Create root SVGElementInstance object for the first
sub-tree node. |
| 513 // | 512 // |
| 514 // Spec: If the 'use' element references a simple graphics element such as a
'rect', then there is only a | 513 // Spec: If the 'use' element references a simple graphics element such as a
'rect', then there is only a |
| 515 // single SVGElementInstance object, and the correspondingElement attribute
on this SVGElementInstance object | 514 // single SVGElementInstance object, and the correspondingElement attribute
on this SVGElementInstance object |
| 516 // is the SVGRectElement that corresponds to the referenced 'rect' element. | 515 // is the SVGRectElement that corresponds to the referenced 'rect' element. |
| 517 m_targetElementInstance = SVGElementInstance::create(this, target); | 516 m_targetElementInstance = SVGElementInstance::create(this, target); |
| 518 | 517 |
| 519 // Eventually enter recursion to build SVGElementInstance objects for the su
b-tree children | 518 // Eventually enter recursion to build SVGElementInstance objects for the su
b-tree children |
| 520 bool foundProblem = false; | 519 bool foundProblem = false; |
| 521 buildInstanceTree(target, m_targetElementInstance.get(), foundProblem); | 520 buildInstanceTree(target, m_targetElementInstance.get(), foundProblem); |
| 522 | 521 |
| 523 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! | 522 // SVG specification does not say a word about <use> & cycles. My view on th
is is: just ignore it! |
| 524 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. | 523 // Non-appearing <use> content is easier to debug, then half-appearing conte
nt. |
| 525 if (foundProblem) { | 524 if (foundProblem) { |
| 526 m_targetElementInstance = 0; | 525 detachInstance(); |
| 527 return; | 526 return; |
| 528 } | 527 } |
| 529 | 528 |
| 530 // Assure instance tree building was successfull | 529 // Assure instance tree building was successfull |
| 531 ASSERT(m_targetElementInstance); | 530 ASSERT(m_targetElementInstance); |
| 532 ASSERT(!m_targetElementInstance->shadowTreeElement()); | 531 ASSERT(!m_targetElementInstance->shadowTreeElement()); |
| 533 ASSERT(m_targetElementInstance->correspondingUseElement() == this); | 532 ASSERT(m_targetElementInstance->correspondingUseElement() == this); |
| 534 ASSERT(m_targetElementInstance->correspondingElement() == target); | 533 ASSERT(m_targetElementInstance->correspondingElement() == target); |
| 535 | 534 |
| 536 // Build shadow tree from instance tree | 535 // Build shadow tree from instance tree |
| (...skipping 12 matching lines...) Expand all Loading... |
| 549 | 548 |
| 550 // Now that the shadow tree is completly expanded, we can associate | 549 // Now that the shadow tree is completly expanded, we can associate |
| 551 // shadow tree elements <-> instances in the instance tree. | 550 // shadow tree elements <-> instances in the instance tree. |
| 552 associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetE
lementInstance.get()); | 551 associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetE
lementInstance.get()); |
| 553 | 552 |
| 554 // If no shadow tree element is present, this means that the reference root | 553 // If no shadow tree element is present, this means that the reference root |
| 555 // element was removed, as it is disallowed (ie. <use> on <foreignObject>) | 554 // element was removed, as it is disallowed (ie. <use> on <foreignObject>) |
| 556 // Do NOT leave an inconsistent instance tree around, instead destruct it. | 555 // Do NOT leave an inconsistent instance tree around, instead destruct it. |
| 557 if (!m_targetElementInstance->shadowTreeElement()) { | 556 if (!m_targetElementInstance->shadowTreeElement()) { |
| 558 shadowRoot->removeAllChildren(); | 557 shadowRoot->removeAllChildren(); |
| 559 m_targetElementInstance = 0; | 558 detachInstance(); |
| 560 return; | 559 return; |
| 561 } | 560 } |
| 562 | 561 |
| 563 // Consistency checks - this is assumed in updateContainerOffset(). | 562 // Consistency checks - this is assumed in updateContainerOffset(). |
| 564 ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowR
oot); | 563 ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowR
oot); |
| 565 | 564 |
| 566 // Eventually dump instance tree | 565 // Eventually dump instance tree |
| 567 #ifdef DUMP_INSTANCE_TREE | 566 #ifdef DUMP_INSTANCE_TREE |
| 568 String text; | 567 String text; |
| 569 unsigned int depth = 0; | 568 unsigned int depth = 0; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 588 transferEventListenersToShadowTree(m_targetElementInstance.get()); | 587 transferEventListenersToShadowTree(m_targetElementInstance.get()); |
| 589 | 588 |
| 590 // Update container offset/size | 589 // Update container offset/size |
| 591 updateContainerOffsets(); | 590 updateContainerOffsets(); |
| 592 updateContainerSizes(); | 591 updateContainerSizes(); |
| 593 | 592 |
| 594 // Update relative length information | 593 // Update relative length information |
| 595 updateRelativeLengthsInformation(); | 594 updateRelativeLengthsInformation(); |
| 596 } | 595 } |
| 597 | 596 |
| 597 void SVGUseElement::detachInstance() |
| 598 { |
| 599 if (!m_targetElementInstance) |
| 600 return; |
| 601 m_targetElementInstance->clearUseElement(); |
| 602 m_targetElementInstance = 0; |
| 603 } |
| 604 |
| 598 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*) | 605 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*) |
| 599 { | 606 { |
| 600 return new (arena) RenderSVGShadowTreeRootContainer(this); | 607 return new (arena) RenderSVGShadowTreeRootContainer(this); |
| 601 } | 608 } |
| 602 | 609 |
| 603 static void updateFromElementCallback(Node* node) | 610 static void updateFromElementCallback(Node* node) |
| 604 { | 611 { |
| 605 if (RenderObject* renderer = node->renderer()) | 612 if (RenderObject* renderer = node->renderer()) |
| 606 renderer->updateFromElement(); | 613 renderer->updateFromElement(); |
| 607 } | 614 } |
| 608 | 615 |
| 609 void SVGUseElement::attach() | 616 void SVGUseElement::attach() |
| 610 { | 617 { |
| 611 SVGStyledTransformableElement::attach(); | 618 SVGStyledTransformableElement::attach(); |
| 612 | 619 |
| 613 if (renderer()) | 620 if (renderer()) |
| 614 queuePostAttachCallback(updateFromElementCallback, this); | 621 queuePostAttachCallback(updateFromElementCallback, this); |
| 615 } | 622 } |
| 616 | 623 |
| 617 void SVGUseElement::detach() | 624 void SVGUseElement::detach() |
| 618 { | 625 { |
| 619 SVGStyledTransformableElement::detach(); | 626 SVGStyledTransformableElement::detach(); |
| 620 m_targetElementInstance = 0; | 627 detachInstance(); |
| 621 } | 628 } |
| 622 | 629 |
| 623 static bool isDirectReference(Node* n) | 630 static bool isDirectReference(Node* n) |
| 624 { | 631 { |
| 625 return n->hasTagName(SVGNames::pathTag) || | 632 return n->hasTagName(SVGNames::pathTag) || |
| 626 n->hasTagName(SVGNames::rectTag) || | 633 n->hasTagName(SVGNames::rectTag) || |
| 627 n->hasTagName(SVGNames::circleTag) || | 634 n->hasTagName(SVGNames::circleTag) || |
| 628 n->hasTagName(SVGNames::ellipseTag) || | 635 n->hasTagName(SVGNames::ellipseTag) || |
| 629 n->hasTagName(SVGNames::polygonTag) || | 636 n->hasTagName(SVGNames::polygonTag) || |
| 630 n->hasTagName(SVGNames::polylineTag) || | 637 n->hasTagName(SVGNames::polylineTag) || |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 SVGElement* element = m_targetElementInstance->correspondingElement(); | 1048 SVGElement* element = m_targetElementInstance->correspondingElement(); |
| 1042 if (!element || !element->isStyled()) | 1049 if (!element || !element->isStyled()) |
| 1043 return false; | 1050 return false; |
| 1044 | 1051 |
| 1045 return static_cast<SVGStyledElement*>(element)->hasRelativeLengths(); | 1052 return static_cast<SVGStyledElement*>(element)->hasRelativeLengths(); |
| 1046 } | 1053 } |
| 1047 | 1054 |
| 1048 } | 1055 } |
| 1049 | 1056 |
| 1050 #endif // ENABLE(SVG) | 1057 #endif // ENABLE(SVG) |
| OLD | NEW |