Take an outer scroll container A that is async-inactive because it has zero scroll range. It contains various active scroll frames and active nested scroll frames. Some content inside A (but not related to any of the active descendant scroll frames) is modified so that the size of the scrolled content increases making the scroll range non-zero and now WantAsyncScroll() is true. The size increase triggers a retained display list update. None of the descendant already-active scroll frames are marked modified, so the display list build does not visit the every active descendant scroll frame (even if we were to visit every direct ASR child of A). Visiting the frame of an ASR is the only way that we can update it to changes in the ASR tree, so some ASRs do not get updated, so the depth values get out of sync and we hit the depth invariant assert.
The most obvious way to fix this is to check after reflow if a scroll frame has changed scroll range that changed the return value of WantAsyncScroll and mark it modified. But this is too large of a hammer because the extra display list building the modified frames will trigger, but also because WantAsyncScroll is relatively heavy. As such we limit the check as narrowly as we can. We use a bool that tracks scroll frames that were inactive during the previous paint but that have active scroll frame descendants. Further, previous work in bug 2044231 reduced the cost of WantAsyncScroll by caching GetScrolledRect during ReflowFinished. The main cost of WantAsyncScroll will then be the memory load of fetching the overflow values from the style display struct which might not be cached at this point (even though they are fetched at the start of the reflow of this scroll frame) because this happens after the reflow of the entire frame tree. Lower down in ReflowFinished we call GetScrollRangeForUserInputEvents() inside |if (mVScrollbarBox || mHScrollbarBox)| which will also fetch those values. So hopefully this should not add many memory fetches.
I also checked that anything else that can change WantAsyncScroll's return value should not have this problem.
Differential Revision: https://phabricator.services.mozilla.com/D304399
Take an outer scroll container A that is async-inactive because it has zero scroll range. It contains various active scroll frames and active nested scroll frames. Some content inside A (but not related to any of the active descendant scroll frames) is modified so that the size of the scrolled content increases making the scroll range non-zero and now WantAsyncScroll() is true. The size increase triggers a retained display list update. None of the descendant already-active scroll frames are marked modified, so the display list build does not visit the every active descendant scroll frame (even if we were to visit every direct ASR child of A). Visiting the frame of an ASR is the only way that we can update it to changes in the ASR tree, so some ASRs do not get updated, so the depth values get out of sync and we hit the depth invariant assert.
The most obvious way to fix this is to check after reflow if a scroll frame has changed scroll range that changed the return value of WantAsyncScroll and mark it modified. But this is too large of a hammer because the extra display list building the modified frames will trigger, but also because WantAsyncScroll is relatively heavy. As such we limit the check as narrowly as we can. We use a bool that tracks scroll frames that were inactive during the previous paint but that have active scroll frame descendants. Further, previous work in bug 2044231 reduced the cost of WantAsyncScroll by caching GetScrolledRect during ReflowFinished. The main cost of WantAsyncScroll will then be the memory load of fetching the overflow values from the style display struct which might not be cached at this point (even though they are fetched at the start of the reflow of this scroll frame) because this happens after the reflow of the entire frame tree. Lower down in ReflowFinished we call GetScrollRangeForUserInputEvents() inside |if (mVScrollbarBox || mHScrollbarBox)| which will also fetch those values. So hopefully this should not add many memory fetches.
I also checked that anything else that can change WantAsyncScroll's return value should not have this problem.
Differential Revision: https://phabricator.services.mozilla.com/D304399
ReflowFinished() can call GetScrolledRect() several times. So use AutoScrolledRectCache to lazily compute the scrolled rect once.
We must construct AutoScrolledRectCache after the visual viewport size can change, since that can affect the scrolled rect.
Differential Revision: https://phabricator.services.mozilla.com/D303965
GetScrolledRect is relatively expensive and has been subject to optimizations in the past. Caching the reference frame during painting was a good start but I want to generalize this to cache the computed rect when we know it can't change for more than just painting (specifically during ReflowFinished).
Use AutoScrolledRectCache on the stack to store the lazily computed scrolled rect and cache the reference frame (if the caller has it), and then store a pointer to it on the scroll frame so we can access it elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D303963
Add "auto" to ScrollLogicalPosition per https://github.com/w3c/csswg-drafts/issues/9576.
Fragment navigation now passes WhereToScroll::Auto so that scroll-snap-align is
respected when present, falling back to the spec defaults (start for block,
nearest for inline) when absent. Explicit scrollIntoView() alignment values are
no longer overridden by snap alignment.
GetScrollSnapAlignFor previously returned None for all axes when the scroll
container had scroll-snap-type: none. Remove that early return so that fragment
navigation (which uses WhereToScroll::Auto) can still honor the target's
scroll-snap-align even on non-snapping containers, as the spec permits.
Differential Revision: https://phabricator.services.mozilla.com/D298959
Removed the Reflow Input in nsIFrame. Added includes for ReflowInput as
necessary in cpp files. Also Forward Declared nsLineLayout in 3 header
files.
Differential Revision: https://phabricator.services.mozilla.com/D298203
Bug 2031757 started treating the <input> button (like the number input
spinbox, or the reveal password button) as a scrollbar part.
Things like print linkifier and such uses the Content() lists, so this
assumption doesn't hold when printing:
https://searchfox.org/firefox-main/rev/8b6198f56d80ba962e0570e5ae8a3c257e2e7bce/layout/generic/nsIFrame.cpp#4270
I'm guessing we haven't hit this before because we suppress scrollbars
when printing.
I think this is probably the most straight-forward fix (just stop making
that assumption).
But LMK if you disagree and I can try something else (another potential
fix is checking the flag in the linking code to put it in the
PositionedDescendants() list, or so, same for the accessibility tree
reference).
Differential Revision: https://phabricator.services.mozilla.com/D297986
will-change doesn't mean it is changing. We already did the same thing
for opacity years ago in bug 1754834.
will-change is useful to prevent side effects when the property changes
(like going from being a containing block for fixed-pos descendants to
not being it).
Given its limited extra effect and the complexity involved, let's remove
it.
We allow it to keep prerendering, since that is actually tested, and
seems worth doing.
Differential Revision: https://phabricator.services.mozilla.com/D228650
The scrollport for single line text inputs doesn't start at the border
edge.
This prevents GetBorderRadii from reducing the border radius too much.
Differential Revision: https://phabricator.services.mozilla.com/D295029
When the root scroll container frame is re-constructed, e.g. the root
element position style is changed from static to fixed,
`mHasVerticalOverflowForDynamicToolbar` flag can not be preserved, thus
we had failed to invoked onShowDynamicToolbar in such cases.
Differential Revision: https://phabricator.services.mozilla.com/D294896
The scrollport for single line text inputs doesn't start at the border
edge.
This prevents GetBorderRadii from reducing the border radius too much.
Differential Revision: https://phabricator.services.mozilla.com/D295029
This also should fix bug 1881942 (placeholder is now scrollable
alongside the textarea).
This makes nsTextControlFrame a subclass of ScrollContainerFrame (with
an inner block), and tweaks layout to match.
It lays out the inner content using block layout and align-content,
rather than bespoke reflow primitives. This makes field-sizing trivial
to implement on top.
This is a bit scary, but simpler in most ways. In particular, it needs
to teach ScrollContainerFrame of the button, because that goes outside
the scrollable area, like scrollbars. That said it needs less
special-cases added than those removed, and it should also be faster
(needs less frames to layout an input with placeholder etc), and match
other browsers better.
The general set-up is:
<text-control-editing-root/>
<placeholder/>
<autofill-preview/>
text-control-editing-root is always inline-block and always displayed
(since it's what grabs the focus / shows the caret). If the
autofill-preview or placeholder are displayed, the editing-root is
zero-width and clipped (note that for placeholder that's guaranteed
because placeholder is only shown with an empty value, but
autofill-preview needs it).
placeholder and autofill-preview are hidden via `display` rather than
visibility. This doesn't make a difference with this patch but it
matters for bug 1977176.
Caret painting needs an extra hop to paint atop the placeholder (no
observable behavior change, but worth calling out).
There is one subtle behavior change, which is that single-line inputs
never report scrollable overflow in the block axis. This matches other
browsers (see the tweak in nsBlockFrame's overflow computation) and is
needed to avoid regressing scrollable-overflow-padding-input.html.
The changes in window_composition_text_querycontent.xhtml are needed
because before this patch, the height of the control editing root was
always the height of the whole textarea. The characters you're composing
might legitimately be taller than the line. Bump the line height so that
that doesn't happen in this test.
Differential Revision: https://phabricator.services.mozilla.com/D293666
This also should fix bug 1881942 (placeholder is now scrollable
alongside the textarea).
This makes nsTextControlFrame a subclass of ScrollContainerFrame (with
an inner block), and tweaks layout to match.
It lays out the inner content using block layout and align-content,
rather than bespoke reflow primitives. This makes field-sizing trivial
to implement on top.
This is a bit scary, but simpler in most ways. In particular, it needs
to teach ScrollContainerFrame of the button, because that goes outside
the scrollable area, like scrollbars. That said it needs less
special-cases added than those removed, and it should also be faster
(needs less frames to layout an input with placeholder etc), and match
other browsers better.
The general set-up is:
<text-control-editing-root/>
<placeholder/>
<autofill-preview/>
text-control-editing-root is always inline-block and always displayed
(since it's what grabs the focus / shows the caret). If the
autofill-preview or placeholder are displayed, the editing-root is
zero-width and clipped (note that for placeholder that's guaranteed
because placeholder is only shown with an empty value, but
autofill-preview needs it).
placeholder and autofill-preview are hidden via `display` rather than
visibility. This doesn't make a difference with this patch but it
matters for bug 1977176.
Caret painting needs an extra hop to paint atop the placeholder (no
observable behavior change, but worth calling out).
There is one subtle behavior change, which is that single-line inputs
never report scrollable overflow in the block axis. This matches other
browsers (see the tweak in nsBlockFrame's overflow computation) and is
needed to avoid regressing scrollable-overflow-padding-input.html.
The changes in window_composition_text_querycontent.xhtml are needed
because before this patch, the height of the control editing root was
always the height of the whole textarea. The characters you're composing
might legitimately be taller than the line. Bump the line height so that
that doesn't happen in this test.
Differential Revision: https://phabricator.services.mozilla.com/D293666
This also should fix bug 1881942 (placeholder is now scrollable
alongside the textarea).
This makes nsTextControlFrame a subclass of ScrollContainerFrame (with
an inner block), and tweaks layout to match.
It lays out the inner content using block layout and align-content,
rather than bespoke reflow primitives. This makes field-sizing trivial
to implement on top.
This is a bit scary, but simpler in most ways. In particular, it needs
to teach ScrollContainerFrame of the button, because that goes outside
the scrollable area, like scrollbars. That said it needs less
special-cases added than those removed, and it should also be faster
(needs less frames to layout an input with placeholder etc), and match
other browsers better.
The general set-up is:
<text-control-editing-root/>
<placeholder/>
<autofill-preview/>
text-control-editing-root is always inline-block and always displayed
(since it's what grabs the focus / shows the caret). If the
autofill-preview or placeholder are displayed, the editing-root is
zero-width and clipped (note that for placeholder that's guaranteed
because placeholder is only shown with an empty value, but
autofill-preview needs it).
placeholder and autofill-preview are hidden via `display` rather than
visibility. This doesn't make a difference with this patch but it
matters for bug 1977176.
Caret painting needs an extra hop to paint atop the placeholder (no
observable behavior change, but worth calling out).
There is one subtle behavior change, which is that single-line inputs
never report scrollable overflow in the block axis. This matches other
browsers (see the tweak in nsBlockFrame's overflow computation) and is
needed to avoid regressing scrollable-overflow-padding-input.html.
The changes in window_composition_text_querycontent.xhtml are needed
because before this patch, the height of the control editing root was
always the height of the whole textarea. The characters you're composing
might legitimately be taller than the line. Bump the line height so that
that doesn't happen in this test.
Differential Revision: https://phabricator.services.mozilla.com/D293666
helper_scroll_position_update_on_clamp.html exercises a scenario where
scroll position updates would fail without the promotion. The scenario is
roughly:
1) An instant scrollTo(10, 300) happens on the main thread
2) The scrollable area gets shrunk horizontally so that
the maximum scroll position becomes 9
3) A ScrollOrigin::Clamp (9, 300) is generated
Without the promotion, there would be two scroll position updates: 1)
abs (10, 300), 2) relative (9, 300). Then APZ calculates the final
destination as (10 + 9, 300 + 300).
Differential Revision: https://phabricator.services.mozilla.com/D294032
This reverts commit 2c25546f3a.
Revert "Bug 2029551 - Use relative scroll position update for ScrollOrigin::Clamp. r=botond"
This reverts commit 5cdc1fc8db.
webkit-scrollbar-zero-width-and-height.html: Tests that setting both width
and height to 0 on ::-webkit-scrollbar hides the scrollbars, matching the
display:none behavior.
webkit-scrollbar-zero-width-and-height-scrollbar-width-thin.html: Tests that
a non-auto scrollbar-width (thin) clobbers the width:0/height:0 hiding, so
scrollbars remain visible.
webkit-scrollbar-percent-width-height.html: Updated to only set one dimension
per test case (width-only or height-only), since setting both to percent values
would now trigger the width:0/height:0 hiding behavior (percent is treated as 0
on Blink/WebKit).
Differential Revision: https://phabricator.services.mozilla.com/D291363
Based on the perfherder report in #2024444, disabling the DL
item cache doesn't regress performance and provides a performance
improvement in heap size on some tests.
This follow up patch removes the existing DL cache infrastructure,
which will become redundant once we move primitive interning in
to the content process via the WR DL builder, rather than during
scene building.
Removing it now simplifies the development of that content process
interning system, since we no longer need to deal with ensuring
that cache items are still correctly handled in that path.
Differential Revision: https://phabricator.services.mozilla.com/D289388
Note about layout.css.scrollbar-width-thin.disabled:
In the case where the pref is false (default),
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars just like what Chrome does.
In the case where the pref is true,
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars either, the width of scrollbar is rendered
as if it's 'auto`.
Differential Revision: https://phabricator.services.mozilla.com/D286183
Disable individual scrollbar relies ScrollbarActivity so that creating
the ScrollbarActivity on each ScrollContainerFrame needs to refer
the document global preference, i.e. nsPresContext::UseOverlayScrollbars
instead of ScrollContainerFrame::UseOverlayScrollbars.
Differential Revision: https://phabricator.services.mozilla.com/D281573
This reverts commit 0bc649e1df.
Revert "Bug 1977511 - Handle `::-webkit-scrollbar { display:none }` as if it's `scrollbar-width: none`. r=layout-reviewers,firefox-style-system-reviewers,emilio"
This reverts commit fe392b1cd5.
Revert "Bug 1977511 - Add reftests for ::-webkit-scrollbar. r=layout-reviewers,emilio"
This reverts commit 1b6d4641c7.
Revert "Bug 1977511 - Disable overlay scrollbars if there's any non-zero width and height defined in ::-webkit-scrollbar. r=layout-reviewers,firefox-style-system-reviewers,emilio"
This reverts commit 926eea5a10.
Revert "Bug 1977511 - Resolve ::-webkit-scrollbar pseudo element styles soon after the scroll container style was set. r=layout-reviewers,devtools-reviewers,firefox-style-system-reviewers,nchevobbe,emilio"
This reverts commit 8164020c76.
Revert "Bug 1977511 - Introduce nsLayoutUtils::UseOverlayScrollbars and use it in proper places instead of nsPresContext::UseOverlayScrollbars. r=layout-reviewers,emilio"
This reverts commit 8856d35471.
Revert "Bug 1977511 - Use ScrollContainerFrame::UseOverlayScrollbars in ResizeObserver and ScrollbarAreaToExcludeFromCompositionBoundsFor. r=layout-reviewers,emilio"
This reverts commit 5baba0ed09.
Note about layout.css.scrollbar-width-thin.disabled:
In the case where the pref is false (default),
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars just like what Chrome does.
In the case where the pref is true,
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars either, the width of scrollbar is rendered
as if it's 'auto`.
Differential Revision: https://phabricator.services.mozilla.com/D286183
Disable individual scrollbar relies ScrollbarActivity so that creating
the ScrollbarActivity on each ScrollContainerFrame needs to refer
the document global preference, i.e. nsPresContext::UseOverlayScrollbars
instead of ScrollContainerFrame::UseOverlayScrollbars.
Differential Revision: https://phabricator.services.mozilla.com/D281573
This reverts commit e7e66a8471.
Revert "Bug 1977511 - Add reftests for ::-webkit-scrollbar. r=layout-reviewers,emilio"
This reverts commit 1ef6a456dc.
Revert "Bug 1977511 - Disable overlay scrollbars if there's any non-zero width and height defined in ::-webkit-scrollbar. r=layout-reviewers,firefox-style-system-reviewers,emilio"
This reverts commit 904febaca7.
Revert "Bug 1977511 - Resolve ::-webkit-scrollbar pseudo element styles soon after the scroll container style was set. r=layout-reviewers,devtools-reviewers,firefox-style-system-reviewers,nchevobbe,emilio"
This reverts commit b8f0d32cfb.
Revert "Bug 1977511 - Introduce nsLayoutUtils::UseOverlayScrollbars and use it in proper places instead of nsPresContext::UseOverlayScrollbars. r=layout-reviewers,emilio"
This reverts commit 0694ea2bf8.
Revert "Bug 1977511 - Use ScrollContainerFrame::UseOverlayScrollbars in ResizeObserver and ScrollbarAreaToExcludeFromCompositionBoundsFor. r=layout-reviewers,emilio"
This reverts commit 19303dead1.
Note about layout.css.scrollbar-width-thin.disabled:
In the case where the pref is false (default),
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars just like what Chrome does.
In the case where the pref is true,
```
.scrollabler { scrollbar-wdith: thin; }
.scrollable::-webkit-scrollbar { display: none; }
```
does NOT hide the scrollbars either, the width of scrollbar is rendered
as if it's 'auto`.
Differential Revision: https://phabricator.services.mozilla.com/D286183