New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing CounterStyle representation from StyleRuleCounterStyle #7114
Conversation
EWS run on previous version of this PR (hash 848a0ff) |
848a0ff
to
5792294
Compare
EWS run on previous version of this PR (hash 5792294) |
5792294
to
a1e3c1e
Compare
EWS run on previous version of this PR (hash a1e3c1e) |
a1e3c1e
to
83b454c
Compare
EWS run on previous version of this PR (hash 83b454c) |
83b454c
to
7361ba0
Compare
EWS run on previous version of this PR (hash 7361ba0) |
7361ba0
to
0a79b29
Compare
EWS run on previous version of this PR (hash 0a79b29) |
0a79b29
to
2903417
Compare
EWS run on previous version of this PR (hash 2903417) |
EWS run on previous version of this PR (hash 2d5d818) |
CounterStyle::CounterStyle(Name name, CounterStyleSystem system, NegativeSymbols negativeSymbols, Symbol prefix, Symbol suffix, Ranges&& ranges, Pad pad, Name fallback, Vector<Symbol>&& symbols, CounterStyleSpeakAs speakAs, Name speakAsReference) | ||
: m_predefinedCounterStyle { true }, m_name { name }, m_system { system }, m_negativeSymbols { negativeSymbols }, m_prefix { prefix }, m_suffix { suffix }, m_ranges { WTFMove(ranges) }, m_pad { pad }, m_fallbackName { fallback }, m_symbols { WTFMove(symbols) }, m_speakAs { speakAs }, m_speakAsNameReference { speakAsReference } | ||
{ } | ||
|
||
CounterStyle::CounterStyle(const StyleRuleCounterStyle& rule) | ||
: m_name { rule.name() }, m_system { toCounterStyleSystemEnum(rule.systemCSSValue()) }, m_negativeSymbols { translateNegativeSymbolsFromStyleRule(rule) }, m_prefix { translatePrefixFromStyleRule(rule) }, m_suffix { translateSuffixFromStyleRule(rule) }, m_ranges { translateRangeFromStyleRule(rule) }, m_pad { translatePadFromStyleRule(rule) }, m_fallbackName { translateFallbackNameFromStyleRule(rule) }, m_symbols { translateSymbolsFromStyleRule(rule) }, m_speakAs { CounterStyleSpeakAs::Auto }, m_speakAsNameReference { ""_s } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a lot of constructor parameters. Maybe this type could be a struct (with public fields) instead of a class? Then you just initialize it with { ... } without writing an explicit constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CounterStyle is a derived class so it won't be classified as an aggregate, right?
https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right but the question is if should/needs to be refcounted. Alternatively you could have a separate pure struct that just contains the fields. CounterStyleDescriptors or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formatting does not follow WebKit style. Each field initialization should be in a separate line, indented.
SpellOut, | ||
CounterStyleNameReference, | ||
}; | ||
|
||
class StyleRuleCounterStyle final : public StyleRuleBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should really be in a file of its own.
RefPtr<CSSValue> systemCSSValue() const { return getPropertyCSSValue(CSSPropertySystem); } | ||
RefPtr<CSSValue> negativeCSSValue() const { return getPropertyCSSValue(CSSPropertyNegative); } | ||
RefPtr<CSSValue> prefixCSSValue() const { return getPropertyCSSValue(CSSPropertyPrefix); } | ||
RefPtr<CSSValue> suffixCSSValue() const { return getPropertyCSSValue(CSSPropertySuffix); } | ||
RefPtr<CSSValue> rangeCSSValue() const { return getPropertyCSSValue(CSSPropertyRange); } | ||
RefPtr<CSSValue> padCSSValue() const { return getPropertyCSSValue(CSSPropertyPad); } | ||
RefPtr<CSSValue> fallbackCSSValue() const { return getPropertyCSSValue(CSSPropertyFallback); } | ||
RefPtr<CSSValue> symbolsCSSValue() const { return getPropertyCSSValue(CSSPropertySymbols); } | ||
RefPtr<CSSValue> additiveSymbolsCSSValue() const { return getPropertyCSSValue(CSSPropertyAdditiveSymbols); } | ||
RefPtr<CSSValue> speakAsCSSValue() const { return getPropertyCSSValue(CSSPropertySpeakAs); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you didn't implement this type but the factoring here is really not ideal. Instead of a StyleProperties member there should be a more processed type that represents the counter style as enums/OptionSets or whatever is appropriate of each type.
You have such a type. Maybe you can replace StyleProperties with your CounterStyle type here?
Source/WebCore/css/CSSCounterStyle.h
Outdated
CounterStyleMap m_authorCounterStyles; | ||
}; | ||
|
||
class CounterStyle : public RefCounted<CounterStyle>, public CanMakeWeakPtr<CounterStyle> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be in a file of its own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filename should match the class name (CSSCounterStyle vs CounterStyle)
Source/WebCore/css/CSSCounterStyle.h
Outdated
class CounterStyle; | ||
using CounterStyleMap = HashMap<AtomString, RefPtr<CounterStyle>>; | ||
|
||
class CounterStyleManager : public RefCounted<CounterStyleManager> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't like Managers. How about Registry?
This should be in a file of its own.
Source/WebCore/css/CSSCounterStyle.h
Outdated
WeakPtr<const CounterStyle> m_extendsReference { nullptr }; | ||
int m_fixedSystemFirstSymbolValue { 1 }; | ||
|
||
OptionSet<ExplicitlySetDescriptors> m_explicitlySetDescriptors; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of maintaining this OptionSet maybe you could make the individual fields std::optional<>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't achieve the same intent. All the descriptors values are defined, implicitly or explicitly. No explicit values should not be overridden when resolving Extends. I.E.: when CounterStyleA extends CounterStyleB, A will just inherit the values from the descriptors that were explicitly defined by the author, but all the descriptors have at least an implicit value.
2d5d818
to
6b429b3
Compare
EWS run on previous version of this PR (hash 6b429b3) |
6b429b3
to
213f69c
Compare
EWS run on previous version of this PR (hash 213f69c) |
213f69c
to
d71b203
Compare
EWS run on previous version of this PR (hash d71b203) |
d71b203
to
166f529
Compare
EWS run on previous version of this PR (hash 166f529) |
166f529
to
832fb78
Compare
EWS run on previous version of this PR (hash 832fb78) |
Source/WebCore/css/CSSCounterStyle.h
Outdated
CounterStyleMap m_authorCounterStyles; | ||
}; | ||
|
||
class CounterStyle : public RefCounted<CounterStyle>, public CanMakeWeakPtr<CounterStyle> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filename should match the class name (CSSCounterStyle vs CounterStyle)
CounterStyle::CounterStyle(Name name, CounterStyleSystem system, NegativeSymbols negativeSymbols, Symbol prefix, Symbol suffix, Ranges&& ranges, Pad pad, Name fallback, Vector<Symbol>&& symbols, CounterStyleSpeakAs speakAs, Name speakAsReference) | ||
: m_predefinedCounterStyle { true }, m_name { name }, m_system { system }, m_negativeSymbols { negativeSymbols }, m_prefix { prefix }, m_suffix { suffix }, m_ranges { WTFMove(ranges) }, m_pad { pad }, m_fallbackName { fallback }, m_symbols { WTFMove(symbols) }, m_speakAs { speakAs }, m_speakAsNameReference { speakAsReference } | ||
{ } | ||
|
||
CounterStyle::CounterStyle(const StyleRuleCounterStyle& rule) | ||
: m_name { rule.name() }, m_system { toCounterStyleSystemEnum(rule.systemCSSValue()) }, m_negativeSymbols { translateNegativeSymbolsFromStyleRule(rule) }, m_prefix { translatePrefixFromStyleRule(rule) }, m_suffix { translateSuffixFromStyleRule(rule) }, m_ranges { translateRangeFromStyleRule(rule) }, m_pad { translatePadFromStyleRule(rule) }, m_fallbackName { translateFallbackNameFromStyleRule(rule) }, m_symbols { translateSymbolsFromStyleRule(rule) }, m_speakAs { CounterStyleSpeakAs::Auto }, m_speakAsNameReference { ""_s } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right but the question is if should/needs to be refcounted. Alternatively you could have a separate pure struct that just contains the fields. CounterStyleDescriptors or something.
CounterStyle::CounterStyle(Name name, CounterStyleSystem system, NegativeSymbols negativeSymbols, Symbol prefix, Symbol suffix, Ranges&& ranges, Pad pad, Name fallback, Vector<Symbol>&& symbols, CounterStyleSpeakAs speakAs, Name speakAsReference) | ||
: m_predefinedCounterStyle { true }, m_name { name }, m_system { system }, m_negativeSymbols { negativeSymbols }, m_prefix { prefix }, m_suffix { suffix }, m_ranges { WTFMove(ranges) }, m_pad { pad }, m_fallbackName { fallback }, m_symbols { WTFMove(symbols) }, m_speakAs { speakAs }, m_speakAsNameReference { speakAsReference } | ||
{ } | ||
|
||
CounterStyle::CounterStyle(const StyleRuleCounterStyle& rule) | ||
: m_name { rule.name() }, m_system { toCounterStyleSystemEnum(rule.systemCSSValue()) }, m_negativeSymbols { translateNegativeSymbolsFromStyleRule(rule) }, m_prefix { translatePrefixFromStyleRule(rule) }, m_suffix { translateSuffixFromStyleRule(rule) }, m_ranges { translateRangeFromStyleRule(rule) }, m_pad { translatePadFromStyleRule(rule) }, m_fallbackName { translateFallbackNameFromStyleRule(rule) }, m_symbols { translateSymbolsFromStyleRule(rule) }, m_speakAs { CounterStyleSpeakAs::Auto }, m_speakAsNameReference { ""_s } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formatting does not follow WebKit style. Each field initialization should be in a separate line, indented.
static CounterStyle::Ranges translateRangeFromStyleRule(const StyleRuleCounterStyle& rule) | ||
{ | ||
auto ranges = rule.rangeCSSValue(); | ||
// auto range will return an empty Ranges | ||
if (!ranges || !is<CSSValueList>(ranges)) | ||
return { }; | ||
auto& list = downcast<CSSValueList>(*ranges); | ||
CounterStyle::Ranges result; | ||
for (auto& rangeValue : list) { | ||
ASSERT(rangeValue->isPrimitiveValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to parse these from a style declaration in StyleRuleCounterStyle is awkward. I think we could have done this at parse time and saved a CounterStyle (or a type that just contains the parsed fields, CounterStyleDescriptor or something) in StyleRuleCounterStyle.
It is bit unclear to me what CounterStyle class represents. Is it final computed counter style that can be pointed to by RenderStyle and directly used by layout/rendering code? Is it an intermediate type that acts as input for style resolution? Or both?
Source/WebCore/css/CSSCounterStyle.h
Outdated
return m_name == other.m_name | ||
&& m_system == other.m_system | ||
&& m_negativeSymbols == other.m_negativeSymbols | ||
&& m_prefix == other.m_prefix | ||
&& m_suffix == other.m_suffix | ||
&& m_ranges == other.m_ranges | ||
&& m_pad == other.m_pad | ||
&& m_fallbackName == other.m_fallbackName | ||
&& m_symbols == other.m_symbols | ||
&& m_additiveSymbols == other.m_additiveSymbols | ||
&& m_speakAs == other.m_speakAs | ||
&& m_speakAsNameReference == other.m_speakAsNameReference | ||
&& m_predefinedCounterStyle == other.m_predefinedCounterStyle | ||
&& m_explicitlySetDescriptors == other.m_explicitlySetDescriptors; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&& lines should be indented.
Source/WebCore/css/CSSCounterStyle.h
Outdated
struct Pad { | ||
unsigned m_padMinimumLength = 0; | ||
Symbol m_padSymbol = "-"_s; | ||
bool operator==(const Pad& other) const = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately I think these still fail to compile in some supported linux configurations.
String counterForSystemCyclic(int); | ||
String counterForSystemFixed(int); | ||
String counterForSystemSymbolic(int); | ||
String counterForSystemAlphabetic(int); | ||
String counterForSystemNumeric(int); | ||
String counterForSystemAdditive(int); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are declared but not defined. It would be nicer to at least add stubs.
for (auto& symbolValue : list) { | ||
auto symbolString = symbolToString(&symbolValue.get()); | ||
if (!symbolString.isNull()) | ||
result.constructAndAppend(WTFMove(symbolString)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why constructAndAppend instead of just append?
if (high->isInteger()) | ||
convertedHigh = high->intValue(); | ||
std::pair<int, int> newRange { convertedLow, convertedHigh }; | ||
result.constructAndAppend(WTFMove(newRange)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why constructAndAppend instead of just append?
if (rule.systemCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::System); | ||
if (rule.negativeCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Negative); | ||
if (rule.prefixCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Prefix); | ||
if (rule.suffixCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Suffix); | ||
if (rule.rangeCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Range); | ||
if (rule.padCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Pad); | ||
if (rule.fallbackCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Fallback); | ||
if (rule.symbolsCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::Symbols); | ||
if (rule.additiveSymbolsCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::AdditiveSymbols); | ||
if (rule.speakAsCSSValue()) | ||
m_explicitlySetDescriptors.add(ExplicitlySetDescriptors::SpeakAs); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be better to not try to implement all descriptors in one go. Maybe just start with a few of the most common ones and add the rest when the whole mechanism is in place? It would make these patches easier to follow and review.
832fb78
to
a8cbff0
Compare
EWS run on previous version of this PR (hash a8cbff0) |
a8cbff0
to
3006368
Compare
EWS run on current version of this PR (hash 3006368) |
3006368
to
f18c3d3
Compare
https://bugs.webkit.org/show_bug.cgi?id=248666 rdar://102910060 Reviewed by Antti Koivisto. Reviewed by Antti Koivisto. * Source/WebCore/Headers.cmake: * Source/WebCore/Sources.txt: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: Adding CSSCounterStyle and CSSCounterStyleDescriptors .h and .cpp files. * Source/WebCore/css/CSSCounterStyle.cpp: Added. (WebCore::CounterStyle::isInRange const): Returns true if counter is in range, as defined by https://www.w3.org/TR/css-counter-styles-3/#descdef-counter-style-range. (WebCore::CounterStyle::CounterStyle): (WebCore::CounterStyle::create): (WebCore::CounterStyle::createCounterStyleDecimal): Create a CounterStyle object representing a Decimal counter. (WebCore::CounterStyle::setFallbackReference): (WebCore::CounterStyle::extendAndResolve): Extend another CounterStyle as defined by https://www.w3.org/TR/css-counter-styles-3/#extends-system and resolve its Extend reference. The counter's system value is then promoted from 'extend' to the valye of the CounterStyle we are extending. (WebCore::CounterStyle::text): Dummy text representation for the counter. The real representation wil be implemented by rdar://103648354. * Source/WebCore/css/CSSCounterStyle.h: Added. (WebCore::CounterStyle::operator== const): (WebCore::CounterStyle::fallbackName const): (WebCore::CounterStyle::extendsName const): (WebCore::CounterStyle::isFallbackUnresolved): (WebCore::CounterStyle::isExtendsUnresolved): (WebCore::CounterStyle::isExtendsSystem const): (WebCore::CounterStyle::system const): (WebCore::CounterStyle::isPredefinedCounterStyle const): Returns true if CounterStyle is predefined by the user agent stylesheet. A counter style parsed from author-defined rule will return false. (WebCore::CounterStyle::isAutoRange const): Returns true if the range descriptor is set to 'auto'. A 'auto' value is represented by a empty vector of ranges. * Source/WebCore/css/CSSCounterStyleRule.cpp: (WebCore::toCounterStyleSystemEnum): * Source/WebCore/css/CSSCounterStyleRule.h: Moving enum to CSSCounterStyle.h. Adding getters for the properties's CSS values. * Source/WebCore/css/CSSStyleSheet.cpp: * Source/WebCore/css/CSSValueKeywords.in: * Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp: (WebCore::CSSPropertyParserHelpers::consumeCounterStyleSystem): * Source/WebCore/dom/Element.h: * Source/WebCore/style/MatchedDeclarationsCache.cpp: (WebCore::Style::MatchedDeclarationsCache::isCacheable): Adding FIXME with matching radars. CSSCounterStyleDescriptors defines the descriptors for the counter-style rule in a specialized manner. It serves as a payload for CSSCounterStyle. * Source/WebCore/css/CSSCounterStyleDescriptors.cpp: Added. (WebCore::translateRangeFromStyleProperties): (WebCore::symbolToString): (WebCore::translatePadFromStyleProperties): (WebCore::translateNegativeSymbolsFromStyleProperties): (WebCore::translateSymbolsFromStyleProperties): (WebCore::translateFallbackNameFromStyleProperties): (WebCore::translatePrefixFromStyleProperties): (WebCore::translateSuffixFromStyleProperties): (WebCore::extractDataFromSystemDescriptor): (WebCore::CSSCounterStyleDescriptors::setExplicitlySetDescriptors): Translation from CSSValues of rule's properties to adequated specialized types. (WebCore::CSSCounterStyleDescriptors::create): Creates an instance of CSSCounterStyleDescriptor based on StyleProperties. A create function was preferred instead of a constructor in order to maintain the class as a aggregate, enabling desginated initializers. * Source/WebCore/css/CSSCounterStyleDescriptors.h: Added. Canonical link: https://commits.webkit.org/258434@main
f18c3d3
to
ac2f8a4
Compare
Committed 258434@main (ac2f8a4): https://commits.webkit.org/258434@main Reviewed commits have been landed. Closing PR #7114 and removing active labels. |
ac2f8a4
3006368
π§ͺ gtk-wk2π§ͺ api-iosπ§ͺ api-gtk