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 |