Skip to content

Commit 24393c7

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Add CSSDelimeter::OptionalWhitespace and CSSDelimeter::CommaOrWhitespaceOrSolidus (#48828)
Summary: Pull Request resolved: #48828 1. Rename `CSSComponentValueDelimeter` to `CSSDelimeter` bc the names are getting way too long. 2. Make the distinction between `Whitespace` and `OptionalWhitespace`. Note that for property values, and function blocks, the value parser will already remove trailing/leading whitespace, but it's weird that whitespace unlike others was not required to be present 3. Add `CSSDelimeter::CommaOrWhitespaceOrSolidus` for simpler parsing in the common pattern of alpha values, and move CSSColor function parsing to use that Changelog: [Internal] Reviewed By: lenaic Differential Revision: D68461968 fbshipit-source-id: 388056e47dfe6ca6003b44e82e00fe416706330b
1 parent d40f90b commit 24393c7

File tree

5 files changed

+186
-105
lines changed

5 files changed

+186
-105
lines changed

packages/react-native/ReactCommon/react/renderer/css/CSSColorFunction.h

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ constexpr std::optional<CSSColor> parseRgbFunction(CSSSyntaxParser& parser) {
5353
if (std::holds_alternative<CSSNumber>(firstValue)) {
5454
redNumber = std::get<CSSNumber>(firstValue).value;
5555

56-
auto green = parseNextCSSValue<CSSNumber>(
57-
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
56+
auto green =
57+
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::CommaOrWhitespace);
5858
if (!std::holds_alternative<CSSNumber>(green)) {
5959
return {};
6060
}
6161
greenNumber = std::get<CSSNumber>(green).value;
6262

63-
auto blue = parseNextCSSValue<CSSNumber>(
64-
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
63+
auto blue =
64+
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::CommaOrWhitespace);
6565
if (!std::holds_alternative<CSSNumber>(blue)) {
6666
return {};
6767
}
@@ -70,31 +70,22 @@ constexpr std::optional<CSSColor> parseRgbFunction(CSSSyntaxParser& parser) {
7070
redNumber = std::get<CSSPercentage>(firstValue).value * 2.55f;
7171

7272
auto green = parseNextCSSValue<CSSPercentage>(
73-
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
73+
parser, CSSDelimiter::CommaOrWhitespace);
7474
if (!std::holds_alternative<CSSPercentage>(green)) {
7575
return {};
7676
}
7777
greenNumber = std::get<CSSPercentage>(green).value * 2.55f;
7878

7979
auto blue = parseNextCSSValue<CSSPercentage>(
80-
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
80+
parser, CSSDelimiter::CommaOrWhitespace);
8181
if (!std::holds_alternative<CSSPercentage>(blue)) {
8282
return {};
8383
}
8484
blueNumber = std::get<CSSPercentage>(blue).value * 2.55f;
8585
}
8686

87-
auto alphaValue = peekNextCSSValue<CSSNumber, CSSPercentage>(
88-
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
89-
if (!std::holds_alternative<std::monostate>(alphaValue)) {
90-
parser.consumeComponentValue(CSSComponentValueDelimiter::CommaOrWhitespace);
91-
} else {
92-
alphaValue = peekNextCSSValue<CSSNumber, CSSPercentage>(
93-
parser, CSSComponentValueDelimiter::Solidus);
94-
if (!std::holds_alternative<std::monostate>(alphaValue)) {
95-
parser.consumeComponentValue(CSSComponentValueDelimiter::Solidus);
96-
}
97-
}
87+
auto alphaValue = parseNextCSSValue<CSSNumber, CSSPercentage>(
88+
parser, CSSDelimiter::CommaOrWhitespaceOrSolidus);
9889

9990
float alphaNumber = std::holds_alternative<std::monostate>(alphaValue) ? 1.0f
10091
: std::holds_alternative<CSSNumber>(alphaValue)

packages/react-native/ReactCommon/react/renderer/css/CSSRatio.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ struct CSSDataTypeParser<CSSRatio> {
3535
if (isValidRatioPart(token.numericValue())) {
3636
float numerator = token.numericValue();
3737

38-
auto denominator = peekNextCSSValue<CSSNumber>(
39-
parser, CSSComponentValueDelimiter::Solidus);
38+
auto denominator =
39+
peekNextCSSValue<CSSNumber>(parser, CSSDelimiter::Solidus);
4040
if (std::holds_alternative<CSSNumber>(denominator) &&
4141
isValidRatioPart(std::get<CSSNumber>(denominator).value)) {
42-
parser.consumeComponentValue(CSSComponentValueDelimiter::Solidus);
42+
parser.consumeComponentValue(CSSDelimiter::Solidus);
4343
return CSSRatio{numerator, std::get<CSSNumber>(denominator).value};
4444
}
4545

packages/react-native/ReactCommon/react/renderer/css/CSSSyntaxParser.h

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,13 @@ concept CSSUniqueComponentValueVisitors =
8989
/**
9090
* Describes the delimeter to expect before the next component value.
9191
*/
92-
enum class CSSComponentValueDelimiter {
93-
Comma,
92+
enum class CSSDelimiter {
9493
Whitespace,
95-
CommaOrWhitespace,
94+
OptionalWhitespace,
9695
Solidus,
96+
Comma,
97+
CommaOrWhitespace,
98+
CommaOrWhitespaceOrSolidus,
9799
None,
98100
};
99101

@@ -142,7 +144,7 @@ class CSSSyntaxParser {
142144
*/
143145
template <typename ReturnT = std::nullptr_t>
144146
constexpr ReturnT consumeComponentValue(
145-
CSSComponentValueDelimiter delimiter,
147+
CSSDelimiter delimiter,
146148
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
147149
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);
148150

@@ -172,7 +174,7 @@ class CSSSyntaxParser {
172174
*/
173175
template <typename ReturnT = std::nullptr_t>
174176
constexpr ReturnT peekComponentValue(
175-
CSSComponentValueDelimiter delimiter,
177+
CSSDelimiter delimiter,
176178
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
177179
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);
178180

@@ -229,38 +231,10 @@ struct CSSComponentValueVisitorDispatcher {
229231
CSSSyntaxParser& parser;
230232

231233
constexpr ReturnT consumeComponentValue(
232-
CSSComponentValueDelimiter delimiter,
234+
CSSDelimiter delimiter,
233235
const VisitorsT&... visitors) {
234-
switch (delimiter) {
235-
case CSSComponentValueDelimiter::Comma:
236-
parser.consumeWhitespace();
237-
if (parser.peek().type() != CSSTokenType::Comma) {
238-
return ReturnT{};
239-
}
240-
parser.consumeToken();
241-
parser.consumeWhitespace();
242-
break;
243-
case CSSComponentValueDelimiter::Whitespace:
244-
parser.consumeWhitespace();
245-
break;
246-
case CSSComponentValueDelimiter::CommaOrWhitespace:
247-
parser.consumeWhitespace();
248-
if (parser.peek().type() == CSSTokenType::Comma) {
249-
parser.consumeToken();
250-
}
251-
parser.consumeWhitespace();
252-
break;
253-
case CSSComponentValueDelimiter::Solidus:
254-
parser.consumeWhitespace();
255-
if (parser.peek().type() != CSSTokenType::Delim ||
256-
parser.peek().stringValue() != "/") {
257-
return ReturnT{};
258-
}
259-
parser.consumeToken();
260-
parser.consumeWhitespace();
261-
break;
262-
case CSSComponentValueDelimiter::None:
263-
break;
236+
if (!consumeDelimiter(delimiter)) {
237+
return {};
264238
}
265239

266240
if (parser.peek().type() == parser.terminator_) {
@@ -301,8 +275,62 @@ struct CSSComponentValueVisitorDispatcher {
301275
return ReturnT{};
302276
}
303277

278+
/**
279+
* Consume a delimiter, returning false if a required delimiter is not found.
280+
*/
281+
constexpr bool consumeDelimiter(CSSDelimiter delimiter) {
282+
if (delimiter == CSSDelimiter::None) {
283+
return true;
284+
}
285+
286+
bool hasWhiteSpace = parser.peek().type() == CSSTokenType::WhiteSpace;
287+
parser.consumeWhitespace();
288+
289+
switch (delimiter) {
290+
case CSSDelimiter::Comma:
291+
if (parser.peek().type() == CSSTokenType::Comma) {
292+
parser.consumeToken();
293+
parser.consumeWhitespace();
294+
return true;
295+
}
296+
return false;
297+
case CSSDelimiter::Whitespace:
298+
return hasWhiteSpace;
299+
case CSSDelimiter::OptionalWhitespace:
300+
return true;
301+
case CSSDelimiter::CommaOrWhitespace:
302+
if (parser.peek().type() == CSSTokenType::Comma) {
303+
parser.consumeToken();
304+
parser.consumeWhitespace();
305+
return true;
306+
}
307+
return hasWhiteSpace;
308+
case CSSDelimiter::Solidus:
309+
if (parser.peek().type() == CSSTokenType::Delim &&
310+
parser.peek().stringValue() == "/") {
311+
parser.consumeToken();
312+
parser.consumeWhitespace();
313+
return true;
314+
}
315+
return false;
316+
case CSSDelimiter::CommaOrWhitespaceOrSolidus:
317+
if (parser.peek().type() == CSSTokenType::Comma ||
318+
(parser.peek().type() == CSSTokenType::Delim &&
319+
parser.peek().stringValue() == "/")) {
320+
parser.consumeToken();
321+
parser.consumeWhitespace();
322+
return true;
323+
}
324+
return hasWhiteSpace;
325+
case CSSDelimiter::None:
326+
return true;
327+
}
328+
329+
return false;
330+
}
331+
304332
constexpr ReturnT peekComponentValue(
305-
CSSComponentValueDelimiter delimiter,
333+
CSSDelimiter delimiter,
306334
const VisitorsT&... visitors) {
307335
auto originalParser = parser;
308336
auto ret = consumeComponentValue(delimiter, visitors...);
@@ -393,7 +421,7 @@ struct CSSComponentValueVisitorDispatcher {
393421

394422
template <typename ReturnT>
395423
constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
396-
CSSComponentValueDelimiter delimiter,
424+
CSSDelimiter delimiter,
397425
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
398426
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
399427
{
@@ -407,13 +435,12 @@ constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
407435
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
408436
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
409437
{
410-
return consumeComponentValue<ReturnT>(
411-
CSSComponentValueDelimiter::None, visitors...);
438+
return consumeComponentValue<ReturnT>(CSSDelimiter::None, visitors...);
412439
}
413440

414441
template <typename ReturnT>
415442
constexpr ReturnT CSSSyntaxParser::peekComponentValue(
416-
CSSComponentValueDelimiter delimiter,
443+
CSSDelimiter delimiter,
417444
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
418445
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
419446
{
@@ -427,8 +454,7 @@ constexpr ReturnT CSSSyntaxParser::peekComponentValue(
427454
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
428455
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
429456
{
430-
return peekComponentValue<ReturnT>(
431-
CSSComponentValueDelimiter::None, visitors...);
457+
return peekComponentValue<ReturnT>(CSSDelimiter::None, visitors...);
432458
}
433459

434460
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/css/CSSValueParser.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class CSSValueParser {
3232
*/
3333
template <CSSDataType... AllowedTypesT>
3434
constexpr std::variant<std::monostate, AllowedTypesT...> consumeValue(
35-
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None) {
35+
CSSDelimiter delimeter = CSSDelimiter::None) {
3636
using ReturnT = std::variant<std::monostate, AllowedTypesT...>;
3737

3838
return parser_.consumeComponentValue<ReturnT>(
@@ -174,7 +174,7 @@ constexpr auto parseCSSProperty(std::string_view css)
174174
template <CSSDataType... AllowedTypesT>
175175
constexpr auto parseNextCSSValue(
176176
CSSSyntaxParser& syntaxParser,
177-
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None)
177+
CSSDelimiter delimeter = CSSDelimiter::None)
178178
-> std::variant<std::monostate, AllowedTypesT...> {
179179
detail::CSSValueParser valueParser(syntaxParser);
180180
return valueParser.consumeValue<AllowedTypesT...>(delimeter);
@@ -187,7 +187,7 @@ constexpr auto parseNextCSSValue(
187187
template <CSSDataType... AllowedTypesT>
188188
constexpr auto peekNextCSSValue(
189189
CSSSyntaxParser& syntaxParser,
190-
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None)
190+
CSSDelimiter delimeter = CSSDelimiter::None)
191191
-> std::variant<std::monostate, AllowedTypesT...> {
192192
auto savedParser = syntaxParser;
193193
detail::CSSValueParser valueParser(syntaxParser);

0 commit comments

Comments
 (0)