Commit 099c04c7 authored by Ian Kilpatrick's avatar Ian Kilpatrick Committed by Commit Bot

[layout] Fix -webkit-line-clamp with text-overflow: ellipsis

Previously we'd apply line truncation when either -webkit-line-clamp
was active, *or* if "text-overflow: ellipsis" was active.

This patch disables the "text-overflow: ellipsis" branch when we are
within a -webkit-line-clamp context.

Bug: 1134483
Change-Id: I5ceb40732bd512e5eb8dc59365e10c4fdd4cf15d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2447610
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816554}
parent 72e7724e
......@@ -326,8 +326,11 @@ void NGInlineLayoutAlgorithm::CreateLine(
container_builder_.SetHangInlineSize(hang_width);
}
// Truncate the line if 'text-overflow: ellipsis' is set, or for line-clamp.
// Truncate the line if:
// - 'text-overflow: ellipsis' is set and we *aren't* a line-clamp context.
// - If we've reached the line-clamp limit.
if (UNLIKELY((line_info->HasOverflow() &&
!ConstraintSpace().IsLineClampContext() &&
node_.GetLayoutBlockFlow()->ShouldTruncateOverflowingText()) ||
ConstraintSpace().LinesUntilClamp() == 1)) {
NGLineTruncator truncator(*line_info);
......
......@@ -199,9 +199,14 @@ NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params),
previous_result_(params.previous_result),
fit_all_lines_(false),
is_resuming_(IsResumingLayout(params.break_token)),
exclusion_space_(params.space.ExclusionSpace()),
abort_when_bfc_block_offset_updated_(false),
has_processed_first_child_(false),
ignore_line_clamp_(false),
is_line_clamp_context_(params.space.IsLineClampContext()),
lines_until_clamp_(params.space.LinesUntilClamp()),
exclusion_space_(params.space.ExclusionSpace()),
early_break_(params.early_break) {}
// Define the destructor here, so that we can forward-declare more in the
......@@ -496,6 +501,7 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
}
if (Style().IsDeprecatedWebkitBoxWithVerticalLineClamp()) {
is_line_clamp_context_ = true;
if (!ignore_line_clamp_)
lines_until_clamp_ = Style().LineClamp();
} else if (Style().HasLineClamp()) {
......@@ -2494,6 +2500,7 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
builder.SetAdjoiningObjectTypes(
container_builder_.AdjoiningObjectTypes());
}
builder.SetIsLineClampContext(is_line_clamp_context_);
builder.SetLinesUntilClamp(lines_until_clamp_);
} else if (child_data.allow_discard_start_margin) {
// If the child is being resumed after a break, margins inside the child may
......
......@@ -372,10 +372,10 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// break. In that case we'll break before first_overflowing_line_. In this
// case there'll either be enough widows for the next fragment, or we have
// determined that we're unable to fulfill the widows request.
bool fit_all_lines_ = false;
bool fit_all_lines_ : 1;
// Set if we're resuming layout of a node that has already produced fragments.
bool is_resuming_;
bool is_resuming_ : 1;
// Set when we're to abort if the BFC block offset gets resolved or updated.
// Sometimes we walk past elements (i.e. floats) that depend on the BFC block
......@@ -383,21 +383,24 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// When this happens, and we finally manage to resolve (or update) the BFC
// block offset at some subsequent element, we need to check if this flag is
// set, and abort layout if it is.
bool abort_when_bfc_block_offset_updated_ = false;
bool abort_when_bfc_block_offset_updated_ : 1;
// This will be set during block fragmentation once we've processed the first
// in-flow child of a container. It is used to check if we're at a valid class
// A or B breakpoint (between block-level siblings or line box siblings).
bool has_processed_first_child_ = false;
bool has_processed_first_child_ : 1;
NGExclusionSpace exclusion_space_;
// If true, ignore the line-clamp property as truncation wont be required.
bool ignore_line_clamp_ : 1;
// If this is within a -webkit-line-clamp context.
bool is_line_clamp_context_ : 1;
// If set, this is the number of lines until a clamp. A value of 1 indicates
// the current line should be clamped. This may go negative.
base::Optional<int> lines_until_clamp_;
// If true, ignore the line-clamp property as truncation wont be required.
bool ignore_line_clamp_ = false;
NGExclusionSpace exclusion_space_;
// If set, one of the lines was clamped and this is the intrinsic size at the
// time of the clamp.
......
......@@ -603,6 +603,9 @@ class CORE_EXPORT NGConstraintSpace final {
return HasRareData() ? rare_data_->ClearanceOffset() : LayoutUnit::Min();
}
// Return true if this is participating within a -webkit-line-clamp context.
bool IsLineClampContext() const { return bitfields_.is_line_clamp_context; }
base::Optional<int> LinesUntilClamp() const {
return HasRareData() ? rare_data_->LinesUntilClamp() : base::nullopt;
}
......@@ -1244,6 +1247,7 @@ class CORE_EXPORT NGConstraintSpace final {
is_anonymous(false),
is_new_formatting_context(false),
is_orthogonal_writing_mode_root(false),
is_line_clamp_context(false),
is_painted_atomically(false),
use_first_line_style(false),
ancestor_has_clearance_past_adjoining_floats(false),
......@@ -1271,6 +1275,7 @@ class CORE_EXPORT NGConstraintSpace final {
is_new_formatting_context == other.is_new_formatting_context &&
is_orthogonal_writing_mode_root ==
other.is_orthogonal_writing_mode_root &&
is_line_clamp_context == other.is_line_clamp_context &&
is_painted_atomically == other.is_painted_atomically &&
use_first_line_style == other.use_first_line_style &&
ancestor_has_clearance_past_adjoining_floats ==
......@@ -1299,6 +1304,7 @@ class CORE_EXPORT NGConstraintSpace final {
unsigned is_anonymous : 1;
unsigned is_new_formatting_context : 1;
unsigned is_orthogonal_writing_mode_root : 1;
unsigned is_line_clamp_context : 1;
unsigned is_painted_atomically : 1;
unsigned use_first_line_style : 1;
......
......@@ -374,6 +374,11 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
section_index);
}
void SetIsLineClampContext(bool is_line_clamp_context) {
DCHECK(!is_new_fc_);
space_.bitfields_.is_line_clamp_context = is_line_clamp_context;
}
void SetLinesUntilClamp(const base::Optional<int>& clamp) {
#if DCHECK_IS_ON()
DCHECK(!is_lines_until_clamp_set_);
......
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
width: 150px;
font: 16px / 32px monospace;
background-color: yellow;
padding: 4px;
overflow: hidden;
}
</style>
<div class="clamp">
supercalifragilisticexpialidocious
supercalifragi…
</div>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
width: 150px;
font: 16px / 32px monospace;
background-color: yellow;
padding: 4px;
overflow: hidden;
}
</style>
<div class="clamp">
supercalifragilisticexpialidocious
supercalifragilisticexpialidocious
</div>
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
<link rel="match" href="reference/webkit-line-clamp-036-ref.html">
<meta name="assert" content="text-overflow: ellipsis shouldn't apply within a -webkit-line-clamp context.">
<style>
.clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
width: 150px;
font: 16px / 32px monospace;
background-color: yellow;
padding: 4px;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="clamp">
supercalifragilisticexpialidocious
supercalifragilisticexpialidocious
supercalifragilisticexpialidocious
</div>
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
<link rel="match" href="reference/webkit-line-clamp-037-ref.html">
<meta name="assert" content="text-overflow: ellipsis shouldn't apply within a -webkit-line-clamp context.">
<style>
.clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
width: 150px;
font: 16px / 32px monospace;
background-color: yellow;
padding: 4px;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="clamp">
supercalifragilisticexpialidocious
supercalifragilisticexpialidocious
</div>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment