LibWeb: Make StyleSheet and CSSStyleSheet GC-allocated

This commit is contained in:
Andreas Kling 2022-08-07 13:14:54 +02:00
parent 0fe923e355
commit 5d60212076
Notes: sideshowbarker 2024-07-17 07:29:15 +09:00
21 changed files with 166 additions and 96 deletions

View file

@ -73,9 +73,24 @@ static StringView sequence_storage_type_to_cpp_storage_type_name(SequenceStorage
}
}
static bool impl_is_wrapper(Type const& type)
{
if (type.name == "StyleSheet"sv)
return true;
if (type.name == "CSSStyleSheet"sv)
return true;
return false;
}
CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
{
if (is_wrappable_type(type)) {
if (impl_is_wrapper(type)) {
return { .name = String::formatted("JS::Handle<{}>", type.name), .sequence_storage_type = SequenceStorageType::MarkedVector };
}
if (type.nullable)
return { .name = String::formatted("RefPtr<{}>", type.name), .sequence_storage_type = SequenceStorageType::Vector };

View file

@ -36,6 +36,8 @@ public:
virtual void initialize(JS::Realm&) override;
virtual ~WindowObject() override = default;
JS::Realm& realm() const { return shape().realm(); }
HTML::Window& impl() { return *m_impl; }
const HTML::Window& impl() const { return *m_impl; }

View file

@ -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();

View file

@ -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<>

View file

@ -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());

View file

@ -21,16 +21,16 @@ class CSSImportRule;
class CSSStyleSheet final
: public StyleSheet
, public Weakable<CSSStyleSheet> {
JS_OBJECT(CSSStyleSheet, StyleSheet);
public:
using WrapperType = Bindings::CSSStyleSheetWrapper;
static NonnullRefPtr<CSSStyleSheet> create(NonnullRefPtrVector<CSSRule> rules, Optional<AK::URL> location)
{
return adopt_ref(*new CSSStyleSheet(move(rules), move(location)));
}
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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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() };

View file

@ -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)

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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;
};
}

View file

@ -1610,7 +1610,7 @@ void Document::evaluate_media_rules()
{
bool any_media_queries_changed_match_state = false;
for (auto& style_sheet : style_sheets().sheets()) {
if (style_sheet.evaluate_media_queries(window()))
if (style_sheet->evaluate_media_queries(window()))
any_media_queries_changed_match_state = true;
}
@ -1837,4 +1837,11 @@ void Document::set_window(Badge<HTML::BrowsingContext>, HTML::Window& window)
m_window = window;
}
Bindings::WindowObject& Document::preferred_window_object() const
{
if (m_window && m_window->wrapper())
return const_cast<Bindings::WindowObject&>(*m_window->wrapper());
return Bindings::main_thread_internal_window_object();
}
}

View file

@ -58,6 +58,11 @@ public:
static NonnullRefPtr<Document> create_with_global_object(Bindings::WindowObject&);
virtual ~Document() override;
// NOTE: This returns the web-facing window object if there is one,
// otherwise it returns the internal window object.
// FIXME: Remove this when Document is a JS::Object.
Bindings::WindowObject& preferred_window_object() const;
size_t next_layout_node_serial_id(Badge<Layout::Node>) { return m_next_layout_node_serial_id++; }
size_t layout_node_count() const { return m_next_layout_node_serial_id; }

View file

@ -468,7 +468,6 @@ class CSSRuleListWrapper;
class CSSRuleWrapper;
class CSSStyleDeclarationWrapper;
class CSSStyleRuleWrapper;
class CSSStyleSheetWrapper;
class CSSSupportsRuleWrapper;
class CustomEventWrapper;
class DocumentFragmentWrapper;
@ -603,7 +602,6 @@ class SelectionWrapper;
class StaticRangeWrapper;
class StorageWrapper;
class StyleSheetListWrapper;
class StyleSheetWrapper;
class SubmitEventWrapper;
class SubtleCryptoWrapper;
class SVGAnimatedLengthWrapper;

View file

@ -126,14 +126,14 @@ void HTMLLinkElement::resource_did_load_stylesheet()
}
}
auto sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(document(), resource()->url()), resource()->encoded_data());
auto* sheet = parse_css_stylesheet(CSS::Parser::ParsingContext(document(), resource()->url()), resource()->encoded_data());
if (!sheet) {
dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Failed to parse stylesheet: {}", resource()->url());
return;
}
sheet->set_owner_node(this);
document().style_sheets().add_sheet(sheet.release_nonnull());
document().style_sheets().add_sheet(*sheet);
}
void HTMLLinkElement::resource_did_load_favicon()

View file

@ -38,27 +38,25 @@ void HTMLStyleElement::removed_from(Node* old_parent)
}
// https://www.w3.org/TR/cssom/#remove-a-css-style-sheet
static void remove_a_css_style_sheet(DOM::Document& document, NonnullRefPtr<CSS::CSSStyleSheet> sheet)
static void remove_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet)
{
VERIFY(sheet.ptr());
// 1. Remove the CSS style sheet from the list of document or shadow root CSS style sheets.
document.style_sheets().remove_sheet(sheet);
// 2. Set the CSS style sheets parent CSS style sheet, owner node and owner CSS rule to null.
sheet->set_parent_css_style_sheet(nullptr);
sheet->set_owner_node(nullptr);
sheet->set_owner_css_rule(nullptr);
sheet.set_parent_css_style_sheet(nullptr);
sheet.set_owner_node(nullptr);
sheet.set_owner_css_rule(nullptr);
}
// https://www.w3.org/TR/cssom/#add-a-css-style-sheet
static void add_a_css_style_sheet(DOM::Document& document, NonnullRefPtr<CSS::CSSStyleSheet> sheet)
static void add_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet)
{
// 1. Add the CSS style sheet to the list of document or shadow root CSS style sheets at the appropriate location. The remainder of these steps deal with the disabled flag.
document.style_sheets().add_sheet(sheet);
// 2. If the disabled flag is set, then return.
if (sheet->disabled())
if (sheet.disabled())
return;
// FIXME: 3. If the title is not the empty string, the alternate flag is unset, and preferred CSS style sheet set name is the empty string change the preferred CSS style sheet set name to the title.
@ -72,23 +70,23 @@ static void add_a_css_style_sheet(DOM::Document& document, NonnullRefPtr<CSS::CS
}
// https://www.w3.org/TR/cssom/#create-a-css-style-sheet
static void create_a_css_style_sheet(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, String location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, NonnullRefPtr<CSS::CSSStyleSheet> sheet)
static void create_a_css_style_sheet(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, String location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
{
// 1. Create a new CSS style sheet object and set its properties as specified.
// FIXME: We receive `sheet` from the caller already. This is weird.
sheet->set_parent_css_style_sheet(parent_style_sheet);
sheet->set_owner_css_rule(owner_rule);
sheet->set_owner_node(owner_node);
sheet->set_type(move(type));
sheet->set_media(move(media));
sheet->set_title(move(title));
sheet->set_alternate(alternate);
sheet->set_origin_clean(origin_clean);
sheet->set_location(move(location));
sheet.set_parent_css_style_sheet(parent_style_sheet);
sheet.set_owner_css_rule(owner_rule);
sheet.set_owner_node(owner_node);
sheet.set_type(move(type));
sheet.set_media(move(media));
sheet.set_title(move(title));
sheet.set_alternate(alternate);
sheet.set_origin_clean(origin_clean);
sheet.set_location(move(location));
// 2. Then run the add a CSS style sheet steps for the newly created CSS style sheet.
add_a_css_style_sheet(document, move(sheet));
add_a_css_style_sheet(document, sheet);
}
// The user agent must run the "update a style block" algorithm whenever one of the following conditions occur:
@ -106,11 +104,11 @@ void HTMLStyleElement::update_a_style_block()
// 1. Let element be the style element.
// 2. If element has an associated CSS style sheet, remove the CSS style sheet in question.
if (m_associated_css_style_sheet) {
if (m_associated_css_style_sheet.cell()) {
remove_a_css_style_sheet(document(), *m_associated_css_style_sheet);
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
m_associated_css_style_sheet = nullptr;
m_associated_css_style_sheet = {};
}
// 3. If element is not connected, then return.
@ -131,7 +129,7 @@ void HTMLStyleElement::update_a_style_block()
return;
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
m_associated_css_style_sheet = sheet;
m_associated_css_style_sheet = JS::make_handle(sheet);
// 6. Create a CSS style sheet with the following properties...
create_a_css_style_sheet(
@ -145,14 +143,21 @@ void HTMLStyleElement::update_a_style_block()
{},
nullptr,
nullptr,
sheet.release_nonnull());
*sheet);
}
// https://www.w3.org/TR/cssom/#dom-linkstyle-sheet
RefPtr<CSS::CSSStyleSheet> HTMLStyleElement::sheet() const
CSS::CSSStyleSheet* HTMLStyleElement::sheet()
{
// The sheet attribute must return the associated CSS style sheet for the node or null if there is no associated CSS style sheet.
return m_associated_css_style_sheet;
return m_associated_css_style_sheet.cell();
}
// https://www.w3.org/TR/cssom/#dom-linkstyle-sheet
CSS::CSSStyleSheet const* HTMLStyleElement::sheet() const
{
// The sheet attribute must return the associated CSS style sheet for the node or null if there is no associated CSS style sheet.
return m_associated_css_style_sheet.cell();
}
}

View file

@ -24,11 +24,12 @@ public:
void update_a_style_block();
RefPtr<CSS::CSSStyleSheet> sheet() const;
CSS::CSSStyleSheet* sheet();
CSS::CSSStyleSheet const* sheet() const;
private:
// https://www.w3.org/TR/cssom/#associated-css-style-sheet
RefPtr<CSS::CSSStyleSheet> m_associated_css_style_sheet;
JS::Handle<CSS::CSSStyleSheet> m_associated_css_style_sheet;
};
}

View file

@ -12,13 +12,13 @@ libweb_js_wrapper(CSS/CSSRule)
libweb_js_wrapper(CSS/CSSRuleList)
libweb_js_wrapper(CSS/CSSStyleDeclaration)
libweb_js_wrapper(CSS/CSSStyleRule)
libweb_js_wrapper(CSS/CSSStyleSheet)
libweb_js_wrapper(CSS/CSSStyleSheet NO_INSTANCE)
libweb_js_wrapper(CSS/CSSSupportsRule)
libweb_js_wrapper(CSS/MediaList)
libweb_js_wrapper(CSS/MediaQueryList)
libweb_js_wrapper(CSS/MediaQueryListEvent)
libweb_js_wrapper(CSS/Screen)
libweb_js_wrapper(CSS/StyleSheet)
libweb_js_wrapper(CSS/StyleSheet NO_INSTANCE)
libweb_js_wrapper(CSS/StyleSheetList)
libweb_js_wrapper(DOM/AbstractRange)
libweb_js_wrapper(DOM/Attribute)

View file

@ -206,7 +206,7 @@ void ConnectionFromClient::debug_request(String const& request, String const& ar
if (request == "dump-style-sheets") {
if (auto* doc = page().top_level_browsing_context().active_document()) {
for (auto& sheet : doc->style_sheets().sheets()) {
Web::dump_sheet(sheet);
Web::dump_sheet(*sheet);
}
}
}