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