Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: Source/WebCore/svg/SVGTRefElement.cpp

Issue 8203008: Merge 96707 - Crash in SVGTRefElement::updateReferencedText. (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/874/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/svg/SVGTRefElement.h ('k') | Source/WebCore/svg/SVGTextPathElement.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 4 * Copyright (C) Research In Motion Limited 2011. 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return adoptRef(new SubtreeModificationEventListener(trefElement, target Id)); 68 return adoptRef(new SubtreeModificationEventListener(trefElement, target Id));
69 } 69 }
70 70
71 static const SubtreeModificationEventListener* cast(const EventListener* lis tener) 71 static const SubtreeModificationEventListener* cast(const EventListener* lis tener)
72 { 72 {
73 return listener->type() == CPPEventListenerType ? static_cast<const Subt reeModificationEventListener*>(listener) : 0; 73 return listener->type() == CPPEventListenerType ? static_cast<const Subt reeModificationEventListener*>(listener) : 0;
74 } 74 }
75 75
76 virtual bool operator==(const EventListener&); 76 virtual bool operator==(const EventListener&);
77 77
78 void removeFromTarget() 78 void clear()
79 { 79 {
80 Element* target = m_trefElement->treeScope()->getElementById(m_targetId) ; 80 Element* target = m_trefElement->treeScope()->getElementById(m_targetId) ;
81 if (target && target->parentNode()) 81 if (target && target->parentNode())
82 target->parentNode()->removeEventListener(eventNames().DOMSubtreeMod ifiedEvent, this, false); 82 target->parentNode()->removeEventListener(eventNames().DOMSubtreeMod ifiedEvent, this, false);
83
84 m_trefElement = 0;
85 m_targetId = String();
83 } 86 }
84 87
85 private: 88 private:
86 SubtreeModificationEventListener(SVGTRefElement* trefElement, String targetI d) 89 SubtreeModificationEventListener(SVGTRefElement* trefElement, String targetI d)
87 : EventListener(CPPEventListenerType) 90 : EventListener(CPPEventListenerType)
88 , m_trefElement(trefElement) 91 , m_trefElement(trefElement)
89 , m_targetId(targetId) 92 , m_targetId(targetId)
90 { 93 {
91 } 94 }
92 95
93 virtual void handleEvent(ScriptExecutionContext*, Event*); 96 virtual void handleEvent(ScriptExecutionContext*, Event*);
94 97
95 SVGTRefElement* m_trefElement; 98 SVGTRefElement* m_trefElement;
96 String m_targetId; 99 String m_targetId;
97 }; 100 };
98 101
99 bool SubtreeModificationEventListener::operator==(const EventListener& listener) 102 bool SubtreeModificationEventListener::operator==(const EventListener& listener)
100 { 103 {
101 if (const SubtreeModificationEventListener* subtreeModificationEventListener = SubtreeModificationEventListener::cast(&listener)) 104 if (const SubtreeModificationEventListener* subtreeModificationEventListener = SubtreeModificationEventListener::cast(&listener))
102 return m_trefElement == subtreeModificationEventListener->m_trefElement; 105 return m_trefElement == subtreeModificationEventListener->m_trefElement;
103 return false; 106 return false;
104 } 107 }
105 108
106 void SubtreeModificationEventListener::handleEvent(ScriptExecutionContext*, Even t* event) 109 void SubtreeModificationEventListener::handleEvent(ScriptExecutionContext*, Even t* event)
107 { 110 {
108 if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement ! = event->target()) 111 if (m_trefElement && event->type() == eventNames().DOMSubtreeModifiedEvent & & m_trefElement != event->target())
109 m_trefElement->updateReferencedText(); 112 m_trefElement->updateReferencedText();
110 } 113 }
111 114
112 class SVGShadowText : public Text { 115 class SVGShadowText : public Text {
113 public: 116 public:
114 static PassRefPtr<SVGShadowText> create(Document* document, const String& da ta) 117 static PassRefPtr<SVGShadowText> create(Document* document, const String& da ta)
115 { 118 {
116 return adoptRef(new SVGShadowText(document, data)); 119 return adoptRef(new SVGShadowText(document, data));
117 } 120 }
118 private: 121 private:
(...skipping 12 matching lines...) Expand all
131 134
132 bool SVGShadowText::willRecalcStyle(StyleChange change) 135 bool SVGShadowText::willRecalcStyle(StyleChange change)
133 { 136 {
134 if (change != NoChange && parentNode()->shadowHost()) { 137 if (change != NoChange && parentNode()->shadowHost()) {
135 if (renderer()) 138 if (renderer())
136 renderer()->setStyle(parentNode()->shadowHost()->renderer()->style() ); 139 renderer()->setStyle(parentNode()->shadowHost()->renderer()->style() );
137 } 140 }
138 return true; 141 return true;
139 } 142 }
140 143
144 SVGTRefElement::~SVGTRefElement()
145 {
146 clearEventListener();
147 }
148
141 void SVGTRefElement::updateReferencedText() 149 void SVGTRefElement::updateReferencedText()
142 { 150 {
143 Element* target = SVGURIReference::targetElementFromIRIString(href(), docume nt()); 151 Element* target = SVGURIReference::targetElementFromIRIString(href(), docume nt());
144 ASSERT(target); 152 ASSERT(target);
145 String textContent; 153 String textContent;
146 if (target->parentNode()) 154 if (target->parentNode())
147 textContent = target->textContent(); 155 textContent = target->textContent();
148 ExceptionCode ignore = 0; 156 ExceptionCode ignore = 0;
149 if (!ensureShadowRoot()->firstChild()) 157 if (!ensureShadowRoot()->firstChild())
150 shadowRoot()->appendChild(SVGShadowText::create(document(), textContent) , ignore); 158 shadowRoot()->appendChild(SVGShadowText::create(document(), textContent) , ignore);
(...skipping 26 matching lines...) Expand all
177 void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName) 185 void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName)
178 { 186 {
179 if (!isSupportedAttribute(attrName)) { 187 if (!isSupportedAttribute(attrName)) {
180 SVGTextPositioningElement::svgAttributeChanged(attrName); 188 SVGTextPositioningElement::svgAttributeChanged(attrName);
181 return; 189 return;
182 } 190 }
183 191
184 SVGElementInstance::InvalidationGuard invalidationGuard(this); 192 SVGElementInstance::InvalidationGuard invalidationGuard(this);
185 193
186 if (SVGURIReference::isKnownAttribute(attrName)) { 194 if (SVGURIReference::isKnownAttribute(attrName)) {
187 if (m_eventListener) { 195 buildPendingResource();
188 m_eventListener->removeFromTarget();
189 m_eventListener = 0;
190 }
191 String id;
192 Element* target = SVGURIReference::targetElementFromIRIString(href(), do cument(), &id);
193 if (!target) {
194 document()->accessSVGExtensions()->addPendingResource(id, this);
195 return;
196 }
197 updateReferencedText();
198 if (inDocument()) {
199 m_eventListener = SubtreeModificationEventListener::create(this, id) ;
200 ASSERT(target->parentNode());
201 target->parentNode()->addEventListener(eventNames().DOMSubtreeModifi edEvent, m_eventListener.get(), false);
202 }
203 if (RenderObject* renderer = this->renderer()) 196 if (RenderObject* renderer = this->renderer())
204 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er); 197 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er);
205 return; 198 return;
206 } 199 }
207 200
208 ASSERT_NOT_REACHED(); 201 ASSERT_NOT_REACHED();
209 } 202 }
210 203
211 RenderObject* SVGTRefElement::createRenderer(RenderArena* arena, RenderStyle*) 204 RenderObject* SVGTRefElement::createRenderer(RenderArena* arena, RenderStyle*)
212 { 205 {
(...skipping 15 matching lines...) Expand all
228 || parentNode()->hasTagName(SVGNames::textTag) 221 || parentNode()->hasTagName(SVGNames::textTag)
229 || parentNode()->hasTagName(SVGNames::textPathTag) 222 || parentNode()->hasTagName(SVGNames::textPathTag)
230 || parentNode()->hasTagName(SVGNames::tspanTag))) 223 || parentNode()->hasTagName(SVGNames::tspanTag)))
231 return StyledElement::rendererIsNeeded(context); 224 return StyledElement::rendererIsNeeded(context);
232 225
233 return false; 226 return false;
234 } 227 }
235 228
236 void SVGTRefElement::buildPendingResource() 229 void SVGTRefElement::buildPendingResource()
237 { 230 {
231 // Remove any existing event listener.
232 clearEventListener();
233
234 String id;
235 Element* target = SVGURIReference::targetElementFromIRIString(href(), docume nt(), &id);
236 if (!target) {
237 if (hasPendingResources() || id.isEmpty())
238 return;
239
240 ASSERT(!hasPendingResources());
241 document()->accessSVGExtensions()->addPendingResource(id, this);
242 ASSERT(hasPendingResources());
243 return;
244 }
245
238 updateReferencedText(); 246 updateReferencedText();
239 if (Element* target = SVGURIReference::targetElementFromIRIString(href(), do cument())) { 247
240 ASSERT(!m_eventListener); 248 // We should not add the event listener if we are not in document yet.
241 m_eventListener = SubtreeModificationEventListener::create(this, target- >getIdAttribute()); 249 if (!inDocument())
242 ASSERT(target->parentNode()); 250 return;
243 target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEv ent, m_eventListener.get(), false); 251
244 } 252 m_eventListener = SubtreeModificationEventListener::create(this, id);
253 ASSERT(target->parentNode());
254 target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
245 } 255 }
246 256
247 void SVGTRefElement::insertedIntoDocument() 257 void SVGTRefElement::insertedIntoDocument()
248 { 258 {
249 SVGStyledElement::insertedIntoDocument(); 259 SVGStyledElement::insertedIntoDocument();
250 String id; 260 buildPendingResource();
251 Element* target = SVGURIReference::targetElementFromIRIString(href(), docume nt(), &id);
252 if (!target) {
253 document()->accessSVGExtensions()->addPendingResource(id, this);
254 return;
255 }
256 updateReferencedText();
257 m_eventListener = SubtreeModificationEventListener::create(this, id);
258 ASSERT(target->parentNode());
259 target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
260 } 261 }
261 262
262 void SVGTRefElement::removedFromDocument() 263 void SVGTRefElement::removedFromDocument()
263 { 264 {
264 SVGStyledElement::removedFromDocument(); 265 SVGStyledElement::removedFromDocument();
266 clearEventListener();
267 }
265 268
266 if (!m_eventListener) 269 void SVGTRefElement::clearEventListener()
267 return; 270 {
268 271 if (m_eventListener) {
269 m_eventListener->removeFromTarget(); 272 m_eventListener->clear();
270 m_eventListener = 0; 273 m_eventListener = 0;
274 }
271 } 275 }
272 276
273 } 277 }
274 278
275 #endif // ENABLE(SVG) 279 #endif // ENABLE(SVG)
OLDNEW
« no previous file with comments | « Source/WebCore/svg/SVGTRefElement.h ('k') | Source/WebCore/svg/SVGTextPathElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698