Bug 1874488 - Make Element.{client,scroll} APIs zoom aware. r=saschanaz,TYLin

Also extend scroll-zoom to cover scroll{Top,Left,To,By}, since that was
completely untested.

Differential Revision: https://phabricator.services.mozilla.com/D200029
This commit is contained in:
Emilio Cobos Álvarez 2024-02-07 21:30:36 +00:00
Родитель 1b7227c33c
Коммит 3f6f4db1d8
6 изменённых файлов: 100 добавлений и 21 удалений

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

@ -826,17 +826,20 @@ void Element::ScrollTo(const ScrollToOptions& aOptions) {
aOptions.mLeft.WasPassed() ||
(aOptions.mTop.WasPassed() && aOptions.mTop.Value() != 0.0);
nsIFrame* frame;
nsIScrollableFrame* sf = GetScrollFrame(
nullptr, needsLayoutFlush ? FlushType::Layout : FlushType::Frames);
&frame, needsLayoutFlush ? FlushType::Layout : FlushType::Frames);
if (!sf) {
return;
}
CSSIntPoint scrollPos = sf->GetRoundedScrollPositionCSSPixels();
if (aOptions.mLeft.WasPassed()) {
scrollPos.x = int32_t(mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value()));
scrollPos.x = int32_t(mozilla::ToZeroIfNonfinite(
frame->Style()->EffectiveZoom().Zoom(aOptions.mLeft.Value())));
}
if (aOptions.mTop.WasPassed()) {
scrollPos.y = int32_t(mozilla::ToZeroIfNonfinite(aOptions.mTop.Value()));
scrollPos.y = int32_t(mozilla::ToZeroIfNonfinite(
frame->Style()->EffectiveZoom().Zoom(aOptions.mTop.Value())));
}
ScrollMode scrollMode = sf->IsSmoothScroll(aOptions.mBehavior)
? ScrollMode::SmoothMsd
@ -852,18 +855,21 @@ void Element::ScrollBy(double aXScrollDif, double aYScrollDif) {
}
void Element::ScrollBy(const ScrollToOptions& aOptions) {
nsIScrollableFrame* sf = GetScrollFrame();
nsIFrame* frame;
nsIScrollableFrame* sf = GetScrollFrame(&frame);
if (!sf) {
return;
}
CSSIntPoint scrollDelta;
if (aOptions.mLeft.WasPassed()) {
scrollDelta.x = int32_t(mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value()));
scrollDelta.x = int32_t(mozilla::ToZeroIfNonfinite(
frame->Style()->EffectiveZoom().Zoom(aOptions.mLeft.Value())));
}
if (aOptions.mTop.WasPassed()) {
scrollDelta.y = int32_t(mozilla::ToZeroIfNonfinite(aOptions.mTop.Value()));
scrollDelta.y = int32_t(mozilla::ToZeroIfNonfinite(
frame->Style()->EffectiveZoom().Zoom(aOptions.mTop.Value())));
}
auto scrollMode = sf->IsSmoothScroll(aOptions.mBehavior)
@ -899,11 +905,12 @@ void Element::MozScrollSnap() {
}
nsRect Element::GetScrollRange() {
nsIScrollableFrame* sf = GetScrollFrame();
nsIFrame* frame;
nsIScrollableFrame* sf = GetScrollFrame(&frame);
if (!sf) {
return nsRect();
}
return sf->GetScrollRange();
return frame->Style()->EffectiveZoom().Unzoom(sf->GetScrollRange());
}
int32_t Element::ScrollTopMin() {
@ -952,15 +959,19 @@ nsSize Element::GetScrollSize() {
} else {
size = GetScrollRectSizeForOverflowVisibleFrame(frame);
}
return size;
if (!frame) {
return size;
}
return frame->Style()->EffectiveZoom().Unzoom(size);
}
nsPoint Element::GetScrollOrigin() {
nsIScrollableFrame* sf = GetScrollFrame();
nsIFrame* frame;
nsIScrollableFrame* sf = GetScrollFrame(&frame);
if (!sf) {
return nsPoint();
}
return sf->GetScrollPosition();
return frame->Style()->EffectiveZoom().Unzoom(sf->GetScrollPosition());
}
int32_t Element::ScrollHeight() {
@ -1008,7 +1019,7 @@ nsRect Element::GetClientAreaRect() {
// The scroll port value might be expanded to the minimum scale size, we
// should limit the size to the ICB in such cases.
scrollPort.SizeTo(sf->GetLayoutSize());
return scrollPort;
return frame->Style()->EffectiveZoom().Unzoom(scrollPort);
}
if (frame &&
@ -1018,7 +1029,8 @@ nsRect Element::GetClientAreaRect() {
(!frame->StyleDisplay()->IsInlineFlow() || frame->IsReplaced())) {
// Special case code to make client area work even when there isn't
// a scroll view, see bug 180552, bug 227567.
return frame->GetPaddingRect() - frame->GetPositionIgnoringScrolling();
return frame->Style()->EffectiveZoom().Unzoom(
frame->GetPaddingRect() - frame->GetPositionIgnoringScrolling());
}
// SVG nodes reach here and just return 0

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

@ -1153,6 +1153,50 @@ inline nscoord StyleZoom::UnzoomCoord(nscoord aValue) const {
return NSToCoordRoundWithClamp(Unzoom(float(aValue)));
}
inline nsSize StyleZoom::Zoom(const nsSize& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsSize(ZoomCoord(aValue.Width()), ZoomCoord(aValue.Height()));
}
inline nsSize StyleZoom::Unzoom(const nsSize& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsSize(UnzoomCoord(aValue.Width()), UnzoomCoord(aValue.Height()));
}
inline nsPoint StyleZoom::Zoom(const nsPoint& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsPoint(ZoomCoord(aValue.X()), ZoomCoord(aValue.Y()));
}
inline nsPoint StyleZoom::Unzoom(const nsPoint& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsPoint(UnzoomCoord(aValue.X()), UnzoomCoord(aValue.Y()));
}
inline nsRect StyleZoom::Zoom(const nsRect& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsRect(ZoomCoord(aValue.X()), ZoomCoord(aValue.Y()),
ZoomCoord(aValue.Width()), ZoomCoord(aValue.Height()));
}
inline nsRect StyleZoom::Unzoom(const nsRect& aValue) const {
if (*this == ONE) {
return aValue;
}
return nsRect(UnzoomCoord(aValue.X()), UnzoomCoord(aValue.Y()),
UnzoomCoord(aValue.Width()), UnzoomCoord(aValue.Height()));
}
} // namespace mozilla
#endif

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

@ -980,6 +980,12 @@ renaming_overrides_prefixing = true
inline float Unzoom(float) const;
inline nscoord ZoomCoord(nscoord) const;
inline nscoord UnzoomCoord(nscoord) const;
inline nsSize Zoom(const nsSize&) const;
inline nsSize Unzoom(const nsSize&) const;
inline nsPoint Zoom(const nsPoint&) const;
inline nsPoint Unzoom(const nsPoint&) const;
inline nsRect Zoom(const nsRect&) const;
inline nsRect Unzoom(const nsRect&) const;
"""
"AnimationName" = """

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

@ -1,3 +0,0 @@
[client-props-zoom.html]
[Client properties for elements with css zoom 1]
expected: FAIL

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

@ -1,3 +0,0 @@
[scroll-zoom.html]
[scroll properties for elements with css zoom 1]
expected: FAIL

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

@ -58,6 +58,29 @@
assert_equals(noZoom.scrollWidth*2, scrollerWithZoomContent.scrollWidth, 'scroll width for zoomed content');
assert_equals(noZoom.scrollHeight, scrollerInZoomedElement.scrollHeight, 'scroll height for scroller in zoomed element');
assert_equals(noZoom.scrollWidth, scrollerInZoomedElement.scrollWidth, 'scroll width for scroller in zoomed element');
});
}, `scroll{Width, Height}`);
test(function() {
assert_equals(noZoom.scrollTop, 0, 'scrollTop should be 0');
assert_equals(noZoom.scrollLeft, 0, 'scrollLeft should be 0');
assert_equals(noZoom.scrollTop, withZoom.scrollTop, 'scrollTop');
assert_equals(noZoom.scrollLeft, withZoom.scrollLeft, 'scrollLeft');
noZoom.scrollTo(noZoom.scrollWidth / 2, noZoom.scrollHeight / 2);
withZoom.scrollTo(withZoom.scrollWidth / 2, withZoom.scrollHeight / 2);
assert_not_equals(noZoom.scrollTop, 0, 'scrollTop should not be 0');
assert_not_equals(noZoom.scrollLeft, 0, 'scrollLeft should not be 0');
assert_equals(noZoom.scrollTop, withZoom.scrollTop, 'scrollTop after scrollTo');
assert_equals(noZoom.scrollLeft, withZoom.scrollLeft, 'scrollLeft after scrollTo');
noZoom.scrollBy(2, 2);
withZoom.scrollBy(2, 2);
assert_equals(noZoom.scrollTop, withZoom.scrollTop, 'scrollTop after scrollBy');
assert_equals(noZoom.scrollLeft, withZoom.scrollLeft, 'scrollLeft after scrollBy');
}, `scroll{Top, Left}`);
</script>
</body>
</body>