Align Element.ScrollIntoView() with the spec.

This also removes the (unused) shadow alias from nsIDOMHTMLElement
which used the different calling convention.

This resolves #927
This commit is contained in:
wolfbeast 2019-01-08 17:35:24 +01:00 • committed by Roy Tam
commit 14ea8bb121
5 changed files with 56 additions and 25 deletions

View file

@ -687,19 +687,23 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, bool aFlushLayout)
} }
void void
Element::ScrollIntoView() Element::ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject)
{ {
ScrollIntoView(ScrollIntoViewOptions()); if (aObject.IsScrollIntoViewOptions()) {
} return ScrollIntoView(aObject.GetAsScrollIntoViewOptions());
void
Element::ScrollIntoView(bool aTop)
{
ScrollIntoViewOptions options;
if (!aTop) {
options.mBlock = ScrollLogicalPosition::End;
} }
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 void
@ -716,9 +720,41 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
return; return;
} }
int16_t vpercent = (aOptions.mBlock == ScrollLogicalPosition::Start) int16_t vpercent = nsIPresShell::SCROLL_CENTER;
? nsIPresShell::SCROLL_TOP switch (aOptions.mBlock) {
: nsIPresShell::SCROLL_BOTTOM; 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; uint32_t flags = nsIPresShell::SCROLL_OVERFLOW_HIDDEN;
if (aOptions.mBehavior == ScrollBehavior::Smooth) { if (aOptions.mBehavior == ScrollBehavior::Smooth) {
@ -731,7 +767,9 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
nsIPresShell::ScrollAxis( nsIPresShell::ScrollAxis(
vpercent, vpercent,
nsIPresShell::SCROLL_ALWAYS), nsIPresShell::SCROLL_ALWAYS),
nsIPresShell::ScrollAxis(), nsIPresShell::ScrollAxis(
hpercent,
nsIPresShell::SCROLL_ALWAYS),
flags); flags);
} }

View file

@ -818,9 +818,10 @@ public:
return slots ? slots->mShadowRoot.get() : nullptr; return slots ? slots->mShadowRoot.get() : nullptr;
} }
void ScrollIntoView(); private:
void ScrollIntoView(bool aTop);
void ScrollIntoView(const ScrollIntoViewOptions &aOptions); void ScrollIntoView(const ScrollIntoViewOptions &aOptions);
public:
void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject);
void Scroll(double aXScroll, double aYScroll); void Scroll(double aXScroll, double aYScroll);
void Scroll(const ScrollToOptions& aOptions); void Scroll(const ScrollToOptions& aOptions);
void ScrollTo(double aXScroll, double aYScroll); void ScrollTo(double aXScroll, double aYScroll);

View file

@ -396,13 +396,6 @@ public:
} }
NS_IMETHOD InsertAdjacentHTML(const nsAString& position, NS_IMETHOD InsertAdjacentHTML(const nsAString& position,
const nsAString& text) final override; const nsAString& text) final override;
NS_IMETHOD ScrollIntoView(bool top, uint8_t _argc) final override {
if (!_argc) {
top = true;
}
mozilla::dom::Element::ScrollIntoView(top);
return NS_OK;
}
NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent) NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent)
final override { final override {
mozilla::dom::Element* offsetParent = GetOffsetParent(); mozilla::dom::Element* offsetParent = GetOffsetParent();

View file

@ -58,7 +58,6 @@ interface nsIDOMHTMLElement : nsIDOMElement
// CSSOM View // CSSOM View
[optional_argc] void scrollIntoView([optional] in boolean top);
readonly attribute nsIDOMElement offsetParent; readonly attribute nsIDOMElement offsetParent;
readonly attribute long offsetTop; readonly attribute long offsetTop;
readonly attribute long offsetLeft; readonly attribute long offsetLeft;

View file

@ -164,9 +164,10 @@ interface Element : Node {
}; };
// http://dev.w3.org/csswg/cssom-view/ // http://dev.w3.org/csswg/cssom-view/
enum ScrollLogicalPosition { "start", "end" }; enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
dictionary ScrollIntoViewOptions : ScrollOptions { dictionary ScrollIntoViewOptions : ScrollOptions {
ScrollLogicalPosition block = "start"; ScrollLogicalPosition block = "start";
ScrollLogicalPosition inline = "nearest";
}; };
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface // http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
@ -175,8 +176,7 @@ partial interface Element {
DOMRect getBoundingClientRect(); DOMRect getBoundingClientRect();
// scrolling // scrolling
void scrollIntoView(boolean top); void scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg);
void scrollIntoView(optional ScrollIntoViewOptions options);
// None of the CSSOM attributes are [Pure], because they flush // None of the CSSOM attributes are [Pure], because they flush
attribute long scrollTop; // scroll on setting attribute long scrollTop; // scroll on setting
attribute long scrollLeft; // scroll on setting attribute long scrollLeft; // scroll on setting