Bug 186344

Summary: font-synthesis inline/computed style in non-canonical
Product: WebKit Reporter: Eric Willigers <ericwilligers>
Component: CSSAssignee: Joonghun Park <jh718.park>
Status: RESOLVED FIXED    
Severity: Normal CC: darin, esprehn+autocc, ews-watchlist, glenn, gsnedders, gyuyoung.kim, jh718.park, koivisto, macpherson, menard, mmaxfield, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 11   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Update layout test results for ios and common
none
Canonicalize CSSValueList at parsing stage in consumeFontSynthesis
none
Patch for landing none

Eric Willigers
Reported 2018-06-06 04:08:48 PDT
Test case: https://jsfiddle.net/ericwilligers/2q9cmrha/ Spec: https://drafts.csswg.org/css-fonts-3/#propdef-font-synthesis none | [ weight || style ] If the values 'weight style' or 'style weight' are assigned, the computed style should be 'weight style', but WebKit gives 'style weight'.
Attachments
Patch (7.17 KB, patch)
2021-11-02 17:59 PDT, Joonghun Park
no flags
Patch (44.41 KB, patch)
2021-11-02 22:23 PDT, Joonghun Park
no flags
Patch (69.44 KB, patch)
2021-11-03 06:07 PDT, Joonghun Park
no flags
Update layout test results for ios and common (98.48 KB, patch)
2021-11-04 00:39 PDT, Joonghun Park
no flags
Canonicalize CSSValueList at parsing stage in consumeFontSynthesis (98.64 KB, patch)
2021-11-05 21:51 PDT, Joonghun Park
no flags
Patch for landing (98.15 KB, patch)
2021-11-06 05:00 PDT, Joonghun Park
no flags
Myles C. Maxfield
Comment 1 2018-06-18 15:59:45 PDT
I thought the spec was in the process of changing the syntax fairly dramatically? I mean, we can flip the order super easily, but if we're going to be changing our implementation substantially, we may want to wait.
Sam Sneddon [:gsnedders]
Comment 2 2021-10-20 08:34:58 PDT
Joonghun Park
Comment 3 2021-11-02 17:59:21 PDT
Joonghun Park
Comment 4 2021-11-02 18:54:30 PDT
Comment on attachment 443153 [details] Patch Layout test results will be updated with the next patchset.
Myles C. Maxfield
Comment 5 2021-11-02 19:08:07 PDT
Comment on attachment 443153 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443153&action=review r=mews > Source/WebCore/css/StyleProperties.cpp:173 > + case CSSPropertyFontSynthesis: > + return fontSynthesisPropertyValue(*value); This is a surprising place for this code. Why is this here and not below (or maybe even in another function?)
Simon Fraser (smfr)
Comment 6 2021-11-02 20:04:30 PDT
Comment on attachment 443153 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443153&action=review >> Source/WebCore/css/StyleProperties.cpp:173 >> + return fontSynthesisPropertyValue(*value); > > This is a surprising place for this code. Why is this here and not below (or maybe even in another function?) Falling through from CSSPropertyStrokeOpacity and returning a fontSynthesisPropertyValue() doesn't seem right.
Joonghun Park
Comment 7 2021-11-02 21:05:05 PDT
Comment on attachment 443153 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=443153&action=review >>> Source/WebCore/css/StyleProperties.cpp:173 >>> + return fontSynthesisPropertyValue(*value); >> >> This is a surprising place for this code. Why is this here and not below (or maybe even in another function?) > > Falling through from CSSPropertyStrokeOpacity and returning a fontSynthesisPropertyValue() doesn't seem right. I moved this callsite to above. Originally I placed this here because it was right before default switch but I didn't see the FALLTHROUGH. And it seems that below place is for shorthand properties, so I will place this call as below. if (auto value = getPropertyCSSValue(propertyID)) { switch (propertyID) { case CSSPropertyFontSynthesis: return fontSynthesisPropertyValue(*value); case CSSPropertyFillOpacity: case CSSPropertyFloodOpacity: ...
Joonghun Park
Comment 8 2021-11-02 22:23:50 PDT
Joonghun Park
Comment 9 2021-11-02 22:59:56 PDT
I updated layout test result on Ubuntu 21.10 and will update layout test result on macOS 12.0.1 too in the next patchset.
Joonghun Park
Comment 10 2021-11-03 06:07:11 PDT
Joonghun Park
Comment 11 2021-11-03 06:19:48 PDT
Could you please review this patch again? I think this patch is ready for review now.
Joonghun Park
Comment 12 2021-11-04 00:39:26 PDT
Created attachment 443281 [details] Update layout test results for ios and common
Joonghun Park
Comment 13 2021-11-04 13:55:14 PDT
Hi, please review this patch when you are available. It seems that ews has passed.
Myles C. Maxfield
Comment 14 2021-11-05 17:23:47 PDT
Comment on attachment 443281 [details] Update layout test results for ios and common View in context: https://bugs.webkit.org/attachment.cgi?id=443281&action=review > Source/WebCore/css/StyleProperties.cpp:505 > +String StyleProperties::fontSynthesisPropertyValue(CSSValue& value) const > +{ > + String valueStr = value.cssText(); > + if (isCSSWideValueKeyword(valueStr) || is<CSSPrimitiveValue>(value)) > + return valueStr; > + > + if (is<CSSValueList>(value)) { > + bool hasWeight = false; > + bool hasStyle = false; > + if (downcast<CSSValueList>(value).hasValue(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight).ptr())) > + hasWeight = true; > + if (downcast<CSSValueList>(value).hasValue(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle).ptr())) > + hasStyle = true; > + return makeString(hasWeight ? "weight" : "", (hasWeight && hasStyle) ? " " : "", hasStyle ? "style" : ""); > + } > + > + return String(); > +} I think, instead of writing this function, we should change consumeFontSynthesis() in CSSPropertyParser.cpp to just canonicalize the list at parsing time. Canonicalizing at parse time would be a simpler solution, and there would not have to be another special case here - StyleProperties::getPropertyValue() would be entirely unmodified. Maybe something like this: bool foundWeight = false; bool foundStyle = false; bool foundSmallCaps = false; while (true) { auto ident = consumeIdent<CSSValueWeight, CSSValueStyle, CSSValueSmallCaps>(range); if (!ident) break; switch (ident->valueID()) { case CSSValueWeight: if (foundWeight) return nullptr; foundWeight = true; case CSSValueStyle: if (foundStyle) return nullptr; foundStyle = true; case CSSValueSmallCaps: if (foundSmallCaps) return nullptr; foundSmallCaps = true; } } RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (foundWeight) list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight)); if (foundStyle) list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle)); if (foundSmallCaps) list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); if (!list->length()) return nullptr; return list; It's probably even possible to make this more concise by using lambdas.
Joonghun Park
Comment 15 2021-11-05 20:39:37 PDT
Comment on attachment 443281 [details] Update layout test results for ios and common View in context: https://bugs.webkit.org/attachment.cgi?id=443281&action=review >> Source/WebCore/css/StyleProperties.cpp:505 >> +} > > I think, instead of writing this function, we should change consumeFontSynthesis() in CSSPropertyParser.cpp to just canonicalize the list at parsing time. Canonicalizing at parse time would be a simpler solution, and there would not have to be another special case here - StyleProperties::getPropertyValue() would be entirely unmodified. > > Maybe something like this: > > bool foundWeight = false; > bool foundStyle = false; > bool foundSmallCaps = false; > while (true) { > auto ident = consumeIdent<CSSValueWeight, CSSValueStyle, CSSValueSmallCaps>(range); > if (!ident) > break; > switch (ident->valueID()) { > case CSSValueWeight: > if (foundWeight) > return nullptr; > foundWeight = true; > case CSSValueStyle: > if (foundStyle) > return nullptr; > foundStyle = true; > case CSSValueSmallCaps: > if (foundSmallCaps) > return nullptr; > foundSmallCaps = true; > } > } > > RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); > if (foundWeight) > list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight)); > if (foundStyle) > list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle)); > if (foundSmallCaps) > list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); > > if (!list->length()) > return nullptr; > return list; > > It's probably even possible to make this more concise by using lambdas. Thank you for your review, Myles:) I applied your comment in the next patchset and will upload it soon.
Joonghun Park
Comment 16 2021-11-05 21:51:33 PDT
Created attachment 443477 [details] Canonicalize CSSValueList at parsing stage in consumeFontSynthesis
Myles C. Maxfield
Comment 17 2021-11-06 00:45:04 PDT
Comment on attachment 443477 [details] Canonicalize CSSValueList at parsing stage in consumeFontSynthesis View in context: https://bugs.webkit.org/attachment.cgi?id=443477&action=review > Source/WebCore/css/parser/CSSPropertyParser.cpp:995 > + auto makeCanonicalizedList = [](CSSParserTokenRange& range) -> RefPtr<CSSValueList> { The fact that this code is in a lambda doesn't seem to be useful. When I mentioned "lambda" I was suggesting using it as a tool to reduce (nearly-)duplicated code. If it's not possible to reduce (nearly-)duplicated code, I suggest we promote this code to no longer be within a lambda.
Joonghun Park
Comment 18 2021-11-06 04:57:58 PDT
Comment on attachment 443477 [details] Canonicalize CSSValueList at parsing stage in consumeFontSynthesis View in context: https://bugs.webkit.org/attachment.cgi?id=443477&action=review >> Source/WebCore/css/parser/CSSPropertyParser.cpp:995 >> + auto makeCanonicalizedList = [](CSSParserTokenRange& range) -> RefPtr<CSSValueList> { > > The fact that this code is in a lambda doesn't seem to be useful. When I mentioned "lambda" I was suggesting using it as a tool to reduce (nearly-)duplicated code. > > If it's not possible to reduce (nearly-)duplicated code, I suggest we promote this code to no longer be within a lambda. I added a small tiny lambda below, except that I promoted all the codes to no longer be within a lambda in the next patchset. Thank you for your review. auto checkAndMarkExistence = [](bool* found) { if (*found) return false; return *found = true; };
Joonghun Park
Comment 19 2021-11-06 05:00:30 PDT
Created attachment 443482 [details] Patch for landing
EWS
Comment 20 2021-11-06 16:07:32 PDT
Committed r285383 (243940@main): <https://commits.webkit.org/243940@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 443482 [details].
Radar WebKit Bug Importer
Comment 21 2021-11-06 16:08:17 PDT
Myles C. Maxfield
Comment 22 2021-11-06 16:18:00 PDT
Note You need to log in before you can comment on or make changes to this bug.