Bug 950225 - Restrict event fluffing in visible area with test case. r=roc

This commit is contained in:
"Kan-Ru Chen (陳侃如)" 2014-01-29 21:54:25 +08:00
parent f007a4d86c
commit caedc4da28
2 changed files with 57 additions and 10 deletions

View File

@ -227,9 +227,22 @@ AppUnitsFromMM(nsIFrame* aFrame, uint32_t aMM, bool aVertical)
return NSToCoordRound(result);
}
/**
* Clip aRect with the bounds of aFrame in the coordinate system of
* aRootFrame. aRootFrame is an ancestor of aFrame.
*/
static nsRect
ClipToFrame(nsIFrame* aRootFrame, nsIFrame* aFrame, nsRect& aRect)
{
nsRect bound = nsLayoutUtils::TransformFrameRectToAncestor(
aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()), aRootFrame);
nsRect result = bound.Intersect(aRect);
return result;
}
static nsRect
GetTargetRect(nsIFrame* aRootFrame, const nsPoint& aPointRelativeToRootFrame,
const EventRadiusPrefs* aPrefs)
nsIFrame* aRestrictToDescendants, const EventRadiusPrefs* aPrefs)
{
nsMargin m(AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[0], true),
AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[1], false),
@ -237,7 +250,7 @@ GetTargetRect(nsIFrame* aRootFrame, const nsPoint& aPointRelativeToRootFrame,
AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[3], false));
nsRect r(aPointRelativeToRootFrame, nsSize(0,0));
r.Inflate(m);
return r;
return ClipToFrame(aRootFrame, aRestrictToDescendants, r);
}
static float
@ -362,13 +375,6 @@ FindFrameTargetedByInputEvent(const WidgetGUIEvent* aEvent,
return target;
}
nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame, prefs);
nsAutoTArray<nsIFrame*,8> candidates;
nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates, flags);
if (NS_FAILED(rv)) {
return target;
}
// If the exact target is non-null, only consider candidate targets in the same
// document as the exact target. Otherwise, if an ancestor document has
// a mouse event handler for example, targets that are !IsElementClickable can
@ -376,6 +382,15 @@ FindFrameTargetedByInputEvent(const WidgetGUIEvent* aEvent,
// would be targeted instead.
nsIFrame* restrictToDescendants = target ?
target->PresContext()->PresShell()->GetRootFrame() : aRootFrame;
nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
restrictToDescendants, prefs);
nsAutoTArray<nsIFrame*,8> candidates;
nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates, flags);
if (NS_FAILED(rv)) {
return target;
}
nsIFrame* closestClickable =
GetClosest(aRootFrame, aPointRelativeToRootFrame, targetRect, prefs,
restrictToDescendants, candidates);

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=780847
.target { position:absolute; left:100px; top:100px; width:100px; height:100px; background:blue; }
</style>
</head>
<body id="body" onload="setTimeout(startTest, 0)" style="margin:0; width:100%; height:100%">
<body id="body" onload="setTimeout(startTest, 0)" style="margin:0; width:100%; height:100%; overflow:hidden">
<p id="display"></p>
<div id="content">
<div id="ruler" style="position:absolute; left:0; top:0; width:1mozmm; height:0;"></div>
@ -47,6 +47,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=780847
<div id="t9" class="target" ontouchend="x=1" hidden></div>
<div id="t10_left" class="target" style="left:-50px;" onmousedown="x=1" hidden></div>
<div id="t10_right" class="target" style="left:auto;right:-50px" onmousedown="x=1" hidden></div>
<div id="t10_top" class="target" style="top:-50px;" onmousedown="x=1" hidden></div>
<div id="t10_bottom" class="target" style="top:auto;bottom:-50px;" onmousedown="x=1" hidden></div>
<div id="t10_over" style="position:absolute; left:0; top:0; width:100%; height:100%; background:yellow;" hidden></div>
</div>
<pre id="test">
<script type="application/javascript">
@ -214,6 +219,33 @@ function test3() {
});
setShowing("t9", false);
setShowing("t10_over", true);
setShowing("t10_left", true);
setShowing("t10_right", true);
setShowing("t10_top", true);
setShowing("t10_bottom", true);
testMouseClick("t10_left", 51, 10, "t10_over", "element outside of visible area is not selected");
if (self.frameElement &&
(self.frameElement.offsetLeft + self.innerWidth >
SpecialPowers.wrap(top).innerWidth)) {
info("WARNING: Window is too narrow, can't test t10_right");
} else {
testMouseClick("t10_right", 49, 10, "t10_over", "element outside of visible area is not selected");
}
testMouseClick("t10_top", 10, 51, "t10_over", "element outside of visible area is not selected");
if (self.frameElement &&
(self.frameElement.offsetTop + self.innerHeight >
SpecialPowers.wrap(top).innerHeight)) {
info("WARNING: Window is too short, can't test t10_bottom");
} else {
testMouseClick("t10_bottom", 10, 49, "t10_over", "element outside of visible area is not selected");
}
setShowing("t10_over", false);
setShowing("t10_left", false);
setShowing("t10_right", false);
setShowing("t10_top", false);
setShowing("t10_bottom", false);
// Not yet tested:
// -- visited link weight
// -- "Closest" using Euclidean distance