Commit 2fa7d005 authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

Resolve text-indent percentages to 0 for intrinsic sizing.

Percentages must be ignored when calculating min/max intrinsic /
preferred inline sizes, since the inline size is by definition unknown
at that point.

This fixes the problem both in the legacy engine and in LayoutNG.

Bug: 906663
Change-Id: Ib29a66ee3d6146e72e6f9ec3283293af48e633a0
Reviewed-on: https://chromium-review.googlesource.com/c/1344090Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609734}
parent 6082921d
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-indent-property">
<meta name="assert" content="Percentages should be ignored when calculating min/max intrinsic sizes.">
<p>Test passes if there is a filled green square.</p>
<div id="container" data-expected-width="50" style="position:relative; float:left; height:100px; background:green;">
<div id="foo">
<div data-offset-x="50" data-expected-width="50" style="display:inline-block; width:50px; height:100px; background:green;"></div>
<div style="width:50px;"></div>
</div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
foo.style.textIndent = "100%";
checkLayout("#container");
</script>
...@@ -1606,9 +1606,6 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths( ...@@ -1606,9 +1606,6 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
LayoutUnit inline_min; LayoutUnit inline_min;
const ComputedStyle& style_to_use = StyleRef(); const ComputedStyle& style_to_use = StyleRef();
LayoutBlock* containing_block = ContainingBlock();
LayoutUnit cw =
containing_block ? containing_block->ContentLogicalWidth() : LayoutUnit();
// If we are at the start of a line, we want to ignore all white-space. // If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space. // Also strip spaces if we previously had text that ended in a trailing space.
...@@ -1633,7 +1630,9 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths( ...@@ -1633,7 +1630,9 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
// Signals the text indent was more negative than the min preferred width // Signals the text indent was more negative than the min preferred width
bool has_remaining_negative_text_indent = false; bool has_remaining_negative_text_indent = false;
LayoutUnit text_indent = MinimumValueForLength(style_to_use.TextIndent(), cw); // Always resolve percentages to 0 when calculating preferred logical widths.
LayoutUnit text_indent =
MinimumValueForLength(style_to_use.TextIndent(), LayoutUnit());
LayoutObject* prev_float = nullptr; LayoutObject* prev_float = nullptr;
bool is_prev_child_inline_flow = false; bool is_prev_child_inline_flow = false;
bool should_break_line_after_text = false; bool should_break_line_after_text = false;
......
...@@ -26,25 +26,10 @@ NGInlineItemResult::NGInlineItemResult(const NGInlineItem* item, ...@@ -26,25 +26,10 @@ NGInlineItemResult::NGInlineItemResult(const NGInlineItem* item,
void NGLineInfo::SetLineStyle(const NGInlineNode& node, void NGLineInfo::SetLineStyle(const NGInlineNode& node,
const NGInlineItemsData& items_data, const NGInlineItemsData& items_data,
const NGConstraintSpace& constraint_space, bool use_first_line_style) {
bool is_first_line,
bool use_first_line_style,
bool is_after_forced_break) {
use_first_line_style_ = use_first_line_style; use_first_line_style_ = use_first_line_style;
items_data_ = &items_data; items_data_ = &items_data;
line_style_ = node.GetLayoutBox()->Style(use_first_line_style_); line_style_ = node.GetLayoutBox()->Style(use_first_line_style_);
if (line_style_->ShouldUseTextIndent(is_first_line, is_after_forced_break)) {
// TODO(kojii): ComputeMinMaxSize does not know parent constraint
// space that we cannot compute percent for text-indent.
const Length& length = line_style_->TextIndent();
LayoutUnit maximum_value;
if (length.IsPercentOrCalc())
maximum_value = constraint_space.AvailableSize().inline_size;
text_indent_ = MinimumValueForLength(length, maximum_value);
} else {
text_indent_ = LayoutUnit();
}
} }
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
namespace blink { namespace blink {
class NGConstraintSpace;
class NGInlineItem; class NGInlineItem;
class NGInlineNode; class NGInlineNode;
...@@ -132,10 +131,7 @@ class CORE_EXPORT NGLineInfo { ...@@ -132,10 +131,7 @@ class CORE_EXPORT NGLineInfo {
} }
void SetLineStyle(const NGInlineNode&, void SetLineStyle(const NGInlineNode&,
const NGInlineItemsData&, const NGInlineItemsData&,
const NGConstraintSpace&, bool use_first_line_style);
bool is_first_formatted_line,
bool use_first_line_style,
bool is_after_forced_break);
// Use ::first-line style if true. // Use ::first-line style if true.
// https://drafts.csswg.org/css-pseudo/#selectordef-first-line // https://drafts.csswg.org/css-pseudo/#selectordef-first-line
...@@ -159,6 +155,7 @@ class CORE_EXPORT NGLineInfo { ...@@ -159,6 +155,7 @@ class CORE_EXPORT NGLineInfo {
NGInlineItemResults* MutableResults() { return &results_; } NGInlineItemResults* MutableResults() { return &results_; }
const NGInlineItemResults& Results() const { return results_; } const NGInlineItemResults& Results() const { return results_; }
void SetTextIndent(LayoutUnit indent) { text_indent_ = indent; }
LayoutUnit TextIndent() const { return text_indent_; } LayoutUnit TextIndent() const { return text_indent_; }
NGBfcOffset BfcOffset() const { return bfc_offset_; } NGBfcOffset BfcOffset() const { return bfc_offset_; }
......
...@@ -158,9 +158,20 @@ void NGLineBreaker::PrepareNextLine() { ...@@ -158,9 +158,20 @@ void NGLineBreaker::PrepareNextLine() {
} }
line_info_->SetStartOffset(offset_); line_info_->SetStartOffset(offset_);
line_info_->SetLineStyle(node_, items_data_, constraint_space_, line_info_->SetLineStyle(node_, items_data_, use_first_line_style_);
is_first_formatted_line_, use_first_line_style_,
previous_line_had_forced_break_); DCHECK(!line_info_->TextIndent());
if (line_info_->LineStyle().ShouldUseTextIndent(
is_first_formatted_line_, previous_line_had_forced_break_)) {
const Length& length = line_info_->LineStyle().TextIndent();
LayoutUnit maximum_value;
// Ignore percentages (resolve to 0) when calculating min/max intrinsic
// sizes.
if (length.IsPercentOrCalc() && mode_ == NGLineBreakerMode::kContent)
maximum_value = constraint_space_.AvailableSize().inline_size;
line_info_->SetTextIndent(MinimumValueForLength(length, maximum_value));
}
// Set the initial style of this line from the break token. Example: // Set the initial style of this line from the break token. Example:
// <p>...<span>....</span></p> // <p>...<span>....</span></p>
// When the line wraps in <span>, the 2nd line needs to start with the style // When the line wraps in <span>, the 2nd line needs to start with the style
......
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