mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb: Invalidate owner sheet on add/remove in CSSStyleProperties
Fixes at least 2 WPT subtests.
This commit is contained in:
parent
fbb3b06462
commit
cf34a7bb32
Notes:
github-actions[bot]
2025-04-24 16:28:02 +00:00
Author: https://github.com/awesomekling
Commit: cf34a7bb32
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4455
Reviewed-by: https://github.com/AtkinsSJ ✅
6 changed files with 87 additions and 7 deletions
|
@ -270,9 +270,13 @@ WebIDL::ExceptionOr<void> CSSStyleProperties::set_property(StringView property_n
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. If updated is true, update style attribute for the CSS declaration block.
|
// 10. If updated is true, update style attribute for the CSS declaration block.
|
||||||
if (updated)
|
if (updated) {
|
||||||
update_style_attribute();
|
update_style_attribute();
|
||||||
|
|
||||||
|
// Non-standard: Invalidate style for the owners of our containing sheet, if any.
|
||||||
|
invalidate_owners(DOM::StyleInvalidationReason::CSSStylePropertiesSetProperty);
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,9 +1053,13 @@ WebIDL::ExceptionOr<String> CSSStyleProperties::remove_property(StringView prope
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. If removed is true, Update style attribute for the CSS declaration block.
|
// 7. If removed is true, Update style attribute for the CSS declaration block.
|
||||||
if (removed)
|
if (removed) {
|
||||||
update_style_attribute();
|
update_style_attribute();
|
||||||
|
|
||||||
|
// Non-standard: Invalidate style for the owners of our containing sheet, if any.
|
||||||
|
invalidate_owners(DOM::StyleInvalidationReason::CSSStylePropertiesRemoveProperty);
|
||||||
|
}
|
||||||
|
|
||||||
// 8. Return value.
|
// 8. Return value.
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -1164,15 +1172,20 @@ WebIDL::ExceptionOr<void> CSSStyleProperties::set_css_text(StringView css_text)
|
||||||
update_style_attribute();
|
update_style_attribute();
|
||||||
|
|
||||||
// Non-standard: Invalidate style for the owners of our containing sheet, if any.
|
// Non-standard: Invalidate style for the owners of our containing sheet, if any.
|
||||||
if (auto rule = parent_rule()) {
|
invalidate_owners(DOM::StyleInvalidationReason::CSSStylePropertiesTextChange);
|
||||||
if (auto sheet = rule->parent_style_sheet()) {
|
|
||||||
sheet->invalidate_owners(DOM::StyleInvalidationReason::CSSStylePropertiesTextChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSSStyleProperties::invalidate_owners(DOM::StyleInvalidationReason reason)
|
||||||
|
{
|
||||||
|
if (auto rule = parent_rule()) {
|
||||||
|
if (auto sheet = rule->parent_style_sheet()) {
|
||||||
|
sheet->invalidate_owners(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom/#set-a-css-declaration
|
// https://drafts.csswg.org/cssom/#set-a-css-declaration
|
||||||
bool CSSStyleProperties::set_a_css_declaration(PropertyID property_id, NonnullRefPtr<CSSStyleValue const> value, Important important)
|
bool CSSStyleProperties::set_a_css_declaration(PropertyID property_id, NonnullRefPtr<CSSStyleValue const> value, Important important)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,6 +71,8 @@ private:
|
||||||
void empty_the_declarations();
|
void empty_the_declarations();
|
||||||
void set_the_declarations(Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties);
|
void set_the_declarations(Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties);
|
||||||
|
|
||||||
|
void invalidate_owners(DOM::StyleInvalidationReason);
|
||||||
|
|
||||||
Vector<StyleProperty> m_properties;
|
Vector<StyleProperty> m_properties;
|
||||||
HashMap<FlyString, StyleProperty> m_custom_properties;
|
HashMap<FlyString, StyleProperty> m_custom_properties;
|
||||||
};
|
};
|
||||||
|
|
|
@ -248,6 +248,11 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::replace_sync(StringView text)
|
||||||
rules_without_import.append(rule);
|
rules_without_import.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The spec doesn't say where to set the parent style sheet, so we'll do it here.
|
||||||
|
for (auto& rule : rules_without_import) {
|
||||||
|
rule->set_parent_style_sheet(this);
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Set sheet’s CSS rules to rules.
|
// 4. Set sheet’s CSS rules to rules.
|
||||||
m_rules->set_rules({}, rules_without_import);
|
m_rules->set_rules({}, rules_without_import);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ enum class ShouldComputeRole {
|
||||||
X(AdoptedStyleSheetsList) \
|
X(AdoptedStyleSheetsList) \
|
||||||
X(CSSFontLoaded) \
|
X(CSSFontLoaded) \
|
||||||
X(CSSImportRule) \
|
X(CSSImportRule) \
|
||||||
|
X(CSSStylePropertiesRemoveProperty) \
|
||||||
|
X(CSSStylePropertiesSetProperty) \
|
||||||
X(CSSStylePropertiesTextChange) \
|
X(CSSStylePropertiesTextChange) \
|
||||||
X(CustomElementStateChange) \
|
X(CustomElementStateChange) \
|
||||||
X(DidLoseFocus) \
|
X(DidLoseFocus) \
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
2 Pass
|
||||||
|
1 Fail
|
||||||
|
Fail mutating constructed CSSStyleSheet applied to root invalidates styles
|
||||||
|
Pass mutating constructed CSSStyleSheet applied to shadowdom invalidates styles
|
||||||
|
Pass mutating dependent constructed CSSStyleSheet applied to shadowdom invalidates styles
|
|
@ -0,0 +1,49 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSSStyleSheet rule mutation invalidation</title>
|
||||||
|
<link rel="author" href="mailto:wpt@keithcirkel.co.uk" title="Keith Cirkel">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/cssom/#extensions-to-the-document-or-shadow-root-interface">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<span id="span1">Should be green.</span>
|
||||||
|
<span id="span2">Should be green.</span>
|
||||||
|
<script>
|
||||||
|
promise_test(async function(t) {
|
||||||
|
const sheet = new CSSStyleSheet();
|
||||||
|
sheet.replaceSync('span {color:var(--color, red);}');
|
||||||
|
document.adoptedStyleSheets = [sheet];
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
document.adoptedStyleSheets = [];
|
||||||
|
})
|
||||||
|
assert_equals(getComputedStyle(span1).color, "rgb(255, 0, 0)", "Sheet should apply");
|
||||||
|
sheet.rules[0].style.setProperty('--color', 'green');
|
||||||
|
assert_equals(getComputedStyle(span1).color, "rgb(0, 128, 0)", "Sheet should invalidate style");
|
||||||
|
document.adoptedStyleSheets = [];
|
||||||
|
assert_equals(getComputedStyle(span1).color, "rgb(0, 0, 0)", "Removing sheet should apply");
|
||||||
|
}, "mutating constructed CSSStyleSheet applied to root invalidates styles");
|
||||||
|
|
||||||
|
promise_test(async function() {
|
||||||
|
span1.attachShadow({mode:'open'})
|
||||||
|
span1.shadowRoot.append(document.createElement('slot'))
|
||||||
|
const sheet = new CSSStyleSheet();
|
||||||
|
sheet.replaceSync(':host {color:var(--color, red);}');
|
||||||
|
span1.shadowRoot.adoptedStyleSheets = [sheet];
|
||||||
|
assert_equals(getComputedStyle(span1).color, "rgb(255, 0, 0)", "Sheet should apply");
|
||||||
|
sheet.rules[0].style.setProperty('--color', 'green');
|
||||||
|
assert_equals(getComputedStyle(span1).color, "rgb(0, 128, 0)", "Sheet should invalidate style");
|
||||||
|
}, "mutating constructed CSSStyleSheet applied to shadowdom invalidates styles");
|
||||||
|
|
||||||
|
promise_test(async function() {
|
||||||
|
span2.attachShadow({mode:'open'})
|
||||||
|
span2.shadowRoot.append(document.createElement('slot'))
|
||||||
|
const sheet1 = new CSSStyleSheet();
|
||||||
|
const sheet2 = new CSSStyleSheet();
|
||||||
|
sheet1.replaceSync(':host {color:var(--color, hotpink);}');
|
||||||
|
sheet2.replaceSync(':host {--color: blue}');
|
||||||
|
const style2 = sheet2.rules[0].style;
|
||||||
|
span2.shadowRoot.adoptedStyleSheets = [sheet1, sheet2];
|
||||||
|
assert_equals(getComputedStyle(span2).color, "rgb(0, 0, 255)", "Sheet should apply");
|
||||||
|
style2.setProperty('--color', 'green');
|
||||||
|
assert_equals(getComputedStyle(span2).color, "rgb(0, 128, 0)", "Sheet should invalidate style");
|
||||||
|
}, "mutating dependent constructed CSSStyleSheet applied to shadowdom invalidates styles");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue