diff options
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS')
32 files changed, 309 insertions, 160 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp index f6ac1a254b..cd10d45401 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp @@ -1,16 +1,20 @@ /* * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSConditionRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSConditionRule.h> namespace Web::CSS { -CSSConditionRule::CSSConditionRule(NonnullRefPtrVector<CSSRule>&& rules) - : CSSGroupingRule(move(rules)) +CSSConditionRule::CSSConditionRule(Bindings::WindowObject& window_object, CSSRuleList& rules) + : CSSGroupingRule(window_object, rules) { + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSConditionRulePrototype>("CSSConditionRule")); } void CSSConditionRule::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const diff --git a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h index 6cf61c2219..58d040a5ee 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h @@ -15,9 +15,10 @@ namespace Web::CSS { class CSSConditionRule : public CSSGroupingRule { AK_MAKE_NONCOPYABLE(CSSConditionRule); AK_MAKE_NONMOVABLE(CSSConditionRule); + JS_OBJECT(CSSConditionRule, CSSGroupingRule); public: - using WrapperType = Bindings::CSSConditionRuleWrapper; + CSSConditionRule& impl() { return *this; } virtual ~CSSConditionRule() = default; @@ -28,7 +29,12 @@ public: virtual void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const override; protected: - explicit CSSConditionRule(NonnullRefPtrVector<CSSRule>&&); + explicit CSSConditionRule(Bindings::WindowObject&, CSSRuleList&); }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSConditionRule& object) { return &object; } +using CSSConditionRuleWrapper = Web::CSS::CSSConditionRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.idl b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.idl index 73c336eaaa..ad01e7db8e 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.idl @@ -1,6 +1,6 @@ #import <CSS/CSSGroupingRule.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSConditionRule : CSSGroupingRule { attribute CSSOMString conditionText; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp index f001068142..f6b3f69086 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp @@ -1,16 +1,26 @@ /* * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSFontFaceRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSFontFaceRule.h> namespace Web::CSS { -CSSFontFaceRule::CSSFontFaceRule(FontFace&& font_face) - : m_font_face(move(font_face)) +CSSFontFaceRule* CSSFontFaceRule::create(Bindings::WindowObject& window_object, FontFace&& font_face) { + return window_object.heap().allocate<CSSFontFaceRule>(window_object.realm(), window_object, move(font_face)); +} + +CSSFontFaceRule::CSSFontFaceRule(Bindings::WindowObject& window_object, FontFace&& font_face) + : CSSRule(window_object) + , m_font_face(move(font_face)) +{ + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSFontFaceRulePrototype>("CSSFontFaceRule")); } CSSStyleDeclaration* CSSFontFaceRule::style() diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h index 80b8866dc3..5967add8fc 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -14,26 +15,21 @@ namespace Web::CSS { class CSSFontFaceRule final : public CSSRule { AK_MAKE_NONCOPYABLE(CSSFontFaceRule); AK_MAKE_NONMOVABLE(CSSFontFaceRule); + JS_OBJECT(CSSFontFaceRule, CSSRule); public: - using WrapperType = Bindings::CSSFontFaceRuleWrapper; - - static NonnullRefPtr<CSSFontFaceRule> create(FontFace&& font_face) - { - return adopt_ref(*new CSSFontFaceRule(move(font_face))); - } + static CSSFontFaceRule* create(Bindings::WindowObject&, FontFace&&); + explicit CSSFontFaceRule(Bindings::WindowObject&, FontFace&&); virtual ~CSSFontFaceRule() override = default; + CSSFontFaceRule& impl() { return *this; } - virtual StringView class_name() const override { return "CSSFontFaceRule"sv; } virtual Type type() const override { return Type::FontFace; } FontFace const& font_face() const { return m_font_face; } CSSStyleDeclaration* style(); private: - explicit CSSFontFaceRule(FontFace&&); - virtual String serialized() const override; FontFace m_font_face; @@ -43,3 +39,8 @@ template<> inline bool CSSRule::fast_is<CSSFontFaceRule>() const { return type() == CSSRule::Type::FontFace; } } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSFontFaceRule& object) { return &object; } +using CSSFontFaceRuleWrapper = Web::CSS::CSSFontFaceRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl index cf5701a19b..3dd9926ec3 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl @@ -1,7 +1,7 @@ #import <CSS/CSSRule.idl> #import <CSS/CSSStyleDeclaration.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSFontFaceRule : CSSRule { readonly attribute CSSStyleDeclaration style; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp index bb214da973..e852b1ff44 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp @@ -1,45 +1,55 @@ /* * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSGroupingRulePrototype.h> #include <LibWeb/Bindings/MainThreadVM.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSGroupingRule.h> #include <LibWeb/CSS/CSSRuleList.h> namespace Web::CSS { -CSSGroupingRule::CSSGroupingRule(NonnullRefPtrVector<CSSRule>&& rules) - // FIXME: Use the same window object for the rule list. - : m_rules(JS::make_handle(CSSRuleList::create(Bindings::main_thread_internal_window_object(), move(rules)))) +CSSGroupingRule::CSSGroupingRule(Bindings::WindowObject& window_object, CSSRuleList& rules) + : CSSRule(window_object) + , m_rules(rules) { - for (auto& rule : *m_rules) + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSGroupingRulePrototype>("CSSGroupingRule")); + for (auto& rule : m_rules) rule.set_parent_rule(this); } +void CSSGroupingRule::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(&m_rules); +} + DOM::ExceptionOr<u32> CSSGroupingRule::insert_rule(StringView rule, u32 index) { - TRY(m_rules->insert_a_css_rule(rule, index)); + TRY(m_rules.insert_a_css_rule(rule, index)); // NOTE: The spec doesn't say where to set the parent rule, so we'll do it here. - m_rules->item(index)->set_parent_rule(this); + m_rules.item(index)->set_parent_rule(this); return index; } DOM::ExceptionOr<void> CSSGroupingRule::delete_rule(u32 index) { - return m_rules->remove_a_css_rule(index); + return m_rules.remove_a_css_rule(index); } void CSSGroupingRule::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const { - m_rules->for_each_effective_style_rule(callback); + m_rules.for_each_effective_style_rule(callback); } void CSSGroupingRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet) { CSSRule::set_parent_style_sheet(parent_style_sheet); - for (auto& rule : *m_rules) + for (auto& rule : m_rules) rule.set_parent_style_sheet(parent_style_sheet); } diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h index 19dae632d3..271572d226 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h @@ -17,15 +17,16 @@ namespace Web::CSS { class CSSGroupingRule : public CSSRule { AK_MAKE_NONCOPYABLE(CSSGroupingRule); AK_MAKE_NONMOVABLE(CSSGroupingRule); + JS_OBJECT(CSSGroupingRule, CSSRule); public: - using WrapperType = Bindings::CSSGroupingRuleWrapper; + CSSGroupingRule& impl() { return *this; } virtual ~CSSGroupingRule() = default; - CSSRuleList const& css_rules() const { return *m_rules; } - CSSRuleList& css_rules() { return *m_rules; } - CSSRuleList* css_rules_for_bindings() { return m_rules.cell(); } + CSSRuleList const& css_rules() const { return m_rules; } + CSSRuleList& css_rules() { return m_rules; } + CSSRuleList* css_rules_for_bindings() { return &m_rules; } DOM::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0); DOM::ExceptionOr<void> delete_rule(u32 index); @@ -34,10 +35,17 @@ public: virtual void set_parent_style_sheet(CSSStyleSheet*) override; protected: - explicit CSSGroupingRule(NonnullRefPtrVector<CSSRule>&&); + explicit CSSGroupingRule(Bindings::WindowObject&, CSSRuleList&); private: - JS::Handle<CSSRuleList> m_rules; + virtual void visit_edges(Cell::Visitor&) override; + + CSSRuleList& m_rules; }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSGroupingRule& object) { return &object; } +using CSSGroupingRuleWrapper = Web::CSS::CSSGroupingRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.idl b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.idl index 6f8280a0fd..7a1c3e3d00 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.idl @@ -1,7 +1,7 @@ #import <CSS/CSSRule.idl> #import <CSS/CSSRuleList.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSGroupingRule : CSSRule { [SameObject, ImplementedAs=css_rules_for_bindings] readonly attribute CSSRuleList cssRules; unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0); diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp index 61ea65e7bc..52c25953bb 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp @@ -1,12 +1,15 @@ /* * Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <AK/Debug.h> #include <AK/URL.h> +#include <LibWeb/Bindings/CSSImportRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/DOM/Document.h> @@ -14,10 +17,19 @@ namespace Web::CSS { +CSSImportRule* CSSImportRule::create(AK::URL url, DOM::Document& document) +{ + auto& window_object = document.preferred_window_object(); + return window_object.heap().allocate<CSSImportRule>(window_object.realm(), move(url), document); +} + CSSImportRule::CSSImportRule(AK::URL url, DOM::Document& document) - : m_url(move(url)) + : CSSRule(document.preferred_window_object()) + , m_url(move(url)) , m_document(document) { + set_prototype(&document.preferred_window_object().ensure_web_prototype<Bindings::CSSImportRulePrototype>("CSSImportRule")); + dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Loading import URL: {}", m_url); auto request = LoadRequest::create_for_url_on_page(m_url, document.page()); @@ -28,6 +40,12 @@ CSSImportRule::CSSImportRule(AK::URL url, DOM::Document& document) set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); } +void CSSImportRule::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_style_sheet); +} + // https://www.w3.org/TR/cssom/#serialize-a-css-rule String CSSImportRule::serialized() const { @@ -79,7 +97,7 @@ void CSSImportRule::resource_did_load() return; } - m_style_sheet = JS::make_handle(sheet); + m_style_sheet = 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 abe16dfb73..ac2cb26a38 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -20,32 +21,30 @@ class CSSImportRule final , public ResourceClient { AK_MAKE_NONCOPYABLE(CSSImportRule); AK_MAKE_NONMOVABLE(CSSImportRule); + JS_OBJECT(CSSImportRule, CSSRule); public: - using WrapperType = Bindings::CSSImportRuleWrapper; - - static NonnullRefPtr<CSSImportRule> create(AK::URL url, DOM::Document& document) - { - return adopt_ref(*new CSSImportRule(move(url), document)); - } + static CSSImportRule* create(AK::URL, DOM::Document&); + CSSImportRule(AK::URL, DOM::Document&); virtual ~CSSImportRule() = default; + CSSImportRule& impl() { return *this; } + AK::URL const& url() const { return m_url; } // FIXME: This should return only the specified part of the url. eg, "stuff/foo.css", not "https://example.com/stuff/foo.css". String href() const { return m_url.to_string(); } - bool has_import_result() const { return !m_style_sheet.is_null(); } - 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); } + bool has_import_result() const { return !m_style_sheet; } + CSSStyleSheet* loaded_style_sheet() { return m_style_sheet; } + CSSStyleSheet const* loaded_style_sheet() const { return m_style_sheet; } + CSSStyleSheet* style_sheet_for_bindings() { return m_style_sheet; } + void set_style_sheet(CSSStyleSheet* style_sheet) { m_style_sheet = style_sheet; } - virtual StringView class_name() const override { return "CSSImportRule"sv; }; virtual Type type() const override { return Type::Import; }; private: - explicit CSSImportRule(AK::URL, DOM::Document&); + virtual void visit_edges(Cell::Visitor&) override; virtual String serialized() const override; @@ -56,10 +55,15 @@ private: AK::URL m_url; WeakPtr<DOM::Document> m_document; Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer; - JS::Handle<CSSStyleSheet> m_style_sheet; + CSSStyleSheet* m_style_sheet { nullptr }; }; template<> inline bool CSSRule::fast_is<CSSImportRule>() const { return type() == CSSRule::Type::Import; } } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSImportRule& object) { return &object; } +using CSSImportRuleWrapper = Web::CSS::CSSImportRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.idl b/Userland/Libraries/LibWeb/CSS/CSSImportRule.idl index 838e64d77a..e274ff93b8 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.idl @@ -2,7 +2,7 @@ #import <CSS/CSSStyleSheet.idl> #import <CSS/MediaList.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSImportRule : CSSRule { readonly attribute USVString href; // [SameObject, PutForwards=mediaText] readonly attribute MediaList media; diff --git a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp index 3e5361817e..698e563fa6 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp @@ -1,17 +1,26 @@ /* * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSMediaRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSMediaRule.h> namespace Web::CSS { -CSSMediaRule::CSSMediaRule(NonnullRefPtr<MediaList>&& media, NonnullRefPtrVector<CSSRule>&& rules) - : CSSConditionRule(move(rules)) +CSSMediaRule* CSSMediaRule::create(Bindings::WindowObject& window_object, NonnullRefPtr<MediaList>&& media_queries, CSSRuleList& rules) +{ + return window_object.heap().allocate<CSSMediaRule>(window_object.realm(), window_object, move(media_queries), rules); +} + +CSSMediaRule::CSSMediaRule(Bindings::WindowObject& window_object, NonnullRefPtr<MediaList>&& media, CSSRuleList& rules) + : CSSConditionRule(window_object, rules) , m_media(move(media)) { + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSMediaRulePrototype>("CSSMediaRule")); } String CSSMediaRule::condition_text() const diff --git a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h index 3bd7214243..f3563660d2 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,18 +17,16 @@ namespace Web::CSS { class CSSMediaRule final : public CSSConditionRule { AK_MAKE_NONCOPYABLE(CSSMediaRule); AK_MAKE_NONMOVABLE(CSSMediaRule); + JS_OBJECT(CSSMediaRule, CSSConditionRule); public: - using WrapperType = Bindings::CSSMediaRuleWrapper; + CSSMediaRule& impl() { return *this; } - static NonnullRefPtr<CSSMediaRule> create(NonnullRefPtr<MediaList>&& media_queries, NonnullRefPtrVector<CSSRule>&& rules) - { - return adopt_ref(*new CSSMediaRule(move(media_queries), move(rules))); - } + static CSSMediaRule* create(Bindings::WindowObject&, NonnullRefPtr<MediaList>&& media_queries, CSSRuleList&); + explicit CSSMediaRule(Bindings::WindowObject&, NonnullRefPtr<MediaList>&&, CSSRuleList&); virtual ~CSSMediaRule() = default; - virtual StringView class_name() const override { return "CSSMediaRule"sv; }; virtual Type type() const override { return Type::Media; }; virtual String condition_text() const override; @@ -39,8 +38,6 @@ public: bool evaluate(HTML::Window const& window) { return m_media->evaluate(window); } private: - explicit CSSMediaRule(NonnullRefPtr<MediaList>&&, NonnullRefPtrVector<CSSRule>&&); - virtual String serialized() const override; NonnullRefPtr<MediaList> m_media; @@ -50,3 +47,8 @@ template<> inline bool CSSRule::fast_is<CSSMediaRule>() const { return type() == CSSRule::Type::Media; } } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSMediaRule& object) { return &object; } +using CSSMediaRuleWrapper = Web::CSS::CSSMediaRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl index 72e3c55454..60fda190c1 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl @@ -1,7 +1,7 @@ #import <CSS/CSSConditionRule.idl> #import <CSS/MediaList.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSMediaRule : CSSConditionRule { [SameObject, PutForwards=mediaText] readonly attribute MediaList media; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp index bd1b94493a..b3c8fcf351 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp @@ -1,15 +1,30 @@ /* * Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/CSSStyleSheet.h> namespace Web::CSS { +CSSRule::CSSRule(Bindings::WindowObject& window_object) + : PlatformObject(window_object.ensure_web_prototype<Bindings::CSSRulePrototype>("CSSRule")) +{ +} + +void CSSRule::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_parent_style_sheet.ptr()); + visitor.visit(m_parent_rule.ptr()); +} + // https://www.w3.org/TR/cssom/#dom-cssrule-csstext String CSSRule::css_text() const { diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.h b/Userland/Libraries/LibWeb/CSS/CSSRule.h index 986dc3a6e6..7b82ba62ce 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.h @@ -1,27 +1,25 @@ /* * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include <AK/RefCounted.h> #include <AK/String.h> -#include <AK/Weakable.h> -#include <LibWeb/Bindings/Wrappable.h> +#include <LibJS/Heap/GCPtr.h> +#include <LibWeb/Bindings/PlatformObject.h> #include <LibWeb/CSS/CSSStyleDeclaration.h> #include <LibWeb/CSS/Selector.h> namespace Web::CSS { -class CSSRule - : public RefCounted<CSSRule> - , public Bindings::Wrappable - , public Weakable<CSSRule> { -public: - using WrapperType = Bindings::CSSRuleWrapper; +class CSSRule : public Bindings::PlatformObject { + JS_OBJECT(CSSRule, JS::Object); +public: + CSSRule& impl() { return *this; } virtual ~CSSRule() = default; // https://drafts.csswg.org/cssom/#dom-cssrule-type @@ -33,26 +31,34 @@ public: Supports = 12, }; - virtual StringView class_name() const = 0; virtual Type type() const = 0; String css_text() const; void set_css_text(StringView); - CSSRule* parent_rule() { return m_parent_rule; } + CSSRule* parent_rule() { return m_parent_rule.ptr(); } void set_parent_rule(CSSRule*); - CSSStyleSheet* parent_style_sheet() { return m_parent_style_sheet; } + CSSStyleSheet* parent_style_sheet() { return m_parent_style_sheet.ptr(); } virtual void set_parent_style_sheet(CSSStyleSheet*); template<typename T> bool fast_is() const = delete; protected: + explicit CSSRule(Bindings::WindowObject&); + virtual String serialized() const = 0; - WeakPtr<CSSRule> m_parent_rule; - WeakPtr<CSSStyleSheet> m_parent_style_sheet; + virtual void visit_edges(Cell::Visitor&) override; + + JS::GCPtr<CSSRule> m_parent_rule; + JS::GCPtr<CSSStyleSheet> m_parent_style_sheet; }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSRule& object) { return &object; } +using CSSRuleWrapper = Web::CSS::CSSRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.idl b/Userland/Libraries/LibWeb/CSS/CSSRule.idl index bd40b41bd6..e7e262bc32 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.idl @@ -1,6 +1,6 @@ #import <CSS/CSSStyleSheet.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSRule { attribute CSSOMString cssText; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index b076c58feb..8aa7bf293c 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -9,23 +9,38 @@ #include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSMediaRule.h> +#include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/CSSRuleList.h> #include <LibWeb/CSS/CSSSupportsRule.h> #include <LibWeb/CSS/Parser/Parser.h> namespace Web::CSS { -CSSRuleList* CSSRuleList::create(Bindings::WindowObject& window_object, NonnullRefPtrVector<Web::CSS::CSSRule>&& rules) +CSSRuleList* CSSRuleList::create(Bindings::WindowObject& window_object, JS::MarkedVector<CSSRule*> const& rules) { - return window_object.heap().allocate<CSSRuleList>(window_object.realm(), window_object, move(rules)); + auto* rule_list = window_object.heap().allocate<CSSRuleList>(window_object.realm(), window_object); + for (auto* rule : rules) + rule_list->m_rules.append(*rule); + return rule_list; } -CSSRuleList::CSSRuleList(Bindings::WindowObject& window_object, NonnullRefPtrVector<CSSRule>&& rules) +CSSRuleList::CSSRuleList(Bindings::WindowObject& window_object) : Bindings::LegacyPlatformObject(window_object.ensure_web_prototype<Bindings::CSSRuleListPrototype>("CSSRuleList")) - , m_rules(move(rules)) { } +CSSRuleList* CSSRuleList::create_empty(Bindings::WindowObject& window_object) +{ + return window_object.heap().allocate<CSSRuleList>(window_object.realm(), window_object); +} + +void CSSRuleList::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + for (auto& rule : m_rules) + visitor.visit(&rule); +} + bool CSSRuleList::is_supported_property_index(u32 index) const { // The object’s supported property indices are the numbers in the range zero to one less than the number of CSSRule objects represented by the collection. @@ -34,7 +49,7 @@ bool CSSRuleList::is_supported_property_index(u32 index) const } // https://www.w3.org/TR/cssom/#insert-a-css-rule -DOM::ExceptionOr<unsigned> CSSRuleList::insert_a_css_rule(Variant<StringView, NonnullRefPtr<CSSRule>> rule, u32 index) +DOM::ExceptionOr<unsigned> CSSRuleList::insert_a_css_rule(Variant<StringView, CSSRule*> rule, u32 index) { // 1. Set length to the number of items in list. auto length = m_rules.size(); @@ -47,11 +62,13 @@ DOM::ExceptionOr<unsigned> CSSRuleList::insert_a_css_rule(Variant<StringView, No // NOTE: The insert-a-css-rule spec expects `rule` to be a string, but the CSSStyleSheet.insertRule() // spec calls this algorithm with an already-parsed CSSRule. So, we use a Variant and skip step 3 // if that variant holds a CSSRule already. - RefPtr<CSSRule> new_rule; + CSSRule* new_rule = nullptr; if (rule.has<StringView>()) { - new_rule = parse_css_rule(CSS::Parser::ParsingContext {}, rule.get<StringView>()); + new_rule = parse_css_rule( + CSS::Parser::ParsingContext { static_cast<Bindings::WindowObject&>(global_object()) }, + rule.get<StringView>()); } else { - new_rule = rule.get<NonnullRefPtr<CSSRule>>(); + new_rule = rule.get<CSSRule*>(); } // 4. If new rule is a syntax error, throw a SyntaxError exception. @@ -63,7 +80,7 @@ DOM::ExceptionOr<unsigned> CSSRuleList::insert_a_css_rule(Variant<StringView, No // FIXME: 6. If new rule is an @namespace at-rule, and list contains anything other than @import at-rules, and @namespace at-rules, throw an InvalidStateError exception. // 7. Insert new rule into list at the zero-indexed position index. - m_rules.insert(index, new_rule.release_nonnull()); + m_rules.insert(index, *new_rule); // 8. Return index. return index; @@ -80,7 +97,7 @@ DOM::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index) return DOM::IndexSizeError::create("CSS rule index out of bounds."); // 3. Set old rule to the indexth item in list. - NonnullRefPtr<CSSRule> old_rule = m_rules[index]; + CSSRule& old_rule = m_rules[index]; // FIXME: 4. If old rule is an @namespace at-rule, and list contains anything other than @import at-rules, and @namespace at-rules, throw an InvalidStateError exception. @@ -88,8 +105,8 @@ DOM::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index) m_rules.remove(index); // 6. Set old rule’s parent CSS rule and parent CSS style sheet to null. - old_rule->set_parent_rule(nullptr); - old_rule->set_parent_style_sheet(nullptr); + old_rule.set_parent_rule(nullptr); + old_rule.set_parent_style_sheet(nullptr); return {}; } @@ -102,7 +119,7 @@ void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const break; case CSSRule::Type::Import: { auto const& import_rule = static_cast<CSSImportRule const&>(rule); - if (import_rule.has_import_result()) + if (import_rule.has_import_result() && import_rule.loaded_style_sheet()) import_rule.loaded_style_sheet()->for_each_effective_style_rule(callback); break; } @@ -129,7 +146,7 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window) break; case CSSRule::Type::Import: { auto& import_rule = verify_cast<CSSImportRule>(rule); - if (import_rule.has_import_result() && import_rule.loaded_style_sheet()->evaluate_media_queries(window)) + if (import_rule.has_import_result() && import_rule.loaded_style_sheet() && import_rule.loaded_style_sheet()->evaluate_media_queries(window)) any_media_queries_changed_match_state = true; break; } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h index af4157f61b..9f94bcc1d4 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h @@ -25,20 +25,30 @@ class CSSRuleList : public Bindings::LegacyPlatformObject { public: CSSRuleList& impl() { return *this; } - static CSSRuleList* create(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>&& rules); - CSSRuleList(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>&&); + static CSSRuleList* create(Bindings::WindowObject&, JS::MarkedVector<CSSRule*> const&); + static CSSRuleList* create_empty(Bindings::WindowObject&); + + explicit CSSRuleList(Bindings::WindowObject&); ~CSSRuleList() = default; - RefPtr<CSSRule> item(size_t index) const + CSSRule const* item(size_t index) const + { + if (index >= length()) + return nullptr; + return &m_rules[index]; + } + + CSSRule* item(size_t index) { if (index >= length()) return nullptr; - return m_rules[index]; + return &m_rules[index]; } + size_t length() const { return m_rules.size(); } - using ConstIterator = AK::SimpleIterator<AK::NonnullPtrVector<NonnullRefPtr<CSSRule>> const, CSSRule const>; - using Iterator = AK::SimpleIterator<AK::NonnullPtrVector<NonnullRefPtr<CSSRule>>, CSSRule>; + using ConstIterator = AK::SimpleIterator<Vector<CSSRule&> const, CSSRule const>; + using Iterator = AK::SimpleIterator<Vector<CSSRule&>, CSSRule>; ConstIterator const begin() const { return m_rules.begin(); } Iterator begin() { return m_rules.begin(); } @@ -50,19 +60,21 @@ public: virtual JS::Value item_value(size_t index) const override; DOM::ExceptionOr<void> remove_a_css_rule(u32 index); - DOM::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, NonnullRefPtr<CSSRule>>, u32 index); + DOM::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, CSSRule*>, u32 index); 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. bool evaluate_media_queries(HTML::Window const&); private: - NonnullRefPtrVector<CSSRule> m_rules; + virtual void visit_edges(Cell::Visitor&) override; + + Vector<CSSRule&> m_rules; }; } namespace Web::Bindings { -inline JS::Object* wrap(JS::GlobalObject&, Web::CSS::CSSRuleList& object) { return &object; } +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSRuleList& object) { return &object; } using CSSRuleListWrapper = Web::CSS::CSSRuleList; } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp index 9b6a2ad0c2..25757b1636 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp @@ -4,15 +4,24 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSStyleRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSStyleRule.h> #include <LibWeb/CSS/Parser/Parser.h> namespace Web::CSS { -CSSStyleRule::CSSStyleRule(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) - : m_selectors(move(selectors)) +CSSStyleRule* CSSStyleRule::create(Bindings::WindowObject& window_object, NonnullRefPtrVector<Web::CSS::Selector>&& selectors, NonnullRefPtr<Web::CSS::CSSStyleDeclaration>&& declaration) +{ + return window_object.heap().allocate<CSSStyleRule>(window_object.realm(), window_object, move(selectors), move(declaration)); +} + +CSSStyleRule::CSSStyleRule(Bindings::WindowObject& window_object, NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) + : CSSRule(window_object) + , m_selectors(move(selectors)) , m_declaration(move(declaration)) { + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSStyleRulePrototype>("CSSStyleRule")); } // https://www.w3.org/TR/cssom/#dom-cssstylerule-style diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h index 090c15db1f..cff6461137 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h @@ -16,23 +16,21 @@ namespace Web::CSS { class CSSStyleRule final : public CSSRule { + JS_OBJECT(CSSStyleRule, CSSRule); AK_MAKE_NONCOPYABLE(CSSStyleRule); AK_MAKE_NONMOVABLE(CSSStyleRule); public: - using WrapperType = Bindings::CSSStyleRuleWrapper; - - static NonnullRefPtr<CSSStyleRule> create(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) - { - return adopt_ref(*new CSSStyleRule(move(selectors), move(declaration))); - } + static CSSStyleRule* create(Bindings::WindowObject&, NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&); + CSSStyleRule(Bindings::WindowObject&, NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&); virtual ~CSSStyleRule() override = default; + CSSStyleRule& impl() { return *this; } + NonnullRefPtrVector<Selector> const& selectors() const { return m_selectors; } CSSStyleDeclaration const& declaration() const { return m_declaration; } - virtual StringView class_name() const override { return "CSSStyleRule"sv; }; virtual Type type() const override { return Type::Style; }; String selector_text() const; @@ -41,8 +39,6 @@ public: CSSStyleDeclaration* style(); private: - CSSStyleRule(NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&); - virtual String serialized() const override; NonnullRefPtrVector<Selector> m_selectors; @@ -53,3 +49,8 @@ template<> inline bool CSSRule::fast_is<CSSStyleRule>() const { return type() == CSSRule::Type::Style; } } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSStyleRule& object) { return &object; } +using CSSStyleRuleWrapper = Web::CSS::CSSStyleRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.idl b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.idl index 5e4708a6e6..2d6a8dc214 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.idl @@ -1,6 +1,7 @@ #import <CSS/CSSRule.idl> #import <CSS/CSSStyleDeclaration.idl> +[Exposed=Window, NoInstanceWrapper] interface CSSStyleRule : CSSRule { attribute CSSOMString selectorText; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index dd0e33c731..1828e30f62 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -13,14 +13,14 @@ namespace Web::CSS { -CSSStyleSheet* CSSStyleSheet::create(Bindings::WindowObject& window_object, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) +CSSStyleSheet* CSSStyleSheet::create(Bindings::WindowObject& window_object, CSSRuleList& rules, Optional<AK::URL> location) { - return window_object.heap().allocate<CSSStyleSheet>(window_object.realm(), window_object, move(rules), move(location)); + return window_object.heap().allocate<CSSStyleSheet>(window_object.realm(), window_object, rules, move(location)); } -CSSStyleSheet::CSSStyleSheet(Bindings::WindowObject& window_object, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location) +CSSStyleSheet::CSSStyleSheet(Bindings::WindowObject& window_object, CSSRuleList& rules, Optional<AK::URL> location) : StyleSheet(window_object) - , m_rules(CSSRuleList::create(window_object, move(rules))) + , m_rules(&rules) { set_prototype(&window_object.ensure_web_prototype<Bindings::CSSStyleSheetPrototype>("CSSStyleSheet")); @@ -35,6 +35,8 @@ void CSSStyleSheet::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_style_sheet_list.ptr()); + visitor.visit(m_rules); + visitor.visit(m_owner_css_rule); } // https://www.w3.org/TR/cssom/#dom-cssstylesheet-insertrule @@ -54,12 +56,11 @@ 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. - auto parsed_rule_nonnull = parsed_rule.release_nonnull(); - auto result = m_rules->insert_a_css_rule(parsed_rule_nonnull, index); + auto result = m_rules->insert_a_css_rule(parsed_rule, index); if (!result.is_exception()) { // NOTE: The spec doesn't say where to set the parent style sheet, so we'll do it here. - parsed_rule_nonnull->set_parent_style_sheet(this); + parsed_rule->set_parent_style_sheet(this); if (m_style_sheet_list) { m_style_sheet_list->document().style_computer().invalidate_rule_cache(); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 3dd08e1733..7712a13f3f 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -24,9 +24,9 @@ class CSSStyleSheet final JS_OBJECT(CSSStyleSheet, StyleSheet); public: - static CSSStyleSheet* create(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location); + static CSSStyleSheet* create(Bindings::WindowObject&, CSSRuleList& rules, Optional<AK::URL> location); - explicit CSSStyleSheet(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>, Optional<AK::URL> location); + explicit CSSStyleSheet(Bindings::WindowObject&, CSSRuleList&, Optional<AK::URL> location); virtual ~CSSStyleSheet() override = default; CSSStyleSheet& impl() { return *this; } @@ -57,9 +57,8 @@ private: CSSRuleList* m_rules { nullptr }; - WeakPtr<CSSRule> m_owner_css_rule; - JS::GCPtr<StyleSheetList> m_style_sheet_list; + CSSRule* m_owner_css_rule { nullptr }; }; } diff --git a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp index b00611f32e..602ca34768 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp @@ -4,15 +4,23 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/CSSSupportsRulePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/CSS/CSSSupportsRule.h> #include <LibWeb/CSS/Parser/Parser.h> namespace Web::CSS { -CSSSupportsRule::CSSSupportsRule(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules) - : CSSConditionRule(move(rules)) +CSSSupportsRule* CSSSupportsRule::create(Bindings::WindowObject& window_object, NonnullRefPtr<Supports>&& supports, CSSRuleList& rules) +{ + return window_object.heap().allocate<CSSSupportsRule>(window_object.realm(), window_object, move(supports), rules); +} + +CSSSupportsRule::CSSSupportsRule(Bindings::WindowObject& window_object, NonnullRefPtr<Supports>&& supports, CSSRuleList& rules) + : CSSConditionRule(window_object, rules) , m_supports(move(supports)) { + set_prototype(&window_object.ensure_web_prototype<Bindings::CSSSupportsRulePrototype>("CSSSupportsRule")); } String CSSSupportsRule::condition_text() const diff --git a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h index 6bc3b1ea4c..31e0dcac7b 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h @@ -17,20 +17,18 @@ namespace Web::CSS { // https://www.w3.org/TR/css-conditional-3/#the-csssupportsrule-interface class CSSSupportsRule final : public CSSConditionRule { + JS_OBJECT(CSSSupportsRule, CSSConditionRule); AK_MAKE_NONCOPYABLE(CSSSupportsRule); AK_MAKE_NONMOVABLE(CSSSupportsRule); public: - using WrapperType = Bindings::CSSSupportsRuleWrapper; - - static NonnullRefPtr<CSSSupportsRule> create(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules) - { - return adopt_ref(*new CSSSupportsRule(move(supports), move(rules))); - } + static CSSSupportsRule* create(Bindings::WindowObject&, NonnullRefPtr<Supports>&&, CSSRuleList&); + explicit CSSSupportsRule(Bindings::WindowObject&, NonnullRefPtr<Supports>&&, CSSRuleList&); virtual ~CSSSupportsRule() = default; - virtual StringView class_name() const override { return "CSSSupportsRule"sv; }; + CSSSupportsRule& impl() { return *this; } + virtual Type type() const override { return Type::Supports; }; String condition_text() const override; @@ -38,8 +36,6 @@ public: virtual bool condition_matches() const override { return m_supports->matches(); } private: - explicit CSSSupportsRule(NonnullRefPtr<Supports>&&, NonnullRefPtrVector<CSSRule>&&); - virtual String serialized() const override; NonnullRefPtr<Supports> m_supports; @@ -49,3 +45,8 @@ template<> inline bool CSSRule::fast_is<CSSSupportsRule>() const { return type() == CSSRule::Type::Supports; } } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::CSS::CSSSupportsRule& object) { return &object; } +using CSSSupportsRuleWrapper = Web::CSS::CSSSupportsRule; +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.idl b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.idl index f60b2a2ebf..f4e9fbb89d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSSupportsRule.idl @@ -1,5 +1,5 @@ #import <CSS/CSSConditionRule.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface CSSSupportsRule : CSSConditionRule { }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 359f58635e..e32ae4efdb 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -44,6 +44,11 @@ ParsingContext::ParsingContext() { } +ParsingContext::ParsingContext(Bindings::WindowObject& window_object) + : m_window_object(window_object) +{ +} + ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url) : m_window_object(document.preferred_window_object()) , m_document(&document) @@ -194,15 +199,16 @@ CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<AK::URL> location) auto style_sheet = parse_a_stylesheet(m_token_stream, {}); // Interpret all of the resulting top-level qualified rules as style rules, defined below. - NonnullRefPtrVector<CSSRule> rules; + JS::MarkedVector<CSSRule*> rules(m_context.window_object().heap()); for (auto& raw_rule : style_sheet.rules) { - auto rule = convert_to_rule(raw_rule); + auto* rule = convert_to_rule(raw_rule); // If any style rule is invalid, or any at-rule is not recognized or is invalid according to its grammar or context, it’s a parse error. Discard that rule. if (rule) - rules.append(*rule); + rules.append(rule); } - return CSSStyleSheet::create(m_context.window_object(), move(rules), move(location)); + auto* rule_list = CSSRuleList::create(m_context.window_object(), move(rules)); + return CSSStyleSheet::create(m_context.window_object(), *rule_list, move(location)); } Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode) @@ -2096,7 +2102,7 @@ Vector<DeclarationOrAtRule> Parser::consume_a_list_of_declarations(TokenStream<T } } -RefPtr<CSSRule> Parser::parse_as_css_rule() +CSSRule* Parser::parse_as_css_rule() { auto maybe_rule = parse_a_rule(m_token_stream); if (maybe_rule) @@ -2593,7 +2599,7 @@ RefPtr<StyleValue> Parser::parse_linear_gradient_function(ComponentValue const& return LinearGradientStyleValue::create(gradient_direction, move(color_stops), gradient_type, repeating_gradient); } -RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule) +CSSRule* Parser::convert_to_rule(NonnullRefPtr<Rule> rule) { if (rule->is_at_rule()) { if (has_ignored_vendor_prefix(rule->at_rule_name())) { @@ -2625,8 +2631,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule) if (url.has_value()) return CSSImportRule::create(url.value(), const_cast<DOM::Document&>(*m_context.document())); - else - dbgln_if(CSS_PARSER_DEBUG, "Unable to parse url from @import rule"); + dbgln_if(CSS_PARSER_DEBUG, "Unable to parse url from @import rule"); } else if (rule->at_rule_name().equals_ignoring_case("media"sv)) { @@ -2637,13 +2642,13 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule) auto child_tokens = TokenStream { rule->block()->values() }; auto parser_rules = parse_a_list_of_rules(child_tokens); - NonnullRefPtrVector<CSSRule> child_rules; + JS::MarkedVector<CSSRule*> child_rules(m_context.window_object().heap()); for (auto& raw_rule : parser_rules) { if (auto child_rule = convert_to_rule(raw_rule)) - child_rules.append(*child_rule); + child_rules.append(child_rule); } - - return CSSMediaRule::create(MediaList::create(move(media_query_list)), move(child_rules)); + auto* rule_list = CSSRuleList::create(m_context.window_object(), move(child_rules)); + return CSSMediaRule::create(m_context.window_object(), MediaList::create(move(media_query_list)), *rule_list); } else if (rule->at_rule_name().equals_ignoring_case("supports"sv)) { @@ -2661,13 +2666,14 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule) return {}; auto child_tokens = TokenStream { rule->block()->values() }; auto parser_rules = parse_a_list_of_rules(child_tokens); - NonnullRefPtrVector<CSSRule> child_rules; + JS::MarkedVector<CSSRule*> child_rules(m_context.window_object().heap()); for (auto& raw_rule : parser_rules) { if (auto child_rule = convert_to_rule(raw_rule)) - child_rules.append(*child_rule); + child_rules.append(child_rule); } - return CSSSupportsRule::create(supports.release_nonnull(), move(child_rules)); + auto* rule_list = CSSRuleList::create(m_context.window_object(), move(child_rules)); + return CSSSupportsRule::create(m_context.window_object(), supports.release_nonnull(), *rule_list); } else { dbgln_if(CSS_PARSER_DEBUG, "Unrecognized CSS at-rule: @{}", rule->at_rule_name()); @@ -2706,7 +2712,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule) return {}; } - return CSSStyleRule::create(move(selectors.value()), move(*declaration)); + return CSSStyleRule::create(m_context.window_object(), move(selectors.value()), move(*declaration)); } return {}; @@ -4690,7 +4696,7 @@ RefPtr<StyleValue> Parser::parse_font_family_value(Vector<ComponentValue> const& return StyleValueList::create(move(font_families), StyleValueList::Separator::Comma); } -RefPtr<CSSRule> Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens) +CSSRule* Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens) { auto declarations_and_at_rules = parse_a_list_of_declarations(tokens); @@ -4791,7 +4797,7 @@ RefPtr<CSSRule> Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens unicode_range.empend(0x0u, 0x10FFFFu); } - return CSSFontFaceRule::create(FontFace { font_family.release_value(), move(src), move(unicode_range) }); + return CSSFontFaceRule::create(m_context.window_object(), FontFace { font_family.release_value(), move(src), move(unicode_range) }); } Vector<FontFace::Source> Parser::parse_font_face_src(TokenStream<ComponentValue>& component_values) @@ -6385,7 +6391,7 @@ namespace Web { CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location) { if (css.is_empty()) - return CSS::CSSStyleSheet::create(context.window_object(), {}, location); + return CSS::CSSStyleSheet::create(context.window_object(), *CSS::CSSRuleList::create_empty(context.window_object()), location); CSS::Parser::Parser parser(context, css); return parser.parse_as_css_stylesheet(location); } @@ -6406,7 +6412,7 @@ RefPtr<CSS::StyleValue> parse_css_value(CSS::Parser::ParsingContext const& conte return parser.parse_as_css_value(property_id); } -RefPtr<CSS::CSSRule> parse_css_rule(CSS::Parser::ParsingContext const& context, StringView css_text) +CSS::CSSRule* parse_css_rule(CSS::Parser::ParsingContext const& context, StringView css_text) { CSS::Parser::Parser parser(context, css_text); return parser.parse_as_css_rule(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 262814c49b..5779008004 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -35,6 +35,7 @@ namespace Web::CSS::Parser { class ParsingContext { public: ParsingContext(); + explicit ParsingContext(Bindings::WindowObject&); explicit ParsingContext(DOM::Document const&); explicit ParsingContext(DOM::Document const&, AK::URL); explicit ParsingContext(DOM::ParentNode&); @@ -127,7 +128,7 @@ public: CSSStyleSheet* parse_as_css_stylesheet(Optional<AK::URL> location); RefPtr<ElementInlineCSSStyleDeclaration> parse_as_style_attribute(DOM::Element&); - RefPtr<CSSRule> parse_as_css_rule(); + CSSRule* parse_as_css_rule(); Optional<StyleProperty> parse_as_supports_condition(); enum class SelectorParsingMode { @@ -235,10 +236,10 @@ private: Optional<GeneralEnclosed> parse_general_enclosed(TokenStream<ComponentValue>&); - RefPtr<CSSRule> parse_font_face_rule(TokenStream<ComponentValue>&); + CSSRule* parse_font_face_rule(TokenStream<ComponentValue>&); Vector<FontFace::Source> parse_font_face_src(TokenStream<ComponentValue>&); - RefPtr<CSSRule> convert_to_rule(NonnullRefPtr<Rule>); + CSSRule* convert_to_rule(NonnullRefPtr<Rule>); RefPtr<PropertyOwningCSSStyleDeclaration> convert_to_style_declaration(Vector<DeclarationOrAtRule> declarations); Optional<StyleProperty> convert_to_style_property(Declaration const&); @@ -423,7 +424,7 @@ CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const&, Str 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); -RefPtr<CSS::CSSRule> parse_css_rule(CSS::Parser::ParsingContext const&, StringView); +CSS::CSSRule* parse_css_rule(CSS::Parser::ParsingContext const&, StringView); RefPtr<CSS::MediaQuery> parse_media_query(CSS::Parser::ParsingContext const&, StringView); NonnullRefPtrVector<CSS::MediaQuery> parse_media_query_list(CSS::Parser::ParsingContext const&, StringView); RefPtr<CSS::Supports> parse_css_supports(CSS::Parser::ParsingContext const&, StringView); diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index ec1c395003..fb484acf06 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -184,7 +184,7 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e size_t selector_index = 0; for (auto& selector : rule.selectors()) { if (SelectorEngine::matches(selector, element, pseudo_element)) { - matching_rules.append({ rule, style_sheet_index, rule_index, selector_index, selector.specificity() }); + matching_rules.append({ &rule, style_sheet_index, rule_index, selector_index, selector.specificity() }); break; } ++selector_index; @@ -1264,7 +1264,7 @@ void StyleComputer::build_rule_cache() 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() }; + MatchingRule matching_rule { &rule, style_sheet_index, rule_index, selector_index, selector.specificity() }; bool added_to_bucket = false; for (auto const& simple_selector : selector.compound_selectors().last().simple_selectors) { diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index b9cd4993e4..9f2b05fedd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -21,7 +21,7 @@ namespace Web::CSS { struct MatchingRule { - RefPtr<CSSStyleRule> rule; + CSSStyleRule const* rule { nullptr }; size_t style_sheet_index { 0 }; size_t rule_index { 0 }; size_t selector_index { 0 }; |