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 {
48 }
49
contentsX(AbstractView * abstractView)50 static int contentsX(AbstractView* abstractView)
51 {
52 if (!abstractView)
53 return 0;
54 Frame* frame = abstractView->frame();
55 if (!frame)
56 return 0;
57 FrameView* frameView = frame->view();
58 if (!frameView)
59 return 0;
60 return frameView->scrollX();
61 }
62
contentsY(AbstractView * abstractView)63 static int contentsY(AbstractView* abstractView)
64 {
65 if (!abstractView)
66 return 0;
67 Frame* frame = abstractView->frame();
68 if (!frame)
69 return 0;
70 FrameView* frameView = frame->view();
71 if (!frameView)
72 return 0;
73 return frameView->scrollY();
74 }
75
MouseRelatedEvent(const AtomicString & eventType,bool canBubble,bool cancelable,PassRefPtr<AbstractView> viewArg,int detail,int screenX,int screenY,int pageX,int pageY,bool ctrlKey,bool altKey,bool shiftKey,bool metaKey,bool isSimulated)76 MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> viewArg,
77 int detail, int screenX, int screenY, int pageX, int pageY,
78 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated)
79 : UIEventWithKeyState(eventType, canBubble, cancelable, viewArg, detail, ctrlKey, altKey, shiftKey, metaKey)
80 , m_screenX(screenX)
81 , m_screenY(screenY)
82 , m_clientX(pageX - contentsX(view()))
83 , m_clientY(pageY - contentsY(view()))
84 , m_pageX(pageX)
85 , m_pageY(pageY)
86 , m_isSimulated(isSimulated)
87 {
88 initCoordinates();
89 }
90
initCoordinates()91 void MouseRelatedEvent::initCoordinates()
92 {
93 // Set up initial values for coordinates.
94 // Correct values can't be computed until we have at target, so receivedTarget
95 // does the "real" computation.
96 m_layerX = m_pageX;
97 m_layerY = m_pageY;
98 m_offsetX = m_pageX;
99 m_offsetY = m_pageY;
100 }
101
initCoordinates(int clientX,int clientY)102 void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
103 {
104 // Set up initial values for coordinates.
105 // Correct values can't be computed until we have at target, so receivedTarget
106 // does the "real" computation.
107 m_clientX = clientX;
108 m_clientY = clientY;
109 m_pageX = clientX + contentsX(view());
110 m_pageY = clientY + contentsY(view());
111 m_layerX = m_pageX;
112 m_layerY = m_pageY;
113 m_offsetX = m_pageX;
114 m_offsetY = m_pageY;
115 }
116
receivedTarget()117 void MouseRelatedEvent::receivedTarget()
118 {
119 ASSERT(target());
120 Node* targ = target()->toNode();
121 if (!targ)
122 return;
123
124 // Compute coordinates that are based on the target.
125 m_layerX = m_pageX;
126 m_layerY = m_pageY;
127 m_offsetX = m_pageX;
128 m_offsetY = m_pageY;
129
130 // Must have an updated render tree for this math to work correctly.
131 targ->document()->updateRendering();
132
133 // Adjust offsetX/Y to be relative to the target's position.
134 if (!isSimulated()) {
135 if (RenderObject* r = targ->renderer()) {
136 FloatPoint absPos = r->absoluteToLocal(FloatPoint(m_pageX, m_pageY), false, true);
137 m_offsetX = absPos.x();
138 m_offsetY = absPos.y();
139 }
140 }
141
142 // Adjust layerX/Y to be relative to the layer.
143 // FIXME: We're pretty sure this is the wrong defintion of "layer."
144 // Our RenderLayer is a more modern concept, and layerX/Y is some
145 // other notion about groups of elements (left over from the Netscape 4 days?);
146 // we should test and fix this.
147 Node* n = targ;
148 while (n && !n->renderer())
149 n = n->parent();
150 if (n) {
151 RenderLayer* layer = n->renderer()->enclosingLayer();
152 layer->updateLayerPosition();
153 for (; layer; layer = layer->parent()) {
154 m_layerX -= layer->xPos();
155 m_layerY -= layer->yPos();
156 }
157 }
158 }
159
pageX() const160 int MouseRelatedEvent::pageX() const
161 {
162 return m_pageX;
163 }
164
pageY() const165 int MouseRelatedEvent::pageY() const
166 {
167 return m_pageY;
168 }
169
x() const170 int MouseRelatedEvent::x() const
171 {
172 // FIXME: This is not correct.
173 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
174 return m_clientX;
175 }
176
y() const177 int MouseRelatedEvent::y() const
178 {
179 // FIXME: This is not correct.
180 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
181 return m_clientY;
182 }
183
184 } // namespace WebCore
185