Extend support range of Korean counter styles to match existing behavior
The officially supported range of Korean counter styles is -9999 - 9999,
but the existing behavior already supports all integers. This patch
extends the range of the Korean custom counters style to match it.
Since the counter style algorithm gets much more complicated above 9999
and will be very cumbersome to formalize using the provided systems,
this patch implements it as a special algorithm and routes it to the
legacy implementation.
Bug: 687225
Change-Id: I6dca1c8f1611394349df8018641020048d023f04
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2670290
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#850348}
diff --git a/third_party/blink/renderer/core/css/counter_style.cc b/third_party/blink/renderer/core/css/counter_style.cc
index a1c7fee4..7ced2ae 100644
--- a/third_party/blink/renderer/core/css/counter_style.cc
+++ b/third_party/blink/renderer/core/css/counter_style.cc
@@ -64,6 +64,12 @@
return CounterStyleSystem::kTradChineseInformal;
case CSSValueID::kInternalTradChineseFormal:
return CounterStyleSystem::kTradChineseFormal;
+ case CSSValueID::kInternalKoreanHangulFormal:
+ return CounterStyleSystem::kKoreanHangulFormal;
+ case CSSValueID::kInternalKoreanHanjaInformal:
+ return CounterStyleSystem::kKoreanHanjaInformal;
+ case CSSValueID::kInternalKoreanHanjaFormal:
+ return CounterStyleSystem::kKoreanHanjaFormal;
case CSSValueID::kInternalLowerArmenian:
return CounterStyleSystem::kLowerArmenian;
case CSSValueID::kInternalUpperArmenian:
@@ -91,6 +97,9 @@
case CounterStyleSystem::kSimpChineseFormal:
case CounterStyleSystem::kTradChineseInformal:
case CounterStyleSystem::kTradChineseFormal:
+ case CounterStyleSystem::kKoreanHangulFormal:
+ case CounterStyleSystem::kKoreanHanjaInformal:
+ case CounterStyleSystem::kKoreanHanjaFormal:
case CounterStyleSystem::kLowerArmenian:
case CounterStyleSystem::kUpperArmenian:
return false;
@@ -119,6 +128,9 @@
case CounterStyleSystem::kSimpChineseFormal:
case CounterStyleSystem::kTradChineseInformal:
case CounterStyleSystem::kTradChineseFormal:
+ case CounterStyleSystem::kKoreanHangulFormal:
+ case CounterStyleSystem::kKoreanHanjaInformal:
+ case CounterStyleSystem::kKoreanHanjaFormal:
case CounterStyleSystem::kLowerArmenian:
case CounterStyleSystem::kUpperArmenian:
return true;
@@ -292,6 +304,33 @@
return list_marker_text::GetText(EListStyleType::kTradChineseFormal, value);
}
+String KoreanHangulFormalAlgorithm(unsigned value) {
+ // @counter-style algorithm works on absolute value, but the legacy
+ // implementation works on the original value (and handles negative sign on
+ // its own). Range check before proceeding.
+ if (value > std::numeric_limits<int>::max())
+ return String();
+ return list_marker_text::GetText(EListStyleType::kKoreanHangulFormal, value);
+}
+
+String KoreanHanjaInformalAlgorithm(unsigned value) {
+ // @counter-style algorithm works on absolute value, but the legacy
+ // implementation works on the original value (and handles negative sign on
+ // its own). Range check before proceeding.
+ if (value > std::numeric_limits<int>::max())
+ return String();
+ return list_marker_text::GetText(EListStyleType::kKoreanHanjaInformal, value);
+}
+
+String KoreanHanjaFormalAlgorithm(unsigned value) {
+ // @counter-style algorithm works on absolute value, but the legacy
+ // implementation works on the original value (and handles negative sign on
+ // its own). Range check before proceeding.
+ if (value > std::numeric_limits<int>::max())
+ return String();
+ return list_marker_text::GetText(EListStyleType::kKoreanHanjaFormal, value);
+}
+
String LowerArmenianAlgorithm(unsigned value) {
if (value > 99999999)
return String();
@@ -453,6 +492,9 @@
case CounterStyleSystem::kSimpChineseFormal:
case CounterStyleSystem::kTradChineseInformal:
case CounterStyleSystem::kTradChineseFormal:
+ case CounterStyleSystem::kKoreanHangulFormal:
+ case CounterStyleSystem::kKoreanHanjaInformal:
+ case CounterStyleSystem::kKoreanHanjaFormal:
return true;
case CounterStyleSystem::kSymbolic:
case CounterStyleSystem::kAlphabetic:
@@ -483,6 +525,9 @@
case CounterStyleSystem::kSimpChineseFormal:
case CounterStyleSystem::kTradChineseInformal:
case CounterStyleSystem::kTradChineseFormal:
+ case CounterStyleSystem::kKoreanHangulFormal:
+ case CounterStyleSystem::kKoreanHanjaInformal:
+ case CounterStyleSystem::kKoreanHanjaFormal:
case CounterStyleSystem::kLowerArmenian:
case CounterStyleSystem::kUpperArmenian:
return true;
@@ -571,6 +616,12 @@
return TradChineseInformalAlgorithm(abs_value);
case CounterStyleSystem::kTradChineseFormal:
return TradChineseFormalAlgorithm(abs_value);
+ case CounterStyleSystem::kKoreanHangulFormal:
+ return KoreanHangulFormalAlgorithm(abs_value);
+ case CounterStyleSystem::kKoreanHanjaInformal:
+ return KoreanHanjaInformalAlgorithm(abs_value);
+ case CounterStyleSystem::kKoreanHanjaFormal:
+ return KoreanHanjaFormalAlgorithm(abs_value);
case CounterStyleSystem::kLowerArmenian:
return LowerArmenianAlgorithm(abs_value);
case CounterStyleSystem::kUpperArmenian:
diff --git a/third_party/blink/renderer/core/css/counter_style.h b/third_party/blink/renderer/core/css/counter_style.h
index a774fa8..0f7cdf36 100644
--- a/third_party/blink/renderer/core/css/counter_style.h
+++ b/third_party/blink/renderer/core/css/counter_style.h
@@ -25,6 +25,9 @@
kSimpChineseFormal,
kTradChineseInformal,
kTradChineseFormal,
+ kKoreanHangulFormal,
+ kKoreanHanjaInformal,
+ kKoreanHanjaFormal,
kLowerArmenian,
kUpperArmenian,
kUnresolvedExtends,
diff --git a/third_party/blink/renderer/core/css/counter_style_test.cc b/third_party/blink/renderer/core/css/counter_style_test.cc
index 07d25a0..ddc7a26 100644
--- a/third_party/blink/renderer/core/css/counter_style_test.cc
+++ b/third_party/blink/renderer/core/css/counter_style_test.cc
@@ -509,4 +509,70 @@
}
}
+TEST_F(CounterStyleTest, KoreanHangulFormal) {
+ // Verifies that our 'korean-hangul-formal' implementation matches the spec in
+ // the officially specified range 1-9999.
+ // https://drafts.csswg.org/css-counter-styles-3/#korean-hangul-formal
+ const CounterStyle& korean_hangul_formal_as_specced =
+ AddCounterStyle("korean-hangul-formal-as-specced", R"CSS(
+ system: additive;
+ range: -9999 9999;
+ additive-symbols: 9000 \AD6C\CC9C, 8000 \D314\CC9C, 7000 \CE60\CC9C, 6000 \C721\CC9C, 5000 \C624\CC9C, 4000 \C0AC\CC9C, 3000 \C0BC\CC9C, 2000 \C774\CC9C, 1000 \C77C\CC9C, 900 \AD6C\BC31, 800 \D314\BC31, 700 \CE60\BC31, 600 \C721\BC31, 500 \C624\BC31, 400 \C0AC\BC31, 300 \C0BC\BC31, 200 \C774\BC31, 100 \C77C\BC31, 90 \AD6C\C2ED, 80 \D314\C2ED, 70 \CE60\C2ED, 60 \C721\C2ED, 50 \C624\C2ED, 40 \C0AC\C2ED, 30 \C0BC\C2ED, 20 \C774\C2ED, 10 \C77C\C2ED, 9 \AD6C, 8 \D314, 7 \CE60, 6 \C721, 5 \C624, 4 \C0AC, 3 \C0BC, 2 \C774, 1 \C77C, 0 \C601;
+ negative: "\B9C8\C774\B108\C2A4 ";
+ )CSS");
+ const CounterStyle& korean_hangul_formal_as_implemented =
+ GetCounterStyle("korean-hangul-formal");
+ for (int value = -9999; value <= 9999; ++value) {
+ String expected =
+ korean_hangul_formal_as_specced.GenerateRepresentation(value);
+ String actual =
+ korean_hangul_formal_as_implemented.GenerateRepresentation(value);
+ EXPECT_EQ(expected, actual);
+ }
+}
+
+TEST_F(CounterStyleTest, KoreanHanjaFormal) {
+ // Verifies that our 'korean-hanja-formal' implementation matches the spec in
+ // the officially specified range 1-9999.
+ // https://drafts.csswg.org/css-counter-styles-3/#korean-hanja-formal
+ const CounterStyle& korean_hanja_formal_as_specced =
+ AddCounterStyle("korean-hanja-formal-as-specced", R"CSS(
+ system: additive;
+ range: -9999 9999;
+ additive-symbols: 9000 \4E5D\4EDF, 8000 \516B\4EDF, 7000 \4E03\4EDF, 6000 \516D\4EDF, 5000 \4E94\4EDF, 4000 \56DB\4EDF, 3000 \53C3\4EDF, 2000 \8CB3\4EDF, 1000 \58F9\4EDF, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4E94\767E, 400 \56DB\767E, 300 \53C3\767E, 200 \8CB3\767E, 100 \58F9\767E, 90 \4E5D\62FE, 80 \516B\62FE, 70 \4E03\62FE, 60 \516D\62FE, 50 \4E94\62FE, 40 \56DB\62FE, 30 \53C3\62FE, 20 \8CB3\62FE, 10 \58F9\62FE, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4E94, 4 \56DB, 3 \53C3, 2 \8CB3, 1 \58F9, 0 \96F6;
+ negative: "\B9C8\C774\B108\C2A4 ";
+ )CSS");
+ const CounterStyle& korean_hanja_formal_as_implemented =
+ GetCounterStyle("korean-hanja-formal");
+ for (int value = -9999; value <= 9999; ++value) {
+ String expected =
+ korean_hanja_formal_as_specced.GenerateRepresentation(value);
+ String actual =
+ korean_hanja_formal_as_implemented.GenerateRepresentation(value);
+ EXPECT_EQ(expected, actual);
+ }
+}
+
+TEST_F(CounterStyleTest, KoreanHanjaInformal) {
+ // Verifies that our 'korean-hanja-informal' implementation matches the spec
+ // in the officially specified range 1-9999.
+ // https://drafts.csswg.org/css-counter-styles-3/#korean-hanja-informal
+ const CounterStyle& korean_hanja_informal_as_specced =
+ AddCounterStyle("korean-hanja-informal-as-specced", R"CSS(
+ system: additive;
+ range: -9999 9999;
+ additive-symbols: 9000 \4E5D\5343, 8000 \516B\5343, 7000 \4E03\5343, 6000 \516D\5343, 5000 \4E94\5343, 4000 \56DB\5343, 3000 \4E09\5343, 2000 \4E8C\5343, 1000 \5343, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4E94\767E, 400 \56DB\767E, 300 \4E09\767E, 200 \4E8C\767E, 100 \767E, 90 \4E5D\5341, 80 \516B\5341, 70 \4E03\5341, 60 \516D\5341, 50 \4E94\5341, 40 \56DB\5341, 30 \4E09\5341, 20 \4E8C\5341, 10 \5341, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4E94, 4 \56DB, 3 \4E09, 2 \4E8C, 1 \4E00, 0 \96F6;
+ negative: "\B9C8\C774\B108\C2A4 ";
+ )CSS");
+ const CounterStyle& korean_hanja_informal_as_implemented =
+ GetCounterStyle("korean-hanja-informal");
+ for (int value = -9999; value <= 9999; ++value) {
+ String expected =
+ korean_hanja_informal_as_specced.GenerateRepresentation(value);
+ String actual =
+ korean_hanja_informal_as_implemented.GenerateRepresentation(value);
+ EXPECT_EQ(expected, actual);
+ }
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index 5c400f5..c81dcfe2 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1479,6 +1479,9 @@
"-internal-simp-chinese-formal",
"-internal-trad-chinese-informal",
"-internal-trad-chinese-formal",
+ "-internal-korean-hangul-formal",
+ "-internal-korean-hanja-informal",
+ "-internal-korean-hanja-formal",
"-internal-hebrew",
"-internal-lower-armenian",
"-internal-upper-armenian",
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_counter_style_descriptor_parser.cc b/third_party/blink/renderer/core/css/parser/at_rule_counter_style_descriptor_parser.cc
index 7ffb1f3..3f771ad 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_counter_style_descriptor_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/at_rule_counter_style_descriptor_parser.cc
@@ -71,6 +71,9 @@
CSSValueID::kInternalSimpChineseFormal,
CSSValueID::kInternalTradChineseInformal,
CSSValueID::kInternalTradChineseFormal,
+ CSSValueID::kInternalKoreanHangulFormal,
+ CSSValueID::kInternalKoreanHanjaInformal,
+ CSSValueID::kInternalKoreanHanjaFormal,
CSSValueID::kInternalLowerArmenian,
CSSValueID::kInternalUpperArmenian>(range))
return ident;
diff --git a/third_party/blink/renderer/core/css/predefined_counter_styles.css b/third_party/blink/renderer/core/css/predefined_counter_styles.css
index e0dfdd88..3dccd1f 100644
--- a/third_party/blink/renderer/core/css/predefined_counter_styles.css
+++ b/third_party/blink/renderer/core/css/predefined_counter_styles.css
@@ -311,34 +311,32 @@
/* https://drafts.csswg.org/css-counter-styles-3/#limited-korean */
+/* Note: While the officially specified range is -9999 to 9999 for these counter
+ * styles, implementations are allowed to support a larger range for
+ * investigative purposes. Therefore, we support the full int range. */
+
@counter-style korean-hangul-formal {
- system: additive;
- range: -9999 9999;
- additive-symbols: 9000 \AD6C\CC9C, 8000 \D314\CC9C, 7000 \CE60\CC9C, 6000 \C721\CC9C, 5000 \C624\CC9C, 4000 \C0AC\CC9C, 3000 \C0BC\CC9C, 2000 \C774\CC9C, 1000 \C77C\CC9C, 900 \AD6C\BC31, 800 \D314\BC31, 700 \CE60\BC31, 600 \C721\BC31, 500 \C624\BC31, 400 \C0AC\BC31, 300 \C0BC\BC31, 200 \C774\BC31, 100 \C77C\BC31, 90 \AD6C\C2ED, 80 \D314\C2ED, 70 \CE60\C2ED, 60 \C721\C2ED, 50 \C624\C2ED, 40 \C0AC\C2ED, 30 \C0BC\C2ED, 20 \C774\C2ED, 10 \C77C\C2ED, 9 \AD6C, 8 \D314, 7 \CE60, 6 \C721, 5 \C624, 4 \C0AC, 3 \C0BC, 2 \C774, 1 \C77C, 0 \C601;
- /* 9000 구천, 8000 팔천, 7000 칠천, 6000 육천, 5000 오천, 4000 사천, 3000 삼천, 2000 이천, 1000 일천, 900 구백, 800 팔백, 700 칠백, 600 육백, 500 오백, 400 사백, 300 삼백, 200 이백, 100 일백, 90 구십, 80 팔십, 70 칠십, 60 육십, 50 오십, 40 사십, 30 삼십, 20 이십, 10 일십, 9 구, 8 팔, 7 칠, 6 육, 5 오, 4 사, 3 삼, 2 이, 1 일, 0 영 */
+ system: -internal-korean-hangul-formal;
suffix: ', ';
negative: "\B9C8\C774\B108\C2A4 ";
/* 마이너스 (followed by a space) */
+ fallback: cjk-decimal;
}
@counter-style korean-hanja-informal {
- system: additive;
- range: -9999 9999;
- additive-symbols: 9000 \4E5D\5343, 8000 \516B\5343, 7000 \4E03\5343, 6000 \516D\5343, 5000 \4E94\5343, 4000 \56DB\5343, 3000 \4E09\5343, 2000 \4E8C\5343, 1000 \5343, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4E94\767E, 400 \56DB\767E, 300 \4E09\767E, 200 \4E8C\767E, 100 \767E, 90 \4E5D\5341, 80 \516B\5341, 70 \4E03\5341, 60 \516D\5341, 50 \4E94\5341, 40 \56DB\5341, 30 \4E09\5341, 20 \4E8C\5341, 10 \5341, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4E94, 4 \56DB, 3 \4E09, 2 \4E8C, 1 \4E00, 0 \96F6;
- /* 9000 九千, 8000 八千, 7000 七千, 6000 六千, 5000 五千, 4000 四千, 3000 三千, 2000 二千, 1000 千, 900 九百, 800 八百, 700 七百, 600 六百, 500 五百, 400 四百, 300 三百, 200 二百, 100 百, 90 九十, 80 八十, 70 七十, 60 六十, 50 五十, 40 四十, 30 三十, 20 二十, 10 十, 9 九, 8 八, 7 七, 6 六, 5 五, 4 四, 3 三, 2 二, 1 一, 0 零 */
+ system: -internal-korean-hanja-informal;
suffix: ', ';
negative: "\B9C8\C774\B108\C2A4 ";
/* 마이너스 (followed by a space) */
+ fallback: cjk-decimal;
}
@counter-style korean-hanja-formal {
- system: additive;
- range: -9999 9999;
- additive-symbols: 9000 \4E5D\4EDF, 8000 \516B\4EDF, 7000 \4E03\4EDF, 6000 \516D\4EDF, 5000 \4E94\4EDF, 4000 \56DB\4EDF, 3000 \53C3\4EDF, 2000 \8CB3\4EDF, 1000 \58F9\4EDF, 900 \4E5D\767E, 800 \516B\767E, 700 \4E03\767E, 600 \516D\767E, 500 \4E94\767E, 400 \56DB\767E, 300 \53C3\767E, 200 \8CB3\767E, 100 \58F9\767E, 90 \4E5D\62FE, 80 \516B\62FE, 70 \4E03\62FE, 60 \516D\62FE, 50 \4E94\62FE, 40 \56DB\62FE, 30 \53C3\62FE, 20 \8CB3\62FE, 10 \58F9\62FE, 9 \4E5D, 8 \516B, 7 \4E03, 6 \516D, 5 \4E94, 4 \56DB, 3 \53C3, 2 \8CB3, 1 \58F9, 0 \96F6;
- /* 9000 九仟, 8000 八仟, 7000 七仟, 6000 六仟, 5000 五仟, 4000 四仟, 3000 參仟, 2000 貳仟, 1000 壹仟, 900 九百, 800 八百, 700 七百, 600 六百, 500 五百, 400 四百, 300 參百, 200 貳百, 100 壹百, 90 九拾, 80 八拾, 70 七拾, 60 六拾, 50 五拾, 40 四拾, 30 參拾, 20 貳拾, 10 壹拾, 9 九, 8 八, 7 七, 6 六, 5 五, 4 四, 3 參, 2 貳, 1 壹, 0 零 */
+ system: -internal-korean-hanja-formal;
suffix: ', ';
negative: "\B9C8\C774\B108\C2A4 ";
/* 마이너스 (followed by a space) */
+ fallback: cjk-decimal;
}
/* https://drafts.csswg.org/css-counter-styles-3/#limited-chinese */
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 872f87b..e9d39397 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -753,13 +753,7 @@
crbug.com/1066577 external/wpt/css/css-lists/li-value-reversed-004.html [ Failure ]
# [css-counter-styles-3]
-# Implemented as custom counter styles, but not exactly match existing behavior:
-# - Complex CJK styles should fallback to 'cjk-decimal', not 'decimal'
-# - CJK styles should support larger value ranges, matching the old behavior
crbug.com/687225 fast/css/content-counter-large-negative-cjk.html [ Failure ]
-crbug.com/687225 fast/lists/css3-counter-styles-054.html [ Failure ]
-crbug.com/687225 fast/lists/css3-counter-styles-059.html [ Failure ]
-crbug.com/687225 fast/lists/css3-counter-styles-064.html [ Failure ]
# Missing ref files for these tests
crbug.com/687225 external/wpt/css/css-counter-styles/* [ Skip ]