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

LibWeb: Invalidate style after CSSStyleSheet.{insert,remove}Rule()

When rules are inserted or removed via the CSSOM API, we now invalidate
document style to ensure that any changes made are reflected.

1% progression on ACID3. :^)
This commit is contained in:
Andreas Kling 2022-03-09 19:57:15 +01:00
parent 0e758b4da8
commit a13079f757
5 changed files with 36 additions and 2 deletions

View file

@ -6,6 +6,8 @@
#include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/StyleSheetList.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/ExceptionOr.h> #include <LibWeb/DOM/ExceptionOr.h>
namespace Web::CSS { namespace Web::CSS {
@ -36,7 +38,16 @@ DOM::ExceptionOr<unsigned> CSSStyleSheet::insert_rule(StringView rule, unsigned
// FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException. // FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException.
// 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index. // 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index.
return m_rules->insert_a_css_rule(parsed_rule.release_nonnull(), index); auto result = m_rules->insert_a_css_rule(parsed_rule.release_nonnull(), index);
if (!result.is_exception()) {
if (m_style_sheet_list) {
m_style_sheet_list->bump_generation();
m_style_sheet_list->document().invalidate_style();
}
}
return result;
} }
// https://www.w3.org/TR/cssom/#dom-cssstylesheet-deleterule // https://www.w3.org/TR/cssom/#dom-cssstylesheet-deleterule
@ -47,7 +58,14 @@ DOM::ExceptionOr<void> CSSStyleSheet::delete_rule(unsigned index)
// FIXME: 2. If the disallow modification flag is set, throw a NotAllowedError DOMException. // FIXME: 2. If the disallow modification flag is set, throw a NotAllowedError DOMException.
// 3. Remove a CSS rule in the CSS rules at index. // 3. Remove a CSS rule in the CSS rules at index.
return m_rules->remove_a_css_rule(index); auto result = m_rules->remove_a_css_rule(index);
if (!result.is_exception()) {
if (m_style_sheet_list) {
m_style_sheet_list->bump_generation();
m_style_sheet_list->document().invalidate_style();
}
}
return result;
} }
// https://www.w3.org/TR/cssom/#dom-cssstylesheet-removerule // https://www.w3.org/TR/cssom/#dom-cssstylesheet-removerule
@ -67,4 +85,9 @@ bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
return m_rules->evaluate_media_queries(window); return m_rules->evaluate_media_queries(window);
} }
void CSSStyleSheet::set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList* list)
{
m_style_sheet_list = list;
}
} }

View file

@ -50,12 +50,16 @@ public:
// Returns whether the match state of any media queries changed after evaluation. // Returns whether the match state of any media queries changed after evaluation.
bool evaluate_media_queries(HTML::Window const&); bool evaluate_media_queries(HTML::Window const&);
void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*);
private: private:
explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>); explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>);
NonnullRefPtr<CSSRuleList> m_rules; NonnullRefPtr<CSSRuleList> m_rules;
WeakPtr<CSSRule> m_owner_css_rule; WeakPtr<CSSRule> m_owner_css_rule;
WeakPtr<StyleSheetList> m_style_sheet_list;
}; };
} }

View file

@ -12,6 +12,7 @@ namespace Web::CSS {
void StyleSheetList::add_sheet(NonnullRefPtr<CSSStyleSheet> sheet) void StyleSheetList::add_sheet(NonnullRefPtr<CSSStyleSheet> sheet)
{ {
VERIFY(!m_sheets.contains_slow(sheet)); VERIFY(!m_sheets.contains_slow(sheet));
sheet->set_style_sheet_list({}, this);
m_sheets.append(move(sheet)); m_sheets.append(move(sheet));
++m_generation; ++m_generation;
@ -20,6 +21,7 @@ void StyleSheetList::add_sheet(NonnullRefPtr<CSSStyleSheet> sheet)
void StyleSheetList::remove_sheet(CSSStyleSheet& sheet) void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
{ {
sheet.set_style_sheet_list({}, nullptr);
m_sheets.remove_first_matching([&](auto& entry) { return &*entry == &sheet; }); m_sheets.remove_first_matching([&](auto& entry) { return &*entry == &sheet; });
++m_generation; ++m_generation;

View file

@ -16,6 +16,7 @@ namespace Web::CSS {
class StyleSheetList class StyleSheetList
: public RefCounted<StyleSheetList> : public RefCounted<StyleSheetList>
, public Weakable<StyleSheetList>
, public Bindings::Wrappable { , public Bindings::Wrappable {
public: public:
using WrapperType = Bindings::StyleSheetListWrapper; using WrapperType = Bindings::StyleSheetListWrapper;
@ -45,6 +46,9 @@ public:
int generation() const { return m_generation; } int generation() const { return m_generation; }
void bump_generation() { ++m_generation; } void bump_generation() { ++m_generation; }
DOM::Document& document() { return m_document; }
DOM::Document const& document() const { return m_document; }
private: private:
explicit StyleSheetList(DOM::Document&); explicit StyleSheetList(DOM::Document&);

View file

@ -73,6 +73,7 @@ class StringStyleValue;
class StyleComputer; class StyleComputer;
class StyleProperties; class StyleProperties;
class StyleSheet; class StyleSheet;
class StyleSheetList;
class StyleValue; class StyleValue;
class StyleValueList; class StyleValueList;
class Supports; class Supports;