Changeset 272121 in webkit
- Timestamp:
- Jan 30, 2021, 2:33:00 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
css/MediaQueryExpression.cpp (modified) (1 diff)
-
css/parser/CSSPropertyParser.cpp (modified) (14 diffs)
-
css/parser/CSSPropertyParserHelpers.cpp (modified) (21 diffs)
-
css/parser/CSSPropertyParserHelpers.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r272118 r272121 1 2021-01-30 Sam Weinig <weinig@apple.com> 2 3 Additional cleanup of CSSPropertyParserHelpers 4 https://bugs.webkit.org/show_bug.cgi?id=221174 5 6 Reviewed by Simon Fraser. 7 8 - Added "raw" versions of consumeInteger and consumePositiveInteger. 9 - Converted consumePosition and consumeOneOrTwoValuedPosition to use 10 an Optional return value rather than out parameters, using a new 11 PositionCoordinates helper struct. 12 - Added consumeNumberOrPercentDividedBy100Raw helper for common patter 13 of supporting eiter a number, or a percentage normalized by dividing 14 it by 100. 15 16 * css/MediaQueryExpression.cpp: 17 * css/parser/CSSPropertyParser.cpp: 18 * css/parser/CSSPropertyParserHelpers.cpp: 19 * css/parser/CSSPropertyParserHelpers.h: 20 1 21 2021-01-30 Zalan Bujtas <zalan@apple.com> 2 22 -
trunk/Source/WebCore/css/MediaQueryExpression.cpp
r270823 r272121 221 221 if (!CSSPropertyParserHelpers::consumeSlashIncludingWhitespace(range)) 222 222 return; 223 RefPtr<CSSPrimitiveValue> denominatorValue = CSSPropertyParserHelpers::consumePositiveInteger(range);223 auto denominatorValue = CSSPropertyParserHelpers::consumePositiveIntegerRaw(range); 224 224 if (!denominatorValue) 225 225 return; 226 226 227 227 unsigned numerator = clampTo<unsigned>(firstValue->doubleValue()); 228 unsigned denominator = clampTo<unsigned>(denominatorValue->doubleValue()); 229 m_value = CSSAspectRatioValue::create(numerator, denominator); 228 m_value = CSSAspectRatioValue::create(numerator, *denominatorValue); 230 229 m_isValid = true; 231 230 return; -
trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp
r272094 r272121 371 371 bool CSSPropertyParser::consumeTransformOrigin(bool important) 372 372 { 373 RefPtr<CSSPrimitiveValue> resultX; 374 RefPtr<CSSPrimitiveValue> resultY; 375 if (consumeOneOrTwoValuedPosition(m_range, m_context.mode, UnitlessQuirk::Forbid, resultX, resultY)) { 373 if (auto resultXY = consumeOneOrTwoValuedPositionCoordinates(m_range, m_context.mode, UnitlessQuirk::Forbid)) { 376 374 m_range.consumeWhitespace(); 377 375 bool atEnd = m_range.atEnd(); 378 RefPtr<CSSPrimitiveValue>resultZ = consumeLength(m_range, m_context.mode, ValueRangeAll);376 auto resultZ = consumeLength(m_range, m_context.mode, ValueRangeAll); 379 377 bool hasZ = resultZ; 380 378 if (!hasZ && !atEnd) 381 379 return false; 382 addProperty(CSSPropertyTransformOriginX, CSSPropertyTransformOrigin, resultX.releaseNonNull(), important);383 addProperty(CSSPropertyTransformOriginY, CSSPropertyTransformOrigin, resultY.releaseNonNull(), important);380 addProperty(CSSPropertyTransformOriginX, CSSPropertyTransformOrigin, WTFMove(resultXY->x), important); 381 addProperty(CSSPropertyTransformOriginY, CSSPropertyTransformOrigin, WTFMove(resultXY->y), important); 384 382 addProperty(CSSPropertyTransformOriginZ, CSSPropertyTransformOrigin, resultZ ? resultZ.releaseNonNull() : CSSValuePool::singleton().createValue(0, CSSUnitType::CSS_PX), important, !hasZ); 385 383 … … 391 389 bool CSSPropertyParser::consumePerspectiveOrigin(bool important) 392 390 { 393 RefPtr<CSSPrimitiveValue> resultX; 394 RefPtr<CSSPrimitiveValue> resultY; 395 if (consumePosition(m_range, m_context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position, resultX, resultY)) { 396 addProperty(CSSPropertyPerspectiveOriginX, CSSPropertyPerspectiveOrigin, resultX.releaseNonNull(), important); 397 addProperty(CSSPropertyPerspectiveOriginY, CSSPropertyPerspectiveOrigin, resultY.releaseNonNull(), important); 391 if (auto result = consumePositionCoordinates(m_range, m_context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position)) { 392 addProperty(CSSPropertyPerspectiveOriginX, CSSPropertyPerspectiveOrigin, WTFMove(result->x), important); 393 addProperty(CSSPropertyPerspectiveOriginY, CSSPropertyPerspectiveOrigin, WTFMove(result->y), important); 398 394 return true; 399 395 } … … 475 471 if (!range.atEnd() && range.peek().type() != CommaToken) { 476 472 // Feature tag values could follow: <integer> | on | off 477 if (auto primitiveValue = consumeInteger(range, 0))478 tagValue = primitiveValue->intValue();473 if (auto integer = consumeIntegerRaw(range, 0)) 474 tagValue = *integer; 479 475 else if (range.peek().id() == CSSValueOn || range.peek().id() == CSSValueOff) 480 476 tagValue = range.consumeIncludingWhitespace().id() == CSSValueOn; … … 1149 1145 return nullptr; 1150 1146 int i = defaultValue; 1151 if ( RefPtr<CSSPrimitiveValue> counterValue = consumeInteger(range))1152 i = counterValue->intValue();1147 if (auto counterValue = consumeIntegerRaw(range)) 1148 i = *counterValue; 1153 1149 list->append(createPrimitiveValuePair(counterName.releaseNonNull(), CSSPrimitiveValue::create(i, CSSUnitType::CSS_NUMBER), Pair::IdenticalValueEncoding::Coalesce)); 1154 1150 } while (!range.atEnd()); … … 1333 1329 static RefPtr<CSSPrimitiveValue> consumeLineClamp(CSSParserTokenRange& range) 1334 1330 { 1335 RefPtr<CSSPrimitiveValue> clampValue = consumePercent(range, ValueRangeNonNegative); 1336 if (clampValue) 1331 if (auto clampValue = consumePercent(range, ValueRangeNonNegative)) 1337 1332 return clampValue; 1338 1333 // When specifying number of lines, don't allow 0 as a valid value. … … 1455 1450 CSSParserTokenRange args = consumeFunction(rangeCopy); 1456 1451 1457 RefPtr<CSSPrimitiveValue> stepsValue = consumePositiveInteger(args);1452 auto stepsValue = consumePositiveIntegerRaw(args); 1458 1453 if (!stepsValue) 1459 1454 return nullptr; … … 1494 1489 return nullptr; 1495 1490 1496 auto steps = stepsValue->intValue(); 1497 if (steps <= 1 && stepPosition == StepsTimingFunction::StepPosition::JumpNone) 1498 return nullptr; 1499 1491 if (*stepsValue == 1 && stepPosition == StepsTimingFunction::StepPosition::JumpNone) 1492 return nullptr; 1493 1500 1494 range = rangeCopy; 1501 return CSSStepsTimingFunctionValue::create( steps, stepPosition);1495 return CSSStepsTimingFunctionValue::create(*stepsValue, stepPosition); 1502 1496 } 1503 1497 … … 2606 2600 shape->setRadius(radius.releaseNonNull()); 2607 2601 if (consumeIdent<CSSValueAt>(args)) { 2608 RefPtr<CSSPrimitiveValue> centerX; 2609 RefPtr<CSSPrimitiveValue> centerY; 2610 if (!consumePosition(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position, centerX, centerY)) 2611 return nullptr; 2612 shape->setCenterX(centerX.releaseNonNull()); 2613 shape->setCenterY(centerY.releaseNonNull()); 2602 auto centerCoordinates = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position); 2603 if (!centerCoordinates) 2604 return nullptr; 2605 shape->setCenterX(WTFMove(centerCoordinates->x)); 2606 shape->setCenterY(WTFMove(centerCoordinates->y)); 2614 2607 } 2615 2608 return shape; … … 2629 2622 } 2630 2623 if (consumeIdent<CSSValueAt>(args)) { 2631 RefPtr<CSSPrimitiveValue> centerX; 2632 RefPtr<CSSPrimitiveValue> centerY; 2633 if (!consumePosition(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position, centerX, centerY)) 2634 return nullptr; 2635 shape->setCenterX(centerX.releaseNonNull()); 2636 shape->setCenterY(centerY.releaseNonNull()); 2624 auto centerCoordinates = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position); 2625 if (!centerCoordinates) 2626 return nullptr; 2627 shape->setCenterX(WTFMove(centerCoordinates->x)); 2628 shape->setCenterY(WTFMove(centerCoordinates->y)); 2637 2629 } 2638 2630 return shape; … … 3603 3595 repeatedValues = CSSGridAutoRepeatValue::create(args.consumeIncludingWhitespace().id()); 3604 3596 else { 3605 // FIXME: a consumeIntegerRaw would be more efficient here. 3606 RefPtr<CSSPrimitiveValue> repetition = consumePositiveInteger(args); 3597 auto repetition = consumePositiveIntegerRaw(args); 3607 3598 if (!repetition) 3608 3599 return false; 3609 repetitions = clampTo<size_t>( repetition->doubleValue(), 0, GridPosition::max());3600 repetitions = clampTo<size_t>(static_cast<size_t>(*repetition), 0, GridPosition::max()); 3610 3601 repeatedValues = CSSValueList::createSpaceSeparated(); 3611 3602 } … … 4364 4355 case CSSPropertyFloodOpacity: 4365 4356 case CSSPropertyOpacity: 4366 { 4367 RefPtr<CSSValue> parsedValue = consumeNumber(m_range, ValueRangeAll); 4368 if (parsedValue) 4357 if (auto parsedValue = consumeNumber(m_range, ValueRangeAll)) 4369 4358 return parsedValue; 4370 4359 return consumePercent(m_range, ValueRangeAll); 4371 }4372 4360 case CSSPropertyWebkitBoxFlex: 4373 4361 return consumeNumber(m_range, ValueRangeAll); … … 5036 5024 unsigned index = 0; 5037 5025 while (!m_range.atEnd() && index++ < 3) { 5038 if (auto num = consumeNumberRaw(m_range)) {5039 if (*num < 0)5026 if (auto number = consumeNumberRaw(m_range)) { 5027 if (*number < 0) 5040 5028 return false; 5041 5029 if (flexGrow == unsetValue) 5042 flexGrow = *num ;5030 flexGrow = *number; 5043 5031 else if (flexShrink == unsetValue) 5044 flexShrink = *num ;5045 else if (!*num ) // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.5032 flexShrink = *number; 5033 else if (!*number) // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set. 5046 5034 flexBasis = CSSPrimitiveValue::create(0, CSSUnitType::CSS_PX); 5047 5035 else … … 5284 5272 { 5285 5273 do { 5286 RefPtr<CSSPrimitiveValue> positionX; 5287 RefPtr<CSSPrimitiveValue> positionY; 5288 if (!consumePosition(range, context.mode, unitless, PositionSyntax::BackgroundPosition, positionX, positionY)) 5274 auto position = consumePositionCoordinates(range, context.mode, unitless, PositionSyntax::BackgroundPosition); 5275 if (!position) 5289 5276 return false; 5290 addBackgroundValue(resultX, positionX.releaseNonNull());5291 addBackgroundValue(resultY, positionY.releaseNonNull());5277 addBackgroundValue(resultX, WTFMove(position->x)); 5278 addBackgroundValue(resultY, WTFMove(position->y)); 5292 5279 } while (consumeCommaIncludingWhitespace(range)); 5293 5280 return true; … … 5362 5349 } else if (property == CSSPropertyBackgroundPositionX || property == CSSPropertyWebkitMaskPositionX) { 5363 5350 CSSParserTokenRange rangeCopy = m_range; 5364 RefPtr<CSSPrimitiveValue> primitiveValue; 5365 RefPtr<CSSPrimitiveValue> primitiveValueY; 5366 if (!consumePosition(rangeCopy, m_context.mode, UnitlessQuirk::Forbid, PositionSyntax::BackgroundPosition, primitiveValue, primitiveValueY)) 5351 auto position = consumePositionCoordinates(rangeCopy, m_context.mode, UnitlessQuirk::Forbid, PositionSyntax::BackgroundPosition); 5352 if (!position) 5367 5353 continue; 5368 value = primitiveValue;5369 valueY = primitiveValueY;5354 value = WTFMove(position->x); 5355 valueY = WTFMove(position->y); 5370 5356 m_range = rangeCopy; 5371 5357 } else if (property == CSSPropertyBackgroundSize || property == CSSPropertyWebkitMaskSize) { -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r272094 r272121 84 84 } 85 85 86 static Optional<double> consumeNumberOrPercentDividedBy100Raw(CSSParserTokenRange& range, ValueRange valueRange = ValueRangeAll) 87 { 88 if (auto percent = consumePercentRaw(range, valueRange)) 89 return *percent / 100.0; 90 if (auto number = consumeNumberRaw(range, valueRange)) 91 return *number; 92 return WTF::nullopt; 93 } 94 86 95 // FIXME: consider pulling in the parsing logic from CSSCalculationValue.cpp. 87 96 class CalcParser { … … 112 121 return nullptr; 113 122 m_sourceRange = m_range; 114 double value = std::max(m_calcValue->doubleValue(), minimumValue); 115 value = std::round(value); 116 return CSSValuePool::singleton().createValue(value, CSSUnitType::CSS_NUMBER); 123 return CSSValuePool::singleton().createValue(std::round(std::max(m_calcValue->doubleValue(), minimumValue)), CSSUnitType::CSS_NUMBER); 124 } 125 126 template<typename IntType> Optional<IntType> consumeIntegerTypeRaw(double minimumValue) 127 { 128 if (!m_calcValue) 129 return WTF::nullopt; 130 m_sourceRange = m_range; 131 return clampTo<IntType>(std::round(std::max(m_calcValue->doubleValue(), minimumValue))); 117 132 } 118 133 … … 185 200 }; 186 201 187 RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange& range, double minimumValue)202 template<typename IntType> Optional<IntType> consumeIntegerTypeRaw(CSSParserTokenRange& range, double minimumValue) 188 203 { 189 204 const CSSParserToken& token = range.peek(); 190 205 if (token.type() == NumberToken) { 191 206 if (token.numericValueType() == NumberValueType || token.numericValue() < minimumValue) 192 return nullptr;193 return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_NUMBER);207 return WTF::nullopt; 208 return clampTo<IntType>(range.consumeIncludingWhitespace().numericValue()); 194 209 } 195 210 196 211 if (token.type() != FunctionToken) 197 return nullptr;212 return WTF::nullopt; 198 213 199 214 CalcParser calcParser(range, CalculationCategory::Number); 200 215 if (const CSSCalcValue* calculation = calcParser.value()) { 201 216 if (calculation->category() != CalculationCategory::Number) 202 return nullptr; 203 return calcParser.consumeInteger(minimumValue); 204 } 205 217 return WTF::nullopt; 218 return calcParser.consumeIntegerTypeRaw<IntType>(minimumValue); 219 } 220 221 return WTF::nullopt; 222 } 223 224 Optional<int> consumeIntegerRaw(CSSParserTokenRange& range, double minimumValue) 225 { 226 return consumeIntegerTypeRaw<int>(range, minimumValue); 227 } 228 229 RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange& range, double minimumValue) 230 { 231 if (auto integer = consumeIntegerRaw(range, minimumValue)) 232 return CSSValuePool::singleton().createValue(*integer, CSSUnitType::CSS_NUMBER); 206 233 return nullptr; 207 234 } 208 235 236 Optional<unsigned> consumePositiveIntegerRaw(CSSParserTokenRange& range) 237 { 238 return consumeIntegerTypeRaw<unsigned>(range, 1); 239 } 240 209 241 RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange& range) 210 242 { 211 return consumeInteger(range, 1); 243 if (auto integer = consumePositiveIntegerRaw(range)) 244 return CSSValuePool::singleton().createValue(*integer, CSSUnitType::CSS_NUMBER); 245 return nullptr; 212 246 } 213 247 … … 724 758 uint8_t alphaComponent = 255; 725 759 if (consumeAlphaSeparator()) { 726 if (auto number = consumeNumberRaw(args)) 727 alphaComponent = convertFloatAlphaTo<uint8_t>(*number); 728 else if (auto percent = consumePercentRaw(args)) 729 alphaComponent = convertFloatAlphaTo<uint8_t>(*percent / 100.0); 730 else 760 auto alpha = consumeNumberOrPercentDividedBy100Raw(args); 761 if (!alpha) 731 762 return { }; 732 }; 763 alphaComponent = convertFloatAlphaTo<uint8_t>(*alpha); 764 } 733 765 734 766 if (!args.atEnd()) … … 775 807 double alpha = 1.0; 776 808 if (commaConsumed || slashConsumed) { 777 if (auto number = consumeNumberRaw(args)) 778 alpha = clampTo<double>(*number, 0.0, 1.0); 779 else if (auto percent = consumePercentRaw(args)) 780 alpha = clampTo<double>(*percent / 100.0f, 0.0, 1.0); 781 else 809 auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(args); 810 if (!alphaParameter) 782 811 return { }; 812 alpha = clampTo<double>(*alphaParameter, 0.0, 1.0); 783 813 } 784 814 … … 794 824 return 1.0f; 795 825 796 if (auto alphaParameter = consumePercentRaw(range, ValueRangeAll)) 797 return clampTo<float>(*alphaParameter / 100.0, 0.0, 1.0); 798 799 if (auto alphaParameter = consumeNumberRaw(range, ValueRangeAll)) 826 if (auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(range)) 800 827 return clampTo<float>(*alphaParameter, 0.0, 1.0); 801 828 … … 873 900 double channels[3] = { 0, 0, 0 }; 874 901 for (int i = 0; i < 3; ++i) { 875 if (auto number = consumeNumberRaw(args)) 876 channels[i] = *number; 877 else if (auto percent = consumePercentRaw(args)) 878 channels[i] = *percent / 100.0; 879 else 902 auto value = consumeNumberOrPercentDividedBy100Raw(args); 903 if (!value) 880 904 break; 905 channels[i] = *value; 881 906 } 882 907 … … 1082 1107 } 1083 1108 1084 static void positionFromOneValue(CSSPrimitiveValue& value, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY)1109 static PositionCoordinates positionFromOneValue(CSSPrimitiveValue& value) 1085 1110 { 1086 1111 bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(value); 1087 resultX = &value;1088 resultY = CSSPrimitiveValue::createIdentifier(CSSValueCenter);1089 1112 if (valueAppliesToYAxisOnly) 1090 std::swap(resultX, resultY); 1091 } 1092 1093 static bool positionFromTwoValues(CSSPrimitiveValue& value1, CSSPrimitiveValue& value2, 1094 RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY) 1095 { 1096 bool mustOrderAsXY = isHorizontalPositionKeywordOnly(value1) || isVerticalPositionKeywordOnly(value2) 1097 || !value1.isValueID() || !value2.isValueID(); 1113 return { CSSPrimitiveValue::createIdentifier(CSSValueCenter), value }; 1114 return { value, CSSPrimitiveValue::createIdentifier(CSSValueCenter) }; 1115 } 1116 1117 static Optional<PositionCoordinates> positionFromTwoValues(CSSPrimitiveValue& value1, CSSPrimitiveValue& value2) 1118 { 1119 bool mustOrderAsXY = isHorizontalPositionKeywordOnly(value1) || isVerticalPositionKeywordOnly(value2) || !value1.isValueID() || !value2.isValueID(); 1098 1120 bool mustOrderAsYX = isVerticalPositionKeywordOnly(value1) || isHorizontalPositionKeywordOnly(value2); 1099 1121 if (mustOrderAsXY && mustOrderAsYX) 1100 return false; 1101 resultX = &value1; 1102 resultY = &value2; 1122 return WTF::nullopt; 1103 1123 if (mustOrderAsYX) 1104 std::swap(resultX, resultY);1105 return true;1124 return PositionCoordinates { value2, value1 }; 1125 return PositionCoordinates { value1, value2 }; 1106 1126 } 1107 1127 … … 1124 1144 // [ center | [ top | bottom ] <length-percentage>? ] 1125 1145 // 1126 static bool backgroundPositionFromThreeValues(const std::array<CSSPrimitiveValue*, 5>& values, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY) 1127 { 1146 static Optional<PositionCoordinates> backgroundPositionFromThreeValues(const std::array<CSSPrimitiveValue*, 5>& values) 1147 { 1148 RefPtr<CSSPrimitiveValue> resultX; 1149 RefPtr<CSSPrimitiveValue> resultY; 1150 1128 1151 CSSPrimitiveValue* center = nullptr; 1129 1152 for (int i = 0; values[i]; i++) { 1130 1153 CSSPrimitiveValue* currentValue = values[i]; 1131 1154 if (!currentValue->isValueID()) 1132 return false;1155 return WTF::nullopt; 1133 1156 1134 1157 CSSValueID id = currentValue->valueID(); 1135 1158 if (id == CSSValueCenter) { 1136 1159 if (center) 1137 return false;1160 return WTF::nullopt; 1138 1161 center = currentValue; 1139 1162 continue; … … 1148 1171 if (id == CSSValueLeft || id == CSSValueRight) { 1149 1172 if (resultX) 1150 return false;1173 return WTF::nullopt; 1151 1174 resultX = result; 1152 1175 } else { 1153 1176 ASSERT(id == CSSValueTop || id == CSSValueBottom); 1154 1177 if (resultY) 1155 return false;1178 return WTF::nullopt; 1156 1179 resultY = result; 1157 1180 } … … 1161 1184 ASSERT(resultX || resultY); 1162 1185 if (resultX && resultY) 1163 return false;1186 return WTF::nullopt; 1164 1187 if (!resultX) 1165 1188 resultX = center; … … 1169 1192 1170 1193 ASSERT(resultX && resultY); 1171 return true;1194 return PositionCoordinates { resultX.releaseNonNull(), resultY.releaseNonNull() }; 1172 1195 } 1173 1196 … … 1182 1205 // [ [ top | bottom ] <length-percentage> ] 1183 1206 // 1184 static bool positionFromFourValues(const std::array<CSSPrimitiveValue*, 5>& values, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY) 1185 { 1207 static Optional<PositionCoordinates> positionFromFourValues(const std::array<CSSPrimitiveValue*, 5>& values) 1208 { 1209 RefPtr<CSSPrimitiveValue> resultX; 1210 RefPtr<CSSPrimitiveValue> resultY; 1211 1186 1212 for (int i = 0; values[i]; i++) { 1187 1213 CSSPrimitiveValue* currentValue = values[i]; 1188 1214 if (!currentValue->isValueID()) 1189 return false;1215 return WTF::nullopt; 1190 1216 1191 1217 CSSValueID id = currentValue->valueID(); 1192 1218 if (id == CSSValueCenter) 1193 return false;1219 return WTF::nullopt; 1194 1220 1195 1221 RefPtr<CSSPrimitiveValue> result; … … 1201 1227 if (id == CSSValueLeft || id == CSSValueRight) { 1202 1228 if (resultX) 1203 return false;1229 return WTF::nullopt; 1204 1230 resultX = result; 1205 1231 } else { 1206 1232 ASSERT(id == CSSValueTop || id == CSSValueBottom); 1207 1233 if (resultY) 1208 return false;1234 return WTF::nullopt; 1209 1235 resultY = result; 1210 1236 } … … 1212 1238 1213 1239 ASSERT(resultX && resultY); 1214 return true;1240 return PositionCoordinates { resultX.releaseNonNull(), resultY.releaseNonNull() }; 1215 1241 } 1216 1242 1217 1243 // FIXME: This may consume from the range upon failure. The background 1218 1244 // shorthand works around it, but we should just fix it here. 1219 bool consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY)1220 { 1221 RefPtr<CSSPrimitiveValue>value1 = consumePositionComponent(range, cssParserMode, unitless);1245 Optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax) 1246 { 1247 auto value1 = consumePositionComponent(range, cssParserMode, unitless); 1222 1248 if (!value1) 1223 return false; 1224 1225 RefPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParserMode, unitless); 1226 if (!value2) { 1227 positionFromOneValue(*value1, resultX, resultY); 1228 return true; 1229 } 1230 1231 RefPtr<CSSPrimitiveValue> value3 = consumePositionComponent(range, cssParserMode, unitless); 1249 return WTF::nullopt; 1250 1251 auto value2 = consumePositionComponent(range, cssParserMode, unitless); 1252 if (!value2) 1253 return positionFromOneValue(*value1); 1254 1255 auto value3 = consumePositionComponent(range, cssParserMode, unitless); 1232 1256 if (!value3) 1233 return positionFromTwoValues(*value1, *value2 , resultX, resultY);1234 1235 RefPtr<CSSPrimitiveValue>value4 = consumePositionComponent(range, cssParserMode, unitless);1257 return positionFromTwoValues(*value1, *value2); 1258 1259 auto value4 = consumePositionComponent(range, cssParserMode, unitless); 1236 1260 1237 std::array<CSSPrimitiveValue*, 5> values; 1238 values[0] = value1.get(); 1239 values[1] = value2.get(); 1240 values[2] = value3.get(); 1241 values[3] = value4.get(); 1242 values[4] = nullptr; 1261 std::array<CSSPrimitiveValue*, 5> values { 1262 value1.get(), 1263 value2.get(), 1264 value3.get(), 1265 value4.get(), 1266 nullptr 1267 }; 1243 1268 1244 1269 if (value4) 1245 return positionFromFourValues(values , resultX, resultY);1270 return positionFromFourValues(values); 1246 1271 1247 1272 if (positionSyntax != PositionSyntax::BackgroundPosition) 1248 return false;1273 return WTF::nullopt; 1249 1274 1250 return backgroundPositionFromThreeValues(values , resultX, resultY);1275 return backgroundPositionFromThreeValues(values); 1251 1276 } 1252 1277 1253 1278 RefPtr<CSSPrimitiveValue> consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax) 1254 1279 { 1255 RefPtr<CSSPrimitiveValue> resultX; 1256 RefPtr<CSSPrimitiveValue> resultY; 1257 if (consumePosition(range, cssParserMode, unitless, positionSyntax, resultX, resultY)) 1258 return CSSPropertyParserHelpersInternal::createPrimitiveValuePair(resultX.releaseNonNull(), resultY.releaseNonNull()); 1280 if (auto coordinates = consumePositionCoordinates(range, cssParserMode, unitless, positionSyntax)) 1281 return CSSPropertyParserHelpersInternal::createPrimitiveValuePair(WTFMove(coordinates->x), WTFMove(coordinates->y)); 1259 1282 return nullptr; 1260 1283 } 1261 1284 1262 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY)1263 { 1264 RefPtr<CSSPrimitiveValue>value1 = consumePositionComponent(range, cssParserMode, unitless);1285 Optional<PositionCoordinates> consumeOneOrTwoValuedPositionCoordinates(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) 1286 { 1287 auto value1 = consumePositionComponent(range, cssParserMode, unitless); 1265 1288 if (!value1) 1266 return false; 1267 RefPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParserMode, unitless); 1268 if (!value2) { 1269 positionFromOneValue(*value1, resultX, resultY); 1270 return true; 1271 } 1272 return positionFromTwoValues(*value1, *value2, resultX, resultY); 1289 return WTF::nullopt; 1290 auto value2 = consumePositionComponent(range, cssParserMode, unitless); 1291 if (!value2) 1292 return positionFromOneValue(*value1); 1293 return positionFromTwoValues(*value1, *value2); 1273 1294 } 1274 1295 … … 1311 1332 } else { 1312 1333 ASSERT(id == CSSValueColorStop); 1313 if (auto percent = consumePercentRaw(args, ValueRangeAll)) 1314 position = *percent / 100.0; 1315 else if (auto number = consumeNumberRaw(args)) 1316 position = *number; 1317 else 1334 auto value = consumeNumberOrPercentDividedBy100Raw(args); 1335 if (!value) 1318 1336 return false; 1337 position = *value; 1319 1338 1320 1339 if (!consumeCommaIncludingWhitespace(args)) … … 1437 1456 auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient); 1438 1457 1439 RefPtr<CSSPrimitiveValue> centerX; 1440 RefPtr<CSSPrimitiveValue> centerY; 1441 consumeOneOrTwoValuedPosition(args, cssParserMode, UnitlessQuirk::Forbid, centerX, centerY); 1442 if ((centerX || centerY) && !consumeCommaIncludingWhitespace(args)) 1458 auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, cssParserMode, UnitlessQuirk::Forbid); 1459 if (centerCoordinate && !consumeCommaIncludingWhitespace(args)) 1443 1460 return nullptr; 1444 1461 … … 1467 1484 return nullptr; 1468 1485 1469 result->setFirstX(centerX.copyRef()); 1470 result->setFirstY(centerY.copyRef()); 1471 result->setSecondX(WTFMove(centerX)); 1472 result->setSecondY(WTFMove(centerY)); 1486 if (centerCoordinate) { 1487 result->setFirstX(centerCoordinate->x.copyRef()); 1488 result->setFirstY(centerCoordinate->y.copyRef()); 1489 result->setSecondX(WTFMove(centerCoordinate->x)); 1490 result->setSecondY(WTFMove(centerCoordinate->y)); 1491 } 1473 1492 result->setShape(WTFMove(shape)); 1474 1493 result->setSizingBehavior(WTFMove(sizeKeyword)); … … 1539 1558 if (args.peek().id() == CSSValueAt) { 1540 1559 args.consumeIncludingWhitespace(); 1541 consumePosition(args, cssParserMode, UnitlessQuirk::Forbid, PositionSyntax::Position, centerX, centerY); 1542 if (!(centerX && centerY)) 1560 1561 auto centerCoordinate = consumePositionCoordinates(args, cssParserMode, UnitlessQuirk::Forbid, PositionSyntax::Position); 1562 if (!centerCoordinate) 1543 1563 return nullptr; 1564 1565 centerX = WTFMove(centerCoordinate->x); 1566 centerY = WTFMove(centerCoordinate->y); 1544 1567 1545 1568 result->setFirstX(centerX.copyRef()); … … 1614 1637 1615 1638 if (consumeIdent<CSSValueAt>(args)) { 1616 RefPtr<CSSPrimitiveValue> centerX; 1617 RefPtr<CSSPrimitiveValue> centerY; 1618 consumePosition(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position, centerX, centerY); 1619 if (!(centerX && centerY)) 1639 auto centerCoordinate = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position); 1640 if (!centerCoordinate) 1620 1641 return nullptr; 1621 1642 1622 result->setFirstX(center X.copyRef());1623 result->setFirstY(center Y.copyRef());1643 result->setFirstX(centerCoordinate->x.copyRef()); 1644 result->setFirstY(centerCoordinate->y.copyRef()); 1624 1645 1625 1646 // Right now, conic gradients have the same start and end centers. 1626 result->setSecondX(WTFMove(center X));1627 result->setSecondY(WTFMove(center Y));1647 result->setSecondX(WTFMove(centerCoordinate->x)); 1648 result->setSecondY(WTFMove(centerCoordinate->y)); 1628 1649 1629 1650 expectComma = true; … … 1653 1674 static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, CSSParserContext context, bool prefixed) 1654 1675 { 1655 RefPtr<CSSValue>fromImageValue = consumeImageOrNone(args, context);1676 auto fromImageValue = consumeImageOrNone(args, context); 1656 1677 if (!fromImageValue || !consumeCommaIncludingWhitespace(args)) 1657 1678 return nullptr; 1658 RefPtr<CSSValue>toImageValue = consumeImageOrNone(args, context);1679 auto toImageValue = consumeImageOrNone(args, context); 1659 1680 if (!toImageValue || !consumeCommaIncludingWhitespace(args)) 1660 1681 return nullptr; 1661 1682 1662 RefPtr<CSSPrimitiveValue> percentage; 1663 if (auto percentValue = consumePercent(args, ValueRangeAll)) 1664 percentage = CSSValuePool::singleton().createValue(clampTo<double>(percentValue->doubleValue() / 100.0, 0, 1), CSSUnitType::CSS_NUMBER); 1665 else if (auto numberValue = consumeNumber(args, ValueRangeAll)) 1666 percentage = CSSValuePool::singleton().createValue(clampTo<double>(numberValue->doubleValue(), 0, 1), CSSUnitType::CSS_NUMBER); 1667 1683 auto percentage = consumeNumberOrPercentDividedBy100Raw(args); 1668 1684 if (!percentage) 1669 1685 return nullptr; 1670 return CSSCrossfadeValue::create(fromImageValue.releaseNonNull(), toImageValue.releaseNonNull(), percentage.releaseNonNull(), prefixed); 1686 auto percentageValue = CSSValuePool::singleton().createValue(clampTo<double>(*percentage, 0, 1), CSSUnitType::CSS_NUMBER); 1687 return CSSCrossfadeValue::create(fromImageValue.releaseNonNull(), toImageValue.releaseNonNull(), WTFMove(percentageValue), prefixed); 1671 1688 } 1672 1689 -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h
r272094 r272121 71 71 using LengthOrPercentRaw = Variant<LengthRaw, double>; 72 72 73 Optional<int> consumeIntegerRaw(CSSParserTokenRange&, double minimumValue = -std::numeric_limits<double>::max()); 73 74 RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange&, double minimumValue = -std::numeric_limits<double>::max()); 75 Optional<unsigned> consumePositiveIntegerRaw(CSSParserTokenRange&); 74 76 RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange&); 75 77 Optional<double> consumeNumberRaw(CSSParserTokenRange&, ValueRange = ValueRangeAll); … … 109 111 }; 110 112 113 struct PositionCoordinates { 114 Ref<CSSPrimitiveValue> x; 115 Ref<CSSPrimitiveValue> y; 116 }; 117 111 118 RefPtr<CSSPrimitiveValue> consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax); 112 bool consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY);113 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, RefPtr<CSSPrimitiveValue>& resultX, RefPtr<CSSPrimitiveValue>& resultY);119 Optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax); 120 Optional<PositionCoordinates> consumeOneOrTwoValuedPositionCoordinates(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk); 114 121 115 122 enum class AllowedImageType : uint8_t {
Note:
See TracChangeset
for help on using the changeset viewer.