mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:27:35 +00:00
LibWeb: Return SelectorParsingResult from all selector parsing functions
This will allow us to know why a selector failed to parse, in situations where that matters. (Like, when a selector includes vendor prefixes...)
This commit is contained in:
parent
e30b702c6c
commit
83cd2eef8f
2 changed files with 44 additions and 46 deletions
|
@ -179,36 +179,36 @@ NonnullRefPtr<CSSStyleSheet> Parser::parse_a_stylesheet(TokenStream<T>& tokens)
|
||||||
|
|
||||||
Optional<SelectorList> Parser::parse_as_selector()
|
Optional<SelectorList> Parser::parse_as_selector()
|
||||||
{
|
{
|
||||||
return parse_a_selector(m_token_stream);
|
auto selector_list = parse_a_selector(m_token_stream);
|
||||||
|
if (!selector_list.is_error())
|
||||||
|
return selector_list.release_value();
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> Parser::parse_a_selector(TokenStream<T>& tokens)
|
Result<SelectorList, Parser::SelectorParsingResult> Parser::parse_a_selector(TokenStream<T>& tokens)
|
||||||
{
|
{
|
||||||
auto selector_list = parse_a_selector_list(tokens);
|
return parse_a_selector_list(tokens);
|
||||||
if (selector_list.has_value())
|
|
||||||
return selector_list;
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<SelectorList> Parser::parse_as_relative_selector()
|
Optional<SelectorList> Parser::parse_as_relative_selector()
|
||||||
{
|
{
|
||||||
return parse_a_relative_selector(m_token_stream);
|
auto selector_list = parse_a_relative_selector(m_token_stream);
|
||||||
}
|
if (!selector_list.is_error())
|
||||||
|
return selector_list.release_value();
|
||||||
template<typename T>
|
|
||||||
Optional<SelectorList> Parser::parse_a_relative_selector(TokenStream<T>& tokens)
|
|
||||||
{
|
|
||||||
auto selector_list = parse_a_relative_selector_list(tokens);
|
|
||||||
if (selector_list.has_value())
|
|
||||||
return selector_list;
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> Parser::parse_a_selector_list(TokenStream<T>& tokens)
|
Result<SelectorList, Parser::SelectorParsingResult> Parser::parse_a_relative_selector(TokenStream<T>& tokens)
|
||||||
|
{
|
||||||
|
return parse_a_relative_selector_list(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Result<SelectorList, Parser::SelectorParsingResult> Parser::parse_a_selector_list(TokenStream<T>& tokens)
|
||||||
{
|
{
|
||||||
auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
|
auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
|
||||||
|
|
||||||
|
@ -216,20 +216,19 @@ Optional<SelectorList> Parser::parse_a_selector_list(TokenStream<T>& tokens)
|
||||||
for (auto& selector_parts : comma_separated_lists) {
|
for (auto& selector_parts : comma_separated_lists) {
|
||||||
auto stream = TokenStream(selector_parts);
|
auto stream = TokenStream(selector_parts);
|
||||||
auto selector = parse_complex_selector(stream, false);
|
auto selector = parse_complex_selector(stream, false);
|
||||||
if (selector)
|
if (selector.is_error())
|
||||||
selectors.append(selector.release_nonnull());
|
return selector.error();
|
||||||
else
|
selectors.append(selector.release_value());
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectors.is_empty())
|
if (selectors.is_empty())
|
||||||
return {};
|
return SelectorParsingResult::SyntaxError;
|
||||||
|
|
||||||
return selectors;
|
return selectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> Parser::parse_a_relative_selector_list(TokenStream<T>& tokens)
|
Result<SelectorList, Parser::SelectorParsingResult> Parser::parse_a_relative_selector_list(TokenStream<T>& tokens)
|
||||||
{
|
{
|
||||||
auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
|
auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
|
||||||
|
|
||||||
|
@ -237,28 +236,27 @@ Optional<SelectorList> Parser::parse_a_relative_selector_list(TokenStream<T>& to
|
||||||
for (auto& selector_parts : comma_separated_lists) {
|
for (auto& selector_parts : comma_separated_lists) {
|
||||||
auto stream = TokenStream(selector_parts);
|
auto stream = TokenStream(selector_parts);
|
||||||
auto selector = parse_complex_selector(stream, true);
|
auto selector = parse_complex_selector(stream, true);
|
||||||
if (selector)
|
if (selector.is_error())
|
||||||
selectors.append(selector.release_nonnull());
|
return selector.error();
|
||||||
else
|
selectors.append(selector.release_value());
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectors.is_empty())
|
if (selectors.is_empty())
|
||||||
return {};
|
return SelectorParsingResult::SyntaxError;
|
||||||
|
|
||||||
return selectors;
|
return selectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Selector> Parser::parse_complex_selector(TokenStream<StyleComponentValueRule>& tokens, bool allow_starting_combinator)
|
Result<NonnullRefPtr<Selector>, Parser::SelectorParsingResult> Parser::parse_complex_selector(TokenStream<StyleComponentValueRule>& tokens, bool allow_starting_combinator)
|
||||||
{
|
{
|
||||||
Vector<Selector::CompoundSelector> compound_selectors;
|
Vector<Selector::CompoundSelector> compound_selectors;
|
||||||
|
|
||||||
auto first_selector = parse_compound_selector(tokens);
|
auto first_selector = parse_compound_selector(tokens);
|
||||||
if (first_selector.is_error())
|
if (first_selector.is_error())
|
||||||
return {};
|
return first_selector.error();
|
||||||
if (!allow_starting_combinator) {
|
if (!allow_starting_combinator) {
|
||||||
if (first_selector.value().combinator != Selector::Combinator::Descendant)
|
if (first_selector.value().combinator != Selector::Combinator::Descendant)
|
||||||
return {};
|
return SelectorParsingResult::SyntaxError;
|
||||||
first_selector.value().combinator = Selector::Combinator::None;
|
first_selector.value().combinator = Selector::Combinator::None;
|
||||||
}
|
}
|
||||||
compound_selectors.append(first_selector.value());
|
compound_selectors.append(first_selector.value());
|
||||||
|
@ -269,13 +267,13 @@ RefPtr<Selector> Parser::parse_complex_selector(TokenStream<StyleComponentValueR
|
||||||
if (compound_selector.error() == SelectorParsingResult::Done)
|
if (compound_selector.error() == SelectorParsingResult::Done)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
return {};
|
return compound_selector.error();
|
||||||
}
|
}
|
||||||
compound_selectors.append(compound_selector.value());
|
compound_selectors.append(compound_selector.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compound_selectors.is_empty())
|
if (compound_selectors.is_empty())
|
||||||
return {};
|
return SelectorParsingResult::SyntaxError;
|
||||||
|
|
||||||
return Selector::create(move(compound_selectors));
|
return Selector::create(move(compound_selectors));
|
||||||
}
|
}
|
||||||
|
@ -581,11 +579,11 @@ Result<Selector::SimpleSelector, Parser::SelectorParsingResult> Parser::parse_si
|
||||||
simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Not;
|
simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Not;
|
||||||
auto function_token_stream = TokenStream(pseudo_function.values());
|
auto function_token_stream = TokenStream(pseudo_function.values());
|
||||||
auto not_selector = parse_a_selector(function_token_stream);
|
auto not_selector = parse_a_selector(function_token_stream);
|
||||||
if (!not_selector.has_value()) {
|
if (not_selector.is_error()) {
|
||||||
dbgln_if(CSS_PARSER_DEBUG, "Invalid selector in :not() clause");
|
dbgln_if(CSS_PARSER_DEBUG, "Invalid selector in :not() clause");
|
||||||
return SelectorParsingResult::SyntaxError;
|
return SelectorParsingResult::SyntaxError;
|
||||||
}
|
}
|
||||||
simple_selector.pseudo_class.not_selector = not_selector.value();
|
simple_selector.pseudo_class.not_selector = not_selector.release_value();
|
||||||
} else if (pseudo_function.name().equals_ignoring_case("nth-child")) {
|
} else if (pseudo_function.name().equals_ignoring_case("nth-child")) {
|
||||||
simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::NthChild;
|
simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::NthChild;
|
||||||
auto function_values = TokenStream<StyleComponentValueRule>(pseudo_function.values());
|
auto function_values = TokenStream<StyleComponentValueRule>(pseudo_function.values());
|
||||||
|
@ -1225,7 +1223,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule)
|
||||||
} else {
|
} else {
|
||||||
auto prelude_stream = TokenStream(rule->m_prelude);
|
auto prelude_stream = TokenStream(rule->m_prelude);
|
||||||
auto selectors = parse_a_selector(prelude_stream);
|
auto selectors = parse_a_selector(prelude_stream);
|
||||||
if (!selectors.has_value() || selectors.value().is_empty()) {
|
if (selectors.is_error() || selectors.value().is_empty()) {
|
||||||
dbgln("CSSParser: style rule selectors invalid; discarding.");
|
dbgln("CSSParser: style rule selectors invalid; discarding.");
|
||||||
prelude_stream.dump_all_tokens();
|
prelude_stream.dump_all_tokens();
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -100,6 +100,11 @@ public:
|
||||||
RefPtr<StyleValue> parse_as_css_value(PropertyID);
|
RefPtr<StyleValue> parse_as_css_value(PropertyID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class SelectorParsingResult {
|
||||||
|
Done,
|
||||||
|
SyntaxError,
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NonnullRefPtr<CSSStyleSheet> parse_a_stylesheet(TokenStream<T>&);
|
NonnullRefPtr<CSSStyleSheet> parse_a_stylesheet(TokenStream<T>&);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -117,13 +122,13 @@ private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vector<Vector<StyleComponentValueRule>> parse_a_comma_separated_list_of_component_values(TokenStream<T>&);
|
Vector<Vector<StyleComponentValueRule>> parse_a_comma_separated_list_of_component_values(TokenStream<T>&);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> parse_a_selector(TokenStream<T>&);
|
Result<SelectorList, SelectorParsingResult> parse_a_selector(TokenStream<T>&);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> parse_a_relative_selector(TokenStream<T>&);
|
Result<SelectorList, SelectorParsingResult> parse_a_relative_selector(TokenStream<T>&);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> parse_a_selector_list(TokenStream<T>&);
|
Result<SelectorList, SelectorParsingResult> parse_a_selector_list(TokenStream<T>&);
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Optional<SelectorList> parse_a_relative_selector_list(TokenStream<T>&);
|
Result<SelectorList, SelectorParsingResult> parse_a_relative_selector_list(TokenStream<T>&);
|
||||||
|
|
||||||
Optional<Selector::SimpleSelector::ANPlusBPattern> parse_a_n_plus_b_pattern(TokenStream<StyleComponentValueRule>&);
|
Optional<Selector::SimpleSelector::ANPlusBPattern> parse_a_n_plus_b_pattern(TokenStream<StyleComponentValueRule>&);
|
||||||
|
|
||||||
|
@ -206,12 +211,7 @@ private:
|
||||||
static OwnPtr<CalculatedStyleValue::CalcNumberSumPartWithOperator> parse_calc_number_sum_part_with_operator(ParsingContext const&, TokenStream<StyleComponentValueRule>&);
|
static OwnPtr<CalculatedStyleValue::CalcNumberSumPartWithOperator> parse_calc_number_sum_part_with_operator(ParsingContext const&, TokenStream<StyleComponentValueRule>&);
|
||||||
static OwnPtr<CalculatedStyleValue::CalcSum> parse_calc_expression(ParsingContext const&, Vector<StyleComponentValueRule> const&);
|
static OwnPtr<CalculatedStyleValue::CalcSum> parse_calc_expression(ParsingContext const&, Vector<StyleComponentValueRule> const&);
|
||||||
|
|
||||||
enum class SelectorParsingResult {
|
Result<NonnullRefPtr<Selector>, SelectorParsingResult> parse_complex_selector(TokenStream<StyleComponentValueRule>&, bool allow_starting_combinator);
|
||||||
Done,
|
|
||||||
SyntaxError,
|
|
||||||
};
|
|
||||||
|
|
||||||
RefPtr<Selector> parse_complex_selector(TokenStream<StyleComponentValueRule>&, bool allow_starting_combinator);
|
|
||||||
Result<Selector::CompoundSelector, SelectorParsingResult> parse_compound_selector(TokenStream<StyleComponentValueRule>&);
|
Result<Selector::CompoundSelector, SelectorParsingResult> parse_compound_selector(TokenStream<StyleComponentValueRule>&);
|
||||||
Optional<Selector::Combinator> parse_selector_combinator(TokenStream<StyleComponentValueRule>&);
|
Optional<Selector::Combinator> parse_selector_combinator(TokenStream<StyleComponentValueRule>&);
|
||||||
Result<Selector::SimpleSelector, SelectorParsingResult> parse_simple_selector(TokenStream<StyleComponentValueRule>&);
|
Result<Selector::SimpleSelector, SelectorParsingResult> parse_simple_selector(TokenStream<StyleComponentValueRule>&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue