mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:07: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:
parent
83758d4cdd
commit
ed97946975
9 changed files with 76 additions and 6 deletions
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<link rel="match" href="reference/text-div.html" />
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.d-none,
|
||||||
|
.oops::-webkit-jkl() {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="d-none">Well, hello friends!</div>
|
12
Tests/LibWeb/Ref/css-unknown-webkit-pseudo-element.html
Normal file
12
Tests/LibWeb/Ref/css-unknown-webkit-pseudo-element.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<link rel="match" href="reference/text-div.html" />
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.d-none,
|
||||||
|
.oops::-webkit-asdf {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="d-none">Well, hello friends!</div>
|
|
@ -0,0 +1 @@
|
||||||
|
.d-none, .oops::-webkit-asdf
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html><style type="text/css">
|
||||||
|
.d-none,
|
||||||
|
.oops::-webkit-asDF {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style><div class="d-none">should not be displayed</div>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
let rules = document.styleSheets[0].cssRules;
|
||||||
|
let rule = rules.item(0);
|
||||||
|
println(rule.selectorText);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
|
#include <LibWeb/Infra/Strings.h>
|
||||||
|
|
||||||
namespace Web::CSS::Parser {
|
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 they’re 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))
|
if (has_ignored_vendor_prefix(pseudo_name))
|
||||||
return ParseError::IncludesIgnoredVendorPrefix;
|
return ParseError::IncludesIgnoredVendorPrefix;
|
||||||
|
|
||||||
|
|
|
@ -390,8 +390,10 @@ StringView Selector::PseudoElement::name(Selector::PseudoElement::Type pseudo_el
|
||||||
return "placeholder"sv;
|
return "placeholder"sv;
|
||||||
case Selector::PseudoElement::Type::Selection:
|
case Selector::PseudoElement::Type::Selection:
|
||||||
return "selection"sv;
|
return "selection"sv;
|
||||||
case Selector::PseudoElement::Type::PseudoElementCount:
|
case Selector::PseudoElement::Type::KnownPseudoElementCount:
|
||||||
break;
|
break;
|
||||||
|
case Selector::PseudoElement::Type::UnknownWebKit:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,26 @@ public:
|
||||||
Selection,
|
Selection,
|
||||||
|
|
||||||
// Keep this last.
|
// 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)
|
explicit PseudoElement(Type type)
|
||||||
: m_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&);
|
static Optional<PseudoElement> from_string(FlyString const&);
|
||||||
|
|
||||||
|
@ -55,6 +66,9 @@ public:
|
||||||
|
|
||||||
StringView name() const
|
StringView name() const
|
||||||
{
|
{
|
||||||
|
if (!m_name.is_empty())
|
||||||
|
return m_name;
|
||||||
|
|
||||||
return name(m_type);
|
return name(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +76,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
|
String m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SimpleSelector {
|
struct SimpleSelector {
|
||||||
|
|
|
@ -410,7 +410,7 @@ private:
|
||||||
RefPtr<CSS::StyleProperties> m_computed_css_values;
|
RefPtr<CSS::StyleProperties> m_computed_css_values;
|
||||||
HashMap<FlyString, CSS::StyleProperty> m_custom_properties;
|
HashMap<FlyString, CSS::StyleProperty> m_custom_properties;
|
||||||
|
|
||||||
using PseudoElementCustomProperties = Array<HashMap<FlyString, CSS::StyleProperty>, to_underlying(CSS::Selector::PseudoElement::Type::PseudoElementCount)>;
|
using PseudoElementCustomProperties = Array<HashMap<FlyString, CSS::StyleProperty>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)>;
|
||||||
mutable OwnPtr<PseudoElementCustomProperties> m_pseudo_element_custom_properties;
|
mutable OwnPtr<PseudoElementCustomProperties> m_pseudo_element_custom_properties;
|
||||||
PseudoElementCustomProperties& pseudo_element_custom_properties() const;
|
PseudoElementCustomProperties& pseudo_element_custom_properties() const;
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ private:
|
||||||
|
|
||||||
Optional<FlyString> m_id;
|
Optional<FlyString> m_id;
|
||||||
|
|
||||||
using PseudoElementLayoutNodes = Array<JS::GCPtr<Layout::Node>, to_underlying(CSS::Selector::PseudoElement::Type::PseudoElementCount)>;
|
using PseudoElementLayoutNodes = Array<JS::GCPtr<Layout::Node>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)>;
|
||||||
OwnPtr<PseudoElementLayoutNodes> m_pseudo_element_nodes;
|
OwnPtr<PseudoElementLayoutNodes> m_pseudo_element_nodes;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reaction-queue
|
// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reaction-queue
|
||||||
|
|
|
@ -41,7 +41,7 @@ void Inspector::inspect_dom_node(i32 node_id, Optional<i32> const& pseudo_elemen
|
||||||
{
|
{
|
||||||
auto& page = global_object().browsing_context()->page();
|
auto& page = global_object().browsing_context()->page();
|
||||||
page.client().inspector_did_select_dom_node(node_id, pseudo_element.map([](auto value) {
|
page.client().inspector_did_select_dom_node(node_id, pseudo_element.map([](auto value) {
|
||||||
VERIFY(value < to_underlying(Web::CSS::Selector::PseudoElement::Type::PseudoElementCount));
|
VERIFY(value < to_underlying(Web::CSS::Selector::PseudoElement::Type::KnownPseudoElementCount));
|
||||||
return static_cast<Web::CSS::Selector::PseudoElement::Type>(value);
|
return static_cast<Web::CSS::Selector::PseudoElement::Type>(value);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue