2 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
3 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
4 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5 * Copyright (C) 2003, 2005, 2006, 2008 Apple Inc. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 #include "core/events/MouseRelatedEvent.h"
26 #include "core/dom/Document.h"
27 #include "core/frame/LocalDOMWindow.h"
28 #include "core/frame/FrameView.h"
29 #include "core/frame/LocalFrame.h"
30 #include "core/layout/LayoutObject.h"
31 #include "core/paint/DeprecatedPaintLayer.h"
35 MouseRelatedEvent::MouseRelatedEvent()
36 : m_positionType(PositionType::Position
)
37 , m_hasCachedRelativePosition(false)
41 static LayoutSize
contentsScrollOffset(AbstractView
* abstractView
)
43 if (!abstractView
|| !abstractView
->isLocalDOMWindow())
45 LocalFrame
* frame
= toLocalDOMWindow(abstractView
)->frame();
48 FrameView
* frameView
= frame
->view();
51 float scaleFactor
= frame
->pageZoomFactor();
52 return LayoutSize(frameView
->scrollX() / scaleFactor
, frameView
->scrollY() / scaleFactor
);
55 MouseRelatedEvent::MouseRelatedEvent(const AtomicString
& eventType
, bool canBubble
, bool cancelable
, PassRefPtrWillBeRawPtr
<AbstractView
> abstractView
,
56 int detail
, const IntPoint
& screenLocation
, const IntPoint
& rootFrameLocation
,
57 const IntPoint
& movementDelta
,
58 bool ctrlKey
, bool altKey
, bool shiftKey
, bool metaKey
, PositionType positionType
, InputDeviceCapabilities
* sourceCapabilities
)
59 : UIEventWithKeyState(eventType
, canBubble
, cancelable
, abstractView
, detail
, ctrlKey
, altKey
, shiftKey
, metaKey
, sourceCapabilities
)
60 , m_screenLocation(screenLocation
)
61 , m_movementDelta(movementDelta
)
62 , m_positionType(positionType
)
64 LayoutPoint adjustedPageLocation
;
65 LayoutPoint scrollPosition
;
67 LocalFrame
* frame
= view() && view()->isLocalDOMWindow() ? toLocalDOMWindow(view())->frame() : nullptr;
68 if (frame
&& hasPosition()) {
69 if (FrameView
* frameView
= frame
->view()) {
70 scrollPosition
= frameView
->scrollPosition();
71 adjustedPageLocation
= frameView
->rootFrameToContents(rootFrameLocation
);
72 float scaleFactor
= 1 / frame
->pageZoomFactor();
73 if (scaleFactor
!= 1.0f
) {
74 adjustedPageLocation
.scale(scaleFactor
, scaleFactor
);
75 scrollPosition
.scale(scaleFactor
, scaleFactor
);
80 m_clientLocation
= adjustedPageLocation
- toLayoutSize(scrollPosition
);
81 m_pageLocation
= adjustedPageLocation
;
86 void MouseRelatedEvent::initCoordinates()
88 // Set up initial values for coordinates.
89 // Correct values are computed lazily, see computeRelativePosition.
90 m_layerLocation
= m_pageLocation
;
91 m_offsetLocation
= m_pageLocation
;
93 computePageLocation();
94 m_hasCachedRelativePosition
= false;
97 void MouseRelatedEvent::initCoordinates(const LayoutPoint
& clientLocation
)
99 // Set up initial values for coordinates.
100 // Correct values are computed lazily, see computeRelativePosition.
101 m_clientLocation
= clientLocation
;
102 m_pageLocation
= clientLocation
+ contentsScrollOffset(view());
104 m_layerLocation
= m_pageLocation
;
105 m_offsetLocation
= m_pageLocation
;
107 computePageLocation();
108 m_hasCachedRelativePosition
= false;
111 static float pageZoomFactor(const UIEvent
* event
)
113 if (!event
->view() || !event
->view()->isLocalDOMWindow())
115 LocalFrame
* frame
= toLocalDOMWindow(event
->view())->frame();
118 return frame
->pageZoomFactor();
121 void MouseRelatedEvent::computePageLocation()
123 float scaleFactor
= pageZoomFactor(this);
124 setAbsoluteLocation(roundedLayoutPoint(FloatPoint(pageX() * scaleFactor
, pageY() * scaleFactor
)));
127 void MouseRelatedEvent::receivedTarget()
129 m_hasCachedRelativePosition
= false;
132 void MouseRelatedEvent::computeRelativePosition()
134 Node
* targetNode
= target() ? target()->toNode() : nullptr;
138 // Compute coordinates that are based on the target.
139 m_layerLocation
= m_pageLocation
;
140 m_offsetLocation
= m_pageLocation
;
142 // Must have an updated layout tree for this math to work correctly.
143 targetNode
->document().updateLayoutIgnorePendingStylesheets();
145 // Adjust offsetLocation to be relative to the target's position.
146 if (LayoutObject
* r
= targetNode
->layoutObject()) {
147 FloatPoint localPos
= r
->absoluteToLocal(FloatPoint(absoluteLocation()), UseTransforms
);
148 m_offsetLocation
= roundedLayoutPoint(localPos
);
149 float scaleFactor
= 1 / pageZoomFactor(this);
150 if (scaleFactor
!= 1.0f
)
151 m_offsetLocation
.scale(scaleFactor
, scaleFactor
);
154 // Adjust layerLocation to be relative to the layer.
155 // FIXME: event.layerX and event.layerY are poorly defined,
156 // and probably don't always correspond to DeprecatedPaintLayer offsets.
157 // https://bugs.webkit.org/show_bug.cgi?id=21868
158 Node
* n
= targetNode
;
159 while (n
&& !n
->layoutObject())
163 // FIXME: This logic is a wrong implementation of convertToLayerCoords.
164 for (DeprecatedPaintLayer
* layer
= n
->layoutObject()->enclosingLayer(); layer
; layer
= layer
->parent())
165 m_layerLocation
-= toLayoutSize(layer
->location());
168 m_hasCachedRelativePosition
= true;
171 int MouseRelatedEvent::layerX()
173 if (!m_hasCachedRelativePosition
)
174 computeRelativePosition();
175 return m_layerLocation
.x();
178 int MouseRelatedEvent::layerY()
180 if (!m_hasCachedRelativePosition
)
181 computeRelativePosition();
182 return m_layerLocation
.y();
185 int MouseRelatedEvent::offsetX()
189 if (!m_hasCachedRelativePosition
)
190 computeRelativePosition();
191 return roundToInt(m_offsetLocation
.x());
194 int MouseRelatedEvent::offsetY()
198 if (!m_hasCachedRelativePosition
)
199 computeRelativePosition();
200 return roundToInt(m_offsetLocation
.y());
203 int MouseRelatedEvent::pageX() const
205 return m_pageLocation
.x();
208 int MouseRelatedEvent::pageY() const
210 return m_pageLocation
.y();
213 int MouseRelatedEvent::x() const
215 // FIXME: This is not correct.
216 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
217 return m_clientLocation
.x();
220 int MouseRelatedEvent::y() const
222 // FIXME: This is not correct.
223 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
224 return m_clientLocation
.y();
227 DEFINE_TRACE(MouseRelatedEvent
)
229 UIEventWithKeyState::trace(visitor
);