| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 { | 62 { |
| 63 return adoptRef(new SVGTRefTargetEventListener(trefElement)); | 63 return adoptRef(new SVGTRefTargetEventListener(trefElement)); |
| 64 } | 64 } |
| 65 | 65 |
| 66 static const SVGTRefTargetEventListener* cast(const EventListener* listener) | 66 static const SVGTRefTargetEventListener* cast(const EventListener* listener) |
| 67 { | 67 { |
| 68 return listener->type() == SVGTRefTargetEventListenerType | 68 return listener->type() == SVGTRefTargetEventListenerType |
| 69 ? static_cast<const SVGTRefTargetEventListener*>(listener) : 0; | 69 ? static_cast<const SVGTRefTargetEventListener*>(listener) : 0; |
| 70 } | 70 } |
| 71 | 71 |
| 72 void attach(Element* target, String& targetId); | 72 void attach(PassRefPtr<Element> target); |
| 73 void detach(); | 73 void detach(); |
| 74 bool isAttached() const { return m_attached; } | 74 bool isAttached() const { return m_target.get(); } |
| 75 | 75 |
| 76 private: | 76 private: |
| 77 SVGTRefTargetEventListener(SVGTRefElement* trefElement); | 77 SVGTRefTargetEventListener(SVGTRefElement* trefElement); |
| 78 | 78 |
| 79 virtual void handleEvent(ScriptExecutionContext*, Event*) OVERRIDE; | 79 virtual void handleEvent(ScriptExecutionContext*, Event*) OVERRIDE; |
| 80 virtual bool operator==(const EventListener&) OVERRIDE; | 80 virtual bool operator==(const EventListener&) OVERRIDE; |
| 81 | 81 |
| 82 SVGTRefElement* m_trefElement; | 82 SVGTRefElement* m_trefElement; |
| 83 String m_targetId; | 83 RefPtr<Element> m_target; |
| 84 bool m_attached; | |
| 85 }; | 84 }; |
| 86 | 85 |
| 87 SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement* trefEleme
nt) | 86 SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement* trefEleme
nt) |
| 88 : EventListener(SVGTRefTargetEventListenerType) | 87 : EventListener(SVGTRefTargetEventListenerType) |
| 89 , m_trefElement(trefElement) | 88 , m_trefElement(trefElement) |
| 90 , m_attached(false) | 89 , m_target(0) |
| 91 { | 90 { |
| 92 ASSERT(m_trefElement); | 91 ASSERT(m_trefElement); |
| 93 } | 92 } |
| 94 | 93 |
| 95 void SVGTRefTargetEventListener::attach(Element* target, String& targetId) | 94 void SVGTRefTargetEventListener::attach(PassRefPtr<Element> target) |
| 96 { | 95 { |
| 97 ASSERT(!isAttached()); | 96 ASSERT(!isAttached()); |
| 98 ASSERT(target); | 97 ASSERT(target.get()); |
| 99 ASSERT(target->inDocument()); | 98 ASSERT(target->inDocument()); |
| 100 ASSERT(!targetId.isEmpty()); | |
| 101 | 99 |
| 102 target->addEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); | 100 target->addEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); |
| 103 target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this,
false); | 101 target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this,
false); |
| 104 m_targetId = targetId; | 102 m_target = target; |
| 105 m_attached = true; | |
| 106 } | 103 } |
| 107 | 104 |
| 108 void SVGTRefTargetEventListener::detach() | 105 void SVGTRefTargetEventListener::detach() |
| 109 { | 106 { |
| 110 if (!isAttached()) | 107 if (!isAttached()) |
| 111 return; | 108 return; |
| 112 | 109 |
| 113 if (Element* target = m_trefElement->treeScope()->getElementById(m_targetId)
) { | 110 m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, fa
lse); |
| 114 target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this,
false); | 111 m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent,
this, false); |
| 115 target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent
, this, false); | 112 m_target.clear(); |
| 116 } | |
| 117 | |
| 118 m_targetId = emptyString(); | |
| 119 m_attached = false; | |
| 120 } | 113 } |
| 121 | 114 |
| 122 bool SVGTRefTargetEventListener::operator==(const EventListener& listener) | 115 bool SVGTRefTargetEventListener::operator==(const EventListener& listener) |
| 123 { | 116 { |
| 124 if (const SVGTRefTargetEventListener* targetListener = SVGTRefTargetEventLis
tener::cast(&listener)) | 117 if (const SVGTRefTargetEventListener* targetListener = SVGTRefTargetEventLis
tener::cast(&listener)) |
| 125 return m_trefElement == targetListener->m_trefElement; | 118 return m_trefElement == targetListener->m_trefElement; |
| 126 return false; | 119 return false; |
| 127 } | 120 } |
| 128 | 121 |
| 129 void SVGTRefTargetEventListener::handleEvent(ScriptExecutionContext*, Event* eve
nt) | 122 void SVGTRefTargetEventListener::handleEvent(ScriptExecutionContext*, Event* eve
nt) |
| 130 { | 123 { |
| 131 ASSERT(isAttached()); | 124 ASSERT(isAttached()); |
| 132 | 125 |
| 133 if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement !
= event->target()) | 126 if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement !
= event->target()) |
| 134 m_trefElement->updateReferencedText(); | 127 m_trefElement->updateReferencedText(m_target.get()); |
| 135 else if (event->type() == eventNames().DOMNodeRemovedFromDocumentEvent) | 128 else if (event->type() == eventNames().DOMNodeRemovedFromDocumentEvent) |
| 136 m_trefElement->detachTarget(); | 129 m_trefElement->detachTarget(); |
| 137 } | 130 } |
| 138 | 131 |
| 139 class SVGShadowText : public Text { | 132 class SVGShadowText : public Text { |
| 140 public: | 133 public: |
| 141 static PassRefPtr<SVGShadowText> create(Document* document, const String& da
ta) | 134 static PassRefPtr<SVGShadowText> create(Document* document, const String& da
ta) |
| 142 { | 135 { |
| 143 return adoptRef(new SVGShadowText(document, data)); | 136 return adoptRef(new SVGShadowText(document, data)); |
| 144 } | 137 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 SVGTRefElement::~SVGTRefElement() | 169 SVGTRefElement::~SVGTRefElement() |
| 177 { | 170 { |
| 178 m_targetListener->detach(); | 171 m_targetListener->detach(); |
| 179 } | 172 } |
| 180 | 173 |
| 181 void SVGTRefElement::createShadowSubtree() | 174 void SVGTRefElement::createShadowSubtree() |
| 182 { | 175 { |
| 183 ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTIO
N); | 176 ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTIO
N); |
| 184 } | 177 } |
| 185 | 178 |
| 186 void SVGTRefElement::updateReferencedText() | 179 void SVGTRefElement::updateReferencedText(Element* target) |
| 187 { | 180 { |
| 188 String textContent; | 181 String textContent; |
| 189 if (Element* target = SVGURIReference::targetElementFromIRIString(href(), do
cument())) | 182 if (target) |
| 190 textContent = target->textContent(); | 183 textContent = target->textContent(); |
| 191 | 184 |
| 192 ASSERT(shadow()); | 185 ASSERT(shadow()); |
| 193 ShadowRoot* root = shadow()->oldestShadowRoot(); | 186 ShadowRoot* root = shadow()->oldestShadowRoot(); |
| 194 if (!root->firstChild()) | 187 if (!root->firstChild()) |
| 195 root->appendChild(SVGShadowText::create(document(), textContent), ASSERT
_NO_EXCEPTION); | 188 root->appendChild(SVGShadowText::create(document(), textContent), ASSERT
_NO_EXCEPTION); |
| 196 else | 189 else |
| 197 root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION); | 190 root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION); |
| 198 } | 191 } |
| 199 | 192 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 void SVGTRefElement::buildPendingResource() | 282 void SVGTRefElement::buildPendingResource() |
| 290 { | 283 { |
| 291 // Remove any existing event listener. | 284 // Remove any existing event listener. |
| 292 m_targetListener->detach(); | 285 m_targetListener->detach(); |
| 293 | 286 |
| 294 // If we're not yet in a document, this function will be called again from i
nsertedInto(). | 287 // If we're not yet in a document, this function will be called again from i
nsertedInto(). |
| 295 if (!inDocument()) | 288 if (!inDocument()) |
| 296 return; | 289 return; |
| 297 | 290 |
| 298 String id; | 291 String id; |
| 299 Element* target = SVGURIReference::targetElementFromIRIString(href(), docume
nt(), &id); | 292 RefPtr<Element> target = SVGURIReference::targetElementFromIRIString(href(),
document(), &id); |
| 300 if (!target) { | 293 if (!target.get()) { |
| 301 if (id.isEmpty()) | 294 if (id.isEmpty()) |
| 302 return; | 295 return; |
| 303 | 296 |
| 304 document()->accessSVGExtensions()->addPendingResource(id, this); | 297 document()->accessSVGExtensions()->addPendingResource(id, this); |
| 305 ASSERT(hasPendingResources()); | 298 ASSERT(hasPendingResources()); |
| 306 return; | 299 return; |
| 307 } | 300 } |
| 308 | 301 |
| 309 // Don't set up event listeners if this is a shadow tree node. | 302 // Don't set up event listeners if this is a shadow tree node. |
| 310 // SVGUseElement::transferEventListenersToShadowTree() handles this task, an
d addEventListener() | 303 // SVGUseElement::transferEventListenersToShadowTree() handles this task, an
d addEventListener() |
| 311 // expects every element instance to have an associated shadow tree element
- which is not the | 304 // expects every element instance to have an associated shadow tree element
- which is not the |
| 312 // case when we land here from SVGUseElement::buildShadowTree(). | 305 // case when we land here from SVGUseElement::buildShadowTree(). |
| 313 if (!isInShadowTree()) | 306 if (!isInShadowTree()) |
| 314 m_targetListener->attach(target, id); | 307 m_targetListener->attach(target); |
| 315 | 308 |
| 316 updateReferencedText(); | 309 updateReferencedText(target.get()); |
| 317 } | 310 } |
| 318 | 311 |
| 319 Node::InsertionNotificationRequest SVGTRefElement::insertedInto(ContainerNode* r
ootParent) | 312 Node::InsertionNotificationRequest SVGTRefElement::insertedInto(ContainerNode* r
ootParent) |
| 320 { | 313 { |
| 321 SVGStyledElement::insertedInto(rootParent); | 314 SVGStyledElement::insertedInto(rootParent); |
| 322 if (rootParent->inDocument()) | 315 if (rootParent->inDocument()) |
| 323 buildPendingResource(); | 316 buildPendingResource(); |
| 324 return InsertionDone; | 317 return InsertionDone; |
| 325 } | 318 } |
| 326 | 319 |
| 327 void SVGTRefElement::removedFrom(ContainerNode* rootParent) | 320 void SVGTRefElement::removedFrom(ContainerNode* rootParent) |
| 328 { | 321 { |
| 329 SVGStyledElement::removedFrom(rootParent); | 322 SVGStyledElement::removedFrom(rootParent); |
| 330 if (rootParent->inDocument()) | 323 if (rootParent->inDocument()) |
| 331 m_targetListener->detach(); | 324 m_targetListener->detach(); |
| 332 } | 325 } |
| 333 | 326 |
| 334 } | 327 } |
| 335 | 328 |
| 336 #endif // ENABLE(SVG) | 329 #endif // ENABLE(SVG) |
| OLD | NEW |