Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[:has() pseudo-class] Support invalidation for :defined pseudo class
https://bugs.webkit.org/show_bug.cgi?id=257385
rdar://109896689

Reviewed by Ryosuke Niwa.

Use PseudoClassChangeInvalidation instead of manually invalidating the subtree, which does not take in account :has().

* LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/defined-in-has-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/defined-in-has.html: Added.
* Source/WebCore/dom/Element.cpp:
(WebCore::Node::setCustomElementState):
(WebCore::Element::setIsDefinedCustomElement):

Canonical link: https://commits.webkit.org/264602@main
  • Loading branch information
nt1m committed May 26, 2023
1 parent 775dc52 commit e721d57
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
@@ -0,0 +1,4 @@
Test :defined pseudo-class invalidation with :has()

PASS Test :has() invalidation with :defined pseudo-class

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<title>:has() invalidation with :defined pseudo-class</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
<link rel="help" href="https://html.spec.whatwg.org/multipage/semantics-other.html#selector-defined">
<style>
#subject {
background-color: red;
width: 100px;
height: 100px;
}
#subject:has(:defined) {
background-color: green;
}
</style>
<body>
Test :defined pseudo-class invalidation with :has()
<div id="subject">
<my-element></my-element>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const GREEN = "rgb(0, 128, 0)";
const RED = "rgb(255, 0, 0)";

function assert_matches_defined(defined) {
assert_equals(getComputedStyle(subject).backgroundColor, defined ? GREEN : RED);
}

test(() => {
assert_matches_defined(false);
customElements.define("my-element", class MyElement extends HTMLElement { });
assert_matches_defined(true);
}, "Test :has() invalidation with :defined pseudo-class");
</script>
</body>
6 changes: 5 additions & 1 deletion Source/WebCore/dom/Element.cpp
Expand Up @@ -2961,6 +2961,11 @@ ShadowRoot& Element::createUserAgentShadowRoot()

inline void Node::setCustomElementState(CustomElementState state)
{
RELEASE_ASSERT(is<Element>(this));
Style::PseudoClassChangeInvalidation styleInvalidation(downcast<Element>(*this),
CSSSelector::PseudoClassDefined,
state == CustomElementState::Custom || state == CustomElementState::Uncustomized
);
auto bitfields = rareDataBitfields();
bitfields.customElementState = static_cast<uint16_t>(state);
setRareDataBitfields(bitfields);
Expand All @@ -2972,7 +2977,6 @@ void Element::setIsDefinedCustomElement(JSCustomElementInterface& elementInterfa
auto& data = ensureElementRareData();
if (!data.customElementReactionQueue())
data.setCustomElementReactionQueue(makeUnique<CustomElementReactionQueue>(elementInterface));
invalidateStyleForSubtree();
InspectorInstrumentation::didChangeCustomElementState(*this);
}

Expand Down

0 comments on commit e721d57

Please sign in to comment.