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 * along 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 m_shadowRoot->clearSVGShadowHost(); 42 } 43 } 44 45 void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change) 46 { 47 if (m_shadowRoot && m_shadowRoot->attached()) 48 m_shadowRoot->recalcStyle(change); 49 } 50 51 void RenderSVGShadowTreeRootContainer::updateFromElement() 52 { 53 bool hadExistingTree = m_shadowRoot; 54 55 SVGUseElement* useElement = static_cast<SVGUseElement*>(node()); 56 if (!m_shadowRoot) { 57 ASSERT(!m_recreateTree); 58 m_shadowRoot = SVGShadowTreeRootElement::create(document(), useElement); 59 useElement->buildPendingResource(); 60 } 61 62 ASSERT(m_shadowRoot->svgShadowHost() == useElement); 63 64 bool shouldRecreateTree = m_recreateTree; 65 if (m_recreateTree) { 66 ASSERT(hadExistingTree); 67 68 if (m_shadowRoot->attached()) 69 m_shadowRoot->detach(); 70 71 m_shadowRoot->removeAllChildren(); 72 m_recreateTree = false; 73 } 74 75 // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so 76 // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use 77 // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true. 78 if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) { 79 useElement->buildShadowAndInstanceTree(m_shadowRoot.get()); 80 81 // Attach shadow root element 82 m_shadowRoot->attachElement(style(), renderArena()); 83 84 // Attach subtree, as if it was a regular non-shadow tree 85 for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling()) 86 child->attach(); 87 } 88 89 ASSERT(!m_recreateTree); 90 RenderSVGTransformableContainer::updateFromElement(); 91 } 92 93 void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 94 { 95 RenderSVGTransformableContainer::styleDidChange(diff, oldStyle); 96 97 if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0) 98 shadowRootRenderer->setStyle(style()); 99 } 100 101 Node* RenderSVGShadowTreeRootContainer::rootElement() const 102 { 103 return m_shadowRoot.get(); 104 } 105 106 } 107 108 #endif 109