Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 2001 Peter Kelly (pmk (at) post.com)
      3  * Copyright (C) 2001 Tobias Anton (anton (at) stud.fbi.fh-darmstadt.de)
      4  * Copyright (C) 2006 Samuel Weinig (sam.weinig (at) 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 
     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 
     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() / frame->pageZoomFactor();
     61 }
     62 
     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() / frame->pageZoomFactor();
     74 }
     75 
     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 
     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     computePageLocation();
    102 }
    103 
    104 void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
    105 {
    106     // Set up initial values for coordinates.
    107     // Correct values can't be computed until we have at target, so receivedTarget
    108     // does the "real" computation.
    109     m_clientX = clientX;
    110     m_clientY = clientY;
    111     m_pageX = clientX + contentsX(view());
    112     m_pageY = clientY + contentsY(view());
    113     m_layerX = m_pageX;
    114     m_layerY = m_pageY;
    115     m_offsetX = m_pageX;
    116     m_offsetY = m_pageY;
    117 
    118     computePageLocation();
    119 }
    120 
    121 void MouseRelatedEvent::computePageLocation()
    122 {
    123     float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
    124     setAbsoluteLocation(roundedIntPoint(FloatPoint(pageX() * zoomFactor, pageY() * zoomFactor)));
    125 }
    126 
    127 void MouseRelatedEvent::receivedTarget()
    128 {
    129     ASSERT(target());
    130     Node* targ = target()->toNode();
    131     if (!targ)
    132         return;
    133 
    134     // Compute coordinates that are based on the target.
    135     m_layerX = m_pageX;
    136     m_layerY = m_pageY;
    137     m_offsetX = m_pageX;
    138     m_offsetY = m_pageY;
    139 
    140     // Must have an updated render tree for this math to work correctly.
    141     targ->document()->updateStyleIfNeeded();
    142 
    143     // Adjust offsetX/Y to be relative to the target's position.
    144     if (!isSimulated()) {
    145         if (RenderObject* r = targ->renderer()) {
    146             FloatPoint localPos = r->absoluteToLocal(absoluteLocation(), false, true);
    147             float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
    148             m_offsetX = lroundf(localPos.x() / zoomFactor);
    149             m_offsetY = lroundf(localPos.y() / zoomFactor);
    150         }
    151     }
    152 
    153     // Adjust layerX/Y to be relative to the layer.
    154     // FIXME: We're pretty sure this is the wrong definition of "layer."
    155     // Our RenderLayer is a more modern concept, and layerX/Y is some
    156     // other notion about groups of elements (left over from the Netscape 4 days?);
    157     // we should test and fix this.
    158     Node* n = targ;
    159     while (n && !n->renderer())
    160         n = n->parent();
    161     if (n) {
    162         RenderLayer* layer = n->renderer()->enclosingLayer();
    163         layer->updateLayerPosition();
    164         for (; layer; layer = layer->parent()) {
    165             m_layerX -= layer->x();
    166             m_layerY -= layer->y();
    167         }
    168     }
    169 }
    170 
    171 int MouseRelatedEvent::pageX() const
    172 {
    173     return m_pageX;
    174 }
    175 
    176 int MouseRelatedEvent::pageY() const
    177 {
    178     return m_pageY;
    179 }
    180 
    181 int MouseRelatedEvent::x() const
    182 {
    183     // FIXME: This is not correct.
    184     // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
    185     return m_clientX;
    186 }
    187 
    188 int MouseRelatedEvent::y() const
    189 {
    190     // FIXME: This is not correct.
    191     // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
    192     return m_clientY;
    193 }
    194 
    195 } // namespace WebCore
    196