1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:17:35 +00:00

LibWeb: Support obsolete but required -webkit- CSS parsing quirk

As outlined in: https://www.w3.org/TR/selectors-4/#compat

We now do not treat unknown webkit pseudo-elements as invalid at parse
time, and also support serializing these elements.

Fixes: #21959
This commit is contained in:
Shannon Booth 2023-12-10 22:06:55 +13:00 committed by Alexander Kalenik
parent 83758d4cdd
commit ed97946975
9 changed files with 76 additions and 6 deletions

View file

@ -10,6 +10,7 @@
#include <AK/Debug.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/Infra/Strings.h>
namespace Web::CSS::Parser {
@ -361,6 +362,19 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
};
}
// https://www.w3.org/TR/selectors-4/#compat
// All other pseudo-elements whose names begin with the string “-webkit-” (matched ASCII case-insensitively)
// and that are not functional notations must be treated as valid at parse time. (That is, ::-webkit-asdf is
// valid at parse time, but ::-webkit-jkl() is not.) If theyre not otherwise recognized and supported, they
// must be treated as matching nothing, and are unknown -webkit- pseudo-elements.
if (pseudo_name.starts_with_bytes("-webkit-"sv, CaseSensitivity::CaseInsensitive)) {
return Selector::SimpleSelector {
.type = Selector::SimpleSelector::Type::PseudoElement,
// Unknown -webkit- pseudo-elements must be serialized in ASCII lowercase.
.value = Selector::PseudoElement { Selector::PseudoElement::Type::UnknownWebKit, MUST(Infra::to_ascii_lowercase(pseudo_name.to_string())) },
};
}
if (has_ignored_vendor_prefix(pseudo_name))
return ParseError::IncludesIgnoredVendorPrefix;

View file

@ -390,8 +390,10 @@ StringView Selector::PseudoElement::name(Selector::PseudoElement::Type pseudo_el
return "placeholder"sv;
case Selector::PseudoElement::Type::Selection:
return "selection"sv;
case Selector::PseudoElement::Type::PseudoElementCount:
case Selector::PseudoElement::Type::KnownPseudoElementCount:
break;
case Selector::PseudoElement::Type::UnknownWebKit:
VERIFY_NOT_REACHED();
}
VERIFY_NOT_REACHED();
}

View file

@ -39,15 +39,26 @@ public:
Selection,
// Keep this last.
PseudoElementCount,
KnownPseudoElementCount,
// https://www.w3.org/TR/selectors-4/#compat
// NOTE: This is not last as the 'unknown -webkit- pseudo-elements' are not stored as part of any Element.
UnknownWebKit,
};
explicit PseudoElement(Type type)
: m_type(type)
{
VERIFY(type != Type::UnknownWebKit);
}
constexpr bool operator==(PseudoElement const&) const = default;
PseudoElement(Type type, String name)
: m_type(type)
, m_name(move(name))
{
}
bool operator==(PseudoElement const&) const = default;
static Optional<PseudoElement> from_string(FlyString const&);
@ -55,6 +66,9 @@ public:
StringView name() const
{
if (!m_name.is_empty())
return m_name;
return name(m_type);
}
@ -62,6 +76,7 @@ public:
private:
Type m_type;
String m_name;
};
struct SimpleSelector {