| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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) |
| OLD | NEW |