Changeset 8557 in webkit
- Timestamp:
- Feb 10, 2005, 12:40:56 AM (20 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog-2005-08-23
r8556 r8557 1 2005-02-08 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Darin. 4 5 <rdar://problem/3977973> pages on ebay leak referenced JavaScript objects -- over time browsing becomes super-slow 6 7 I fixed this by removing all event listeners for a document, it's 8 children, and any disconnected nodes that used to be in the 9 document at document detach time. Mozilla temporarily disables 10 event listeners on such nodes, but re-enables them if you 11 re-parant a node into a new document. However, in WebCore, you 12 can't re-parent a node into another document, so there is no 13 observable change in behavior. 14 15 We have to do this to break the possible reference cycles between 16 event listeners and the dom nodes they are attached to (e.g. via 17 scope chain, as in this case). 18 19 * khtml/xml/dom_docimpl.cpp: 20 (DocumentImpl::detach): 21 (DocumentImpl::removeAllEventListenersFromAllNodesx): 22 (DocumentImpl::registerDisconnectedNodeWithEventListeners): 23 (DocumentImpl::unregisterDisconnectedNodeWithEventListeners): 24 (DocumentImpl::removeAllDisconnectedNodeEventListeners): 25 * khtml/xml/dom_docimpl.h: 26 * khtml/xml/dom_nodeimpl.cpp: 27 (NodeImpl::~NodeImpl): 28 (NodeImpl::addEventListener): 29 (NodeImpl::removeEventListener): 30 (NodeImpl::removeAllEventListeners): 31 (NodeImpl::removeHTMLEventListener): 32 (NodeImpl::insertedIntoDocument): 33 (NodeImpl::removedFromDocument): 34 * khtml/xml/dom_nodeimpl.h: 35 1 36 2005-02-09 Chris Blumenberg <cblu@apple.com> 2 37 -
trunk/WebCore/khtml/xml/dom_docimpl.cpp
r8554 r8557 1192 1192 m_imageLoadEventDispatchingList.clear(); 1193 1193 1194 removeAllEventListenersFromAllNodes(); 1195 1194 1196 NodeBaseImpl::detach(); 1195 1197 … … 1204 1206 delete m_renderArena; 1205 1207 m_renderArena = 0; 1208 } 1209 } 1210 1211 void DocumentImpl::removeAllEventListenersFromAllNodes() 1212 { 1213 m_windowEventListeners.clear(); 1214 removeAllDisconnectedNodeEventListeners(); 1215 for (NodeImpl *n = this; n; n = n->traverseNextNode()) { 1216 n->removeAllEventListeners(); 1217 } 1218 } 1219 1220 void DocumentImpl::registerDisconnectedNodeWithEventListeners(NodeImpl *node) 1221 { 1222 m_disconnectedNodesWithEventListeners.insert(node, node); 1223 } 1224 1225 void DocumentImpl::unregisterDisconnectedNodeWithEventListeners(NodeImpl *node) 1226 { 1227 m_disconnectedNodesWithEventListeners.remove(node); 1228 } 1229 1230 void DocumentImpl::removeAllDisconnectedNodeEventListeners() 1231 { 1232 for (QPtrDictIterator<NodeImpl> iter(m_disconnectedNodesWithEventListeners); 1233 iter.current(); 1234 ++iter) { 1235 iter.current()->removeAllEventListeners(); 1206 1236 } 1207 1237 } -
trunk/WebCore/khtml/xml/dom_docimpl.h
r8309 r8557 703 703 DOMString m_policyBaseURL; 704 704 705 QPtrDict<NodeImpl> m_disconnectedNodesWithEventListeners; 706 705 707 #if APPLE_CHANGES 706 708 public: … … 734 736 void setDashboardRegions (const QValueList<khtml::DashboardRegionValue>& regions); 735 737 738 void removeAllEventListenersFromAllNodes(); 739 740 void registerDisconnectedNodeWithEventListeners(NodeImpl *node); 741 void unregisterDisconnectedNodeWithEventListeners(NodeImpl *node); 742 736 743 private: 744 void removeAllDisconnectedNodeEventListeners(); 745 737 746 JSEditor *jsEditor(); 738 747 -
trunk/WebCore/khtml/xml/dom_nodeimpl.cpp
r8554 r8557 111 111 if (m_render) 112 112 detach(); 113 if (m_regdListeners && !m_regdListeners->isEmpty() && getDocument() && !inDocument()) 114 getDocument()->unregisterDisconnectedNodeWithEventListeners(this); 113 115 delete m_regdListeners; 114 116 delete m_nodeLists; … … 341 343 void NodeImpl::addEventListener(int id, EventListener *listener, const bool useCapture) 342 344 { 345 if (getDocument() && !getDocument()->attached()) 346 return; 347 343 348 switch (id) { 344 349 case EventImpl::DOMSUBTREEMODIFIED_EVENT: … … 379 384 removeEventListener(id,listener,useCapture); 380 385 386 // adding the first one 387 if (m_regdListeners->isEmpty() && getDocument() && !inDocument()) 388 getDocument()->registerDisconnectedNodeWithEventListeners(this); 389 381 390 m_regdListeners->append(rl); 382 391 listener->deref(); … … 394 403 if (*(it.current()) == rl) { 395 404 m_regdListeners->removeRef(it.current()); 405 // removed last 406 if (m_regdListeners->isEmpty() && getDocument() && !inDocument()) 407 getDocument()->unregisterDisconnectedNodeWithEventListeners(this); 396 408 return; 397 409 } 410 } 411 412 void NodeImpl::removeAllEventListeners() 413 { 414 delete m_regdListeners; 415 m_regdListeners = 0; 398 416 } 399 417 … … 408 426 it.current()->listener->eventListenerType() == "_khtml_HTMLEventListener") { 409 427 m_regdListeners->removeRef(it.current()); 428 // removed last 429 if (m_regdListeners->isEmpty() && getDocument() && !inDocument()) 430 getDocument()->unregisterDisconnectedNodeWithEventListeners(this); 410 431 return; 411 432 } … … 1095 1116 void NodeImpl::insertedIntoDocument() 1096 1117 { 1118 if (m_regdListeners && !m_regdListeners->isEmpty() && getDocument()) 1119 getDocument()->unregisterDisconnectedNodeWithEventListeners(this); 1120 1097 1121 setInDocument(true); 1098 1122 } … … 1100 1124 void NodeImpl::removedFromDocument() 1101 1125 { 1126 if (m_regdListeners && !m_regdListeners->isEmpty() && getDocument()) 1127 getDocument()->registerDisconnectedNodeWithEventListeners(this); 1128 1102 1129 setInDocument(false); 1103 1130 } -
trunk/WebCore/khtml/xml/dom_nodeimpl.h
r8492 r8557 278 278 void setHTMLEventListener(int id, EventListener *listener); 279 279 EventListener *getHTMLEventListener(int id); 280 void removeAllEventListeners(); 280 281 281 282 bool dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false);
Note:
See TracChangeset
for help on using the changeset viewer.