diff options
author | Andreas Kling <kling@serenityos.org> | 2022-08-07 13:14:54 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-06 00:27:09 +0200 |
commit | 5d60212076f05fd85607e05e1496ad009dcf501b (patch) | |
tree | f14e5cf5e08624aad9ea01ea99d0cc618ff1ac39 /Userland/Libraries/LibWeb/CSS | |
parent | 0fe923e35580ce1745f47c0d812ce7689ae84063 (diff) | |
download | serenity-5d60212076f05fd85607e05e1496ad009dcf501b.zip |
LibWeb: Make StyleSheet and CSSStyleSheet GC-allocated
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.h | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 15 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h | 19 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleComputer.cpp | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleSheet.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleSheet.h | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleSheetList.h | 12 |
11 files changed, 98 insertions, 61 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp index 932d8120c7..61ea65e7bc 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp @@ -73,13 +73,13 @@ void CSSImportRule::resource_did_load() dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Resource did load, has encoded data. URL: {}", resource()->url()); } - auto sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(*m_document, resource()->url()), resource()->encoded_data()); + auto* sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(*m_document, resource()->url()), resource()->encoded_data()); if (!sheet) { dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Failed to parse stylesheet: {}", resource()->url()); return; } - m_style_sheet = move(sheet); + m_style_sheet = JS::make_handle(sheet); m_document->style_computer().invalidate_rule_cache(); m_document->invalidate_style(); diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h index 82a558c45b..abe16dfb73 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h @@ -8,6 +8,7 @@ #pragma once #include <AK/URL.h> +#include <LibJS/Heap/Handle.h> #include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/DOM/DocumentLoadEventDelayer.h> @@ -35,10 +36,10 @@ public: String href() const { return m_url.to_string(); } bool has_import_result() const { return !m_style_sheet.is_null(); } - RefPtr<CSSStyleSheet> loaded_style_sheet() { return m_style_sheet; } - RefPtr<CSSStyleSheet> const loaded_style_sheet() const { return m_style_sheet; } - NonnullRefPtr<CSSStyleSheet> style_sheet_for_bindings() { return *m_style_sheet; } - void set_style_sheet(RefPtr<CSSStyleSheet> const& style_sheet) { m_style_sheet = style_sheet; } + CSSStyleSheet* loaded_style_sheet() { return m_style_sheet.cell(); } + CSSStyleSheet const* loaded_style_sheet() const { return m_style_sheet.cell(); } + CSSStyleSheet* style_sheet_for_bindings() { return m_style_sheet.cell(); } + void set_style_sheet(CSSStyleSheet* style_sheet) { m_style_sheet = JS::make_handle(style_sheet); } virtual StringView class_name() const override { return "CSSImportRule"sv; }; virtual Type type() const override { return Type::Import; }; @@ -55,7 +56,7 @@ private: AK::URL m_url; WeakPtr<DOM::Document> m_document; Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer; - RefPtr<CSSStyleSheet> m_style_sheet; + JS::Handle<CSSStyleSheet> m_style_sheet; }; template<> diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index cecdb9ebe5..7958b05033 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -1,9 +1,10 @@ /* - * Copyright (c) 2019-2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2019-2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSStyleSheetPrototype.h> #include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/StyleSheetList.h> @@ -12,9 +13,17 @@ namespace Web::CSS { -CSSStyleSheet::CSSStyleSheet(NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) - : m_rules(CSSRuleList::create(move(rules))) +CSSStyleSheet* CSSStyleSheet::create(Bindings::WindowObject& window_object, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) { + return window_object.heap().allocate<CSSStyleSheet>(window_object.realm(), window_object, move(rules), move(location)); +} + +CSSStyleSheet::CSSStyleSheet(Bindings::WindowObject& window_object, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) + : StyleSheet(window_object) + , m_rules(CSSRuleList::create(move(rules))) +{ + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSStyleSheetPrototype>("CSSStyleSheet")); + if (location.has_value()) set_location(location->to_string()); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 53178ce391..78cb2e0cb5 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -21,16 +21,16 @@ class CSSImportRule; class CSSStyleSheet final : public StyleSheet , public Weakable<CSSStyleSheet> { -public: - using WrapperType = Bindings::CSSStyleSheetWrapper; + JS_OBJECT(CSSStyleSheet, StyleSheet); - static NonnullRefPtr<CSSStyleSheet> create(NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) - { - return adopt_ref(*new CSSStyleSheet(move(rules), move(location))); - } +public: + static CSSStyleSheet* create(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location); + explicit CSSStyleSheet(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>, Optional<AK::URL> location); virtual ~CSSStyleSheet() override = default; + CSSStyleSheet& impl() { return *this; } + void set_owner_css_rule(CSSRule* rule) { m_owner_css_rule = rule; } virtual String type() const override { return "text/css"; } @@ -53,8 +53,6 @@ public: void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*); private: - explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>, Optional<AK::URL> location); - NonnullRefPtr<CSSRuleList> m_rules; WeakPtr<CSSRule> m_owner_css_rule; @@ -65,7 +63,6 @@ private: } namespace Web::Bindings { - -CSSStyleSheetWrapper* wrap(JS::Realm&, CSS::CSSStyleSheet&); - +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSStyleSheet& object) { return &object; } +using CSSStyleSheetWrapper = Web::CSS::CSSStyleSheet; } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 2c09f36687..359f58635e 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -13,6 +13,7 @@ #include <AK/GenericLexer.h> #include <AK/NonnullRefPtrVector.h> #include <AK/SourceLocation.h> +#include <LibWeb/Bindings/MainThreadVM.h> #include <LibWeb/CSS/CSSFontFaceRule.h> #include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSMediaRule.h> @@ -38,20 +39,28 @@ static void log_parse_error(SourceLocation const& location = SourceLocation::cur namespace Web::CSS::Parser { +ParsingContext::ParsingContext() + : m_window_object(Bindings::main_thread_internal_window_object()) +{ +} + ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url) - : m_document(&document) + : m_window_object(document.preferred_window_object()) + , m_document(&document) , m_url(move(url)) { } ParsingContext::ParsingContext(DOM::Document const& document) - : m_document(&document) + : m_window_object(document.preferred_window_object()) + , m_document(&document) , m_url(document.url()) { } ParsingContext::ParsingContext(DOM::ParentNode& parent_node) - : m_document(&parent_node.document()) + : m_window_object(parent_node.document().preferred_window_object()) + , m_document(&parent_node.document()) , m_url(parent_node.document().url()) { } @@ -179,7 +188,7 @@ Parser::ParsedStyleSheet Parser::parse_a_stylesheet(TokenStream<T>& tokens, Opti } // https://www.w3.org/TR/css-syntax-3/#parse-a-css-stylesheet -NonnullRefPtr<CSSStyleSheet> Parser::parse_as_css_stylesheet(Optional<AK::URL> location) +CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<AK::URL> location) { // To parse a CSS stylesheet, first parse a stylesheet. auto style_sheet = parse_a_stylesheet(m_token_stream, {}); @@ -193,7 +202,7 @@ NonnullRefPtr<CSSStyleSheet> Parser::parse_as_css_stylesheet(Optional<AK::URL> l rules.append(*rule); } - return CSSStyleSheet::create(move(rules), move(location)); + return CSSStyleSheet::create(m_context.window_object(), move(rules), move(location)); } Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode) @@ -6373,10 +6382,10 @@ TimePercentage Parser::Dimension::time_percentage() const namespace Web { -RefPtr<CSS::CSSStyleSheet> parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location) +CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location) { if (css.is_empty()) - return CSS::CSSStyleSheet::create({}, location); + return CSS::CSSStyleSheet::create(context.window_object(), {}, location); CSS::Parser::Parser parser(context, css); return parser.parse_as_css_stylesheet(location); } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index c9b7fbb63b..262814c49b 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -34,7 +34,7 @@ namespace Web::CSS::Parser { class ParsingContext { public: - ParsingContext() = default; + ParsingContext(); explicit ParsingContext(DOM::Document const&); explicit ParsingContext(DOM::Document const&, AK::URL); explicit ParsingContext(DOM::ParentNode&); @@ -46,7 +46,10 @@ public: PropertyID current_property_id() const { return m_current_property_id; } void set_current_property_id(PropertyID property_id) { m_current_property_id = property_id; } + Bindings::WindowObject& window_object() const { return m_window_object; } + private: + Bindings::WindowObject& m_window_object; DOM::Document const* m_document { nullptr }; PropertyID m_current_property_id { PropertyID::Invalid }; AK::URL m_url; @@ -122,7 +125,7 @@ public: Parser(ParsingContext const&, StringView input, String const& encoding = "utf-8"); ~Parser() = default; - NonnullRefPtr<CSSStyleSheet> parse_as_css_stylesheet(Optional<AK::URL> location); + CSSStyleSheet* parse_as_css_stylesheet(Optional<AK::URL> location); RefPtr<ElementInlineCSSStyleDeclaration> parse_as_style_attribute(DOM::Element&); RefPtr<CSSRule> parse_as_css_rule(); Optional<StyleProperty> parse_as_supports_condition(); @@ -416,7 +419,7 @@ private: namespace Web { -RefPtr<CSS::CSSStyleSheet> parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional<AK::URL> location = {}); +CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional<AK::URL> location = {}); RefPtr<CSS::ElementInlineCSSStyleDeclaration> parse_css_style_attribute(CSS::Parser::ParsingContext const&, StringView, DOM::Element&); RefPtr<CSS::StyleValue> parse_css_value(CSS::Parser::ParsingContext const&, StringView, CSS::PropertyID property_id = CSS::PropertyID::Invalid); Optional<CSS::SelectorList> parse_selector(CSS::Parser::ParsingContext const&, StringView); diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index c1b7125160..294c622432 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -108,24 +108,24 @@ private: HashMap<float, NonnullRefPtr<Gfx::ScaledFont>> mutable m_cached_fonts; }; -static StyleSheet& default_stylesheet() +static CSSStyleSheet& default_stylesheet() { - static StyleSheet* sheet; - if (!sheet) { + static JS::Handle<CSSStyleSheet> sheet; + if (!sheet.cell()) { extern char const default_stylesheet_source[]; String css = default_stylesheet_source; - sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(), css).leak_ref(); + sheet = JS::make_handle(parse_css_stylesheet(CSS::Parser::ParsingContext(), css)); } return *sheet; } -static StyleSheet& quirks_mode_stylesheet() +static CSSStyleSheet& quirks_mode_stylesheet() { - static StyleSheet* sheet; - if (!sheet) { + static JS::Handle<CSSStyleSheet> sheet; + if (!sheet.cell()) { extern char const quirks_mode_stylesheet_source[]; String css = quirks_mode_stylesheet_source; - sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(), css).leak_ref(); + sheet = JS::make_handle(parse_css_stylesheet(CSS::Parser::ParsingContext(), css)); } return *sheet; } @@ -140,7 +140,7 @@ void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback c } if (cascade_origin == CascadeOrigin::Author) { for (auto const& sheet : document().style_sheets().sheets()) { - callback(sheet); + callback(*sheet); } } } @@ -180,7 +180,7 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e size_t style_sheet_index = 0; for_each_stylesheet(cascade_origin, [&](auto& sheet) { size_t rule_index = 0; - static_cast<CSSStyleSheet const&>(sheet).for_each_effective_style_rule([&](auto const& rule) { + sheet.for_each_effective_style_rule([&](auto const& rule) { size_t selector_index = 0; for (auto& selector : rule.selectors()) { if (SelectorEngine::matches(selector, element, pseudo_element)) { @@ -1261,7 +1261,7 @@ void StyleComputer::build_rule_cache() size_t style_sheet_index = 0; for_each_stylesheet(CascadeOrigin::Author, [&](auto& sheet) { size_t rule_index = 0; - static_cast<CSSStyleSheet const&>(sheet).for_each_effective_style_rule([&](auto const& rule) { + sheet.for_each_effective_style_rule([&](auto const& rule) { size_t selector_index = 0; for (CSS::Selector const& selector : rule.selectors()) { MatchingRule matching_rule { rule, style_sheet_index, rule_index, selector_index, selector.specificity() }; diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp index 36c04d7702..ae5d520889 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp @@ -5,12 +5,25 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/StyleSheetPrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/StyleSheet.h> #include <LibWeb/DOM/Element.h> namespace Web::CSS { +StyleSheet::StyleSheet(Bindings::WindowObject& window_object) + : PlatformObject(window_object.ensure_web_prototype<Bindings::StyleSheetPrototype>("StyleSheet")) +{ +} + +void StyleSheet::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_parent_style_sheet); +} + void StyleSheet::set_owner_node(DOM::Element* element) { if (element) diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheet.h b/Userland/Libraries/LibWeb/CSS/StyleSheet.h index 7c921a3f35..8da67177fa 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/StyleSheet.h @@ -7,17 +7,16 @@ #pragma once -#include <AK/RefCounted.h> -#include <LibWeb/Bindings/Wrappable.h> +#include <LibWeb/Bindings/PlatformObject.h> #include <LibWeb/Forward.h> namespace Web::CSS { -class StyleSheet - : public RefCounted<StyleSheet> - , public Bindings::Wrappable { +class StyleSheet : public Bindings::PlatformObject { + JS_OBJECT(StyleSheet, Bindings::PlatformObject); + public: - using WrapperType = Bindings::StyleSheetWrapper; + StyleSheet& impl() { return *this; } virtual ~StyleSheet() = default; @@ -49,12 +48,14 @@ public: void set_parent_css_style_sheet(CSSStyleSheet*); protected: - StyleSheet() = default; + explicit StyleSheet(Bindings::WindowObject&); private: + virtual void visit_edges(Cell::Visitor&) override; + WeakPtr<DOM::Element> m_owner_node; - WeakPtr<CSSStyleSheet> m_parent_style_sheet; + CSSStyleSheet* m_parent_style_sheet { nullptr }; String m_location; String m_title; @@ -67,3 +68,8 @@ private: }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::StyleSheet& object) { return &object; } +using StyleSheetWrapper = Web::CSS::StyleSheet; +} diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp index 18f177009c..981f665c12 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp @@ -9,14 +9,13 @@ namespace Web::CSS { -void StyleSheetList::add_sheet(NonnullRefPtr<CSSStyleSheet> sheet) +void StyleSheetList::add_sheet(CSSStyleSheet& sheet) { - VERIFY(!m_sheets.contains_slow(sheet)); - sheet->set_style_sheet_list({}, this); - m_sheets.append(sheet); + sheet.set_style_sheet_list({}, this); + m_sheets.append(JS::make_handle(sheet)); m_document.style_computer().invalidate_rule_cache(); - m_document.style_computer().load_fonts_from_sheet(*sheet); + m_document.style_computer().load_fonts_from_sheet(sheet); m_document.invalidate_style(); } diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h index 098936ffd0..1ed54bf9f7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h @@ -26,17 +26,17 @@ public: return adopt_ref(*new StyleSheetList(document)); } - void add_sheet(NonnullRefPtr<CSSStyleSheet>); + void add_sheet(CSSStyleSheet&); void remove_sheet(CSSStyleSheet&); - NonnullRefPtrVector<CSSStyleSheet> const& sheets() const { return m_sheets; } - NonnullRefPtrVector<CSSStyleSheet>& sheets() { return m_sheets; } + Vector<JS::Handle<CSSStyleSheet>> const& sheets() const { return m_sheets; } + Vector<JS::Handle<CSSStyleSheet>>& sheets() { return m_sheets; } - RefPtr<CSSStyleSheet> item(size_t index) const + CSSStyleSheet* item(size_t index) const { if (index >= m_sheets.size()) return {}; - return m_sheets[index]; + return const_cast<CSSStyleSheet*>(m_sheets[index].cell()); } size_t length() const { return m_sheets.size(); } @@ -50,7 +50,7 @@ private: explicit StyleSheetList(DOM::Document&); DOM::Document& m_document; - NonnullRefPtrVector<CSSStyleSheet> m_sheets; + Vector<JS::Handle<CSSStyleSheet>> m_sheets; }; } |