This patch changes the signature to `GetMinISize()`, `GetPrefISize()`,
`IntrinsicISize` by adding a helper struct as a preparation. Then we can just
add more data such as a percentage basis to the struct without altering the
signature in the future.
When passing `IntrinsicSizeInput` struct down to another helper method, we
generally just pass the original one if the method is computing the intrinsic
size of our own or our anonymous children. If the method is computing our
children's intrinsic contribution, we'll need to create a brand new
`IntrinsicSizeInput` for our children.
Differential Revision: https://phabricator.services.mozilla.com/D219521
This patch changes the signature to `GetMinISize()`, `GetPrefISize()`,
`IntrinsicISize` by adding a helper struct as a preparation. Then we can just
add more data such as a percentage basis to the struct without altering the
signature in the future.
When passing `IntrinsicSizeInput` struct down to another helper method, we
generally just pass the original one if the method is computing the intrinsic
size of our own or our anonymous children. If the method is computing our
children's intrinsic contribution, we'll need to create a brand new
`IntrinsicSizeInput` for our children.
Differential Revision: https://phabricator.services.mozilla.com/D219521
Most frame types have identical or very similar implementation for GetMinISize()
and GetPrefISize(), and many of them already have `IntrinsicISize()` to unify
the implementation. This patch introduces nsIFrame::IntrinsicISize() so that
derived classes only need to override one method.
`nsBlockFrame`, `ColumnSetWrapperFrame`, and `nsColumnSetFrame` are the only
three classes where their `GetMinISize()` and `GetPrefISize()` have significant
differences. Therefore, we rename `GetMinISize()` and `GetPrefISize()` to
`MinISize()` and `PrefISize`, respectively, and use them as helpers to implement
their `IntrinsicISize()`.
This patch doesn't change behavior.
Differential Revision: https://phabricator.services.mozilla.com/D217790
This reverts the backout, effectively re-landing all the original patches here and the test-manifest
followups that were pushed after the original landing.
Differential Revision: https://phabricator.services.mozilla.com/D212698
This is an alternative version of SetLength to be used for the child of an nsFirstLetterFrame,
when we may need to create continuations in order to separate the first-letter from its
following text.
With this, the intrinsic sizes of first-letter should be computed correctly.
Differential Revision: https://phabricator.services.mozilla.com/D211597
Extend the per-frame-class bit we have to devirtualize IsLeaf to also
devirtualize IsFrameOfType. That is, move this data to FrameClasses.py.
This was done by going through all the frame classes, trying to preserve
behavior.
The only quirky thing is that I had to add two more trivial frame
classes, `nsAudioFrame` for audio elements, and
`nsFloatingFirstLetterFrame`. That's because these frame classes were
returning different answers at runtime, but they do this only on
conditions that trigger frame reconstruction (floating, and being an
audio element, respectively).
Differential Revision: https://phabricator.services.mozilla.com/D194703
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line
Differential Revision: https://phabricator.services.mozilla.com/D173886
Before, there existed 3 virtual functions that calculated baselines:
- `GetLogicalBaseline`
- `GetVerticalAlignBaseline`
- `GetNaturalBaselineBOffset`
Each of them had slightly different behaviours:
- `GetLogicalBaseline` would synthesize a baseline if there is no baseline.
Others would simply return `false`.
- `GetNaturalBaselineBOffset` requires the caller to pick which of first/last
baseline to calculate. Others pick on on their own.
- `GetNaturalBaselineBOffset`'s result can be either offset from border box
start/end edge, depending on the caller-supplied baseline. Others always
return offset from border box start edge.
Now:
- `GetNaturalBaselineBOffset` is the sole virtual function.
- `GetLogicalBaseline` exists to support its use, with 2 virtual helper functions:
- `SynthesizeFallbackBaseline` to generate a baseline for elements that
doesn't have one.
- `GetBaselineSharingGroup` to preserve the default baseline picking behaviour.
Differential Revision: https://phabricator.services.mozilla.com/D167990
Historically, Gecko implemented the behavior allowed by CSS2 whereby a floated ::first-letter is "boxed"
tightly around the glyph shape, rather than using constant font-ascent and -descent metrics which may
leave a lot of blank space depending whether the character has any ascender/descender or not.
However, neither webkit nor blink do this, which leads to webcompat pain when sites are constructed
assuming their behavior.
Eventually, I think we should ideally reimplement ::first-letter entirely at frame-construction time,
rather than during reflow. But in the interest of minimizing risk here, and making it easy to flip
between our existing "legacy" behavior and the new "compatible" behavior, this patch leaves the
overall implementation unchanged and just alters the metrics used for the resulting first-letter
frame.
This patch creates an integer pref layout.css.floating-first-letter.tight-glyph-bounds to allow us
to choose between three behaviors:
1: Use tight glyph bounds, and ignore line-height; the baseline of the floated letter automatically
adjusts to wrap text around the "ink box" of the glyph. This is the existing Gecko behavior.
0: Don't use tight glyph bounds, respect line-height: the floated letter acts like a normal <span>
with float positioning; baseline position and vertical size are based on font metrics but not
the specific shape of the individual glyph. This gives a similar result to webkit/blink.
-1: Automatically choose between (1) and (0) based on heuristics to try and detect whether the page
was written with the webkit/blink behavior (0) in mind; specifically, if there is a line-height
of less than 1em, or a negative block-start margin, we assume the author was trying to eliminate
excess blank space that behavior (0) tends to produce, and so we use that model.
Initially, this patch leaves the behavior unchanged for Beta/Release builds, but enables option -1 (use
heuristics to choose which layout model to apply) on Nightly so we can see how that works in practice.
Differential Revision: https://phabricator.services.mozilla.com/D165008
Historically, Gecko implemented the behavior allowed by CSS2 whereby a floated ::first-letter is "boxed"
tightly around the glyph shape, rather than using constant font-ascent and -descent metrics which may
leave a lot of blank space depending whether the character has any ascender/descender or not.
However, neither webkit nor blink do this, which leads to webcompat pain when sites are constructed
assuming their behavior.
Eventually, I think we should ideally reimplement ::first-letter entirely at frame-construction time,
rather than during reflow. But in the interest of minimizing risk here, and making it easy to flip
between our existing "legacy" behavior and the new "compatible" behavior, this patch leaves the
overall implementation unchanged and just alters the metrics used for the resulting first-letter
frame.
This patch creates an integer pref layout.css.floating-first-letter.tight-glyph-bounds to allow us
to choose between three behaviors:
1: Use tight glyph bounds, and ignore line-height; the baseline of the floated letter automatically
adjusts to wrap text around the "ink box" of the glyph. This is the existing Gecko behavior.
0: Don't use tight glyph bounds, respect line-height: the floated letter acts like a normal <span>
with float positioning; baseline position and vertical size are based on font metrics but not
the specific shape of the individual glyph. This gives a similar result to webkit/blink.
-1: Automatically choose between (1) and (0) based on heuristics to try and detect whether the page
was written with the webkit/blink behavior (0) in mind; specifically, if there is a line-height
of less than 1em, or a negative block-start margin, we assume the author was trying to eliminate
excess blank space that behavior (0) tends to produce, and so we use that model.
Initially, this patch leaves the behavior unchanged for Beta/Release builds, but enables option -1 (use
heuristics to choose which layout model to apply) on Nightly so we can see how that works in practice.
Differential Revision: https://phabricator.services.mozilla.com/D165008
SetFrame() is equivalent to `operator=`, so external callers can use `operator=`
instead. For the two callers wanting to set `nsFrameList` to `AbsoluteFrameList`
in `nsCSSFrameConstructor`, removing SetFrame() disallows it. However, we can
easily change the declaration from `nsFrameList` to a `AbsoluteFrameList` to
resolve the problem.
Differential Revision: https://phabricator.services.mozilla.com/D160840
RemoveFramesAfter and ExtractTail have similar purpose, so we really should keep
one of them to avoid confusion.
They have the following minor differences:
1. RemoveFramesAfter() keeps aFrame in the list, while ExtractTail() returns it.
2. If aFrame is empty, RemoveFramesAfter() returns the entire list, while
ExtractTail returns an empty list.
It's more convenient for the existing callers to use the RemoveFramesAfter(), so
ExtractTail is unneeded.
After this patch, both RemoveFramesAfter() and RemoveFramesBefore() return the
entire list if aFrame is nullptr.
Rename RemoveFramesAfter() to TakeFramesAfter() for symmetry with
TakeFramesBefore().
This change shouldn't change the behavior.
Differential Revision: https://phabricator.services.mozilla.com/D158807
In the description of the mTruncated bit, its purpose is the same as calling
SetInlineLineBreakBeforeAndReset(). We've removed all its usages in previous
patches, so the bit is no longer needed.
Differential Revision: https://phabricator.services.mozilla.com/D151461
Its type is not `BlockReflowInput` but an ordinary `ReflowInput`. Rename it to
`mLineContainerRI` to match its accessor.
While I'm here, I change `mLineContainerRI` to be a reference since it cannot be
nullptr (see nsLineLayout's constructor); also, replace
`mLineContainerRI->mFrame` with `LineContainerFrame()`.
Differential Revision: https://phabricator.services.mozilla.com/D139438
While nsInlineFrame and nsFirstLetterFrame are going to continue sharing the same code, nsRubyFrame will use the refactored version to compute its intrinsic sizes.
This way we can also eliminate the need for checking the intrinsic type inside the function.
This patch shouldn't change behavior. It's just a refactoring of existing code.
Differential Revision: https://phabricator.services.mozilla.com/D109227
This patch adds the struct as a parameter to various functions.
The struct is cached in ReflowInput so that we don't need to pass it
down to the internal method where nsIFrame::ComputeSize() is called.
In the subsequent patches, we'll use it to revise the implementation of
flex container's flex base size resolution, and size overrides.
Differential Revision: https://phabricator.services.mozilla.com/D101793
This patch adds the struct as a parameter to various functions.
The struct is cached in ReflowInput so that we don't need to pass it
down to the internal method where nsIFrame::ComputeSize() is called.
In the subsequent patches, we'll use it to revise the implementation of
flex container's flex base size resolution, and size overrides.
Differential Revision: https://phabricator.services.mozilla.com/D101793