Commit cd18243c authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Chromium LUCI CQ

Implement custom 'pad' values for @counter-style

Bug: 687225
Change-Id: Id90bf61c99aabcd464d12f9f43e95ec9bf5d5eb4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2585676
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836847}
parent c3aca307
......@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/css/css_value_pair.h"
#include "third_party/blink/renderer/core/css/style_rule_counter_style.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
......@@ -246,6 +247,12 @@ CounterStyle::CounterStyle(const StyleRuleCounterStyle& rule)
}
}
if (const CSSValue* pad = rule.GetPad()) {
const CSSValuePair& pair = To<CSSValuePair>(*pad);
pad_length_ = To<CSSPrimitiveValue>(pair.First()).GetIntValue();
pad_symbol_ = SymbolToString(pair.Second());
}
// TODO(crbug.com/687225): Implement and populate other fields.
}
......@@ -269,6 +276,11 @@ void CounterStyle::ResolveExtends(const CounterStyle& extended) {
negative_suffix_ = extended.negative_suffix_;
}
if (!style_rule_->GetPad()) {
pad_length_ = extended.pad_length_;
pad_symbol_ = extended.pad_symbol_;
}
// TODO(crbug.com/687225): Implement and populate other fields.
}
......@@ -324,23 +336,37 @@ bool CounterStyle::NeedsNegativeSign(int value) const {
}
}
String CounterStyle::GenerateRepresentation(int value) const {
String CounterStyle::GenerateFallbackRepresentation(int value) const {
if (is_in_fallback_) {
// We are in a fallback cycle. Use decimal instead.
return GetDecimal().GenerateRepresentation(value);
}
base::AutoReset<bool> in_fallback_scope(&is_in_fallback_, true);
return fallback_style_->GenerateRepresentation(value);
}
String CounterStyle::GenerateRepresentation(int value) const {
if (pad_length_ > kCounterLengthLimit)
return GenerateFallbackRepresentation(value);
String initial_representation = GenerateInitialRepresentation(value);
if (initial_representation.IsNull()) {
base::AutoReset<bool> in_fallback_scope(&is_in_fallback_, true);
return fallback_style_->GenerateRepresentation(value);
}
if (initial_representation.IsNull())
return GenerateFallbackRepresentation(value);
// TODO(crbug.com/687225): Implement non-default 'pad' value.
wtf_size_t initial_length = NumGraphemeClusters(initial_representation);
if (NeedsNegativeSign(value)) {
initial_length += NumGraphemeClusters(negative_prefix_);
initial_length += NumGraphemeClusters(negative_suffix_);
}
wtf_size_t pad_copies =
pad_length_ > initial_length ? pad_length_ - initial_length : 0;
StringBuilder result;
if (NeedsNegativeSign(value))
result.Append(negative_prefix_);
for (wtf_size_t i = 0; i < pad_copies; ++i)
result.Append(pad_symbol_);
result.Append(initial_representation);
if (NeedsNegativeSign(value))
result.Append(negative_suffix_);
......
......@@ -73,6 +73,10 @@ class CORE_EXPORT CounterStyle final : public GarbageCollected<CounterStyle> {
// 'system', 'range' and 'symbols'/'additive-symbols' descriptor values.
String GenerateInitialRepresentation(int value) const;
// Uses the fallback counter style to generate a representation for the value.
// It may recurse, and if it enters a loop, it uses 'decimal' instead.
String GenerateFallbackRepresentation(int value) const;
// The corresponding style rule in CSS.
Member<const StyleRuleCounterStyle> style_rule_;
......@@ -100,6 +104,9 @@ class CORE_EXPORT CounterStyle final : public GarbageCollected<CounterStyle> {
String negative_prefix_ = "-";
String negative_suffix_;
String pad_symbol_;
wtf_size_t pad_length_ = 0;
friend class CounterStyleMapTest;
};
......
......@@ -206,4 +206,50 @@ TEST_F(CounterStyleTest, CustomNegative) {
EXPECT_EQ("99", extended.GenerateRepresentation(99));
}
TEST_F(CounterStyleTest, CustomPad) {
InsertStyleElement(R"CSS(
@counter-style financial-decimal-pad {
system: extends decimal;
negative: '(' ')';
pad: 4 '0';
}
@counter-style extended {
system: extends financial-decimal-pad;
}
)CSS");
UpdateAllLifecyclePhasesForTest();
// Getting custom 'pad' directly from descriptor value.
const CounterStyle& financial_decimal_pad =
GetCounterStyle("financial-decimal-pad");
EXPECT_EQ("(99)", financial_decimal_pad.GenerateRepresentation(-99));
EXPECT_EQ("(01)", financial_decimal_pad.GenerateRepresentation(-1));
EXPECT_EQ("0000", financial_decimal_pad.GenerateRepresentation(0));
EXPECT_EQ("0001", financial_decimal_pad.GenerateRepresentation(1));
EXPECT_EQ("0099", financial_decimal_pad.GenerateRepresentation(99));
// Getting custom 'pad' indirectly by extending a counter style.
const CounterStyle& extended = GetCounterStyle("extended");
EXPECT_EQ("(99)", extended.GenerateRepresentation(-99));
EXPECT_EQ("(01)", extended.GenerateRepresentation(-1));
EXPECT_EQ("0000", extended.GenerateRepresentation(0));
EXPECT_EQ("0001", extended.GenerateRepresentation(1));
EXPECT_EQ("0099", extended.GenerateRepresentation(99));
}
TEST_F(CounterStyleTest, PadLengthLimit) {
InsertStyleElement(R"CSS(
@counter-style foo {
system: extends decimal;
pad: 1000 '0';
}
)CSS");
UpdateAllLifecyclePhasesForTest();
// Pad length is too long. Fallback to 'decimal'.
const CounterStyle& foo = GetCounterStyle("foo");
EXPECT_EQ("0", foo.GenerateRepresentation(0));
}
} // namespace blink
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