KHTML
SVGElementInstance.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> 00003 00004 This file is part of the KDE project 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "config.h" 00023 #include "wtf/Platform.h" 00024 00025 #if ENABLE(SVG) 00026 #include "SVGElementInstance.h" 00027 00028 /*#include "Event.h" 00029 #include "EventListener.h"*/ 00030 #include "SVGElementInstanceList.h" 00031 #include "SVGUseElement.h" 00032 00033 #include <wtf/Assertions.h> 00034 00035 namespace WebCore { 00036 00037 SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement) 00038 : m_refCount(0) 00039 , m_parent(0) 00040 , m_useElement(useElement) 00041 , m_element(originalElement) 00042 , m_shadowTreeElement(0) 00043 , m_previousSibling(0) 00044 , m_nextSibling(0) 00045 , m_firstChild(0) 00046 , m_lastChild(0) 00047 { 00048 ASSERT(m_useElement); 00049 ASSERT(m_element); 00050 00051 // Register as instance for passed element. 00052 m_element->document()->accessSVGExtensions()->mapInstanceToElement(this, m_element.get()); 00053 } 00054 00055 SVGElementInstance::~SVGElementInstance() 00056 { 00057 for (RefPtr<SVGElementInstance> child = m_firstChild; child; child = child->m_nextSibling) 00058 child->setParent(0); 00059 00060 // Deregister as instance for passed element. 00061 m_element->document()->accessSVGExtensions()->removeInstanceMapping(this, m_element.get()); 00062 } 00063 00064 SVGElement* SVGElementInstance::correspondingElement() const 00065 { 00066 return m_element.get(); 00067 } 00068 00069 SVGUseElement* SVGElementInstance::correspondingUseElement() const 00070 { 00071 return m_useElement; 00072 } 00073 00074 SVGElementInstance* SVGElementInstance::parentNode() const 00075 { 00076 return parent(); 00077 } 00078 00079 PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes() 00080 { 00081 return SVGElementInstanceList::create(this); 00082 } 00083 00084 SVGElementInstance* SVGElementInstance::previousSibling() const 00085 { 00086 return m_previousSibling; 00087 } 00088 00089 SVGElementInstance* SVGElementInstance::nextSibling() const 00090 { 00091 return m_nextSibling; 00092 } 00093 00094 SVGElementInstance* SVGElementInstance::firstChild() const 00095 { 00096 return m_firstChild; 00097 } 00098 00099 SVGElementInstance* SVGElementInstance::lastChild() const 00100 { 00101 return m_lastChild; 00102 } 00103 00104 SVGElement* SVGElementInstance::shadowTreeElement() const 00105 { 00106 return m_shadowTreeElement; 00107 } 00108 00109 void SVGElementInstance::setShadowTreeElement(SVGElement* element) 00110 { 00111 ASSERT(element); 00112 m_shadowTreeElement = element; 00113 } 00114 00115 void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) 00116 { 00117 child->setParent(this); 00118 00119 if (m_lastChild) { 00120 child->m_previousSibling = m_lastChild; 00121 m_lastChild->m_nextSibling = child.get(); 00122 } else 00123 m_firstChild = child.get(); 00124 00125 m_lastChild = child.get(); 00126 } 00127 00128 // Helper function for updateInstance 00129 static bool containsUseChildNode(Node* start) 00130 { 00131 if (start->hasTagName(SVGNames::useTag)) 00132 return true; 00133 00134 for (Node* current = start->firstChild(); current; current = current->nextSibling()) { 00135 if (containsUseChildNode(current)) 00136 return true; 00137 } 00138 00139 return false; 00140 } 00141 00142 void SVGElementInstance::updateInstance(SVGElement* element) 00143 { 00144 ASSERT(element == m_element); 00145 ASSERT(m_shadowTreeElement); 00146 00147 // TODO: Eventually come up with a more optimized updating logic for the cases below: 00148 // 00149 // <symbol>: We can't just clone the original element, we need to apply 00150 // the same "replace by generated content" logic that SVGUseElement does. 00151 // 00152 // <svg>: <use> on <svg> is too rare to actually implement it faster. 00153 // If someone still wants to do it: recloning, adjusting width/height attributes is enough. 00154 // 00155 // <use>: Too hard to get it right in a fast way. Recloning seems the only option. 00156 00157 if (m_element->hasTagName(SVGNames::symbolTag) || 00158 m_element->hasTagName(SVGNames::svgTag) || 00159 containsUseChildNode(m_element.get())) { 00160 m_useElement->buildPendingResource(); 00161 return; 00162 } 00163 00164 // For all other nodes this logic is sufficient. 00165 WTF::PassRefPtr<Node> clone = m_element->cloneNode(true); 00166 SVGUseElement::removeDisallowedElementsFromSubtree(clone.get()); 00167 SVGElement* svgClone = 0; 00168 if (clone && clone->isSVGElement()) 00169 svgClone = static_cast<SVGElement*>(clone.get()); 00170 ASSERT(svgClone); 00171 00172 // Replace node in the <use> shadow tree 00173 /*ExceptionCode*//*khtml*/int ec = 0; 00174 m_shadowTreeElement->parentNode()->replaceChild(clone.releaseRef(), m_shadowTreeElement, ec); 00175 ASSERT(ec == 0); 00176 00177 m_shadowTreeElement = svgClone; 00178 } 00179 00180 SVGElementInstance* SVGElementInstance::toSVGElementInstance() 00181 { 00182 return this; 00183 } 00184 00185 EventTargetNode* SVGElementInstance::toNode() 00186 { 00187 return m_element.get(); 00188 } 00189 00190 void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool useCapture) 00191 { 00192 Q_UNUSED(eventType); 00193 Q_UNUSED(eventListener); 00194 Q_UNUSED(useCapture); 00195 // FIXME! 00196 } 00197 00198 void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool useCapture) 00199 { 00200 Q_UNUSED(eventType); 00201 Q_UNUSED(eventListener); 00202 Q_UNUSED(useCapture); 00203 // FIXME! 00204 } 00205 00206 bool SVGElementInstance::dispatchEvent(PassRefPtr<Event>, ExceptionCode& ec, bool tempEvent) 00207 { 00208 Q_UNUSED(ec); 00209 Q_UNUSED(tempEvent); 00210 // FIXME! 00211 return false; 00212 } 00213 00214 } 00215 00216 #endif // ENABLE(SVG) 00217 00218 // vim:ts=4:noet
KDE 4.6 API Reference