Bug 1012752 - Snap scrolled area to layer pixels. r=tnikkel

We want the maximum scroll position to be aligned with layer pixels. That way
we don't have to re-rasterize the scrolled contents once scrolling hits the
edge of the scrollable area.

Here's how we determine the maximum scroll position: We get the scroll port
rect, snapped to layer pixels. Then we get the scrolled rect and also snap
that to layer pixels. The maximum scroll position is set to the difference
between right/bottom edges of these rectangles.
Now the scrollable area is computed by adding this maximum scroll position
to the unsnapped scroll port size.
The underlying idea here is: Pretend we have overflow:visible so that the
scrolled contents start at (0, 0) relative to the scroll port and spill over
the scroll port edges. When these contents are rendered, their rendering is
snapped to layer pixels. We want those exact pixels to be accessible by
scrolling.

This way of computing the snapped scrollable area ensures that, if you scroll
to the maximum scroll position, the right/bottom edges of the rendered
scrolled contents line up exactly with the right/bottom edges of the scroll
port. The scrolled contents are neither cut off nor are they moved too far.
(This is something that no other browser engine gets completely right, see the
testcase in bug 1012752.)

There are also a few disadvantages to this solution. We snap to layer pixels,
and the size of a layer pixel can depend on the zoom level, the document
resolution, the current screen's scale factor, and CSS transforms. The snap
origin is the position of the reference frame. So a change to any of these
things can influence the scrollable area and the maximum scroll position.
This patch does not make us adjust the current scroll position in the event
that the maximum scroll position changes such that the current scroll position
would be out of range, unless there's a reflow of the scrolled contents. This
means that we can sometimes render a slightly inconsistent state where the
current scroll position exceeds the maximum scroll position. We can fix this
once it turns out to be a problem; I doubt that it will be a problem because
none of the other browsers seems to prevent this problem either.

The size of the scrollable area is exposed through the DOM properties
scrollWidth and scrollHeight. At the moment, these are integer properties, so
their value is rounded to the nearest CSS pixel. Before this patch, the
returned value would always be within 0.5 CSS pixels of the value that layout
computed for the content's scrollable overflow based on the CSS styles of the
contents.
Now that scrollWidth and scrollHeight also depend on pixel snapping, their
values can deviate by up to one layer pixel from what the page might expect
based on the styles of the contents. This change requires a few changes to
existing tests.
The fact that scrollWidth and scrollHeight can change based on the position of
the scrollable element and the zoom level / resolution may surprise some web
pages. However, this also seems to happen in Edge. Edge seems to always round
scrollWidth and scrollHeight upwards, possibly to their equivalent of layout
device pixels.

MozReview-Commit-ID: 3LFV7Lio4tG

--HG--
extra : histedit_source : 5390eeebfe9a2791d9ac8e91ec1dfec4ec7b4118
This commit is contained in:
Markus Stange 2016-06-02 15:41:51 -04:00
Родитель cfa0d595fb
Коммит f8e66e0cdf
13 изменённых файлов: 299 добавлений и 19 удалений

Просмотреть файл

@ -37,9 +37,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=332246
/** Test for Bug 332246 **/
function isWithFuzz(itIs, itShouldBe, fuzz, description) {
ok(Math.abs(itIs - itShouldBe) <= fuzz, `${description} - expected a value between ${itShouldBe - fuzz} and ${itShouldBe + fuzz}, got ${itIs}`);
}
var a1 = document.getElementById('a1');
var a2 = document.getElementById('a2');
is(a1.scrollHeight, 400, "Wrong a1.scrollHeight");
isWithFuzz(a1.scrollHeight, 400, 1, "Wrong a1.scrollHeight");
is(a1.offsetHeight, 100, "Wrong a1.offsetHeight");
a2.scrollIntoView(true);
is(a1.scrollTop, 100, "Wrong scrollTop value after a2.scrollIntoView(true)");
@ -48,7 +52,7 @@ is(a1.scrollTop, 200, "Wrong scrollTop value after a2.scrollIntoView(false)");
var b1 = document.getElementById('b1');
var b2 = document.getElementById('b2');
is(b1.scrollHeight, 420, "Wrong b1.scrollHeight");
isWithFuzz(b1.scrollHeight, 420, 1, "Wrong b1.scrollHeight");
is(b1.offsetHeight, 100, "Wrong b1.offsetHeight");
b2.scrollIntoView(true);
is(b1.scrollTop, 100, "Wrong scrollTop value after b2.scrollIntoView(true)");
@ -57,12 +61,12 @@ is(b1.scrollTop, 220, "Wrong scrollTop value after b2.scrollIntoView(false)");
var c1 = document.getElementById('c1');
var c2 = document.getElementById('c2');
is(c1.scrollHeight, 320, "Wrong c1.scrollHeight");
isWithFuzz(c1.scrollHeight, 320, 1, "Wrong c1.scrollHeight");
is(c1.offsetHeight, 100, "Wrong c1.offsetHeight");
c2.scrollIntoView(true);
is(c1.scrollTop, 100, "Wrong scrollTop value after c2.scrollIntoView(true)");
c2.scrollIntoView(false);
is(c1.scrollTop, 220, "Wrong scrollTop value after c2.scrollIntoView(false)");
isWithFuzz(c1.scrollTop, 220, 1, "Wrong scrollTop value after c2.scrollIntoView(false)");
</script>
</pre>

Просмотреть файл

@ -12,8 +12,12 @@
}
</style>
</head>
<!-- We set a transform on the body element so that it creates a reference frame.
This makes sure that snapping of scrolled areas for the contained elements
is not influenced by offsets outside of this document. -->
<body id="body" onload="setTimeout(testElements, 0, 'testelements', SimpleTest.finish);"
style="margin: 1px; border: 2px solid black; padding: 4px;">
style="margin: 1px; border: 2px solid black; padding: 4px; transform: translateY(1px);">
<div id="testelements" style="margin: 0; border: 0; padding: 0;">
<div id="div1" style="margin: 0; margin-left: 6px; margin-top: 2px; border: 1px solid green; padding: 6px; width: 50px; height: 20px"
@ -55,7 +59,7 @@
</div>
<div id="scrollbox"
style="overflow: scroll; padding-left: 0px; margin: 3px; border: 4px solid green; max-width: 80px; max-height: 70px;"
style="overflow: scroll; padding-left: 0px; margin: 3px; border: 4px solid green; max-width: 80px; max-height: 70px"
_scrollWidth="62" _scrollHeight="32"
_clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32"><p id="p1" style="margin: 0; padding: 0;">One</p>
<p id="p2">Two</p>

Просмотреть файл

@ -181,12 +181,25 @@ function checkCoord(element, type, val, testname)
is(element[type], Math.round(val), testname + " " + type);
}
function checkCoordFuzzy(element, type, val, fuzz, testname)
{
if (val != -10000)
ok(Math.abs(element[type] - Math.round(val)) <= fuzz, testname + " " + type);
}
function checkCoords(element, type, left, top, width, height, testname)
{
checkCoord(element, type + "Left", left, testname);
checkCoord(element, type + "Top", top, testname);
checkCoord(element, type + "Width", width, testname);
checkCoord(element, type + "Height", height, testname);
if (type == "scroll") {
// scrollWidth and scrollHeight can deviate by 1 pixel due to snapping.
checkCoordFuzzy(element, type + "Width", width, 1, testname);
checkCoordFuzzy(element, type + "Height", height, 1, testname);
} else {
checkCoord(element, type + "Width", width, testname);
checkCoord(element, type + "Height", height, testname);
}
if (element instanceof SVGElement)
return;

Просмотреть файл

@ -5,6 +5,7 @@
#include "nsRect.h"
#include "mozilla/gfx/Types.h" // for NS_SIDE_BOTTOM, etc
#include "mozilla/CheckedInt.h" // for CheckedInt
#include "nsDeviceContext.h" // for nsDeviceContext
#include "nsString.h" // for nsAutoString, etc
#include "nsMargin.h" // for nsMargin
@ -20,6 +21,19 @@ const mozilla::gfx::IntRect& GetMaxSizedIntRect() {
return r;
}
bool nsRect::Overflows() const {
#ifdef NS_COORD_IS_FLOAT
return false;
#else
mozilla::CheckedInt<int32_t> xMost = this->x;
xMost += this->width;
mozilla::CheckedInt<int32_t> yMost = this->y;
yMost += this->height;
return !xMost.isValid() || !yMost.isValid();
#endif
}
#ifdef DEBUG
// Diagnostics

Просмотреть файл

@ -129,6 +129,9 @@ struct nsRect :
*this = aRect1.SaturatingUnionEdges(aRect2);
}
// Return whether this rect's right or bottom edge overflow int32.
bool Overflows() const;
/**
* Return this rect scaled to a different appunits per pixel (APP) ratio.
* In the RoundOut version we make the rect the smallest rect containing the

Просмотреть файл

@ -5621,6 +5621,13 @@ ScrollFrameHelper::GetBorderRadii(const nsSize& aFrameSize,
return true;
}
static nscoord
SnapCoord(nscoord aCoord, double aRes, nscoord aAppUnitsPerPixel)
{
double snappedToLayerPixels = NS_round((aRes*aCoord)/aAppUnitsPerPixel);
return NSToCoordRoundWithClamp(snappedToLayerPixels*aAppUnitsPerPixel/aRes);
}
nsRect
ScrollFrameHelper::GetScrolledRect() const
{
@ -5634,30 +5641,82 @@ ScrollFrameHelper::GetScrolledRect() const
if (result.height < mScrollPort.height) {
NS_WARNING("Scrolled rect smaller than scrollport?");
}
// Expand / contract the result by up to half a layer pixel so that scrolling
// to the right / bottom edge does not change the layer pixel alignment of
// the scrolled contents.
// For that, we first convert the scroll port and the scrolled rect to rects
// relative to the reference frame, since that's the space where painting does
// snapping.
nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
nsIFrame* referenceFrame = nsLayoutUtils::GetReferenceFrame(mOuter);
nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(referenceFrame);
nsRect scrollPort(mScrollPort.TopLeft() + toReferenceFrame, scrollPortSize);
nsRect scrolledRect = result + scrollPort.TopLeft();
if (scrollPort.Overflows() || scrolledRect.Overflows()) {
return result;
}
// Now, snap the bottom right corner of both of these rects.
// We snap to layer pixels, so we need to respect the layer's scale.
nscoord appUnitsPerDevPixel = mScrolledFrame->PresContext()->AppUnitsPerDevPixel();
gfxSize scale = FrameLayerBuilder::GetPaintedLayerScaleForFrame(mScrolledFrame);
if (scale.IsEmpty()) {
scale = gfxSize(1.0f, 1.0f);
}
// Compute bounds for the scroll position, and computed the snapped scrolled
// rect from the scroll position bounds.
nscoord snappedScrolledAreaBottom = SnapCoord(scrolledRect.YMost(), scale.height, appUnitsPerDevPixel);
nscoord snappedScrollPortBottom = SnapCoord(scrollPort.YMost(), scale.height, appUnitsPerDevPixel);
nscoord maximumScrollOffsetY = snappedScrolledAreaBottom - snappedScrollPortBottom;
result.SetBottomEdge(scrollPort.height + maximumScrollOffsetY);
if (GetScrolledFrameDir() == NS_STYLE_DIRECTION_LTR) {
nscoord snappedScrolledAreaRight = SnapCoord(scrolledRect.XMost(), scale.width, appUnitsPerDevPixel);
nscoord snappedScrollPortRight = SnapCoord(scrollPort.XMost(), scale.width, appUnitsPerDevPixel);
nscoord maximumScrollOffsetX = snappedScrolledAreaRight - snappedScrollPortRight;
result.SetRightEdge(scrollPort.width + maximumScrollOffsetX);
} else {
// In RTL, the scrolled area's right edge is at scrollPort.XMost(),
// and the scrolled area's x position is zero or negative. We want
// the right edge to stay flush with the scroll port, so we snap the
// left edge.
nscoord snappedScrolledAreaLeft = SnapCoord(scrolledRect.x, scale.width, appUnitsPerDevPixel);
nscoord snappedScrollPortLeft = SnapCoord(scrollPort.x, scale.width, appUnitsPerDevPixel);
nscoord minimumScrollOffsetX = snappedScrolledAreaLeft - snappedScrollPortLeft;
result.SetLeftEdge(minimumScrollOffsetX);
}
return result;
}
nsRect
ScrollFrameHelper::GetScrolledRectInternal(const nsRect& aScrolledFrameOverflowArea,
const nsSize& aScrollPortSize) const
{
uint8_t frameDir = IsLTR() ? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
uint8_t
ScrollFrameHelper::GetScrolledFrameDir() const
{
// If the scrolled frame has unicode-bidi: plaintext, the paragraph
// direction set by the text content overrides the direction of the frame
if (mScrolledFrame->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
nsIFrame* childFrame = mScrolledFrame->PrincipalChildList().FirstChild();
if (childFrame) {
frameDir =
(nsBidiPresUtils::ParagraphDirection(childFrame) == NSBIDI_LTR)
return (nsBidiPresUtils::ParagraphDirection(childFrame) == NSBIDI_LTR)
? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
}
}
return IsLTR() ? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
}
nsRect
ScrollFrameHelper::GetScrolledRectInternal(const nsRect& aScrolledFrameOverflowArea,
const nsSize& aScrollPortSize) const
{
return nsLayoutUtils::GetScrolledRect(mScrolledFrame,
aScrolledFrameOverflowArea,
aScrollPortSize, frameDir);
aScrollPortSize, GetScrolledFrameDir());
}
nsMargin

Просмотреть файл

@ -626,6 +626,7 @@ protected:
AsyncScrollEventType mAsyncScrollEvent;
bool HasPluginFrames();
bool HasPerspective() const;
uint8_t GetScrolledFrameDir() const;
static void EnsureFrameVisPrefsCached();
static bool sFrameVisPrefsCached;

Просмотреть файл

@ -9,7 +9,7 @@
</head>
<body>
<p id="display"></p>
<div id="outer" style="overflow:auto; height:200px; border:2px dotted black;" onscroll="doneScroll()">
<div id="outer" style="overflow:auto; height:200px; border:2px dotted black; transform: translateY(1px)" onscroll="doneScroll()">
<div id="d" style="overflow:auto; height:102px;" onscroll="doneScroll()">
<div id="inner" style="height:100.1px; border:1px solid black; background:yellow;">Hello</div>
</div>

Просмотреть файл

@ -11,7 +11,7 @@
position: absolute;
left: 200px;
top: 100px;
font: 14px/1.1em "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace;
font: 14px/1.3em "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace;
}
</style>
</head>

Просмотреть файл

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en" reftest-async-scroll>
<meta charset="utf-8">
<title>Make sure the scrolled layer is not invalidated when you scroll all the way to the bottom</title>
<style>
body {
margin: 0;
}
.scrollbox {
margin: 50px;
width: 200px;
height: 200px;
overflow: auto;
}
.scrolled-contents {
height: 150.2px;
padding-top: 150px;
}
.reftest-no-paint {
margin: 0 20px;
border: 1px solid blue;
height: 25px;
}
</style>
<body>
<div class="scrollbox"
reftest-displayport-x="0" reftest-displayport-y="0"
reftest-displayport-w="200" reftest-displayport-h="200"
reftest-async-scroll-x="0" reftest-async-scroll-y="0">
<div class="scrolled-contents">
<div class="reftest-no-paint">
<!-- This element has the magic "reftest-no-paint" class which
constitutes the actual test here. -->
</div>
</div>
</div>
<script>
var scrollbox = document.querySelector(".scrollbox");
scrollbox.scrollTop = 2;
scrollbox.scrollTop = 1;
scrollbox.scrollTop = 0;
function doTest() {
scrollbox.scrollTop = 999;
document.documentElement.removeAttribute("class");
}
document.addEventListener("MozReftestInvalidate", doTest);
</script>

Просмотреть файл

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>Fractional scroll area position / size</title>
<style>
body {
margin: 0;
}
#scrollbox {
width: 200px;
overflow: hidden;
background: red;
}
#scrolled-content {
background: lime;
box-sizing: border-box;
border: solid black;
border-width: 1px 0;
}
</style>
<div id="scrollbox">
<div id="scrolled-content"></div>
</div>
<script>
function getFloatQueryParams(defaultValues) {
let result = Object.assign({}, defaultValues);
for (let chunk of location.search.substr(1).split("&")) {
let parts = chunk.split("=");
result[parts[0]] = parseFloat(parts[1]);
}
return result;
}
let params = getFloatQueryParams({
top: 0,
outerBottom: 100,
innerBottom: 100,
borderTop: 0,
borderBottom: 0,
scrollBefore: 0,
scrollAfter: undefined,
offsetAfter: undefined,
});
let scrollArea = document.getElementById("scrollbox");
let scrolledContent = document.getElementById("scrolled-content");
scrollArea.style.marginTop = params.top + "px";
scrollArea.style.height = (params.outerBottom - params.top) + "px";
scrolledContent.style.height = (params.innerBottom - params.top) + "px";
scrollArea.scrollTop = 1;
scrollArea.scrollTop = 2;
scrollArea.scrollTop = params.scrollBefore;
window.addEventListener("MozReftestInvalidate", function () {
if (params.scrollAfter !== undefined) {
scrollArea.scrollTop = params.scrollAfter;
}
if (params.offsetAfter !== undefined) {
document.body.style.marginTop = params.offsetAfter + "px";
}
document.documentElement.className = "";
});
</script>

Просмотреть файл

@ -36,3 +36,52 @@ skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,
== frame-scrolling-attr-1.html frame-scrolling-attr-ref.html
fuzzy-if(asyncPan&&!layersGPUAccelerated,102,2420) == frame-scrolling-attr-2.html frame-scrolling-attr-ref.html
== move-item.html move-item-ref.html # bug 1125750
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
!= fractional-scroll-area-invalidation.html about:blank

Просмотреть файл

@ -22,7 +22,7 @@ skip-if(B2G||Mulet) HTTP(..) == table-cell.html table-cell-ref.html # Initial mu
skip-if(Mulet) fuzzy-if(gtkWidget,10,32) HTTP(..) == two-value-syntax.html two-value-syntax-ref.html # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables
skip-if(B2G||Mulet) HTTP(..) == single-value.html single-value-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(gtkWidget,10,2) HTTP(..) == atomic-under-marker.html atomic-under-marker-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
fuzzy(1,702) skip-if(Android||B2G||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
fuzzy(1,2616) skip-if(Android||B2G||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
HTTP(..) == combobox-zoom.html combobox-zoom-ref.html
# The vertical-text pref setting can be removed after bug 1138384 lands