RESOLVED FIXED 190038
Registered custom properties should allow inheritance to be controlled
https://bugs.webkit.org/show_bug.cgi?id=190038
Summary Registered custom properties should allow inheritance to be controlled
Justin Michaud
Reported 2018-09-27 08:32:47 PDT
Registered custom properties should allow inheritance to be controlled by the inherits parameter.
Attachments
Patch (93.12 KB, patch)
2018-09-27 09:04 PDT, Justin Michaud
no flags
Archive of layout-test-results from ews103 for mac-sierra (2.37 MB, application/zip)
2018-09-27 10:17 PDT, EWS Watchlist
no flags
Archive of layout-test-results from ews106 for mac-sierra-wk2 (2.90 MB, application/zip)
2018-09-27 10:29 PDT, EWS Watchlist
no flags
Archive of layout-test-results from ews112 for mac-sierra (3.05 MB, application/zip)
2018-09-27 11:10 PDT, EWS Watchlist
no flags
Archive of layout-test-results from ews125 for ios-simulator-wk2 (28.61 MB, application/zip)
2018-09-27 11:24 PDT, EWS Watchlist
no flags
Archive of layout-test-results from ews117 for mac-sierra (3.04 MB, application/zip)
2018-09-27 13:13 PDT, EWS Watchlist
no flags
Patch (97.60 KB, patch)
2018-09-27 13:42 PDT, Justin Michaud
no flags
Patch (99.87 KB, patch)
2018-09-27 19:41 PDT, Justin Michaud
no flags
Patch (101.05 KB, patch)
2018-09-27 20:33 PDT, Justin Michaud
no flags
Patch (101.55 KB, patch)
2018-09-28 14:19 PDT, Justin Michaud
no flags
Patch (101.57 KB, patch)
2018-09-28 15:32 PDT, Justin Michaud
no flags
Patch (110.70 KB, patch)
2018-10-01 21:58 PDT, Justin Michaud
no flags
Patch (110.47 KB, patch)
2018-10-01 22:07 PDT, Justin Michaud
no flags
Archive of layout-test-results from ews107 for mac-sierra-wk2 (3.05 MB, application/zip)
2018-10-01 23:29 PDT, EWS Watchlist
no flags
Patch (143.17 KB, patch)
2018-10-02 10:35 PDT, Justin Michaud
no flags
Patch (143.17 KB, patch)
2018-10-03 10:20 PDT, Justin Michaud
no flags
Justin Michaud
Comment 1 2018-09-27 09:04:50 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 2 2018-09-27 09:07:21 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 3 2018-09-27 10:17:30 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 4 2018-09-27 10:17:32 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 5 2018-09-27 10:29:38 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 6 2018-09-27 10:29:40 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 7 2018-09-27 11:10:10 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 8 2018-09-27 11:10:12 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 9 2018-09-27 11:23:58 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 10 2018-09-27 11:24:00 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 11 2018-09-27 13:13:09 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 12 2018-09-27 13:13:11 PDT Comment hidden (obsolete)
Justin Michaud
Comment 13 2018-09-27 13:42:54 PDT Comment hidden (obsolete)
Justin Michaud
Comment 14 2018-09-27 14:18:19 PDT Comment hidden (obsolete)
Justin Michaud
Comment 15 2018-09-27 15:21:23 PDT Comment hidden (obsolete)
Justin Michaud
Comment 16 2018-09-27 19:41:10 PDT
Justin Michaud
Comment 17 2018-09-27 20:33:32 PDT
Dean Jackson
Comment 18 2018-09-28 11:33:01 PDT
Comment on attachment 351045 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351045&action=review You might want to wait for smfr to take a look at this. Otherwise, I like it! > Source/WebCore/ChangeLog:26 > + * css/CSSComputedStyleDeclaration.cpp: > + (WebCore::ComputedStyleExtractor::customPropertyValue): Since this is a pretty large patch, can you provide short summaries of what you changed in this section? You don't need to do it for every line, or even every file, but it's nice to split it into groups of related code and say what happened. e.g. Changed "CustomPropertyValueMap" to "CustomPropertyValueCascade". > Source/WebCore/css/CSSComputedStyleDeclaration.cpp:2631 > + // TODO this should be done based on the syntax Nit: End comment with . > Source/WebCore/css/CSSCustomPropertyValue.h:82 > + Length* resolvedTypedValue() { return m_resolvedTypedValue.get(); } > + const Length* resolvedTypedValue() const { return m_resolvedTypedValue.get(); } > + void setResolvedTypedValue(Length length) { m_resolvedTypedValue = std::make_unique<Length>(WTFMove(length)); } Do you think this might be better named resolvedLengthValue()? At the moment you're only resolving Lengths - will that always be the case? > Source/WebCore/css/CSSCustomPropertyValue.h:119 > + // TODO It should not be possible to express an invalid state, such as containsVariables() && resolvedTypedValue() Nit: Say "FIXME:" instead of "TODO". End comment with . > Source/WebCore/css/CSSValue.cpp:493 > + auto* val = map? map->get(name) : nullptr; Nit: Space before ? I'm trying to see if there is a better way to write this.... for (auto* map : m_map) { if (!map) continue; if (auto* val = map->get(name)) return val; } I'm not sure it is better. > Source/WebCore/css/CSSValue.h:280 > +// Wrapper class to merge a number of CustomPropertyValueMaps into one, picking the first map > +// that contains a particular key Nit: End comment with . > Source/WebCore/css/CSSValue.h:284 > + CustomPropertyValueMapCascade(const Vector<const CustomPropertyValueMap*>& map) > + : m_map { map } { } Style Nit: CustomPropertyValueMapCascade(const Vector<const CustomPropertyValueMap*>& map) : m_map { map } { } > Source/WebCore/css/CSSVariableData.cpp:147 > + // TODO we should not have to serialize a value that was already resolved Nit: FIXME: and . > Source/WebCore/css/StyleBuilderCustom.h:1880 > +// These are called directly from the generated code, not based off the json file I don't think you need this comment. > Source/WebCore/css/StyleBuilderCustom.h:1883 > + auto* initialVal = registered? registered->initialValue.get() : nullptr; Nit: Space before ? > Source/WebCore/css/StyleResolver.cpp:2279 > + // TODO cycles should be detected Nit: FIXME: and . > Source/WebCore/css/parser/CSSPropertyParser.cpp:3953 > + case CSSPropertyCustom: // TODO this should be based on syntax Nit: FIXME: and . > Source/WebCore/rendering/style/RenderStyle.cpp:2252 > + for (auto* customPropertyData : {&inheritedPropertyData, &nonInheritedPropertyData}) { Nit: Spaces around { and } > Source/WebCore/rendering/style/RenderStyle.cpp:2266 > + // Now insert invalid values, or defaults if the property is registered Nit: . > Source/WebCore/rendering/style/RenderStyle.cpp:2269 > + auto* registered = registeredProperties.get(property); This can go down where it is first used.
Justin Michaud
Comment 19 2018-09-28 14:19:49 PDT
Justin Michaud
Comment 20 2018-09-28 15:32:48 PDT
Justin Michaud
Comment 21 2018-09-28 20:10:21 PDT
Comment on attachment 351124 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351124&action=review > Source/WebCore/css/StyleResolver.cpp:1639 > + CSSRegisteredCustomProperty* customPropertyRegistered; This is ub, which is why the windows build failed I think. Why did nothing else catch this?
Antti Koivisto
Comment 22 2018-10-01 02:13:13 PDT
Comment on attachment 351124 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351124&action=review > Source/WebCore/css/CSSComputedStyleDeclaration.cpp:2628 > + auto* value = CustomPropertyValueMapCascade({ &style->inheritedCustomProperties(), &style->nonInheritedCustomProperties() }).get(propertyName); That's a pretty indirect way of doing two hash lookups. > Source/WebCore/css/CSSComputedStyleDeclaration.cpp:4166 > - auto results = copyToVector(customProperties.keys()); > - return results.at(index); > + const auto& inheritedCustomProperties = style->inheritedCustomProperties(); > + > + if (i < numComputedProperties + inheritedCustomProperties.size()) { > + auto results = copyToVector(inheritedCustomProperties.keys()); > + return results.at(i - numComputedProperties); > + } > + > + const auto& nonInheritedCustomProperties = style->nonInheritedCustomProperties(); > + auto results = copyToVector(nonInheritedCustomProperties.keys()); > + return results.at(i - inheritedCustomProperties.size() - numComputedProperties); This code is weird. We are indexing into hash maps that have completely random order. There is also unnecessary copying into a vector. I know this patch didn't add these things but still... > Source/WebCore/css/CSSCustomPropertyValue.h:81 > + Length* resolvedTypedValue() { return m_resolvedTypedValue.get(); } > + const Length* resolvedTypedValue() const { return m_resolvedTypedValue.get(); } Returning std::optional<Length> would be more modern. > Source/WebCore/css/CSSCustomPropertyValue.h:120 > + // FIXME: It should not be possible to express an invalid state, such as containsVariables() && resolvedTypedValue(). > + std::unique_ptr<Length> m_resolvedTypedValue { nullptr }; I think you want std::optional. Also explicit initialization is unnecessary. > Source/WebCore/css/CSSValue.cpp:499 > +CSSCustomPropertyValue* CustomPropertyValueMapCascade::get(const AtomicString& name) const > +{ > + for (auto* map : m_map) { > + if (!map) > + continue; > + if (auto* val = map->get(name)) > + return val; > + } > + return nullptr; > +} Maybe this should just be a helper on RenderStyle? (see below) > Source/WebCore/css/CSSValue.h:292 > +// Wrapper class to merge a number of CustomPropertyValueMaps into one, picking the first map > +// that contains a particular key. > +class CustomPropertyValueMapCascade { > +public: > + CustomPropertyValueMapCascade(const Vector<const CustomPropertyValueMap*>& map) > + : m_map { map } > + { > + } > + > + CSSCustomPropertyValue* get(const AtomicString& name) const; > + > +private: > + const Vector<const CustomPropertyValueMap*> m_map; > +}; What guarantees the CustomPropertyValueMaps stay alive during lifetime of this object? > Source/WebCore/css/StyleBuilderCustom.h:1883 > + auto* initialVal = registered ? registered->initialValue.get() : nullptr; > + if (initialVal) { initialVal local doesn't add anything and could be removed. Also WebKit style is to use full words ('initialValue'). > Source/WebCore/css/StyleBuilderCustom.h:1903 > +inline void StyleBuilderCustom::applyValueCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, CSSValue& value) > +{ > + auto* customPropertyValue = &downcast<CSSCustomPropertyValue>(value); How do we know this cast is safe? The function should probably be taking CSSCustomPropertyValue and leaving casting to the clients. > Source/WebCore/css/StyleResolver.cpp:1710 > + CustomPropertyValueMapCascade customProperties({ &m_state.style()->inheritedCustomProperties(), &m_state.style()->nonInheritedCustomProperties() }); > + > + return parser.parseValueWithVariableReferences(propID, value, customProperties, document().getCSSRegisteredCustomPropertySet(), *m_state.style()); You now pass both CustomPropertyValueMapCascade and style almost everywhere. This makes the whole CustomPropertyValueMapCascade type sort of pointless (and it doesn't do much in the first place) as all the same information is available from RenderStyle. How about just getting rid of CustomPropertyValueMapCascade and simply adding a property name getter to RenderStyle that resolves the value from right maps? > Source/WebCore/css/makeprop.pl:1041 > + if (isInitial) > + StyleBuilderCustom::applyInitialCustomProperty(styleResolver, registered, downcast<CSSCustomPropertyValue>(value).name()); > + else if (isInherit) > + StyleBuilderCustom::applyInheritCustomProperty(styleResolver, registered, downcast<CSSCustomPropertyValue>(value).name()); > + else > + StyleBuilderCustom::applyValueCustomProperty(styleResolver, registered, value); Why does't call to applyValueCustomProperty cast the value to CSSCustomPropertyValue here like the other functions do? > Source/WebCore/css/parser/CSSParser.cpp:216 > + if (value.isVariableReferenceValue()) { > + const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value); is<CSSVariableReferenceValue>(value) pairs better with downcast<> > Source/WebCore/css/parser/CSSPropertyParser.cpp:3953 > + case CSSPropertyCustom: // FIXME this should be based on syntax. I don't understand the comment. > Source/WebCore/rendering/style/RenderStyle.cpp:2249 > - if (!m_rareInheritedData->customProperties->containsVariables) > - return; > + auto& inheritedPropertyData = m_rareInheritedData.access().customProperties.access(); > + auto& nonInheritedPropertyData = m_rareNonInheritedData.access().customProperties.access(); This now copies both rareInheritedData and rareNonInheritedData unconditionally. You should check what actually needs to be mutated before triggering COW.
Justin Michaud
Comment 23 2018-10-01 13:30:14 PDT
Comment on attachment 351124 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351124&action=review >> Source/WebCore/css/parser/CSSParser.cpp:216 >> + const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value); > > is<CSSVariableReferenceValue>(value) pairs better with downcast<> Why does the original code use isVariableReferenceValue() instead of is<>()? Is it just legacy?
Justin Michaud
Comment 24 2018-10-01 21:58:28 PDT
Justin Michaud
Comment 25 2018-10-01 22:07:23 PDT
EWS Watchlist
Comment 26 2018-10-01 23:29:28 PDT Comment hidden (obsolete)
EWS Watchlist
Comment 27 2018-10-01 23:29:30 PDT Comment hidden (obsolete)
Justin Michaud
Comment 28 2018-10-02 10:35:18 PDT
Antti Koivisto
Comment 29 2018-10-03 06:51:18 PDT
Comment on attachment 351415 [details] Patch Looks good, r=me
Antti Koivisto
Comment 30 2018-10-03 07:03:31 PDT
Comment on attachment 351415 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351415&action=review > Source/WebCore/css/CSSCustomPropertyValue.h:85 > + const std::optional<Length> resolvedTypedValue() const { return m_resolvedTypedValue; } This could return a reference. > Source/WebCore/rendering/style/RenderStyle.h:2006 > + for (auto* map : { &nonInheritedCustomProperties(), &inheritedCustomProperties() }) { Would simply for (auto& map : { nonInheritedCustomProperties(), inheritedCustomProperties() }) work (or would it end up creating copies of the maps)?
Justin Michaud
Comment 31 2018-10-03 10:19:31 PDT
Comment on attachment 351415 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=351415&action=review >> Source/WebCore/rendering/style/RenderStyle.h:2006 >> + for (auto* map : { &nonInheritedCustomProperties(), &inheritedCustomProperties() }) { > > Would simply > > for (auto& map : { nonInheritedCustomProperties(), inheritedCustomProperties() }) > > work (or would it end up creating copies of the maps)? I think we need some kind of wrapper on it, since you can't have an initialization list of references as far as I know.
Justin Michaud
Comment 32 2018-10-03 10:20:56 PDT
WebKit Commit Bot
Comment 33 2018-10-03 23:23:10 PDT
Comment on attachment 351532 [details] Patch Clearing flags on attachment: 351532 Committed r236828: <https://trac.webkit.org/changeset/236828>
WebKit Commit Bot
Comment 34 2018-10-03 23:23:12 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 35 2018-10-03 23:24:45 PDT
Note You need to log in before you can comment on or make changes to this bug.