зеркало из https://github.com/mozilla/gecko-dev.git
Bug 69787. Implement MouseEvent.offsetX/Y. r=mats,smaug
--HG-- extra : rebase_source : 0120fa29fb94c1c2f992b4e3bae63c5120b90f4b
This commit is contained in:
Родитель
b84e0849ec
Коммит
843379803a
|
@ -959,7 +959,6 @@ Event::GetClientCoords(nsPresContext* aPresContext,
|
|||
if (!shell) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return CSSIntPoint(0, 0);
|
||||
|
@ -970,6 +969,44 @@ Event::GetClientCoords(nsPresContext* aPresContext,
|
|||
return CSSIntPoint::FromAppUnitsRounded(pt);
|
||||
}
|
||||
|
||||
// static
|
||||
CSSIntPoint
|
||||
Event::GetOffsetCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint)
|
||||
{
|
||||
if (!aEvent->mFlags.mIsBeingDispatched) {
|
||||
return GetPageCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->target);
|
||||
if (!content) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
|
||||
if (!shell) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
shell->FlushPendingNotifications(Flush_Layout);
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
CSSIntPoint clientCoords =
|
||||
GetClientCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
nsPoint pt = CSSPixel::ToAppUnits(clientCoords);
|
||||
if (nsLayoutUtils::TransformPoint(rootFrame, frame, pt) ==
|
||||
nsLayoutUtils::TRANSFORM_SUCCEEDED) {
|
||||
pt -= frame->GetPaddingRectRelativeToSelf().TopLeft();
|
||||
return CSSPixel::FromAppUnitsRounded(pt);
|
||||
}
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
|
||||
// To be called ONLY by Event::GetType (which has the additional
|
||||
// logic for handling user-defined events).
|
||||
// static
|
||||
|
|
|
@ -141,6 +141,10 @@ public:
|
|||
static LayoutDeviceIntPoint GetScreenCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint);
|
||||
static CSSIntPoint GetOffsetCoords(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint);
|
||||
|
||||
static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
|
|
|
@ -386,6 +386,20 @@ MouseEvent::ClientY()
|
|||
mClientPoint).y;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MouseEvent::OffsetX()
|
||||
{
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
mClientPoint).x;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MouseEvent::OffsetY()
|
||||
{
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
mClientPoint).y;
|
||||
}
|
||||
|
||||
bool
|
||||
MouseEvent::AltKey()
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
int32_t ScreenY();
|
||||
int32_t ClientX();
|
||||
int32_t ClientY();
|
||||
int32_t OffsetX();
|
||||
int32_t OffsetY();
|
||||
bool CtrlKey();
|
||||
bool ShiftKey();
|
||||
bool AltKey();
|
||||
|
|
|
@ -182,3 +182,4 @@ skip-if = buildapp == 'b2g' || e10s
|
|||
[test_bug1096146.html]
|
||||
support-files =
|
||||
bug1096146_embedded.html
|
||||
[test_offsetxy.html]
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for DOM MouseEvent offsetX/Y</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<div id="d" style="position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
|
||||
<div id="d2" style="position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px; transform:translateX(100px)"></div>
|
||||
<div id="d3" style="display:none; position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
|
||||
<div id="d4" style="transform:scale(0); position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var offsetX = -1, offsetY = -1;
|
||||
var ev = new MouseEvent("click", {clientX:110, clientY:110});
|
||||
d.addEventListener("click", function (event) {
|
||||
is(ev, event, "Event objects must match");
|
||||
offsetX = event.offsetX;
|
||||
offsetY = event.offsetY;
|
||||
});
|
||||
d.dispatchEvent(ev);
|
||||
is(offsetX, 5);
|
||||
is(offsetY, 5);
|
||||
is(ev.offsetX, ev.pageX);
|
||||
is(ev.offsetY, ev.pageY);
|
||||
|
||||
var ev2 = new MouseEvent("click", {clientX:220, clientY:130});
|
||||
d2.addEventListener("click", function (event) {
|
||||
is(ev2, event, "Event objects must match");
|
||||
offsetX = event.offsetX;
|
||||
offsetY = event.offsetY;
|
||||
});
|
||||
d2.dispatchEvent(ev2);
|
||||
is(offsetX, 15);
|
||||
is(offsetY, 25);
|
||||
is(ev2.offsetX, ev2.pageX);
|
||||
is(ev2.offsetY, ev2.pageY);
|
||||
|
||||
var ev3 = new MouseEvent("click", {clientX:110, clientY:110});
|
||||
d3.addEventListener("click", function (event) {
|
||||
is(ev3, event, "Event objects must match");
|
||||
offsetX = event.offsetX;
|
||||
offsetY = event.offsetY;
|
||||
});
|
||||
d3.dispatchEvent(ev3);
|
||||
is(offsetX, 0);
|
||||
is(offsetY, 0);
|
||||
is(ev3.offsetX, ev3.pageX);
|
||||
is(ev3.offsetY, ev3.pageY);
|
||||
|
||||
var ev4 = new MouseEvent("click", {clientX:110, clientY:110});
|
||||
d4.addEventListener("click", function (event) {
|
||||
is(ev4, event, "Event objects must match");
|
||||
offsetX = event.offsetX;
|
||||
offsetY = event.offsetY;
|
||||
});
|
||||
d4.dispatchEvent(ev4);
|
||||
is(offsetX, 0);
|
||||
is(offsetY, 0);
|
||||
is(ev4.offsetX, ev4.pageX);
|
||||
is(ev4.offsetY, ev4.pageY);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -15,6 +15,8 @@ interface MouseEvent : UIEvent {
|
|||
readonly attribute long screenY;
|
||||
readonly attribute long clientX;
|
||||
readonly attribute long clientY;
|
||||
readonly attribute long offsetX;
|
||||
readonly attribute long offsetY;
|
||||
readonly attribute boolean ctrlKey;
|
||||
readonly attribute boolean shiftKey;
|
||||
readonly attribute boolean altKey;
|
||||
|
|
|
@ -2403,8 +2403,8 @@ nsLayoutUtils::TransformPoint(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
|||
// coordinate space.
|
||||
return NONINVERTIBLE_TRANSFORM;
|
||||
}
|
||||
aPoint.x = toDevPixels.x / devPixelsPerAppUnitToFrame;
|
||||
aPoint.y = toDevPixels.y / devPixelsPerAppUnitToFrame;
|
||||
aPoint.x = NSToCoordRound(toDevPixels.x / devPixelsPerAppUnitToFrame);
|
||||
aPoint.y = NSToCoordRound(toDevPixels.y / devPixelsPerAppUnitToFrame);
|
||||
return TRANSFORM_SUCCEEDED;
|
||||
}
|
||||
|
||||
|
|
|
@ -593,6 +593,9 @@ function doTest(aTest)
|
|||
is(gEvent[name], null, description + ": mismatch with fixed value (" + name + ")");
|
||||
} else if (aTest.todoMismatch.indexOf(name) >= 0) {
|
||||
todo_is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
|
||||
} else if (name == "offsetX" || name == "offsetY") {
|
||||
// do nothing; these are defined to return different values during event dispatch
|
||||
// vs not during event dispatch
|
||||
} else {
|
||||
is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче