@@ -1170,18 +1170,17 @@ static LogicalSize CalculateContainingBlockSizeForAbsolutes(
1170
1170
}
1171
1171
1172
1172
/* *
1173
- * Returns aFrame if it is a non-BFC block frame, and null otherwise.
1173
+ * Returns aFrame if it is an in-flow, non-BFC block frame, and null otherwise.
1174
1174
*
1175
1175
* This is used to determine whether to recurse into aFrame when applying
1176
1176
* -webkit-line-clamp.
1177
1177
*/
1178
1178
static const nsBlockFrame* GetAsLineClampDescendant (const nsIFrame* aFrame) {
1179
- if (const nsBlockFrame* block = do_QueryFrame (aFrame)) {
1180
- if (!block->HasAnyStateBits (NS_BLOCK_BFC)) {
1181
- return block;
1182
- }
1179
+ const nsBlockFrame* block = do_QueryFrame (aFrame);
1180
+ if (!block || block->HasAnyStateBits (NS_FRAME_OUT_OF_FLOW | NS_BLOCK_BFC)) {
1181
+ return nullptr ;
1183
1182
}
1184
- return nullptr ;
1183
+ return block ;
1185
1184
}
1186
1185
1187
1186
static nsBlockFrame* GetAsLineClampDescendant (nsIFrame* aFrame) {
@@ -1343,28 +1342,30 @@ class MOZ_RAII LineClampLineIterator {
1343
1342
};
1344
1343
1345
1344
static bool ClearLineClampEllipsis (nsBlockFrame* aFrame) {
1346
- if (!aFrame->HasAnyStateBits (NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS)) {
1345
+ if (aFrame->HasLineClampEllipsis ()) {
1346
+ MOZ_ASSERT (!aFrame->HasLineClampEllipsisDescendant ());
1347
+ aFrame->SetHasLineClampEllipsis (false );
1348
+ for (auto & line : aFrame->Lines ()) {
1349
+ if (line.HasLineClampEllipsis ()) {
1350
+ line.ClearHasLineClampEllipsis ();
1351
+ break ;
1352
+ }
1353
+ }
1354
+ return true ;
1355
+ }
1356
+
1357
+ if (aFrame->HasLineClampEllipsisDescendant ()) {
1358
+ aFrame->SetHasLineClampEllipsisDescendant (false );
1347
1359
for (nsIFrame* f : aFrame->PrincipalChildList ()) {
1348
1360
if (nsBlockFrame* child = GetAsLineClampDescendant (f)) {
1349
1361
if (ClearLineClampEllipsis (child)) {
1350
1362
return true ;
1351
1363
}
1352
1364
}
1353
1365
}
1354
- return false ;
1355
- }
1356
-
1357
- aFrame->RemoveStateBits (NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS);
1358
-
1359
- for (auto & line : aFrame->Lines ()) {
1360
- if (line.HasLineClampEllipsis ()) {
1361
- line.ClearHasLineClampEllipsis ();
1362
- return true ;
1363
- }
1364
1366
}
1365
1367
1366
- // We didn't find a line with the ellipsis; it must have been deleted already.
1367
- return true ;
1368
+ return false ;
1368
1369
}
1369
1370
1370
1371
void nsBlockFrame::ClearLineClampEllipsis () { ::ClearLineClampEllipsis (this ); }
@@ -1869,6 +1870,12 @@ nsReflowStatus nsBlockFrame::TrialReflow(nsPresContext* aPresContext,
1869
1870
// overflow line lists being cleared out between reflow passes.
1870
1871
DrainOverflowLines ();
1871
1872
1873
+ // Clear any existing -webkit-line-clamp ellipsis if we're reflowing the
1874
+ // line-clamp root.
1875
+ if (IsLineClampRoot (this )) {
1876
+ ClearLineClampEllipsis ();
1877
+ }
1878
+
1872
1879
bool blockStartMarginRoot, blockEndMarginRoot;
1873
1880
IsMarginRoot (&blockStartMarginRoot, &blockEndMarginRoot);
1874
1881
@@ -2018,11 +2025,6 @@ nsReflowStatus nsBlockFrame::TrialReflow(nsPresContext* aPresContext,
2018
2025
// block-start padding.
2019
2026
}
2020
2027
2021
- // Clear any existing -webkit-line-clamp ellipsis.
2022
- if (aReflowInput.mStyleDisplay ->mWebkitLineClamp ) {
2023
- ClearLineClampEllipsis ();
2024
- }
2025
-
2026
2028
CheckFloats (state);
2027
2029
2028
2030
// Compute our final size (for this trial layout)
@@ -2052,8 +2054,8 @@ static nsLineBox* FindLineClampTarget(nsBlockFrame*& aFrame,
2052
2054
nsBlockFrame* aStopAtFrame,
2053
2055
StyleLineClamp aLineNumber) {
2054
2056
MOZ_ASSERT (aLineNumber > 0 );
2055
- MOZ_ASSERT (!aFrame->HasAnyStateBits (NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS ),
2056
- " Should have been removed earlier in nsBlockReflow::Reflow " );
2057
+ MOZ_ASSERT (!aFrame->HasLineClampEllipsis ( ),
2058
+ " Should have been removed earlier" );
2057
2059
2058
2060
nsLineBox* target = nullptr ;
2059
2061
nsBlockFrame* targetFrame = nullptr ;
@@ -2114,11 +2116,16 @@ nscoord nsBlockFrame::ApplyLineClamp(nscoord aContentBlockEndEdge) {
2114
2116
2115
2117
// Mark the line as having an ellipsis so that TextOverflow will render it.
2116
2118
line->SetHasLineClampEllipsis ();
2117
- target->AddStateBits (NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS );
2119
+ target->SetHasLineClampEllipsis ( true );
2118
2120
2119
2121
// Translate the b-end edge of the line up to aFrame's space.
2120
2122
nscoord edge = line->BEnd ();
2121
2123
for (nsIFrame* f = target; f; f = f->GetParent ()) {
2124
+ MOZ_ASSERT (f->IsBlockFrameOrSubclass (),
2125
+ " GetAsLineClampDescendant guarantees this" );
2126
+ if (f != target) {
2127
+ static_cast (f)->SetHasLineClampEllipsisDescendant (true );
2128
+ }
2122
2129
if (f == this ) {
2123
2130
break ;
2124
2131
}
@@ -7637,7 +7644,7 @@ static void DisplayLine(nsDisplayListBuilder* aBuilder,
7637
7644
const bool aLineInLine, const nsDisplayListSet& aLists,
7638
7645
nsBlockFrame* aFrame, TextOverflow* aTextOverflow,
7639
7646
uint32_t aLineNumberForTextOverflow, int32_t aDepth,
7640
- int32_t & aDrawnLines) {
7647
+ int32_t & aDrawnLines, bool & aFoundLineClamp ) {
7641
7648
#ifdef DEBUG
7642
7649
if (nsBlockFrame::gLamePaintMetrics ) {
7643
7650
aDrawnLines++;
@@ -7670,6 +7677,14 @@ static void DisplayLine(nsDisplayListBuilder* aBuilder,
7670
7677
kid = kid->GetNextSibling ();
7671
7678
}
7672
7679
7680
+ if (aFrame->HasLineClampEllipsisDescendant () && !aLineInLine) {
7681
+ if (nsBlockFrame* f = GetAsLineClampDescendant (aLine->mFirstChild )) {
7682
+ if (f->HasLineClampEllipsis () || f->HasLineClampEllipsisDescendant ()) {
7683
+ aFoundLineClamp = true ;
7684
+ }
7685
+ }
7686
+ }
7687
+
7673
7688
if (aTextOverflow && aLineInLine) {
7674
7689
aTextOverflow->ProcessLine (collection, aLine.get (),
7675
7690
aLineNumberForTextOverflow);
@@ -7774,12 +7789,14 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
7774
7789
// runs of text as a whole, which requires we iterate through all lines
7775
7790
// to find our backplate size.
7776
7791
nsLineBox* cursor =
7777
- (hasDescendantPlaceHolders || textOverflow.isSome () || backplateColor)
7792
+ (hasDescendantPlaceHolders || textOverflow.isSome () || backplateColor ||
7793
+ HasLineClampEllipsis () || HasLineClampEllipsisDescendant ())
7778
7794
? nullptr
7779
7795
: GetFirstLineContaining (aBuilder->GetDirtyRect ().y );
7780
7796
LineIterator line_end = LinesEnd ();
7781
7797
7782
7798
TextOverflow* textOverflowPtr = textOverflow.ptrOr (nullptr );
7799
+ bool foundClamp = false ;
7783
7800
7784
7801
if (cursor) {
7785
7802
for (LineIterator line = mLines .begin (cursor); line != line_end; ++line) {
@@ -7794,7 +7811,8 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
7794
7811
7795
7812
if (ShouldDescendIntoLine (lineArea)) {
7796
7813
DisplayLine (aBuilder, line, line->IsInline (), aLists, this , nullptr ,
7797
- 0 , depth, drawnLines);
7814
+ 0 , depth, drawnLines, foundClamp);
7815
+ MOZ_ASSERT (!foundClamp);
7798
7816
}
7799
7817
}
7800
7818
}
@@ -7825,7 +7843,7 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
7825
7843
7826
7844
if ((lineInLine && textOverflowPtr) || ShouldDescendIntoLine (lineArea)) {
7827
7845
DisplayLine (aBuilder, line, lineInLine, aLists, this , textOverflowPtr,
7828
- lineCount, depth, drawnLines);
7846
+ lineCount, depth, drawnLines, foundClamp );
7829
7847
}
7830
7848
7831
7849
if (!lineInLine && !curBackplateArea.IsEmpty ()) {
@@ -7856,6 +7874,10 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
7856
7874
}
7857
7875
}
7858
7876
}
7877
+ foundClamp = foundClamp || line->HasLineClampEllipsis ();
7878
+ if (foundClamp) {
7879
+ break ;
7880
+ }
7859
7881
lineCount++;
7860
7882
}
7861
7883
0 commit comments