зеркало из 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) {
|
if (!shell) {
|
||||||
return CSSIntPoint(0, 0);
|
return CSSIntPoint(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||||
if (!rootFrame) {
|
if (!rootFrame) {
|
||||||
return CSSIntPoint(0, 0);
|
return CSSIntPoint(0, 0);
|
||||||
|
@ -970,6 +969,44 @@ Event::GetClientCoords(nsPresContext* aPresContext,
|
||||||
return CSSIntPoint::FromAppUnitsRounded(pt);
|
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
|
// To be called ONLY by Event::GetType (which has the additional
|
||||||
// logic for handling user-defined events).
|
// logic for handling user-defined events).
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -141,6 +141,10 @@ public:
|
||||||
static LayoutDeviceIntPoint GetScreenCoords(nsPresContext* aPresContext,
|
static LayoutDeviceIntPoint GetScreenCoords(nsPresContext* aPresContext,
|
||||||
WidgetEvent* aEvent,
|
WidgetEvent* aEvent,
|
||||||
LayoutDeviceIntPoint aPoint);
|
LayoutDeviceIntPoint aPoint);
|
||||||
|
static CSSIntPoint GetOffsetCoords(nsPresContext* aPresContext,
|
||||||
|
WidgetEvent* aEvent,
|
||||||
|
LayoutDeviceIntPoint aPoint,
|
||||||
|
CSSIntPoint aDefaultPoint);
|
||||||
|
|
||||||
static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
|
static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
|
|
|
@ -386,6 +386,20 @@ MouseEvent::ClientY()
|
||||||
mClientPoint).y;
|
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
|
bool
|
||||||
MouseEvent::AltKey()
|
MouseEvent::AltKey()
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,8 @@ public:
|
||||||
int32_t ScreenY();
|
int32_t ScreenY();
|
||||||
int32_t ClientX();
|
int32_t ClientX();
|
||||||
int32_t ClientY();
|
int32_t ClientY();
|
||||||
|
int32_t OffsetX();
|
||||||
|
int32_t OffsetY();
|
||||||
bool CtrlKey();
|
bool CtrlKey();
|
||||||
bool ShiftKey();
|
bool ShiftKey();
|
||||||
bool AltKey();
|
bool AltKey();
|
||||||
|
|
|
@ -182,3 +182,4 @@ skip-if = buildapp == 'b2g' || e10s
|
||||||
[test_bug1096146.html]
|
[test_bug1096146.html]
|
||||||
support-files =
|
support-files =
|
||||||
bug1096146_embedded.html
|
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 screenY;
|
||||||
readonly attribute long clientX;
|
readonly attribute long clientX;
|
||||||
readonly attribute long clientY;
|
readonly attribute long clientY;
|
||||||
|
readonly attribute long offsetX;
|
||||||
|
readonly attribute long offsetY;
|
||||||
readonly attribute boolean ctrlKey;
|
readonly attribute boolean ctrlKey;
|
||||||
readonly attribute boolean shiftKey;
|
readonly attribute boolean shiftKey;
|
||||||
readonly attribute boolean altKey;
|
readonly attribute boolean altKey;
|
||||||
|
|
|
@ -2403,8 +2403,8 @@ nsLayoutUtils::TransformPoint(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
||||||
// coordinate space.
|
// coordinate space.
|
||||||
return NONINVERTIBLE_TRANSFORM;
|
return NONINVERTIBLE_TRANSFORM;
|
||||||
}
|
}
|
||||||
aPoint.x = toDevPixels.x / devPixelsPerAppUnitToFrame;
|
aPoint.x = NSToCoordRound(toDevPixels.x / devPixelsPerAppUnitToFrame);
|
||||||
aPoint.y = toDevPixels.y / devPixelsPerAppUnitToFrame;
|
aPoint.y = NSToCoordRound(toDevPixels.y / devPixelsPerAppUnitToFrame);
|
||||||
return TRANSFORM_SUCCEEDED;
|
return TRANSFORM_SUCCEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -593,6 +593,9 @@ function doTest(aTest)
|
||||||
is(gEvent[name], null, description + ": mismatch with fixed value (" + name + ")");
|
is(gEvent[name], null, description + ": mismatch with fixed value (" + name + ")");
|
||||||
} else if (aTest.todoMismatch.indexOf(name) >= 0) {
|
} else if (aTest.todoMismatch.indexOf(name) >= 0) {
|
||||||
todo_is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
|
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 {
|
} else {
|
||||||
is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
|
is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче