• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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.
6  *
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
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "config.h"
24 #include "MouseRelatedEvent.h"
25 
26 #include "DOMWindow.h"
27 #include "Document.h"
28 #include "Frame.h"
29 #include "FrameView.h"
30 #include "RenderLayer.h"
31 #include "RenderObject.h"
32 
33 namespace WebCore {
34 
MouseRelatedEvent()35 MouseRelatedEvent::MouseRelatedEvent()
36     : m_screenX(0)
37     , m_screenY(0)
38     , m_clientX(0)
39     , m_clientY(0)
40     , m_pageX(0)
41     , m_pageY(0)
42     , m_layerX(0)
43     , m_layerY(0)
44     , m_offsetX(0)
45     , m_offsetY(0)
46     , m_isSimulated(false)
47     , m_hasCachedRelativePosition(false)
48 {
49 }
50 
contentsX(AbstractView * abstractView)51 static int contentsX(AbstractView* abstractView)
52 {
53     if (!abstractView)
54         return 0;
55     Frame* frame = abstractView->frame();
56     if (!frame)
57         return 0;
58     FrameView* frameView = frame->view();
59     if (!frameView)
60         return 0;
61     return frameView->scrollX() / frame->pageZoomFactor();
62 }
63 
contentsY(AbstractView * abstractView)64 static int contentsY(AbstractView* abstractView)
65 {
66     if (!abstractView)
67         return 0;
68     Frame* frame = abstractView->frame();
69     if (!frame)
70         return 0;
71     FrameView* frameView = frame->view();
72     if (!frameView)
73         return 0;
74     return frameView->scrollY() / frame->pageZoomFactor();
75 }
76 
MouseRelatedEvent(const AtomicString & eventType,bool canBubble,bool cancelable,PassRefPtr<AbstractView> abstractView,int detail,int screenX,int screenY,int windowX,int windowY,bool ctrlKey,bool altKey,bool shiftKey,bool metaKey,bool isSimulated)77 MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> abstractView,
78                                      int detail, int screenX, int screenY, int windowX, int windowY,
79                                      bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated)
80     : UIEventWithKeyState(eventType, canBubble, cancelable, abstractView, detail, ctrlKey, altKey, shiftKey, metaKey)
81     , m_screenX(screenX)
82     , m_screenY(screenY)
83     , m_clientX(0)
84     , m_clientY(0)
85     , m_pageX(0)
86     , m_pageY(0)
87     , m_isSimulated(isSimulated)
88 {
89     IntPoint adjustedPageLocation;
90     IntPoint scrollPosition;
91 
92     Frame* frame = view() ? view()->frame() : 0;
93     if (frame && !isSimulated) {
94         if (FrameView* frameView = frame->view()) {
95             scrollPosition = frameView->scrollPosition();
96             adjustedPageLocation = frameView->windowToContents(IntPoint(windowX, windowY));
97             float pageZoom = frame->pageZoomFactor();
98             if (pageZoom != 1.0f) {
99                 // Adjust our pageX and pageY to account for the page zoom.
100                 adjustedPageLocation.setX(lroundf(adjustedPageLocation.x() / pageZoom));
101                 adjustedPageLocation.setY(lroundf(adjustedPageLocation.y() / pageZoom));
102                 scrollPosition.setX(scrollPosition.x() / pageZoom);
103                 scrollPosition.setY(scrollPosition.y() / pageZoom);
104             }
105         }
106     }
107 
108     IntPoint clientLocation(adjustedPageLocation - scrollPosition);
109     m_clientX = clientLocation.x();
110     m_clientY = clientLocation.y();
111     m_pageX = adjustedPageLocation.x();
112     m_pageY = adjustedPageLocation.y();
113 
114     initCoordinates();
115 }
116 
initCoordinates()117 void MouseRelatedEvent::initCoordinates()
118 {
119     // Set up initial values for coordinates.
120     // Correct values are computed lazily, see computeRelativePosition.
121     m_layerX = m_pageX;
122     m_layerY = m_pageY;
123     m_offsetX = m_pageX;
124     m_offsetY = m_pageY;
125 
126     computePageLocation();
127     m_hasCachedRelativePosition = false;
128 }
129 
initCoordinates(int clientX,int clientY)130 void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
131 {
132     // Set up initial values for coordinates.
133     // Correct values are computed lazily, see computeRelativePosition.
134     m_clientX = clientX;
135     m_clientY = clientY;
136     m_pageX = clientX + contentsX(view());
137     m_pageY = clientY + contentsY(view());
138     m_layerX = m_pageX;
139     m_layerY = m_pageY;
140     m_offsetX = m_pageX;
141     m_offsetY = m_pageY;
142 
143     computePageLocation();
144     m_hasCachedRelativePosition = false;
145 }
146 
pageZoomFactor(const UIEvent * event)147 static float pageZoomFactor(const UIEvent* event)
148 {
149     DOMWindow* window = event->view();
150     if (!window)
151         return 1;
152     Frame* frame = window->frame();
153     if (!frame)
154         return 1;
155     return frame->pageZoomFactor();
156 }
157 
computePageLocation()158 void MouseRelatedEvent::computePageLocation()
159 {
160     float zoomFactor = pageZoomFactor(this);
161     setAbsoluteLocation(roundedIntPoint(FloatPoint(pageX() * zoomFactor, pageY() * zoomFactor)));
162 }
163 
receivedTarget()164 void MouseRelatedEvent::receivedTarget()
165 {
166     m_hasCachedRelativePosition = false;
167 }
168 
computeRelativePosition()169 void MouseRelatedEvent::computeRelativePosition()
170 {
171     Node* targetNode = target() ? target()->toNode() : 0;
172     if (!targetNode)
173         return;
174 
175     // Compute coordinates that are based on the target.
176     m_layerX = m_pageX;
177     m_layerY = m_pageY;
178     m_offsetX = m_pageX;
179     m_offsetY = m_pageY;
180 
181     // Must have an updated render tree for this math to work correctly.
182     targetNode->document()->updateStyleIfNeeded();
183 
184     // Adjust offsetX/Y to be relative to the target's position.
185     if (!isSimulated()) {
186         if (RenderObject* r = targetNode->renderer()) {
187             FloatPoint localPos = r->absoluteToLocal(absoluteLocation(), false, true);
188             float zoomFactor = pageZoomFactor(this);
189             m_offsetX = lroundf(localPos.x() / zoomFactor);
190             m_offsetY = lroundf(localPos.y() / zoomFactor);
191         }
192     }
193 
194     // Adjust layerX/Y to be relative to the layer.
195     // FIXME: We're pretty sure this is the wrong definition of "layer."
196     // Our RenderLayer is a more modern concept, and layerX/Y is some
197     // other notion about groups of elements (left over from the Netscape 4 days?);
198     // we should test and fix this.
199     Node* n = targetNode;
200     while (n && !n->renderer())
201         n = n->parentNode();
202 
203     RenderLayer* layer;
204     if (n && (layer = n->renderer()->enclosingLayer())) {
205         layer->updateLayerPosition();
206         for (; layer; layer = layer->parent()) {
207             m_layerX -= layer->x();
208             m_layerY -= layer->y();
209         }
210     }
211 
212     m_hasCachedRelativePosition = true;
213 }
214 
layerX()215 int MouseRelatedEvent::layerX()
216 {
217     if (!m_hasCachedRelativePosition)
218         computeRelativePosition();
219     return m_layerX;
220 }
221 
layerY()222 int MouseRelatedEvent::layerY()
223 {
224     if (!m_hasCachedRelativePosition)
225         computeRelativePosition();
226     return m_layerY;
227 }
228 
offsetX()229 int MouseRelatedEvent::offsetX()
230 {
231     if (!m_hasCachedRelativePosition)
232         computeRelativePosition();
233     return m_offsetX;
234 }
235 
offsetY()236 int MouseRelatedEvent::offsetY()
237 {
238     if (!m_hasCachedRelativePosition)
239         computeRelativePosition();
240     return m_offsetY;
241 }
242 
pageX() const243 int MouseRelatedEvent::pageX() const
244 {
245     return m_pageX;
246 }
247 
pageY() const248 int MouseRelatedEvent::pageY() const
249 {
250     return m_pageY;
251 }
252 
x() const253 int MouseRelatedEvent::x() const
254 {
255     // FIXME: This is not correct.
256     // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
257     return m_clientX;
258 }
259 
y() const260 int MouseRelatedEvent::y() const
261 {
262     // FIXME: This is not correct.
263     // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
264     return m_clientY;
265 }
266 
267 } // namespace WebCore
268