RESOLVED FIXED 203442
calc() serialization doesn't match the spec
https://bugs.webkit.org/show_bug.cgi?id=203442
Summary calc() serialization doesn't match the spec
Simon Fraser (smfr)
Reported 2019-10-25 18:34:28 PDT
We fail a lot of calc() WPT because our serialization doesn't match the spec. There are a few problems: * we fail to simplify calc(1 + -2) to calc(1 - 2) * we don't sort the arguments * we serialize min(a, b) as calc(min(a, b)) * we serialize calc(a + b + c) as calc(a + (b + c))
Attachments
Patch (271.25 KB, patch)
2019-12-03 10:04 PST, Simon Fraser (smfr)
dino: review+
Radar WebKit Bug Importer
Comment 1 2019-10-25 18:34:41 PDT
Simon Fraser (smfr)
Comment 2 2019-11-11 08:21:26 PST
Have a mostly-working patch for this.
Simon Fraser (smfr)
Comment 3 2019-12-03 10:04:24 PST
Dean Jackson
Comment 4 2019-12-03 10:44:47 PST
Comment on attachment 384721 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=384721&action=review > Source/WebCore/css/CSSCalculationValue.cpp:556 > + double computeLengthPx(const CSSToLengthConversionData& conversionData) const final { return 1.0 / m_child->computeLengthPx(conversionData); } Could conversionData ever provide a 0? > Source/WebCore/css/CSSCalculationValue.cpp:1026 > + // If nodes contains any dimensions, remove them from nodes, sort them by their units, ordered ASCII case-insensitively, and append them to ret. This comment isn't what you're doing here though right? You're just sorting by ASCII. > Source/WebCore/css/CSSCalculationValue.cpp:1329 > Vector<double> doubleValues; > - for (auto& child : m_children) > - doubleValues.append(child->doubleValue()); > + doubleValues.reserveInitialCapacity(m_children.size()); > + bool allowNumbers = calcOperator() == CalcOperator::Multiply; > + for (auto& child : m_children) { > + CSSUnitType childType = unitType; > + if (allowNumbers && unitType != CSSUnitType::CSS_NUMBER && child->primitiveType() == CSSUnitType::CSS_NUMBER) > + childType = CSSUnitType::CSS_NUMBER; > + doubleValues.uncheckedAppend(child->doubleValue(childType)); > + } You could do evaluate(m_children.map([&] (auto& child) { ... return child->doubleValue(childType); })) and avoid the local variable + reserveInitialCapacity. > Source/WebCore/css/CSSCalculationValue.cpp:1339 > return evaluate(doubleValues); Ditto. > Source/WebCore/css/CSSCalculationValue.cpp:1873 > + return values; Another place where you could .map() > Source/WebCore/platform/CalculationValue.cpp:253 > - case CalcOperator::Min: ts << "max"; break; > - case CalcOperator::Max: ts << "min"; break; > + case CalcOperator::Min: ts << "min"; break; > + case CalcOperator::Max: ts << "max"; break; Wow.
Simon Fraser (smfr)
Comment 5 2019-12-03 18:23:26 PST
Simon Fraser (smfr)
Comment 6 2019-12-03 20:13:05 PST
Note You need to log in before you can comment on or make changes to this bug.