-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CSS function component values (#44470)
Summary: Pull Request resolved: #44470 CSS component values, as defined in the syntax spec, are either "preserved tokens", CSS functions, or simple blocks. This is distinct from the higher-level "component value type" specified in the [values and units](https://www.w3.org/TR/css-values-3/#component-types) spec. I was previously short-circuiting a bit, from preserved tokens, to a higher level data structure. This separates them out, adding a layer exposing the preserved token as `CSSSyntaxParser::Token`, and now a `CSSSyntaxParser::Function`, which can represent a named function and its nested component values. This does not yet wire functions beyond CSSParser returned component values. Changelog: [Internal] Reviewed By: rshest Differential Revision: D57089275 fbshipit-source-id: 97eeb1a7b3363c79d99f9419ba6e022c4c3c31d0
- Loading branch information
1 parent
3f17c8b
commit a37111a
Showing
7 changed files
with
576 additions
and
327 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
227 changes: 0 additions & 227 deletions
227
packages/react-native/ReactCommon/react/renderer/css/CSSParser.h
This file was deleted.
Oops, something went wrong.
105 changes: 105 additions & 0 deletions
105
packages/react-native/ReactCommon/react/renderer/css/CSSSyntaxParser.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <optional> | ||
#include <variant> | ||
#include <vector> | ||
|
||
#include <react/renderer/css/CSSTokenizer.h> | ||
|
||
namespace facebook::react { | ||
|
||
/** | ||
* CSSSyntaxParser allows parsing streams of CSS text into "component values", | ||
* being either a preserved token, or a function. | ||
* | ||
* https://www.w3.org/TR/css-syntax-3/#component-value | ||
*/ | ||
class CSSSyntaxParser { | ||
public: | ||
struct Function; | ||
|
||
using PreservedToken = CSSToken; | ||
using ComponentValue = std::variant<std::monostate, PreservedToken, Function>; | ||
|
||
struct Function { | ||
std::string_view name{}; | ||
std::vector<ComponentValue> args{}; | ||
}; | ||
|
||
/** | ||
* Construct the parser over the given string_view, which must stay alive for | ||
* the duration of the CSSSyntaxParser. | ||
*/ | ||
explicit constexpr CSSSyntaxParser(std::string_view css) | ||
: tokenizer_{css}, currentToken_(tokenizer_.next()) {} | ||
|
||
/** | ||
* Directly consume the next component value | ||
* | ||
* https://www.w3.org/TR/css-syntax-3/#consume-component-value | ||
*/ | ||
inline ComponentValue consumeComponentValue() { | ||
if (peek().type() == CSSTokenType::Function) { | ||
auto function = consumeFunction(); | ||
return function.has_value() ? ComponentValue{std::move(*function)} | ||
: ComponentValue{}; | ||
} else { | ||
return consumeToken(); | ||
} | ||
} | ||
|
||
private: | ||
constexpr const CSSToken& peek() const { | ||
return currentToken_; | ||
} | ||
|
||
constexpr CSSToken consumeToken() { | ||
auto prevToken = currentToken_; | ||
currentToken_ = tokenizer_.next(); | ||
return prevToken; | ||
} | ||
|
||
inline std::optional<Function> consumeFunction() { | ||
// https://www.w3.org/TR/css-syntax-3/#consume-a-function | ||
Function function{.name = consumeToken().stringValue()}; | ||
|
||
while (true) { | ||
auto nextValue = consumeComponentValue(); | ||
if (std::holds_alternative<std::monostate>(nextValue)) { | ||
return {}; | ||
} | ||
|
||
if (auto token = std::get_if<CSSToken>(&nextValue)) { | ||
if (token->type() == CSSTokenType::CloseParen) { | ||
return function; | ||
} | ||
if (token->type() == CSSTokenType::EndOfFile) { | ||
return {}; | ||
} | ||
function.args.emplace_back(std::move(*token)); | ||
continue; | ||
} | ||
|
||
if (auto func = std::get_if<Function>(&nextValue)) { | ||
function.args.emplace_back(std::move(*func)); | ||
continue; | ||
} | ||
|
||
return {}; | ||
} | ||
|
||
return function; | ||
} | ||
|
||
CSSTokenizer tokenizer_; | ||
CSSToken currentToken_; | ||
}; | ||
|
||
} // namespace facebook::react |
Oops, something went wrong.