f7d7b16d9131fed72582cdc2beeb2398cbdd956d
[WebKit-https.git] / WebCore / page / FrameView.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4  *                     1999 Lars Knoll <knoll@kde.org>
5  *                     1999 Antti Koivisto <koivisto@kde.org>
6  *                     2000 Dirk Mueller <mueller@kde.org>
7  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include "config.h"
26 #include "FrameView.h"
27
28 #include "AXObjectCache.h"
29 #include "CachedImage.h"
30 #include "Cursor.h"
31 #include "EventNames.h"
32 #include "Frame.h"
33 #include "FrameTree.h"
34 #include "HTMLDocument.h"
35 #include "HTMLFrameSetElement.h"
36 #include "HTMLInputElement.h"
37 #include "HTMLNames.h"
38 #include "Image.h"
39 #include "MouseEvent.h"
40 #include "MouseEventWithHitTestResults.h"
41 #include "OverflowEvent.h"
42 #include "PlatformKeyboardEvent.h"
43 #include "PlatformWheelEvent.h"
44 #include "RenderArena.h"
45 #include "RenderPart.h"
46 #include "RenderText.h"
47 #include "RenderView.h"
48 #include "SelectionController.h"
49 #include "cssstyleselector.h"
50
51 namespace WebCore {
52
53 using namespace EventNames;
54 using namespace HTMLNames;
55
56 struct ScheduledEvent {
57     RefPtr<Event> m_event;
58     RefPtr<EventTargetNode> m_eventTarget;
59     bool m_tempEvent;
60 };
61
62 class FrameViewPrivate {
63 public:
64     FrameViewPrivate(FrameView* view)
65         : m_hasBorder(false)
66         , layoutTimer(view, &FrameView::layoutTimerFired)
67         , hoverTimer(view, &FrameView::hoverTimerFired)
68         , m_resizeLayer(0)
69         , m_mediaType("screen")
70         , m_scheduledEvents(0)
71         , m_overflowStatusDirty(true)
72         , m_viewportRenderer(0)
73     {
74         repaintRects = 0;
75         isTransparent = false;
76         vmode = hmode = ScrollBarAuto;
77         needToInitScrollBars = true;
78         reset();
79     }
80     ~FrameViewPrivate()
81     {
82         delete repaintRects;
83         delete m_scheduledEvents;
84     }
85     void reset()
86     {
87         underMouse = 0;
88         oldUnder = 0;
89         oldSubframe = 0;
90         linkPressed = false;
91         useSlowRepaints = false;
92         slowRepaintObjectCount = 0;
93         dragTarget = 0;
94         borderTouched = false;
95         scrollBarMoved = false;
96         ignoreWheelEvents = false;
97         borderX = 30;
98         borderY = 30;
99         clickCount = 0;
100         clickNode = 0;
101         scrollingSelf = false;
102         layoutTimer.stop();
103         layoutRoot = 0;
104         delayedLayout = false;
105         mousePressed = false;
106         doFullRepaint = true;
107         layoutSchedulingEnabled = true;
108         layoutCount = 0;
109         firstLayout = true;
110         hoverTimer.stop();
111         if (repaintRects)
112             repaintRects->clear();
113         resizingFrameSet = 0;
114         m_resizeLayer = 0;
115     }
116
117     RefPtr<Node> underMouse;
118     RefPtr<Node> oldUnder;
119     RefPtr<Frame> oldSubframe;
120
121     bool borderTouched : 1;
122     bool borderStart : 1;
123     bool scrollBarMoved : 1;
124     bool doFullRepaint : 1;
125     bool m_hasBorder : 1;
126     
127     ScrollBarMode vmode;
128     ScrollBarMode hmode;
129     bool linkPressed;
130     bool useSlowRepaints;
131     unsigned slowRepaintObjectCount;
132     bool ignoreWheelEvents;
133
134     int borderX, borderY;
135     int clickCount;
136     RefPtr<Node> clickNode;
137
138     bool scrollingSelf;
139     Timer<FrameView> layoutTimer;
140     bool delayedLayout;
141     RefPtr<Node> layoutRoot;
142     
143     bool layoutSchedulingEnabled;
144     int layoutCount;
145
146     bool firstLayout;
147     bool needToInitScrollBars;
148     bool mousePressed;
149     bool isTransparent;
150     
151     Timer<FrameView> hoverTimer;
152     
153     RenderLayer* m_resizeLayer;
154     IntSize offsetFromResizeCorner;
155     
156     // Used by objects during layout to communicate repaints that need to take place only
157     // after all layout has been completed.
158     DeprecatedPtrList<RenderObject::RepaintInfo>* repaintRects;
159     
160     RefPtr<Node> dragTarget;
161     RefPtr<HTMLFrameSetElement> resizingFrameSet;
162     
163     String m_mediaType;
164     
165     Vector<ScheduledEvent*>* m_scheduledEvents;
166     
167     bool m_overflowStatusDirty;
168     bool horizontalOverflow;
169     bool m_verticalOverflow;    
170     RenderObject* m_viewportRenderer;
171 };
172
173 FrameView::FrameView(Frame *frame)
174     : m_refCount(1)
175     , m_frame(frame)
176     , d(new FrameViewPrivate(this))
177 {
178     init();
179
180     show();
181 }
182
183 FrameView::~FrameView()
184 {
185     resetScrollBars();
186
187     ASSERT(m_refCount == 0);
188
189     if (d->hoverTimer.isActive())
190         d->hoverTimer.stop();
191     if (m_frame) {
192         // FIXME: Is this really the right place to call detach on the document?
193         if (Document* doc = m_frame->document())
194             doc->detach();
195         if (RenderPart* renderer = m_frame->ownerRenderer())
196             renderer->setWidget(0);
197     }
198
199     delete d;
200     d = 0;
201 }
202
203 void FrameView::clearPart()
204 {
205     m_frame = 0;
206 }
207
208 void FrameView::resetScrollBars()
209 {
210     // Reset the document's scrollbars back to our defaults before we yield the floor.
211     d->firstLayout = true;
212     suppressScrollBars(true);
213     ScrollView::setVScrollBarMode(d->vmode);
214     ScrollView::setHScrollBarMode(d->hmode);
215     suppressScrollBars(false);
216 }
217
218 void FrameView::init()
219 {
220     m_margins = IntSize(-1, -1); // undefined
221     m_size = IntSize();
222 }
223
224 void FrameView::clear()
225 {
226     setStaticBackground(false);
227     
228     // FIXME: 6498 Should just be able to call m_frame->selection().clear()
229     m_frame->setSelection(SelectionController());
230
231     d->reset();
232
233 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
234     if (d->layoutTimer.isActive() && m_frame->document() && !m_frame->document()->ownerElement())
235         printf("Killing the layout timer from a clear at %d\n", m_frame->document()->elapsedTime());
236 #endif    
237     d->layoutTimer.stop();
238
239     cleared();
240
241     suppressScrollBars(true);
242 }
243
244 void FrameView::initScrollBars()
245 {
246     if (!d->needToInitScrollBars)
247         return;
248     d->needToInitScrollBars = false;
249     setScrollBarsMode(hScrollBarMode());
250 }
251
252 void FrameView::setMarginWidth(int w)
253 {
254     // make it update the rendering area when set
255     m_margins.setWidth(w);
256 }
257
258 void FrameView::setMarginHeight(int h)
259 {
260     // make it update the rendering area when set
261     m_margins.setHeight(h);
262 }
263
264 void FrameView::adjustViewSize()
265 {
266     if (m_frame->document()) {
267         Document *document = m_frame->document();
268
269         RenderView* root = static_cast<RenderView *>(document->renderer());
270         if (!root)
271             return;
272         
273         int docw = root->docWidth();
274         int doch = root->docHeight();
275     
276         resizeContents(docw, doch);
277     }
278 }
279
280 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollBarMode& hMode, ScrollBarMode& vMode)
281 {
282     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
283     // overflow:hidden and overflow:scroll on <body> as applying to the document's
284     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
285     // use the root element.
286     switch (o->style()->overflowX()) {
287         case OHIDDEN:
288             hMode = ScrollBarAlwaysOff;
289             break;
290         case OSCROLL:
291             hMode = ScrollBarAlwaysOn;
292             break;
293         case OAUTO:
294             hMode = ScrollBarAuto;
295             break;
296         default:
297             // Don't set it at all.
298             ;
299     }
300     
301      switch (o->style()->overflowY()) {
302         case OHIDDEN:
303             vMode = ScrollBarAlwaysOff;
304             break;
305         case OSCROLL:
306             vMode = ScrollBarAlwaysOn;
307             break;
308         case OAUTO:
309             vMode = ScrollBarAuto;
310             break;
311         default:
312             // Don't set it at all.
313             ;
314     }
315
316     d->m_viewportRenderer = o;
317 }
318
319 int FrameView::layoutCount() const
320 {
321     return d->layoutCount;
322 }
323
324 bool FrameView::needsFullRepaint() const
325 {
326     return d->doFullRepaint;
327 }
328
329 void FrameView::addRepaintInfo(RenderObject* o, const IntRect& r)
330 {
331     if (!d->repaintRects) {
332         d->repaintRects = new DeprecatedPtrList<RenderObject::RepaintInfo>;
333         d->repaintRects->setAutoDelete(true);
334     }
335     
336     d->repaintRects->append(new RenderObject::RepaintInfo(o, r));
337 }
338
339 Node* FrameView::layoutRoot() const
340 {
341     return layoutPending() ? 0 : d->layoutRoot.get();
342 }
343
344 void FrameView::layout(bool allowSubtree)
345 {
346     d->layoutTimer.stop();
347     d->delayedLayout = false;
348
349     // Protect the view from being deleted during layout (in recalcStyle)
350     RefPtr<FrameView> protector(this);
351
352     if (!m_frame) {
353         // FIXME: Do we need to set m_size.width here?
354         // FIXME: Should we set m_size.height here too?
355         m_size.setWidth(visibleWidth());
356         return;
357     }
358
359     if (!allowSubtree && d->layoutRoot) {
360         if (d->layoutRoot->renderer())
361             d->layoutRoot->renderer()->markContainingBlocksForLayout(false);
362         d->layoutRoot = 0;
363     }
364
365     bool subtree = d->layoutRoot;
366     Document* document = m_frame->document();
367     if (!document) {
368         // FIXME: Should we set m_size.height here too?
369         m_size.setWidth(visibleWidth());
370         return;
371     }
372
373     Node* rootNode = subtree ? d->layoutRoot.get() : document;
374     d->layoutSchedulingEnabled = false;
375
376     // Always ensure our style info is up-to-date.  This can happen in situations where
377     // the layout beats any sort of style recalc update that needs to occur.
378     if (document->hasChangedChild())
379         document->recalcStyle();
380     
381     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit, 
382     // so there's no point to continuiing to layout
383     if (protector->hasOneRef())
384         return;
385
386     RenderObject* root = rootNode->renderer();
387     if (!root) {
388         // FIXME: Do we need to set m_size here?
389         d->layoutSchedulingEnabled = true;
390         return;
391     }
392
393     ScrollBarMode hMode = d->hmode;
394     ScrollBarMode vMode = d->vmode;
395     
396     if (!subtree) {
397         Document* document = static_cast<Document*>(rootNode);
398         RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
399         if (document->isHTMLDocument()) {
400             Node *body = static_cast<HTMLDocument*>(document)->body();
401             if (body && body->renderer()) {
402                 if (body->hasTagName(framesetTag)) {
403                     body->renderer()->setNeedsLayout(true);
404                     vMode = ScrollBarAlwaysOff;
405                     hMode = ScrollBarAlwaysOff;
406                 } else if (body->hasTagName(bodyTag)) {
407                     if (!d->firstLayout && m_size.height() != visibleHeight() && static_cast<RenderBox*>(body->renderer())->stretchesToViewHeight())
408                         body->renderer()->setChildNeedsLayout(true);
409                     // It's sufficient to just check one overflow direction, since it's illegal to have visible in only one direction.
410                     RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE ? body->renderer() : rootRenderer;
411                     applyOverflowToViewport(o, hMode, vMode); // Only applies to HTML UAs, not to XML/XHTML UAs
412                 }
413             }
414         } else if (rootRenderer)
415             applyOverflowToViewport(rootRenderer, hMode, vMode); // XML/XHTML UAs use the root element.
416 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
417         if (d->firstLayout && !document->ownerElement())
418             printf("Elapsed time before first layout: %d\n", document->elapsedTime());
419 #endif
420     }
421
422     d->doFullRepaint = !subtree && (d->firstLayout || static_cast<RenderView*>(root)->printingMode());
423     if (d->repaintRects)
424         d->repaintRects->clear();
425
426     bool didFirstLayout = false;
427     if (!subtree) {
428         // Now set our scrollbar state for the layout.
429         ScrollBarMode currentHMode = hScrollBarMode();
430         ScrollBarMode currentVMode = vScrollBarMode();
431
432         if (d->firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
433             suppressScrollBars(true);
434             if (d->firstLayout) {
435                 d->firstLayout = false;
436                 didFirstLayout = true;
437                 
438                 // Set the initial vMode to AlwaysOn if we're auto.
439                 if (vMode == ScrollBarAuto)
440                     ScrollView::setVScrollBarMode(ScrollBarAlwaysOn); // This causes a vertical scrollbar to appear.
441                 // Set the initial hMode to AlwaysOff if we're auto.
442                 if (hMode == ScrollBarAuto)
443                     ScrollView::setHScrollBarMode(ScrollBarAlwaysOff); // This causes a horizontal scrollbar to disappear.
444             }
445             
446             if (hMode == vMode)
447                 ScrollView::setScrollBarsMode(hMode);
448             else {
449                 ScrollView::setHScrollBarMode(hMode);
450                 ScrollView::setVScrollBarMode(vMode);
451             }
452
453             suppressScrollBars(false, true);
454         }
455
456         IntSize oldSize = m_size;
457
458         m_size = IntSize(visibleWidth(), visibleHeight());
459
460         if (oldSize != m_size)
461             d->doFullRepaint = true;
462     }
463     
464     RenderLayer* layer = root->enclosingLayer();
465      
466     if (!d->doFullRepaint) {
467         layer->checkForRepaintOnResize();
468         root->repaintObjectsBeforeLayout();
469     }
470
471     if (subtree) {
472         if (root->recalcMinMax())
473             root->recalcMinMaxWidths();
474     }
475     root->layout();
476     d->layoutRoot = 0;
477
478     m_frame->invalidateSelection();
479    
480     d->layoutSchedulingEnabled=true;
481
482     if (!subtree && !static_cast<RenderView*>(root)->printingMode())
483         resizeContents(layer->width(), layer->height());
484
485     // Now update the positions of all layers.
486     layer->updateLayerPositions(d->doFullRepaint);
487
488     // We update our widget positions right after doing a layout.
489     if (!subtree)
490         static_cast<RenderView*>(root)->updateWidgetPositions();
491     
492     if (d->repaintRects && !d->repaintRects->isEmpty()) {
493         // FIXME: Could optimize this and have objects removed from this list
494         // if they ever do full repaints.
495         RenderObject::RepaintInfo* r;
496         DeprecatedPtrListIterator<RenderObject::RepaintInfo> it(*d->repaintRects);
497         for (; (r = it.current()); ++it)
498             r->m_object->repaintRectangle(r->m_repaintRect);
499         d->repaintRects->clear();
500     }
501     
502     d->layoutCount++;
503
504 #if __APPLE__
505     if (AXObjectCache::accessibilityEnabled())
506         root->document()->axObjectCache()->postNotification(root, "AXLayoutComplete");
507     updateDashboardRegions();
508 #endif
509
510     if (didFirstLayout)
511         m_frame->didFirstLayout();
512     
513     if (root->needsLayout()) {
514         scheduleRelayout();
515         return;
516     }
517     setStaticBackground(useSlowRepaints());
518
519     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
520         updateOverflowStatus(visibleWidth() < contentsWidth(),
521                              visibleHeight() < contentsHeight());
522
523     // Dispatch events scheduled during layout
524     dispatchScheduledEvents();    
525 }
526
527 //
528 // Event Handling
529 //
530 /////////////////
531
532 static Frame* subframeForEvent(const MouseEventWithHitTestResults& mev)
533 {
534     if (!mev.targetNode())
535         return 0;
536
537     RenderObject* renderer = mev.targetNode()->renderer();
538     if (!renderer || !renderer->isWidget())
539         return 0;
540
541     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
542     if (!widget || !widget->isFrameView())
543         return 0;
544
545     return static_cast<FrameView*>(widget)->frame();
546 }
547
548 void FrameView::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
549 {
550     if (!m_frame->document())
551         return;
552
553     RefPtr<FrameView> protector(this);
554
555     d->mousePressed = true;
556
557     MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
558
559     if (m_frame->passSubframeEventToSubframe(mev)) {
560         invalidateClick();
561         return;
562     }
563
564     d->clickCount = mouseEvent.clickCount();
565     d->clickNode = mev.targetNode();
566     
567     RenderLayer* layer = d->clickNode->renderer()? d->clickNode->renderer()->enclosingLayer() : 0;
568     IntPoint p =  viewportToContents(mouseEvent.pos());
569     if (layer && layer->isPointInResizeControl(p)) {
570         layer->setInResizeMode(true);
571         d->m_resizeLayer = layer;
572         d->offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
573         invalidateClick();
574         return;  
575     }
576
577     bool swallowEvent = dispatchMouseEvent(mousedownEvent, mev.targetNode(), true, d->clickCount, mouseEvent, true);
578
579     if (!swallowEvent) {
580         // Refetch the event target node if it currently is the shadow node inside an <input> element.
581         // If a mouse event handler changes the input element type to one that has a widget associated,
582         // we'd like to Frame::handleMousePressEvent to pass the event to the widget and thus the
583         // event target node can't still be the shadow node.
584         if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag))
585             mev = prepareMouseEvent(true, true, false, mouseEvent);
586
587         m_frame->handleMousePressEvent(mev);
588         // Many AK widgets run their own event loops and consume events while the mouse is down.
589         // When they finish, currentEvent is the mouseUp that they exited on.  We need to update
590         // the khtml state with this mouseUp, which khtml never saw.
591         // If this event isn't a mouseUp, we assume that the mouseUp will be coming later.  There
592         // is a hole here if the widget consumes the mouseUp and subsequent events.
593         if (m_frame->lastEventIsMouseUp())
594             d->mousePressed = false;
595     }
596 }
597
598 void FrameView::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
599 {
600     if (!m_frame->document())
601         return;
602
603     RefPtr<FrameView> protector(this);
604
605     // We get this instead of a second mouse-up 
606     d->mousePressed = false;
607
608     MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
609
610     if (m_frame->passSubframeEventToSubframe(mev))
611         return;
612
613     d->clickCount = mouseEvent.clickCount();
614     bool swallowEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, d->clickCount, mouseEvent, false);
615
616     if (mev.targetNode() == d->clickNode)
617         dispatchMouseEvent(clickEvent, mev.targetNode(), true, d->clickCount, mouseEvent, true);
618
619     // Qt delivers a release event AND a double click event.
620     if (!swallowEvent) {
621         m_frame->handleMouseReleaseEvent(mev);
622         m_frame->handleMouseReleaseDoubleClickEvent(mev);
623     }
624
625     invalidateClick();
626 }
627
628 static bool isSubmitImage(Node *node)
629 {
630     return node && node->hasTagName(inputTag) && static_cast<HTMLInputElement*>(node)->inputType() == HTMLInputElement::IMAGE;
631 }
632
633 static Cursor selectCursor(const MouseEventWithHitTestResults& event, Frame* frame, bool mousePressed)
634 {
635     // During selection, use an I-beam no matter what we're over.
636     if (mousePressed && frame->hasSelection())
637         return iBeamCursor();
638
639     Node* node = event.targetNode();
640     RenderObject* renderer = node ? node->renderer() : 0;
641     RenderStyle* style = renderer ? renderer->style() : 0;
642
643     if (style && style->cursorImage() && !style->cursorImage()->image()->isNull())
644         if (!style->cursorImage()->isErrorImage())
645             return style->cursorImage()->image();
646         else 
647             style = 0; // Fallback to CURSOR_AUTO
648
649     switch (style ? style->cursor() : CURSOR_AUTO) {
650         case CURSOR_AUTO: {
651             bool editable = (node && node->isContentEditable());
652             if ((event.isOverLink() || isSubmitImage(node)) && (!editable || event.event().shiftKey()))
653                 return handCursor();
654             RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
655             bool inResizer = false;
656             if (frame->view() && layer && layer->isPointInResizeControl(frame->view()->viewportToContents(event.event().pos())))
657                 inResizer = true;
658             if ((editable || (renderer && renderer->isText() && renderer->canSelect())) && !inResizer)
659                 return iBeamCursor();
660             // FIXME: If the point is in a layer's overflow scrollbars, we should use the pointer cursor
661             return pointerCursor();
662         }
663         case CURSOR_CROSS:
664             return crossCursor();
665         case CURSOR_POINTER:
666             return handCursor();
667         case CURSOR_MOVE:
668             return moveCursor();
669         case CURSOR_E_RESIZE:
670             return eastResizeCursor();
671         case CURSOR_W_RESIZE:
672             return westResizeCursor();
673         case CURSOR_N_RESIZE:
674             return northResizeCursor();
675         case CURSOR_S_RESIZE:
676             return southResizeCursor();
677         case CURSOR_NE_RESIZE:
678             return northEastResizeCursor();
679         case CURSOR_SW_RESIZE:
680             return southWestResizeCursor();
681         case CURSOR_NW_RESIZE:
682             return northWestResizeCursor();
683         case CURSOR_SE_RESIZE:
684             return southEastResizeCursor();
685         case CURSOR_NS_RESIZE:
686             return northSouthResizeCursor();
687         case CURSOR_EW_RESIZE:
688             return eastWestResizeCursor();
689         case CURSOR_NESW_RESIZE:
690             return northEastSouthWestResizeCursor();
691         case CURSOR_NWSE_RESIZE:
692             return northWestSouthEastResizeCursor();
693         case CURSOR_COL_RESIZE:
694             return columnResizeCursor();
695         case CURSOR_ROW_RESIZE:
696             return rowResizeCursor();
697         case CURSOR_TEXT:
698             return iBeamCursor();
699         case CURSOR_WAIT:
700             return waitCursor();
701         case CURSOR_HELP:
702             return helpCursor();
703         case CURSOR_DEFAULT:
704             return pointerCursor();
705     }
706     return pointerCursor();
707 }
708
709 void FrameView::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent)
710 {
711     // in Radar 3703768 we saw frequent crashes apparently due to the
712     // part being null here, which seems impossible, so check for nil
713     // but also assert so that we can try to figure this out in debug
714     // builds, if it happens.
715     ASSERT(m_frame);
716     if (!m_frame || !m_frame->document())
717         return;
718
719     RefPtr<FrameView> protector(this);
720     
721     if (d->hoverTimer.isActive())
722         d->hoverTimer.stop();
723
724     if (d->resizingFrameSet) {
725         dispatchMouseEvent(mousemoveEvent, d->resizingFrameSet.get(), false, 0, mouseEvent, false);
726         return;
727     }
728
729     // Treat mouse move events while the mouse is pressed as "read-only" in prepareMouseEvent
730     // if we are allowed to select.
731     // This means that :hover and :active freeze in the state they were in when the mouse
732     // was pressed, rather than updating for nodes the mouse moves over as you hold the mouse down.
733     MouseEventWithHitTestResults mev = prepareMouseEvent(d->mousePressed && m_frame->mouseDownMayStartSelect(),
734         d->mousePressed, true, mouseEvent);
735
736     if (d->oldSubframe && d->oldSubframe->tree()->isDescendantOf(m_frame.get()))
737         m_frame->passSubframeEventToSubframe(mev, d->oldSubframe.get());
738
739     bool swallowEvent = dispatchMouseEvent(mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
740     
741     if (d->m_resizeLayer && d->m_resizeLayer->inResizeMode())
742         d->m_resizeLayer->resize(mouseEvent, d->offsetFromResizeCorner);
743
744     if (!swallowEvent)
745         m_frame->handleMouseMoveEvent(mev);
746     
747     RefPtr<Frame> newSubframe = subframeForEvent(mev);
748     
749     if (newSubframe && d->oldSubframe != newSubframe)
750         m_frame->passSubframeEventToSubframe(mev, newSubframe.get());
751     else
752         setCursor(selectCursor(mev, m_frame.get(), d->mousePressed));
753     
754     d->oldSubframe = newSubframe;
755 }
756
757 void FrameView::invalidateClick()
758 {
759     d->clickCount = 0;
760     d->clickNode = 0;
761 }
762
763 bool FrameView::mousePressed()
764 {
765     return d->mousePressed;
766 }
767
768 void FrameView::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
769 {
770     if (!m_frame->document())
771         return;
772
773     RefPtr<FrameView> protector(this);
774
775     d->mousePressed = false;
776
777     if (d->resizingFrameSet) {
778         dispatchMouseEvent(mouseupEvent, d->resizingFrameSet.get(), true, d->clickCount, mouseEvent, false);
779         return;
780     }
781
782     MouseEventWithHitTestResults mev = prepareMouseEvent(false, false, false, mouseEvent);
783
784     if (m_frame->passSubframeEventToSubframe(mev))
785         return;
786
787     bool swallowEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, d->clickCount, mouseEvent, false);
788
789     if (d->clickCount > 0 && mev.targetNode() == d->clickNode)
790         dispatchMouseEvent(clickEvent, mev.targetNode(), true, d->clickCount, mouseEvent, true);
791
792     if (d->m_resizeLayer) {
793         d->m_resizeLayer->setInResizeMode(false);
794         d->m_resizeLayer = 0;
795     }
796
797     if (!swallowEvent)
798         m_frame->handleMouseReleaseEvent(mev);
799
800     invalidateClick();
801 }
802
803 bool FrameView::dispatchDragEvent(const AtomicString& eventType, Node *dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
804 {
805     IntPoint contentsPos = viewportToContents(event.pos());
806     
807     RefPtr<MouseEvent> me = new MouseEvent(eventType,
808         true, true, m_frame->document()->defaultView(),
809         0, event.globalX(), event.globalY(), contentsPos.x(), contentsPos.y(),
810         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
811         0, 0, clipboard);
812
813     ExceptionCode ec = 0;
814     EventTargetNodeCast(dragTarget)->dispatchEvent(me.get(), ec, true);
815     return me->defaultPrevented();
816 }
817
818 bool FrameView::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
819 {
820     bool accept = false;
821
822     MouseEventWithHitTestResults mev = prepareMouseEvent(true, false, false, event);
823
824     // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
825     Node* newTarget = mev.targetNode();
826     if (newTarget && newTarget->isTextNode())
827         newTarget = newTarget->parentNode();
828     if (newTarget)
829         newTarget = newTarget->shadowAncestorNode();
830
831     if (d->dragTarget != newTarget) {
832         // note this ordering is explicitly chosen to match WinIE
833         if (newTarget)
834             accept = dispatchDragEvent(dragenterEvent, newTarget, event, clipboard);
835         if (d->dragTarget)
836             dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
837     } else {
838         if (newTarget)
839             accept = dispatchDragEvent(dragoverEvent, newTarget, event, clipboard);
840     }
841     d->dragTarget = newTarget;
842
843     return accept;
844 }
845
846 void FrameView::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
847 {
848     if (d->dragTarget)
849         dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
850     d->dragTarget = 0;
851 }
852
853 bool FrameView::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
854 {
855     bool accept = false;
856     if (d->dragTarget)
857         accept = dispatchDragEvent(dropEvent, d->dragTarget.get(), event, clipboard);
858     d->dragTarget = 0;
859     return accept;
860 }
861
862 Node* FrameView::nodeUnderMouse() const
863 {
864     return d->underMouse.get();
865 }
866
867 bool FrameView::scrollTo(const IntRect& bounds)
868 {
869     d->scrollingSelf = true; // so scroll events get ignored
870
871     int x, y, xe, ye;
872     x = bounds.x();
873     y = bounds.y();
874     xe = bounds.right() - 1;
875     ye = bounds.bottom() - 1;
876     
877     int deltax;
878     int deltay;
879
880     int curHeight = visibleHeight();
881     int curWidth = visibleWidth();
882
883     if (ye - y>curHeight-d->borderY)
884         ye = y + curHeight - d->borderY;
885
886     if (xe - x>curWidth-d->borderX)
887         xe = x + curWidth - d->borderX;
888
889     // is xpos of target left of the view's border?
890     if (x < contentsX() + d->borderX)
891         deltax = x - contentsX() - d->borderX;
892     // is xpos of target right of the view's right border?
893     else if (xe + d->borderX > contentsX() + curWidth)
894         deltax = xe + d->borderX - (contentsX() + curWidth);
895     else
896         deltax = 0;
897
898     // is ypos of target above upper border?
899     if (y < contentsY() + d->borderY)
900         deltay = y - contentsY() - d->borderY;
901     // is ypos of target below lower border?
902     else if (ye + d->borderY > contentsY() + curHeight)
903         deltay = ye + d->borderY - (contentsY() + curHeight);
904     else
905         deltay = 0;
906
907     int maxx = curWidth - d->borderX;
908     int maxy = curHeight - d->borderY;
909
910     int scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax > -maxx ? deltax : -maxx);
911     int scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay > -maxy ? deltay : -maxy);
912
913     if (contentsX() + scrollX < 0)
914         scrollX = -contentsX();
915     else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
916         scrollX = contentsWidth() - visibleWidth() - contentsX();
917
918     if (contentsY() + scrollY < 0)
919         scrollY = -contentsY();
920     else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
921         scrollY = contentsHeight() - visibleHeight() - contentsY();
922
923     scrollBy(scrollX, scrollY);
924
925     // generate abs(scroll.)
926     if (scrollX < 0)
927         scrollX = -scrollX;
928     if (scrollY < 0)
929         scrollY = -scrollY;
930
931     d->scrollingSelf = false;
932
933     return scrollX != maxx && scrollY != maxy;
934 }
935
936 void FrameView::focusNextPrevNode(bool next)
937 {
938     // Sets the focus node of the document to be the node after (or if next is false, before) the current focus node.
939     // Only nodes that are selectable (i.e. for which isSelectable() returns true) are taken into account, and the order
940     // used is that specified in the HTML spec (see Document::nextFocusNode() and Document::previousFocusNode()
941     // for details).
942
943     Document *doc = m_frame->document();
944     Node *oldFocusNode = doc->focusNode();
945     Node *newFocusNode;
946
947     // Find the next/previous node from the current one
948     if (next)
949         newFocusNode = doc->nextFocusNode(oldFocusNode);
950     else
951         newFocusNode = doc->previousFocusNode(oldFocusNode);
952
953     // If there was previously no focus node and the user has scrolled the document, then instead of picking the first
954     // focusable node in the document, use the first one that lies within the visible area (if possible).
955     if (!oldFocusNode && newFocusNode && d->scrollBarMoved) {
956         bool visible = false;
957         Node *toFocus = newFocusNode;
958         while (!visible && toFocus) {
959             if (toFocus->getRect().intersects(IntRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()))) {
960                 // toFocus is visible in the contents area
961                 visible = true;
962             } else {
963                 // toFocus is _not_ visible in the contents area, pick the next node
964                 if (next)
965                     toFocus = doc->nextFocusNode(toFocus);
966                 else
967                     toFocus = doc->previousFocusNode(toFocus);
968             }
969         }
970
971         if (toFocus)
972             newFocusNode = toFocus;
973     }
974
975     d->scrollBarMoved = false;
976
977     if (!newFocusNode)
978       {
979         // No new focus node, scroll to bottom or top depending on next
980         if (next)
981             scrollTo(IntRect(contentsX()+visibleWidth()/2,contentsHeight(),0,0));
982         else
983             scrollTo(IntRect(contentsX()+visibleWidth()/2,0,0,0));
984     }
985     else {
986         // EDIT FIXME: if it's an editable element, activate the caret
987         // otherwise, hide it
988         if (newFocusNode->isContentEditable()) {
989             // make caret visible
990         } 
991         else {
992             // hide caret
993         }
994
995         // Scroll the view as necessary to ensure that the new focus node is visible
996         if (oldFocusNode) {
997             if (!scrollTo(newFocusNode->getRect()))
998                 return;
999         }
1000         else {
1001             if (doc->renderer()) {
1002                 doc->renderer()->enclosingLayer()->scrollRectToVisible(IntRect(contentsX(), next ? 0: contentsHeight(), 0, 0));
1003             }
1004         }
1005     }
1006     // Set focus node on the document
1007     m_frame->document()->setFocusNode(newFocusNode);
1008 }
1009
1010 void FrameView::setMediaType(const String& mediaType)
1011 {
1012     d->m_mediaType = mediaType;
1013 }
1014
1015 String FrameView::mediaType() const
1016 {
1017     // See if we have an override type.
1018     String overrideType = m_frame->overrideMediaType();
1019     if (!overrideType.isNull())
1020         return overrideType;
1021     return d->m_mediaType;
1022 }
1023
1024 bool FrameView::useSlowRepaints() const
1025 {
1026     return d->useSlowRepaints || d->slowRepaintObjectCount > 0;
1027 }
1028
1029 void FrameView::setUseSlowRepaints()
1030 {
1031     d->useSlowRepaints = true;
1032     setStaticBackground(true);
1033 }
1034
1035 void FrameView::addSlowRepaintObject()
1036 {
1037     if (d->slowRepaintObjectCount == 0)
1038         setStaticBackground(true);
1039     d->slowRepaintObjectCount++;
1040 }
1041
1042 void FrameView::removeSlowRepaintObject()
1043 {
1044     d->slowRepaintObjectCount--;
1045     if (d->slowRepaintObjectCount == 0)
1046         setStaticBackground(d->useSlowRepaints);
1047 }
1048
1049 void FrameView::setScrollBarsMode(ScrollBarMode mode)
1050 {
1051     d->vmode = mode;
1052     d->hmode = mode;
1053     
1054     ScrollView::setScrollBarsMode(mode);
1055 }
1056
1057 void FrameView::setVScrollBarMode(ScrollBarMode mode)
1058 {
1059     d->vmode = mode;
1060     ScrollView::setVScrollBarMode(mode);
1061 }
1062
1063 void FrameView::setHScrollBarMode(ScrollBarMode mode)
1064 {
1065     d->hmode = mode;
1066     ScrollView::setHScrollBarMode(mode);
1067 }
1068
1069 void FrameView::restoreScrollBar()
1070 {
1071     suppressScrollBars(false);
1072 }
1073
1074 void FrameView::setResizingFrameSet(HTMLFrameSetElement* frameSet)
1075 {
1076     d->resizingFrameSet = frameSet;
1077 }
1078
1079 void FrameView::scrollPointRecursively(int x, int y)
1080 {
1081     if (frame()->prohibitsScrolling())
1082         return;
1083
1084     ScrollView::scrollPointRecursively(x, y);
1085 }
1086
1087 void FrameView::setContentsPos(int x, int y)
1088 {
1089     if (frame()->prohibitsScrolling())
1090         return;
1091
1092     ScrollView::setContentsPos(x, y);
1093 }
1094
1095 MouseEventWithHitTestResults FrameView::prepareMouseEvent(bool readonly, bool active, bool mouseMove, const PlatformMouseEvent& mev)
1096 {
1097     ASSERT(m_frame);
1098     ASSERT(m_frame->document());
1099     
1100     IntPoint vPoint = viewportToContents(mev.pos());
1101     return m_frame->document()->prepareMouseEvent(readonly, active, mouseMove, vPoint, mev);
1102 }
1103
1104 bool FrameView::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool cancelable,
1105     int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
1106 {
1107     // if the target node is a text node, dispatch on the parent node - rdar://4196646
1108     if (targetNode && targetNode->isTextNode())
1109         targetNode = targetNode->parentNode();
1110     if (targetNode)
1111         targetNode = targetNode->shadowAncestorNode();
1112     d->underMouse = targetNode;
1113
1114     // mouseout/mouseover
1115     if (setUnder) {
1116         if (d->oldUnder && d->oldUnder->document() != frame()->document())
1117             d->oldUnder = 0;
1118
1119         if (d->oldUnder != targetNode) {
1120             // send mouseout event to the old node
1121             if (d->oldUnder)
1122                 EventTargetNodeCast(d->oldUnder.get())->dispatchMouseEvent(mouseEvent, mouseoutEvent, 0, targetNode);
1123             // send mouseover event to the new node
1124             if (targetNode)
1125                 EventTargetNodeCast(targetNode)->dispatchMouseEvent(mouseEvent, mouseoverEvent, 0, d->oldUnder.get());
1126         }
1127         d->oldUnder = targetNode;
1128     }
1129
1130     bool swallowEvent = false;
1131
1132     if (targetNode)
1133         swallowEvent = EventTargetNodeCast(targetNode)->dispatchMouseEvent(mouseEvent, eventType, clickCount);
1134     
1135     if (!swallowEvent && eventType == mousedownEvent) {
1136         // Blur current focus node when a link/button is clicked; this
1137         // is expected by some sites that rely on onChange handlers running
1138         // from form fields before the button click is processed.
1139         Node* node = targetNode;
1140         RenderObject* renderer = node ? node->renderer() : 0;
1141                 
1142         // Walk up the render tree to search for a node to focus.
1143         // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
1144         while (renderer) {
1145             node = renderer->element();
1146             if (node && node->isFocusable())
1147                 break;
1148             renderer = renderer->parent();
1149         }
1150         // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent
1151         // if the page already set it (e.g., by canceling default behavior).
1152         if (node && node->isMouseFocusable()) {
1153             if (!m_frame->document()->setFocusNode(node))
1154                 swallowEvent = true;
1155         } else if (!node || !node->focused()) {
1156             if (!m_frame->document()->setFocusNode(0))
1157                 swallowEvent = true;
1158         }
1159     }
1160
1161     return swallowEvent;
1162 }
1163
1164 void FrameView::setIgnoreWheelEvents(bool e)
1165 {
1166     d->ignoreWheelEvents = e;
1167 }
1168
1169 void FrameView::handleWheelEvent(PlatformWheelEvent& e)
1170 {
1171     Document *doc = m_frame->document();
1172     if (doc) {
1173         RenderObject *docRenderer = doc->renderer();
1174         if (docRenderer) {
1175             IntPoint vPoint = viewportToContents(e.pos());
1176
1177             RenderObject::NodeInfo hitTestResult(true, false);
1178             doc->renderer()->layer()->hitTest(hitTestResult, vPoint); 
1179             Node *node = hitTestResult.innerNode();
1180
1181            if (m_frame->passWheelEventToChildWidget(node)) {
1182                 e.accept();
1183                 return;
1184             }
1185             if (node) {
1186                 node = node->shadowAncestorNode();
1187                 EventTargetNodeCast(node)->dispatchWheelEvent(e);
1188                 if (e.isAccepted())
1189                     return;
1190             }
1191         }
1192     }
1193 }
1194
1195 void FrameView::scrollBarMoved()
1196 {
1197     // FIXME: Need to arrange for this to be called when the view is scrolled!
1198     if (!d->scrollingSelf)
1199         d->scrollBarMoved = true;
1200 }
1201
1202 void FrameView::repaintRectangle(const IntRect& r, bool immediate)
1203 {
1204     updateContents(r, immediate);
1205 }
1206
1207 void FrameView::layoutTimerFired(Timer<FrameView>*)
1208 {
1209 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1210     if (m_frame->document() && !m_frame->document()->ownerElement())
1211         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
1212 #endif
1213     layout();
1214 }
1215
1216 void FrameView::hoverTimerFired(Timer<FrameView>*)
1217 {
1218     d->hoverTimer.stop();
1219     prepareMouseEvent(false, false, true, PlatformMouseEvent());
1220 }
1221
1222 void FrameView::scheduleRelayout()
1223 {
1224     if (d->layoutRoot) {
1225         if (d->layoutRoot->renderer())
1226             d->layoutRoot->renderer()->markContainingBlocksForLayout(false);
1227         d->layoutRoot = 0;
1228     }
1229     if (!d->layoutSchedulingEnabled)
1230         return;
1231
1232     if (!m_frame->document() || !m_frame->document()->shouldScheduleLayout())
1233         return;
1234
1235     int delay = m_frame->document()->minimumLayoutDelay();
1236     if (d->layoutTimer.isActive() && d->delayedLayout && !delay)
1237         unscheduleRelayout();
1238     if (d->layoutTimer.isActive())
1239         return;
1240
1241     d->delayedLayout = delay != 0;
1242
1243 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1244     if (!m_frame->document()->ownerElement())
1245         printf("Scheduling layout for %d\n", delay);
1246 #endif
1247
1248     d->layoutTimer.startOneShot(delay * 0.001);
1249 }
1250
1251 void FrameView::scheduleRelayoutOfSubtree(Node* n)
1252 {
1253     if (!d->layoutSchedulingEnabled || m_frame->document() && m_frame->document()->renderer() && m_frame->document()->renderer()->needsLayout()) {
1254         if (n->renderer())
1255             n->renderer()->markContainingBlocksForLayout(false);
1256         return;
1257     }
1258
1259     if (layoutPending()) {
1260         if (d->layoutRoot != n) {
1261             // Just do a full relayout
1262             if (d->layoutRoot && d->layoutRoot->renderer())
1263                 d->layoutRoot->renderer()->markContainingBlocksForLayout(false);
1264             d->layoutRoot = 0;
1265             if (n->renderer())
1266                 n->renderer()->markContainingBlocksForLayout(false);
1267         }
1268     } else {
1269         int delay = m_frame->document()->minimumLayoutDelay();
1270         d->layoutRoot = n;
1271         d->delayedLayout = delay != 0;
1272         d->layoutTimer.startOneShot(delay * 0.001);
1273     }
1274 }
1275
1276 bool FrameView::layoutPending() const
1277 {
1278     return d->layoutTimer.isActive();
1279 }
1280
1281 bool FrameView::haveDelayedLayoutScheduled()
1282 {
1283     return d->layoutTimer.isActive() && d->delayedLayout;
1284 }
1285
1286 void FrameView::unscheduleRelayout()
1287 {
1288     if (!d->layoutTimer.isActive())
1289         return;
1290
1291 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1292     if (m_frame->document() && !m_frame->document()->ownerElement())
1293         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
1294 #endif
1295     
1296     d->layoutTimer.stop();
1297     d->delayedLayout = false;
1298 }
1299
1300 bool FrameView::isTransparent() const
1301 {
1302     return d->isTransparent;
1303 }
1304
1305 void FrameView::setTransparent(bool isTransparent)
1306 {
1307     d->isTransparent = isTransparent;
1308 }
1309
1310 void FrameView::scheduleHoverStateUpdate()
1311 {
1312     if (!d->hoverTimer.isActive())
1313         d->hoverTimer.startOneShot(0);
1314 }
1315
1316 void FrameView::setHasBorder(bool b)
1317 {
1318     d->m_hasBorder = b;
1319     updateBorder();
1320 }
1321
1322 bool FrameView::hasBorder() const
1323 {
1324     return d->m_hasBorder;
1325 }
1326
1327 void FrameView::cleared()
1328 {
1329     if (m_frame)
1330         if (RenderPart* renderer = m_frame->ownerRenderer())
1331             renderer->viewCleared();
1332 }
1333
1334
1335 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNode> eventTarget, bool tempEvent)
1336 {
1337     if (!d->m_scheduledEvents)
1338         d->m_scheduledEvents = new Vector<ScheduledEvent*>;
1339     
1340     ScheduledEvent *scheduledEvent = new ScheduledEvent;
1341     scheduledEvent->m_event = event;
1342     scheduledEvent->m_eventTarget = eventTarget;
1343     scheduledEvent->m_tempEvent = tempEvent;
1344     
1345     d->m_scheduledEvents->append(scheduledEvent);
1346 }
1347
1348 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
1349 {
1350     if (!d->m_viewportRenderer)
1351         return;
1352     
1353     if (d->m_overflowStatusDirty) {
1354         d->horizontalOverflow = horizontalOverflow;
1355         d->m_verticalOverflow = verticalOverflow;
1356         d->m_overflowStatusDirty = false;
1357         
1358         return;
1359     }
1360     
1361     bool horizontalOverflowChanged = (d->horizontalOverflow != horizontalOverflow);
1362     bool verticalOverflowChanged = (d->m_verticalOverflow != verticalOverflow);
1363     
1364     if (horizontalOverflowChanged || verticalOverflowChanged) {
1365         d->horizontalOverflow = horizontalOverflow;
1366         d->m_verticalOverflow = verticalOverflow;
1367         
1368         scheduleEvent(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
1369                                         EventTargetNodeCast(d->m_viewportRenderer->element()), true);
1370     }
1371     
1372 }
1373
1374 void FrameView::dispatchScheduledEvents()
1375 {
1376     if (!d->m_scheduledEvents)
1377         return;
1378     
1379     Vector<ScheduledEvent*> scheduledEventsCopy = *d->m_scheduledEvents;
1380     d->m_scheduledEvents->clear();
1381     
1382     Vector<ScheduledEvent*>::iterator end = scheduledEventsCopy.end();
1383     for (Vector<ScheduledEvent*>::iterator it = scheduledEventsCopy.begin(); it != end; ++it) {
1384         ScheduledEvent* scheduledEvent = *it;
1385         
1386         ExceptionCode ec = 0;
1387         
1388         // Only dispatch events to nodes that are in the document
1389         if (scheduledEvent->m_eventTarget->inDocument())
1390             scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event, ec, scheduledEvent->m_tempEvent);
1391         
1392         delete scheduledEvent;
1393     }    
1394 }
1395
1396 }