@@ -183,52 +183,56 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
183183 ASSERT (!evt->type ().isNull ()); // JavaScript code could create an event with an empty name
184184
185185 // work out what nodes to send event to
186- DeprecatedPtrList <Node> nodeChain;
186+ Vector <Node* > nodeChain;
187187
188188 if (inDocument ()) {
189189 for (Node* n = this ; n; n = n->eventParentNode ()) {
190190 n->ref ();
191- nodeChain.prepend ( n);
191+ nodeChain.insert ( 0 , n);
192192 }
193193 } else {
194194 // if node is not in the document just send event to itself
195195 ref ();
196- nodeChain.prepend (this );
196+ nodeChain.append (this );
197197 }
198-
199- DeprecatedPtrListIterator<Node> it (nodeChain);
198+
199+ unsigned chainSize = nodeChain.size ();
200+ unsigned index = 0 ;
200201
201202 // Before we begin dispatching events, give the target node a chance to do some work prior
202203 // to the DOM event handlers getting a crack.
203204 void * data = preDispatchEventHandler (evt.get ());
204205
205206 // trigger any capturing event handlers on our way down
206207 evt->setEventPhase (Event::CAPTURING_PHASE);
207-
208- it. toFirst () ;
208+
209+ index = 0 ;
209210 // Handle window events for capture phase, except load events, this quirk is needed
210211 // because Mozilla used to never propagate load events to the window object
211- if (evt->type () != loadEvent && it. current () ->isDocumentNode () && !evt->propagationStopped ())
212- static_cast <Document*>(it. current () )->handleWindowEvent (evt.get (), true );
212+ if (evt->type () != loadEvent && chainSize && nodeChain[ 0 ] ->isDocumentNode () && !evt->propagationStopped ())
213+ static_cast <Document*>(nodeChain[ 0 ] )->handleWindowEvent (evt.get (), true );
213214
214- for (; it. current () && it. current () != this && !evt->propagationStopped (); ++it ) {
215- evt->setCurrentTarget (EventTargetNodeCast (it. current () ));
216- EventTargetNodeCast (it. current () )->handleLocalEvents (evt.get (), true );
215+ for (; index < chainSize && nodeChain[index] != this && !evt->propagationStopped (); ++index ) {
216+ evt->setCurrentTarget (EventTargetNodeCast (nodeChain[index] ));
217+ EventTargetNodeCast (nodeChain[index] )->handleLocalEvents (evt.get (), true );
217218 }
218219
219220 // dispatch to the actual target node
220- it.toLast ();
221+ if (chainSize)
222+ index = chainSize - 1 ;
221223 if (!evt->propagationStopped ()) {
222224 evt->setEventPhase (Event::AT_TARGET);
223- evt->setCurrentTarget (EventTargetNodeCast (it. current () ));
225+ evt->setCurrentTarget (EventTargetNodeCast (nodeChain[index] ));
224226
225227 // We do want capturing event listeners to be invoked here, even though
226228 // that violates the specification since Mozilla does it.
227- EventTargetNodeCast (it. current () )->handleLocalEvents (evt.get (), true );
229+ EventTargetNodeCast (nodeChain[index] )->handleLocalEvents (evt.get (), true );
228230
229- EventTargetNodeCast (it. current () )->handleLocalEvents (evt.get (), false );
231+ EventTargetNodeCast (nodeChain[index] )->handleLocalEvents (evt.get (), false );
230232 }
231- --it;
233+
234+ if (index)
235+ --index;
232236
233237 // ok, now bubble up again (only non-capturing event handlers will be called)
234238 // ### recalculate the node chain here? (e.g. if target node moved in document by previous event handlers)
@@ -244,17 +248,21 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
244248
245249 if (evt->bubbles ()) {
246250 evt->setEventPhase (Event::BUBBLING_PHASE);
247- for (; it.current () && !evt->propagationStopped () && !evt->cancelBubble (); --it) {
248- evt->setCurrentTarget (EventTargetNodeCast (it.current ()));
249- EventTargetNodeCast (it.current ())->handleLocalEvents (evt.get (), false );
251+ for (;; ) {
252+ if (!chainSize || evt->propagationStopped () || evt->cancelBubble ())
253+ break ;
254+ evt->setCurrentTarget (EventTargetNodeCast (nodeChain[index]));
255+ EventTargetNodeCast (nodeChain[index])->handleLocalEvents (evt.get (), false );
256+ if (!index)
257+ break ;
258+ --index;
250259 }
251260 // Handle window events for bubbling phase, except load events, this quirk is needed
252261 // because Mozilla used to never propagate load events at all
253262
254- it.toFirst ();
255- if (evt->type () != loadEvent && it.current ()->isDocumentNode () && !evt->propagationStopped () && !evt->cancelBubble ()) {
256- evt->setCurrentTarget (EventTargetNodeCast (it.current ()));
257- static_cast <Document*>(it.current ())->handleWindowEvent (evt.get (), false );
263+ if (evt->type () != loadEvent && chainSize && nodeChain[0 ]->isDocumentNode () && !evt->propagationStopped () && !evt->cancelBubble ()) {
264+ evt->setCurrentTarget (EventTargetNodeCast (nodeChain[0 ]));
265+ static_cast <Document*>(nodeChain[0 ])->handleWindowEvent (evt.get (), false );
258266 }
259267 }
260268
@@ -268,17 +276,24 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
268276
269277 // now we call all default event handlers (this is not part of DOM - it is internal to khtml)
270278
271- it.toLast ();
272- if (evt->bubbles ())
273- for (; it.current () && !evt->defaultPrevented () && !evt->defaultHandled (); --it)
274- EventTargetNodeCast (it.current ())->defaultEventHandler (evt.get ());
275- else if (!evt->defaultPrevented () && !evt->defaultHandled ())
276- EventTargetNodeCast (it.current ())->defaultEventHandler (evt.get ());
279+ if (chainSize) {
280+ unsigned defaultIndex = chainSize - 1 ;
281+ if (evt->bubbles ()) {
282+ for (;; ) {
283+ if (evt->defaultPrevented () || evt->defaultHandled ())
284+ break ;
285+ EventTargetNodeCast (nodeChain[defaultIndex])->defaultEventHandler (evt.get ());
286+ if (!defaultIndex)
287+ break ;
288+ --defaultIndex;
289+ }
290+ } else if (!evt->defaultPrevented () && !evt->defaultHandled ())
291+ EventTargetNodeCast (nodeChain[defaultIndex])->defaultEventHandler (evt.get ());
292+ }
277293
278294 // deref all nodes in chain
279- it.toFirst ();
280- for (; it.current (); ++it)
281- it.current ()->deref (); // this may delete us
295+ for (unsigned i = 0 ; i < chainSize; ++i)
296+ nodeChain[i]->deref (); // this may delete us
282297
283298 Document::updateDocumentsRendering ();
284299
0 commit comments