From 5d60212076f05fd85607e05e1496ad009dcf501b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 7 Aug 2022 13:14:54 +0200 Subject: [PATCH] LibWeb: Make StyleSheet and CSSStyleSheet GC-allocated --- .../LibWeb/WrapperGenerator/IDLGenerators.cpp | 15 +++++ .../Libraries/LibWeb/Bindings/WindowObject.h | 2 + .../Libraries/LibWeb/CSS/CSSImportRule.cpp | 4 +- Userland/Libraries/LibWeb/CSS/CSSImportRule.h | 11 ++-- .../Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 15 ++++- Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h | 19 +++---- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 23 +++++--- Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 9 ++- .../Libraries/LibWeb/CSS/StyleComputer.cpp | 22 ++++---- Userland/Libraries/LibWeb/CSS/StyleSheet.cpp | 13 +++++ Userland/Libraries/LibWeb/CSS/StyleSheet.h | 22 +++++--- .../Libraries/LibWeb/CSS/StyleSheetList.cpp | 9 ++- .../Libraries/LibWeb/CSS/StyleSheetList.h | 12 ++-- Userland/Libraries/LibWeb/DOM/Document.cpp | 9 ++- Userland/Libraries/LibWeb/DOM/Document.h | 5 ++ Userland/Libraries/LibWeb/Forward.h | 2 - .../Libraries/LibWeb/HTML/HTMLLinkElement.cpp | 4 +- .../LibWeb/HTML/HTMLStyleElement.cpp | 55 ++++++++++--------- .../Libraries/LibWeb/HTML/HTMLStyleElement.h | 5 +- Userland/Libraries/LibWeb/idl_files.cmake | 4 +- .../WebContent/ConnectionFromClient.cpp | 2 +- 21 files changed, 166 insertions(+), 96 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp index db4282b912..b8b55ef9b0 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp @@ -73,9 +73,24 @@ static StringView sequence_storage_type_to_cpp_storage_type_name(SequenceStorage } } +static bool impl_is_wrapper(Type const& type) +{ + if (type.name == "StyleSheet"sv) + return true; + + if (type.name == "CSSStyleSheet"sv) + return true; + + return false; +} + CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface) { if (is_wrappable_type(type)) { + if (impl_is_wrapper(type)) { + return { .name = String::formatted("JS::Handle<{}>", type.name), .sequence_storage_type = SequenceStorageType::MarkedVector }; + } + if (type.nullable) return { .name = String::formatted("RefPtr<{}>", type.name), .sequence_storage_type = SequenceStorageType::Vector }; diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.h b/Userland/Libraries/LibWeb/Bindings/WindowObject.h index 7e7a8bac78..b3bd2e61f5 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.h @@ -36,6 +36,8 @@ public: virtual void initialize(JS::Realm&) override; virtual ~WindowObject() override = default; + JS::Realm& realm() const { return shape().realm(); } + HTML::Window& impl() { return *m_impl; } const HTML::Window& impl() const { return *m_impl; } 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 +#include #include #include #include @@ -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 loaded_style_sheet() { return m_style_sheet; } - RefPtr const loaded_style_sheet() const { return m_style_sheet; } - NonnullRefPtr style_sheet_for_bindings() { return *m_style_sheet; } - void set_style_sheet(RefPtr 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 m_document; Optional m_document_load_event_delayer; - RefPtr m_style_sheet; + JS::Handle 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 + * Copyright (c) 2019-2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -12,9 +13,17 @@ namespace Web::CSS { -CSSStyleSheet::CSSStyleSheet(NonnullRefPtrVector rules, Optional location) - : m_rules(CSSRuleList::create(move(rules))) +CSSStyleSheet* CSSStyleSheet::create(Bindings::WindowObject& window_object, NonnullRefPtrVector rules, Optional location) { + return window_object.heap().allocate(window_object.realm(), window_object, move(rules), move(location)); +} + +CSSStyleSheet::CSSStyleSheet(Bindings::WindowObject& window_object, NonnullRefPtrVector rules, Optional location) + : StyleSheet(window_object) + , m_rules(CSSRuleList::create(move(rules))) +{ + set_prototype(&window_object.ensure_web_prototype("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 { + JS_OBJECT(CSSStyleSheet, StyleSheet); + public: - using WrapperType = Bindings::CSSStyleSheetWrapper; - - static NonnullRefPtr create(NonnullRefPtrVector rules, Optional location) - { - return adopt_ref(*new CSSStyleSheet(move(rules), move(location))); - } + static CSSStyleSheet* create(Bindings::WindowObject&, NonnullRefPtrVector rules, Optional location); + explicit CSSStyleSheet(Bindings::WindowObject&, NonnullRefPtrVector, Optional 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*); private: - explicit CSSStyleSheet(NonnullRefPtrVector, Optional location); - NonnullRefPtr m_rules; WeakPtr 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 #include #include +#include #include #include #include @@ -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& tokens, Opti } // https://www.w3.org/TR/css-syntax-3/#parse-a-css-stylesheet -NonnullRefPtr Parser::parse_as_css_stylesheet(Optional location) +CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional location) { // To parse a CSS stylesheet, first parse a stylesheet. auto style_sheet = parse_a_stylesheet(m_token_stream, {}); @@ -193,7 +202,7 @@ NonnullRefPtr Parser::parse_as_css_stylesheet(Optional l rules.append(*rule); } - return CSSStyleSheet::create(move(rules), move(location)); + return CSSStyleSheet::create(m_context.window_object(), move(rules), move(location)); } Optional Parser::parse_as_selector(SelectorParsingMode parsing_mode) @@ -6373,10 +6382,10 @@ TimePercentage Parser::Dimension::time_percentage() const namespace Web { -RefPtr parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional location) +CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional 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 parse_as_css_stylesheet(Optional location); + CSSStyleSheet* parse_as_css_stylesheet(Optional location); RefPtr parse_as_style_attribute(DOM::Element&); RefPtr parse_as_css_rule(); Optional parse_as_supports_condition(); @@ -416,7 +419,7 @@ private: namespace Web { -RefPtr parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional location = {}); +CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, StringView, Optional location = {}); RefPtr parse_css_style_attribute(CSS::Parser::ParsingContext const&, StringView, DOM::Element&); RefPtr parse_css_value(CSS::Parser::ParsingContext const&, StringView, CSS::PropertyID property_id = CSS::PropertyID::Invalid); Optional 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> mutable m_cached_fonts; }; -static StyleSheet& default_stylesheet() +static CSSStyleSheet& default_stylesheet() { - static StyleSheet* sheet; - if (!sheet) { + static JS::Handle 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 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 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(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(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 +#include #include #include #include namespace Web::CSS { +StyleSheet::StyleSheet(Bindings::WindowObject& window_object) + : PlatformObject(window_object.ensure_web_prototype("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 -#include +#include #include namespace Web::CSS { -class StyleSheet - : public RefCounted - , 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 m_owner_node; - WeakPtr 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 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); + void add_sheet(CSSStyleSheet&); void remove_sheet(CSSStyleSheet&); - NonnullRefPtrVector const& sheets() const { return m_sheets; } - NonnullRefPtrVector& sheets() { return m_sheets; } + Vector> const& sheets() const { return m_sheets; } + Vector>& sheets() { return m_sheets; } - RefPtr item(size_t index) const + CSSStyleSheet* item(size_t index) const { if (index >= m_sheets.size()) return {}; - return m_sheets[index]; + return const_cast(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 m_sheets; + Vector> m_sheets; }; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index b80cd11415..311ed5f600 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1610,7 +1610,7 @@ void Document::evaluate_media_rules() { bool any_media_queries_changed_match_state = false; for (auto& style_sheet : style_sheets().sheets()) { - if (style_sheet.evaluate_media_queries(window())) + if (style_sheet->evaluate_media_queries(window())) any_media_queries_changed_match_state = true; } @@ -1837,4 +1837,11 @@ void Document::set_window(Badge, HTML::Window& window) m_window = window; } +Bindings::WindowObject& Document::preferred_window_object() const +{ + if (m_window && m_window->wrapper()) + return const_cast(*m_window->wrapper()); + return Bindings::main_thread_internal_window_object(); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 36b971930f..458018fc82 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -58,6 +58,11 @@ public: static NonnullRefPtr create_with_global_object(Bindings::WindowObject&); virtual ~Document() override; + // NOTE: This returns the web-facing window object if there is one, + // otherwise it returns the internal window object. + // FIXME: Remove this when Document is a JS::Object. + Bindings::WindowObject& preferred_window_object() const; + size_t next_layout_node_serial_id(Badge) { return m_next_layout_node_serial_id++; } size_t layout_node_count() const { return m_next_layout_node_serial_id; } diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index b852bc722c..cbb297d8ee 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -468,7 +468,6 @@ class CSSRuleListWrapper; class CSSRuleWrapper; class CSSStyleDeclarationWrapper; class CSSStyleRuleWrapper; -class CSSStyleSheetWrapper; class CSSSupportsRuleWrapper; class CustomEventWrapper; class DocumentFragmentWrapper; @@ -603,7 +602,6 @@ class SelectionWrapper; class StaticRangeWrapper; class StorageWrapper; class StyleSheetListWrapper; -class StyleSheetWrapper; class SubmitEventWrapper; class SubtleCryptoWrapper; class SVGAnimatedLengthWrapper; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 5684d6a70b..345011dcc5 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -126,14 +126,14 @@ void HTMLLinkElement::resource_did_load_stylesheet() } } - auto sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(document(), resource()->url()), resource()->encoded_data()); + auto* sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(document(), resource()->url()), resource()->encoded_data()); if (!sheet) { dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Failed to parse stylesheet: {}", resource()->url()); return; } sheet->set_owner_node(this); - document().style_sheets().add_sheet(sheet.release_nonnull()); + document().style_sheets().add_sheet(*sheet); } void HTMLLinkElement::resource_did_load_favicon() diff --git a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp index 293e703873..f7655da00d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp @@ -38,27 +38,25 @@ void HTMLStyleElement::removed_from(Node* old_parent) } // https://www.w3.org/TR/cssom/#remove-a-css-style-sheet -static void remove_a_css_style_sheet(DOM::Document& document, NonnullRefPtr sheet) +static void remove_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet) { - VERIFY(sheet.ptr()); - // 1. Remove the CSS style sheet from the list of document or shadow root CSS style sheets. document.style_sheets().remove_sheet(sheet); // 2. Set the CSS style sheet’s parent CSS style sheet, owner node and owner CSS rule to null. - sheet->set_parent_css_style_sheet(nullptr); - sheet->set_owner_node(nullptr); - sheet->set_owner_css_rule(nullptr); + sheet.set_parent_css_style_sheet(nullptr); + sheet.set_owner_node(nullptr); + sheet.set_owner_css_rule(nullptr); } // https://www.w3.org/TR/cssom/#add-a-css-style-sheet -static void add_a_css_style_sheet(DOM::Document& document, NonnullRefPtr sheet) +static void add_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet) { // 1. Add the CSS style sheet to the list of document or shadow root CSS style sheets at the appropriate location. The remainder of these steps deal with the disabled flag. document.style_sheets().add_sheet(sheet); // 2. If the disabled flag is set, then return. - if (sheet->disabled()) + if (sheet.disabled()) return; // FIXME: 3. If the title is not the empty string, the alternate flag is unset, and preferred CSS style sheet set name is the empty string change the preferred CSS style sheet set name to the title. @@ -72,23 +70,23 @@ static void add_a_css_style_sheet(DOM::Document& document, NonnullRefPtr sheet) +static void create_a_css_style_sheet(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, String location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet) { // 1. Create a new CSS style sheet object and set its properties as specified. // FIXME: We receive `sheet` from the caller already. This is weird. - sheet->set_parent_css_style_sheet(parent_style_sheet); - sheet->set_owner_css_rule(owner_rule); - sheet->set_owner_node(owner_node); - sheet->set_type(move(type)); - sheet->set_media(move(media)); - sheet->set_title(move(title)); - sheet->set_alternate(alternate); - sheet->set_origin_clean(origin_clean); - sheet->set_location(move(location)); + sheet.set_parent_css_style_sheet(parent_style_sheet); + sheet.set_owner_css_rule(owner_rule); + sheet.set_owner_node(owner_node); + sheet.set_type(move(type)); + sheet.set_media(move(media)); + sheet.set_title(move(title)); + sheet.set_alternate(alternate); + sheet.set_origin_clean(origin_clean); + sheet.set_location(move(location)); // 2. Then run the add a CSS style sheet steps for the newly created CSS style sheet. - add_a_css_style_sheet(document, move(sheet)); + add_a_css_style_sheet(document, sheet); } // The user agent must run the "update a style block" algorithm whenever one of the following conditions occur: @@ -106,11 +104,11 @@ void HTMLStyleElement::update_a_style_block() // 1. Let element be the style element. // 2. If element has an associated CSS style sheet, remove the CSS style sheet in question. - if (m_associated_css_style_sheet) { + if (m_associated_css_style_sheet.cell()) { remove_a_css_style_sheet(document(), *m_associated_css_style_sheet); // FIXME: This should probably be handled by StyleSheet::set_owner_node(). - m_associated_css_style_sheet = nullptr; + m_associated_css_style_sheet = {}; } // 3. If element is not connected, then return. @@ -131,7 +129,7 @@ void HTMLStyleElement::update_a_style_block() return; // FIXME: This should probably be handled by StyleSheet::set_owner_node(). - m_associated_css_style_sheet = sheet; + m_associated_css_style_sheet = JS::make_handle(sheet); // 6. Create a CSS style sheet with the following properties... create_a_css_style_sheet( @@ -145,14 +143,21 @@ void HTMLStyleElement::update_a_style_block() {}, nullptr, nullptr, - sheet.release_nonnull()); + *sheet); } // https://www.w3.org/TR/cssom/#dom-linkstyle-sheet -RefPtr HTMLStyleElement::sheet() const +CSS::CSSStyleSheet* HTMLStyleElement::sheet() { // The sheet attribute must return the associated CSS style sheet for the node or null if there is no associated CSS style sheet. - return m_associated_css_style_sheet; + return m_associated_css_style_sheet.cell(); +} + +// https://www.w3.org/TR/cssom/#dom-linkstyle-sheet +CSS::CSSStyleSheet const* HTMLStyleElement::sheet() const +{ + // The sheet attribute must return the associated CSS style sheet for the node or null if there is no associated CSS style sheet. + return m_associated_css_style_sheet.cell(); } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.h b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.h index 56261eaf01..e12d1dd3ec 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.h @@ -24,11 +24,12 @@ public: void update_a_style_block(); - RefPtr sheet() const; + CSS::CSSStyleSheet* sheet(); + CSS::CSSStyleSheet const* sheet() const; private: // https://www.w3.org/TR/cssom/#associated-css-style-sheet - RefPtr m_associated_css_style_sheet; + JS::Handle m_associated_css_style_sheet; }; } diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 9e91f119fd..5ed62a0f50 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -12,13 +12,13 @@ libweb_js_wrapper(CSS/CSSRule) libweb_js_wrapper(CSS/CSSRuleList) libweb_js_wrapper(CSS/CSSStyleDeclaration) libweb_js_wrapper(CSS/CSSStyleRule) -libweb_js_wrapper(CSS/CSSStyleSheet) +libweb_js_wrapper(CSS/CSSStyleSheet NO_INSTANCE) libweb_js_wrapper(CSS/CSSSupportsRule) libweb_js_wrapper(CSS/MediaList) libweb_js_wrapper(CSS/MediaQueryList) libweb_js_wrapper(CSS/MediaQueryListEvent) libweb_js_wrapper(CSS/Screen) -libweb_js_wrapper(CSS/StyleSheet) +libweb_js_wrapper(CSS/StyleSheet NO_INSTANCE) libweb_js_wrapper(CSS/StyleSheetList) libweb_js_wrapper(DOM/AbstractRange) libweb_js_wrapper(DOM/Attribute) diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index 901f56bd33..2276a0324b 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -206,7 +206,7 @@ void ConnectionFromClient::debug_request(String const& request, String const& ar if (request == "dump-style-sheets") { if (auto* doc = page().top_level_browsing_context().active_document()) { for (auto& sheet : doc->style_sheets().sheets()) { - Web::dump_sheet(sheet); + Web::dump_sheet(*sheet); } } }