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
Notes: sideshowbarker 2024-07-18 03:23:00 +09:00
5 changed files with 36 additions and 2 deletions

View file

@ -6,6 +6,8 @@
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/StyleSheetList.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/ExceptionOr.h>
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.
// 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
@ -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.
// 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
@ -67,4 +85,9 @@ bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& 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.
bool evaluate_media_queries(HTML::Window const&);
void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*);
private:
explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>);
NonnullRefPtr<CSSRuleList> m_rules;
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)
{
VERIFY(!m_sheets.contains_slow(sheet));
sheet->set_style_sheet_list({}, this);
m_sheets.append(move(sheet));
++m_generation;
@ -20,6 +21,7 @@ void StyleSheetList::add_sheet(NonnullRefPtr<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_generation;

View file

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

View file

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