blob: 275492f9fbd764e71bc7884932d50f65cf8476c2 [file] [log] [blame]
darin@apple.com48ac3c42008-06-14 08:46:51 +00001/*
weinig681a5172006-06-19 22:58:36 +00002 * 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)
benjamin@webkit.orgac28bde2013-06-19 22:41:17 +00005 * Copyright (C) 2003, 2005, 2006, 2008, 2013 Apple Inc. All rights reserved.
weinig681a5172006-06-19 22:58:36 +00006 *
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.
11 *
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.
16 *
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
ddkilzerc8eccec2007-09-26 02:29:57 +000019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
weinig681a5172006-06-19 22:58:36 +000021 */
22
23#include "config.h"
24#include "MouseRelatedEvent.h"
25
rniwa@webkit.orgf8614f72018-05-04 23:52:43 +000026#include "DOMWindow.h"
weinig681a5172006-06-19 22:58:36 +000027#include "Document.h"
darin8ce13dc2006-06-26 16:38:55 +000028#include "Frame.h"
darin647be152006-11-05 22:02:23 +000029#include "FrameView.h"
megan_gardner@apple.comea94f532017-07-10 19:46:01 +000030#include "LayoutPoint.h"
weinig681a5172006-06-19 22:58:36 +000031#include "RenderLayer.h"
32#include "RenderObject.h"
ysuzuki@apple.come4070702019-09-18 22:10:00 +000033#include <wtf/IsoMallocInlines.h>
weinig681a5172006-06-19 22:58:36 +000034
35namespace WebCore {
36
ysuzuki@apple.come4070702019-09-18 22:10:00 +000037WTF_MAKE_ISO_ALLOCATED_IMPL(MouseRelatedEvent);
38
darin@apple.com0ce67df2019-06-17 01:48:13 +000039MouseRelatedEvent::MouseRelatedEvent(const AtomString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed,
rniwa@webkit.org1321fa32018-08-24 20:14:50 +000040 MonotonicTime timestamp, RefPtr<WindowProxy>&& view, int detail,
rniwa@webkit.orgdc499bd2018-08-24 22:51:33 +000041 const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier> modifiers, IsSimulated isSimulated, IsTrusted isTrusted)
42 : UIEventWithKeyState(eventType, canBubble, isCancelable, isComposed, timestamp, WTFMove(view), detail, modifiers, isTrusted)
eae@chromium.org039e8262011-06-01 23:19:02 +000043 , m_screenLocation(screenLocation)
scheib@chromium.orge972c2e2011-11-24 00:25:38 +000044#if ENABLE(POINTER_LOCK)
45 , m_movementDelta(movementDelta)
46#endif
rniwa@webkit.org26464652018-08-22 04:41:06 +000047 , m_isSimulated(isSimulated == IsSimulated::Yes)
weinig681a5172006-06-19 22:58:36 +000048{
rniwa@webkit.org26464652018-08-22 04:41:06 +000049#if !ENABLE(POINTER_LOCK)
50 UNUSED_PARAM(movementDelta);
51#endif
52 init(m_isSimulated, windowLocation);
53}
54
darin@apple.com0ce67df2019-06-17 01:48:13 +000055MouseRelatedEvent::MouseRelatedEvent(const AtomString& type, IsCancelable isCancelable, MonotonicTime timestamp, RefPtr<WindowProxy>&& view, const IntPoint& globalLocation, OptionSet<Modifier> modifiers)
rniwa@webkit.org1321fa32018-08-24 20:14:50 +000056 : MouseRelatedEvent(type, CanBubble::Yes, isCancelable, IsComposed::Yes, timestamp,
57 WTFMove(view), 0, globalLocation, globalLocation /* Converted in init */, { }, modifiers, IsSimulated::No)
rniwa@webkit.org26464652018-08-22 04:41:06 +000058{
jiewen_tan@apple.comcb979e92016-02-11 00:03:11 +000059}
60
darin@apple.com0ce67df2019-06-17 01:48:13 +000061MouseRelatedEvent::MouseRelatedEvent(const AtomString& eventType, const MouseRelatedEventInit& initializer, IsTrusted isTrusted)
rniwa@webkit.org1321fa32018-08-24 20:14:50 +000062 : UIEventWithKeyState(eventType, initializer)
jiewen_tan@apple.comcb979e92016-02-11 00:03:11 +000063 , m_screenLocation(IntPoint(initializer.screenX, initializer.screenY))
64#if ENABLE(POINTER_LOCK)
65 , m_movementDelta(IntPoint(0, 0))
66#endif
jiewen_tan@apple.comcb979e92016-02-11 00:03:11 +000067{
rniwa@webkit.org1321fa32018-08-24 20:14:50 +000068 ASSERT_UNUSED(isTrusted, isTrusted == IsTrusted::No);
jiewen_tan@apple.comcb979e92016-02-11 00:03:11 +000069 init(false, IntPoint(0, 0));
70}
71
72void MouseRelatedEvent::init(bool isSimulated, const IntPoint& windowLocation)
73{
simon.fraser@apple.comde89f4d2017-06-30 02:09:09 +000074 if (!isSimulated) {
cdumez@apple.com240d0172018-04-27 22:11:00 +000075 if (auto* frameView = frameViewFromWindowProxy(view())) {
simon.fraser@apple.comba0535e2017-05-13 18:24:15 +000076 FloatPoint absolutePoint = frameView->windowToContents(windowLocation);
77 FloatPoint documentPoint = frameView->absoluteToDocumentPoint(absolutePoint);
78 m_pageLocation = flooredLayoutPoint(documentPoint);
simon.fraser@apple.com5cdcc942017-07-17 20:24:16 +000079 m_clientLocation = pagePointToClientPoint(m_pageLocation, frameView);
dglazkov@chromium.org3beb6ec2011-03-31 16:01:13 +000080 }
81 }
82
weinig681a5172006-06-19 22:58:36 +000083 initCoordinates();
84}
85
86void MouseRelatedEvent::initCoordinates()
87{
88 // Set up initial values for coordinates.
eae@chromium.org198fc132011-03-29 11:02:33 +000089 // Correct values are computed lazily, see computeRelativePosition.
eae@chromium.org039e8262011-06-01 23:19:02 +000090 m_layerLocation = m_pageLocation;
91 m_offsetLocation = m_pageLocation;
simon.fraser@apple.com032683d2009-03-22 17:35:38 +000092
93 computePageLocation();
eae@chromium.org198fc132011-03-29 11:02:33 +000094 m_hasCachedRelativePosition = false;
weinig681a5172006-06-19 22:58:36 +000095}
96
cdumez@apple.com240d0172018-04-27 22:11:00 +000097FrameView* MouseRelatedEvent::frameViewFromWindowProxy(WindowProxy* windowProxy)
simon.fraser@apple.com5cdcc942017-07-17 20:24:16 +000098{
cdumez@apple.com240d0172018-04-27 22:11:00 +000099 if (!windowProxy || !is<DOMWindow>(windowProxy->window()))
simon.fraser@apple.com5cdcc942017-07-17 20:24:16 +0000100 return nullptr;
101
cdumez@apple.com240d0172018-04-27 22:11:00 +0000102 auto* frame = downcast<DOMWindow>(*windowProxy->window()).frame();
103 return frame ? frame->view() : nullptr;
simon.fraser@apple.com5cdcc942017-07-17 20:24:16 +0000104}
105
106LayoutPoint MouseRelatedEvent::pagePointToClientPoint(LayoutPoint pagePoint, FrameView* frameView)
107{
108 if (!frameView)
109 return pagePoint;
110
111 return flooredLayoutPoint(frameView->documentToClientPoint(pagePoint));
112}
113
114LayoutPoint MouseRelatedEvent::pagePointToAbsolutePoint(LayoutPoint pagePoint, FrameView* frameView)
115{
116 if (!frameView)
117 return pagePoint;
118
119 return pagePoint.scaled(frameView->documentToAbsoluteScaleFactor());
120}
121
eae@chromium.org61ebe432011-08-15 19:31:06 +0000122void MouseRelatedEvent::initCoordinates(const LayoutPoint& clientLocation)
darin896f6712006-06-28 03:52:29 +0000123{
124 // Set up initial values for coordinates.
eae@chromium.org198fc132011-03-29 11:02:33 +0000125 // Correct values are computed lazily, see computeRelativePosition.
simon.fraser@apple.comba0535e2017-05-13 18:24:15 +0000126 FloatSize documentToClientOffset;
cdumez@apple.com240d0172018-04-27 22:11:00 +0000127 if (auto* frameView = frameViewFromWindowProxy(view()))
simon.fraser@apple.comde89f4d2017-06-30 02:09:09 +0000128 documentToClientOffset = frameView->documentToClientOffset();
simon.fraser@apple.comba0535e2017-05-13 18:24:15 +0000129
eae@chromium.org039e8262011-06-01 23:19:02 +0000130 m_clientLocation = clientLocation;
simon.fraser@apple.comba0535e2017-05-13 18:24:15 +0000131 m_pageLocation = clientLocation - LayoutSize(documentToClientOffset);
eae@chromium.org039e8262011-06-01 23:19:02 +0000132
133 m_layerLocation = m_pageLocation;
134 m_offsetLocation = m_pageLocation;
simon.fraser@apple.com032683d2009-03-22 17:35:38 +0000135
136 computePageLocation();
eae@chromium.org198fc132011-03-29 11:02:33 +0000137 m_hasCachedRelativePosition = false;
simon.fraser@apple.com032683d2009-03-22 17:35:38 +0000138}
139
simon.fraser@apple.comde89f4d2017-06-30 02:09:09 +0000140float MouseRelatedEvent::documentToAbsoluteScaleFactor() const
jknotten@chromium.org664f04f2011-10-06 10:10:07 +0000141{
cdumez@apple.com240d0172018-04-27 22:11:00 +0000142 if (auto* frameView = frameViewFromWindowProxy(view()))
simon.fraser@apple.comde89f4d2017-06-30 02:09:09 +0000143 return frameView->documentToAbsoluteScaleFactor();
144
145 return 1;
jknotten@chromium.org664f04f2011-10-06 10:10:07 +0000146}
147
simon.fraser@apple.com032683d2009-03-22 17:35:38 +0000148void MouseRelatedEvent::computePageLocation()
149{
cdumez@apple.com240d0172018-04-27 22:11:00 +0000150 m_absoluteLocation = pagePointToAbsolutePoint(m_pageLocation, frameViewFromWindowProxy(view()));
darin896f6712006-06-28 03:52:29 +0000151}
152
weinig681a5172006-06-19 22:58:36 +0000153void MouseRelatedEvent::receivedTarget()
154{
eae@chromium.org198fc132011-03-29 11:02:33 +0000155 m_hasCachedRelativePosition = false;
156}
157
158void MouseRelatedEvent::computeRelativePosition()
159{
darin@apple.com17cae1e2017-11-13 06:12:09 +0000160 if (!is<Node>(target()))
ap5f8a6da2006-12-15 21:49:43 +0000161 return;
darin@apple.com17cae1e2017-11-13 06:12:09 +0000162 auto& targetNode = downcast<Node>(*target());
ap5f8a6da2006-12-15 21:49:43 +0000163
weinig681a5172006-06-19 22:58:36 +0000164 // Compute coordinates that are based on the target.
eae@chromium.org039e8262011-06-01 23:19:02 +0000165 m_layerLocation = m_pageLocation;
166 m_offsetLocation = m_pageLocation;
weinig681a5172006-06-19 22:58:36 +0000167
weinig681a5172006-06-19 22:58:36 +0000168 // Must have an updated render tree for this math to work correctly.
darin@apple.com17cae1e2017-11-13 06:12:09 +0000169 targetNode.document().updateLayoutIgnorePendingStylesheets();
weinig681a5172006-06-19 22:58:36 +0000170
eae@chromium.org039e8262011-06-01 23:19:02 +0000171 // Adjust offsetLocation to be relative to the target's position.
darin@apple.com17cae1e2017-11-13 06:12:09 +0000172 if (RenderObject* r = targetNode.renderer()) {
zalan@apple.com83de8f82014-08-26 02:11:44 +0000173 m_offsetLocation = LayoutPoint(r->absoluteToLocal(absoluteLocation(), UseTransforms));
simon.fraser@apple.comde89f4d2017-06-30 02:09:09 +0000174 float scaleFactor = 1 / documentToAbsoluteScaleFactor();
jonlee@apple.comb8f98c32012-11-18 08:03:31 +0000175 if (scaleFactor != 1.0f)
simon.fraser@apple.com0b353f32016-11-04 05:11:12 +0000176 m_offsetLocation.scale(scaleFactor);
weinig681a5172006-06-19 22:58:36 +0000177 }
178
eae@chromium.org039e8262011-06-01 23:19:02 +0000179 // Adjust layerLocation to be relative to the layer.
simon.fraser@apple.com6a7e0c82012-11-30 23:00:41 +0000180 // FIXME: event.layerX and event.layerY are poorly defined,
181 // and probably don't always correspond to RenderLayer offsets.
182 // https://bugs.webkit.org/show_bug.cgi?id=21868
darin@apple.com17cae1e2017-11-13 06:12:09 +0000183 Node* n = &targetNode;
weinig681a5172006-06-19 22:58:36 +0000184 while (n && !n->renderer())
dglazkov@chromium.orge43caa72010-11-18 00:20:10 +0000185 n = n->parentNode();
eae@chromium.org198fc132011-03-29 11:02:33 +0000186
187 RenderLayer* layer;
188 if (n && (layer = n->renderer()->enclosingLayer())) {
weinig681a5172006-06-19 22:58:36 +0000189 for (; layer; layer = layer->parent()) {
eae@chromium.orgfc240a22011-11-02 00:08:04 +0000190 m_layerLocation -= toLayoutSize(layer->location());
weinig681a5172006-06-19 22:58:36 +0000191 }
192 }
eae@chromium.org198fc132011-03-29 11:02:33 +0000193
194 m_hasCachedRelativePosition = true;
195}
megan_gardner@apple.comea94f532017-07-10 19:46:01 +0000196
197FloatPoint MouseRelatedEvent::locationInRootViewCoordinates() const
198{
cdumez@apple.com240d0172018-04-27 22:11:00 +0000199 if (auto* frameView = frameViewFromWindowProxy(view()))
simon.fraser@apple.com5cdcc942017-07-17 20:24:16 +0000200 return frameView->contentsToRootView(roundedIntPoint(m_absoluteLocation));
201
202 return m_absoluteLocation;
megan_gardner@apple.comea94f532017-07-10 19:46:01 +0000203}
eae@chromium.org198fc132011-03-29 11:02:33 +0000204
205int MouseRelatedEvent::layerX()
206{
207 if (!m_hasCachedRelativePosition)
208 computeRelativePosition();
eae@chromium.org039e8262011-06-01 23:19:02 +0000209 return m_layerLocation.x();
eae@chromium.org198fc132011-03-29 11:02:33 +0000210}
211
212int MouseRelatedEvent::layerY()
213{
214 if (!m_hasCachedRelativePosition)
215 computeRelativePosition();
eae@chromium.org039e8262011-06-01 23:19:02 +0000216 return m_layerLocation.y();
eae@chromium.org198fc132011-03-29 11:02:33 +0000217}
218
219int MouseRelatedEvent::offsetX()
220{
akling@apple.combc74c642014-02-28 18:44:10 +0000221 if (isSimulated())
222 return 0;
eae@chromium.org198fc132011-03-29 11:02:33 +0000223 if (!m_hasCachedRelativePosition)
224 computeRelativePosition();
leviw@chromium.org0e230612012-03-01 19:33:44 +0000225 return roundToInt(m_offsetLocation.x());
eae@chromium.org198fc132011-03-29 11:02:33 +0000226}
227
228int MouseRelatedEvent::offsetY()
229{
akling@apple.combc74c642014-02-28 18:44:10 +0000230 if (isSimulated())
231 return 0;
eae@chromium.org198fc132011-03-29 11:02:33 +0000232 if (!m_hasCachedRelativePosition)
233 computeRelativePosition();
leviw@chromium.org0e230612012-03-01 19:33:44 +0000234 return roundToInt(m_offsetLocation.y());
weinig681a5172006-06-19 22:58:36 +0000235}
236
237int MouseRelatedEvent::pageX() const
238{
eae@chromium.org039e8262011-06-01 23:19:02 +0000239 return m_pageLocation.x();
weinig681a5172006-06-19 22:58:36 +0000240}
241
242int MouseRelatedEvent::pageY() const
243{
eae@chromium.org039e8262011-06-01 23:19:02 +0000244 return m_pageLocation.y();
245}
246
eae@chromium.org61ebe432011-08-15 19:31:06 +0000247const LayoutPoint& MouseRelatedEvent::pageLocation() const
eae@chromium.org039e8262011-06-01 23:19:02 +0000248{
249 return m_pageLocation;
weinig681a5172006-06-19 22:58:36 +0000250}
251
252int MouseRelatedEvent::x() const
253{
254 // FIXME: This is not correct.
255 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
eae@chromium.org039e8262011-06-01 23:19:02 +0000256 return m_clientLocation.x();
weinig681a5172006-06-19 22:58:36 +0000257}
258
259int MouseRelatedEvent::y() const
260{
261 // FIXME: This is not correct.
262 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
eae@chromium.org039e8262011-06-01 23:19:02 +0000263 return m_clientLocation.y();
weinig681a5172006-06-19 22:58:36 +0000264}
265
266} // namespace WebCore