summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/CSS
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS')
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp8
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSConditionRule.h10
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSConditionRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp14
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h19
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp28
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h20
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSGroupingRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp22
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSImportRule.h32
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSImportRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp13
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSMediaRule.h18
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRule.cpp15
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRule.h34
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp45
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRuleList.h30
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp13
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleRule.h19
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleRule.idl1
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp15
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h7
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp12
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h19
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSSupportsRule.idl2
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp46
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h9
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.cpp4
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.h2
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 };