1 /* 2 Copyright (C) Research In Motion Limited 2010. All rights reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 aint with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301, USA. 18 */ 19 20 #include "config.h" 21 22 #if ENABLE(SVG) 23 #include "RenderSVGShadowTreeRootContainer.h" 24 25 #include "MouseEvent.h" 26 #include "SVGShadowTreeElements.h" 27 #include "SVGUseElement.h" 28 29 namespace WebCore { 30 31 RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement* node) 32 : RenderSVGTransformableContainer(node) 33 , m_recreateTree(false) 34 { 35 } 36 37 RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer() 38 { 39 if (m_shadowRoot && m_shadowRoot->attached()) 40 m_shadowRoot->detach(); 41 } 42 43 void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change) 44 { 45 if (m_shadowRoot && m_shadowRoot->attached()) 46 m_shadowRoot->recalcStyle(change); 47 } 48 49 void RenderSVGShadowTreeRootContainer::updateFromElement() 50 { 51 bool hadExistingTree = m_shadowRoot; 52 53 SVGUseElement* useElement = static_cast<SVGUseElement*>(node()); 54 if (!m_shadowRoot) { 55 ASSERT(!m_recreateTree); 56 m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement); 57 useElement->buildPendingResource(); 58 } 59 60 ASSERT(m_shadowRoot->shadowParentNode() == useElement); 61 62 bool shouldRecreateTree = m_recreateTree; 63 if (m_recreateTree) { 64 ASSERT(hadExistingTree); 65 66 if (m_shadowRoot->attached()) 67 m_shadowRoot->detach(); 68 69 m_shadowRoot->removeAllChildren(); 70 m_recreateTree = false; 71 } 72 73 // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so 74 // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use 75 // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true. 76 if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) { 77 useElement->buildShadowAndInstanceTree(m_shadowRoot.get()); 78 79 // Attach shadow root element 80 m_shadowRoot->attachElement(style(), renderArena()); 81 82 // Attach subtree, as if it was a regular non-shadow tree 83 for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling()) 84 child->attach(); 85 } 86 87 ASSERT(!m_recreateTree); 88 RenderSVGTransformableContainer::updateFromElement(); 89 } 90 91 void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 92 { 93 RenderSVGTransformableContainer::styleDidChange(diff, oldStyle); 94 95 if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0) 96 shadowRootRenderer->setStyle(style()); 97 } 98 99 } 100 101 #endif 102