28eec966584b6acffe4da1247a27bd993dae841c
[WebKit-https.git] / WebCore / page / mac / EventHandlerMac.mm
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "EventHandler.h"
28
29 #include "BlockExceptions.h"
30 #include "ClipboardMac.h"
31 #include "Cursor.h"
32 #include "Document.h"
33 #include "DragController.h"
34 #include "EventNames.h"
35 #include "FloatPoint.h"
36 #include "FocusController.h"
37 #include "FoundationExtras.h"
38 #include "FrameLoader.h"
39 #include "Frame.h"
40 #include "FrameTree.h"
41 #include "FrameView.h"
42 #include "HTMLFrameOwnerElement.h"
43 #include "HTMLFrameSetElement.h"
44 #include "HitTestRequest.h"
45 #include "HitTestResult.h"
46 #include "KeyboardEvent.h"
47 #include "MouseEventWithHitTestResults.h"
48 #include "Page.h"
49 #include "PlatformKeyboardEvent.h"
50 #include "PlatformScrollBar.h"
51 #include "PlatformWheelEvent.h"
52 #include "RenderWidget.h"
53 #include "WebCoreFrameBridge.h"
54
55 namespace WebCore {
56
57 using namespace EventNames;
58
59 static RetainPtr<NSEvent>& currentEvent()
60 {
61     static RetainPtr<NSEvent> event;
62     return event;
63 }
64
65 NSEvent *EventHandler::currentNSEvent()
66 {
67     return currentEvent().get();
68 }
69
70 bool EventHandler::wheelEvent(NSEvent *event)
71 {
72     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
73     currentEvent() = event;
74
75     PlatformWheelEvent wheelEvent(event);
76     handleWheelEvent(wheelEvent);
77
78     ASSERT(currentEvent() == event);
79     currentEvent() = oldCurrentEvent;
80
81     return wheelEvent.isAccepted();
82 }
83
84 PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const
85 {
86     NSEvent *event = [NSApp currentEvent];
87     if (!event)
88         return 0;
89     switch ([event type]) {
90         case NSKeyDown: {
91             PlatformKeyboardEvent platformEvent(event);
92             platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
93             return new KeyboardEvent(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
94         }
95         case NSKeyUp:
96             return new KeyboardEvent(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
97         default:
98             return 0;
99     }
100 }
101
102 static inline bool isKeyboardOptionTab(KeyboardEvent* event)
103 {
104     return event
105     && (event->type() == keydownEvent || event->type() == keypressEvent)
106     && event->altKey()
107     && event->keyIdentifier() == "U+0009";    
108 }
109
110 bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
111 {
112     return isKeyboardOptionTab(event);
113 }
114
115 bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
116 {
117     KeyboardUIMode keyboardUIMode = [m_frame->bridge() keyboardUIMode];
118     bool handlingOptionTab = isKeyboardOptionTab(event);
119
120     // If tab-to-links is off, option-tab always highlights all controls
121     if ((keyboardUIMode & KeyboardAccessTabsToLinks) == 0 && handlingOptionTab)
122         return true;
123     
124     // If system preferences say to include all controls, we always include all controls
125     if (keyboardUIMode & KeyboardAccessFull)
126         return true;
127     
128     // Otherwise tab-to-links includes all controls, unless the sense is flipped via option-tab.
129     if (keyboardUIMode & KeyboardAccessTabsToLinks)
130         return !handlingOptionTab;
131     
132     return handlingOptionTab;
133 }
134
135 bool EventHandler::keyEvent(NSEvent *event)
136 {
137     bool result;
138     BEGIN_BLOCK_OBJC_EXCEPTIONS;
139
140     ASSERT([event type] == NSKeyDown || [event type] == NSKeyUp);
141
142     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
143     currentEvent() = event;
144
145     result = keyEvent(PlatformKeyboardEvent(event));
146     
147     ASSERT(currentEvent() == event);
148     currentEvent() = oldCurrentEvent;
149
150     return result;
151
152     END_BLOCK_OBJC_EXCEPTIONS;
153
154     return false;
155 }
156
157 void EventHandler::focusDocumentView()
158 {
159     Page* page = m_frame->page();
160     if (!page)
161         return;
162
163     if (FrameView* frameView = m_frame->view())
164         if (NSView *documentView = frameView->getDocumentView())
165             page->chrome()->focusNSView(documentView);
166     
167     page->focusController()->setFocusedFrame(m_frame);
168 }
169
170 bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
171 {
172     // Figure out which view to send the event to.
173     RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0;
174     if (!target || !target->isWidget())
175         return false;
176     
177     // Double-click events don't exist in Cocoa. Since passWidgetMouseDownEventToWidget will
178     // just pass currentEvent down to the widget, we don't want to call it for events that
179     // don't correspond to Cocoa events.  The mousedown/ups will have already been passed on as
180     // part of the pressed/released handling.
181     return passMouseDownEventToWidget(static_cast<RenderWidget*>(target)->widget());
182 }
183
184 bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
185 {
186     return passMouseDownEventToWidget(renderWidget->widget());
187 }
188
189 static bool lastEventIsMouseUp()
190 {
191     // Many AK widgets run their own event loops and consume events while the mouse is down.
192     // When they finish, currentEvent is the mouseUp that they exited on.  We need to update
193     // the khtml state with this mouseUp, which khtml never saw.  This method lets us detect
194     // that state.
195
196     BEGIN_BLOCK_OBJC_EXCEPTIONS;
197     NSEvent *currentEventAfterHandlingMouseDown = [NSApp currentEvent];
198     if (currentEvent() != currentEventAfterHandlingMouseDown &&
199         [currentEventAfterHandlingMouseDown type] == NSLeftMouseUp &&
200         [currentEventAfterHandlingMouseDown timestamp] >= [currentEvent().get() timestamp])
201             return true;
202     END_BLOCK_OBJC_EXCEPTIONS;
203
204     return false;
205 }
206
207 bool EventHandler::passMouseDownEventToWidget(Widget* widget)
208 {
209     // FIXME: this method always returns true
210
211     if (!widget) {
212         LOG_ERROR("hit a RenderWidget without a corresponding Widget, means a frame is half-constructed");
213         return true;
214     }
215
216     BEGIN_BLOCK_OBJC_EXCEPTIONS;
217     
218     NSView *nodeView = widget->getView();
219     ASSERT(nodeView);
220     ASSERT([nodeView superview]);
221     NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
222     if (!view)
223         // We probably hit the border of a RenderWidget
224         return true;
225     
226     if ([m_frame->bridge() firstResponder] == view) {
227         // In the case where we just became first responder, we should send the mouseDown:
228         // to the NSTextField, not the NSTextField's editor. This code makes sure that happens.
229         // If we don't do this, we see a flash of selected text when clicking in a text field.
230         // FIXME: This is the only caller of textViewWasFirstResponderAtMouseDownTime. When we
231         // eliminate all use of NSTextField/NSTextView in form fields we can eliminate this code,
232         // and textViewWasFirstResponderAtMouseDownTime:, and the instance variable WebHTMLView
233         // keeps solely to support textViewWasFirstResponderAtMouseDownTime:.
234         if ([view isKindOfClass:[NSTextView class]] && ![m_frame->bridge() textViewWasFirstResponderAtMouseDownTime:(NSTextView *)view]) {
235             NSView *superview = view;
236             while (superview != nodeView) {
237                 superview = [superview superview];
238                 ASSERT(superview);
239                 if ([superview isKindOfClass:[NSControl class]]) {
240                     NSControl *control = static_cast<NSControl*>(superview);
241                     if ([control currentEditor] == view)
242                         view = superview;
243                     break;
244                 }
245             }
246         }
247     } else {
248         // Normally [NSWindow sendEvent:] handles setting the first responder.
249         // But in our case, the event was sent to the view representing the entire web page.
250         if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey]) {
251             [m_frame->bridge() makeFirstResponder:view];
252         }
253     }
254
255     // We need to "defer loading" while tracking the mouse, because tearing down the
256     // page while an AppKit control is tracking the mouse can cause a crash.
257     
258     // FIXME: In theory, WebCore now tolerates tear-down while tracking the
259     // mouse. We should confirm that, and then remove the deferrsLoading
260     // hack entirely.
261     
262     bool wasDeferringLoading = m_frame->page()->defersLoading();
263     if (!wasDeferringLoading)
264         m_frame->page()->setDefersLoading(true);
265
266     ASSERT(!m_sendingEventToSubview);
267     m_sendingEventToSubview = true;
268     [view mouseDown:currentEvent().get()];
269     m_sendingEventToSubview = false;
270     
271     if (!wasDeferringLoading)
272         m_frame->page()->setDefersLoading(false);
273
274     // Remember which view we sent the event to, so we can direct the release event properly.
275     m_mouseDownView = view;
276     m_mouseDownWasInSubframe = false;
277     
278     // Many AppKit widgets run their own event loops and consume events while the mouse is down.
279     // When they finish, currentEvent is the mouseUp that they exited on.  We need to update
280     // the EventHandler state with this mouseUp, which we never saw.
281     // If this event isn't a mouseUp, we assume that the mouseUp will be coming later.  There
282     // is a hole here if the widget consumes both the mouseUp and subsequent events.
283     if (lastEventIsMouseUp())
284         m_mousePressed = false;
285
286     END_BLOCK_OBJC_EXCEPTIONS;
287
288     return true;
289 }
290     
291 // Note that this does the same kind of check as [target isDescendantOf:superview].
292 // There are two differences: This is a lot slower because it has to walk the whole
293 // tree, and this works in cases where the target has already been deallocated.
294 static bool findViewInSubviews(NSView *superview, NSView *target)
295 {
296     BEGIN_BLOCK_OBJC_EXCEPTIONS;
297     NSEnumerator *e = [[superview subviews] objectEnumerator];
298     NSView *subview;
299     while ((subview = [e nextObject])) {
300         if (subview == target || findViewInSubviews(subview, target)) {
301             return true;
302         }
303     }
304     END_BLOCK_OBJC_EXCEPTIONS;
305     
306     return false;
307 }
308
309 NSView *EventHandler::mouseDownViewIfStillGood()
310 {
311     // Since we have no way of tracking the lifetime of m_mouseDownView, we have to assume that
312     // it could be deallocated already. We search for it in our subview tree; if we don't find
313     // it, we set it to nil.
314     NSView *mouseDownView = m_mouseDownView;
315     if (!mouseDownView) {
316         return nil;
317     }
318     FrameView* topFrameView = m_frame->view();
319     NSView *topView = topFrameView ? topFrameView->getView() : nil;
320     if (!topView || !findViewInSubviews(topView, mouseDownView)) {
321         m_mouseDownView = nil;
322         return nil;
323     }
324     return mouseDownView;
325 }
326
327 bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
328 {
329     return m_activationEventNumber == event.eventNumber();
330 }
331
332 bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&)
333 {
334     NSView *view = mouseDownViewIfStillGood();
335     
336     if (!view)
337         return false;
338     
339     if (!m_mouseDownWasInSubframe) {
340         m_sendingEventToSubview = true;
341         BEGIN_BLOCK_OBJC_EXCEPTIONS;
342         [view mouseDragged:currentEvent().get()];
343         END_BLOCK_OBJC_EXCEPTIONS;
344         m_sendingEventToSubview = false;
345     }
346     
347     return true;
348 }
349     
350 Clipboard* EventHandler::createDraggingClipboard() const 
351 {
352     NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
353     // Must be done before ondragstart adds types and data to the pboard,
354     // also done for security, as it erases data from the last drag
355     [pasteboard declareTypes:[NSArray array] owner:nil];
356     return new ClipboardMac(true, pasteboard, ClipboardWritable, m_frame);
357 }
358     
359 bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
360 {
361     NSView *view = mouseDownViewIfStillGood();
362     if (!view)
363         return false;
364     
365     if (!m_mouseDownWasInSubframe) {
366         m_sendingEventToSubview = true;
367         BEGIN_BLOCK_OBJC_EXCEPTIONS;
368         [view mouseUp:currentEvent().get()];
369         END_BLOCK_OBJC_EXCEPTIONS;
370         m_sendingEventToSubview = false;
371     }
372  
373     return true;
374 }
375     
376 bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe, HitTestResult* hoveredNode)
377 {
378     BEGIN_BLOCK_OBJC_EXCEPTIONS;
379
380     switch ([currentEvent().get() type]) {
381         case NSMouseMoved:
382             // Since we're passing in currentEvent() here, we can call
383             // handleMouseMoveEvent() directly, since the save/restore of
384             // currentEvent() that mouseMoved() does would have no effect.
385             subframe->eventHandler()->handleMouseMoveEvent(currentEvent().get(), hoveredNode);
386             return true;
387         
388         case NSLeftMouseDown: {
389             Node* node = event.targetNode();
390             if (!node)
391                 return false;
392             RenderObject* renderer = node->renderer();
393             if (!renderer || !renderer->isWidget())
394                 return false;
395             Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
396             if (!widget || !widget->isFrameView())
397                 return false;
398             if (!passWidgetMouseDownEventToWidget(static_cast<RenderWidget*>(renderer)))
399                 return false;
400             m_mouseDownWasInSubframe = true;
401             return true;
402         }
403         case NSLeftMouseUp: {
404             if (!m_mouseDownWasInSubframe)
405                 return false;
406             NSView *view = mouseDownViewIfStillGood();
407             if (!view)
408                 return false;
409             ASSERT(!m_sendingEventToSubview);
410             m_sendingEventToSubview = true;
411             [view mouseUp:currentEvent().get()];
412             m_sendingEventToSubview = false;
413             return true;
414         }
415         case NSLeftMouseDragged: {
416             if (!m_mouseDownWasInSubframe)
417                 return false;
418             NSView *view = mouseDownViewIfStillGood();
419             if (!view)
420                 return false;
421             ASSERT(!m_sendingEventToSubview);
422             m_sendingEventToSubview = true;
423             [view mouseDragged:currentEvent().get()];
424             m_sendingEventToSubview = false;
425             return true;
426         }
427         default:
428             return false;
429     }
430     END_BLOCK_OBJC_EXCEPTIONS;
431
432     return false;
433 }
434
435 bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget* widget)
436 {
437     BEGIN_BLOCK_OBJC_EXCEPTIONS;
438         
439     if ([currentEvent().get() type] != NSScrollWheel || m_sendingEventToSubview || !widget) 
440         return false;
441
442     NSView *nodeView = widget->getView();
443     ASSERT(nodeView);
444     ASSERT([nodeView superview]);
445     NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
446     if (!view)
447         // We probably hit the border of a RenderWidget
448         return false;
449
450     m_sendingEventToSubview = true;
451     [view scrollWheel:currentEvent().get()];
452     m_sendingEventToSubview = false;
453     return true;
454             
455     END_BLOCK_OBJC_EXCEPTIONS;
456     return false;
457 }
458
459 void EventHandler::mouseDown(NSEvent *event)
460 {
461     FrameView* v = m_frame->view();
462     if (!v || m_sendingEventToSubview)
463         return;
464
465     BEGIN_BLOCK_OBJC_EXCEPTIONS;
466     
467     m_frame->loader()->resetMultipleFormSubmissionProtection();
468
469     m_mouseDownView = nil;
470     dragState().m_dragSrc = 0;
471     
472     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
473     currentEvent() = event;
474     m_mouseDown = PlatformMouseEvent(event);
475     
476     handleMousePressEvent(event);
477     
478     ASSERT(currentEvent() == event);
479     currentEvent() = oldCurrentEvent;
480
481     END_BLOCK_OBJC_EXCEPTIONS;
482 }
483
484 void EventHandler::mouseDragged(NSEvent *event)
485 {
486     FrameView* v = m_frame->view();
487     if (!v || m_sendingEventToSubview)
488         return;
489
490     BEGIN_BLOCK_OBJC_EXCEPTIONS;
491
492     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
493     currentEvent() = event;
494
495     handleMouseMoveEvent(event);
496     
497     ASSERT(currentEvent() == event);
498     currentEvent() = oldCurrentEvent;
499
500     END_BLOCK_OBJC_EXCEPTIONS;
501 }
502
503 void EventHandler::mouseUp(NSEvent *event)
504 {
505     FrameView* v = m_frame->view();
506     if (!v || m_sendingEventToSubview)
507         return;
508
509     BEGIN_BLOCK_OBJC_EXCEPTIONS;
510
511     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
512     currentEvent() = event;
513
514     // Our behavior here is a little different that Qt. Qt always sends
515     // a mouse release event, even for a double click. To correct problems
516     // in khtml's DOM click event handling we do not send a release here
517     // for a double click. Instead we send that event from FrameView's
518     // handleMouseDoubleClickEvent. Note also that the third click of
519     // a triple click is treated as a single click, but the fourth is then
520     // treated as another double click. Hence the "% 2" below.
521     int clickCount = [event clickCount];
522     if (clickCount > 0 && clickCount % 2 == 0)
523         handleMouseDoubleClickEvent(event);
524     else
525         handleMouseReleaseEvent(event);
526     
527     ASSERT(currentEvent() == event);
528     currentEvent() = oldCurrentEvent;
529     
530     m_mouseDownView = nil;
531
532     END_BLOCK_OBJC_EXCEPTIONS;
533 }
534
535 /*
536  A hack for the benefit of AK's PopUpButton, which uses the Carbon menu manager, which thus
537  eats all subsequent events after it is starts its modal tracking loop.  After the interaction
538  is done, this routine is used to fix things up.  When a mouse down started us tracking in
539  the widget, we post a fake mouse up to balance the mouse down we started with. When a 
540  key down started us tracking in the widget, we post a fake key up to balance things out.
541  In addition, we post a fake mouseMoved to get the cursor in sync with whatever we happen to 
542  be over after the tracking is done.
543  */
544 void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
545 {
546     BEGIN_BLOCK_OBJC_EXCEPTIONS;
547
548     m_sendingEventToSubview = false;
549     int eventType = [initiatingEvent type];
550     if (eventType == NSLeftMouseDown || eventType == NSKeyDown) {
551         NSEvent *fakeEvent = nil;
552         if (eventType == NSLeftMouseDown) {
553             fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
554                                     location:[initiatingEvent locationInWindow]
555                                 modifierFlags:[initiatingEvent modifierFlags]
556                                     timestamp:[initiatingEvent timestamp]
557                                 windowNumber:[initiatingEvent windowNumber]
558                                         context:[initiatingEvent context]
559                                     eventNumber:[initiatingEvent eventNumber]
560                                     clickCount:[initiatingEvent clickCount]
561                                     pressure:[initiatingEvent pressure]];
562         
563             [NSApp postEvent:fakeEvent atStart:YES];
564         } else { // eventType == NSKeyDown
565             fakeEvent = [NSEvent keyEventWithType:NSKeyUp
566                                     location:[initiatingEvent locationInWindow]
567                                modifierFlags:[initiatingEvent modifierFlags]
568                                    timestamp:[initiatingEvent timestamp]
569                                 windowNumber:[initiatingEvent windowNumber]
570                                      context:[initiatingEvent context]
571                                   characters:[initiatingEvent characters] 
572                  charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers] 
573                                    isARepeat:[initiatingEvent isARepeat] 
574                                      keyCode:[initiatingEvent keyCode]];
575             [NSApp postEvent:fakeEvent atStart:YES];
576         }
577         // FIXME:  We should really get the current modifierFlags here, but there's no way to poll
578         // them in Cocoa, and because the event stream was stolen by the Carbon menu code we have
579         // no up-to-date cache of them anywhere.
580         fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved
581                                        location:[[m_frame->bridge() window] convertScreenToBase:[NSEvent mouseLocation]]
582                                   modifierFlags:[initiatingEvent modifierFlags]
583                                       timestamp:[initiatingEvent timestamp]
584                                    windowNumber:[initiatingEvent windowNumber]
585                                         context:[initiatingEvent context]
586                                     eventNumber:0
587                                      clickCount:0
588                                        pressure:0];
589         [NSApp postEvent:fakeEvent atStart:YES];
590     }
591     
592     END_BLOCK_OBJC_EXCEPTIONS;
593 }
594
595 void EventHandler::mouseMoved(NSEvent *event)
596 {
597     // Reject a mouse moved if the button is down - screws up tracking during autoscroll
598     // These happen because WebKit sometimes has to fake up moved events.
599     if (!m_frame->view() || m_mousePressed || m_sendingEventToSubview)
600         return;
601     
602     BEGIN_BLOCK_OBJC_EXCEPTIONS;
603
604     RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
605     currentEvent() = event;
606     
607     mouseMoved(PlatformMouseEvent(event));
608     
609     ASSERT(currentEvent() == event);
610     currentEvent() = oldCurrentEvent;
611
612     END_BLOCK_OBJC_EXCEPTIONS;
613 }
614
615 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
616 {
617     return passSubframeEventToSubframe(mev, subframe);
618 }
619
620 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
621 {
622     return passSubframeEventToSubframe(mev, subframe, hoveredNode);
623 }
624
625 bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
626 {
627     return passSubframeEventToSubframe(mev, subframe);
628 }
629
630 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar* scrollbar)
631 {
632     return passMouseDownEventToWidget(scrollbar);
633 }
634
635 }