LibWeb: Make CSSRule and all its subclasses GC-allocated

This commit is contained in:
Andreas Kling 2022-08-07 15:46:44 +02:00
parent 5d6cb9cbdb
commit 12042f0757
Notes: sideshowbarker 2024-07-17 07:29:03 +09:00
39 changed files with 338 additions and 236 deletions

View file

@ -39,7 +39,6 @@ interface CSSRule {
- It must have a public `using WrapperType = Bindings::HTMLDetailsElementWrapper;` - It must have a public `using WrapperType = Bindings::HTMLDetailsElementWrapper;`
7. Depending on what kind of thing your interface is, you may need to add it to the `WrapperFactory` of that kind: 7. Depending on what kind of thing your interface is, you may need to add it to the `WrapperFactory` of that kind:
- CSSRules: [`LibWeb/Bindings/CSSRuleWrapperFactory.cpp`](../../Userland/Libraries/LibWeb/Bindings/CSSRuleWrapperFactory.cpp)
- Events: [`LibWeb/Bindings/EventWrapperFactory.cpp`](../../Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp) - Events: [`LibWeb/Bindings/EventWrapperFactory.cpp`](../../Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp)
- Elements: [`LibWeb/Bindings/NodeWrapperFactory.cpp`](../../Userland/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp) - Elements: [`LibWeb/Bindings/NodeWrapperFactory.cpp`](../../Userland/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp)

View file

@ -87,6 +87,27 @@ static bool impl_is_wrapper(Type const& type)
if (type.name == "CSSRuleList"sv) if (type.name == "CSSRuleList"sv)
return true; return true;
if (type.name == "CSSRule"sv)
return true;
if (type.name == "CSSStyleRule"sv)
return true;
if (type.name == "CSSFontFaceRule"sv)
return true;
if (type.name == "CSSConditionRule"sv)
return true;
if (type.name == "CSSGroupingRule"sv)
return true;
if (type.name == "CSSMediaRule"sv)
return true;
if (type.name == "CSSImportRule"sv)
return true;
return false; return false;
} }
@ -2884,7 +2905,6 @@ void generate_constructor_implementation(IDL::Interface const& interface)
#if __has_include(<LibWeb/Bindings/@wrapper_class@.h>) #if __has_include(<LibWeb/Bindings/@wrapper_class@.h>)
#include <LibWeb/Bindings/@wrapper_class@.h> #include <LibWeb/Bindings/@wrapper_class@.h>
#endif #endif
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
#include <LibWeb/Bindings/EventTargetWrapperFactory.h> #include <LibWeb/Bindings/EventTargetWrapperFactory.h>
#include <LibWeb/Bindings/EventWrapperFactory.h> #include <LibWeb/Bindings/EventWrapperFactory.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h> #include <LibWeb/Bindings/ExceptionOrUtils.h>

View file

@ -1,41 +0,0 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/TypeCasts.h>
#include <LibWeb/Bindings/CSSFontFaceRuleWrapper.h>
#include <LibWeb/Bindings/CSSImportRuleWrapper.h>
#include <LibWeb/Bindings/CSSMediaRuleWrapper.h>
#include <LibWeb/Bindings/CSSRuleWrapper.h>
#include <LibWeb/Bindings/CSSRuleWrapperFactory.h>
#include <LibWeb/Bindings/CSSStyleRuleWrapper.h>
#include <LibWeb/Bindings/CSSSupportsRuleWrapper.h>
#include <LibWeb/CSS/CSSFontFaceRule.h>
#include <LibWeb/CSS/CSSImportRule.h>
#include <LibWeb/CSS/CSSMediaRule.h>
#include <LibWeb/CSS/CSSStyleRule.h>
#include <LibWeb/CSS/CSSSupportsRule.h>
namespace Web::Bindings {
CSSRuleWrapper* wrap(JS::Realm& realm, CSS::CSSRule& rule)
{
if (rule.wrapper())
return static_cast<CSSRuleWrapper*>(rule.wrapper());
if (is<CSS::CSSStyleRule>(rule))
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, verify_cast<CSS::CSSStyleRule>(rule)));
if (is<CSS::CSSImportRule>(rule))
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, verify_cast<CSS::CSSImportRule>(rule)));
if (is<CSS::CSSMediaRule>(rule))
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, verify_cast<CSS::CSSMediaRule>(rule)));
if (is<CSS::CSSFontFaceRule>(rule))
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, verify_cast<CSS::CSSFontFaceRule>(rule)));
if (is<CSS::CSSSupportsRule>(rule))
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, verify_cast<CSS::CSSSupportsRule>(rule)));
return static_cast<CSSRuleWrapper*>(wrap_impl(realm, rule));
}
}

View file

@ -1,16 +0,0 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibJS/Forward.h>
#include <LibWeb/Forward.h>
namespace Web::Bindings {
CSSRuleWrapper* wrap(JS::Realm&, CSS::CSSRule&);
}

View file

@ -4,7 +4,6 @@ set(SOURCES
Bindings/AudioConstructor.cpp Bindings/AudioConstructor.cpp
Bindings/CrossOriginAbstractOperations.cpp Bindings/CrossOriginAbstractOperations.cpp
Bindings/CSSNamespace.cpp Bindings/CSSNamespace.cpp
Bindings/CSSRuleWrapperFactory.cpp
Bindings/CSSStyleDeclarationWrapperCustom.cpp Bindings/CSSStyleDeclarationWrapperCustom.cpp
Bindings/EventListenerWrapper.cpp Bindings/EventListenerWrapper.cpp
Bindings/EventTargetWrapperFactory.cpp Bindings/EventTargetWrapperFactory.cpp

View file

@ -1,16 +1,20 @@
/* /*
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSConditionRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSConditionRule.h> #include <LibWeb/CSS/CSSConditionRule.h>
namespace Web::CSS { namespace Web::CSS {
CSSConditionRule::CSSConditionRule(NonnullRefPtrVector<CSSRule>&& rules) CSSConditionRule::CSSConditionRule(Bindings::WindowObject& window_object, CSSRuleList& rules)
: CSSGroupingRule(move(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 void CSSConditionRule::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const

View file

@ -15,9 +15,10 @@ namespace Web::CSS {
class CSSConditionRule : public CSSGroupingRule { class CSSConditionRule : public CSSGroupingRule {
AK_MAKE_NONCOPYABLE(CSSConditionRule); AK_MAKE_NONCOPYABLE(CSSConditionRule);
AK_MAKE_NONMOVABLE(CSSConditionRule); AK_MAKE_NONMOVABLE(CSSConditionRule);
JS_OBJECT(CSSConditionRule, CSSGroupingRule);
public: public:
using WrapperType = Bindings::CSSConditionRuleWrapper; CSSConditionRule& impl() { return *this; }
virtual ~CSSConditionRule() = default; virtual ~CSSConditionRule() = default;
@ -28,7 +29,12 @@ public:
virtual void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const override; virtual void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const override;
protected: 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;
}

View file

@ -1,6 +1,6 @@
#import <CSS/CSSGroupingRule.idl> #import <CSS/CSSGroupingRule.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSConditionRule : CSSGroupingRule { interface CSSConditionRule : CSSGroupingRule {
attribute CSSOMString conditionText; attribute CSSOMString conditionText;
}; };

View file

@ -1,16 +1,26 @@
/* /*
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSFontFaceRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSFontFaceRule.h> #include <LibWeb/CSS/CSSFontFaceRule.h>
namespace Web::CSS { namespace Web::CSS {
CSSFontFaceRule::CSSFontFaceRule(FontFace&& font_face) CSSFontFaceRule* CSSFontFaceRule::create(Bindings::WindowObject& window_object, FontFace&& font_face)
: m_font_face(move(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() CSSStyleDeclaration* CSSFontFaceRule::style()

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -14,26 +15,21 @@ namespace Web::CSS {
class CSSFontFaceRule final : public CSSRule { class CSSFontFaceRule final : public CSSRule {
AK_MAKE_NONCOPYABLE(CSSFontFaceRule); AK_MAKE_NONCOPYABLE(CSSFontFaceRule);
AK_MAKE_NONMOVABLE(CSSFontFaceRule); AK_MAKE_NONMOVABLE(CSSFontFaceRule);
JS_OBJECT(CSSFontFaceRule, CSSRule);
public: public:
using WrapperType = Bindings::CSSFontFaceRuleWrapper; static CSSFontFaceRule* create(Bindings::WindowObject&, FontFace&&);
explicit CSSFontFaceRule(Bindings::WindowObject&, FontFace&&);
static NonnullRefPtr<CSSFontFaceRule> create(FontFace&& font_face)
{
return adopt_ref(*new CSSFontFaceRule(move(font_face)));
}
virtual ~CSSFontFaceRule() override = default; 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; } virtual Type type() const override { return Type::FontFace; }
FontFace const& font_face() const { return m_font_face; } FontFace const& font_face() const { return m_font_face; }
CSSStyleDeclaration* style(); CSSStyleDeclaration* style();
private: private:
explicit CSSFontFaceRule(FontFace&&);
virtual String serialized() const override; virtual String serialized() const override;
FontFace m_font_face; FontFace m_font_face;
@ -43,3 +39,8 @@ template<>
inline bool CSSRule::fast_is<CSSFontFaceRule>() const { return type() == CSSRule::Type::FontFace; } 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;
}

View file

@ -1,7 +1,7 @@
#import <CSS/CSSRule.idl> #import <CSS/CSSRule.idl>
#import <CSS/CSSStyleDeclaration.idl> #import <CSS/CSSStyleDeclaration.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSFontFaceRule : CSSRule { interface CSSFontFaceRule : CSSRule {
readonly attribute CSSStyleDeclaration style; readonly attribute CSSStyleDeclaration style;
}; };

View file

@ -1,45 +1,55 @@
/* /*
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSGroupingRulePrototype.h>
#include <LibWeb/Bindings/MainThreadVM.h> #include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSGroupingRule.h> #include <LibWeb/CSS/CSSGroupingRule.h>
#include <LibWeb/CSS/CSSRuleList.h> #include <LibWeb/CSS/CSSRuleList.h>
namespace Web::CSS { namespace Web::CSS {
CSSGroupingRule::CSSGroupingRule(NonnullRefPtrVector<CSSRule>&& rules) CSSGroupingRule::CSSGroupingRule(Bindings::WindowObject& window_object, CSSRuleList& rules)
// FIXME: Use the same window object for the rule list. : CSSRule(window_object)
: m_rules(JS::make_handle(CSSRuleList::create(Bindings::main_thread_internal_window_object(), move(rules)))) , 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); 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) 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. // 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; return index;
} }
DOM::ExceptionOr<void> CSSGroupingRule::delete_rule(u32 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 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) void CSSGroupingRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet)
{ {
CSSRule::set_parent_style_sheet(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); rule.set_parent_style_sheet(parent_style_sheet);
} }

View file

@ -17,15 +17,16 @@ namespace Web::CSS {
class CSSGroupingRule : public CSSRule { class CSSGroupingRule : public CSSRule {
AK_MAKE_NONCOPYABLE(CSSGroupingRule); AK_MAKE_NONCOPYABLE(CSSGroupingRule);
AK_MAKE_NONMOVABLE(CSSGroupingRule); AK_MAKE_NONMOVABLE(CSSGroupingRule);
JS_OBJECT(CSSGroupingRule, CSSRule);
public: public:
using WrapperType = Bindings::CSSGroupingRuleWrapper; CSSGroupingRule& impl() { return *this; }
virtual ~CSSGroupingRule() = default; virtual ~CSSGroupingRule() = default;
CSSRuleList const& css_rules() const { return *m_rules; } CSSRuleList const& css_rules() const { return m_rules; }
CSSRuleList& css_rules() { return *m_rules; } CSSRuleList& css_rules() { return m_rules; }
CSSRuleList* css_rules_for_bindings() { return m_rules.cell(); } CSSRuleList* css_rules_for_bindings() { return &m_rules; }
DOM::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0); DOM::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0);
DOM::ExceptionOr<void> delete_rule(u32 index); DOM::ExceptionOr<void> delete_rule(u32 index);
@ -34,10 +35,17 @@ public:
virtual void set_parent_style_sheet(CSSStyleSheet*) override; virtual void set_parent_style_sheet(CSSStyleSheet*) override;
protected: protected:
explicit CSSGroupingRule(NonnullRefPtrVector<CSSRule>&&); explicit CSSGroupingRule(Bindings::WindowObject&, CSSRuleList&);
private: 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;
}

View file

@ -1,7 +1,7 @@
#import <CSS/CSSRule.idl> #import <CSS/CSSRule.idl>
#import <CSS/CSSRuleList.idl> #import <CSS/CSSRuleList.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSGroupingRule : CSSRule { interface CSSGroupingRule : CSSRule {
[SameObject, ImplementedAs=css_rules_for_bindings] readonly attribute CSSRuleList cssRules; [SameObject, ImplementedAs=css_rules_for_bindings] readonly attribute CSSRuleList cssRules;
unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0); unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0);

View file

@ -1,12 +1,15 @@
/* /*
* Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/Debug.h> #include <AK/Debug.h>
#include <AK/URL.h> #include <AK/URL.h>
#include <LibWeb/Bindings/CSSImportRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSImportRule.h>
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
@ -14,10 +17,19 @@
namespace Web::CSS { 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) CSSImportRule::CSSImportRule(AK::URL url, DOM::Document& document)
: m_url(move(url)) : CSSRule(document.preferred_window_object())
, m_url(move(url))
, m_document(document) , 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); dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Loading import URL: {}", m_url);
auto request = LoadRequest::create_for_url_on_page(m_url, document.page()); 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)); 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 // https://www.w3.org/TR/cssom/#serialize-a-css-rule
String CSSImportRule::serialized() const String CSSImportRule::serialized() const
{ {
@ -79,7 +97,7 @@ void CSSImportRule::resource_did_load()
return; return;
} }
m_style_sheet = JS::make_handle(sheet); m_style_sheet = sheet;
m_document->style_computer().invalidate_rule_cache(); m_document->style_computer().invalidate_rule_cache();
m_document->invalidate_style(); m_document->invalidate_style();

View file

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -20,32 +21,30 @@ class CSSImportRule final
, public ResourceClient { , public ResourceClient {
AK_MAKE_NONCOPYABLE(CSSImportRule); AK_MAKE_NONCOPYABLE(CSSImportRule);
AK_MAKE_NONMOVABLE(CSSImportRule); AK_MAKE_NONMOVABLE(CSSImportRule);
JS_OBJECT(CSSImportRule, CSSRule);
public: public:
using WrapperType = Bindings::CSSImportRuleWrapper; static CSSImportRule* create(AK::URL, DOM::Document&);
CSSImportRule(AK::URL, DOM::Document&);
static NonnullRefPtr<CSSImportRule> create(AK::URL url, DOM::Document& document)
{
return adopt_ref(*new CSSImportRule(move(url), document));
}
virtual ~CSSImportRule() = default; virtual ~CSSImportRule() = default;
CSSImportRule& impl() { return *this; }
AK::URL const& url() const { return m_url; } 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". // 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(); } String href() const { return m_url.to_string(); }
bool has_import_result() const { return !m_style_sheet.is_null(); } bool has_import_result() const { return !m_style_sheet; }
CSSStyleSheet* loaded_style_sheet() { return m_style_sheet.cell(); } CSSStyleSheet* loaded_style_sheet() { return m_style_sheet; }
CSSStyleSheet const* loaded_style_sheet() const { return m_style_sheet.cell(); } CSSStyleSheet const* loaded_style_sheet() const { return m_style_sheet; }
CSSStyleSheet* style_sheet_for_bindings() { return m_style_sheet.cell(); } CSSStyleSheet* style_sheet_for_bindings() { return m_style_sheet; }
void set_style_sheet(CSSStyleSheet* style_sheet) { m_style_sheet = JS::make_handle(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; }; virtual Type type() const override { return Type::Import; };
private: private:
explicit CSSImportRule(AK::URL, DOM::Document&); virtual void visit_edges(Cell::Visitor&) override;
virtual String serialized() const override; virtual String serialized() const override;
@ -56,10 +55,15 @@ private:
AK::URL m_url; AK::URL m_url;
WeakPtr<DOM::Document> m_document; WeakPtr<DOM::Document> m_document;
Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer; Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;
JS::Handle<CSSStyleSheet> m_style_sheet; CSSStyleSheet* m_style_sheet { nullptr };
}; };
template<> template<>
inline bool CSSRule::fast_is<CSSImportRule>() const { return type() == CSSRule::Type::Import; } 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;
}

View file

@ -2,7 +2,7 @@
#import <CSS/CSSStyleSheet.idl> #import <CSS/CSSStyleSheet.idl>
#import <CSS/MediaList.idl> #import <CSS/MediaList.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSImportRule : CSSRule { interface CSSImportRule : CSSRule {
readonly attribute USVString href; readonly attribute USVString href;
// [SameObject, PutForwards=mediaText] readonly attribute MediaList media; // [SameObject, PutForwards=mediaText] readonly attribute MediaList media;

View file

@ -1,17 +1,26 @@
/* /*
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSMediaRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSMediaRule.h> #include <LibWeb/CSS/CSSMediaRule.h>
namespace Web::CSS { namespace Web::CSS {
CSSMediaRule::CSSMediaRule(NonnullRefPtr<MediaList>&& media, NonnullRefPtrVector<CSSRule>&& rules) CSSMediaRule* CSSMediaRule::create(Bindings::WindowObject& window_object, NonnullRefPtr<MediaList>&& media_queries, CSSRuleList& rules)
: CSSConditionRule(move(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)) , m_media(move(media))
{ {
set_prototype(&window_object.ensure_web_prototype<Bindings::CSSMediaRulePrototype>("CSSMediaRule"));
} }
String CSSMediaRule::condition_text() const String CSSMediaRule::condition_text() const

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -16,18 +17,16 @@ namespace Web::CSS {
class CSSMediaRule final : public CSSConditionRule { class CSSMediaRule final : public CSSConditionRule {
AK_MAKE_NONCOPYABLE(CSSMediaRule); AK_MAKE_NONCOPYABLE(CSSMediaRule);
AK_MAKE_NONMOVABLE(CSSMediaRule); AK_MAKE_NONMOVABLE(CSSMediaRule);
JS_OBJECT(CSSMediaRule, CSSConditionRule);
public: public:
using WrapperType = Bindings::CSSMediaRuleWrapper; CSSMediaRule& impl() { return *this; }
static NonnullRefPtr<CSSMediaRule> create(NonnullRefPtr<MediaList>&& media_queries, NonnullRefPtrVector<CSSRule>&& rules) static CSSMediaRule* create(Bindings::WindowObject&, NonnullRefPtr<MediaList>&& media_queries, CSSRuleList&);
{ explicit CSSMediaRule(Bindings::WindowObject&, NonnullRefPtr<MediaList>&&, CSSRuleList&);
return adopt_ref(*new CSSMediaRule(move(media_queries), move(rules)));
}
virtual ~CSSMediaRule() = default; virtual ~CSSMediaRule() = default;
virtual StringView class_name() const override { return "CSSMediaRule"sv; };
virtual Type type() const override { return Type::Media; }; virtual Type type() const override { return Type::Media; };
virtual String condition_text() const override; virtual String condition_text() const override;
@ -39,8 +38,6 @@ public:
bool evaluate(HTML::Window const& window) { return m_media->evaluate(window); } bool evaluate(HTML::Window const& window) { return m_media->evaluate(window); }
private: private:
explicit CSSMediaRule(NonnullRefPtr<MediaList>&&, NonnullRefPtrVector<CSSRule>&&);
virtual String serialized() const override; virtual String serialized() const override;
NonnullRefPtr<MediaList> m_media; NonnullRefPtr<MediaList> m_media;
@ -50,3 +47,8 @@ template<>
inline bool CSSRule::fast_is<CSSMediaRule>() const { return type() == CSSRule::Type::Media; } 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;
}

View file

@ -1,7 +1,7 @@
#import <CSS/CSSConditionRule.idl> #import <CSS/CSSConditionRule.idl>
#import <CSS/MediaList.idl> #import <CSS/MediaList.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSMediaRule : CSSConditionRule { interface CSSMediaRule : CSSConditionRule {
[SameObject, PutForwards=mediaText] readonly attribute MediaList media; [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
}; };

View file

@ -1,15 +1,30 @@
/* /*
* Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/CSSRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/CSSStyleSheet.h>
namespace Web::CSS { 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 // https://www.w3.org/TR/cssom/#dom-cssrule-csstext
String CSSRule::css_text() const String CSSRule::css_text() const
{ {

View file

@ -1,27 +1,25 @@
/* /*
* Copyright (c) 2021, the SerenityOS developers. * Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#pragma once #pragma once
#include <AK/RefCounted.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/Weakable.h> #include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Bindings/Wrappable.h> #include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/CSS/CSSStyleDeclaration.h> #include <LibWeb/CSS/CSSStyleDeclaration.h>
#include <LibWeb/CSS/Selector.h> #include <LibWeb/CSS/Selector.h>
namespace Web::CSS { namespace Web::CSS {
class CSSRule class CSSRule : public Bindings::PlatformObject {
: public RefCounted<CSSRule> JS_OBJECT(CSSRule, JS::Object);
, public Bindings::Wrappable
, public Weakable<CSSRule> {
public:
using WrapperType = Bindings::CSSRuleWrapper;
public:
CSSRule& impl() { return *this; }
virtual ~CSSRule() = default; virtual ~CSSRule() = default;
// https://drafts.csswg.org/cssom/#dom-cssrule-type // https://drafts.csswg.org/cssom/#dom-cssrule-type
@ -33,26 +31,34 @@ public:
Supports = 12, Supports = 12,
}; };
virtual StringView class_name() const = 0;
virtual Type type() const = 0; virtual Type type() const = 0;
String css_text() const; String css_text() const;
void set_css_text(StringView); 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*); 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*); virtual void set_parent_style_sheet(CSSStyleSheet*);
template<typename T> template<typename T>
bool fast_is() const = delete; bool fast_is() const = delete;
protected: protected:
explicit CSSRule(Bindings::WindowObject&);
virtual String serialized() const = 0; virtual String serialized() const = 0;
WeakPtr<CSSRule> m_parent_rule; virtual void visit_edges(Cell::Visitor&) override;
WeakPtr<CSSStyleSheet> m_parent_style_sheet;
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;
}

View file

@ -1,6 +1,6 @@
#import <CSS/CSSStyleSheet.idl> #import <CSS/CSSStyleSheet.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSRule { interface CSSRule {
attribute CSSOMString cssText; attribute CSSOMString cssText;

View file

@ -9,23 +9,38 @@
#include <LibWeb/Bindings/WindowObject.h> #include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSImportRule.h>
#include <LibWeb/CSS/CSSMediaRule.h> #include <LibWeb/CSS/CSSMediaRule.h>
#include <LibWeb/CSS/CSSRule.h>
#include <LibWeb/CSS/CSSRuleList.h> #include <LibWeb/CSS/CSSRuleList.h>
#include <LibWeb/CSS/CSSSupportsRule.h> #include <LibWeb/CSS/CSSSupportsRule.h>
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
namespace Web::CSS { 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")) : 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 bool CSSRuleList::is_supported_property_index(u32 index) const
{ {
// The objects supported property indices are the numbers in the range zero to one less than the number of CSSRule objects represented by the collection. // The objects 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 // 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. // 1. Set length to the number of items in list.
auto length = m_rules.size(); 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() // 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 // 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. // if that variant holds a CSSRule already.
RefPtr<CSSRule> new_rule; CSSRule* new_rule = nullptr;
if (rule.has<StringView>()) { 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 { } else {
new_rule = rule.get<NonnullRefPtr<CSSRule>>(); new_rule = rule.get<CSSRule*>();
} }
// 4. If new rule is a syntax error, throw a SyntaxError exception. // 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. // 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. // 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. // 8. Return index.
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."); return DOM::IndexSizeError::create("CSS rule index out of bounds.");
// 3. Set old rule to the indexth item in list. // 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. // 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); m_rules.remove(index);
// 6. Set old rules parent CSS rule and parent CSS style sheet to null. // 6. Set old rules parent CSS rule and parent CSS style sheet to null.
old_rule->set_parent_rule(nullptr); old_rule.set_parent_rule(nullptr);
old_rule->set_parent_style_sheet(nullptr); old_rule.set_parent_style_sheet(nullptr);
return {}; return {};
} }
@ -102,7 +119,7 @@ void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const
break; break;
case CSSRule::Type::Import: { case CSSRule::Type::Import: {
auto const& import_rule = static_cast<CSSImportRule const&>(rule); 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); import_rule.loaded_style_sheet()->for_each_effective_style_rule(callback);
break; break;
} }
@ -129,7 +146,7 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window)
break; break;
case CSSRule::Type::Import: { case CSSRule::Type::Import: {
auto& import_rule = verify_cast<CSSImportRule>(rule); 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; any_media_queries_changed_match_state = true;
break; break;
} }

View file

@ -25,20 +25,30 @@ class CSSRuleList : public Bindings::LegacyPlatformObject {
public: public:
CSSRuleList& impl() { return *this; } CSSRuleList& impl() { return *this; }
static CSSRuleList* create(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>&& rules); static CSSRuleList* create(Bindings::WindowObject&, JS::MarkedVector<CSSRule*> const&);
CSSRuleList(Bindings::WindowObject&, NonnullRefPtrVector<CSSRule>&&); static CSSRuleList* create_empty(Bindings::WindowObject&);
explicit CSSRuleList(Bindings::WindowObject&);
~CSSRuleList() = default; ~CSSRuleList() = default;
RefPtr<CSSRule> item(size_t index) const CSSRule const* item(size_t index) const
{ {
if (index >= length()) if (index >= length())
return nullptr; return nullptr;
return m_rules[index]; return &m_rules[index];
} }
CSSRule* item(size_t index)
{
if (index >= length())
return nullptr;
return &m_rules[index];
}
size_t length() const { return m_rules.size(); } size_t length() const { return m_rules.size(); }
using ConstIterator = AK::SimpleIterator<AK::NonnullPtrVector<NonnullRefPtr<CSSRule>> const, CSSRule const>; using ConstIterator = AK::SimpleIterator<Vector<CSSRule&> const, CSSRule const>;
using Iterator = AK::SimpleIterator<AK::NonnullPtrVector<NonnullRefPtr<CSSRule>>, CSSRule>; using Iterator = AK::SimpleIterator<Vector<CSSRule&>, CSSRule>;
ConstIterator const begin() const { return m_rules.begin(); } ConstIterator const begin() const { return m_rules.begin(); }
Iterator begin() { 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; virtual JS::Value item_value(size_t index) const override;
DOM::ExceptionOr<void> remove_a_css_rule(u32 index); 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; 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. // Returns whether the match state of any media queries changed after evaluation.
bool evaluate_media_queries(HTML::Window const&); bool evaluate_media_queries(HTML::Window const&);
private: private:
NonnullRefPtrVector<CSSRule> m_rules; virtual void visit_edges(Cell::Visitor&) override;
Vector<CSSRule&> m_rules;
}; };
} }
namespace Web::Bindings { 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; using CSSRuleListWrapper = Web::CSS::CSSRuleList;
} }

View file

@ -4,15 +4,24 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSStyleRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSStyleRule.h> #include <LibWeb/CSS/CSSStyleRule.h>
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
namespace Web::CSS { namespace Web::CSS {
CSSStyleRule::CSSStyleRule(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) CSSStyleRule* CSSStyleRule::create(Bindings::WindowObject& window_object, NonnullRefPtrVector<Web::CSS::Selector>&& selectors, NonnullRefPtr<Web::CSS::CSSStyleDeclaration>&& declaration)
: m_selectors(move(selectors)) {
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)) , m_declaration(move(declaration))
{ {
set_prototype(&window_object.ensure_web_prototype<Bindings::CSSStyleRulePrototype>("CSSStyleRule"));
} }
// https://www.w3.org/TR/cssom/#dom-cssstylerule-style // https://www.w3.org/TR/cssom/#dom-cssstylerule-style

View file

@ -16,23 +16,21 @@
namespace Web::CSS { namespace Web::CSS {
class CSSStyleRule final : public CSSRule { class CSSStyleRule final : public CSSRule {
JS_OBJECT(CSSStyleRule, CSSRule);
AK_MAKE_NONCOPYABLE(CSSStyleRule); AK_MAKE_NONCOPYABLE(CSSStyleRule);
AK_MAKE_NONMOVABLE(CSSStyleRule); AK_MAKE_NONMOVABLE(CSSStyleRule);
public: public:
using WrapperType = Bindings::CSSStyleRuleWrapper; static CSSStyleRule* create(Bindings::WindowObject&, NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&);
CSSStyleRule(Bindings::WindowObject&, NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&);
static NonnullRefPtr<CSSStyleRule> create(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration)
{
return adopt_ref(*new CSSStyleRule(move(selectors), move(declaration)));
}
virtual ~CSSStyleRule() override = default; virtual ~CSSStyleRule() override = default;
CSSStyleRule& impl() { return *this; }
NonnullRefPtrVector<Selector> const& selectors() const { return m_selectors; } NonnullRefPtrVector<Selector> const& selectors() const { return m_selectors; }
CSSStyleDeclaration const& declaration() const { return m_declaration; } CSSStyleDeclaration const& declaration() const { return m_declaration; }
virtual StringView class_name() const override { return "CSSStyleRule"sv; };
virtual Type type() const override { return Type::Style; }; virtual Type type() const override { return Type::Style; };
String selector_text() const; String selector_text() const;
@ -41,8 +39,6 @@ public:
CSSStyleDeclaration* style(); CSSStyleDeclaration* style();
private: private:
CSSStyleRule(NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&);
virtual String serialized() const override; virtual String serialized() const override;
NonnullRefPtrVector<Selector> m_selectors; NonnullRefPtrVector<Selector> m_selectors;
@ -53,3 +49,8 @@ template<>
inline bool CSSRule::fast_is<CSSStyleRule>() const { return type() == CSSRule::Type::Style; } 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;
}

View file

@ -1,6 +1,7 @@
#import <CSS/CSSRule.idl> #import <CSS/CSSRule.idl>
#import <CSS/CSSStyleDeclaration.idl> #import <CSS/CSSStyleDeclaration.idl>
[Exposed=Window, NoInstanceWrapper]
interface CSSStyleRule : CSSRule { interface CSSStyleRule : CSSRule {
attribute CSSOMString selectorText; attribute CSSOMString selectorText;

View file

@ -13,14 +13,14 @@
namespace Web::CSS { 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) : StyleSheet(window_object)
, m_rules(CSSRuleList::create(window_object, move(rules))) , m_rules(&rules)
{ {
set_prototype(&window_object.ensure_web_prototype<Bindings::CSSStyleSheetPrototype>("CSSStyleSheet")); 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); Base::visit_edges(visitor);
visitor.visit(m_style_sheet_list.ptr()); 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 // 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. // FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException.
// 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index. // 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index.
auto parsed_rule_nonnull = parsed_rule.release_nonnull(); auto result = m_rules->insert_a_css_rule(parsed_rule, index);
auto result = m_rules->insert_a_css_rule(parsed_rule_nonnull, index);
if (!result.is_exception()) { if (!result.is_exception()) {
// NOTE: The spec doesn't say where to set the parent style sheet, so we'll do it here. // 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) { if (m_style_sheet_list) {
m_style_sheet_list->document().style_computer().invalidate_rule_cache(); m_style_sheet_list->document().style_computer().invalidate_rule_cache();

View file

@ -24,9 +24,9 @@ class CSSStyleSheet final
JS_OBJECT(CSSStyleSheet, StyleSheet); JS_OBJECT(CSSStyleSheet, StyleSheet);
public: 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; virtual ~CSSStyleSheet() override = default;
CSSStyleSheet& impl() { return *this; } CSSStyleSheet& impl() { return *this; }
@ -57,9 +57,8 @@ private:
CSSRuleList* m_rules { nullptr }; CSSRuleList* m_rules { nullptr };
WeakPtr<CSSRule> m_owner_css_rule;
JS::GCPtr<StyleSheetList> m_style_sheet_list; JS::GCPtr<StyleSheetList> m_style_sheet_list;
CSSRule* m_owner_css_rule { nullptr };
}; };
} }

View file

@ -4,15 +4,23 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/CSSSupportsRulePrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSSupportsRule.h> #include <LibWeb/CSS/CSSSupportsRule.h>
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
namespace Web::CSS { namespace Web::CSS {
CSSSupportsRule::CSSSupportsRule(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules) CSSSupportsRule* CSSSupportsRule::create(Bindings::WindowObject& window_object, NonnullRefPtr<Supports>&& supports, CSSRuleList& rules)
: CSSConditionRule(move(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)) , m_supports(move(supports))
{ {
set_prototype(&window_object.ensure_web_prototype<Bindings::CSSSupportsRulePrototype>("CSSSupportsRule"));
} }
String CSSSupportsRule::condition_text() const String CSSSupportsRule::condition_text() const

View file

@ -17,20 +17,18 @@ namespace Web::CSS {
// https://www.w3.org/TR/css-conditional-3/#the-csssupportsrule-interface // https://www.w3.org/TR/css-conditional-3/#the-csssupportsrule-interface
class CSSSupportsRule final : public CSSConditionRule { class CSSSupportsRule final : public CSSConditionRule {
JS_OBJECT(CSSSupportsRule, CSSConditionRule);
AK_MAKE_NONCOPYABLE(CSSSupportsRule); AK_MAKE_NONCOPYABLE(CSSSupportsRule);
AK_MAKE_NONMOVABLE(CSSSupportsRule); AK_MAKE_NONMOVABLE(CSSSupportsRule);
public: public:
using WrapperType = Bindings::CSSSupportsRuleWrapper; static CSSSupportsRule* create(Bindings::WindowObject&, NonnullRefPtr<Supports>&&, CSSRuleList&);
explicit CSSSupportsRule(Bindings::WindowObject&, NonnullRefPtr<Supports>&&, CSSRuleList&);
static NonnullRefPtr<CSSSupportsRule> create(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules)
{
return adopt_ref(*new CSSSupportsRule(move(supports), move(rules)));
}
virtual ~CSSSupportsRule() = default; virtual ~CSSSupportsRule() = default;
virtual StringView class_name() const override { return "CSSSupportsRule"sv; }; CSSSupportsRule& impl() { return *this; }
virtual Type type() const override { return Type::Supports; }; virtual Type type() const override { return Type::Supports; };
String condition_text() const override; String condition_text() const override;
@ -38,8 +36,6 @@ public:
virtual bool condition_matches() const override { return m_supports->matches(); } virtual bool condition_matches() const override { return m_supports->matches(); }
private: private:
explicit CSSSupportsRule(NonnullRefPtr<Supports>&&, NonnullRefPtrVector<CSSRule>&&);
virtual String serialized() const override; virtual String serialized() const override;
NonnullRefPtr<Supports> m_supports; NonnullRefPtr<Supports> m_supports;
@ -49,3 +45,8 @@ template<>
inline bool CSSRule::fast_is<CSSSupportsRule>() const { return type() == CSSRule::Type::Supports; } 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;
}

View file

@ -1,5 +1,5 @@
#import <CSS/CSSConditionRule.idl> #import <CSS/CSSConditionRule.idl>
[Exposed=Window] [Exposed=Window, NoInstanceWrapper]
interface CSSSupportsRule : CSSConditionRule { interface CSSSupportsRule : CSSConditionRule {
}; };

View file

@ -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) ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url)
: m_window_object(document.preferred_window_object()) : m_window_object(document.preferred_window_object())
, m_document(&document) , 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, {}); auto style_sheet = parse_a_stylesheet(m_token_stream, {});
// Interpret all of the resulting top-level qualified rules as style rules, defined below. // 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) { 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, its a parse error. Discard that rule. // If any style rule is invalid, or any at-rule is not recognized or is invalid according to its grammar or context, its a parse error. Discard that rule.
if (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) 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); auto maybe_rule = parse_a_rule(m_token_stream);
if (maybe_rule) 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); 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 (rule->is_at_rule()) {
if (has_ignored_vendor_prefix(rule->at_rule_name())) { 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()) if (url.has_value())
return CSSImportRule::create(url.value(), const_cast<DOM::Document&>(*m_context.document())); 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)) { } 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 child_tokens = TokenStream { rule->block()->values() };
auto parser_rules = parse_a_list_of_rules(child_tokens); 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) { for (auto& raw_rule : parser_rules) {
if (auto child_rule = convert_to_rule(raw_rule)) if (auto child_rule = convert_to_rule(raw_rule))
child_rules.append(*child_rule); child_rules.append(child_rule);
} }
auto* rule_list = CSSRuleList::create(m_context.window_object(), move(child_rules));
return CSSMediaRule::create(MediaList::create(move(media_query_list)), 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)) { } 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 {}; return {};
auto child_tokens = TokenStream { rule->block()->values() }; auto child_tokens = TokenStream { rule->block()->values() };
auto parser_rules = parse_a_list_of_rules(child_tokens); 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) { for (auto& raw_rule : parser_rules) {
if (auto child_rule = convert_to_rule(raw_rule)) 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 { } else {
dbgln_if(CSS_PARSER_DEBUG, "Unrecognized CSS at-rule: @{}", rule->at_rule_name()); 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 {};
} }
return CSSStyleRule::create(move(selectors.value()), move(*declaration)); return CSSStyleRule::create(m_context.window_object(), move(selectors.value()), move(*declaration));
} }
return {}; return {};
@ -4690,7 +4696,7 @@ RefPtr<StyleValue> Parser::parse_font_family_value(Vector<ComponentValue> const&
return StyleValueList::create(move(font_families), StyleValueList::Separator::Comma); 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); 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); 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) 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) CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location)
{ {
if (css.is_empty()) 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); CSS::Parser::Parser parser(context, css);
return parser.parse_as_css_stylesheet(location); 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); 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); CSS::Parser::Parser parser(context, css_text);
return parser.parse_as_css_rule(); return parser.parse_as_css_rule();

View file

@ -35,6 +35,7 @@ namespace Web::CSS::Parser {
class ParsingContext { class ParsingContext {
public: public:
ParsingContext(); ParsingContext();
explicit ParsingContext(Bindings::WindowObject&);
explicit ParsingContext(DOM::Document const&); explicit ParsingContext(DOM::Document const&);
explicit ParsingContext(DOM::Document const&, AK::URL); explicit ParsingContext(DOM::Document const&, AK::URL);
explicit ParsingContext(DOM::ParentNode&); explicit ParsingContext(DOM::ParentNode&);
@ -127,7 +128,7 @@ public:
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<ElementInlineCSSStyleDeclaration> parse_as_style_attribute(DOM::Element&);
RefPtr<CSSRule> parse_as_css_rule(); CSSRule* parse_as_css_rule();
Optional<StyleProperty> parse_as_supports_condition(); Optional<StyleProperty> parse_as_supports_condition();
enum class SelectorParsingMode { enum class SelectorParsingMode {
@ -235,10 +236,10 @@ private:
Optional<GeneralEnclosed> parse_general_enclosed(TokenStream<ComponentValue>&); 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>&); 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); RefPtr<PropertyOwningCSSStyleDeclaration> convert_to_style_declaration(Vector<DeclarationOrAtRule> declarations);
Optional<StyleProperty> convert_to_style_property(Declaration const&); 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::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); 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); 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); RefPtr<CSS::MediaQuery> parse_media_query(CSS::Parser::ParsingContext const&, StringView);
NonnullRefPtrVector<CSS::MediaQuery> parse_media_query_list(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); RefPtr<CSS::Supports> parse_css_supports(CSS::Parser::ParsingContext const&, StringView);

View file

@ -184,7 +184,7 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e
size_t selector_index = 0; size_t selector_index = 0;
for (auto& selector : rule.selectors()) { for (auto& selector : rule.selectors()) {
if (SelectorEngine::matches(selector, element, pseudo_element)) { 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; break;
} }
++selector_index; ++selector_index;
@ -1264,7 +1264,7 @@ void StyleComputer::build_rule_cache()
sheet.for_each_effective_style_rule([&](auto const& rule) { sheet.for_each_effective_style_rule([&](auto const& rule) {
size_t selector_index = 0; size_t selector_index = 0;
for (CSS::Selector const& selector : rule.selectors()) { 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; bool added_to_bucket = false;
for (auto const& simple_selector : selector.compound_selectors().last().simple_selectors) { for (auto const& simple_selector : selector.compound_selectors().last().simple_selectors) {

View file

@ -21,7 +21,7 @@
namespace Web::CSS { namespace Web::CSS {
struct MatchingRule { struct MatchingRule {
RefPtr<CSSStyleRule> rule; CSSStyleRule const* rule { nullptr };
size_t style_sheet_index { 0 }; size_t style_sheet_index { 0 };
size_t rule_index { 0 }; size_t rule_index { 0 };
size_t selector_index { 0 }; size_t selector_index { 0 };

View file

@ -459,15 +459,7 @@ class CharacterDataWrapper;
class CloseEventWrapper; class CloseEventWrapper;
class CommentWrapper; class CommentWrapper;
class CryptoWrapper; class CryptoWrapper;
class CSSConditionRuleWrapper;
class CSSFontFaceRuleWrapper;
class CSSGroupingRuleWrapper;
class CSSImportRuleWrapper;
class CSSMediaRuleWrapper;
class CSSRuleWrapper;
class CSSStyleDeclarationWrapper; class CSSStyleDeclarationWrapper;
class CSSStyleRuleWrapper;
class CSSSupportsRuleWrapper;
class CustomEventWrapper; class CustomEventWrapper;
class DocumentFragmentWrapper; class DocumentFragmentWrapper;
class DocumentTypeWrapper; class DocumentTypeWrapper;

View file

@ -3,17 +3,17 @@
libweb_js_wrapper(Crypto/Crypto) libweb_js_wrapper(Crypto/Crypto)
libweb_js_wrapper(Crypto/SubtleCrypto) libweb_js_wrapper(Crypto/SubtleCrypto)
libweb_js_wrapper(CSS/CSSConditionRule) libweb_js_wrapper(CSS/CSSConditionRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSFontFaceRule) libweb_js_wrapper(CSS/CSSFontFaceRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSGroupingRule) libweb_js_wrapper(CSS/CSSGroupingRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSImportRule) libweb_js_wrapper(CSS/CSSImportRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSMediaRule) libweb_js_wrapper(CSS/CSSMediaRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSRule) libweb_js_wrapper(CSS/CSSRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSRuleList NO_INSTANCE) libweb_js_wrapper(CSS/CSSRuleList NO_INSTANCE)
libweb_js_wrapper(CSS/CSSStyleDeclaration) libweb_js_wrapper(CSS/CSSStyleDeclaration)
libweb_js_wrapper(CSS/CSSStyleRule) libweb_js_wrapper(CSS/CSSStyleRule NO_INSTANCE)
libweb_js_wrapper(CSS/CSSStyleSheet NO_INSTANCE) libweb_js_wrapper(CSS/CSSStyleSheet NO_INSTANCE)
libweb_js_wrapper(CSS/CSSSupportsRule) libweb_js_wrapper(CSS/CSSSupportsRule NO_INSTANCE)
libweb_js_wrapper(CSS/MediaList) libweb_js_wrapper(CSS/MediaList)
libweb_js_wrapper(CSS/MediaQueryList) libweb_js_wrapper(CSS/MediaQueryList)
libweb_js_wrapper(CSS/MediaQueryListEvent) libweb_js_wrapper(CSS/MediaQueryListEvent)