LibWeb: Implement CSSStyleSheet.replaceSync()
This method behaves the same as `CSSStyleSheet.replace()` but the operation is performed synchronously.
This commit is contained in:
parent
81c67d34eb
commit
87b52a1816
Notes:
sideshowbarker
2024-07-18 02:13:10 +09:00
Author: https://github.com/tcl3 Commit: https://github.com/SerenityOS/serenity/commit/87b52a1816 Pull-request: https://github.com/SerenityOS/serenity/pull/23327 Reviewed-by: https://github.com/awesomekling
5 changed files with 94 additions and 1 deletions
|
@ -0,0 +1,8 @@
|
|||
Exception thrown when calling replaceSync() on non-constructed stylesheet: NotAllowedError
|
||||
Number of CSS rules after replaceSync(): 2
|
||||
Rule: .test { font-size: 14px; }
|
||||
Rule: .test2 { font-size: 16px; }
|
||||
cssRules returns the same object before and after replaceSync(): true
|
||||
@import rule should be not appear below:
|
||||
Rule: .test { padding: 100px; }
|
||||
Calling replaceSync() while the disallow modification flag set throws: NotAllowedError
|
57
Tests/LibWeb/Text/input/css/CSSStyleSheet-replaceSync.html
Normal file
57
Tests/LibWeb/Text/input/css/CSSStyleSheet-replaceSync.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.test {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const newStyle = `
|
||||
.test {
|
||||
font-size: 14px;
|
||||
}
|
||||
.test2 {
|
||||
font-size: 16px;
|
||||
}`;
|
||||
const newStyle2 = `.test {
|
||||
padding: 100px;
|
||||
}`;
|
||||
|
||||
const nonConstructedSheet = document.styleSheets[0];
|
||||
try {
|
||||
nonConstructedSheet.replaceSync(newStyle);
|
||||
println("FAIL");
|
||||
} catch (e) {
|
||||
println(`Exception thrown when calling replaceSync() on non-constructed stylesheet: ${e.name}`);
|
||||
}
|
||||
|
||||
const sheet = new CSSStyleSheet();
|
||||
const cssRules = sheet.cssRules;
|
||||
|
||||
sheet.replaceSync(newStyle);
|
||||
println(`Number of CSS rules after replaceSync(): ${sheet.cssRules.length}`);
|
||||
for (const rule of sheet.cssRules) {
|
||||
println(`Rule: ${rule.cssText}`);
|
||||
}
|
||||
|
||||
const cssRulesAfterReplaceSync = sheet.cssRules;
|
||||
println(`cssRules returns the same object before and after replaceSync(): ${cssRules === cssRulesAfterReplaceSync}`);
|
||||
|
||||
const importRule = `@import url("test.css");`;
|
||||
sheet.replaceSync(`${newStyle2} ${importRule}`);
|
||||
|
||||
println(`@import rule should be not appear below:`);
|
||||
for (const rule of sheet.cssRules) {
|
||||
println(`Rule: ${rule.cssText}`);
|
||||
}
|
||||
|
||||
const unresolvedPromise = sheet.replace(newStyle);
|
||||
try {
|
||||
sheet.replaceSync(newStyle);
|
||||
println("FAIL");
|
||||
} catch (e) {
|
||||
println(`Calling replaceSync() while the disallow modification flag set throws: ${e.name}`);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -230,6 +230,33 @@ JS::NonnullGCPtr<JS::Promise> CSSStyleSheet::replace(String text)
|
|||
return promise;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-replacesync
|
||||
WebIDL::ExceptionOr<void> CSSStyleSheet::replace_sync(StringView text)
|
||||
{
|
||||
// 1. If the constructed flag is not set, or the disallow modification flag is set, throw a NotAllowedError DOMException.
|
||||
if (!constructed())
|
||||
return WebIDL::NotAllowedError::create(realm(), "Can't call replaceSync() on non-constructed stylesheets"_fly_string);
|
||||
if (disallow_modification())
|
||||
return WebIDL::NotAllowedError::create(realm(), "Can't call replaceSync() on non-modifiable stylesheets"_fly_string);
|
||||
|
||||
// 2. Let rules be the result of running parse a stylesheet’s contents from text.
|
||||
auto context = m_style_sheet_list ? CSS::Parser::ParsingContext { m_style_sheet_list->document() } : CSS::Parser::ParsingContext { realm() };
|
||||
auto* parsed_stylesheet = parse_css_stylesheet(context, text);
|
||||
auto& rules = parsed_stylesheet->rules();
|
||||
|
||||
// 3. If rules contains one or more @import rules, remove those rules from rules.
|
||||
JS::MarkedVector<JS::NonnullGCPtr<CSSRule>> rules_without_import(realm().heap());
|
||||
for (auto rule : rules) {
|
||||
if (rule->type() != CSSRule::Type::Import)
|
||||
rules_without_import.append(rule);
|
||||
}
|
||||
|
||||
// 4.Set sheet’s CSS rules to rules.
|
||||
m_rules->set_rules({}, rules_without_import);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/cssom/#dom-cssstylesheet-removerule
|
||||
WebIDL::ExceptionOr<void> CSSStyleSheet::remove_rule(unsigned index)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
WebIDL::ExceptionOr<void> delete_rule(unsigned index);
|
||||
|
||||
JS::NonnullGCPtr<JS::Promise> replace(String text);
|
||||
WebIDL::ExceptionOr<void> replace_sync(StringView text);
|
||||
|
||||
void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
|
||||
// Returns whether the match state of any media queries changed after evaluation.
|
||||
|
|
|
@ -14,7 +14,7 @@ interface CSSStyleSheet : StyleSheet {
|
|||
undefined deleteRule(unsigned long index);
|
||||
|
||||
Promise<CSSStyleSheet> replace(USVString text);
|
||||
// FIXME: undefined replaceSync(USVString text);
|
||||
undefined replaceSync(USVString text);
|
||||
|
||||
// https://drafts.csswg.org/cssom/#legacy-css-style-sheet-members
|
||||
[SameObject, ImplementedAs=css_rules] readonly attribute CSSRuleList rules;
|
||||
|
|
Loading…
Add table
Reference in a new issue