Bug 370492: Stop using views for event.PageX/Y, event.layerX/Y, image.x/y. r+sr=roc.

This commit is contained in:
sharparrow1@yahoo.com
2007-02-18 10:43:12 +00:00
parent af2009acd7
commit 3c6fed7935
7 changed files with 79 additions and 73 deletions

View File

@@ -45,13 +45,13 @@
#include "nsIDOMNode.h"
#include "nsIContent.h"
#include "nsContentUtils.h"
#include "nsIViewManager.h"
#include "nsIScrollableView.h"
#include "nsIWidget.h"
#include "nsIPresShell.h"
#include "nsIEventStateManager.h"
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsIScrollableFrame.h"
#include "nsIViewManager.h"
nsDOMUIEvent::nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ?
@@ -256,49 +256,42 @@ nsDOMUIEvent::InitUIEvent(const nsAString & typeArg, PRBool canBubbleArg, PRBool
}
// ---- nsDOMNSUIEvent implementation -------------------
nsPoint
nsDOMUIEvent::GetPagePoint()
{
if (((nsGUIEvent*)mEvent)->widget) {
// Native event; calculate using presentation
nsPoint pt(0, 0);
nsIScrollableFrame* scrollframe =
mPresContext->PresShell()->GetRootScrollFrameAsScrollable();
if (scrollframe)
pt += scrollframe->GetScrollPosition();
nsIFrame* rootFrame = mPresContext->PresShell()->GetRootFrame();
if (rootFrame)
pt += nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, rootFrame);
return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
}
return GetClientPoint();
}
NS_IMETHODIMP
nsDOMUIEvent::GetPageX(PRInt32* aPageX)
{
NS_ENSURE_ARG_POINTER(aPageX);
nsresult ret = NS_OK;
PRInt32 scrollX = 0;
nsIScrollableView* view = nsnull;
GetScrollInfo(&view);
if(view) {
nscoord xPos, yPos;
ret = view->GetScrollPosition(xPos, yPos);
scrollX = nsPresContext::AppUnitsToIntCSSPixels(xPos);
}
if (NS_SUCCEEDED(ret)) {
*aPageX = GetClientPoint().x + scrollX;
}
return ret;
*aPageX = GetPagePoint().x;
return NS_OK;
}
NS_IMETHODIMP
nsDOMUIEvent::GetPageY(PRInt32* aPageY)
{
NS_ENSURE_ARG_POINTER(aPageY);
nsresult ret = NS_OK;
PRInt32 scrollY = 0;
nsIScrollableView* view = nsnull;
GetScrollInfo(&view);
if(view) {
nscoord xPos, yPos;
ret = view->GetScrollPosition(xPos, yPos);
scrollY = nsPresContext::AppUnitsToIntCSSPixels(yPos);
}
if (NS_SUCCEEDED(ret)) {
*aPageY = GetClientPoint().y + scrollY;
}
return ret;
*aPageY = GetPagePoint().y;
return NS_OK;
}
NS_IMETHODIMP
@@ -379,23 +372,16 @@ nsPoint nsDOMUIEvent::GetLayerPoint() {
!mPresContext) {
return nsPoint(0,0);
}
// XXX This is supposed to be relative to the nearest view?
// Any element can have a view, not just positioned ones.
// XXX I'm not really sure this is correct; it's my best shot, though
nsIFrame* targetFrame;
nsPoint pt;
mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
while (targetFrame && !targetFrame->HasView()) {
targetFrame = targetFrame->GetParent();
}
if (targetFrame) {
pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, targetFrame);
pt.x = nsPresContext::AppUnitsToIntCSSPixels(pt.x);
pt.y = nsPresContext::AppUnitsToIntCSSPixels(pt.y);
return pt;
} else {
if (!targetFrame)
return nsPoint(0,0);
}
nsIFrame* layer = nsLayoutUtils::GetClosestLayer(targetFrame);
nsPoint pt(nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, layer));
pt.x = nsPresContext::AppUnitsToIntCSSPixels(pt.x);
pt.y = nsPresContext::AppUnitsToIntCSSPixels(pt.y);
return pt;
}
NS_IMETHODIMP
@@ -440,22 +426,6 @@ nsDOMUIEvent::GetPreventDefault(PRBool* aReturn)
return NS_OK;
}
nsresult
nsDOMUIEvent::GetScrollInfo(nsIScrollableView** aScrollableView)
{
NS_ENSURE_ARG_POINTER(aScrollableView);
if (!mPresContext) {
*aScrollableView = nsnull;
return NS_ERROR_FAILURE;
}
nsIViewManager *vm = mPresContext->GetViewManager();
if (vm)
return vm->GetRootScrollableView(aScrollableView);
return NS_OK;
}
NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
{
if((mEvent->eventStructType == NS_RECONVERSION_EVENT) ||

View File

@@ -72,10 +72,10 @@ public:
protected:
// Internal helper functions
nsresult GetScrollInfo(nsIScrollableView** aScrollableView);
nsPoint GetClientPoint();
nsPoint GetScreenPoint();
nsPoint GetLayerPoint();
nsPoint GetPagePoint();
protected:
nsCOMPtr<nsIDOMAbstractView> mView;

View File

@@ -75,6 +75,8 @@
#include "nsIDOMHTMLMapElement.h"
#include "nsEventDispatcher.h"
#include "nsLayoutUtils.h"
// XXX nav attrs: suppress
class nsHTMLImageElement : public nsGenericHTMLElement,
@@ -244,14 +246,8 @@ nsHTMLImageElement::GetXY()
return point;
}
// XXX This should search for the nearest abs. pos. container
nsPoint origin(0, 0);
nsIView* parentView;
nsresult rv = frame->GetOffsetFromView(origin, &parentView);
if (NS_FAILED(rv)) {
return point;
}
nsIFrame* layer = nsLayoutUtils::GetClosestLayer(frame->GetParent());
nsPoint origin(frame->GetOffsetTo(layer));
// Convert to pixels using that scale
point.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
point.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);

View File

@@ -94,6 +94,7 @@ class nsCSSFrameConstructor;
class nsISelection;
template<class E> class nsCOMArray;
class nsWeakFrame;
class nsIScrollableFrame;
typedef short SelectionType;
@@ -300,6 +301,11 @@ public:
*/
nsIFrame* GetRootScrollFrame() const;
/*
* The same as GetRootScrollFrame, but returns an nsIScrollableFrame
*/
nsIScrollableFrame* GetRootScrollFrameAsScrollable() const;
/**
* Returns the page sequence frame associated with the frame hierarchy.
* Returns NULL if not a paginated view.

View File

@@ -1852,3 +1852,16 @@ nsLayoutUtils::GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult)
}
return PR_FALSE;
}
/* static */ nsIFrame*
nsLayoutUtils::GetClosestLayer(nsIFrame* aFrame)
{
nsIFrame* layer;
for (layer = aFrame; layer; layer = layer->GetParent()) {
if (layer->GetStyleDisplay()->IsPositioned() ||
(layer->GetParent() &&
layer->GetParent()->GetType() == nsGkAtoms::scrollFrame))
break;
}
return layer;
}

View File

@@ -580,6 +580,16 @@ public:
* Otherwise returns false.
*/
static PRBool GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult);
/**
* Gets the closest frame (the frame passed in or one of its parents) that
* qualifies as a "layer"; used in DOM0 methods that depends upon that
* definition. This is the nearest frame that is either positioned or scrolled
* (the child of a scroll frame). In Gecko terms, it's approximately
* equivalent to having a view, at least for simple HTML. However, views are
* going away, so this is a cleaner definition.
*/
static nsIFrame* GetClosestLayer(nsIFrame* aFrame);
};
#endif // nsLayoutUtils_h__

View File

@@ -3197,6 +3197,17 @@ nsIPresShell::GetRootScrollFrame() const
return theFrame;
}
nsIScrollableFrame*
nsIPresShell::GetRootScrollFrameAsScrollable() const
{
nsIFrame* frame = GetRootScrollFrame();
if (!frame)
return nsnull;
nsIScrollableFrame* scrollableFrame = nsnull;
CallQueryInterface(frame, &scrollableFrame);
return scrollableFrame;
}
NS_IMETHODIMP
PresShell::GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const
{