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