зеркало из https://github.com/mozilla/gecko-dev.git
Bug 866102 - Implement -webkit-line-clamp. r=mats,emilio,dholbert
Differential Revision: https://phabricator.services.mozilla.com/D20115 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
de6f8d5227
Коммит
f5b7d1380b
|
@ -279,6 +279,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"transform-origin",
|
||||
"-moz-window-transform",
|
||||
"-moz-window-transform-origin",
|
||||
"-webkit-line-clamp",
|
||||
])],
|
||||
["coord", new Set([
|
||||
"border-bottom-left-radius",
|
||||
|
|
|
@ -2317,6 +2317,20 @@ exports.CSS_PROPERTIES = {
|
|||
"unset"
|
||||
]
|
||||
},
|
||||
"-webkit-line-clamp": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"-webkit-line-clamp"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"inherit",
|
||||
"initial",
|
||||
"none",
|
||||
"revert",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"-webkit-mask": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
|
@ -3104,6 +3118,7 @@ exports.CSS_PROPERTIES = {
|
|||
"shape-margin",
|
||||
"shape-outside",
|
||||
"touch-action",
|
||||
"-webkit-line-clamp",
|
||||
"color",
|
||||
"column-width",
|
||||
"column-count",
|
||||
|
@ -10517,6 +10532,10 @@ exports.PREFERENCES = [
|
|||
"transform-box",
|
||||
"svg.transform-box.enabled"
|
||||
],
|
||||
[
|
||||
"-webkit-line-clamp",
|
||||
"layout.css.webkit-line-clamp.enabled"
|
||||
],
|
||||
[
|
||||
"overflow-clip-box-block",
|
||||
"layout.css.overflow-clip-box.enabled"
|
||||
|
|
|
@ -97,7 +97,15 @@ BlockReflowInput::BlockReflowInput(const ReflowInput& aReflowInput,
|
|||
if (aBlockNeedsFloatManager) {
|
||||
mFlags.mBlockNeedsFloatManager = true;
|
||||
}
|
||||
mFlags.mCanHaveTextOverflow = css::TextOverflow::CanHaveTextOverflow(mBlock);
|
||||
|
||||
// We need to check mInsideLineClamp here since we are here before the block
|
||||
// has been reflowed, and CanHaveOverflowMarkers() relies on the block's
|
||||
// NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS state bit to know if a -webkit-line-clamp
|
||||
// ellipsis is set on one of the block's lines. And that state bit is only
|
||||
// set after we do the bsize measuring reflow of the flex item.
|
||||
mFlags.mCanHaveOverflowMarkers =
|
||||
aReflowInput.mFlags.mInsideLineClamp ||
|
||||
css::TextOverflow::CanHaveOverflowMarkers(mBlock);
|
||||
|
||||
MOZ_ASSERT(FloatManager(),
|
||||
"Float manager should be valid when creating BlockReflowInput!");
|
||||
|
|
|
@ -40,7 +40,7 @@ class BlockReflowInput {
|
|||
mIsOverflowContainer(false),
|
||||
mIsFloatListInBlockPropertyTable(false),
|
||||
mFloatFragmentsInsideColumnEnabled(false),
|
||||
mCanHaveTextOverflow(false) {}
|
||||
mCanHaveOverflowMarkers(false) {}
|
||||
|
||||
// Set in the BlockReflowInput constructor when the frame being reflowed has
|
||||
// been given NS_UNCONSTRAINEDSIZE as its available BSize in the
|
||||
|
@ -104,8 +104,8 @@ class BlockReflowInput {
|
|||
// Set when the pref layout.float-fragments-inside-column.enabled is true.
|
||||
bool mFloatFragmentsInsideColumnEnabled : 1;
|
||||
|
||||
// Set when we need text-overflow processing.
|
||||
bool mCanHaveTextOverflow : 1;
|
||||
// Set when we need text-overflow or -webkit-line-clamp processing.
|
||||
bool mCanHaveOverflowMarkers : 1;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -215,6 +215,7 @@ ReflowInput::ReflowInput(nsPresContext* aPresContext,
|
|||
mFlags.mIClampMarginBoxMinSize = !!(aFlags & I_CLAMP_MARGIN_BOX_MIN_SIZE);
|
||||
mFlags.mBClampMarginBoxMinSize = !!(aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE);
|
||||
mFlags.mApplyAutoMinSize = !!(aFlags & I_APPLY_AUTO_MIN_SIZE);
|
||||
mFlags.mApplyLineClamp = false;
|
||||
|
||||
if ((aFlags & DUMMY_PARENT_REFLOW_INPUT) ||
|
||||
(mParentReflowInput->mFlags.mDummyParentReflowInput &&
|
||||
|
|
|
@ -270,6 +270,20 @@ struct SizeComputationInput {
|
|||
// with when we set & react to these bits.
|
||||
bool mIOffsetsNeedCSSAlign : 1;
|
||||
bool mBOffsetsNeedCSSAlign : 1;
|
||||
|
||||
// Are we somewhere inside an element with -webkit-line-clamp set?
|
||||
// This flag is inherited into descendant ReflowInputs, but we don't bother
|
||||
// resetting it to false when crossing over into a block descendant that
|
||||
// -webkit-line-clamp skips over (such as a BFC).
|
||||
bool mInsideLineClamp : 1;
|
||||
|
||||
// Is this a flex item, and should we add or remove a -webkit-line-clamp
|
||||
// ellipsis on a descendant line? It's possible for this flag to be true
|
||||
// when mInsideLineClamp is false if we previously had a numeric
|
||||
// -webkit-line-clamp value, but now have 'none' and we need to find the
|
||||
// line with the ellipsis flag and clear it.
|
||||
// This flag is not inherited into descendant ReflowInputs.
|
||||
bool mApplyLineClamp : 1;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -152,11 +152,11 @@ class nsDisplayTextOverflowMarker final : public nsPaintedDisplayItem {
|
|||
public:
|
||||
nsDisplayTextOverflowMarker(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const nsRect& aRect, nscoord aAscent,
|
||||
const nsStyleTextOverflowSide* aStyle,
|
||||
nsStyleTextOverflowSide aStyle,
|
||||
uint32_t aLineNumber, uint16_t aIndex)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mRect(aRect),
|
||||
mStyle(*aStyle),
|
||||
mStyle(aStyle),
|
||||
mAscent(aAscent),
|
||||
mIndex((aLineNumber << 1) + aIndex) {
|
||||
MOZ_COUNT_CTOR(nsDisplayTextOverflowMarker);
|
||||
|
@ -344,9 +344,10 @@ TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder,
|
|||
/* static */
|
||||
Maybe<TextOverflow> TextOverflow::WillProcessLines(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aBlockFrame) {
|
||||
// Ignore 'text-overflow' for event and frame visibility processing.
|
||||
// Ignore text-overflow and -webkit-line-clamp for event and frame visibility
|
||||
// processing.
|
||||
if (aBuilder->IsForEventDelivery() || aBuilder->IsForFrameVisibility() ||
|
||||
!CanHaveTextOverflow(aBlockFrame)) {
|
||||
!CanHaveOverflowMarkers(aBlockFrame)) {
|
||||
return Nothing();
|
||||
}
|
||||
nsIScrollableFrame* scrollableFrame =
|
||||
|
@ -461,7 +462,7 @@ void TextOverflow::AnalyzeMarkerEdges(nsIFrame* aFrame,
|
|||
if (iendOverlap > 0) {
|
||||
snappedRect.ISize(mBlockWM) -= snappedIEnd;
|
||||
}
|
||||
aAlignmentEdges->Accumulate(mBlockWM, snappedRect);
|
||||
aAlignmentEdges->AccumulateInner(mBlockWM, snappedRect);
|
||||
*aFoundVisibleTextOrAtomic = true;
|
||||
}
|
||||
}
|
||||
|
@ -470,12 +471,15 @@ void TextOverflow::AnalyzeMarkerEdges(nsIFrame* aFrame,
|
|||
}
|
||||
} else if (!insideIStartEdge || !insideIEndEdge) {
|
||||
// frame is outside
|
||||
if (!insideIStartEdge) {
|
||||
aAlignmentEdges->AccumulateOuter(mBlockWM, borderRect);
|
||||
}
|
||||
if (IsAtomicElement(aFrame, aFrameType)) {
|
||||
aFramesToHide->PutEntry(aFrame);
|
||||
}
|
||||
} else {
|
||||
// frame is inside
|
||||
aAlignmentEdges->Accumulate(mBlockWM, borderRect);
|
||||
aAlignmentEdges->AccumulateInner(mBlockWM, borderRect);
|
||||
if (aFrameType == LayoutFrameType::Text) {
|
||||
auto textFrame = static_cast<nsTextFrame*>(aFrame);
|
||||
if (textFrame->HasNonSuppressedText()) {
|
||||
|
@ -491,8 +495,8 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
FrameHashtable* aFramesToHide,
|
||||
AlignmentEdges* aAlignmentEdges) {
|
||||
// No ellipsing for 'clip' style.
|
||||
bool suppressIStart = mIStart.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
bool suppressIEnd = mIEnd.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
bool suppressIStart = mIStart.IsSuppressed();
|
||||
bool suppressIEnd = mIEnd.IsSuppressed();
|
||||
if (mCanHaveInlineAxisScrollbar) {
|
||||
LogicalPoint pos(mBlockWM, mScrollableFrame->GetScrollPosition(),
|
||||
mBlockSize);
|
||||
|
@ -504,7 +508,10 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
suppressIStart = true;
|
||||
}
|
||||
if (pos.I(mBlockWM) >= scrollRange.IEnd(mBlockWM)) {
|
||||
suppressIEnd = true;
|
||||
// Except that we always want to display a -webkit-line-clamp ellipsis.
|
||||
if (!mIEnd.mHasBlockEllipsis) {
|
||||
suppressIEnd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -543,22 +550,29 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
|
||||
LogicalRect lineRect(mBlockWM, aLine->GetScrollableOverflowArea(),
|
||||
mBlockSize);
|
||||
const bool istartOverflow =
|
||||
const bool istartWantsMarker =
|
||||
!suppressIStart &&
|
||||
lineRect.IStart(mBlockWM) < contentArea.IStart(mBlockWM);
|
||||
const bool iendOverflow =
|
||||
const bool iendWantsTextOverflowMarker =
|
||||
!suppressIEnd && lineRect.IEnd(mBlockWM) > contentArea.IEnd(mBlockWM);
|
||||
if (!istartOverflow && !iendOverflow) {
|
||||
// The line does not overflow on a side we should ellipsize.
|
||||
const bool iendWantsBlockEllipsisMarker =
|
||||
!suppressIEnd && mIEnd.mHasBlockEllipsis;
|
||||
const bool iendWantsMarker =
|
||||
iendWantsTextOverflowMarker || iendWantsBlockEllipsisMarker;
|
||||
if (!istartWantsMarker && !iendWantsMarker) {
|
||||
// We don't need any markers on this line.
|
||||
return nonSnappedContentArea;
|
||||
}
|
||||
|
||||
int pass = 0;
|
||||
bool retryEmptyLine = true;
|
||||
bool guessIStart = istartOverflow;
|
||||
bool guessIEnd = iendOverflow;
|
||||
mIStart.mActive = istartOverflow;
|
||||
mIEnd.mActive = iendOverflow;
|
||||
bool guessIStart = istartWantsMarker;
|
||||
bool guessIEnd = iendWantsMarker;
|
||||
mIStart.mActive = istartWantsMarker;
|
||||
mIEnd.mActive = iendWantsMarker;
|
||||
mIStart.mEdgeAligned = mCanHaveInlineAxisScrollbar && istartWantsMarker;
|
||||
mIEnd.mEdgeAligned =
|
||||
mCanHaveInlineAxisScrollbar && iendWantsTextOverflowMarker;
|
||||
bool clippedIStartMarker = false;
|
||||
bool clippedIEndMarker = false;
|
||||
do {
|
||||
|
@ -601,7 +615,8 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
&clippedMarkerEdges);
|
||||
}
|
||||
if (!foundVisibleTextOrAtomic && retryEmptyLine) {
|
||||
aAlignmentEdges->mAssigned = false;
|
||||
aAlignmentEdges->mAssignedInner = false;
|
||||
aAlignmentEdges->mIEndOuter = 0;
|
||||
aFramesToHide->Clear();
|
||||
pass = -1;
|
||||
if (mIStart.IsNeeded() && mIStart.mActive && !clippedIStartMarker) {
|
||||
|
@ -635,9 +650,23 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
// so examine the line again without suppressing markers.
|
||||
retryEmptyLine = false;
|
||||
mIStart.mISize = mIStart.mIntrinsicISize;
|
||||
mIStart.mActive = guessIStart = istartOverflow;
|
||||
mIStart.mActive = guessIStart = istartWantsMarker;
|
||||
mIEnd.mISize = mIEnd.mIntrinsicISize;
|
||||
mIEnd.mActive = guessIEnd = iendOverflow;
|
||||
mIEnd.mActive = guessIEnd = iendWantsMarker;
|
||||
// If we wanted to place a block ellipsis but didn't, due to not having
|
||||
// any visible content to align to or the line's content being scrolled
|
||||
// out of view, then clip the ellipsis so that it looks like it is aligned
|
||||
// with the out of view content.
|
||||
if (mIEnd.IsNeeded() && mIEnd.mActive && mIEnd.mHasBlockEllipsis) {
|
||||
NS_ASSERTION(nonSnappedContentArea.IStart(mBlockWM) >
|
||||
aAlignmentEdges->mIEndOuter,
|
||||
"Expected the alignment edge for the out of view content "
|
||||
"to be before the start of the content area");
|
||||
mIEnd.mISize = std::max(
|
||||
mIEnd.mIntrinsicISize - (nonSnappedContentArea.IStart(mBlockWM) -
|
||||
aAlignmentEdges->mIEndOuter),
|
||||
0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (guessIStart == (mIStart.mActive && mIStart.IsNeeded()) &&
|
||||
|
@ -652,10 +681,10 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
}
|
||||
NS_ASSERTION(pass == 0, "2nd pass should never guess wrong");
|
||||
} while (++pass != 2);
|
||||
if (!istartOverflow || !mIStart.mActive) {
|
||||
if (!istartWantsMarker || !mIStart.mActive) {
|
||||
mIStart.Reset();
|
||||
}
|
||||
if (!iendOverflow || !mIEnd.mActive) {
|
||||
if (!iendWantsMarker || !mIEnd.mActive) {
|
||||
mIEnd.Reset();
|
||||
}
|
||||
return nonSnappedContentArea;
|
||||
|
@ -663,13 +692,18 @@ LogicalRect TextOverflow::ExamineLineFrames(nsLineBox* aLine,
|
|||
|
||||
void TextOverflow::ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine,
|
||||
uint32_t aLineNumber) {
|
||||
NS_ASSERTION(mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
|
||||
mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP,
|
||||
"TextOverflow with 'clip' for both sides");
|
||||
if (mIStart.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP &&
|
||||
mIEnd.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP &&
|
||||
!aLine->HasLineClampEllipsis()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIStart.Reset();
|
||||
mIStart.mActive = mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
mIEnd.Reset();
|
||||
mIEnd.mActive = mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
mIEnd.mHasBlockEllipsis = aLine->HasLineClampEllipsis();
|
||||
mIEnd.mActive = mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
|
||||
aLine->HasLineClampEllipsis();
|
||||
|
||||
FrameHashtable framesToHide(64);
|
||||
AlignmentEdges alignmentEdges;
|
||||
|
@ -680,11 +714,10 @@ void TextOverflow::ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine,
|
|||
if (!needIStart && !needIEnd) {
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(
|
||||
mIStart.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP || !needIStart,
|
||||
"left marker for 'clip'");
|
||||
NS_ASSERTION(mIEnd.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP || !needIEnd,
|
||||
"right marker for 'clip'");
|
||||
NS_ASSERTION(!mIStart.IsSuppressed() || !needIStart,
|
||||
"left marker when not needed");
|
||||
NS_ASSERTION(!mIEnd.IsSuppressed() || !needIEnd,
|
||||
"right marker when not needed");
|
||||
|
||||
// If there is insufficient space for both markers then keep the one on the
|
||||
// end side per the block's 'direction'.
|
||||
|
@ -699,11 +732,30 @@ void TextOverflow::ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine,
|
|||
if (needIEnd) {
|
||||
InflateIEnd(mBlockWM, &insideMarkersArea, -mIEnd.mISize);
|
||||
}
|
||||
if (!mCanHaveInlineAxisScrollbar && alignmentEdges.mAssigned) {
|
||||
|
||||
if (alignmentEdges.mAssignedInner) {
|
||||
if (mIStart.mEdgeAligned) {
|
||||
alignmentEdges.mIStart = insideMarkersArea.IStart(mBlockWM);
|
||||
}
|
||||
if (mIEnd.mEdgeAligned) {
|
||||
alignmentEdges.mIEnd = insideMarkersArea.IEnd(mBlockWM);
|
||||
}
|
||||
LogicalRect alignmentRect(mBlockWM, alignmentEdges.mIStart,
|
||||
insideMarkersArea.BStart(mBlockWM),
|
||||
alignmentEdges.ISize(), 1);
|
||||
insideMarkersArea.IntersectRect(insideMarkersArea, alignmentRect);
|
||||
} else {
|
||||
// There was no content on the line that was visible at the current scolled
|
||||
// position. If we wanted to place a block ellipsis but failed due to
|
||||
// having no visible content to align it to, we still need to ensure it
|
||||
// is displayed. It goes at the start of the line, even though it's an
|
||||
// IEnd marker, since that is the side of the line that the content has
|
||||
// been scrolled past. We set the insideMarkersArea to a zero-sized
|
||||
// rectangle placed next to the scrolled-out-of-view content.
|
||||
if (mIEnd.mHasBlockEllipsis) {
|
||||
insideMarkersArea = LogicalRect(mBlockWM, alignmentEdges.mIEndOuter,
|
||||
insideMarkersArea.BStart(mBlockWM), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Clip and remove display items as needed at the final marker edges.
|
||||
|
@ -762,16 +814,28 @@ void TextOverflow::PruneDisplayListContents(
|
|||
}
|
||||
|
||||
/* static */
|
||||
bool TextOverflow::HasClippedOverflow(nsIFrame* aBlockFrame) {
|
||||
bool TextOverflow::HasClippedTextOverflow(nsIFrame* aBlockFrame) {
|
||||
const nsStyleTextReset* style = aBlockFrame->StyleTextReset();
|
||||
return style->mTextOverflow.mLeft.mType == NS_STYLE_TEXT_OVERFLOW_CLIP &&
|
||||
style->mTextOverflow.mRight.mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool TextOverflow::CanHaveTextOverflow(nsIFrame* aBlockFrame) {
|
||||
bool TextOverflow::HasBlockEllipsis(nsIFrame* aBlockFrame) {
|
||||
nsBlockFrame* f = do_QueryFrame(aBlockFrame);
|
||||
return f && f->HasAnyStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool TextOverflow::CanHaveOverflowMarkers(nsIFrame* aBlockFrame) {
|
||||
// Treat a line with a -webkit-line-clamp ellipsis as a kind of text
|
||||
// overflow.
|
||||
if (aBlockFrame->HasAnyStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Nothing to do for text-overflow:clip or if 'overflow-x/y:visible'.
|
||||
if (HasClippedOverflow(aBlockFrame) ||
|
||||
if (HasClippedTextOverflow(aBlockFrame) ||
|
||||
IsInlineAxisOverflowVisible(aBlockFrame)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -815,8 +879,8 @@ void TextOverflow::CreateMarkers(const nsLineBox* aLine, bool aCreateIStart,
|
|||
ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
|
||||
markerRect, clipState);
|
||||
mMarkerList.AppendNewToTop<nsDisplayTextOverflowMarker>(
|
||||
mBuilder, mBlock, markerRect, aLine->GetLogicalAscent(), mIStart.mStyle,
|
||||
aLineNumber, 0);
|
||||
mBuilder, mBlock, markerRect, aLine->GetLogicalAscent(),
|
||||
*mIStart.mStyle, aLineNumber, 0);
|
||||
}
|
||||
|
||||
if (aCreateIEnd) {
|
||||
|
@ -831,7 +895,9 @@ void TextOverflow::CreateMarkers(const nsLineBox* aLine, bool aCreateIStart,
|
|||
ClipMarker(aContentArea.GetPhysicalRect(mBlockWM, mBlockSize) + offset,
|
||||
markerRect, clipState);
|
||||
mMarkerList.AppendNewToTop<nsDisplayTextOverflowMarker>(
|
||||
mBuilder, mBlock, markerRect, aLine->GetLogicalAscent(), mIEnd.mStyle,
|
||||
mBuilder, mBlock, markerRect, aLine->GetLogicalAscent(),
|
||||
mIEnd.mHasBlockEllipsis ? nsStyleTextOverflowSide::Ellipsis()
|
||||
: *mIEnd.mStyle,
|
||||
aLineNumber, 1);
|
||||
}
|
||||
}
|
||||
|
@ -841,7 +907,13 @@ void TextOverflow::Marker::SetupString(nsIFrame* aFrame) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS) {
|
||||
// A limitation here is that at the IEnd of a line, we only ever render one of
|
||||
// a text-overflow marker and a -webkit-line-clamp block ellipsis. Since we
|
||||
// don't track the block ellipsis string and the text-overflow marker string
|
||||
// separately, if both apply to the element, we will always use "…" as the
|
||||
// string for text-overflow.
|
||||
if (HasBlockEllipsis(aFrame) ||
|
||||
mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS) {
|
||||
gfxTextRun* textRun = GetEllipsisTextRun(aFrame);
|
||||
if (textRun) {
|
||||
mISize = textRun->GetAdvanceWidth();
|
||||
|
|
|
@ -64,14 +64,14 @@ class TextOverflow final {
|
|||
*/
|
||||
nsDisplayList& GetMarkers() { return mMarkerList; }
|
||||
|
||||
/**
|
||||
* @return true if aBlockFrmae has text-overflow:clip on both sides.
|
||||
*/
|
||||
static bool HasClippedOverflow(nsIFrame* aBlockFrame);
|
||||
/**
|
||||
* @return true if aBlockFrame needs analysis for text overflow.
|
||||
*/
|
||||
static bool CanHaveTextOverflow(nsIFrame* aBlockFrame);
|
||||
// Returns whether aBlockFrame has text-overflow:clip on both sides.
|
||||
static bool HasClippedTextOverflow(nsIFrame* aBlockFrame);
|
||||
|
||||
// Returns whether aBlockFrame has a block ellipsis on one of its lines.
|
||||
static bool HasBlockEllipsis(nsIFrame* aBlockFrame);
|
||||
|
||||
// Returns whether aBlockFrame needs analysis for text overflow.
|
||||
static bool CanHaveOverflowMarkers(nsIFrame* aBlockFrame);
|
||||
|
||||
typedef nsTHashtable<nsPtrHashKey<nsIFrame>> FrameHashtable;
|
||||
|
||||
|
@ -79,22 +79,36 @@ class TextOverflow final {
|
|||
typedef mozilla::WritingMode WritingMode;
|
||||
typedef mozilla::LogicalRect LogicalRect;
|
||||
|
||||
// Edges to align the IStart and IEnd markers to.
|
||||
struct AlignmentEdges {
|
||||
AlignmentEdges() : mIStart(0), mIEnd(0), mAssigned(false) {}
|
||||
void Accumulate(WritingMode aWM, const LogicalRect& aRect) {
|
||||
if (MOZ_LIKELY(mAssigned)) {
|
||||
AlignmentEdges()
|
||||
: mIStart(0), mIEnd(0), mIEndOuter(0), mAssignedInner(false) {}
|
||||
void AccumulateInner(WritingMode aWM, const LogicalRect& aRect) {
|
||||
if (MOZ_LIKELY(mAssignedInner)) {
|
||||
mIStart = std::min(mIStart, aRect.IStart(aWM));
|
||||
mIEnd = std::max(mIEnd, aRect.IEnd(aWM));
|
||||
} else {
|
||||
mIStart = aRect.IStart(aWM);
|
||||
mIEnd = aRect.IEnd(aWM);
|
||||
mAssigned = true;
|
||||
mAssignedInner = true;
|
||||
}
|
||||
}
|
||||
void AccumulateOuter(WritingMode aWM, const LogicalRect& aRect) {
|
||||
mIEndOuter = std::max(mIEndOuter, aRect.IEnd(aWM));
|
||||
}
|
||||
nscoord ISize() { return mIEnd - mIStart; }
|
||||
|
||||
// The outermost edges of all text and atomic inline-level frames that are
|
||||
// inside the area between the markers.
|
||||
nscoord mIStart;
|
||||
nscoord mIEnd;
|
||||
bool mAssigned;
|
||||
|
||||
// The closest IEnd edge of all text and atomic inline-level frames that
|
||||
// fall completely before the IStart edge of the content area. (Used to
|
||||
// align a block ellipsis when there are no visible frames to align to.)
|
||||
nscoord mIEndOuter;
|
||||
|
||||
bool mAssignedInner;
|
||||
};
|
||||
|
||||
struct InnerClipEdges {
|
||||
|
@ -136,8 +150,10 @@ class TextOverflow final {
|
|||
* and the bounds of what will be displayed between the markers.
|
||||
* @param aLine the line we're processing
|
||||
* @param aFramesToHide frames that should have their display items removed
|
||||
* @param aAlignmentEdges the outermost edges of all text and atomic
|
||||
* inline-level frames that are inside the area between the markers
|
||||
* @param aAlignmentEdges edges the markers will be aligned to, including
|
||||
* the outermost edges of all text and atomic inline-level frames that
|
||||
* are inside the content area, and the closest IEnd edge of such a frame
|
||||
* outside the content area
|
||||
* @return the area inside which we should add any markers;
|
||||
* this is the block's content area narrowed by any floats on this line.
|
||||
*/
|
||||
|
@ -151,8 +167,10 @@ class TextOverflow final {
|
|||
* @param aContentArea the block's content area
|
||||
* @param aInsideMarkersArea the rectangle between the markers
|
||||
* @param aFramesToHide frames that should have their display items removed
|
||||
* @param aAlignmentEdges the outermost edges of all text and atomic
|
||||
* inline-level frames that are inside the area between the markers
|
||||
* @param aAlignmentEdges edges the markers will be aligned to, including
|
||||
* the outermost edges of all text and atomic inline-level frames that
|
||||
* are inside the content area, and the closest IEnd edge of such a frame
|
||||
* outside the content area
|
||||
* @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
|
||||
* inline-level frame is visible between the marker edges
|
||||
* @param aClippedMarkerEdges the innermost edges of all text and atomic
|
||||
|
@ -179,6 +197,10 @@ class TextOverflow final {
|
|||
* @param aAlignmentEdges the outermost edges of all text and atomic
|
||||
* inline-level frames that are inside the area between the markers
|
||||
* inside aInsideMarkersArea
|
||||
* @param aAlignmentEdges edges the markers will be aligned to, including
|
||||
* the outermost edges of all text and atomic inline-level frames that
|
||||
* are inside aInsideMarkersArea, and the closest IEnd edge of such a frame
|
||||
* outside the content area
|
||||
* @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
|
||||
* inline-level frame is visible between the marker edges
|
||||
* @param aClippedMarkerEdges the innermost edges of all text and atomic
|
||||
|
@ -234,7 +256,9 @@ class TextOverflow final {
|
|||
mStyle = &aStyle;
|
||||
mIntrinsicISize = 0;
|
||||
mHasOverflow = false;
|
||||
mHasBlockEllipsis = false;
|
||||
mActive = false;
|
||||
mEdgeAligned = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,22 +266,35 @@ class TextOverflow final {
|
|||
*/
|
||||
void SetupString(nsIFrame* aFrame);
|
||||
|
||||
bool IsNeeded() const { return mHasOverflow; }
|
||||
void Reset() { mHasOverflow = false; }
|
||||
bool IsSuppressed() const {
|
||||
return !mHasBlockEllipsis && mStyle->mType == NS_STYLE_TEXT_OVERFLOW_CLIP;
|
||||
}
|
||||
bool IsNeeded() const { return mHasOverflow || mHasBlockEllipsis; }
|
||||
void Reset() {
|
||||
mHasOverflow = false;
|
||||
mHasBlockEllipsis = false;
|
||||
mEdgeAligned = false;
|
||||
}
|
||||
|
||||
// The current width of the marker, the range is [0 .. mIntrinsicISize].
|
||||
nscoord mISize;
|
||||
// The intrinsic width of the marker.
|
||||
nscoord mIntrinsicISize;
|
||||
// The style for this side.
|
||||
// The text-overflow style for this side. Ignored if we're rendering a
|
||||
// block ellipsis.
|
||||
const nsStyleTextOverflowSide* mStyle;
|
||||
// True if there is visible overflowing inline content on this side.
|
||||
bool mHasOverflow;
|
||||
// True if mMarkerString and mWidth have been setup from style.
|
||||
// True if this side has a block ellipsis (from -webkit-line-clamp).
|
||||
bool mHasBlockEllipsis;
|
||||
// True if mISize and mIntrinsicISize have been setup from style.
|
||||
bool mInitialized;
|
||||
// True if the style is text-overflow:clip on this side and the marker
|
||||
// True if the style is not text-overflow:clip on this side and the marker
|
||||
// won't cause the line to become empty.
|
||||
bool mActive;
|
||||
// True if this marker is aligned to the edge of the content box, so that
|
||||
// when scrolling the marker doesn't jump around.
|
||||
bool mEdgeAligned;
|
||||
};
|
||||
|
||||
Marker mIStart; // the inline start marker
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "mozilla/RestyleManager.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsFlexContainerFrame.h"
|
||||
|
||||
#include "nsBidiPresUtils.h"
|
||||
|
||||
|
@ -1057,6 +1058,139 @@ static LogicalSize CalculateContainingBlockSizeForAbsolutes(
|
|||
return cbSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns aFrame if it is a non-BFC block frame, and null otherwise.
|
||||
*
|
||||
* This is used to determine whether to recurse into aFrame when applying
|
||||
* -webkit-line-clamp.
|
||||
*/
|
||||
static nsBlockFrame* GetAsLineClampDescendant(nsIFrame* aFrame) {
|
||||
if (nsBlockFrame* block = do_QueryFrame(aFrame)) {
|
||||
if (!block->HasAllStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS)) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator over all descendant inline line boxes, except for those that are
|
||||
* under an independent formatting context.
|
||||
*/
|
||||
class MOZ_RAII LineClampLineIterator {
|
||||
public:
|
||||
explicit LineClampLineIterator(nsBlockFrame* aFrame)
|
||||
: mCur(aFrame->LinesBegin()),
|
||||
mEnd(aFrame->LinesEnd()),
|
||||
mCurrentFrame(mCur == mEnd ? nullptr : aFrame) {
|
||||
if (mCur != mEnd && !mCur->IsInline()) {
|
||||
Advance();
|
||||
}
|
||||
}
|
||||
|
||||
nsLineBox* GetCurrentLine() { return mCurrentFrame ? mCur.get() : nullptr; }
|
||||
nsBlockFrame* GetCurrentFrame() { return mCurrentFrame; }
|
||||
|
||||
// Advances the iterator to the next line line.
|
||||
//
|
||||
// Next() shouldn't be called once the iterator is at the end, which can be
|
||||
// checked for by GetCurrentLine() or GetCurrentFrame() returning null.
|
||||
void Next() {
|
||||
MOZ_ASSERT(mCur != mEnd && mCurrentFrame,
|
||||
"Don't call Next() when the iterator is at the end");
|
||||
++mCur;
|
||||
Advance();
|
||||
}
|
||||
|
||||
private:
|
||||
void Advance() {
|
||||
for (;;) {
|
||||
if (mCur == mEnd) {
|
||||
// Reached the end of the current block. Pop the parent off the
|
||||
// stack; if there isn't one, then we've reached the end.
|
||||
if (mStack.IsEmpty()) {
|
||||
mCurrentFrame = nullptr;
|
||||
break;
|
||||
}
|
||||
auto entry = mStack.PopLastElement();
|
||||
mCurrentFrame = entry.first();
|
||||
mCur = entry.second();
|
||||
mEnd = mCurrentFrame->LinesEnd();
|
||||
} else if (mCur->IsBlock()) {
|
||||
if (nsBlockFrame* child = GetAsLineClampDescendant(mCur->mFirstChild)) {
|
||||
nsBlockFrame::LineIterator next = mCur;
|
||||
++next;
|
||||
mStack.AppendElement(MakePair(mCurrentFrame, next));
|
||||
mCur = child->LinesBegin();
|
||||
mEnd = child->LinesEnd();
|
||||
mCurrentFrame = child;
|
||||
} else {
|
||||
// Some kind of frame we shouldn't descend into.
|
||||
++mCur;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mCur->IsInline());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The current line within the current block.
|
||||
//
|
||||
// When this is equal to mEnd, the iterator is at its end, and mCurrentFrame
|
||||
// is set to null.
|
||||
nsBlockFrame::LineIterator mCur;
|
||||
|
||||
// The iterator end for the current block.
|
||||
nsBlockFrame::LineIterator mEnd;
|
||||
|
||||
// The current block.
|
||||
nsBlockFrame* mCurrentFrame;
|
||||
|
||||
// Stack of mCurrentFrame and mEnd values that we push and pop as we enter and
|
||||
// exist blocks.
|
||||
AutoTArray<Pair<nsBlockFrame*, nsBlockFrame::LineIterator>, 8> mStack;
|
||||
};
|
||||
|
||||
static bool ClearLineClampEllipsis(nsBlockFrame* aFrame) {
|
||||
if (!aFrame->HasAnyStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS)) {
|
||||
for (nsIFrame* f : aFrame->PrincipalChildList()) {
|
||||
if (nsBlockFrame* child = GetAsLineClampDescendant(f)) {
|
||||
if (ClearLineClampEllipsis(child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
aFrame->RemoveStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
|
||||
nsBlockFrame::LineIterator line = aFrame->LinesBegin();
|
||||
nsBlockFrame::LineIterator end = aFrame->LinesEnd();
|
||||
while (line != end) {
|
||||
if (line->HasLineClampEllipsis()) {
|
||||
line->ClearHasLineClampEllipsis();
|
||||
return true;
|
||||
}
|
||||
++line;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("expected to find a line with HasLineClampEllipsis");
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsBlockFrame::ClearLineClampEllipsis() {
|
||||
::ClearLineClampEllipsis(this);
|
||||
}
|
||||
|
||||
static bool IsLineClampItem(const ReflowInput& aReflowInput) {
|
||||
return aReflowInput.mFlags.mApplyLineClamp ||
|
||||
(aReflowInput.mParentReflowInput &&
|
||||
aReflowInput.mParentReflowInput->mFrame->IsScrollFrame() &&
|
||||
aReflowInput.mParentReflowInput->mFlags.mApplyLineClamp);
|
||||
}
|
||||
|
||||
void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) {
|
||||
|
@ -1303,6 +1437,11 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
|||
// block-start padding.
|
||||
}
|
||||
|
||||
// Clear any existing -webkit-line-clamp ellipsis.
|
||||
if (IsLineClampItem(aReflowInput)) {
|
||||
ClearLineClampEllipsis();
|
||||
}
|
||||
|
||||
CheckFloats(state);
|
||||
|
||||
// Compute our final size
|
||||
|
@ -1515,6 +1654,109 @@ bool nsBlockFrame::CheckForCollapsedBEndMarginFromClearanceLine() {
|
|||
// not reached
|
||||
}
|
||||
|
||||
static nsLineBox* FindLineClampTarget(nsBlockFrame*& aFrame,
|
||||
uint32_t aLineNumber) {
|
||||
MOZ_ASSERT(aLineNumber > 0);
|
||||
MOZ_ASSERT(!aFrame->HasAnyStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS),
|
||||
"Should have been removed earlier in nsBlockReflow::Reflow");
|
||||
|
||||
nsLineBox* target = nullptr;
|
||||
nsBlockFrame* targetFrame = nullptr;
|
||||
bool foundFollowingLine = false;
|
||||
|
||||
LineClampLineIterator iter(aFrame);
|
||||
|
||||
while (nsLineBox* line = iter.GetCurrentLine()) {
|
||||
MOZ_ASSERT(!line->HasLineClampEllipsis(),
|
||||
"Should have been removed earlier in nsBlockFrame::Reflow");
|
||||
MOZ_ASSERT(!iter.GetCurrentFrame()->HasAnyStateBits(
|
||||
NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS),
|
||||
"Should have been removed earlier in nsBlockReflow::Reflow");
|
||||
|
||||
// Don't count a line that only has collapsible white space (as might exist
|
||||
// after calling e.g. getBoxQuads).
|
||||
if (line->IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aLineNumber == 0) {
|
||||
// We already previously found our target line, and now we have
|
||||
// confirmed that there is another line after it.
|
||||
foundFollowingLine = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (--aLineNumber == 0) {
|
||||
// This is our target line. Continue looping to confirm that we
|
||||
// have another line after us.
|
||||
target = line;
|
||||
targetFrame = iter.GetCurrentFrame();
|
||||
}
|
||||
|
||||
iter.Next();
|
||||
}
|
||||
|
||||
if (!foundFollowingLine) {
|
||||
aFrame = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(target);
|
||||
MOZ_ASSERT(targetFrame);
|
||||
|
||||
aFrame = targetFrame;
|
||||
return target;
|
||||
}
|
||||
|
||||
static nscoord ApplyLineClamp(const ReflowInput& aReflowInput,
|
||||
nsBlockFrame* aFrame, nscoord aContentBSize) {
|
||||
// We only do the work of applying the -webkit-line-clamp value during the
|
||||
// measuring bsize reflow. Boxes affected by -webkit-line-clamp are always
|
||||
// inflexible, so we will never need to select a different line to place the
|
||||
// ellipsis on in the subsequent real reflow.
|
||||
if (!IsLineClampItem(aReflowInput)) {
|
||||
return aContentBSize;
|
||||
}
|
||||
|
||||
auto container =
|
||||
static_cast<nsFlexContainerFrame*>(nsLayoutUtils::GetClosestFrameOfType(
|
||||
aFrame, LayoutFrameType::FlexContainer));
|
||||
MOZ_ASSERT(container,
|
||||
"A flex item affected by -webkit-line-clamp must have an ancestor "
|
||||
"flex container");
|
||||
|
||||
uint32_t lineClamp = container->GetLineClampValue();
|
||||
if (lineClamp == 0) {
|
||||
// -webkit-line-clamp is none or doesn't apply.
|
||||
return aContentBSize;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(container->HasAnyStateBits(NS_STATE_FLEX_IS_EMULATING_LEGACY_BOX),
|
||||
"Should only have an effective -webkit-line-clamp value if we "
|
||||
"are in a legacy flex container");
|
||||
|
||||
nsBlockFrame* frame = aFrame;
|
||||
nsLineBox* line = FindLineClampTarget(frame, lineClamp);
|
||||
if (!line) {
|
||||
// The number of lines did not exceed the -webkit-line-clamp value.
|
||||
return aContentBSize;
|
||||
}
|
||||
|
||||
// Mark the line as having an ellipsis so that TextOverflow will render it.
|
||||
line->SetHasLineClampEllipsis();
|
||||
frame->AddStateBits(NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
container->AddStateBits(NS_STATE_FLEX_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
|
||||
// Translate the b-end edge of the line up to aFrame's space.
|
||||
nscoord edge = line->BEnd();
|
||||
for (nsIFrame* f = frame; f != aFrame; f = f->GetParent()) {
|
||||
edge +=
|
||||
f->GetLogicalPosition(f->GetParent()->GetSize()).B(f->GetWritingMode());
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
void nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
|
||||
BlockReflowInput& aState,
|
||||
ReflowOutput& aMetrics,
|
||||
|
@ -1625,10 +1867,12 @@ void nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
|
|||
finalSize.BSize(wm) = autoBSize;
|
||||
} else if (aState.mReflowStatus.IsComplete()) {
|
||||
nscoord contentBSize = blockEndEdgeOfChildren - borderPadding.BStart(wm);
|
||||
nscoord autoBSize = aReflowInput.ApplyMinMaxBSize(contentBSize);
|
||||
nscoord lineClampedContentBSize =
|
||||
ApplyLineClamp(aReflowInput, this, contentBSize);
|
||||
nscoord autoBSize = aReflowInput.ApplyMinMaxBSize(lineClampedContentBSize);
|
||||
if (autoBSize != contentBSize) {
|
||||
// Our min- or max-bsize value made our bsize change. Don't carry out
|
||||
// our kids' block-end margins.
|
||||
// Our min-block-size, max-block-size, or -webkit-line-clamp value made
|
||||
// our bsize change. Don't carry out our kids' block-end margins.
|
||||
aMetrics.mCarriedOutBEndMargin.Zero();
|
||||
}
|
||||
autoBSize += borderPadding.BStart(wm) + borderPadding.BEnd(wm);
|
||||
|
@ -2808,9 +3052,9 @@ void nsBlockFrame::ReflowLine(BlockReflowInput& aState, LineIterator aLine,
|
|||
aLine->SetLineWrapped(false);
|
||||
ReflowInlineFrames(aState, aLine, aKeepReflowGoing);
|
||||
|
||||
// Store the line's float edges for text-overflow analysis if needed.
|
||||
// Store the line's float edges for overflow marker analysis if needed.
|
||||
aLine->ClearFloatEdges();
|
||||
if (aState.mFlags.mCanHaveTextOverflow) {
|
||||
if (aState.mFlags.mCanHaveOverflowMarkers) {
|
||||
WritingMode wm = aLine->mWritingMode;
|
||||
nsFlowAreaRect r = aState.GetFloatAvailableSpaceForBSize(
|
||||
aLine->BStart(), aLine->BSize(), nullptr);
|
||||
|
|
|
@ -577,6 +577,12 @@ class nsBlockFrame : public nsContainerFrame {
|
|||
// @see nsIFrame::AddSizeOfExcludingThisForTree
|
||||
void AddSizeOfExcludingThisForTree(nsWindowSizes&) const override;
|
||||
|
||||
/**
|
||||
* Clears any -webkit-line-clamp ellipsis on a line in this block or one
|
||||
* of its descendants.
|
||||
*/
|
||||
void ClearLineClampEllipsis();
|
||||
|
||||
protected:
|
||||
/** @see DoRemoveFrame */
|
||||
void DoRemoveFrameInternal(nsIFrame* aDeletedFrame, uint32_t aFlags,
|
||||
|
|
|
@ -833,6 +833,10 @@ class nsFlexContainerFrame::FlexItem : public LinkedListElement<FlexItem> {
|
|||
bool CanMainSizeInfluenceCrossSize(
|
||||
const FlexboxAxisTracker& aAxisTracker) const;
|
||||
|
||||
// Gets the block frame that contains the flex item's content. This is
|
||||
// Frame() itself or one of its descendants.
|
||||
nsBlockFrame* BlockFrame() const;
|
||||
|
||||
protected:
|
||||
// Helper called by the constructor, to set mNeedsMinSizeAutoResolution:
|
||||
void CheckForMinSizeAuto(const ReflowInput& aFlexItemReflowInput,
|
||||
|
@ -1262,19 +1266,25 @@ uint16_t nsFlexContainerFrame::CSSAlignmentForAbsPosChild(
|
|||
UniquePtr<FlexItem> nsFlexContainerFrame::GenerateFlexItemForChild(
|
||||
nsPresContext* aPresContext, nsIFrame* aChildFrame,
|
||||
const ReflowInput& aParentReflowInput,
|
||||
const FlexboxAxisTracker& aAxisTracker) {
|
||||
const FlexboxAxisTracker& aAxisTracker, bool aHasLineClampEllipsis) {
|
||||
// Create temporary reflow input just for sizing -- to get hypothetical
|
||||
// main-size and the computed values of min / max main-size property.
|
||||
// (This reflow input will _not_ be used for reflow.)
|
||||
ReflowInput childRI(
|
||||
aPresContext, aParentReflowInput, aChildFrame,
|
||||
aParentReflowInput.ComputedSize(aChildFrame->GetWritingMode()));
|
||||
childRI.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
|
||||
|
||||
// FLEX GROW & SHRINK WEIGHTS
|
||||
// --------------------------
|
||||
float flexGrow, flexShrink;
|
||||
if (IsLegacyBox(this)) {
|
||||
flexGrow = flexShrink = aChildFrame->StyleXUL()->mBoxFlex;
|
||||
if (GetLineClampValue() != 0) {
|
||||
// Items affected by -webkit-line-clamp are always inflexible.
|
||||
flexGrow = flexShrink = 0;
|
||||
} else {
|
||||
flexGrow = flexShrink = aChildFrame->StyleXUL()->mBoxFlex;
|
||||
}
|
||||
} else {
|
||||
const nsStylePosition* stylePos = aChildFrame->StylePosition();
|
||||
flexGrow = stylePos->mFlexGrow;
|
||||
|
@ -1379,7 +1389,8 @@ UniquePtr<FlexItem> nsFlexContainerFrame::GenerateFlexItemForChild(
|
|||
|
||||
// Resolve "flex-basis:auto" and/or "min-[width|height]:auto" (which might
|
||||
// require us to reflow the item to measure content height)
|
||||
ResolveAutoFlexBasisAndMinSize(aPresContext, *item, childRI, aAxisTracker);
|
||||
ResolveAutoFlexBasisAndMinSize(aPresContext, *item, childRI, aAxisTracker,
|
||||
aHasLineClampEllipsis);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
@ -1554,8 +1565,8 @@ static bool ResolveAutoFlexBasisFromRatio(
|
|||
// we may want to resolve that in this function, too.
|
||||
void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
|
||||
nsPresContext* aPresContext, FlexItem& aFlexItem,
|
||||
const ReflowInput& aItemReflowInput,
|
||||
const FlexboxAxisTracker& aAxisTracker) {
|
||||
const ReflowInput& aItemReflowInput, const FlexboxAxisTracker& aAxisTracker,
|
||||
bool aHasLineClampEllipsis) {
|
||||
// (Note: We can guarantee that the flex-basis will have already been
|
||||
// resolved if the main axis is the same is the same as the item's inline
|
||||
// axis. Inline-axis values should always be resolvable without reflow.)
|
||||
|
@ -1658,7 +1669,7 @@ void nsFlexContainerFrame::ResolveAutoFlexBasisAndMinSize(
|
|||
|
||||
nscoord contentBSize = MeasureFlexItemContentBSize(
|
||||
aPresContext, aFlexItem, forceBResizeForMeasuringReflow,
|
||||
*flexContainerRI);
|
||||
aHasLineClampEllipsis, *flexContainerRI);
|
||||
if (minSizeNeedsToMeasureContent) {
|
||||
resolvedMinSize = std::min(resolvedMinSize, contentBSize);
|
||||
}
|
||||
|
@ -1823,7 +1834,7 @@ void nsFlexContainerFrame::MarkIntrinsicISizesDirty() {
|
|||
|
||||
nscoord nsFlexContainerFrame::MeasureFlexItemContentBSize(
|
||||
nsPresContext* aPresContext, FlexItem& aFlexItem,
|
||||
bool aForceBResizeForMeasuringReflow,
|
||||
bool aForceBResizeForMeasuringReflow, bool aHasLineClampEllipsis,
|
||||
const ReflowInput& aParentReflowInput) {
|
||||
// Set up a reflow input for measuring the flex item's auto-height:
|
||||
WritingMode wm = aFlexItem.Frame()->GetWritingMode();
|
||||
|
@ -1833,6 +1844,9 @@ nscoord nsFlexContainerFrame::MeasureFlexItemContentBSize(
|
|||
aFlexItem.Frame(), availSize, Nothing(),
|
||||
ReflowInput::CALLER_WILL_INIT);
|
||||
childRIForMeasuringBSize.mFlags.mIsFlexContainerMeasuringBSize = true;
|
||||
childRIForMeasuringBSize.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
|
||||
childRIForMeasuringBSize.mFlags.mApplyLineClamp =
|
||||
childRIForMeasuringBSize.mFlags.mInsideLineClamp || aHasLineClampEllipsis;
|
||||
childRIForMeasuringBSize.Init(aPresContext);
|
||||
|
||||
if (aFlexItem.IsStretched()) {
|
||||
|
@ -3355,6 +3369,22 @@ void FlexItem::ResolveStretchedCrossSize(
|
|||
mIsStretched = true;
|
||||
}
|
||||
|
||||
static nsBlockFrame* FindFlexItemBlockFrame(nsIFrame* aFrame) {
|
||||
if (nsBlockFrame* block = do_QueryFrame(aFrame)) {
|
||||
return block;
|
||||
}
|
||||
for (nsIFrame* f : aFrame->PrincipalChildList()) {
|
||||
if (nsBlockFrame* block = FindFlexItemBlockFrame(f)) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsBlockFrame* FlexItem::BlockFrame() const {
|
||||
return FindFlexItemBlockFrame(Frame());
|
||||
}
|
||||
|
||||
void SingleLineCrossAxisPositionTracker::ResolveAutoMarginsInCrossAxis(
|
||||
const FlexLine& aLine, FlexItem& aItem) {
|
||||
// Subtract the space that our item is already occupying, to see how much
|
||||
|
@ -3728,7 +3758,8 @@ void nsFlexContainerFrame::GenerateFlexLines(
|
|||
nsPresContext* aPresContext, const ReflowInput& aReflowInput,
|
||||
nscoord aContentBoxMainSize, nscoord aAvailableBSizeForContent,
|
||||
const nsTArray<StrutInfo>& aStruts, const FlexboxAxisTracker& aAxisTracker,
|
||||
nscoord aMainGapSize, nsTArray<nsIFrame*>& aPlaceholders, /* out */
|
||||
nscoord aMainGapSize, bool aHasLineClampEllipsis,
|
||||
nsTArray<nsIFrame*>& aPlaceholders, /* out */
|
||||
LinkedList<FlexLine>& aLines /* out */) {
|
||||
MOZ_ASSERT(aLines.isEmpty(), "Expecting outparam to start out empty");
|
||||
|
||||
|
@ -3827,7 +3858,7 @@ void nsFlexContainerFrame::GenerateFlexLines(
|
|||
nextStrutIdx++;
|
||||
} else {
|
||||
item = GenerateFlexItemForChild(aPresContext, childFrame, aReflowInput,
|
||||
aAxisTracker);
|
||||
aAxisTracker, aHasLineClampEllipsis);
|
||||
}
|
||||
|
||||
nscoord itemInnerHypotheticalMainSize = item->GetMainSize();
|
||||
|
@ -4223,6 +4254,13 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
|
||||
}
|
||||
|
||||
// Check if there is a -webkit-line-clamp ellipsis somewhere inside at least
|
||||
// one of the flex items, so we can clear the flag before the block frame
|
||||
// re-sets it on the appropriate line during its bsize measuring reflow.
|
||||
bool hasLineClampEllipsis =
|
||||
HasAnyStateBits(NS_STATE_FLEX_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
RemoveStateBits(NS_STATE_FLEX_HAS_LINE_CLAMP_ELLIPSIS);
|
||||
|
||||
const FlexboxAxisTracker axisTracker(this, aReflowInput.GetWritingMode());
|
||||
|
||||
// Check to see if we need to create a computed info structure, to
|
||||
|
@ -4280,14 +4318,14 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
AutoTArray<StrutInfo, 1> struts;
|
||||
DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus,
|
||||
contentBoxMainSize, availableBSizeForContent, struts,
|
||||
axisTracker, mainGapSize, crossGapSize);
|
||||
axisTracker, mainGapSize, crossGapSize, hasLineClampEllipsis);
|
||||
|
||||
if (!struts.IsEmpty()) {
|
||||
// We're restarting flex layout, with new knowledge of collapsed items.
|
||||
aStatus.Reset();
|
||||
DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus,
|
||||
contentBoxMainSize, availableBSizeForContent, struts,
|
||||
axisTracker, mainGapSize, crossGapSize);
|
||||
axisTracker, mainGapSize, crossGapSize, hasLineClampEllipsis);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4502,7 +4540,7 @@ void nsFlexContainerFrame::DoFlexLayout(
|
|||
const ReflowInput& aReflowInput, nsReflowStatus& aStatus,
|
||||
nscoord aContentBoxMainSize, nscoord aAvailableBSizeForContent,
|
||||
nsTArray<StrutInfo>& aStruts, const FlexboxAxisTracker& aAxisTracker,
|
||||
nscoord aMainGapSize, nscoord aCrossGapSize) {
|
||||
nscoord aMainGapSize, nscoord aCrossGapSize, bool aHasLineClampEllipsis) {
|
||||
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||
|
||||
AutoCleanLinkedList<FlexLine> lines;
|
||||
|
@ -4510,7 +4548,8 @@ void nsFlexContainerFrame::DoFlexLayout(
|
|||
|
||||
GenerateFlexLines(aPresContext, aReflowInput, aContentBoxMainSize,
|
||||
aAvailableBSizeForContent, aStruts, aAxisTracker,
|
||||
aMainGapSize, placeholderKids, lines);
|
||||
aMainGapSize, aHasLineClampEllipsis, placeholderKids,
|
||||
lines);
|
||||
|
||||
if ((lines.getFirst()->IsEmpty() && !lines.getFirst()->getNext()) ||
|
||||
aReflowInput.mStyleDisplay->IsContainLayout()) {
|
||||
|
@ -4656,6 +4695,7 @@ void nsFlexContainerFrame::DoFlexLayout(
|
|||
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
|
||||
ReflowInput childReflowInput(aPresContext, aReflowInput, item->Frame(),
|
||||
availSize);
|
||||
childReflowInput.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
|
||||
if (!sizeOverride) {
|
||||
// Directly override the computed main-size, by tweaking reflow input:
|
||||
if (item->IsInlineAxisMainAxis()) {
|
||||
|
@ -4837,7 +4877,8 @@ void nsFlexContainerFrame::DoFlexLayout(
|
|||
const nscoord itemNormalBPos = framePos.B(flexWM);
|
||||
|
||||
// Check if we actually need to reflow the item -- if we already reflowed
|
||||
// it with the right size, we can just reposition it as-needed.
|
||||
// it with the right size, and there is no need to do a reflow to clear
|
||||
// out a -webkit-line-clamp ellipsis, we can just reposition it as-needed.
|
||||
bool itemNeedsReflow = true; // (Start out assuming the worst.)
|
||||
if (item->HadMeasuringReflow()) {
|
||||
LogicalSize finalFlexItemCBSize =
|
||||
|
@ -4869,7 +4910,17 @@ void nsFlexContainerFrame::DoFlexLayout(
|
|||
}
|
||||
if (itemNeedsReflow) {
|
||||
ReflowFlexItem(aPresContext, aAxisTracker, aReflowInput, *item,
|
||||
framePos, containerSize);
|
||||
framePos, containerSize, aHasLineClampEllipsis);
|
||||
}
|
||||
|
||||
// If we didn't perform a final reflow of the item, we still have a
|
||||
// -webkit-line-clamp ellipsis hanging around, but we shouldn't have one
|
||||
// any more, we need to clear that now. We strictly only need to do this
|
||||
// if we didn't do a bsize measuring reflow of the item earlier (since
|
||||
// that is normally when we deal with -webkit-line-clamp ellipses) but
|
||||
// not all flex items need such a reflow.
|
||||
if (!itemNeedsReflow && aHasLineClampEllipsis && GetLineClampValue() == 0) {
|
||||
item->BlockFrame()->ClearLineClampEllipsis();
|
||||
}
|
||||
|
||||
// If the item has auto margins, and we were tracking the UsedMargin
|
||||
|
@ -5029,13 +5080,21 @@ void nsFlexContainerFrame::MoveFlexItemToFinalPosition(
|
|||
void nsFlexContainerFrame::ReflowFlexItem(
|
||||
nsPresContext* aPresContext, const FlexboxAxisTracker& aAxisTracker,
|
||||
const ReflowInput& aReflowInput, const FlexItem& aItem,
|
||||
LogicalPoint& aFramePos, const nsSize& aContainerSize) {
|
||||
LogicalPoint& aFramePos, const nsSize& aContainerSize,
|
||||
bool aHasLineClampEllipsis) {
|
||||
WritingMode outerWM = aReflowInput.GetWritingMode();
|
||||
WritingMode wm = aItem.Frame()->GetWritingMode();
|
||||
LogicalSize availSize = aReflowInput.ComputedSize(wm);
|
||||
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
|
||||
ReflowInput childReflowInput(aPresContext, aReflowInput, aItem.Frame(),
|
||||
availSize);
|
||||
childReflowInput.mFlags.mInsideLineClamp = GetLineClampValue() != 0;
|
||||
// This is the final reflow of this flex item; if we previously had a
|
||||
// -webkit-line-clamp, and we missed our chance to clear the ellipsis
|
||||
// because we didn't need to call MeasureFlexItemContentBSize, we set
|
||||
// mApplyLineClamp to cause it to get cleared here.
|
||||
childReflowInput.mFlags.mApplyLineClamp =
|
||||
!childReflowInput.mFlags.mInsideLineClamp && aHasLineClampEllipsis;
|
||||
|
||||
// Keep track of whether we've overriden the child's computed ISize
|
||||
// and/or BSize, so we can set its resize flags accordingly.
|
||||
|
@ -5140,6 +5199,8 @@ void nsFlexContainerFrame::ReflowPlaceholders(
|
|||
LogicalSize availSize = aReflowInput.ComputedSize(wm);
|
||||
ReflowInput childReflowInput(aPresContext, aReflowInput, placeholder,
|
||||
availSize);
|
||||
// No need to set the -webkit-line-clamp related flags when reflowing
|
||||
// a placeholder.
|
||||
ReflowOutput childDesiredSize(childReflowInput);
|
||||
nsReflowStatus childReflowStatus;
|
||||
ReflowChild(placeholder, aPresContext, childDesiredSize, childReflowInput,
|
||||
|
@ -5237,3 +5298,17 @@ nscoord nsFlexContainerFrame::GetPrefISize(gfxContext* aRenderingContext) {
|
|||
|
||||
return mCachedPrefISize;
|
||||
}
|
||||
|
||||
uint32_t nsFlexContainerFrame::GetLineClampValue() const {
|
||||
// -webkit-line-clamp should only work on items in flex containers that are
|
||||
// display:-webkit-(inline-)box and -webkit-box-orient:vertical.
|
||||
//
|
||||
// This check makes -webkit-line-clamp work on display:-moz-box too, but
|
||||
// that shouldn't be a big deal.
|
||||
if (!HasAnyStateBits(NS_STATE_FLEX_IS_EMULATING_LEGACY_BOX) ||
|
||||
StyleXUL()->mBoxOrient != StyleBoxOrient::Vertical) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return StyleDisplay()->mLineClamp;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,14 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective value of -webkit-line-clamp for this flex container.
|
||||
*
|
||||
* This will be 0 if the property is 'none', or if the element is not
|
||||
* display:-webkit-(inline-)box and -webkit-box-orient:vertical.
|
||||
*/
|
||||
uint32_t GetLineClampValue() const;
|
||||
|
||||
// nsContainerFrame overrides
|
||||
uint16_t CSSAlignmentForAbsPosChild(
|
||||
const ReflowInput& aChildRI,
|
||||
|
@ -264,7 +272,8 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
nscoord aAvailableBSizeForContent,
|
||||
nsTArray<StrutInfo>& aStruts,
|
||||
const FlexboxAxisTracker& aAxisTracker,
|
||||
nscoord aMainGapSize, nscoord aCrossGapSize);
|
||||
nscoord aMainGapSize, nscoord aCrossGapSize,
|
||||
bool aHasLineClampEllipsis);
|
||||
|
||||
/**
|
||||
* Checks whether our child-frame list "mFrames" is sorted, using the given
|
||||
|
@ -297,7 +306,7 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
mozilla::UniquePtr<FlexItem> GenerateFlexItemForChild(
|
||||
nsPresContext* aPresContext, nsIFrame* aChildFrame,
|
||||
const ReflowInput& aParentReflowInput,
|
||||
const FlexboxAxisTracker& aAxisTracker);
|
||||
const FlexboxAxisTracker& aAxisTracker, bool aHasLineClampEllipsis);
|
||||
|
||||
/**
|
||||
* This method gets a cached measuring reflow for a flex item, or does it and
|
||||
|
@ -319,6 +328,7 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
nscoord MeasureFlexItemContentBSize(nsPresContext* aPresContext,
|
||||
FlexItem& aFlexItem,
|
||||
bool aForceBResizeForMeasuringReflow,
|
||||
bool aHasLineClampEllipsis,
|
||||
const ReflowInput& aParentReflowInput);
|
||||
|
||||
/**
|
||||
|
@ -329,7 +339,8 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
void ResolveAutoFlexBasisAndMinSize(nsPresContext* aPresContext,
|
||||
FlexItem& aFlexItem,
|
||||
const ReflowInput& aItemReflowInput,
|
||||
const FlexboxAxisTracker& aAxisTracker);
|
||||
const FlexboxAxisTracker& aAxisTracker,
|
||||
bool aHasLineClampEllipsis);
|
||||
|
||||
/**
|
||||
* Returns true if "this" is the nsFlexContainerFrame for a -moz-box or
|
||||
|
@ -358,7 +369,7 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
nscoord aAvailableBSizeForContent,
|
||||
const nsTArray<StrutInfo>& aStruts,
|
||||
const FlexboxAxisTracker& aAxisTracker,
|
||||
nscoord aMainGapSize,
|
||||
nscoord aMainGapSize, bool aHasLineClampEllipsis,
|
||||
nsTArray<nsIFrame*>& aPlaceholders,
|
||||
mozilla::LinkedList<FlexLine>& aLines);
|
||||
|
||||
|
@ -411,7 +422,7 @@ class nsFlexContainerFrame final : public nsContainerFrame {
|
|||
const FlexboxAxisTracker& aAxisTracker,
|
||||
const ReflowInput& aReflowInput, const FlexItem& aItem,
|
||||
mozilla::LogicalPoint& aFramePos,
|
||||
const nsSize& aContainerSize);
|
||||
const nsSize& aContainerSize, bool aHasLineClampEllipsis);
|
||||
|
||||
/**
|
||||
* Helper-function to perform a "dummy reflow" on all our nsPlaceholderFrame
|
||||
|
|
|
@ -350,6 +350,10 @@ FRAME_STATE_BIT(FlexContainer, 22, NS_STATE_FLEX_GENERATE_COMPUTED_VALUES)
|
|||
// True if the container has no flex items; may lie if there is a pending reflow
|
||||
FRAME_STATE_BIT(FlexContainer, 23, NS_STATE_FLEX_SYNTHESIZE_BASELINE)
|
||||
|
||||
// True if any flex item in the container has a line with a
|
||||
// -webkit-line-ellipsis marker.
|
||||
FRAME_STATE_BIT(FlexContainer, 24, NS_STATE_FLEX_HAS_LINE_CLAMP_ELLIPSIS)
|
||||
|
||||
// == Frame state bits that apply to grid container frames ====================
|
||||
|
||||
FRAME_STATE_GROUP(GridContainer, nsGridContainerFrame)
|
||||
|
@ -568,6 +572,12 @@ FRAME_STATE_BIT(Block, 29, NS_BLOCK_HAS_FIRST_LETTER_STYLE)
|
|||
FRAME_STATE_BIT(Block, 30, NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER)
|
||||
FRAME_STATE_BIT(Block, 31, NS_BLOCK_FRAME_HAS_INSIDE_MARKER)
|
||||
|
||||
// NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS indicates that exactly one line in this
|
||||
// block has the LineClampEllipsis flag set, and that such a line must be found
|
||||
// and have that flag cleared when reflowing this element's nearest legacy box
|
||||
// container.
|
||||
FRAME_STATE_BIT(Block, 60, NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS)
|
||||
|
||||
// This block has had a child marked dirty, so before we reflow we need
|
||||
// to look through the lines to find any such children and mark
|
||||
// appropriate lines dirty.
|
||||
|
|
|
@ -1185,6 +1185,7 @@ NS_QUERYFRAME_HEAD(nsHTMLScrollFrame)
|
|||
NS_QUERYFRAME_ENTRY(nsIScrollableFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollbarMediator)
|
||||
NS_QUERYFRAME_ENTRY(nsHTMLScrollFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
//----------nsXULScrollFrame-------------------------------------------
|
||||
|
|
|
@ -471,8 +471,9 @@ class ScrollFrameHelper : public nsIReflowCallback {
|
|||
PostScrollEndEvent();
|
||||
}
|
||||
mTransformingByAPZ = aTransforming;
|
||||
if (!mozilla::css::TextOverflow::HasClippedOverflow(mOuter)) {
|
||||
// If the block has some text-overflow stuff we should kick off a paint
|
||||
if (!mozilla::css::TextOverflow::HasClippedTextOverflow(mOuter) ||
|
||||
mozilla::css::TextOverflow::HasBlockEllipsis(mScrolledFrame)) {
|
||||
// If the block has some overflow marker stuff we should kick off a paint
|
||||
// because we have special behaviour for it when APZ scrolling is active.
|
||||
mOuter->SchedulePaint();
|
||||
}
|
||||
|
|
|
@ -267,6 +267,11 @@ class nsLineBox final : public nsLineLink {
|
|||
void ClearHadFloatPushed() { mFlags.mHadFloatPushed = false; }
|
||||
bool HadFloatPushed() const { return mFlags.mHadFloatPushed; }
|
||||
|
||||
// mHasLineClampEllipsis bit
|
||||
void SetHasLineClampEllipsis() { mFlags.mHasLineClampEllipsis = true; }
|
||||
void ClearHasLineClampEllipsis() { mFlags.mHasLineClampEllipsis = false; }
|
||||
bool HasLineClampEllipsis() const { return mFlags.mHasLineClampEllipsis; }
|
||||
|
||||
private:
|
||||
// Add a hash table for fast lookup when the line has more frames than this.
|
||||
static const uint32_t kMinChildCountForHashtable = 200;
|
||||
|
@ -608,6 +613,13 @@ class nsLineBox final : public nsLineLink {
|
|||
// that was pushed to a later column or page.
|
||||
bool mHadFloatPushed : 1;
|
||||
bool mHasHashedFrames : 1;
|
||||
// Indicates that this line is the one identified by an ancestor block
|
||||
// with -webkit-line-clamp on its legacy flex container, and that subsequent
|
||||
// lines under that block are "clamped" away, and therefore we need to
|
||||
// render a 'text-overflow: ellipsis'-like marker in this line. At most one
|
||||
// line in the set of lines found by LineClampLineIterator for a given
|
||||
// block will have this flag set.
|
||||
bool mHasLineClampEllipsis : 1;
|
||||
StyleClear mBreakType;
|
||||
};
|
||||
|
||||
|
|
|
@ -912,7 +912,8 @@ void nsLineLayout::ReflowFrame(nsIFrame* aFrame, nsReflowStatus& aReflowStatus,
|
|||
// in the line layout data structures. See bug 1490281 to fix the
|
||||
// underlying issue. When that's fixed this check should be removed.
|
||||
!outOfFlowFrame->IsLetterFrame() &&
|
||||
!GetOutermostLineLayout()->mBlockRI->mFlags.mCanHaveTextOverflow) {
|
||||
!GetOutermostLineLayout()
|
||||
->mBlockRI->mFlags.mCanHaveOverflowMarkers) {
|
||||
// We'll do this at the next break opportunity.
|
||||
RecordNoWrapFloat(outOfFlowFrame);
|
||||
} else {
|
||||
|
|
|
@ -2957,6 +2957,7 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
|
|||
mScrollSnapPointsY(eStyleUnit_None),
|
||||
mScrollSnapDestination(
|
||||
{LengthPercentage::Zero(), LengthPercentage::Zero()}),
|
||||
mLineClamp(0),
|
||||
mBackfaceVisibility(NS_STYLE_BACKFACE_VISIBILITY_VISIBLE),
|
||||
mTransformStyle(NS_STYLE_TRANSFORM_STYLE_FLAT),
|
||||
mTransformBox(StyleGeometryBox::BorderBox),
|
||||
|
@ -3022,6 +3023,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
|||
mScrollSnapPointsY(aSource.mScrollSnapPointsY),
|
||||
mScrollSnapDestination(aSource.mScrollSnapDestination),
|
||||
mScrollSnapCoordinate(aSource.mScrollSnapCoordinate),
|
||||
mLineClamp(aSource.mLineClamp),
|
||||
mBackfaceVisibility(aSource.mBackfaceVisibility),
|
||||
mTransformStyle(aSource.mTransformStyle),
|
||||
mTransformBox(aSource.mTransformBox),
|
||||
|
@ -3219,6 +3221,10 @@ nsChangeHint nsStyleDisplay::CalcDifference(
|
|||
}
|
||||
}
|
||||
|
||||
if (mLineClamp != aNewData.mLineClamp) {
|
||||
hint |= NS_STYLE_HINT_REFLOW;
|
||||
}
|
||||
|
||||
if (mVerticalAlign != aNewData.mVerticalAlign) {
|
||||
// XXX Can this just be AllReflowHints + RepaintFrame, and be included in
|
||||
// the block below?
|
||||
|
|
|
@ -1358,6 +1358,12 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
|||
struct nsStyleTextOverflowSide {
|
||||
nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
|
||||
|
||||
static nsStyleTextOverflowSide Ellipsis() {
|
||||
nsStyleTextOverflowSide side;
|
||||
side.mType = NS_STYLE_TEXT_OVERFLOW_ELLIPSIS;
|
||||
return side;
|
||||
}
|
||||
|
||||
bool operator==(const nsStyleTextOverflowSide& aOther) const {
|
||||
return mType == aOther.mType && (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
|
||||
mString == aOther.mString);
|
||||
|
@ -1901,6 +1907,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
nsStyleCoord mScrollSnapPointsY;
|
||||
mozilla::Position mScrollSnapDestination;
|
||||
nsTArray<mozilla::Position> mScrollSnapCoordinate;
|
||||
uint32_t mLineClamp;
|
||||
|
||||
// mSpecifiedTransform is the list of transform functions as
|
||||
// specified, or null to indicate there is no transform. (inherit or
|
||||
|
|
|
@ -217,6 +217,7 @@
|
|||
-moz-box-direction: inherit;
|
||||
-moz-box-pack: inherit;
|
||||
-moz-box-align: inherit;
|
||||
-webkit-line-clamp: inherit;
|
||||
/* Grid container */
|
||||
grid-auto-columns: inherit;
|
||||
grid-auto-rows: inherit;
|
||||
|
|
|
@ -8541,6 +8541,17 @@ if (IsCSSPropertyPrefEnabled("layout.css.column-span.enabled")) {
|
|||
};
|
||||
}
|
||||
|
||||
if (IsCSSPropertyPrefEnabled("layout.css.webkit-line-clamp.enabled")) {
|
||||
gCSSProperties["-webkit-line-clamp"] = {
|
||||
domProp: "webkitLineClamp",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "none" ],
|
||||
other_values: [ "1", "2" ],
|
||||
invalid_values: [ "auto", "0", "-1" ],
|
||||
};
|
||||
}
|
||||
|
||||
if (false) {
|
||||
// TODO These properties are chrome-only, and are not exposed via CSSOM.
|
||||
// We may still want to find a way to test them. See bug 1206999.
|
||||
|
|
|
@ -298,6 +298,7 @@ var supported_properties = {
|
|||
test_length_clamped, test_percent_clamped ],
|
||||
"word-spacing": [ test_length_transition, test_length_unclamped ],
|
||||
"z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ],
|
||||
"-webkit-line-clamp": [ test_pos_integer_or_none_transition ],
|
||||
"-webkit-text-fill-color": [ test_color_transition,
|
||||
test_currentcolor_transition ],
|
||||
"-webkit-text-stroke-color": [ test_color_transition,
|
||||
|
@ -2254,7 +2255,7 @@ function test_grid_gap(prop) {
|
|||
test_percent_clamped(prop);
|
||||
}
|
||||
|
||||
function test_pos_integer_or_auto_transition(prop) {
|
||||
function test_pos_integer_or_keyword_transition(prop, keyword) {
|
||||
div.style.setProperty("transition-property", "none", "");
|
||||
div.style.setProperty(prop, "4", "");
|
||||
is(cs.getPropertyValue(prop), "4",
|
||||
|
@ -2264,9 +2265,9 @@ function test_pos_integer_or_auto_transition(prop) {
|
|||
is(cs.getPropertyValue(prop), "6",
|
||||
"integer-valued property " + prop + ": interpolation of integers");
|
||||
check_distance(prop, "4", "6", "12");
|
||||
div.style.setProperty(prop, "auto", "");
|
||||
is(cs.getPropertyValue(prop), "auto",
|
||||
"integer-valued property " + prop + ": auto not interpolable");
|
||||
div.style.setProperty(prop, keyword, "");
|
||||
is(cs.getPropertyValue(prop), keyword,
|
||||
"integer-valued property " + prop + ": " + keyword + " not interpolable");
|
||||
div.style.setProperty(prop, "8", "");
|
||||
is(cs.getPropertyValue(prop), "8",
|
||||
"integer-valued property " + prop + ": computed value before transition");
|
||||
|
@ -2276,6 +2277,14 @@ function test_pos_integer_or_auto_transition(prop) {
|
|||
check_distance(prop, "8", "7", "4");
|
||||
}
|
||||
|
||||
function test_pos_integer_or_auto_transition(prop) {
|
||||
return test_pos_integer_or_keyword_transition(prop, "auto");
|
||||
}
|
||||
|
||||
function test_pos_integer_or_none_transition(prop) {
|
||||
return test_pos_integer_or_keyword_transition(prop, "none");
|
||||
}
|
||||
|
||||
function test_integer_at_least_one_clamping(prop) {
|
||||
div.style.setProperty("transition-timing-function", FUNC_NEGATIVE, "");
|
||||
div.style.setProperty("transition-property", "none", "");
|
||||
|
|
|
@ -1340,6 +1340,13 @@ VARCACHE_PREF(
|
|||
)
|
||||
#undef PREF_VALUE
|
||||
|
||||
// Is support for -webkit-line-clamp enabled?
|
||||
VARCACHE_PREF(
|
||||
"layout.css.webkit-line-clamp.enabled",
|
||||
layout_css_webkit_line_clamp_enabled,
|
||||
bool, true
|
||||
)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// JavaScript prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -337,6 +337,7 @@ class Longhand(object):
|
|||
"OverflowWrap",
|
||||
"OverscrollBehavior",
|
||||
"Percentage",
|
||||
"PositiveIntegerOrNone",
|
||||
"Resize",
|
||||
"SVGOpacity",
|
||||
"SVGPaintOrder",
|
||||
|
|
|
@ -2515,7 +2515,7 @@ fn static_assert() {
|
|||
rotate scroll-snap-points-x scroll-snap-points-y
|
||||
scroll-snap-coordinate -moz-binding will-change
|
||||
offset-path shape-outside
|
||||
translate scale""" %>
|
||||
translate scale -webkit-line-clamp""" %>
|
||||
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
||||
#[inline]
|
||||
pub fn generate_combined_transform(&mut self) {
|
||||
|
@ -2924,6 +2924,27 @@ fn static_assert() {
|
|||
self.copy_offset_path_from(other);
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set__webkit_line_clamp(&mut self, v: longhands::_webkit_line_clamp::computed_value::T) {
|
||||
self.gecko.mLineClamp = match v {
|
||||
Either::First(n) => n.0 as u32,
|
||||
Either::Second(None_) => 0,
|
||||
};
|
||||
}
|
||||
|
||||
${impl_simple_copy('_webkit_line_clamp', 'mLineClamp')}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone__webkit_line_clamp(&self) -> longhands::_webkit_line_clamp::computed_value::T {
|
||||
match self.gecko.mLineClamp {
|
||||
0 => Either::Second(None_),
|
||||
n => {
|
||||
debug_assert!(n <= std::i32::MAX as u32);
|
||||
Either::First((n as i32).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</%self:impl_trait>
|
||||
|
||||
<%def name="simple_image_array_property(name, shorthand, field_name)">
|
||||
|
|
|
@ -670,3 +670,15 @@ ${helpers.predefined_type(
|
|||
animation_value_type="discrete",
|
||||
spec="https://compat.spec.whatwg.org/#touch-action",
|
||||
)}
|
||||
|
||||
// Note that we only implement -webkit-line-clamp as a single, longhand
|
||||
// property for now, but the spec defines line-clamp as a shorthand for separate
|
||||
// max-lines, block-ellipsis, and continue properties.
|
||||
${helpers.predefined_type(
|
||||
"-webkit-line-clamp",
|
||||
"PositiveIntegerOrNone",
|
||||
"Either::Second(None_)",
|
||||
gecko_pref="layout.css.webkit-line-clamp.enabled",
|
||||
animation_value_type="Integer",
|
||||
spec="https://drafts.csswg.org/css-overflow-3/#line-clamp",
|
||||
)}
|
||||
|
|
|
@ -640,6 +640,9 @@ impl From<CSSInteger> for PositiveInteger {
|
|||
}
|
||||
}
|
||||
|
||||
/// A computed positive `<integer>` value or `none`.
|
||||
pub type PositiveIntegerOrNone = Either<PositiveInteger, None_>;
|
||||
|
||||
/// rect(...)
|
||||
pub type ClipRect = generics::ClipRect<LengthOrAuto>;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as Generic
|
|||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||
use super::generics::transform::IsParallelTo;
|
||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::{Auto, CSSFloat, CSSInteger, Either};
|
||||
use super::{Auto, CSSFloat, CSSInteger, Either, None_};
|
||||
use crate::context::QuirksMode;
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::serialize_atom_identifier;
|
||||
|
@ -593,6 +593,9 @@ impl Parse for PositiveInteger {
|
|||
}
|
||||
}
|
||||
|
||||
/// A specified positive `<integer>` value or `none`.
|
||||
pub type PositiveIntegerOrNone = Either<PositiveInteger, None_>;
|
||||
|
||||
/// The specified value of a grid `<track-breadth>`
|
||||
pub type TrackBreadth = GenericTrackBreadth<LengthPercentage>;
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[webkit-line-clamp-with-line-height.tentative.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: parsing -webkit-line-clamp with invalid values</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#webkit-line-clamp">
|
||||
<meta name="assert" content="-webkit-line-clamp supports only the grammar 'none | <integer>'.">
|
||||
<meta name="assert" content="Zero or negative max-lines integers are invalid.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_invalid_value("-webkit-line-clamp", 'auto');
|
||||
|
||||
test_invalid_value("-webkit-line-clamp", '0');
|
||||
test_invalid_value("-webkit-line-clamp", '-5');
|
||||
|
||||
test_invalid_value("-webkit-line-clamp", 'none "~"');
|
||||
test_invalid_value("-webkit-line-clamp", '1 "~"');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: parsing -webkit-line-clamp with valid values</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#webkit-line-clamp">
|
||||
<meta name="assert" content="-webkit-line-clamp supports the full grammar 'none | <integer>'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("-webkit-line-clamp", 'none');
|
||||
|
||||
test_valid_value("-webkit-line-clamp", '1');
|
||||
test_valid_value("-webkit-line-clamp", '6');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4…</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4…</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4…</div></div>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2…</div><div>Line A
|
||||
Line B…</div>Line 一
|
||||
Line 二…</div>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3…</div></div></div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5…</div></div>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
padding: 0 4px;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5…</div></div>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
display: flex;
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5…</div></div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<table class="child" border="1"><tr><td>Line 3
|
||||
Line 4</td></tr></table>Line 5…</div></div>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2…</div>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 4px 0;
|
||||
background-color: yellow;
|
||||
writing-mode: vertical-rl;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2…</div>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3…</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3…</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3…</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-inline-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
Before <div class="clamp">Line 1
|
||||
Line 2
|
||||
Line …</div> After</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
width: 11ch;
|
||||
}
|
||||
.float {
|
||||
float: right;
|
||||
color: orange;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div><div class="float">[f]</div>A B C D…</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<fieldset>Line 3
|
||||
Line 4<legend>Line 5
|
||||
Line 6</legend></fieldset>Line 7…</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
.child {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div class="child">Line 1
|
||||
Line 2
|
||||
Line 3…</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3…</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
.big {
|
||||
font-weight: bold;
|
||||
border-top: 2px solid blue;
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div class="item">Line 1
|
||||
Line 2
|
||||
Line 3 <span class="big">BIG</span>…</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
…</div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp when not display:-webkit-box</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-001-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should not apply to an element that is not a flex item for a legacy -webkit-box or -webkit-inline-box flex container.">
|
||||
<style>
|
||||
.clamp {
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp when not -webkit-box-orient:vertical</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-001-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should not apply to an element whose parent is not -webkit-box-orient:vertical.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with fewer lines than specified</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-001-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should not have an effect on an element with fewer lines than specified.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 6;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with exactly as many lines as specified</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-001-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should not have an effect on an element with exactly as many lines as specified.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 5;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with more lines than specified</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should clamp to the specified number of lines.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
padding: 0 4px;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: sizing of -webkit-line-clamp affected elements</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-006-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should size the element to the clamped number of lines.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp applied to a non-anonymous flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-007-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should apply to a flex item in a -webkit-box or -webkit-inline-box flex container.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div></div>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp applied to all flex items</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-008-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should apply to all flex items in a -webkit-box or -webkit-inline-box flex container independently.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
}
|
||||
div {
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3</div><div>Line A
|
||||
Line B
|
||||
Line C</div>Line 一
|
||||
Line 二
|
||||
Line 三</div>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with non-BFC block children in flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-009-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should count lines in non-BFC block children of the flex items.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div></div></div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with non-BFC block children in flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-010-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should count lines in non-BFC block children of the flex items.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 5;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5
|
||||
Line 6</div></div>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with BFC child in flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-011-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should skip lines in BFC children of the flex items.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
overflow: auto;
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
padding: 0 4px;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5
|
||||
Line 6</div></div>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with flex container child in flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-012-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should skip lines in independent formatting contexts in the flex items.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
display: flex;
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<div class="child">Line 3
|
||||
Line 4</div>Line 5
|
||||
Line 6</div></div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with table child in flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-013-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should skip lines in independent formatting contexts in the flex items.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
font: 24px / 48px serif;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<table class="child" border="1"><tr><td>Line 3
|
||||
Line 4</td></tr></table>Line 5
|
||||
Line 6</div></div>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp on RTL flex item</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-014-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should place the ellipsis appropriately in RTL content.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3</div>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp on vertical writing mode flex item when -webkit-box-orient:horizontal</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-015-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should not apply to a -webkit-box-orient:horizontal flex item even if using a vertical writing mode.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-line-clamp: 2;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 4px 0;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
writing-mode: vertical-rl;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp value on flex child</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-016-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp value on the flex child should be ignored.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div class="child">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div></div>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing -webkit-line-clamp</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-017-ref.html">
|
||||
<meta name="assert" content="Dynamically changing -webkit-line-clamp on an element from none to a number less than the number of lines should apply the clamping.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").style.webkitLineClamp = 3;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing -webkit-line-clamp</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-018-ref.html">
|
||||
<meta name="assert" content="Dynamically changing -webkit-line-clamp on an element from a number to none remove the clamping.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").style.webkitLineClamp = "none";
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing -webkit-line-clamp</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-019-ref.html">
|
||||
<meta name="assert" content="Dynamically changing -webkit-line-clamp on an element from a number less than to a number greater than the number of lines.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").style.webkitLineClamp = 6;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing -webkit-line-clamp</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-020-ref.html">
|
||||
<meta name="assert" content="Dynamically changing -webkit-line-clamp on an element from a number greater than to a number less than the number of lines.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 6;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").style.webkitLineClamp = 3;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing contents of a -webkit-line-clamp affected element</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-021-ref.html">
|
||||
<meta name="assert" content="Dynamically changing contents of a -webkit-line-clamp element so that it exceeds the specified number of lines should start clamping.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").textContent = `Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5`;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing contents of a -webkit-line-clamp affected element</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-022-ref.html">
|
||||
<meta name="assert" content="Dynamically changing contents of a -webkit-line-clamp element so that it no longer exceeds the specified number of lines should stop clamping.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").textContent = `Line 1
|
||||
Line 2`;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing contents of a -webkit-line-clamp affected element</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-023-ref.html">
|
||||
<meta name="assert" content="Dynamically changing contents of a -webkit-line-clamp element so that it matches the specified number of lines should stop clamping.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").textContent = `Line 1
|
||||
Line 2
|
||||
Line 3`;
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp on a display:-webkit-inline-box container</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-024-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should apply to display:-webkit-inline-box containers.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-inline-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
Before <div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div> After</div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with floats</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-025-ref.html">
|
||||
<meta name="assert" content="A -webkit-line-clamp induced ellipsis is placed after shrinking the line due to floats.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
width: 11ch;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.float {
|
||||
float: right;
|
||||
color: orange;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div><div class="float">[f]</div>A B C D
|
||||
E F G H</div></div>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: Dynamically changing -webkit-box-orient when -webkit-line-clamp applies</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-026-ref.html">
|
||||
<meta name="assert" content="Dynamically changing a -webkit-line-clamp affected element to be -webkit-box-orient:horizontal should cause the line clamp to be removed.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div>
|
||||
<p>Following content.</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector(".clamp").style.webkitBoxOrient = "horizontal";
|
||||
document.documentElement.className = "";
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp and fieldset</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-027-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should skip over fieldsets.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2<fieldset>Line 3
|
||||
Line 4<legend>Line 5
|
||||
Line 6</legend></fieldset>Line 7
|
||||
Line 8</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp and scrollable items</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-029-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should apply to flex items that are scrollable.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.child {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div class="child">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp and scrollable container</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-030-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should apply to flex items when the container is scrollable.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px monospace;
|
||||
white-space: pre;
|
||||
background-color: yellow;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
Line 4
|
||||
Line 5</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp and a line with inlines of different heights</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-031-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should clamp to the bottom of the line box.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
.big {
|
||||
font-weight: bold;
|
||||
border-top: 2px solid blue;
|
||||
border-bottom: 2px solid blue;
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
<div class="clamp"><div>Line 1
|
||||
Line 2
|
||||
Line 3 <span class="big">BIG</span>
|
||||
Line 4
|
||||
Line 5</div></div>
|
||||
<p>Following content.</p>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Overflow: -webkit-line-clamp with an ellipsis on a blank line</title>
|
||||
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="reference/webkit-line-clamp-032-ref.html">
|
||||
<meta name="assert" content="-webkit-line-clamp should render an ellipsis on a blank line.">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
font: 16px / 32px serif;
|
||||
white-space: pre;
|
||||
padding: 0 4px;
|
||||
background-color: yellow;
|
||||
overflow: hidden; /* can be removed once implementations update their old -webkit-line-clamp implementations */
|
||||
}
|
||||
</style>
|
||||
<div class="clamp">Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
|
||||
Line 5</div>
|
Загрузка…
Ссылка в новой задаче