Diff
Modified: trunk/LayoutTests/ChangeLog (276487 => 276488)
--- trunk/LayoutTests/ChangeLog 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/ChangeLog 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,3 +1,63 @@
+2021-04-22 Tyler Wilcock <[email protected]>
+
+ [css-counter-styles] Parse @counter-style descriptors
+ https://bugs.webkit.org/show_bug.cgi?id=224718
+
+ Reviewed by Darin Adler.
+
+ Add test ensuring <image> @counter-style symbol values cannot be
+ parsed when the `counterStyleAtRuleImageSymbolsEnabled` feature flag
+ is disabled.
+
+ ---
+
+ This test is skipped on Windows because I haven't been able to get the
+ required feature flags (CSSCounterStyleAtRulesEnabled and
+ CSSCounterStyleAtRuleImageSymbolsEnabled) to work properly for that
+ port.
+
+ The code hidden behind these flags is all in the CSS parser, which is not
+ unique to Windows, so I think we can be confident that if the test passes
+ on all other platforms, that the behavior is correct on Windows too.
+
+ One attempt at implementing the necessary Windows-specific flag functionality is here:
+
+ https://bugs.webkit.org/attachment.cgi?id=426371&action=""
+
+ Which failed to compile[1] with this error:
+
+ > C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp(834,51): error C2039: 'setCSSCounterStyleAtRulesEnabled': is not a member of 'IWebPreferencesPrivate7' [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Tools\DumpRenderTree\DumpRenderTreeLib.vcxproj]
+ > C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp(835,62): error C2039: 'setCSSCounterStyleAtRuleImageSymbolsEnabled': is not a member of 'IWebPreferencesPrivate7' [C:\cygwin\home\buildbot\worker\Windows-EWS\build\WebKitBuild\Release\Tools\DumpRenderTree\DumpRenderTreeLib.vcxproj]
+
+ Those methods are present in `IWebPreferencesPrivate7.idl`, and implemented similarly to other
+ flags in other places (e.g. win/WebPreferences.{h, cpp}, win/WebPreferenceKeysPrivate.h).
+ I can't reproduce this compilation error on my Windows machine.
+
+ I then tried removing the lines that caused the above compilation failure.
+ Those setters are called in DumpRenderTree::enableExperimentalFeatures, so in
+ lieu of enabling these flags there I could enable the flag I need via test header.
+
+ That patch is: https://bugs.webkit.org/attachment.cgi?id=426509&action=""
+
+ This results in successful compilation, but causes lots (all?) of the
+ layout tests to fail[2] with a stacktrace that looks like:
+
+00007ffc`3e9e3113 WebKit!WebPreferences::speechRecognitionEnabled(int * enabled = 0x00007ffc`3eae0f50)+0x29 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebKitLegacy\win\WebPreferences.cpp @ 2617]
+00007ffc`3e9e3cc0 DumpRenderTreeLib!resetWebPreferencesToConsistentValues(struct IWebPreferences * preferences = 0x00000205`e2f204b0)+0x63 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp @ 847]
+00007ffc`3e9e4171 DumpRenderTreeLib!resetWebViewToConsistentStateBeforeTesting(class WTR::TestOptions * options = 0x00000065`738fea60)+0x2e0 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp @ 1054]
+00007ffc`3e9e67d3 DumpRenderTreeLib!runTest(class std::basic_string<char,std::char_traits<char>,std::allocator<char> > * inputLine = <Value unavailable error>)+0x2f1 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp @ 1239]
+00007ff7`89952f30 DumpRenderTreeLib!main(int argc = <Value unavailable error>, char ** argv = <Value unavailable error>)+0x5d3 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\DumpRenderTree\win\DumpRenderTree.cpp @ 1676]
+00007ff7`89953884 DumpRenderTree!main(int argc = 0n2, char ** argv = 0x00000205`e2e74b80)+0x880 [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Tools\win\DLLLauncher\DLLLauncherMain.cpp @ 232]
+
+ I haven't done much digging into why this happens, and cannot reproduce it on my Windows machine.
+
+ [1]: https://ews-build.webkit.org/#/builders/10/builds/86747
+ [2]: https://ews-build.webkit.org/#/builders/10/builds/86897
+
+ * platform/win/TestExpectations: Skip newly added test on Windows.
+ * webexposed/counter-style-image-symbols-not-exposed-expected.txt: Added.
+ * webexposed/counter-style-image-symbols-not-exposed.html: Added.
+
2021-04-22 Megan Gardner <[email protected]>
Sometimes appHighlights are not painted when created.
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,3 +1,46 @@
+2021-04-22 Tyler Wilcock <[email protected]>
+
+ [css-counter-styles] Parse @counter-style descriptors
+ https://bugs.webkit.org/show_bug.cgi?id=224718
+
+ Reviewed by Darin Adler.
+
+ Parsing for all @counter-style descriptors is implemented with this
+ patch, so mark more tests passing.
+
+ You'll notice that some @counter-style descriptors implemented in this
+ patch did not gain any passing tests (e.g. `pad`, `negative`). In all
+ of these cases, the expected results contain a <string> value, and we
+ fail only because we incorrectly don't serialize these <string> values
+ with quotes. I have manually confirmed in all cases that these values
+ are properly parsed, so it's just the serialization that's incorrect.
+
+ These <string> values serialize without quotes because WebKit's representation
+ of custom identifiers is not a separate type, but instead overloaded onto the
+ CSS_STRING type. This means that during serialization time, WebKit must guess
+ whether it is actually serializing a string (and include quotes if so), or if
+ it's serializing a custom ident (leaving off quotes if so).
+
+ Relevant code snippet:
+
+ https://github.com/WebKit/WebKit/blob/36caeec07975bd5f47db8ac6b749c2787230a461/Source/WebCore/css/CSSMarkup.cpp#L153#L161
+
+ Relevant changelog snippet from David Hyatt, 2016-12-07:
+
+ > We also overload CSS_STRING primitive value type and have it act as both a string
+ > and a custom identifier. This is lame, since the parser should have made two different
+ > types of objects instead, but since our parser doesn't do that yet, I added a serializeAsStringOrCustomIdent
+ > that preserves our old behavior of "quote the string only if needed." In this case what
+ > that really meant was "Try to guess that we were originally a custom ident and leave off
+ > quotes if so." This function will go away once we properly create CSSStringValues and
+ > CSSCustomIdentValues instead of turning the latter into strings.
+
+ * web-platform-tests/css/css-counter-styles/counter-style-fallback-expected.txt:
+ * web-platform-tests/css/css-counter-styles/counter-style-prefix-suffix-syntax-expected.txt:
+ * web-platform-tests/css/css-counter-styles/counter-style-range-syntax-expected.txt:
+ * web-platform-tests/css/css-counter-styles/counter-style-speak-as-syntax-expected.txt:
+ * web-platform-tests/css/css-counter-styles/counter-style-system-syntax-expected.txt:
+
2021-04-22 Antoine Quint <[email protected]>
Add discrete animation support for border-image-repeat
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-fallback-expected.txt (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-fallback-expected.txt 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-fallback-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,5 +1,5 @@
-FAIL @counter-style 'fallback: bar' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'fallback: bar' is valid
PASS @counter-style 'fallback: "bar"' is invalid
PASS @counter-style 'fallback: none' is invalid
PASS @counter-style 'fallback: initial' is invalid
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-prefix-suffix-syntax-expected.txt (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-prefix-suffix-syntax-expected.txt 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-prefix-suffix-syntax-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -7,8 +7,8 @@
FAIL @counter-style 'suffix: "inherit"' is valid assert_not_equals: got disallowed value -1
FAIL @counter-style 'prefix: "unset"' is valid assert_not_equals: got disallowed value -1
FAIL @counter-style 'suffix: "unset"' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'prefix: custom-ident' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'suffix: custom-ident' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'prefix: custom-ident' is valid
+PASS @counter-style 'suffix: custom-ident' is valid
PASS @counter-style 'prefix: initial' is invalid
PASS @counter-style 'suffix: initial' is invalid
PASS @counter-style 'prefix: inherit' is invalid
@@ -15,12 +15,12 @@
PASS @counter-style 'suffix: inherit' is invalid
PASS @counter-style 'prefix: unset' is invalid
PASS @counter-style 'suffix: unset' is invalid
-FAIL @counter-style 'prefix: url("https://example.com/foo.png")' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'suffix: url("https://example.com/foo.png")' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'prefix: url(https://example.com/foo.png)' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'suffix: url(https://example.com/foo.png)' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'prefix: linear-gradient(yellow, blue)' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'suffix: linear-gradient(yellow, blue)' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'prefix: url("https://example.com/foo.png")' is valid
+PASS @counter-style 'suffix: url("https://example.com/foo.png")' is valid
+PASS @counter-style 'prefix: url(https://example.com/foo.png)' is valid
+PASS @counter-style 'suffix: url(https://example.com/foo.png)' is valid
+PASS @counter-style 'prefix: linear-gradient(yellow, blue)' is valid
+PASS @counter-style 'suffix: linear-gradient(yellow, blue)' is valid
PASS @counter-style 'prefix: ' is invalid
PASS @counter-style 'suffix: ' is invalid
PASS @counter-style 'prefix: foo bar' is invalid
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-range-syntax-expected.txt (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-range-syntax-expected.txt 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-range-syntax-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,10 +1,10 @@
-FAIL @counter-style 'range: auto' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'range: infinite infinite' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'range: infinite 0' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'range: 0 infinite' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'range: infinite 0, 5 10, 100 infinite' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'range: infinite 10, 5 20, 15 infinite' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'range: auto' is valid
+PASS @counter-style 'range: infinite infinite' is valid
+PASS @counter-style 'range: infinite 0' is valid
+PASS @counter-style 'range: 0 infinite' is valid
+PASS @counter-style 'range: infinite 0, 5 10, 100 infinite' is valid
+PASS @counter-style 'range: infinite 10, 5 20, 15 infinite' is valid
PASS @counter-style 'range: ' is invalid
PASS @counter-style 'range: 0 -1' is invalid
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-speak-as-syntax-expected.txt (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-speak-as-syntax-expected.txt 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-speak-as-syntax-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,11 +1,11 @@
-FAIL @counter-style 'speak-as: auto' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: bullets' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: numbers' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: words' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: spell-out' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: bar' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'speak-as: spellout' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'speak-as: auto' is valid
+PASS @counter-style 'speak-as: bullets' is valid
+PASS @counter-style 'speak-as: numbers' is valid
+PASS @counter-style 'speak-as: words' is valid
+PASS @counter-style 'speak-as: spell-out' is valid
+PASS @counter-style 'speak-as: bar' is valid
+PASS @counter-style 'speak-as: spellout' is valid
PASS @counter-style 'speak-as: bullets numbers' is invalid
PASS @counter-style 'speak-as: none' is invalid
PASS @counter-style 'speak-as: initial' is invalid
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-system-syntax-expected.txt (276487 => 276488)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-system-syntax-expected.txt 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-counter-styles/counter-style-system-syntax-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,13 +1,13 @@
-FAIL @counter-style 'system: cyclic' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: fixed' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: fixed 100' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: fixed -1' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: symbolic' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: alphabetic' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: numeric' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: additive' is valid assert_not_equals: got disallowed value -1
-FAIL @counter-style 'system: extends bar' is valid assert_not_equals: got disallowed value -1
+PASS @counter-style 'system: cyclic' is valid
+PASS @counter-style 'system: fixed' is valid
+PASS @counter-style 'system: fixed 100' is valid
+PASS @counter-style 'system: fixed -1' is valid
+PASS @counter-style 'system: symbolic' is valid
+PASS @counter-style 'system: alphabetic' is valid
+PASS @counter-style 'system: numeric' is valid
+PASS @counter-style 'system: additive' is valid
+PASS @counter-style 'system: extends bar' is valid
PASS @counter-style 'system: float' is invalid
PASS @counter-style 'system: cyclic cyclic' is invalid
PASS @counter-style 'system: extends none' is invalid
Modified: trunk/LayoutTests/platform/win/TestExpectations (276487 => 276488)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-04-23 05:25:40 UTC (rev 276488)
@@ -4657,3 +4657,7 @@
fast/forms/option-mouseevents.html [ Pass Failure ]
fast/forms/password-doubleclick-selection.html [ Pass Failure ]
fast/text/offsetForPosition-complex-fallback.html [ Pass Failure ]
+
+# This test is skipped because the necessary feature flag functionality specific to the Windows WebKit legacy port is
+# not implemented. The feature flags in question are CSSCounterStyleAtRulesEnabled and CSSCounterStyleAtRuleImageSymbolsEnabled.
+webexposed/counter-style-image-symbols-not-exposed.html [ Skip ]
Added: trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed-expected.txt (0 => 276488)
--- trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed-expected.txt (rev 0)
+++ trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed-expected.txt 2021-04-23 05:25:40 UTC (rev 276488)
@@ -0,0 +1,3 @@
+
+PASS @counter-style image symbols are not exposed
+
Added: trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed.html (0 => 276488)
--- trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed.html (rev 0)
+++ trunk/LayoutTests/webexposed/counter-style-image-symbols-not-exposed.html 2021-04-23 05:25:40 UTC (rev 276488)
@@ -0,0 +1,17 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ CSSCounterStyleAtRuleImageSymbolsEnabled=false ] -->
+<script src=""
+<script src=""
+<style>
+ @counter-style foo {
+ system: cyclic;
+ suffix: " ";
+ symbols: linear-gradient(yellow, blue);
+ }
+</style>
+<script>
+ test(function() {
+ const cssRules = document.styleSheets[0].cssRules
+ assert_equals(cssRules.length, 1, 'Should\'ve been able to parse @counter-style.')
+ assert_equals(cssRules[0].symbols, '', 'Shouldn\'t have been able to parse image symbol value with the runtime feature flag disabled.')
+ }, '@counter-style image symbols are not exposed')
+</script>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (276487 => 276488)
--- trunk/Source/WebCore/ChangeLog 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/ChangeLog 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,3 +1,69 @@
+2021-04-22 Tyler Wilcock <[email protected]>
+
+ [css-counter-styles] Parse @counter-style descriptors
+ https://bugs.webkit.org/show_bug.cgi?id=224718
+
+ Reviewed by Darin Adler.
+
+ Implement parsing and CSSCounterStyleRule IDL interface for @counter-style descriptors.
+ See spec for full details on all descriptors:
+
+ https://drafts.csswg.org/css-counter-styles-3/#the-counter-style-rule
+
+ Test: webexposed/counter-style-image-symbols-not-exposed.html and WPTs
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::ComputedStyleExtractor::valueForPropertyInStyle):
+ Return `nullptr` for new @counter-style descriptor properties.
+
+ * css/CSSCounterStyleRule.cpp:
+ (WebCore::toCounterStyleSystemEnum):
+ (WebCore::symbolsValidForSystem):
+ (WebCore::StyleRuleCounterStyle::newValueInvalidOrEqual const):
+ (WebCore::CSSCounterStyleRule::cssText const):
+ (WebCore::CSSCounterStyleRule::setName):
+ (WebCore::CSSCounterStyleRule::setterInternal):
+ (WebCore::CSSCounterStyleRule::setSystem):
+ (WebCore::CSSCounterStyleRule::setNegative):
+ (WebCore::CSSCounterStyleRule::setPrefix):
+ (WebCore::CSSCounterStyleRule::setSuffix):
+ (WebCore::CSSCounterStyleRule::setRange):
+ (WebCore::CSSCounterStyleRule::setPad):
+ (WebCore::CSSCounterStyleRule::setFallback):
+ (WebCore::CSSCounterStyleRule::setSymbols):
+ (WebCore::CSSCounterStyleRule::setAdditiveSymbols):
+ (WebCore::CSSCounterStyleRule::setSpeakAs):
+ Implement setters and tangential functionality required by setters.
+
+ * css/CSSCounterStyleRule.h:
+ Replace FIXME with actual descriptor getter and setter
+ implementations.
+
+ * css/CSSProperties.json:
+ Add @counter-style descriptor properties.
+
+ * css/CSSValueKeywords.in:
+ Add new values required for `system` and `speak-as`
+ @counter-style descriptor properties.
+
+ * css/parser/CSSParserContext.cpp:
+ (WebCore::CSSParserContext::isPropertyRuntimeDisabled const):
+ Ensure new @counter-style descriptors are disabled at runtime based
+ on CSSParserContext state.
+
+ * css/parser/CSSPropertyParser.cpp:
+ (WebCore::consumeCounterStyleSystem):
+ (WebCore::consumeCounterStyleSymbol):
+ (WebCore::consumeCounterStyleNegative):
+ (WebCore::consumeCounterStyleRangeBound):
+ (WebCore::consumeCounterStyleRange):
+ (WebCore::consumeCounterStylePad):
+ (WebCore::consumeCounterStyleSymbols):
+ (WebCore::consumeCounterStyleAdditiveSymbols):
+ (WebCore::consumeCounterStyleSpeakAs):
+ (WebCore::CSSPropertyParser::parseCounterStyleDescriptor):
+ Parse @counter-style descriptors.
+
2021-04-22 Megan Gardner <[email protected]>
Sometimes appHighlights are not painted when created.
Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (276487 => 276488)
--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp 2021-04-23 05:25:40 UTC (rev 276488)
@@ -4003,6 +4003,18 @@
ASSERT_NOT_REACHED();
break;
+ // These are intentionally unimplemented because they are actually descriptors for @counter-style.
+ case CSSPropertySystem:
+ case CSSPropertyNegative:
+ case CSSPropertyPrefix:
+ case CSSPropertySuffix:
+ case CSSPropertyRange:
+ case CSSPropertyPad:
+ case CSSPropertyFallback:
+ case CSSPropertySymbols:
+ case CSSPropertyAdditiveSymbols:
+ break;
+
/* Unimplemented @font-face properties */
case CSSPropertySrc:
case CSSPropertyUnicodeRange:
Modified: trunk/Source/WebCore/css/CSSCounterStyleRule.cpp (276487 => 276488)
--- trunk/Source/WebCore/css/CSSCounterStyleRule.cpp 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/CSSCounterStyleRule.cpp 2021-04-23 05:25:40 UTC (rev 276488)
@@ -26,6 +26,12 @@
#include "config.h"
#include "CSSCounterStyleRule.h"
+#include "CSSPropertyParser.h"
+#include "CSSStyleSheet.h"
+#include "CSSTokenizer.h"
+#include "Pair.h"
+#include <wtf/text/StringBuilder.h>
+
namespace WebCore {
StyleRuleCounterStyle::StyleRuleCounterStyle(const AtomString& name, Ref<StyleProperties>&& properties)
@@ -40,6 +46,94 @@
return adoptRef(*new StyleRuleCounterStyle(name, WTFMove(properties)));
}
+static CounterStyleSystem toCounterStyleSystemEnum(RefPtr<CSSValue> system)
+{
+ if (!system || !system->isPrimitiveValue())
+ return CounterStyleSystem::Symbolic;
+
+ auto& primitiveSystemValue = downcast<CSSPrimitiveValue>(*system);
+ ASSERT(primitiveSystemValue.isValueID() || primitiveSystemValue.isPair());
+ CSSValueID systemKeyword = CSSValueInvalid;
+ if (primitiveSystemValue.isValueID())
+ systemKeyword = primitiveSystemValue.valueID();
+ else if (auto* pair = primitiveSystemValue.pairValue()) {
+ // This value must be `fixed` or `extends`, both of which can or must have an additional component.
+ auto firstValue = pair->first();
+ ASSERT(firstValue && firstValue->isValueID());
+ if (firstValue)
+ systemKeyword = firstValue->valueID();
+ }
+
+ switch (systemKeyword) {
+ case CSSValueCyclic:
+ return CounterStyleSystem::Cyclic;
+ case CSSValueFixed:
+ return CounterStyleSystem::Fixed;
+ case CSSValueSymbolic:
+ return CounterStyleSystem::Symbolic;
+ case CSSValueAlphabetic:
+ return CounterStyleSystem::Alphabetic;
+ case CSSValueNumeric:
+ return CounterStyleSystem::Numeric;
+ case CSSValueAdditive:
+ return CounterStyleSystem::Additive;
+ case CSSValueExtends:
+ return CounterStyleSystem::Extends;
+ default:
+ ASSERT_NOT_REACHED();
+ return CounterStyleSystem::Symbolic;
+ }
+}
+
+static bool symbolsValidForSystem(CounterStyleSystem system, RefPtr<CSSValue> symbols, RefPtr<CSSValue> additiveSymbols)
+{
+ switch (system) {
+ case CounterStyleSystem::Cyclic:
+ case CounterStyleSystem::Fixed:
+ case CounterStyleSystem::Symbolic:
+ return symbols && symbols->isValueList() && downcast<CSSValueList>(*symbols).length();
+ case CounterStyleSystem::Alphabetic:
+ case CounterStyleSystem::Numeric:
+ return symbols && symbols->isValueList() && downcast<CSSValueList>(*symbols).length() >= 2u;
+ case CounterStyleSystem::Additive:
+ return additiveSymbols && additiveSymbols->isValueList() && downcast<CSSValueList>(*additiveSymbols).length();
+ case CounterStyleSystem::Extends:
+ return !symbols && !additiveSymbols;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+bool StyleRuleCounterStyle::newValueInvalidOrEqual(CSSPropertyID propertyID, const RefPtr<CSSValue> newValue) const
+{
+ auto currentValue = m_properties->getPropertyCSSValue(propertyID);
+ if (compareCSSValuePtr(currentValue, newValue))
+ return true;
+
+ RefPtr<CSSValue> symbols;
+ RefPtr<CSSValue> additiveSymbols;
+ switch (propertyID) {
+ case CSSPropertySystem:
+ // If the attribute being set is `system`, and the new value would change the algorithm used, do nothing
+ // and abort these steps.
+ // (It's okay to change an aspect of the algorithm, like the first symbol value of a `fixed` system.)
+ return toCounterStyleSystemEnum(currentValue) != toCounterStyleSystemEnum(newValue);
+ case CSSPropertySymbols:
+ symbols = newValue;
+ additiveSymbols = m_properties->getPropertyCSSValue(CSSPropertyAdditiveSymbols);
+ break;
+ case CSSPropertyAdditiveSymbols:
+ symbols = m_properties->getPropertyCSSValue(CSSPropertySymbols);
+ additiveSymbols = newValue;
+ break;
+ default:
+ return false;
+ }
+ auto system = m_properties->getPropertyCSSValue(CSSPropertySystem);
+ return symbolsValidForSystem(toCounterStyleSystemEnum(system), symbols, additiveSymbols);
+}
+
StyleRuleCounterStyle::~StyleRuleCounterStyle() = default;
MutableStyleProperties& StyleRuleCounterStyle::mutableProperties()
@@ -64,8 +158,58 @@
String CSSCounterStyleRule::cssText() const
{
- // FIXME: Implement this function when we parse @counter-style descriptors.
- return emptyString();
+ String systemText = system();
+ const char* systemPrefix = systemText.isEmpty() ? "" : " system: ";
+ const char* systemSuffix = systemText.isEmpty() ? "" : ";";
+
+ String symbolsText = symbols();
+ const char* symbolsPrefix = symbolsText.isEmpty() ? "" : " symbols: ";
+ const char* symbolsSuffix = symbolsText.isEmpty() ? "" : ";";
+
+ String additiveSymbolsText = additiveSymbols();
+ const char* additiveSymbolsPrefix = additiveSymbolsText.isEmpty() ? "" : " additive-symbols: ";
+ const char* additiveSymbolsSuffix = additiveSymbolsText.isEmpty() ? "" : ";";
+
+ String negativeText = negative();
+ const char* negativePrefix = negativeText.isEmpty() ? "" : " negative: ";
+ const char* negativeSuffix = negativeText.isEmpty() ? "" : ";";
+
+ String prefixText = prefix();
+ const char* prefixTextPrefix = prefixText.isEmpty() ? "" : " prefix: ";
+ const char* prefixTextSuffix = prefixText.isEmpty() ? "" : ";";
+
+ String suffixText = suffix();
+ const char* suffixTextPrefix = suffixText.isEmpty() ? "" : " suffix: ";
+ const char* suffixTextSuffix = suffixText.isEmpty() ? "" : ";";
+
+ String padText = pad();
+ const char* padPrefix = padText.isEmpty() ? "" : " pad: ";
+ const char* padSuffix = padText.isEmpty() ? "" : ";";
+
+ String rangeText = range();
+ const char* rangePrefix = rangeText.isEmpty() ? "" : " range: ";
+ const char* rangeSuffix = rangeText.isEmpty() ? "" : ";";
+
+ String fallbackText = fallback();
+ const char* fallbackPrefix = fallbackText.isEmpty() ? "" : " fallback: ";
+ const char* fallbackSuffix = fallbackText.isEmpty() ? "" : ";";
+
+ String speakAsText = speakAs();
+ const char* speakAsPrefix = speakAsText.isEmpty() ? "" : " speak-as: ";
+ const char* speakAsSuffix = speakAsText.isEmpty() ? "" : ";";
+
+ return makeString("@counter-style ", name(), " {",
+ systemPrefix, systemText, systemSuffix,
+ symbolsPrefix, symbolsText, symbolsSuffix,
+ additiveSymbolsPrefix, additiveSymbolsText, additiveSymbolsSuffix,
+ negativePrefix, negativeText, negativeSuffix,
+ prefixTextPrefix, prefixText, prefixTextSuffix,
+ suffixTextPrefix, suffixText, suffixTextSuffix,
+ padPrefix, padText, padSuffix,
+ rangePrefix, rangeText, rangeSuffix,
+ fallbackPrefix, fallbackText, fallbackSuffix,
+ speakAsPrefix, speakAsText, speakAsSuffix,
+ " }");
}
void CSSCounterStyleRule::reattach(StyleRuleBase& rule)
@@ -73,4 +217,79 @@
m_counterStyleRule = static_cast<StyleRuleCounterStyle&>(rule);
}
+// https://drafts.csswg.org/css-counter-styles-3/#dom-csscounterstylerule-name
+void CSSCounterStyleRule::setName(const String& text)
+{
+ auto tokenizer = CSSTokenizer(text);
+ auto tokenRange = tokenizer.tokenRange();
+ auto name = CSSPropertyParserHelpers::consumeCounterStyleNameInPrelude(tokenRange);
+ if (name.isNull() || name == m_counterStyleRule->name())
+ return;
+
+ CSSStyleSheet::RuleMutationScope mutationScope(this);
+ m_counterStyleRule->setName(name);
+}
+
+void CSSCounterStyleRule::setterInternal(CSSPropertyID propertyID, const String& valueText)
+{
+ auto tokenizer = CSSTokenizer(valueText);
+ auto tokenRange = tokenizer.tokenRange();
+ auto newValue = CSSPropertyParser::parseCounterStyleDescriptor(propertyID, tokenRange, parserContext());
+ if (m_counterStyleRule->newValueInvalidOrEqual(propertyID, newValue))
+ return;
+
+ CSSStyleSheet::RuleMutationScope mutationScope(this);
+ m_counterStyleRule->mutableProperties().setProperty(propertyID, WTFMove(newValue));
+}
+
+void CSSCounterStyleRule::setSystem(const String& text)
+{
+ setterInternal(CSSPropertySystem, text);
+}
+
+void CSSCounterStyleRule::setNegative(const String& text)
+{
+ setterInternal(CSSPropertyNegative, text);
+}
+
+void CSSCounterStyleRule::setPrefix(const String& text)
+{
+ setterInternal(CSSPropertyPrefix, text);
+}
+
+void CSSCounterStyleRule::setSuffix(const String& text)
+{
+ setterInternal(CSSPropertySuffix, text);
+}
+
+void CSSCounterStyleRule::setRange(const String& text)
+{
+ setterInternal(CSSPropertyRange, text);
+}
+
+void CSSCounterStyleRule::setPad(const String& text)
+{
+ setterInternal(CSSPropertyPad, text);
+}
+
+void CSSCounterStyleRule::setFallback(const String& text)
+{
+ setterInternal(CSSPropertyFallback, text);
+}
+
+void CSSCounterStyleRule::setSymbols(const String& text)
+{
+ setterInternal(CSSPropertySymbols, text);
+}
+
+void CSSCounterStyleRule::setAdditiveSymbols(const String& text)
+{
+ setterInternal(CSSPropertyAdditiveSymbols, text);
+}
+
+void CSSCounterStyleRule::setSpeakAs(const String& text)
+{
+ setterInternal(CSSPropertySpeakAs, text);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/css/CSSCounterStyleRule.h (276487 => 276488)
--- trunk/Source/WebCore/css/CSSCounterStyleRule.h 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/CSSCounterStyleRule.h 2021-04-23 05:25:40 UTC (rev 276488)
@@ -32,6 +32,18 @@
namespace WebCore {
+// The keywords that can be used as values for the counter-style `system` descriptor.
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-system
+enum class CounterStyleSystem : uint8_t {
+ Cyclic,
+ Numeric,
+ Alphabetic,
+ Symbolic,
+ Additive,
+ Fixed,
+ Extends
+};
+
class StyleRuleCounterStyle final : public StyleRuleBase {
public:
static Ref<StyleRuleCounterStyle> create(const AtomString& name, Ref<StyleProperties>&&);
@@ -41,7 +53,21 @@
MutableStyleProperties& mutableProperties();
const AtomString& name() const { return m_name; }
+ String system() const { return m_properties->getPropertyValue(CSSPropertySystem); }
+ String negative() const { return m_properties->getPropertyValue(CSSPropertyNegative); }
+ String prefix() const { return m_properties->getPropertyValue(CSSPropertyPrefix); }
+ String suffix() const { return m_properties->getPropertyValue(CSSPropertySuffix); }
+ String range() const { return m_properties->getPropertyValue(CSSPropertyRange); }
+ String pad() const { return m_properties->getPropertyValue(CSSPropertyPad); }
+ String fallback() const { return m_properties->getPropertyValue(CSSPropertyFallback); }
+ String symbols() const { return m_properties->getPropertyValue(CSSPropertySymbols); }
+ String additiveSymbols() const { return m_properties->getPropertyValue(CSSPropertyAdditiveSymbols); }
+ String speakAs() const { return m_properties->getPropertyValue(CSSPropertySpeakAs); }
+ bool newValueInvalidOrEqual(CSSPropertyID, const RefPtr<CSSValue> newValue) const;
+
+ void setName(const AtomString& name) { m_name = name; }
+
private:
explicit StyleRuleCounterStyle(const AtomString&, Ref<StyleProperties>&&);
@@ -59,34 +85,34 @@
CSSRule::Type type() const final { return COUNTER_STYLE_RULE; }
String name() const { return m_counterStyleRule->name(); }
- // FIXME: Implement after we parse @counter-style descriptors.
- String system() const { return emptyString(); }
- String negative() const { return emptyString(); }
- String prefix() const { return emptyString(); }
- String suffix() const { return emptyString(); }
- String range() const { return emptyString(); }
- String pad() const { return emptyString(); }
- String fallback() const { return emptyString(); }
- String symbols() const { return emptyString(); }
- String additiveSymbols() const { return emptyString(); }
- String speakAs() const { return emptyString(); }
+ String system() const { return m_counterStyleRule->system(); }
+ String negative() const { return m_counterStyleRule->negative(); }
+ String prefix() const { return m_counterStyleRule->prefix(); }
+ String suffix() const { return m_counterStyleRule->suffix(); }
+ String range() const { return m_counterStyleRule->range(); }
+ String pad() const { return m_counterStyleRule->pad(); }
+ String fallback() const { return m_counterStyleRule->fallback(); }
+ String symbols() const { return m_counterStyleRule->symbols(); }
+ String additiveSymbols() const { return m_counterStyleRule->additiveSymbols(); }
+ String speakAs() const { return m_counterStyleRule->speakAs(); }
- // FIXME: Implement after we parse @counter-style descriptors.
- void setName(const String&) { }
- void setSystem(const String&) { }
- void setNegative(const String&) { }
- void setPrefix(const String&) { }
- void setSuffix(const String&) { }
- void setRange(const String&) { }
- void setPad(const String&) { }
- void setFallback(const String&) { }
- void setSymbols(const String&) { }
- void setAdditiveSymbols(const String&) { }
- void setSpeakAs(const String&) { }
+ void setName(const String&);
+ void setSystem(const String&);
+ void setNegative(const String&);
+ void setPrefix(const String&);
+ void setSuffix(const String&);
+ void setRange(const String&);
+ void setPad(const String&);
+ void setFallback(const String&);
+ void setSymbols(const String&);
+ void setAdditiveSymbols(const String&);
+ void setSpeakAs(const String&);
private:
CSSCounterStyleRule(StyleRuleCounterStyle&, CSSStyleSheet* parent);
+ void setterInternal(CSSPropertyID, const String&);
+
Ref<StyleRuleCounterStyle> m_counterStyleRule;
};
Modified: trunk/Source/WebCore/css/CSSProperties.json (276487 => 276488)
--- trunk/Source/WebCore/css/CSSProperties.json 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/CSSProperties.json 2021-04-23 05:25:40 UTC (rev 276488)
@@ -803,6 +803,16 @@
"url": "https://www.w3.org/TR/css-ruby-1/#rubypos"
}
},
+ "additive-symbols": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-symbols"
+ }
+ },
"alignment-baseline": {
"values": [
"auto",
@@ -2436,6 +2446,16 @@
"category": "svg"
}
},
+ "fallback": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-fallback"
+ }
+ },
"fill": {
"inherited": true,
"codegen-properties": {
@@ -3377,6 +3397,16 @@
"url": "https://drafts.csswg.org/css-overscroll-1/#propdef-overscroll-behavior-y"
}
},
+ "pad": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-pad"
+ }
+ },
"padding": {
"codegen-properties": {
"longhands": [
@@ -3850,6 +3880,16 @@
"url": "https://www.w3.org/TR/css3-speech/#speak-as"
}
},
+ "symbols": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-symbols"
+ }
+ },
"table-layout": {
"values": [
"auto",
@@ -6044,6 +6084,16 @@
},
"status": "non-standard"
},
+ "negative": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-negative"
+ }
+ },
"color-scheme": {
"inherited": true,
"values": [
@@ -6129,6 +6179,16 @@
"url": "https://www.w3.org/TR/css-transforms-1/#propdef-perspective-origin"
}
},
+ "prefix": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-prefix"
+ }
+ },
"-webkit-print-color-adjust": {
"inherited": true,
"values": [
@@ -6137,6 +6197,16 @@
],
"status": "non-standard"
},
+ "range": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-range"
+ }
+ },
"-webkit-rtl-ordering": {
"inherited": true,
"values": [
@@ -6149,6 +6219,16 @@
},
"status": "non-standard"
},
+ "suffix": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-suffix"
+ }
+ },
"-webkit-svg-shadow": {
"codegen-properties": {
"skip-codegen": true
@@ -6971,6 +7051,16 @@
"url": "https://www.w3.org/TR/css-shapes/#propdef-shape-image-threshold"
}
},
+ "system": {
+ "codegen-properties": {
+ "settings-flag": "cssCounterStyleAtRules",
+ "skip-builder": true
+ },
+ "specification": {
+ "category": "css-counter-styles",
+ "url": "https://www.w3.org/TR/css-counter-styles-3/#counter-style-system"
+ }
+ },
"-webkit-tap-highlight-color": {
"inherited": true,
"codegen-properties": {
@@ -7141,6 +7231,11 @@
"longname": "CSS Generated Content Module",
"url": "https://www.w3.org/TR/css-content-3/"
},
+ "css-counter-styles": {
+ "shortname": "CSS Counter Styles",
+ "longname": "CSS Counter Styles Module",
+ "url": "https://www.w3.org/TR/css-counter-styles-3"
+ },
"css-device-adapt": {
"shortname": "CSS Device Adaptation",
"longname": "CSS Device Adaptation Module",
Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (276487 => 276488)
--- trunk/Source/WebCore/css/CSSValueKeywords.in 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1505,6 +1505,24 @@
standard
high
+// @counter-style `system` descriptor values
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-system
+cyclic
+numeric
+// alphabetic
+symbolic
+additive
+// fixed
+extends
+
+// @counter-style `speak-as` descriptor values
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-speak-as
+// auto
+bullets
+numbers
+words
+// spell-out
+
// @supports selector()
// https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
selector
Modified: trunk/Source/WebCore/css/parser/CSSParserContext.cpp (276487 => 276488)
--- trunk/Source/WebCore/css/parser/CSSParserContext.cpp 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/parser/CSSParserContext.cpp 2021-04-23 05:25:40 UTC (rev 276488)
@@ -181,6 +181,16 @@
bool CSSParserContext::isPropertyRuntimeDisabled(CSSPropertyID property) const
{
switch (property) {
+ case CSSPropertyAdditiveSymbols:
+ case CSSPropertyFallback:
+ case CSSPropertyPad:
+ case CSSPropertySymbols:
+ case CSSPropertyNegative:
+ case CSSPropertyPrefix:
+ case CSSPropertyRange:
+ case CSSPropertySuffix:
+ case CSSPropertySystem:
+ return !counterStyleAtRulesEnabled;
case CSSPropertyAspectRatio:
return !aspectRatioEnabled;
case CSSPropertyContain:
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (276487 => 276488)
--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp 2021-04-23 05:25:40 UTC (rev 276488)
@@ -4535,15 +4535,219 @@
return nullptr;
}
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-system
+static RefPtr<CSSPrimitiveValue> consumeCounterStyleSystem(CSSParserTokenRange& range)
+{
+ if (auto ident = consumeIdent<CSSValueCyclic, CSSValueNumeric, CSSValueAlphabetic, CSSValueSymbolic, CSSValueAdditive>(range))
+ return ident;
+
+ if (auto ident = consumeIdent<CSSValueFixed>(range)) {
+ if (range.atEnd())
+ return ident;
+ // If we have the `fixed` keyword but the range is not at the end, the next token must be a integer.
+ // If it's not, this value is invalid.
+ auto firstSymbolValue = consumeInteger(range);
+ if (!firstSymbolValue)
+ return nullptr;
+ return createPrimitiveValuePair(ident.releaseNonNull(), firstSymbolValue.releaseNonNull());
+ }
+
+ if (auto ident = consumeIdent<CSSValueExtends>(range)) {
+ // There must be a `<counter-style-name>` following the `extends` keyword. If there isn't, this value is invalid.
+ auto parsedCounterStyleName = consumeCounterStyleName(range);
+ if (!parsedCounterStyleName)
+ return nullptr;
+ return createPrimitiveValuePair(ident.releaseNonNull(), parsedCounterStyleName.releaseNonNull());
+ }
+ return nullptr;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#typedef-symbol
+static RefPtr<CSSValue> consumeCounterStyleSymbol(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ if (auto string = consumeString(range))
+ return string;
+ if (auto customIdent = consumeCustomIdent(range))
+ return customIdent;
+ // There are inherent difficulties in supporting <image> symbols in @counter-styles, so gate them behind a
+ // flag for now. https://bugs.webkit.org/show_bug.cgi?id=167645
+ if (context.counterStyleAtRuleImageSymbolsEnabled) {
+ if (auto image = consumeImage(range, context, { AllowedImageType::URLFunction, AllowedImageType::GeneratedImage }))
+ return image;
+ }
+ return nullptr;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-negative
+static RefPtr<CSSValue> consumeCounterStyleNegative(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ auto prependValue = consumeCounterStyleSymbol(range, context);
+ if (!prependValue)
+ return nullptr;
+ if (range.atEnd())
+ return prependValue;
+
+ auto appendValue = consumeCounterStyleSymbol(range, context);
+ if (!appendValue || !range.atEnd())
+ return nullptr;
+
+ RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
+ values->append(prependValue.releaseNonNull());
+ values->append(appendValue.releaseNonNull());
+ return values;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-range
+static RefPtr<CSSPrimitiveValue> consumeCounterStyleRangeBound(CSSParserTokenRange& range)
+{
+ if (auto infinite = consumeIdent<CSSValueInfinite>(range))
+ return infinite;
+ if (auto integer = consumeInteger(range))
+ return integer;
+ return nullptr;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-range
+static RefPtr<CSSValue> consumeCounterStyleRange(CSSParserTokenRange& range)
+{
+ if (auto autoValue = consumeIdent<CSSValueAuto>(range))
+ return autoValue;
+
+ auto rangeList = CSSValueList::createCommaSeparated();
+ do {
+ auto lowerBound = consumeCounterStyleRangeBound(range);
+ if (!lowerBound)
+ return nullptr;
+ auto upperBound = consumeCounterStyleRangeBound(range);
+ if (!upperBound)
+ return nullptr;
+
+ // If the lower bound of any range is higher than the upper bound, the entire descriptor is invalid and must be
+ // ignored.
+ if (lowerBound->isNumber() && upperBound->isNumber() && lowerBound->intValue() > upperBound->intValue())
+ return nullptr;
+ rangeList->append(createPrimitiveValuePair(lowerBound.releaseNonNull(), upperBound.releaseNonNull(), Pair::IdenticalValueEncoding::DoNotCoalesce));
+ } while (consumeCommaIncludingWhitespace(range));
+ if (!range.atEnd() || !rangeList->length())
+ return nullptr;
+ return rangeList;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-pad
+static RefPtr<CSSValue> consumeCounterStylePad(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ RefPtr<CSSValue> integer;
+ RefPtr<CSSValue> symbol;
+ while (!integer || !symbol) {
+ if (!integer) {
+ integer = consumeInteger(range, 0);
+ if (integer)
+ continue;
+ }
+ if (!symbol) {
+ symbol = consumeCounterStyleSymbol(range, context);
+ if (symbol)
+ continue;
+ }
+ return nullptr;
+ }
+ if (!range.atEnd())
+ return nullptr;
+ auto values = CSSValueList::createSpaceSeparated();
+ values->append(integer.releaseNonNull());
+ values->append(symbol.releaseNonNull());
+ return values;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-symbols
+static RefPtr<CSSValue> consumeCounterStyleSymbols(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ auto symbols = CSSValueList::createSpaceSeparated();
+ while (!range.atEnd()) {
+ auto symbol = consumeCounterStyleSymbol(range, context);
+ if (!symbol)
+ return nullptr;
+ symbols->append(symbol.releaseNonNull());
+ }
+ if (!symbols->length())
+ return nullptr;
+ return symbols;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-symbols
+static RefPtr<CSSValue> consumeCounterStyleAdditiveSymbols(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ auto values = CSSValueList::createCommaSeparated();
+ RefPtr<CSSPrimitiveValue> lastInteger;
+ do {
+ RefPtr<CSSPrimitiveValue> integer;
+ RefPtr<CSSValue> symbol;
+ while (!integer || !symbol) {
+ if (!integer) {
+ integer = consumeInteger(range, 0);
+ if (integer)
+ continue;
+ }
+ if (!symbol) {
+ symbol = consumeCounterStyleSymbol(range, context);
+ if (symbol)
+ continue;
+ }
+ return nullptr;
+ }
+
+ if (lastInteger) {
+ // The additive tuples must be specified in order of strictly descending
+ // weight; otherwise, the declaration is invalid and must be ignored.
+ if (integer->intValue() >= lastInteger->intValue())
+ return nullptr;
+ }
+ lastInteger = integer;
+ values->append(integer.releaseNonNull());
+ values->append(symbol.releaseNonNull());
+ } while (consumeCommaIncludingWhitespace(range));
+ if (!range.atEnd() || !values->length())
+ return nullptr;
+ return values;
+}
+
+// https://www.w3.org/TR/css-counter-styles-3/#counter-style-speak-as
+static RefPtr<CSSValue> consumeCounterStyleSpeakAs(CSSParserTokenRange& range)
+{
+ if (auto speakAsIdent = consumeIdent<CSSValueAuto, CSSValueBullets, CSSValueNumbers, CSSValueWords, CSSValueSpellOut>(range))
+ return speakAsIdent;
+ return consumeCounterStyleName(range);
+}
+
RefPtr<CSSValue> CSSPropertyParser::parseCounterStyleDescriptor(CSSPropertyID propId, CSSParserTokenRange& range, const CSSParserContext& context)
{
if (!context.counterStyleAtRulesEnabled)
return nullptr;
- // FIXME: Implement this function when we can parse @counter-style descriptors.
- UNUSED_PARAM(propId);
- UNUSED_PARAM(range);
- UNUSED_PARAM(context);
- return nullptr;
+
+ switch (propId) {
+ case CSSPropertySystem:
+ return consumeCounterStyleSystem(range);
+ case CSSPropertyNegative:
+ return consumeCounterStyleNegative(range, context);
+ case CSSPropertyPrefix:
+ case CSSPropertySuffix:
+ return consumeCounterStyleSymbol(range, context);
+ case CSSPropertyRange:
+ return consumeCounterStyleRange(range);
+ case CSSPropertyPad:
+ return consumeCounterStylePad(range, context);
+ case CSSPropertyFallback:
+ return consumeCounterStyleName(range);
+ case CSSPropertySymbols:
+ return consumeCounterStyleSymbols(range, context);
+ case CSSPropertyAdditiveSymbols:
+ return consumeCounterStyleAdditiveSymbols(range, context);
+ case CSSPropertySpeakAs:
+ return consumeCounterStyleSpeakAs(range);
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
}
bool CSSPropertyParser::parseCounterStyleDescriptor(CSSPropertyID propId, const CSSParserContext& context)
Modified: trunk/Tools/ChangeLog (276487 => 276488)
--- trunk/Tools/ChangeLog 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Tools/ChangeLog 2021-04-23 05:25:40 UTC (rev 276488)
@@ -1,3 +1,15 @@
+2021-04-22 Tyler Wilcock <[email protected]>
+
+ [css-counter-styles] Parse @counter-style descriptors
+ https://bugs.webkit.org/show_bug.cgi?id=224718
+
+ Reviewed by Darin Adler.
+
+ * DumpRenderTree/TestOptions.cpp:
+ (WTR::TestOptions::defaults):
+ Fix typo (missing 's'). CSSCounterStyleAtRulesEnabled, not
+ CSSCounterStyleAtRuleEnabled.
+
2021-04-22 BJ Burg <[email protected]>
[Cocoa] re-enable test case WKInspectorDelegate.InspectorConfiguration
Modified: trunk/Tools/DumpRenderTree/TestOptions.cpp (276487 => 276488)
--- trunk/Tools/DumpRenderTree/TestOptions.cpp 2021-04-23 05:20:30 UTC (rev 276487)
+++ trunk/Tools/DumpRenderTree/TestOptions.cpp 2021-04-23 05:25:40 UTC (rev 276488)
@@ -133,7 +133,7 @@
{ "AsyncClipboardAPIEnabled", false },
{ "AttachmentElementEnabled", false },
{ "CSSContainmentEnabled", false },
- { "CSSCounterStyleAtRuleEnabled", false },
+ { "CSSCounterStyleAtRulesEnabled", false },
{ "CSSCounterStyleAtRuleImageSymbolsEnabled", false },
{ "CSSLogicalEnabled", false },
{ "CSSOMViewSmoothScrollingEnabled", false },