diff options
Diffstat (limited to 'WebCore/page/EventHandler.cpp')
| -rw-r--r-- | WebCore/page/EventHandler.cpp | 280 |
1 files changed, 191 insertions, 89 deletions
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 937f08f..8b6b602 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -87,6 +87,7 @@ namespace WebCore { using namespace HTMLNames; +#if ENABLE(DRAG_SUPPORT) // The link drag hysteresis is much larger than the others because there // needs to be enough space to cancel the link press without starting a link drag, // and because dragging links is rare. @@ -94,6 +95,7 @@ const int LinkDragHysteresis = 40; const int ImageDragHysteresis = 5; const int TextDragHysteresis = 3; const int GeneralDragHysteresis = 3; +#endif // ENABLE(DRAG_SUPPORT) // Match key code of composition keydown event on windows. // IE sends VK_PROCESSKEY which has value 229; @@ -106,10 +108,9 @@ using namespace SVGNames; // When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth const double autoscrollInterval = 0.05; -static Frame* subframeForTargetNode(Node*); static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&); -static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node) +static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode) { if (!delta) return; @@ -118,12 +119,13 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir RenderBox* enclosingBox = node->renderer()->enclosingBox(); if (e.granularity() == ScrollByPageWheelEvent) { - if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1)) + if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode)) e.accept(); return; - } + } + float pixelsToScroll = delta > 0 ? delta : -delta; - if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll)) + if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode)) e.accept(); } @@ -134,10 +136,12 @@ inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResu return false; } +#if ENABLE(DRAG_SUPPORT) inline bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; } +#endif #endif @@ -146,7 +150,9 @@ EventHandler::EventHandler(Frame* frame) , m_mousePressed(false) , m_capturesDragging(false) , m_mouseDownMayStartSelect(false) +#if ENABLE(DRAG_SUPPORT) , m_mouseDownMayStartDrag(false) +#endif , m_mouseDownWasSingleClickInSelection(false) , m_beganSelectingText(false) , m_panScrollInProgress(false) @@ -179,11 +185,13 @@ EventHandler::~EventHandler() { } +#if ENABLE(DRAG_SUPPORT) EventHandler::EventHandlerDragState& EventHandler::dragState() { DEFINE_STATIC_LOCAL(EventHandlerDragState, state, ()); return state; } +#endif // ENABLE(DRAG_SUPPORT) void EventHandler::clear() { @@ -203,13 +211,17 @@ void EventHandler::clear() m_touch = 0; #endif m_frameSetBeingResized = 0; +#if ENABLE(DRAG_SUPPORT) m_dragTarget = 0; + m_shouldOnlyFireDragOverEvent = false; +#endif m_currentMousePosition = IntPoint(); m_mousePressNode = 0; m_mousePressed = false; m_capturesDragging = false; m_capturingMouseEventsNode = 0; m_latchedWheelEventNode = 0; + m_previousWheelScrolledNode = 0; } void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result) @@ -357,8 +369,10 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event) { +#if ENABLE(DRAG_SUPPORT) // Reset drag state. dragState().m_dragSrc = 0; +#endif if (ScrollView* scrollView = m_frame->view()) { if (scrollView->isPointInScrollbarCorner(event.event().pos())) @@ -371,8 +385,10 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve // so it's allowed to start a drag or selection. m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()); +#if ENABLE(DRAG_SUPPORT) // Careful that the drag starting logic stays in sync with eventMayStartDrag() m_mouseDownMayStartDrag = singleClick; +#endif m_mouseDownWasSingleClickInSelection = false; @@ -400,7 +416,9 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve Node* innerNode = event.targetNode(); m_mousePressNode = innerNode; +#if ENABLE(DRAG_SUPPORT) m_dragStartPos = event.event().pos(); +#endif bool swallowEvent = false; m_frame->selection()->setCaretBlinkingSuspended(true); @@ -420,6 +438,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve return swallowEvent; } +#if ENABLE(DRAG_SUPPORT) bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event) { if (handleDrag(event)) @@ -442,7 +461,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll // Otherwise, let the bridge handle it so the view can scroll itself. RenderObject* renderer = targetNode->renderer(); - while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) { + while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) { if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement()) renderer = renderer->document()->ownerElement()->renderer(); else @@ -559,6 +578,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& m_frame->selection()->setSelection(newSelection); } } +#endif // ENABLE(DRAG_SUPPORT) bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event) { @@ -586,7 +606,9 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e m_frame->selection()->setCaretBlinkingSuspended(false); m_mousePressed = false; m_capturesDragging = false; +#if ENABLE(DRAG_SUPPORT) m_mouseDownMayStartDrag = false; +#endif m_mouseDownMayStartSelect = false; m_mouseDownMayStartAutoscroll = false; m_mouseDownWasInSubframe = false; @@ -598,7 +620,9 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e // on the selection, the selection goes away. However, if we are // editing, place the caret. if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText +#if ENABLE(DRAG_SUPPORT) && m_dragStartPos == event.event().pos() +#endif && m_frame->selection()->isRange() && event.event().button() != RightButton) { VisibleSelection newSelection; @@ -732,7 +756,7 @@ void EventHandler::updateAutoscrollRenderer() if (Node* nodeAtPoint = hitTest.innerNode()) m_autoscrollRenderer = nodeAtPoint->renderer(); - while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeProgramaticallyScrolled(false))) + while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeScrolledAndHasScrollableArea())) m_autoscrollRenderer = m_autoscrollRenderer->parent(); } @@ -741,6 +765,7 @@ void EventHandler::setAutoscrollRenderer(RenderObject* renderer) m_autoscrollRenderer = renderer; } +#if ENABLE(DRAG_SUPPORT) void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const { flagDHTML = false; @@ -761,6 +786,7 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const flagDHTML = (mask & DragSourceActionDHTML) != DragSourceActionNone; flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection)); } +#endif // ENABLE(DRAG_SUPPORT) HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars) { @@ -883,8 +909,10 @@ bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity g if (node) { RenderObject* r = node->renderer(); - if (r && !r->isListBox()) - return r->enclosingBox()->scroll(direction, granularity); + if (r && !r->isListBox() && r->enclosingBox()->scroll(direction, granularity)) { + setFrameWasScrolledByUser(); + return true; + } } return false; @@ -914,10 +942,10 @@ Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResul { if (!hitTestResult.isOverWidget()) return 0; - return subframeForTargetNode(hitTestResult.targetNode()); + return EventHandler::subframeForTargetNode(hitTestResult.targetNode()); } -Frame* subframeForTargetNode(Node* node) +Frame* EventHandler::subframeForTargetNode(Node* node) { if (!node) return 0; @@ -1117,7 +1145,9 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) m_capturesDragging = true; m_currentMousePosition = mouseEvent.pos(); m_mouseDownTimestamp = mouseEvent.timestamp(); +#if ENABLE(DRAG_SUPPORT) m_mouseDownMayStartDrag = false; +#endif m_mouseDownMayStartSelect = false; m_mouseDownMayStartAutoscroll = false; if (FrameView* view = m_frame->view()) @@ -1141,6 +1171,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) m_mousePressNode = mev.targetNode(); +#if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) { InspectorController* inspector = page->inspectorController(); if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) { @@ -1149,6 +1180,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) return true; } } +#endif Frame* subframe = subframeForHitTestResult(mev); if (subframe && passMousePressEventToSubframe(mev, subframe)) { @@ -1172,7 +1204,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) { RenderObject* renderer = mev.targetNode()->renderer(); - while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) { + while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) { if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement()) renderer = renderer->document()->ownerElement()->renderer(); else @@ -1393,8 +1425,10 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi return true; swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true); +#if ENABLE(DRAG_SUPPORT) if (!swallowEvent) swallowEvent = handleMouseDraggedEvent(mev); +#endif // ENABLE(DRAG_SUPPORT) return swallowEvent; } @@ -1464,6 +1498,7 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent; } +#if ENABLE(DRAG_SUPPORT) bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard) { FrameView* view = m_frame->view(); @@ -1486,6 +1521,35 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa return me->defaultPrevented(); } +bool EventHandler::canHandleDragAndDropForTarget(DragAndDropHandleType type, Node* target, const PlatformMouseEvent& event, Clipboard* clipboard, bool* accepted) +{ + bool canHandle = false; + bool wasAccepted = false; + + if (target->hasTagName(frameTag) || target->hasTagName(iframeTag)) { + Frame* frame = static_cast<HTMLFrameElementBase*>(target)->contentFrame(); + if (frame) { + switch (type) { + case UpdateDragAndDrop: + wasAccepted = frame->eventHandler()->updateDragAndDrop(event, clipboard); + break; + case CancelDragAndDrop: + frame->eventHandler()->cancelDragAndDrop(event, clipboard); + break; + case PerformDragAndDrop: + wasAccepted = frame->eventHandler()->performDragAndDrop(event, clipboard); + break; + } + } + } else + canHandle = true; + + if (accepted) + *accepted = wasAccepted; + + return canHandle; +} + bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { bool accept = false; @@ -1507,27 +1571,34 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* // FIXME: this ordering was explicitly chosen to match WinIE. However, // it is sometimes incorrect when dragging within subframes, as seen with // LayoutTests/fast/events/drag-in-frames.html. - if (newTarget) { - if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) - accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard); + // + // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. + if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) { + // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event. + if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { + // for now we don't care if event handler cancels default behavior, since there is none + dispatchDragSrcEvent(eventNames().dragEvent, event); + } + accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard); } - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); - else - dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + if (m_dragTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, m_dragTarget.get(), event, clipboard, &accept)) + dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + + if (newTarget) { + // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that + // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function. + m_shouldOnlyFireDragOverEvent = true; } } else { - if (newTarget) { - if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) - accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard); + if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) { + // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier. + if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { + // for now we don't care if event handler cancels default behavior, since there is none + dispatchDragSrcEvent(eventNames().dragEvent, event); + } + accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard); + m_shouldOnlyFireDragOverEvent = false; } } m_dragTarget = newTarget; @@ -1537,13 +1608,10 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - frame->eventHandler()->cancelDragAndDrop(event, clipboard); - else - dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + if (m_dragTarget && canHandleDragAndDropForTarget(CancelDragAndDrop, m_dragTarget.get(), event, clipboard)) { + if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) + dispatchDragSrcEvent(eventNames().dragEvent, event); + dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); } clearDragState(); } @@ -1551,14 +1619,8 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { bool accept = false; - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->performDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); - } + if (m_dragTarget && canHandleDragAndDropForTarget(PerformDragAndDrop, m_dragTarget.get(), event, clipboard, &accept)) + dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); clearDragState(); return accept; } @@ -1567,10 +1629,12 @@ void EventHandler::clearDragState() { m_dragTarget = 0; m_capturingMouseEventsNode = 0; + m_shouldOnlyFireDragOverEvent = false; #if PLATFORM(MAC) m_sendingEventToSubview = false; #endif } +#endif // ENABLE(DRAG_SUPPORT) void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n) { @@ -1692,12 +1756,15 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe swallowEvent = m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount); if (!swallowEvent && eventType == eventNames().mousedownEvent) { + // The layout needs to be up to date to determine if an element is focusable. + m_frame->document()->updateLayoutIgnorePendingStylesheets(); + // Blur current focus node when a link/button is clicked; this // is expected by some sites that rely on onChange handlers running // from form fields before the button click is processed. Node* node = m_nodeUnderMouse.get(); RenderObject* renderer = node ? node->renderer() : 0; - + // Walk up the render tree to search for a node to focus. // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields. while (renderer) { @@ -1736,6 +1803,13 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe return swallowEvent; } +#if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && PLATFORM(LINUX)) +bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const +{ + return false; +} +#endif + bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) { Document* doc = m_frame->document(); @@ -1749,35 +1823,39 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) FrameView* view = m_frame->view(); if (!view) return false; + setFrameWasScrolledByUser(); IntPoint vPoint = view->windowToContents(e.pos()); Node* node; bool isOverWidget; bool didSetLatchedNode = false; - + + HitTestRequest request(HitTestRequest::ReadOnly); + HitTestResult result(vPoint); + doc->renderView()->layer()->hitTest(request, result); + if (m_useLatchedWheelEventNode) { if (!m_latchedWheelEventNode) { - HitTestRequest request(HitTestRequest::ReadOnly); - HitTestResult result(vPoint); - doc->renderView()->layer()->hitTest(request, result); m_latchedWheelEventNode = result.innerNode(); m_widgetIsLatched = result.isOverWidget(); didSetLatchedNode = true; } - + node = m_latchedWheelEventNode.get(); isOverWidget = m_widgetIsLatched; } else { if (m_latchedWheelEventNode) m_latchedWheelEventNode = 0; - - HitTestRequest request(HitTestRequest::ReadOnly); - HitTestResult result(vPoint); - doc->renderView()->layer()->hitTest(request, result); + if (m_previousWheelScrolledNode) + m_previousWheelScrolledNode = 0; + node = result.innerNode(); isOverWidget = result.isOverWidget(); } - + + if (shouldTurnVerticalTicksIntoHorizontal(result)) + e.turnVerticalTicksIntoHorizontal(); + if (node) { // Figure out which view to send the event to. RenderObject* target = node->renderer(); @@ -1794,17 +1872,20 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) node->dispatchWheelEvent(e); if (e.isAccepted()) return true; - + // If we don't have a renderer, send the wheel event to the first node we find with a renderer. // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll. while (node && !node->renderer()) node = node->parent(); - + if (node && node->renderer()) { // Just break up into two scrolls if we need to. Diagonal movement on // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set). - scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node); - scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node); + Node* stopNode = m_previousWheelScrolledNode.get(); + scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node, &stopNode); + scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node, &stopNode); + if (!m_useLatchedWheelEventNode) + m_previousWheelScrolledNode = stopNode; } } @@ -1819,6 +1900,7 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) return e.isAccepted(); } +#if ENABLE(CONTEXT_MENUS) bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) { Document* doc = m_frame->document(); @@ -1849,6 +1931,7 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) return swallowEvent; } +#endif // ENABLE(CONTEXT_MENUS) void EventHandler::scheduleHoverStateUpdate() { @@ -1868,12 +1951,13 @@ bool EventHandler::canMouseDownStartSelect(Node* node) for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) { if (Node* node = curr->node()) - return node->dispatchEvent(eventNames().selectstartEvent, true, true); + return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true)); } return true; } +#if ENABLE(DRAG_SUPPORT) bool EventHandler::canMouseDragExtendSelect(Node* node) { if (!node || !node->renderer()) @@ -1881,11 +1965,12 @@ bool EventHandler::canMouseDragExtendSelect(Node* node) for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) { if (Node* node = curr->node()) - return node->dispatchEvent(eventNames().selectstartEvent, true, true); + return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true)); } return true; } +#endif // ENABLE(DRAG_SUPPORT) void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) { @@ -2109,6 +2194,7 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) } } +#if ENABLE(DRAG_SUPPORT) bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const { IntPoint dragViewportLocation((int)floatDragViewportLocation.x(), (int)floatDragViewportLocation.y()); @@ -2142,19 +2228,12 @@ void EventHandler::freeClipboard() bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const { - if (!node || node->hasChildNodes() || !m_frame->view()) + if (!node || !m_frame->view()) return false; Page* page = m_frame->page(); return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point); } - -void EventHandler::dragSourceMovedTo(const PlatformMouseEvent& event) -{ - if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) - // for now we don't care if event handler cancels default behavior, since there is none - dispatchDragSrcEvent(eventNames().dragEvent, event); -} - + void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation) { if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { @@ -2280,9 +2359,10 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event) // gather values from DHTML element, if it set any dragState().m_dragClipboard->sourceOperation(srcOp); - // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with - // dragImage! Because of that dumb reentrancy, we may think we've not started the - // drag when that happens. So we have to assume it's started before we kick it off. + // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the + // drag with dragImage! Because of that dumb reentrancy, we may think we've not + // started the drag when that happens. So we have to assume it's started before we + // kick it off. dragState().m_dragClipboard->setDragHasStarted(); } } @@ -2308,6 +2388,7 @@ cleanupDrag: // No more default handling (like selection), whether we're past the hysteresis bounds or not return true; } +#endif // ENABLE(DRAG_SUPPORT) bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, bool isLineBreak, bool isBackTab) { @@ -2339,7 +2420,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve } -#if !PLATFORM(MAC) && !PLATFORM(QT) +#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU) bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const { return false; @@ -2440,27 +2521,33 @@ void EventHandler::capsLockStateMayHaveChanged() void EventHandler::sendResizeEvent() { - m_frame->document()->dispatchWindowEvent(eventNames().resizeEvent, false, false); + m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false)); } void EventHandler::sendScrollEvent() { + setFrameWasScrolledByUser(); + if (m_frame->view()) + m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false)); +} + +void EventHandler::setFrameWasScrolledByUser() +{ FrameView* v = m_frame->view(); - if (!v) - return; - v->setWasScrolledByUser(true); - m_frame->document()->dispatchEvent(eventNames().scrollEvent, true, false); + if (v) + v->setWasScrolledByUser(true); } bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar) { if (!scrollbar || !scrollbar->enabled()) return false; + setFrameWasScrolledByUser(); return scrollbar->mouseDown(mev.event()); } #if ENABLE(TOUCH_EVENTS) // Android -bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) +int EventHandler::handleTouchEvent(const PlatformTouchEvent& e) { // only handle the touch event in the top frame handler if (m_frame->tree()->parent(true)) @@ -2468,17 +2555,17 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) Document* doc = m_frame->document(); if (!doc) - return false; + return 0; RenderObject* docRenderer = doc->renderer(); if (!docRenderer) - return false; + return 0; if (doc->touchEventListeners().size() == 0) - return false; + return 0; TouchEventType type = e.eventType(); - if (type == TouchEventStart) { + if (type == TouchEventStart || type == TouchEventLongPress || type == TouchEventDoubleTap) { Frame* frame = m_frame; IntPoint vPoint = frame->view()->windowToContents(e.pos()); HitTestRequest request(HitTestRequest::ReadOnly); @@ -2518,13 +2605,13 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) if ((type == TouchEventMove) && (e.x() == m_touch->screenX()) && (e.y() == m_touch->screenY())) { // don't trigger the event if it hasn't really moved - return false; + return 0; } IntPoint vPoint = m_touch->frame()->view()->windowToContents(e.pos()); m_touch->updateLocation(e.x(), e.y(), vPoint.x(), vPoint.y()); } else { - return false; + return 0; } RefPtr<TouchList> touchList = TouchList::create(); @@ -2557,15 +2644,30 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e) m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY()); break; + case TouchEventLongPress: + te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(), + eventNames().touchlongpressEvent, m_touch->frame()->document()->defaultView(), + m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY()); + break; + + case TouchEventDoubleTap: + te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(), + eventNames().touchdoubletapEvent, m_touch->frame()->document()->defaultView(), + m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY()); + break; + default: return false; } ExceptionCode ec = 0; m_touch->target()->dispatchEvent(te.get(), ec); - if (type == TouchEventEnd || type == TouchEventCancel) { + if (type == TouchEventEnd || type == TouchEventCancel) m_touch = 0; - } - return te->defaultPrevented(); + if (type == TouchEventLongPress || type == TouchEventDoubleTap) + return 0; + return (te->defaultPrevented() ? preventTouch : 0) + | (te->longPressPrevented() ? preventLongPress : 0) + | (te->doubleTapPrevented() ? preventDoubleTap : 0); } #endif |
