зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1389274 - Correct the behavior of Element.scrollIntoView to match the draft spec and pass web platform tests; r=annevk,bkelly
MozReview-Commit-ID: 3is36wstsdb --HG-- extra : rebase_source : f4a7598aad5b04a2dcaf40d09ee7733b4d6982f6
This commit is contained in:
Родитель
f39cc5cc25
Коммит
cdaa875696
|
@ -728,19 +728,23 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, FlushType aFlushType)
|
|||
}
|
||||
|
||||
void
|
||||
Element::ScrollIntoView()
|
||||
Element::ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject)
|
||||
{
|
||||
ScrollIntoView(ScrollIntoViewOptions());
|
||||
}
|
||||
|
||||
void
|
||||
Element::ScrollIntoView(bool aTop)
|
||||
{
|
||||
ScrollIntoViewOptions options;
|
||||
if (!aTop) {
|
||||
options.mBlock = ScrollLogicalPosition::End;
|
||||
if (aObject.IsScrollIntoViewOptions()) {
|
||||
return ScrollIntoView(aObject.GetAsScrollIntoViewOptions());
|
||||
}
|
||||
ScrollIntoView(options);
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(aObject.IsBoolean());
|
||||
|
||||
ScrollIntoViewOptions options;
|
||||
if (aObject.GetAsBoolean()) {
|
||||
options.mBlock = ScrollLogicalPosition::Start;
|
||||
options.mInline = ScrollLogicalPosition::Nearest;
|
||||
} else {
|
||||
options.mBlock = ScrollLogicalPosition::End;
|
||||
options.mInline = ScrollLogicalPosition::Nearest;
|
||||
}
|
||||
return ScrollIntoView(options);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -757,9 +761,41 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
|
|||
return;
|
||||
}
|
||||
|
||||
int16_t vpercent = (aOptions.mBlock == ScrollLogicalPosition::Start)
|
||||
? nsIPresShell::SCROLL_TOP
|
||||
: nsIPresShell::SCROLL_BOTTOM;
|
||||
int16_t vpercent = nsIPresShell::SCROLL_CENTER;
|
||||
switch (aOptions.mBlock) {
|
||||
case ScrollLogicalPosition::Start:
|
||||
vpercent = nsIPresShell::SCROLL_TOP;
|
||||
break;
|
||||
case ScrollLogicalPosition::Center:
|
||||
vpercent = nsIPresShell::SCROLL_CENTER;
|
||||
break;
|
||||
case ScrollLogicalPosition::End:
|
||||
vpercent = nsIPresShell::SCROLL_BOTTOM;
|
||||
break;
|
||||
case ScrollLogicalPosition::Nearest:
|
||||
vpercent = nsIPresShell::SCROLL_MINIMUM;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value");
|
||||
}
|
||||
|
||||
int16_t hpercent = nsIPresShell::SCROLL_CENTER;
|
||||
switch (aOptions.mInline) {
|
||||
case ScrollLogicalPosition::Start:
|
||||
hpercent = nsIPresShell::SCROLL_LEFT;
|
||||
break;
|
||||
case ScrollLogicalPosition::Center:
|
||||
hpercent = nsIPresShell::SCROLL_CENTER;
|
||||
break;
|
||||
case ScrollLogicalPosition::End:
|
||||
hpercent = nsIPresShell::SCROLL_RIGHT;
|
||||
break;
|
||||
case ScrollLogicalPosition::Nearest:
|
||||
hpercent = nsIPresShell::SCROLL_MINIMUM;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value");
|
||||
}
|
||||
|
||||
uint32_t flags = nsIPresShell::SCROLL_OVERFLOW_HIDDEN;
|
||||
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
|
||||
|
@ -772,7 +808,9 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
|
|||
nsIPresShell::ScrollAxis(
|
||||
vpercent,
|
||||
nsIPresShell::SCROLL_ALWAYS),
|
||||
nsIPresShell::ScrollAxis(),
|
||||
nsIPresShell::ScrollAxis(
|
||||
hpercent,
|
||||
nsIPresShell::SCROLL_ALWAYS),
|
||||
flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -1079,9 +1079,10 @@ public:
|
|||
return slots ? slots->mShadowRoot.get() : nullptr;
|
||||
}
|
||||
|
||||
void ScrollIntoView();
|
||||
void ScrollIntoView(bool aTop);
|
||||
private:
|
||||
void ScrollIntoView(const ScrollIntoViewOptions &aOptions);
|
||||
public:
|
||||
void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject);
|
||||
void Scroll(double aXScroll, double aYScroll);
|
||||
void Scroll(const ScrollToOptions& aOptions);
|
||||
void ScrollTo(double aXScroll, double aYScroll);
|
||||
|
|
|
@ -171,9 +171,10 @@ interface Element : Node {
|
|||
};
|
||||
|
||||
// http://dev.w3.org/csswg/cssom-view/
|
||||
enum ScrollLogicalPosition { "start", "end" };
|
||||
enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
|
||||
dictionary ScrollIntoViewOptions : ScrollOptions {
|
||||
ScrollLogicalPosition block = "start";
|
||||
ScrollLogicalPosition inline = "nearest";
|
||||
};
|
||||
|
||||
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
|
||||
|
@ -182,8 +183,7 @@ partial interface Element {
|
|||
DOMRect getBoundingClientRect();
|
||||
|
||||
// scrolling
|
||||
void scrollIntoView(boolean top);
|
||||
void scrollIntoView(optional ScrollIntoViewOptions options);
|
||||
void scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg);
|
||||
// None of the CSSOM attributes are [Pure], because they flush
|
||||
attribute long scrollTop; // scroll on setting
|
||||
attribute long scrollLeft; // scroll on setting
|
||||
|
|
|
@ -337739,12 +337739,6 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"cssom-view/scrollIntoView-empty-args.html": [
|
||||
[
|
||||
"/cssom-view/scrollIntoView-empty-args.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"cssom-view/scrollIntoView-shadow.html": [
|
||||
[
|
||||
"/cssom-view/scrollIntoView-shadow.html",
|
||||
|
@ -578704,10 +578698,6 @@
|
|||
"987051cdbad355cbb1bbb8ea1030a3b17e533f09",
|
||||
"manual"
|
||||
],
|
||||
"cssom-view/scrollIntoView-empty-args.html": [
|
||||
"57e22136750f54145c37722674389590b7f340b6",
|
||||
"testharness"
|
||||
],
|
||||
"cssom-view/scrollIntoView-shadow.html": [
|
||||
"3c4a18992105fd7bf19cbf29f0b6d80cb12ca98c",
|
||||
"testharness"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
[scrollIntoView-empty-args.html]
|
||||
type: testharness
|
||||
[scrollIntoView should behave correctly when the arg is not fully specified as ScrollIntoViewOptions]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView should behave correctly when the arg is [object Object\]]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView should behave correctly when the arg is null]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
[scrollIntoView-shadow.html]
|
||||
type: testharness
|
||||
[scrollIntoView should behave correctly if applies to shadow dom elements]
|
||||
expected: FAIL
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1293844
|
||||
expected:
|
||||
if stylo: FAIL
|
||||
PASS
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
[scrollIntoView-smooth.html]
|
||||
type: testharness
|
||||
[Smooth scrollIntoView should scroll the element to the 'nearest' position]
|
||||
expected: FAIL
|
||||
|
||||
[Smooth scrollIntoView should scroll the element to the 'start' position]
|
||||
expected: FAIL
|
||||
|
||||
[Smooth scrollIntoView should scroll the element to the 'center' position]
|
||||
expected: FAIL
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
[scrollintoview.html]
|
||||
type: testharness
|
||||
[scrollIntoView({block: "center", inline: "center"}) starting at left,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "center", inline: "center"}) starting at left,bottom]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "center", inline: "center"}) starting at right,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "center", inline: "center"}) starting at right,bottom]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "start", inline: "start"}) starting at left,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "start", inline: "start"}) starting at left,bottom]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "end", inline: "end"}) starting at right,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "end", inline: "end"}) starting at right,bottom]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "nearest", inline: "nearest"}) starting at left,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "nearest", inline: "nearest"}) starting at left,bottom]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "nearest", inline: "nearest"}) starting at right,top]
|
||||
expected: FAIL
|
||||
|
||||
[scrollIntoView({block: "nearest", inline: "nearest"}) starting at right,bottom]
|
||||
expected: FAIL
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Check End Position of scrollIntoView when arg is not fully specified</title>
|
||||
|
||||
<style>
|
||||
#container {
|
||||
position: relative;
|
||||
height: 1000px;
|
||||
width: 800px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#content {
|
||||
position: absolute;
|
||||
height: 500px;
|
||||
width: 400px;
|
||||
left: 1000px;
|
||||
top: 1000px;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="container">
|
||||
<div id="filler" style="height: 2500px; width: 2500px"></div>
|
||||
<div id="content">I must become visible</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
add_completion_callback(() => document.getElementById("container").remove());
|
||||
var content = document.getElementById("content");
|
||||
var container = document.getElementById("container");
|
||||
|
||||
var remaining_width = container.clientWidth - content.clientWidth;
|
||||
var remaining_height = container.clientHeight - content.clientHeight;
|
||||
|
||||
function instantScrollToTestArgs(arg, expected_x, expected_y) {
|
||||
test(t => {
|
||||
container.scrollTop = container.scrollLeft = 0;
|
||||
|
||||
assert_not_equals(container.scrollLeft, expected_x);
|
||||
assert_not_equals(container.scrollTop, expected_y);
|
||||
if (arg == "omitted")
|
||||
content.scrollIntoView();
|
||||
else
|
||||
content.scrollIntoView(arg);
|
||||
assert_approx_equals(container.scrollTop, expected_y, 1, "verify scroll top");
|
||||
assert_approx_equals(container.scrollLeft, expected_x, 1, "verify scroll left");
|
||||
|
||||
}, "scrollIntoView should behave correctly when the arg is " + arg);
|
||||
}
|
||||
|
||||
// expected alignment: inline => nearest, block => start
|
||||
instantScrollToTestArgs("omitted",
|
||||
content.offsetLeft - remaining_width,
|
||||
content.offsetTop);
|
||||
|
||||
// expected alignment: inline => nearest, block => start
|
||||
instantScrollToTestArgs(true,
|
||||
content.offsetLeft - remaining_width,
|
||||
content.offsetTop);
|
||||
|
||||
// expected alignment: inline => nearest, block => end
|
||||
instantScrollToTestArgs(false,
|
||||
content.offsetLeft - remaining_width,
|
||||
content.offsetTop - remaining_height);
|
||||
|
||||
// expected alignment: inline => center, block => center
|
||||
instantScrollToTestArgs({},
|
||||
content.offsetLeft - remaining_width / 2,
|
||||
content.offsetTop - remaining_height / 2);
|
||||
|
||||
// expected alignment: inline => center, block => center
|
||||
instantScrollToTestArgs(null,
|
||||
content.offsetLeft - remaining_width / 2,
|
||||
content.offsetTop - remaining_height / 2);
|
||||
|
||||
// expected alignment: inline => nearest, block => start
|
||||
instantScrollToTestArgs(undefined,
|
||||
content.offsetLeft - remaining_width,
|
||||
content.offsetTop);
|
||||
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче