1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 13:07:46 +00:00

LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtr

This commit is contained in:
Matthew Olsson 2023-02-26 16:09:02 -07:00 committed by Andreas Kling
parent 1df3652e27
commit 7c0c1c8f49
214 changed files with 825 additions and 827 deletions

View file

@ -156,7 +156,7 @@ JS::VM& main_thread_vm()
// 2. Let script execution context be callback.[[HostDefined]].[[ActiveScriptContext]]. (NOTE: Not necessary)
// 3. Prepare to run a callback with incumbent settings.
callback_host_defined.incumbent_settings.prepare_to_run_callback();
callback_host_defined.incumbent_settings->prepare_to_run_callback();
// 4. If script execution context is not null, then push script execution context onto the JavaScript execution context stack.
if (callback_host_defined.active_script_context)
@ -172,7 +172,7 @@ JS::VM& main_thread_vm()
}
// 7. Clean up after running a callback with incumbent settings.
callback_host_defined.incumbent_settings.clean_up_after_running_callback();
callback_host_defined.incumbent_settings->clean_up_after_running_callback();
// 8. Return result.
return result;
@ -419,7 +419,7 @@ void queue_mutation_observer_microtask(DOM::Document const& document)
// 4. If records is not empty, then invoke mos callback with « records, mo », and mo. If this throws an exception, catch it, and report the exception.
if (!records.is_empty()) {
auto& callback = mutation_observer->callback();
auto& realm = callback.callback_context.realm();
auto& realm = callback.callback_context->realm();
auto wrapped_records = MUST(JS::Array::create(realm, 0));
for (size_t i = 0; i < records.size(); ++i) {
@ -446,7 +446,7 @@ NonnullOwnPtr<JS::ExecutionContext> create_a_new_javascript_realm(JS::VM& vm, Fu
auto realm_execution_context = MUST(JS::Realm::initialize_host_defined_realm(vm, move(create_global_object), move(create_global_this_value)));
// 3. Remove realm execution context from the JavaScript execution context stack.
vm.execution_context_stack().remove_first_matching([&realm_execution_context](auto* execution_context) {
vm.execution_context_stack().remove_first_matching([&realm_execution_context](auto execution_context) {
return execution_context == realm_execution_context.ptr();
});

View file

@ -45,7 +45,7 @@ struct WebEngineCustomJobCallbackData final : public JS::JobCallback::CustomData
virtual ~WebEngineCustomJobCallbackData() override = default;
HTML::EnvironmentSettingsObject& incumbent_settings;
JS::NonnullGCPtr<HTML::EnvironmentSettingsObject> incumbent_settings;
OwnPtr<JS::ExecutionContext> active_script_context;
};

View file

@ -18,8 +18,8 @@ CSSGroupingRule::CSSGroupingRule(JS::Realm& realm, CSSRuleList& rules)
: CSSRule(realm)
, m_rules(rules)
{
for (auto& rule : m_rules)
rule.set_parent_rule(this);
for (auto& rule : *m_rules)
rule->set_parent_rule(this);
}
JS::ThrowCompletionOr<void> CSSGroupingRule::initialize(JS::Realm& realm)
@ -33,32 +33,32 @@ JS::ThrowCompletionOr<void> CSSGroupingRule::initialize(JS::Realm& realm)
void CSSGroupingRule::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_rules);
visitor.visit(m_rules);
}
WebIDL::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;
}
WebIDL::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)
rule.set_parent_style_sheet(parent_style_sheet);
for (auto& rule : *m_rules)
rule->set_parent_style_sheet(parent_style_sheet);
}
}

View file

@ -22,7 +22,7 @@ public:
CSSRuleList const& css_rules() const { return m_rules; }
CSSRuleList& css_rules() { return m_rules; }
CSSRuleList* css_rules_for_bindings() { return &m_rules; }
CSSRuleList* css_rules_for_bindings() { return m_rules; }
WebIDL::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0);
WebIDL::ExceptionOr<void> delete_rule(u32 index);
@ -37,7 +37,7 @@ protected:
virtual void visit_edges(Cell::Visitor&) override;
private:
CSSRuleList& m_rules;
JS::NonnullGCPtr<CSSRuleList> m_rules;
};
}

View file

@ -34,17 +34,17 @@ JS::ThrowCompletionOr<void> CSSMediaRule::initialize(JS::Realm& realm)
void CSSMediaRule::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_media);
visitor.visit(m_media);
}
DeprecatedString CSSMediaRule::condition_text() const
{
return m_media.media_text();
return m_media->media_text();
}
void CSSMediaRule::set_condition_text(DeprecatedString text)
{
m_media.set_media_text(text);
m_media->set_media_text(text);
}
// https://www.w3.org/TR/cssom-1/#serialize-a-css-rule

View file

@ -26,11 +26,11 @@ public:
virtual DeprecatedString condition_text() const override;
virtual void set_condition_text(DeprecatedString) override;
virtual bool condition_matches() const override { return m_media.matches(); }
virtual bool condition_matches() const override { return m_media->matches(); }
MediaList* media() const { return &m_media; }
MediaList* media() const { return m_media; }
bool evaluate(HTML::Window const& window) { return m_media.evaluate(window); }
bool evaluate(HTML::Window const& window) { return m_media->evaluate(window); }
private:
CSSMediaRule(JS::Realm&, MediaList&, CSSRuleList&);
@ -39,7 +39,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override;
virtual DeprecatedString serialized() const override;
MediaList& m_media;
JS::NonnullGCPtr<MediaList> m_media;
};
template<>

View file

@ -47,7 +47,7 @@ void CSSRuleList::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
for (auto& rule : m_rules)
visitor.visit(&rule);
visitor.visit(rule);
}
bool CSSRuleList::is_supported_property_index(u32 index) const
@ -123,23 +123,23 @@ WebIDL::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index)
void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
{
for (auto const& rule : m_rules) {
switch (rule.type()) {
switch (rule->type()) {
case CSSRule::Type::FontFace:
break;
case CSSRule::Type::Import: {
auto const& import_rule = static_cast<CSSImportRule const&>(rule);
auto const& import_rule = static_cast<CSSImportRule const&>(*rule);
if (import_rule.has_import_result() && import_rule.loaded_style_sheet())
import_rule.loaded_style_sheet()->for_each_effective_style_rule(callback);
break;
}
case CSSRule::Type::Media:
static_cast<CSSMediaRule const&>(rule).for_each_effective_style_rule(callback);
static_cast<CSSMediaRule const&>(*rule).for_each_effective_style_rule(callback);
break;
case CSSRule::Type::Style:
callback(static_cast<CSSStyleRule const&>(rule));
callback(static_cast<CSSStyleRule const&>(*rule));
break;
case CSSRule::Type::Supports:
static_cast<CSSSupportsRule const&>(rule).for_each_effective_style_rule(callback);
static_cast<CSSSupportsRule const&>(*rule).for_each_effective_style_rule(callback);
break;
}
}
@ -150,17 +150,17 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window)
bool any_media_queries_changed_match_state = false;
for (auto& rule : m_rules) {
switch (rule.type()) {
switch (rule->type()) {
case CSSRule::Type::FontFace:
break;
case CSSRule::Type::Import: {
auto& import_rule = verify_cast<CSSImportRule>(rule);
auto& import_rule = verify_cast<CSSImportRule>(*rule);
if (import_rule.has_import_result() && import_rule.loaded_style_sheet() && import_rule.loaded_style_sheet()->evaluate_media_queries(window))
any_media_queries_changed_match_state = true;
break;
}
case CSSRule::Type::Media: {
auto& media_rule = verify_cast<CSSMediaRule>(rule);
auto& media_rule = verify_cast<CSSMediaRule>(*rule);
bool did_match = media_rule.condition_matches();
bool now_matches = media_rule.evaluate(window);
if (did_match != now_matches)
@ -172,7 +172,7 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window)
case CSSRule::Type::Style:
break;
case CSSRule::Type::Supports: {
auto& supports_rule = verify_cast<CSSSupportsRule>(rule);
auto& supports_rule = verify_cast<CSSSupportsRule>(*rule);
if (supports_rule.condition_matches() && supports_rule.css_rules().evaluate_media_queries(window))
any_media_queries_changed_match_state = true;
break;

View file

@ -32,26 +32,23 @@ public:
{
if (index >= length())
return nullptr;
return &m_rules[index];
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<Vector<CSSRule&> const, CSSRule const>;
using Iterator = AK::SimpleIterator<Vector<CSSRule&>, CSSRule>;
auto begin() const { return m_rules.begin(); }
auto begin() { return m_rules.begin(); }
ConstIterator const begin() const { return m_rules.begin(); }
Iterator begin() { return m_rules.begin(); }
ConstIterator const end() const { return m_rules.end(); }
Iterator end() { return m_rules.end(); }
auto end() const { return m_rules.end(); }
auto end() { return m_rules.end(); }
virtual bool is_supported_property_index(u32 index) const override;
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
@ -82,7 +79,7 @@ private:
virtual bool named_property_setter_has_identifier() const override { return false; }
virtual bool named_property_deleter_has_identifier() const override { return false; }
Vector<CSSRule&> m_rules;
Vector<JS::NonnullGCPtr<CSSRule>> m_rules;
};
}

View file

@ -35,13 +35,13 @@ JS::ThrowCompletionOr<void> CSSStyleRule::initialize(JS::Realm& realm)
void CSSStyleRule::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_declaration);
visitor.visit(m_declaration);
}
// https://www.w3.org/TR/cssom/#dom-cssstylerule-style
CSSStyleDeclaration* CSSStyleRule::style()
{
return &m_declaration;
return m_declaration;
}
// https://www.w3.org/TR/cssom/#serialize-a-css-rule

View file

@ -40,7 +40,7 @@ private:
virtual DeprecatedString serialized() const override;
Vector<NonnullRefPtr<Selector>> m_selectors;
CSSStyleDeclaration& m_declaration;
JS::NonnullGCPtr<CSSStyleDeclaration> m_declaration;
};
template<>

View file

@ -27,7 +27,7 @@ CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& me
set_location(location->to_deprecated_string());
for (auto& rule : *m_rules)
rule.set_parent_style_sheet(this);
rule->set_parent_style_sheet(this);
}
JS::ThrowCompletionOr<void> CSSStyleSheet::initialize(JS::Realm& realm)
@ -106,7 +106,7 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::remove_rule(unsigned index)
void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
{
if (m_media.matches()) {
if (m_media->matches()) {
m_rules->for_each_effective_style_rule(callback);
}
}
@ -115,8 +115,8 @@ bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
{
bool any_media_queries_changed_match_state = false;
bool did_match = m_media.matches();
bool now_matches = m_media.evaluate(window);
bool did_match = m_media->matches();
bool now_matches = m_media->evaluate(window);
if (did_match != now_matches)
any_media_queries_changed_match_state = true;
if (now_matches && m_rules->evaluate_media_queries(window))

View file

@ -54,10 +54,10 @@ private:
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
CSSRuleList* m_rules { nullptr };
JS::GCPtr<CSSRuleList> m_rules;
JS::GCPtr<StyleSheetList> m_style_sheet_list;
CSSRule* m_owner_css_rule { nullptr };
JS::GCPtr<CSSRule> m_owner_css_rule;
};
}

View file

@ -48,8 +48,8 @@ public:
JS::Realm& realm() const { return m_realm; }
private:
JS::Realm& m_realm;
DOM::Document const* m_document { nullptr };
JS::NonnullGCPtr<JS::Realm> m_realm;
JS::GCPtr<DOM::Document const> m_document;
PropertyID m_current_property_id { PropertyID::Invalid };
AK::URL m_url;
};

View file

@ -136,8 +136,8 @@ static void collect_style_sheets(CSSStyleSheet const& sheet, Vector<JS::NonnullG
{
sheets.append(sheet);
for (auto const& rule : sheet.rules()) {
if (rule.type() == CSSRule::Type::Import) {
auto const& import_rule = static_cast<CSSImportRule const&>(rule);
if (rule->type() == CSSRule::Type::Import) {
auto const& import_rule = static_cast<CSSImportRule const&>(*rule);
if (auto const* imported_sheet = import_rule.loaded_style_sheet()) {
collect_style_sheets(*imported_sheet, sheets);
}
@ -991,7 +991,7 @@ CSSPixels StyleComputer::root_element_font_size() const
{
constexpr float default_root_element_font_size = 16;
auto const* root_element = m_document.first_child_of_type<HTML::HTMLHtmlElement>();
auto const* root_element = m_document->first_child_of_type<HTML::HTMLHtmlElement>();
if (!root_element)
return default_root_element_font_size;
@ -1588,9 +1588,9 @@ void StyleComputer::did_load_font([[maybe_unused]] FlyString const& family_name)
void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet)
{
for (auto const& rule : static_cast<CSSStyleSheet const&>(sheet).rules()) {
if (!is<CSSFontFaceRule>(rule))
if (!is<CSSFontFaceRule>(*rule))
continue;
auto const& font_face = static_cast<CSSFontFaceRule const&>(rule).font_face();
auto const& font_face = static_cast<CSSFontFaceRule const&>(*rule).font_face();
if (font_face.sources().is_empty())
continue;
if (m_loaded_fonts.contains(font_face.font_family()))
@ -1620,7 +1620,7 @@ void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet)
continue;
LoadRequest request;
auto url = m_document.parse_url(candidate_url.value().to_deprecated_string());
auto url = m_document->parse_url(candidate_url.value().to_deprecated_string());
auto loader = make<FontLoader>(const_cast<StyleComputer&>(*this), font_face.font_family(), move(url));
const_cast<StyleComputer&>(*this).m_loaded_fonts.set(font_face.font_family().to_string(), move(loader));
}

View file

@ -21,7 +21,7 @@
namespace Web::CSS {
struct MatchingRule {
CSSStyleRule const* rule { nullptr };
JS::GCPtr<CSSStyleRule const> rule;
size_t style_sheet_index { 0 };
size_t rule_index { 0 };
size_t selector_index { 0 };
@ -114,7 +114,7 @@ private:
void build_rule_cache();
void build_rule_cache_if_needed() const;
DOM::Document& m_document;
JS::NonnullGCPtr<DOM::Document> m_document;
struct RuleCache {
HashMap<FlyString, Vector<MatchingRule>> rules_by_id;

View file

@ -36,12 +36,12 @@ public:
MediaList* media() const
{
return &m_media;
return m_media;
}
void set_media(DeprecatedString media)
{
m_media.set_media_text(media);
m_media->set_media_text(media);
}
bool is_alternate() const { return m_alternate; }
@ -59,7 +59,7 @@ protected:
explicit StyleSheet(JS::Realm&, MediaList& media);
virtual void visit_edges(Cell::Visitor&) override;
MediaList& m_media;
JS::NonnullGCPtr<MediaList> m_media;
private:
JS::GCPtr<DOM::Element> m_owner_node;

View file

@ -24,9 +24,9 @@ void StyleSheetList::add_sheet(CSSStyleSheet& sheet)
return;
}
m_document.style_computer().invalidate_rule_cache();
m_document.style_computer().load_fonts_from_sheet(sheet);
m_document.invalidate_style();
m_document->style_computer().invalidate_rule_cache();
m_document->style_computer().load_fonts_from_sheet(sheet);
m_document->invalidate_style();
}
void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
@ -41,8 +41,8 @@ void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
sort_sheets();
m_document.style_computer().invalidate_rule_cache();
m_document.invalidate_style();
m_document->style_computer().invalidate_rule_cache();
m_document->invalidate_style();
}
WebIDL::ExceptionOr<JS::NonnullGCPtr<StyleSheetList>> StyleSheetList::create(DOM::Document& document)

View file

@ -60,7 +60,7 @@ private:
void sort_sheets();
DOM::Document& m_document;
JS::NonnullGCPtr<DOM::Document> m_document;
Vector<JS::NonnullGCPtr<CSSStyleSheet>> m_sheets;
};

View file

@ -59,7 +59,7 @@ void AccessibilityTreeNode::serialize_tree_as_json(JsonObjectSerializer<StringBu
if (value()->has_child_nodes()) {
auto node_children = MUST(object.add_array("children"sv));
for (auto* child : children()) {
for (auto& child : children()) {
if (child->value()->is_uninteresting_whitespace_node())
continue;
JsonObjectSerializer<StringBuilder> child_object = MUST(node_children.add_object());

View file

@ -22,7 +22,7 @@ public:
JS::GCPtr<DOM::Node const> value() const { return m_value; }
void set_value(JS::GCPtr<DOM::Node const> value) { m_value = value; }
Vector<AccessibilityTreeNode*> children() const { return m_children; }
Vector<JS::GCPtr<AccessibilityTreeNode>> children() const { return m_children; }
void append_child(AccessibilityTreeNode* child) { m_children.append(child); }
void serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object, Document const&) const;
@ -34,7 +34,7 @@ private:
explicit AccessibilityTreeNode(JS::GCPtr<DOM::Node const>);
JS::GCPtr<DOM::Node const> m_value;
Vector<AccessibilityTreeNode*> m_children;
Vector<JS::GCPtr<AccessibilityTreeNode>> m_children;
};
}

View file

@ -36,7 +36,7 @@ private:
Document& document() { return m_document; }
Document const& document() const { return m_document; }
Document& m_document;
JS::NonnullGCPtr<Document> m_document;
};
}

View file

@ -567,7 +567,7 @@ private:
bool m_needs_full_style_update { false };
HashTable<NodeIterator*> m_node_iterators;
HashTable<JS::GCPtr<NodeIterator>> m_node_iterators;
// https://html.spec.whatwg.org/multipage/dom.html#is-initial-about:blank
bool m_is_initial_about_blank { false };

View file

@ -83,7 +83,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<JS::Handle<DOM::DOMEvent
// 6. Let global be listener callbacks associated Realms global object.
auto& callback = listener->callback->callback();
auto& realm = callback.callback.shape().realm();
auto& realm = callback.callback->shape().realm();
auto& global = realm.global_object();
// 7. Let currentEvent be undefined.

View file

@ -464,12 +464,12 @@ WebIDL::CallbackType* EventTarget::get_current_value_of_event_handler(Deprecated
function->set_script_or_module({});
// 12. Set eventHandler's value to the result of creating a Web IDL EventHandler callback function object whose object reference is function and whose callback context is settings object.
event_handler->value = realm.heap().allocate_without_realm<WebIDL::CallbackType>(*function, settings_object).ptr();
event_handler->value = JS::GCPtr(realm.heap().allocate_without_realm<WebIDL::CallbackType>(*function, settings_object));
}
// 4. Return eventHandler's value.
VERIFY(event_handler->value.has<WebIDL::CallbackType*>());
return *event_handler->value.get_pointer<WebIDL::CallbackType*>();
VERIFY(event_handler->value.has<JS::GCPtr<WebIDL::CallbackType>>());
return *event_handler->value.get_pointer<JS::GCPtr<WebIDL::CallbackType>>();
}
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:event-handler-idl-attributes-3
@ -512,7 +512,7 @@ void EventTarget::set_event_handler_attribute(DeprecatedFlyString const& name, W
auto& event_handler = event_handler_iterator->value;
event_handler->value = value;
event_handler->value = JS::GCPtr(value);
// 4. Activate an event handler given eventTarget and name.
// NOTE: See the optimization comment above.

View file

@ -80,7 +80,7 @@ WebIDL::ExceptionOr<void> MutationObserver::observe(Node& target, MutationObserv
// 7. For each registered of targets registered observer list, if registereds observer is this:
bool updated_existing_observer = false;
for (auto& registered_observer : target.registered_observers_list()) {
if (registered_observer.observer().ptr() != this)
if (registered_observer->observer().ptr() != this)
continue;
updated_existing_observer = true;
@ -92,12 +92,12 @@ WebIDL::ExceptionOr<void> MutationObserver::observe(Node& target, MutationObserv
continue;
node->registered_observers_list().remove_all_matching([&registered_observer](RegisteredObserver& observer) {
return is<TransientRegisteredObserver>(observer) && verify_cast<TransientRegisteredObserver>(observer).source().ptr() == &registered_observer;
return is<TransientRegisteredObserver>(observer) && verify_cast<TransientRegisteredObserver>(observer).source().ptr() == registered_observer;
});
}
// 2. Set registereds options to options.
registered_observer.set_options(options);
registered_observer->set_options(options);
break;
}

View file

@ -602,8 +602,8 @@ void Node::remove(bool suppress_observers)
// whose observer is registereds observer, options is registereds options, and source is registered to nodes registered observer list.
for (auto* inclusive_ancestor = parent; inclusive_ancestor; inclusive_ancestor = inclusive_ancestor->parent()) {
for (auto& registered : inclusive_ancestor->m_registered_observer_list) {
if (registered.options().subtree) {
auto transient_observer = TransientRegisteredObserver::create(registered.observer(), registered.options(), registered);
if (registered->options().subtree) {
auto transient_observer = TransientRegisteredObserver::create(registered->observer(), registered->options(), registered);
m_registered_observer_list.append(move(transient_observer));
}
}
@ -1411,7 +1411,7 @@ void Node::queue_mutation_record(DeprecatedFlyString const& type, DeprecatedStri
for (auto& node : nodes) {
for (auto& registered_observer : node->m_registered_observer_list) {
// 1. Let options be registereds options.
auto& options = registered_observer.options();
auto& options = registered_observer->options();
// 2. If none of the following are true
// - node is not target and options["subtree"] is false
@ -1426,7 +1426,7 @@ void Node::queue_mutation_record(DeprecatedFlyString const& type, DeprecatedStri
&& !(type == MutationType::characterData && (!options.character_data.has_value() || !options.character_data.value()))
&& !(type == MutationType::childList && !options.child_list)) {
// 1. Let mo be registereds observer.
auto mutation_observer = registered_observer.observer();
auto mutation_observer = registered_observer->observer();
// 2. If interestedObservers[mo] does not exist, then set interestedObservers[mo] to null.
if (!interested_observers.contains(mutation_observer))

View file

@ -645,7 +645,7 @@ protected:
// https://dom.spec.whatwg.org/#registered-observer-list
// "Nodes have a strong reference to registered observers in their registered observer list." https://dom.spec.whatwg.org/#garbage-collection
Vector<RegisteredObserver&> m_registered_observer_list;
Vector<JS::NonnullGCPtr<RegisteredObserver>> m_registered_observer_list;
void build_accessibility_tree(AccessibilityTreeNode& parent);

View file

@ -24,7 +24,7 @@ NodeFilter::NodeFilter(JS::Realm& realm, WebIDL::CallbackType& callback)
void NodeFilter::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_callback);
visitor.visit(m_callback);
}
}

View file

@ -46,7 +46,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override;
WebIDL::CallbackType& m_callback;
JS::NonnullGCPtr<WebIDL::CallbackType> m_callback;
};
AK_ENUM_BITWISE_OPERATORS(NodeFilter::WhatToShow);

View file

@ -42,7 +42,7 @@ Node const* StaticNodeList::item(u32 index) const
// The item(index) method must return the indexth node in the collection. If there is no indexth node in the collection, then the method must return null.
if (index >= m_static_nodes.size())
return nullptr;
return &m_static_nodes[index];
return m_static_nodes[index];
}
// https://dom.spec.whatwg.org/#ref-for-dfn-supported-property-indices

View file

@ -29,7 +29,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override;
Vector<Node&> m_static_nodes;
Vector<JS::NonnullGCPtr<Node>> m_static_nodes;
};
}

View file

@ -519,7 +519,7 @@ WebIDL::ExceptionOr<void> fetch_response_handover(JS::Realm& realm, Infrastructu
// timingInfos server-timing headers to the result of getting, decoding, and splitting `Server-Timing` from
// responses header list.
// The user agent may decide to expose `Server-Timing` headers to non-secure contexts requests as well.
auto* client = fetch_params.request()->client();
auto client = fetch_params.request()->client();
if (!response.is_network_error() && client != nullptr && HTML::is_secure_context(*client)) {
auto server_timing_headers = TRY_OR_THROW_OOM(vm, response.header_list()->get_decode_and_split("Server-Timing"sv.bytes()));
if (server_timing_headers.has_value())
@ -588,7 +588,7 @@ WebIDL::ExceptionOr<void> fetch_response_handover(JS::Realm& realm, Infrastructu
// 3. If fetchParamss requests initiator type is non-null and fetchParamss requests clients global
// object is fetchParamss task destination, then run fetchParamss controllers report timing steps
// given fetchParamss requests clients global object.
auto* client = fetch_params.request()->client();
auto client = fetch_params.request()->client();
auto const* task_destination_global_object = fetch_params.task_destination().get_pointer<JS::NonnullGCPtr<JS::Object>>();
if (client != nullptr && task_destination_global_object != nullptr) {
if (fetch_params.request()->initiator_type().has_value() && &client->global_object() == task_destination_global_object->ptr())
@ -1459,7 +1459,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
if (response->status() == 401
&& http_request->response_tainting() != Infrastructure::Request::ResponseTainting::CORS
&& include_credentials == IncludeCredentials::Yes
&& request->window().has<HTML::EnvironmentSettingsObject*>()) {
&& request->window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()) {
// 1. Needs testing: multiple `WWW-Authenticate` headers, missing, parsing issues.
// (Red box in the spec, no-op)

View file

@ -48,7 +48,7 @@ JS::ThrowCompletionOr<void> HeadersIterator::initialize(JS::Realm& realm)
void HeadersIterator::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_headers);
visitor.visit(m_headers);
}
// https://webidl.spec.whatwg.org/#es-iterable, Step 2
@ -56,7 +56,7 @@ JS::ThrowCompletionOr<JS::Object*> HeadersIterator::next()
{
// The value pairs to iterate over are the return value of running sort and combine with thiss header list.
auto value_pairs_to_iterate_over = [&]() -> JS::ThrowCompletionOr<Vector<Fetch::Infrastructure::Header>> {
auto headers_or_error = m_headers.m_header_list->sort_and_combine();
auto headers_or_error = m_headers->m_header_list->sort_and_combine();
if (headers_or_error.is_error())
return vm().throw_completion<JS::InternalError>(JS::ErrorType::NotEnoughMemoryToAllocate);
return headers_or_error.release_value();

View file

@ -28,7 +28,7 @@ private:
HeadersIterator(Headers const&, JS::Object::PropertyKind iteration_kind);
Headers const& m_headers;
JS::NonnullGCPtr<Headers const> m_headers;
JS::Object::PropertyKind m_iteration_kind;
size_t m_index { 0 };
};

View file

@ -157,8 +157,8 @@ public:
using OriginType = Variant<Origin, HTML::Origin>;
using PolicyContainerType = Variant<PolicyContainer, HTML::PolicyContainer>;
using ReferrerType = Variant<Referrer, AK::URL>;
using ReservedClientType = Variant<Empty, HTML::Environment*, HTML::EnvironmentSettingsObject*>;
using WindowType = Variant<Window, HTML::EnvironmentSettingsObject*>;
using ReservedClientType = Variant<Empty, JS::GCPtr<HTML::Environment>, JS::GCPtr<HTML::EnvironmentSettingsObject>>;
using WindowType = Variant<Window, JS::GCPtr<HTML::EnvironmentSettingsObject>>;
[[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::VM&);
@ -178,8 +178,8 @@ public:
[[nodiscard]] BodyType& body() { return m_body; }
void set_body(BodyType body) { m_body = move(body); }
[[nodiscard]] HTML::EnvironmentSettingsObject const* client() const { return m_client; }
[[nodiscard]] HTML::EnvironmentSettingsObject* client() { return m_client; }
[[nodiscard]] JS::GCPtr<HTML::EnvironmentSettingsObject const> client() const { return m_client; }
[[nodiscard]] JS::GCPtr<HTML::EnvironmentSettingsObject> client() { return m_client; }
void set_client(HTML::EnvironmentSettingsObject* client) { m_client = client; }
[[nodiscard]] ReservedClientType const& reserved_client() const { return m_reserved_client; }
@ -343,7 +343,7 @@ private:
// https://fetch.spec.whatwg.org/#concept-request-client
// A request has an associated client (null or an environment settings object).
HTML::EnvironmentSettingsObject* m_client { nullptr };
JS::GCPtr<HTML::EnvironmentSettingsObject> m_client;
// https://fetch.spec.whatwg.org/#concept-request-reserved-client
// A request has an associated reserved client (null, an environment, or an environment settings object). Unless

View file

@ -157,8 +157,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
auto window = Infrastructure::Request::WindowType { Infrastructure::Request::Window::Client };
// 9. If requests window is an environment settings object and its origin is same origin with origin, then set window to requests window.
if (input_request->window().has<HTML::EnvironmentSettingsObject*>()) {
auto* eso = input_request->window().get<HTML::EnvironmentSettingsObject*>();
if (input_request->window().has<JS::GCPtr<HTML::EnvironmentSettingsObject>>()) {
auto eso = input_request->window().get<JS::GCPtr<HTML::EnvironmentSettingsObject>>();
if (eso->origin().is_same_origin(origin))
window = input_request->window();
}

View file

@ -35,7 +35,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override;
// https://html.spec.whatwg.org/multipage/browsers.html#browsing-context-group-set
OrderedHashTable<BrowsingContext*> m_browsing_context_set;
OrderedHashTable<JS::GCPtr<BrowsingContext>> m_browsing_context_set;
WeakPtr<Page> m_page;
};

View file

@ -38,17 +38,17 @@ void CanvasPath::bezier_curve_to(double cp1x, double cp1y, double cp2x, double c
WebIDL::ExceptionOr<void> CanvasPath::arc(float x, float y, float radius, float start_angle, float end_angle, bool counter_clockwise)
{
if (radius < 0)
return WebIDL::IndexSizeError::create(m_self.realm(), DeprecatedString::formatted("The radius provided ({}) is negative.", radius));
return WebIDL::IndexSizeError::create(m_self->realm(), DeprecatedString::formatted("The radius provided ({}) is negative.", radius));
return ellipse(x, y, radius, radius, 0, start_angle, end_angle, counter_clockwise);
}
WebIDL::ExceptionOr<void> CanvasPath::ellipse(float x, float y, float radius_x, float radius_y, float rotation, float start_angle, float end_angle, bool counter_clockwise)
{
if (radius_x < 0)
return WebIDL::IndexSizeError::create(m_self.realm(), DeprecatedString::formatted("The major-axis radius provided ({}) is negative.", radius_x));
return WebIDL::IndexSizeError::create(m_self->realm(), DeprecatedString::formatted("The major-axis radius provided ({}) is negative.", radius_x));
if (radius_y < 0)
return WebIDL::IndexSizeError::create(m_self.realm(), DeprecatedString::formatted("The minor-axis radius provided ({}) is negative.", radius_y));
return WebIDL::IndexSizeError::create(m_self->realm(), DeprecatedString::formatted("The minor-axis radius provided ({}) is negative.", radius_y));
if (constexpr float tau = M_TAU; (!counter_clockwise && (end_angle - start_angle) >= tau)
|| (counter_clockwise && (start_angle - end_angle) >= tau)) {

View file

@ -36,7 +36,7 @@ protected:
}
private:
Bindings::PlatformObject& m_self;
JS::NonnullGCPtr<Bindings::PlatformObject> m_self;
Gfx::Path m_path;
};

View file

@ -137,7 +137,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
// 5. Otherwise:
else {
// 1. Let crossOriginGet be undefined.
Optional<JS::FunctionObject*> cross_origin_get;
Optional<JS::GCPtr<JS::FunctionObject>> cross_origin_get;
// 2. If e.[[NeedsGet]] is true, then set crossOriginGet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the getter of the IDL attribute P on object O.
if (*entry.needs_get) {
@ -149,7 +149,7 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
}
// 3. Let crossOriginSet be undefined.
Optional<JS::FunctionObject*> cross_origin_set;
Optional<JS::GCPtr<JS::FunctionObject>> cross_origin_set;
// If e.[[NeedsSet]] is true, then set crossOriginSet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the setter of the IDL attribute P on object O.
if (*entry.needs_set) {

View file

@ -24,7 +24,7 @@ void EventHandler::visit_edges(Cell::Visitor& visitor)
Cell::visit_edges(visitor);
visitor.visit(listener);
if (auto* callback = value.get_pointer<WebIDL::CallbackType*>())
if (auto* callback = value.get_pointer<JS::GCPtr<WebIDL::CallbackType>>())
visitor.visit(*callback);
}

View file

@ -23,10 +23,10 @@ public:
// NOTE: This does not contain Empty as part of the optimization of not allocating all event handler attributes up front.
// FIXME: The string should actually be an "internal raw uncompiled handler" struct. This struct is just the uncompiled source code plus a source location for reporting parse errors.
// https://html.spec.whatwg.org/multipage/webappapis.html#internal-raw-uncompiled-handler
Variant<DeprecatedString, WebIDL::CallbackType*> value;
Variant<DeprecatedString, JS::GCPtr<WebIDL::CallbackType>> value;
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-listener
DOM::DOMEventListener* listener { nullptr };
JS::GCPtr<DOM::DOMEventListener> listener;
private:
virtual StringView class_name() const override { return "EventHandler"sv; }

View file

@ -308,7 +308,7 @@ void EventLoop::perform_a_microtask_checkpoint()
// 4. For each environment settings object whose responsible event loop is this event loop, notify about rejected promises on that environment settings object.
for (auto& environment_settings_object : m_related_environment_settings_objects)
environment_settings_object.notify_about_rejected_promises({});
environment_settings_object->notify_about_rejected_promises({});
// FIXME: 5. Cleanup Indexed Database transactions.
@ -362,7 +362,7 @@ void EventLoop::register_environment_settings_object(Badge<EnvironmentSettingsOb
void EventLoop::unregister_environment_settings_object(Badge<EnvironmentSettingsObject>, EnvironmentSettingsObject& environment_settings_object)
{
bool did_remove = m_related_environment_settings_objects.remove_first_matching([&](auto& entry) { return &entry == &environment_settings_object; });
bool did_remove = m_related_environment_settings_objects.remove_first_matching([&](auto& entry) { return entry.ptr() == &environment_settings_object; });
VERIFY(did_remove);
}

View file

@ -101,10 +101,10 @@ private:
Vector<WeakPtr<DOM::Document>> m_documents;
// Used to implement step 4 of "perform a microtask checkpoint".
Vector<EnvironmentSettingsObject&> m_related_environment_settings_objects;
Vector<JS::NonnullGCPtr<EnvironmentSettingsObject>> m_related_environment_settings_objects;
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
Vector<EnvironmentSettingsObject&> m_backup_incumbent_settings_object_stack;
Vector<JS::NonnullGCPtr<EnvironmentSettingsObject>> m_backup_incumbent_settings_object_stack;
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
size_t m_termination_nesting_level { 0 };

View file

@ -12,6 +12,7 @@
#include <AK/StringView.h>
#include <AK/Types.h>
#include <AK/Utf8View.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Forward.h>
#include <LibWeb/HTML/Parser/HTMLToken.h>
@ -176,7 +177,7 @@ private:
void restore_to(Utf8CodePointIterator const& new_iterator);
HTMLToken::Position nth_last_position(size_t n = 0);
HTMLParser* m_parser { nullptr };
JS::GCPtr<HTMLParser> m_parser;
State m_state { State::Data };
State m_return_state { State::Data };

View file

@ -39,7 +39,7 @@ private:
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
JS::Promise* m_promise { nullptr };
JS::GCPtr<JS::Promise> m_promise;
JS::Value m_reason;
};

View file

@ -259,7 +259,7 @@ void EnvironmentSettingsObject::notify_about_rejected_promises(Badge<EventLoop>)
// 4. If p's [[PromiseIsHandled]] internal slot is false, add p to settings object's outstanding rejected promises weak set.
if (!promise->is_handled())
m_outstanding_rejected_promises_weak_set.append(promise);
m_outstanding_rejected_promises_weak_set.append(*promise);
// This algorithm results in promise rejections being marked as handled or not handled. These concepts parallel handled and not handled script errors.
// If a rejection is still not handled after this, then the rejection may be reported to a developer console.

View file

@ -130,7 +130,7 @@ private:
// https://html.spec.whatwg.org/multipage/webappapis.html#outstanding-rejected-promises-weak-set
// The outstanding rejected promises weak set must not create strong references to any of its members, and implementations are free to limit its size, e.g. by removing old entries from it when new ones are added.
Vector<JS::Promise*> m_outstanding_rejected_promises_weak_set;
Vector<JS::GCPtr<JS::Promise>> m_outstanding_rejected_promises_weak_set;
// https://html.spec.whatwg.org/multipage/webappapis.html#about-to-be-notified-rejected-promises-list
Vector<JS::Handle<JS::Promise>> m_about_to_be_notified_rejected_promises_list;

View file

@ -48,7 +48,7 @@ public:
struct Entry {
EntryType type;
JavaScriptModuleScript* module_script;
JS::GCPtr<JavaScriptModuleScript> module_script;
};
bool is_fetching(AK::URL const& url, DeprecatedString const& type) const;

View file

@ -35,7 +35,7 @@ private:
AK::URL m_base_url;
DeprecatedString m_filename;
EnvironmentSettingsObject& m_settings_object;
JS::NonnullGCPtr<EnvironmentSettingsObject> m_settings_object;
};
}

View file

@ -30,7 +30,7 @@ void WindowEnvironmentSettingsObject::visit_edges(JS::Cell::Visitor& visitor)
WebIDL::ExceptionOr<void> WindowEnvironmentSettingsObject::setup(AK::URL const& creation_url, NonnullOwnPtr<JS::ExecutionContext> execution_context, Optional<Environment> reserved_environment, AK::URL top_level_creation_url, Origin top_level_origin)
{
// 1. Let realm be the value of execution context's Realm component.
auto* realm = execution_context->realm;
auto realm = execution_context->realm;
VERIFY(realm);
// 2. Let window be realm's global object.

View file

@ -25,7 +25,7 @@ public:
static JS::NonnullGCPtr<WorkerEnvironmentSettingsObject> setup(NonnullOwnPtr<JS::ExecutionContext> execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */)
{
auto* realm = execution_context->realm;
auto realm = execution_context->realm;
VERIFY(realm);
auto settings_object = realm->heap().allocate<WorkerEnvironmentSettingsObject>(*realm, move(execution_context)).release_allocated_value_but_fixme_should_propagate_errors();
settings_object->target_browsing_context = nullptr;

View file

@ -15,7 +15,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::href() const
{
auto& vm = realm().vm();
// The href getter steps are to return this's WorkerGlobalScope object's url, serialized.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope.url().serialize()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope->url().serialize()));
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-origin
@ -23,7 +23,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::origin() const
{
auto& vm = realm().vm();
// The origin getter steps are to return the serialization of this's WorkerGlobalScope object's url's origin.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope.url().serialize_origin()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope->url().serialize_origin()));
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-protocol
@ -31,7 +31,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::protocol() const
{
auto& vm = realm().vm();
// The protocol getter steps are to return this's WorkerGlobalScope object's url's scheme, followed by ":".
return TRY_OR_THROW_OOM(vm, String::formatted("{}:", m_global_scope.url().scheme().view()));
return TRY_OR_THROW_OOM(vm, String::formatted("{}:", m_global_scope->url().scheme().view()));
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-host
@ -41,7 +41,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::host() const
// The host getter steps are:
// 1. Let url be this's WorkerGlobalScope object's url.
auto const& url = m_global_scope.url();
auto const& url = m_global_scope->url();
// 2. If url's host is null, return the empty string.
if (url.host().is_empty())
@ -62,7 +62,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::hostname() const
// The hostname getter steps are:
// 1. Let host be this's WorkerGlobalScope object's url's host.
auto const& host = m_global_scope.url().host();
auto const& host = m_global_scope->url().host();
// 2. If host is null, return the empty string.
if (host.is_empty())
@ -79,7 +79,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::port() const
// The port getter steps are:
// 1. Let port be this's WorkerGlobalScope object's url's port.
auto const& port = m_global_scope.url().port();
auto const& port = m_global_scope->url().port();
// 2. If port is null, return the empty string.
if (!port.has_value())
@ -93,7 +93,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::pathname() const
{
auto& vm = realm().vm();
// The pathname getter steps are to return the result of URL path serializing this's WorkerGlobalScope object's url.
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope.url().path()));
return TRY_OR_THROW_OOM(vm, String::from_deprecated_string(m_global_scope->url().path()));
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerlocation-search
@ -103,7 +103,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::search() const
// The search getter steps are:
// 1. Let query be this's WorkerGlobalScope object's url's query.
auto const& query = m_global_scope.url().query();
auto const& query = m_global_scope->url().query();
// 2. If query is either null or the empty string, return the empty string.
if (query.is_empty())
@ -120,7 +120,7 @@ WebIDL::ExceptionOr<String> WorkerLocation::hash() const
// The hash getter steps are:
// 1. Let fragment be this's WorkerGlobalScope object's url's fragment.
auto const& fragment = m_global_scope.url().fragment();
auto const& fragment = m_global_scope->url().fragment();
// 2. If fragment is either null or the empty string, return the empty string.
if (fragment.is_empty())

View file

@ -32,7 +32,7 @@ private:
virtual void visit_edges(Cell::Visitor&) override;
WorkerGlobalScope& m_global_scope;
JS::NonnullGCPtr<WorkerGlobalScope> m_global_scope;
};
}

View file

@ -85,7 +85,7 @@ void BlockFormattingContext::parent_context_did_dimension_child_root_box()
// We can also layout absolutely positioned boxes within this BFC.
for (auto& box : m_absolutely_positioned_boxes) {
auto& cb_state = m_state.get(*box.containing_block());
auto& cb_state = m_state.get(*box->containing_block());
auto available_width = AvailableSize::make_definite(cb_state.content_width() + cb_state.padding_left + cb_state.padding_right);
auto available_height = AvailableSize::make_definite(cb_state.content_height() + cb_state.padding_top + cb_state.padding_bottom);
layout_absolutely_positioned_element(box, AvailableSpace(available_width, available_height));

View file

@ -76,7 +76,7 @@ private:
};
struct FloatingBox {
Box const& box;
JS::NonnullGCPtr<Box const> box;
// Offset from left/right edge to the left content edge of `box`.
CSSPixels offset_from_edge { 0 };
@ -155,7 +155,7 @@ private:
FloatSideData m_left_floats;
FloatSideData m_right_floats;
Vector<Box const&> m_absolutely_positioned_boxes;
Vector<JS::NonnullGCPtr<Box const>> m_absolutely_positioned_boxes;
bool m_was_notified_after_parent_dimensioned_my_root_box { false };
};

View file

@ -131,9 +131,9 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
// 3. Determine the flex base size and hypothetical main size of each item
for (auto& item : m_flex_items) {
if (item.box.is_replaced_box()) {
if (item.box->is_replaced_box()) {
// FIXME: Get rid of prepare_for_replaced_layout() and make replaced elements figure out their intrinsic size lazily.
static_cast<ReplacedBox&>(item.box).prepare_for_replaced_layout();
static_cast<ReplacedBox&>(*item.box).prepare_for_replaced_layout();
}
determine_flex_base_size_and_hypothetical_main_size(item);
}
@ -239,49 +239,49 @@ void FlexFormattingContext::parent_context_did_dimension_child_root_box()
void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::FlexDirection flex_direction) const
{
auto width_of_containing_block = m_state.get(*item.box.containing_block()).content_width();
auto width_of_containing_block = m_state.get(*item.box->containing_block()).content_width();
auto width_of_containing_block_as_length = CSS::Length::make_px(width_of_containing_block);
// FIXME: This should also take reverse-ness into account
if (flex_direction == CSS::FlexDirection::Row || flex_direction == CSS::FlexDirection::RowReverse) {
item.borders.main_before = item.box.computed_values().border_left().width;
item.borders.main_after = item.box.computed_values().border_right().width;
item.borders.cross_before = item.box.computed_values().border_top().width;
item.borders.cross_after = item.box.computed_values().border_bottom().width;
item.borders.main_before = item.box->computed_values().border_left().width;
item.borders.main_after = item.box->computed_values().border_right().width;
item.borders.cross_before = item.box->computed_values().border_top().width;
item.borders.cross_after = item.box->computed_values().border_bottom().width;
item.padding.main_before = item.box.computed_values().padding().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_after = item.box.computed_values().padding().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_before = item.box.computed_values().padding().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_after = item.box.computed_values().padding().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_before = item.box->computed_values().padding().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_after = item.box->computed_values().padding().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_before = item.box->computed_values().padding().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_after = item.box->computed_values().padding().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before = item.box.computed_values().margin().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before = item.box->computed_values().margin().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_after = item.box->computed_values().margin().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box->computed_values().margin().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box->computed_values().margin().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before_is_auto = item.box.computed_values().margin().left().is_auto();
item.margins.main_after_is_auto = item.box.computed_values().margin().right().is_auto();
item.margins.cross_before_is_auto = item.box.computed_values().margin().top().is_auto();
item.margins.cross_after_is_auto = item.box.computed_values().margin().bottom().is_auto();
item.margins.main_before_is_auto = item.box->computed_values().margin().left().is_auto();
item.margins.main_after_is_auto = item.box->computed_values().margin().right().is_auto();
item.margins.cross_before_is_auto = item.box->computed_values().margin().top().is_auto();
item.margins.cross_after_is_auto = item.box->computed_values().margin().bottom().is_auto();
} else {
item.borders.main_before = item.box.computed_values().border_top().width;
item.borders.main_after = item.box.computed_values().border_bottom().width;
item.borders.cross_before = item.box.computed_values().border_left().width;
item.borders.cross_after = item.box.computed_values().border_right().width;
item.borders.main_before = item.box->computed_values().border_top().width;
item.borders.main_after = item.box->computed_values().border_bottom().width;
item.borders.cross_before = item.box->computed_values().border_left().width;
item.borders.cross_after = item.box->computed_values().border_right().width;
item.padding.main_before = item.box.computed_values().padding().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_after = item.box.computed_values().padding().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_before = item.box.computed_values().padding().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_after = item.box.computed_values().padding().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_before = item.box->computed_values().padding().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.main_after = item.box->computed_values().padding().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_before = item.box->computed_values().padding().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.padding.cross_after = item.box->computed_values().padding().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before = item.box.computed_values().margin().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before = item.box->computed_values().margin().top().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_after = item.box->computed_values().margin().bottom().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box->computed_values().margin().left().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box->computed_values().margin().right().resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before_is_auto = item.box.computed_values().margin().top().is_auto();
item.margins.main_after_is_auto = item.box.computed_values().margin().bottom().is_auto();
item.margins.cross_before_is_auto = item.box.computed_values().margin().left().is_auto();
item.margins.cross_after_is_auto = item.box.computed_values().margin().right().is_auto();
item.margins.main_before_is_auto = item.box->computed_values().margin().top().is_auto();
item.margins.main_after_is_auto = item.box->computed_values().margin().bottom().is_auto();
item.margins.cross_before_is_auto = item.box->computed_values().margin().left().is_auto();
item.margins.cross_after_is_auto = item.box->computed_values().margin().right().is_auto();
}
};
@ -585,13 +585,13 @@ CSSPixels FlexFormattingContext::calculate_indefinite_main_size(FlexItem const&
// https://drafts.csswg.org/css-flexbox-1/#propdef-flex-basis
CSS::FlexBasisData FlexFormattingContext::used_flex_basis_for_item(FlexItem const& item) const
{
auto flex_basis = item.box.computed_values().flex_basis();
auto flex_basis = item.box->computed_values().flex_basis();
if (flex_basis.type == CSS::FlexBasis::Auto) {
// https://drafts.csswg.org/css-flexbox-1/#valdef-flex-basis-auto
// When specified on a flex item, the auto keyword retrieves the value of the main size property as the used flex-basis.
// If that value is itself auto, then the used value is content.
auto const& main_size = is_row_layout() ? item.box.computed_values().width() : item.box.computed_values().height();
auto const& main_size = is_row_layout() ? item.box->computed_values().width() : item.box->computed_values().height();
if (main_size.is_auto()) {
flex_basis.type = CSS::FlexBasis::Content;
@ -647,11 +647,11 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
// - an intrinsic aspect ratio,
// - a used flex basis of content, and
// - a definite cross size,
if (item.box.has_intrinsic_aspect_ratio()
if (item.box->has_intrinsic_aspect_ratio()
&& item.used_flex_basis.type == CSS::FlexBasis::Content
&& has_definite_cross_size(item.box)) {
// flex_base_size is calculated from definite cross size and intrinsic aspect ratio
return resolved_definite_cross_size(item) * item.box.intrinsic_aspect_ratio().value();
return resolved_definite_cross_size(item) * item.box->intrinsic_aspect_ratio().value();
}
// C. If the used flex basis is content or depends on its available space,
@ -735,8 +735,8 @@ Optional<CSSPixels> FlexFormattingContext::transferred_size_suggestion(FlexItem
// If the item has a preferred aspect ratio and its preferred cross size is definite,
// then the transferred size suggestion is that size
// (clamped by its minimum and maximum cross sizes if they are definite), converted through the aspect ratio.
if (item.box.has_intrinsic_aspect_ratio() && has_definite_cross_size(item.box)) {
auto aspect_ratio = item.box.intrinsic_aspect_ratio().value();
if (item.box->has_intrinsic_aspect_ratio() && has_definite_cross_size(item.box)) {
auto aspect_ratio = item.box->intrinsic_aspect_ratio().value();
// FIXME: Clamp cross size to min/max cross size before this conversion.
return resolved_definite_cross_size(item) * aspect_ratio;
}
@ -757,7 +757,7 @@ CSSPixels FlexFormattingContext::content_based_minimum_size(FlexItem const& item
// otherwise, the smaller of its transferred size suggestion and its content size suggestion
// if the element is replaced and its transferred size suggestion exists;
if (item.box.is_replaced_box()) {
if (item.box->is_replaced_box()) {
if (auto transferred_size_suggestion = this->transferred_size_suggestion(item); transferred_size_suggestion.has_value()) {
return min(transferred_size_suggestion.value(), content_size_suggestion(item));
}
@ -899,9 +899,9 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
for (FlexItem& item : line.items) {
if (used_flex_factor == FlexFactor::FlexGrowFactor) {
item.flex_factor = item.box.computed_values().flex_grow();
item.flex_factor = item.box->computed_values().flex_grow();
} else if (used_flex_factor == FlexFactor::FlexShrinkFactor) {
item.flex_factor = item.box.computed_values().flex_shrink();
item.flex_factor = item.box->computed_values().flex_shrink();
}
// Freeze, setting its target main size to its hypothetical main size…
// - any item that has a flex factor of zero
@ -1092,7 +1092,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
}
auto cross_size = [&]() {
if (item.box.computed_values().box_sizing() == CSS::BoxSizing::BorderBox) {
if (item.box->computed_values().box_sizing() == CSS::BoxSizing::BorderBox) {
return max(CSSPixels(0.0f), resolved_definite_cross_size(item) - item.padding.cross_before - item.padding.cross_after - item.borders.cross_before - item.borders.cross_after);
}
@ -1358,7 +1358,7 @@ void FlexFormattingContext::dump_items() const
dbgln("{} flex-line #{}:", flex_container().debug_description(), i);
for (size_t j = 0; j < m_flex_lines[i].items.size(); ++j) {
auto& item = m_flex_lines[i].items[j];
dbgln("{} flex-item #{}: {} (main:{}, cross:{})", flex_container().debug_description(), j, item.box.debug_description(), item.main_size.value_or(-1), item.cross_size.value_or(-1));
dbgln("{} flex-item #{}: {} (main:{}, cross:{})", flex_container().debug_description(), j, item.box->debug_description(), item.main_size.value_or(-1), item.cross_size.value_or(-1));
}
}
}
@ -1533,20 +1533,20 @@ void FlexFormattingContext::copy_dimensions_from_flex_items_to_boxes()
auto const& box = item.box;
auto& box_state = m_state.get_mutable(box);
box_state.padding_left = box.computed_values().padding().left().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_right = box.computed_values().padding().right().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_top = box.computed_values().padding().top().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_bottom = box.computed_values().padding().bottom().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_left = box->computed_values().padding().left().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_right = box->computed_values().padding().right().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_top = box->computed_values().padding().top().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.padding_bottom = box->computed_values().padding().bottom().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_left = box.computed_values().margin().left().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_right = box.computed_values().margin().right().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_top = box.computed_values().margin().top().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_bottom = box.computed_values().margin().bottom().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_left = box->computed_values().margin().left().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_right = box->computed_values().margin().right().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_top = box->computed_values().margin().top().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.margin_bottom = box->computed_values().margin().bottom().resolved(box, CSS::Length::make_px(m_flex_container_state.content_width())).to_px(box);
box_state.border_left = box.computed_values().border_left().width;
box_state.border_right = box.computed_values().border_right().width;
box_state.border_top = box.computed_values().border_top().width;
box_state.border_bottom = box.computed_values().border_bottom().width;
box_state.border_left = box->computed_values().border_left().width;
box_state.border_right = box->computed_values().border_right().width;
box_state.border_top = box->computed_values().border_top().width;
box_state.border_bottom = box->computed_values().border_bottom().width;
set_main_size(box, item.main_size.value());
set_cross_size(box, item.cross_size.value());
@ -1604,10 +1604,10 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
CSSPixels result = contribution - outer_flex_base_size;
if (result > 0) {
if (item.box.computed_values().flex_grow() >= 1) {
result /= item.box.computed_values().flex_grow();
if (item.box->computed_values().flex_grow() >= 1) {
result /= item.box->computed_values().flex_grow();
} else {
result *= item.box.computed_values().flex_grow();
result *= item.box->computed_values().flex_grow();
}
} else if (result < 0) {
if (item.scaled_flex_shrink_factor == 0)
@ -1636,8 +1636,8 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
float sum_of_flex_shrink_factors = 0;
for (auto& item : flex_line.items) {
greatest_desired_flex_fraction = max(greatest_desired_flex_fraction, item.desired_flex_fraction);
sum_of_flex_grow_factors += item.box.computed_values().flex_grow();
sum_of_flex_shrink_factors += item.box.computed_values().flex_shrink();
sum_of_flex_grow_factors += item.box->computed_values().flex_grow();
sum_of_flex_shrink_factors += item.box->computed_values().flex_shrink();
}
float chosen_flex_fraction = greatest_desired_flex_fraction;
@ -1663,7 +1663,7 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
for (auto& item : flex_line.items) {
float product = 0;
if (item.desired_flex_fraction > 0)
product = flex_line.chosen_flex_fraction * item.box.computed_values().flex_grow();
product = flex_line.chosen_flex_fraction * item.box->computed_values().flex_grow();
else if (item.desired_flex_fraction < 0)
product = flex_line.chosen_flex_fraction * item.scaled_flex_shrink_factor;
auto result = item.flex_base_size + product;
@ -1923,7 +1923,7 @@ bool FlexFormattingContext::flex_item_is_stretched(FlexItem const& item) const
if (alignment != CSS::AlignItems::Stretch)
return false;
// If the cross size property of the flex item computes to auto, and neither of the cross-axis margins are auto, the flex item is stretched.
auto const& computed_cross_size = is_row_layout() ? item.box.computed_values().height() : item.box.computed_values().width();
auto const& computed_cross_size = is_row_layout() ? item.box->computed_values().height() : item.box->computed_values().width();
return computed_cross_size.is_auto() && !item.margins.cross_before_is_auto && !item.margins.cross_after_is_auto;
}

View file

@ -48,7 +48,7 @@ private:
};
struct FlexItem {
Box& box;
JS::NonnullGCPtr<Box> box;
CSS::FlexBasisData used_flex_basis {};
bool used_flex_basis_is_definite { false };
CSSPixels flex_base_size { 0 };

View file

@ -321,7 +321,7 @@ CSSPixels FormattingContext::compute_auto_height_for_block_formatting_context_ro
// In addition, if the element has any floating descendants
// whose bottom margin edge is below the element's bottom content edge,
// then the height is increased to include those edges.
for (auto* floating_box : m_state.get(root).floating_descendants()) {
for (auto floating_box : m_state.get(root).floating_descendants()) {
// NOTE: Floating box coordinates are relative to their own containing block,
// which may or may not be the BFC root.
auto margin_box = margin_box_rect_in_ancestor_coordinate_space(*floating_box, root, m_state);

View file

@ -123,7 +123,7 @@ protected:
Type m_type {};
FormattingContext* m_parent { nullptr };
Box const& m_context_box;
JS::NonnullGCPtr<Box const> m_context_box;
LayoutState& m_state;
};

View file

@ -1680,8 +1680,8 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
// 1. Position anything that's not auto-positioned.
for (size_t i = 0; i < m_boxes_to_place.size(); i++) {
auto const& child_box = m_boxes_to_place[i];
if (is_auto_positioned_row(child_box.computed_values().grid_row_start(), child_box.computed_values().grid_row_end())
|| is_auto_positioned_column(child_box.computed_values().grid_column_start(), child_box.computed_values().grid_column_end()))
if (is_auto_positioned_row(child_box->computed_values().grid_row_start(), child_box->computed_values().grid_row_end())
|| is_auto_positioned_column(child_box->computed_values().grid_column_start(), child_box->computed_values().grid_column_end()))
continue;
place_item_with_row_and_column_position(box, child_box);
m_boxes_to_place.remove(i);
@ -1692,7 +1692,7 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
// FIXME: Do "dense" packing
for (size_t i = 0; i < m_boxes_to_place.size(); i++) {
auto const& child_box = m_boxes_to_place[i];
if (is_auto_positioned_row(child_box.computed_values().grid_row_start(), child_box.computed_values().grid_row_end()))
if (is_auto_positioned_row(child_box->computed_values().grid_row_start(), child_box->computed_values().grid_row_end()))
continue;
place_item_with_row_position(box, child_box);
m_boxes_to_place.remove(i);
@ -1723,7 +1723,7 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
// FIXME: no distinction made. See #4.2
// 4.1.1. If the item has a definite column position:
if (!is_auto_positioned_column(child_box.computed_values().grid_column_start(), child_box.computed_values().grid_column_end()))
if (!is_auto_positioned_column(child_box->computed_values().grid_column_start(), child_box->computed_values().grid_column_end()))
place_item_with_column_position(box, child_box, auto_placement_cursor_x, auto_placement_cursor_y);
// 4.1.2. If the item has an automatic grid position in both axes:

View file

@ -49,7 +49,7 @@ public:
int gap_adjusted_column(Box const& parent_box);
private:
Box const& m_box;
JS::NonnullGCPtr<Box const> m_box;
int m_row { 0 };
int m_row_span { 1 };
int m_column { 0 };
@ -120,7 +120,7 @@ private:
OccupationGrid m_occupation_grid;
Vector<PositionedBox> m_positioned_boxes;
Vector<Box const&> m_boxes_to_place;
Vector<JS::NonnullGCPtr<Box const>> m_boxes_to_place;
CSSPixels get_free_space_x(AvailableSpace const& available_space);
CSSPixels get_free_space_y(Box const&);

View file

@ -52,7 +52,7 @@ void InlineLevelIterator::exit_node_with_box_model_metrics()
auto& node = m_box_model_node_stack.last();
auto& used_values = m_layout_state.get_mutable(node);
auto const& computed_values = node.computed_values();
auto const& computed_values = node->computed_values();
used_values.margin_right = computed_values.margin().right().resolved(node, CSS::Length::make_px(m_container_state.content_width())).to_px(node);
used_values.border_right = computed_values.border_right().width;
@ -83,7 +83,7 @@ Layout::Node const* InlineLevelIterator::next_inline_node_in_pre_order(Layout::N
// If node is the last node on the "box model node stack", pop it off.
if (!m_box_model_node_stack.is_empty()
&& &m_box_model_node_stack.last() == node) {
&& m_box_model_node_stack.last() == node) {
exit_node_with_box_model_metrics();
}
if (!node || node == stay_within)
@ -92,7 +92,7 @@ Layout::Node const* InlineLevelIterator::next_inline_node_in_pre_order(Layout::N
// If node is the last node on the "box model node stack", pop it off.
if (!m_box_model_node_stack.is_empty()
&& &m_box_model_node_stack.last() == node) {
&& m_box_model_node_stack.last() == node) {
exit_node_with_box_model_metrics();
}
@ -104,7 +104,7 @@ void InlineLevelIterator::compute_next()
if (m_next_node == nullptr)
return;
do {
m_next_node = next_inline_node_in_pre_order(*m_next_node, &m_container);
m_next_node = next_inline_node_in_pre_order(*m_next_node, m_container);
} while (m_next_node && (!m_next_node->is_inline() && !m_next_node->is_out_of_flow(m_inline_formatting_context)));
}

View file

@ -31,7 +31,7 @@ public:
FloatingElement,
};
Type type {};
Layout::Node const* node { nullptr };
JS::GCPtr<Layout::Node const> node {};
size_t offset_in_node { 0 };
size_t length_in_node { 0 };
CSSPixels width { 0.0f };
@ -68,10 +68,10 @@ private:
Layout::InlineFormattingContext& m_inline_formatting_context;
Layout::LayoutState& m_layout_state;
Layout::BlockContainer const& m_container;
JS::NonnullGCPtr<Layout::BlockContainer const> m_container;
Layout::LayoutState::UsedValues const& m_container_state;
Layout::Node const* m_current_node { nullptr };
Layout::Node const* m_next_node { nullptr };
JS::GCPtr<Layout::Node const> m_current_node;
JS::GCPtr<Layout::Node const> m_next_node;
LayoutMode const m_layout_mode;
struct TextNodeContext {
@ -95,7 +95,7 @@ private:
Optional<ExtraBoxMetrics> m_extra_leading_metrics;
Optional<ExtraBoxMetrics> m_extra_trailing_metrics;
Vector<NodeWithStyleAndBoxModelMetrics const&> m_box_model_node_stack;
Vector<JS::NonnullGCPtr<NodeWithStyleAndBoxModelMetrics const>> m_box_model_node_stack;
};
}

View file

@ -131,7 +131,7 @@ struct LayoutState {
AvailableSize available_width_inside() const;
AvailableSize available_height_inside() const;
Layout::NodeWithStyleAndBoxModelMetrics* m_node { nullptr };
JS::GCPtr<Layout::NodeWithStyleAndBoxModelMetrics> m_node { nullptr };
CSSPixels m_content_width { 0 };
CSSPixels m_content_height { 0 };
@ -139,7 +139,7 @@ struct LayoutState {
bool m_has_definite_width { false };
bool m_has_definite_height { false };
HashTable<Box const*> m_floating_descendants;
HashTable<JS::GCPtr<Box const>> m_floating_descendants;
};
CSSPixels resolved_definite_width(Box const&) const;
@ -171,7 +171,7 @@ struct LayoutState {
Optional<CSSPixels> max_content_height_with_max_content_available_width;
};
HashMap<NodeWithStyleAndBoxModelMetrics const*, NonnullOwnPtr<IntrinsicSizes>> mutable intrinsic_sizes;
HashMap<JS::GCPtr<NodeWithStyleAndBoxModelMetrics const>, NonnullOwnPtr<IntrinsicSizes>> mutable intrinsic_sizes;
LayoutState const* m_parent { nullptr };
LayoutState const& m_root;

View file

@ -37,7 +37,7 @@ StringView LineBoxFragment::text() const
CSSPixelRect const LineBoxFragment::absolute_rect() const
{
CSSPixelRect rect { {}, size() };
rect.set_location(m_layout_node.containing_block()->paint_box()->absolute_position());
rect.set_location(m_layout_node->containing_block()->paint_box()->absolute_position());
rect.translate_by(offset());
return rect;
}

View file

@ -7,6 +7,7 @@
#pragma once
#include <LibGfx/Rect.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/Forward.h>
#include <LibWeb/PixelUnits.h>
@ -79,7 +80,7 @@ public:
bool is_atomic_inline() const;
private:
Node const& m_layout_node;
JS::NonnullGCPtr<Node const> m_layout_node;
int m_start { 0 };
int m_length { 0 };
CSSPixelPoint m_offset;

View file

@ -108,13 +108,13 @@ void TableFormattingContext::compute_table_measures()
for (auto& cell : m_cells) {
auto width_of_containing_block = m_state.get(*table_wrapper().containing_block()).content_width();
auto width_of_containing_block_as_length = CSS::Length::make_px(width_of_containing_block);
auto& computed_values = cell.box.computed_values();
auto& computed_values = cell.box->computed_values();
CSSPixels padding_left = computed_values.padding().left().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
CSSPixels padding_right = computed_values.padding().right().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
auto is_left_most_cell = cell.column_index == 0;
auto is_right_most_cell = cell.column_index == m_columns.size() - 1;
auto should_hide_borders = cell.box.computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
auto should_hide_borders = cell.box->computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
CSSPixels border_left = should_hide_borders && !is_left_most_cell ? 0 : computed_values.border_left().width;
CSSPixels border_right = should_hide_borders && !is_right_most_cell ? 0 : computed_values.border_right().width;
@ -392,24 +392,24 @@ void TableFormattingContext::calculate_row_heights(LayoutMode layout_mode)
for (size_t i = 0; i < cell.column_span; ++i)
span_width += m_columns[cell.column_index + i].used_width;
auto width_of_containing_block = m_state.get(*cell.box.containing_block()).content_width();
auto width_of_containing_block = m_state.get(*cell.box->containing_block()).content_width();
auto width_of_containing_block_as_length = CSS::Length::make_px(width_of_containing_block);
cell_state.padding_top = cell.box.computed_values().padding().top().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_bottom = cell.box.computed_values().padding().bottom().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_left = cell.box.computed_values().padding().left().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_right = cell.box.computed_values().padding().right().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_top = cell.box->computed_values().padding().top().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_bottom = cell.box->computed_values().padding().bottom().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_left = cell.box->computed_values().padding().left().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
cell_state.padding_right = cell.box->computed_values().padding().right().resolved(cell.box, width_of_containing_block_as_length).to_px(cell.box);
auto is_top_most_cell = cell.row_index == 0;
auto is_left_most_cell = cell.column_index == 0;
auto is_right_most_cell = cell.column_index == m_columns.size() - 1;
auto is_bottom_most_cell = cell.row_index == m_rows.size() - 1;
auto should_hide_borders = cell.box.computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
auto should_hide_borders = cell.box->computed_values().border_collapse() == CSS::BorderCollapse::Collapse;
cell_state.border_top = (should_hide_borders && is_top_most_cell) ? 0 : cell.box.computed_values().border_top().width;
cell_state.border_bottom = (should_hide_borders && is_bottom_most_cell) ? 0 : cell.box.computed_values().border_bottom().width;
cell_state.border_left = (should_hide_borders && is_left_most_cell) ? 0 : cell.box.computed_values().border_left().width;
cell_state.border_right = (should_hide_borders && is_right_most_cell) ? 0 : cell.box.computed_values().border_right().width;
cell_state.border_top = (should_hide_borders && is_top_most_cell) ? 0 : cell.box->computed_values().border_top().width;
cell_state.border_bottom = (should_hide_borders && is_bottom_most_cell) ? 0 : cell.box->computed_values().border_bottom().width;
cell_state.border_left = (should_hide_borders && is_left_most_cell) ? 0 : cell.box->computed_values().border_left().width;
cell_state.border_right = (should_hide_borders && is_right_most_cell) ? 0 : cell.box->computed_values().border_right().width;
cell_state.set_content_width((span_width - cell_state.border_box_left() - cell_state.border_box_right()));
if (auto independent_formatting_context = layout_inside(cell.box, layout_mode, cell_state.available_inner_space_or_constraints_from(*m_available_space))) {
@ -484,7 +484,7 @@ void TableFormattingContext::position_cell_boxes()
auto& row_state = m_state.get(m_rows[cell.row_index].box);
CSSPixels const cell_border_box_height = cell_state.content_height() + cell_state.border_box_top() + cell_state.border_box_bottom();
CSSPixels const row_content_height = row_state.content_height();
auto const& vertical_align = cell.box.computed_values().vertical_align();
auto const& vertical_align = cell.box->computed_values().vertical_align();
if (vertical_align.has<CSS::VerticalAlign>()) {
switch (vertical_align.get<CSS::VerticalAlign>()) {
case CSS::VerticalAlign::Middle: {

View file

@ -57,13 +57,13 @@ private:
};
struct Row {
Box& box;
JS::NonnullGCPtr<Box> box;
CSSPixels used_height { 0 };
CSSPixels baseline { 0 };
};
struct Cell {
Box& box;
JS::NonnullGCPtr<Box> box;
size_t column_index;
size_t row_index;
size_t column_span;

View file

@ -128,11 +128,11 @@ void TreeBuilder::insert_node_into_inline_or_block_ancestor(Layout::Node& node,
// Non-inlines can't be inserted into an inline parent, so find the nearest non-inline ancestor.
auto& nearest_non_inline_ancestor = [&]() -> Layout::NodeWithStyle& {
for (auto& ancestor : m_ancestor_stack.in_reverse()) {
if (!ancestor.display().is_inline_outside())
if (!ancestor->display().is_inline_outside())
return ancestor;
if (!ancestor.display().is_flow_inside())
if (!ancestor->display().is_flow_inside())
return ancestor;
if (ancestor.dom_node() && is<SVG::SVGForeignObjectElement>(*ancestor.dom_node()))
if (ancestor->dom_node() && is<SVG::SVGForeignObjectElement>(*ancestor->dom_node()))
return ancestor;
}
VERIFY_NOT_REACHED();
@ -237,7 +237,7 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
if (!dom_node.parent_or_shadow_host()) {
m_layout_root = layout_node;
} else if (layout_node->is_svg_box()) {
m_ancestor_stack.last().append_child(*layout_node);
m_ancestor_stack.last()->append_child(*layout_node);
} else {
insert_node_into_inline_or_block_ancestor(*layout_node, display, AppendOrPrepend::Append);
}

View file

@ -49,7 +49,7 @@ private:
ErrorOr<void> create_pseudo_element_if_needed(DOM::Element&, CSS::Selector::PseudoElement, AppendOrPrepend);
JS::GCPtr<Layout::Node> m_layout_root;
Vector<Layout::NodeWithStyle&> m_ancestor_stack;
Vector<JS::NonnullGCPtr<Layout::NodeWithStyle>> m_ancestor_stack;
};
}

View file

@ -207,7 +207,7 @@ bool FrameLoader::load(LoadRequest& request, Type type)
return false;
}
if (!m_browsing_context.is_frame_nesting_allowed(request.url())) {
if (!m_browsing_context->is_frame_nesting_allowed(request.url())) {
dbgln("No further recursion is allowed for the frame, abort load!");
return false;
}
@ -216,7 +216,7 @@ bool FrameLoader::load(LoadRequest& request, Type type)
if (type == Type::Navigation || type == Type::Reload || type == Type::Redirect) {
if (auto* page = browsing_context().page()) {
if (&page->top_level_browsing_context() == &m_browsing_context)
if (&page->top_level_browsing_context() == m_browsing_context)
page->client().page_did_start_loading(url, type == Type::Redirect);
}
}

View file

@ -47,7 +47,7 @@ private:
void load_favicon(RefPtr<Gfx::Bitmap> bitmap = nullptr);
bool parse_document(DOM::Document&, ByteBuffer const& data);
HTML::BrowsingContext& m_browsing_context;
JS::NonnullGCPtr<HTML::BrowsingContext> m_browsing_context;
size_t m_redirects_count { 0 };
};

View file

@ -36,7 +36,7 @@ void ImageLoader::load_without_resetting_redirect_counter(AK::URL const& url)
{
m_loading_state = LoadingState::Loading;
auto request = LoadRequest::create_for_url_on_page(url, m_owner_element.document().page());
auto request = LoadRequest::create_for_url_on_page(url, m_owner_element->document().page());
set_resource(ResourceLoader::the().load_resource(Resource::Type::Image, request));
}

View file

@ -53,7 +53,7 @@ private:
Failed,
};
DOM::Element& m_owner_element;
JS::NonnullGCPtr<DOM::Element> m_owner_element;
mutable bool m_visible_in_viewport { false };

View file

@ -36,9 +36,9 @@ void EditEventHandler::handle_delete_character_after(DOM::Position const& cursor
// FIXME: When nodes are removed from the DOM, the associated layout nodes become stale and still
// remain in the layout tree. This has to be fixed, this just causes everything to be recomputed
// which really hurts performance.
m_browsing_context.active_document()->force_layout();
m_browsing_context->active_document()->force_layout();
m_browsing_context.did_edit({});
m_browsing_context->did_edit({});
}
// This method is quite convoluted but this is necessary to make editing feel intuitive.
@ -97,9 +97,9 @@ void EditEventHandler::handle_delete(DOM::Range& range)
// FIXME: When nodes are removed from the DOM, the associated layout nodes become stale and still
// remain in the layout tree. This has to be fixed, this just causes everything to be recomputed
// which really hurts performance.
m_browsing_context.active_document()->force_layout();
m_browsing_context->active_document()->force_layout();
m_browsing_context.did_edit({});
m_browsing_context->did_edit({});
}
void EditEventHandler::handle_insert(DOM::Position position, u32 code_point)
@ -119,8 +119,8 @@ void EditEventHandler::handle_insert(DOM::Position position, u32 code_point)
// FIXME: When nodes are removed from the DOM, the associated layout nodes become stale and still
// remain in the layout tree. This has to be fixed, this just causes everything to be recomputed
// which really hurts performance.
m_browsing_context.active_document()->force_layout();
m_browsing_context->active_document()->force_layout();
m_browsing_context.did_edit({});
m_browsing_context->did_edit({});
}
}

View file

@ -25,7 +25,7 @@ public:
virtual void handle_insert(DOM::Position, u32 code_point);
private:
HTML::BrowsingContext& m_browsing_context;
JS::NonnullGCPtr<HTML::BrowsingContext> m_browsing_context;
};
}

View file

@ -121,36 +121,36 @@ EventHandler::~EventHandler() = default;
Layout::Viewport const* EventHandler::layout_root() const
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return nullptr;
return m_browsing_context.active_document()->layout_node();
return m_browsing_context->active_document()->layout_node();
}
Layout::Viewport* EventHandler::layout_root()
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return nullptr;
return m_browsing_context.active_document()->layout_node();
return m_browsing_context->active_document()->layout_node();
}
Painting::PaintableBox* EventHandler::paint_root()
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return nullptr;
return const_cast<Painting::PaintableBox*>(m_browsing_context.active_document()->paint_box());
return const_cast<Painting::PaintableBox*>(m_browsing_context->active_document()->paint_box());
}
Painting::PaintableBox const* EventHandler::paint_root() const
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return nullptr;
return const_cast<Painting::PaintableBox*>(m_browsing_context.active_document()->paint_box());
return const_cast<Painting::PaintableBox*>(m_browsing_context->active_document()->paint_box());
}
bool EventHandler::handle_mousewheel(CSSPixelPoint position, unsigned button, unsigned buttons, unsigned int modifiers, int wheel_delta_x, int wheel_delta_y)
{
if (m_browsing_context.active_document())
m_browsing_context.active_document()->update_layout();
if (m_browsing_context->active_document())
m_browsing_context->active_document()->update_layout();
if (!paint_root())
return false;
@ -186,7 +186,7 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint position, unsigned button, un
auto offset = compute_mouse_event_offset(position, *layout_node);
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, offset.x(), offset.y(), position.x(), position.y(), wheel_delta_x, wheel_delta_y, buttons, button).release_value_but_fixme_should_propagate_errors())) {
if (auto* page = m_browsing_context.page()) {
if (auto* page = m_browsing_context->page()) {
page->client().page_did_request_scroll(wheel_delta_x * 20, wheel_delta_y * 20);
}
}
@ -200,8 +200,8 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint position, unsigned button, un
bool EventHandler::handle_mouseup(CSSPixelPoint position, unsigned button, unsigned buttons, unsigned modifiers)
{
if (m_browsing_context.active_document())
m_browsing_context.active_document()->update_layout();
if (m_browsing_context->active_document())
m_browsing_context->active_document()->update_layout();
if (!paint_root())
return false;
@ -273,7 +273,7 @@ bool EventHandler::handle_mouseup(CSSPixelPoint position, unsigned button, unsig
//
// https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
if (JS::GCPtr<HTML::HTMLAnchorElement const> link = node->enclosing_link_element()) {
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context.active_document();
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context->active_document();
auto href = link->href();
auto url = document->parse_url(href);
dbgln("Web::EventHandler: Clicking on a link to {}", url);
@ -281,28 +281,28 @@ bool EventHandler::handle_mouseup(CSSPixelPoint position, unsigned button, unsig
if (href.starts_with("javascript:"sv)) {
document->run_javascript(href.substring_view(11, href.length() - 11));
} else if (!url.fragment().is_null() && url.equals(document->url(), AK::URL::ExcludeFragment::Yes)) {
m_browsing_context.scroll_to_anchor(url.fragment());
m_browsing_context->scroll_to_anchor(url.fragment());
} else {
if (m_browsing_context.is_top_level()) {
if (auto* page = m_browsing_context.page())
if (m_browsing_context->is_top_level()) {
if (auto* page = m_browsing_context->page())
page->client().page_did_click_link(url, link->target(), modifiers);
}
}
} else if (button == GUI::MouseButton::Middle) {
if (auto* page = m_browsing_context.page())
if (auto* page = m_browsing_context->page())
page->client().page_did_middle_click_link(url, link->target(), modifiers);
} else if (button == GUI::MouseButton::Secondary) {
if (auto* page = m_browsing_context.page())
page->client().page_did_request_link_context_menu(m_browsing_context.to_top_level_position(position), url, link->target(), modifiers);
if (auto* page = m_browsing_context->page())
page->client().page_did_request_link_context_menu(m_browsing_context->to_top_level_position(position), url, link->target(), modifiers);
}
} else if (button == GUI::MouseButton::Secondary) {
if (is<HTML::HTMLImageElement>(*node)) {
auto& image_element = verify_cast<HTML::HTMLImageElement>(*node);
auto image_url = image_element.document().parse_url(image_element.src());
if (auto* page = m_browsing_context.page())
page->client().page_did_request_image_context_menu(m_browsing_context.to_top_level_position(position), image_url, "", modifiers, image_element.bitmap());
} else if (auto* page = m_browsing_context.page()) {
page->client().page_did_request_context_menu(m_browsing_context.to_top_level_position(position));
if (auto* page = m_browsing_context->page())
page->client().page_did_request_image_context_menu(m_browsing_context->to_top_level_position(position), image_url, "", modifiers, image_element.bitmap());
} else if (auto* page = m_browsing_context->page()) {
page->client().page_did_request_context_menu(m_browsing_context->to_top_level_position(position));
}
}
}
@ -317,13 +317,13 @@ after_node_use:
bool EventHandler::handle_mousedown(CSSPixelPoint position, unsigned button, unsigned buttons, unsigned modifiers)
{
if (m_browsing_context.active_document())
m_browsing_context.active_document()->update_layout();
if (m_browsing_context->active_document())
m_browsing_context->active_document()->update_layout();
if (!paint_root())
return false;
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context.active_document();
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context->active_document();
JS::GCPtr<DOM::Node> node;
{
@ -358,7 +358,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint position, unsigned button, uns
return false;
}
if (auto* page = m_browsing_context.page())
if (auto* page = m_browsing_context->page())
page->set_focused_browsing_context({}, m_browsing_context);
// Search for the first parent of the hit target that's an element.
@ -398,7 +398,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint position, unsigned button, uns
// If we didn't focus anything, place the document text cursor at the mouse position.
// FIXME: This is all rather strange. Find a better solution.
if (!did_focus_something) {
m_browsing_context.set_cursor_position(DOM::Position(*paintable->dom_node(), result->index_in_node));
m_browsing_context->set_cursor_position(DOM::Position(*paintable->dom_node(), result->index_in_node));
if (auto selection = document->get_selection()) {
(void)selection->set_base_and_extent(*paintable->dom_node(), result->index_in_node, *paintable->dom_node(), result->index_in_node);
}
@ -412,13 +412,13 @@ bool EventHandler::handle_mousedown(CSSPixelPoint position, unsigned button, uns
bool EventHandler::handle_mousemove(CSSPixelPoint position, unsigned buttons, unsigned modifiers)
{
if (m_browsing_context.active_document())
m_browsing_context.active_document()->update_layout();
if (m_browsing_context->active_document())
m_browsing_context->active_document()->update_layout();
if (!paint_root())
return false;
auto& document = *m_browsing_context.active_document();
auto& document = *m_browsing_context->active_document();
bool hovered_node_changed = false;
bool is_hovering_link = false;
@ -443,7 +443,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint position, unsigned buttons, un
return false;
// FIXME: It feels a bit aggressive to always update the cursor like this.
if (auto* page = m_browsing_context.page())
if (auto* page = m_browsing_context->page())
page->client().page_did_request_cursor_change(Gfx::StandardCursor::None);
}
@ -496,7 +496,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint position, unsigned buttons, un
if (m_in_mouse_selection) {
auto hit = paint_root()->hit_test(position, Painting::HitTestType::TextCursor);
if (start_index.has_value() && hit.has_value() && hit->dom_node()) {
m_browsing_context.set_cursor_position(DOM::Position(*hit->dom_node(), *start_index));
m_browsing_context->set_cursor_position(DOM::Position(*hit->dom_node(), *start_index));
if (auto selection = document.get_selection()) {
auto anchor_node = selection->anchor_node();
if (anchor_node)
@ -504,20 +504,20 @@ bool EventHandler::handle_mousemove(CSSPixelPoint position, unsigned buttons, un
else
(void)selection->set_base_and_extent(*hit->paintable->dom_node(), hit->index_in_node, *hit->paintable->dom_node(), hit->index_in_node);
}
m_browsing_context.set_needs_display();
m_browsing_context->set_needs_display();
}
if (auto* page = m_browsing_context.page())
if (auto* page = m_browsing_context->page())
page->client().page_did_change_selection();
}
}
if (auto* page = m_browsing_context.page()) {
if (auto* page = m_browsing_context->page()) {
page->client().page_did_request_cursor_change(hovered_node_cursor);
if (hovered_node_changed) {
JS::GCPtr<HTML::HTMLElement const> hovered_html_element = document.hovered_node() ? document.hovered_node()->enclosing_html_element_with_attribute(HTML::AttributeNames::title) : nullptr;
if (hovered_html_element && !hovered_html_element->title().is_null()) {
page->client().page_did_enter_tooltip_area(m_browsing_context.to_top_level_position(position), hovered_html_element->title());
page->client().page_did_enter_tooltip_area(m_browsing_context->to_top_level_position(position), hovered_html_element->title());
} else {
page->client().page_did_leave_tooltip_area();
}
@ -532,8 +532,8 @@ bool EventHandler::handle_mousemove(CSSPixelPoint position, unsigned buttons, un
bool EventHandler::handle_doubleclick(CSSPixelPoint position, unsigned button, unsigned buttons, unsigned modifiers)
{
if (m_browsing_context.active_document())
m_browsing_context.active_document()->update_layout();
if (m_browsing_context->active_document())
m_browsing_context->active_document()->update_layout();
if (!paint_root())
return false;
@ -614,7 +614,7 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint position, unsigned button, u
return text_for_rendering.length();
}();
m_browsing_context.set_cursor_position(DOM::Position(*paintable->dom_node(), first_word_break_after));
m_browsing_context->set_cursor_position(DOM::Position(*paintable->dom_node(), first_word_break_after));
if (auto selection = node->document().get_selection()) {
(void)selection->set_base_and_extent(*paintable->dom_node(), first_word_break_before, *paintable->dom_node(), first_word_break_after);
}
@ -626,13 +626,13 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint position, unsigned button, u
bool EventHandler::focus_next_element()
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return false;
auto* element = m_browsing_context.active_document()->focused_element();
auto* element = m_browsing_context->active_document()->focused_element();
if (!element) {
element = m_browsing_context.active_document()->first_child_of_type<DOM::Element>();
element = m_browsing_context->active_document()->first_child_of_type<DOM::Element>();
if (element && element->is_focusable()) {
m_browsing_context.active_document()->set_focused_element(element);
m_browsing_context->active_document()->set_focused_element(element);
return true;
}
}
@ -640,19 +640,19 @@ bool EventHandler::focus_next_element()
for (element = element->next_element_in_pre_order(); element && !element->is_focusable(); element = element->next_element_in_pre_order())
;
m_browsing_context.active_document()->set_focused_element(element);
m_browsing_context->active_document()->set_focused_element(element);
return element;
}
bool EventHandler::focus_previous_element()
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return false;
auto* element = m_browsing_context.active_document()->focused_element();
auto* element = m_browsing_context->active_document()->focused_element();
if (!element) {
element = m_browsing_context.active_document()->last_child_of_type<DOM::Element>();
element = m_browsing_context->active_document()->last_child_of_type<DOM::Element>();
if (element && element->is_focusable()) {
m_browsing_context.active_document()->set_focused_element(element);
m_browsing_context->active_document()->set_focused_element(element);
return true;
}
}
@ -660,7 +660,7 @@ bool EventHandler::focus_previous_element()
for (element = element->previous_element_in_pre_order(); element && !element->is_focusable(); element = element->previous_element_in_pre_order())
;
m_browsing_context.active_document()->set_focused_element(element);
m_browsing_context->active_document()->set_focused_element(element);
return element;
}
@ -699,10 +699,10 @@ bool EventHandler::fire_keyboard_event(DeprecatedFlyString const& event_name, HT
bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_point)
{
if (!m_browsing_context.active_document())
if (!m_browsing_context->active_document())
return false;
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context.active_document();
JS::NonnullGCPtr<DOM::Document> document = *m_browsing_context->active_document();
if (!document->layout_node())
return false;
@ -718,7 +718,7 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin
selection->remove_all_ranges();
// FIXME: This doesn't work for some reason?
m_browsing_context.set_cursor_position({ *range->start_container(), range->start_offset() });
m_browsing_context->set_cursor_position({ *range->start_container(), range->start_offset() });
if (key == KeyCode::Key_Backspace || key == KeyCode::Key_Delete) {
m_edit_event_handler->handle_delete(*range);
@ -726,56 +726,56 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin
}
if (!should_ignore_keydown_event(code_point)) {
m_edit_event_handler->handle_delete(*range);
m_edit_event_handler->handle_insert(m_browsing_context.cursor_position(), code_point);
m_browsing_context.increment_cursor_position_offset();
m_edit_event_handler->handle_insert(m_browsing_context->cursor_position(), code_point);
m_browsing_context->increment_cursor_position_offset();
return true;
}
}
}
if (m_browsing_context.cursor_position().is_valid() && m_browsing_context.cursor_position().node()->is_editable()) {
if (m_browsing_context->cursor_position().is_valid() && m_browsing_context->cursor_position().node()->is_editable()) {
if (key == KeyCode::Key_Backspace) {
if (!m_browsing_context.decrement_cursor_position_offset()) {
if (!m_browsing_context->decrement_cursor_position_offset()) {
// FIXME: Move to the previous node and delete the last character there.
return true;
}
m_edit_event_handler->handle_delete_character_after(m_browsing_context.cursor_position());
m_edit_event_handler->handle_delete_character_after(m_browsing_context->cursor_position());
return true;
}
if (key == KeyCode::Key_Delete) {
if (m_browsing_context.cursor_position().offset_is_at_end_of_node()) {
if (m_browsing_context->cursor_position().offset_is_at_end_of_node()) {
// FIXME: Move to the next node and delete the first character there.
return true;
}
m_edit_event_handler->handle_delete_character_after(m_browsing_context.cursor_position());
m_edit_event_handler->handle_delete_character_after(m_browsing_context->cursor_position());
return true;
}
if (key == KeyCode::Key_Right) {
if (!m_browsing_context.increment_cursor_position_offset()) {
if (!m_browsing_context->increment_cursor_position_offset()) {
// FIXME: Move to the next node.
}
return true;
}
if (key == KeyCode::Key_Left) {
if (!m_browsing_context.decrement_cursor_position_offset()) {
if (!m_browsing_context->decrement_cursor_position_offset()) {
// FIXME: Move to the previous node.
}
return true;
}
if (key == KeyCode::Key_Home) {
auto& node = *static_cast<DOM::Text*>(const_cast<DOM::Node*>(m_browsing_context.cursor_position().node()));
m_browsing_context.set_cursor_position(DOM::Position { node, 0 });
auto& node = *static_cast<DOM::Text*>(const_cast<DOM::Node*>(m_browsing_context->cursor_position().node()));
m_browsing_context->set_cursor_position(DOM::Position { node, 0 });
return true;
}
if (key == KeyCode::Key_End) {
auto& node = *static_cast<DOM::Text*>(const_cast<DOM::Node*>(m_browsing_context.cursor_position().node()));
m_browsing_context.set_cursor_position(DOM::Position { node, (unsigned)node.data().length() });
auto& node = *static_cast<DOM::Text*>(const_cast<DOM::Node*>(m_browsing_context->cursor_position().node()));
m_browsing_context->set_cursor_position(DOM::Position { node, (unsigned)node.data().length() });
return true;
}
if (!should_ignore_keydown_event(code_point)) {
m_edit_event_handler->handle_insert(m_browsing_context.cursor_position(), code_point);
m_browsing_context.increment_cursor_position_offset();
m_edit_event_handler->handle_insert(m_browsing_context->cursor_position(), code_point);
m_browsing_context->increment_cursor_position_offset();
return true;
}
@ -806,7 +806,7 @@ CSSPixelPoint EventHandler::compute_mouse_event_client_offset(CSSPixelPoint even
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-clientx
// The clientX attribute must return the x-coordinate of the position where the event occurred relative to the origin of the viewport.
auto scroll_offset = m_browsing_context.viewport_scroll_offset();
auto scroll_offset = m_browsing_context->viewport_scroll_offset();
return event_page_position.translated(-scroll_offset);
}
@ -816,7 +816,7 @@ CSSPixelPoint EventHandler::compute_mouse_event_page_offset(CSSPixelPoint event_
// FIXME: 1. If the events dispatch flag is set, return the horizontal coordinate of the position where the event occurred relative to the origin of the initial containing block and terminate these steps.
// 2. Let offset be the value of the scrollX attribute of the events associated Window object, if there is one, or zero otherwise.
auto scroll_offset = m_browsing_context.viewport_scroll_offset();
auto scroll_offset = m_browsing_context->viewport_scroll_offset();
// 3. Return the sum of offset and the value of the events clientX attribute.
return event_client_offset.translated(scroll_offset);

View file

@ -50,7 +50,7 @@ private:
Painting::PaintableBox* paint_root();
Painting::PaintableBox const* paint_root() const;
HTML::BrowsingContext& m_browsing_context;
JS::NonnullGCPtr<HTML::BrowsingContext> m_browsing_context;
bool m_in_mouse_selection { false };

View file

@ -29,7 +29,7 @@ static void paint_node(Layout::Node const& layout_node, PaintContext& context, P
StackingContext::StackingContext(Layout::Box& box, StackingContext* parent)
: m_box(box)
, m_transform(combine_transformations(m_box.computed_values().transformations()))
, m_transform(combine_transformations(m_box->computed_values().transformations()))
, m_transform_origin(compute_transform_origin())
, m_parent(parent)
{
@ -41,10 +41,10 @@ StackingContext::StackingContext(Layout::Box& box, StackingContext* parent)
void StackingContext::sort()
{
quick_sort(m_children, [](auto& a, auto& b) {
auto a_z_index = a->m_box.computed_values().z_index().value_or(0);
auto b_z_index = b->m_box.computed_values().z_index().value_or(0);
auto a_z_index = a->m_box->computed_values().z_index().value_or(0);
auto b_z_index = b->m_box->computed_values().z_index().value_or(0);
if (a_z_index == b_z_index)
return a->m_box.is_before(b->m_box);
return a->m_box->is_before(b->m_box);
return a_z_index < b_z_index;
});
@ -140,11 +140,11 @@ void StackingContext::paint_internal(PaintContext& context) const
paint_node(m_box, context, PaintPhase::Border);
auto paint_child = [&](auto* child) {
auto parent = child->m_box.parent();
auto parent = child->m_box->parent();
auto* parent_paintable = parent ? parent->paintable() : nullptr;
if (parent_paintable)
parent_paintable->before_children_paint(context, PaintPhase::Foreground);
auto containing_block = child->m_box.containing_block();
auto containing_block = child->m_box->containing_block();
auto* containing_block_paintable = containing_block ? containing_block->paintable() : nullptr;
if (containing_block_paintable)
containing_block_paintable->apply_clip_overflow_rect(context, PaintPhase::Foreground);
@ -159,7 +159,7 @@ void StackingContext::paint_internal(PaintContext& context) const
// Draw positioned descendants with negative z-indices (step 3)
for (auto* child : m_children) {
if (child->m_box.computed_values().z_index().has_value() && child->m_box.computed_values().z_index().value() < 0)
if (child->m_box->computed_values().z_index().has_value() && child->m_box->computed_values().z_index().value() < 0)
paint_child(child);
}
@ -175,7 +175,7 @@ void StackingContext::paint_internal(PaintContext& context) const
// Draw positioned descendants with z-index `0` or `auto` in tree order. (step 8)
// NOTE: Non-positioned descendants that establish stacking contexts with z-index `0` or `auto` are also painted here.
// FIXME: There's more to this step that we have yet to understand and implement.
m_box.paint_box()->for_each_in_subtree_of_type<PaintableBox>([&](PaintableBox const& paint_box) {
m_box->paint_box()->for_each_in_subtree_of_type<PaintableBox>([&](PaintableBox const& paint_box) {
auto const& z_index = paint_box.computed_values().z_index();
if (auto* child = paint_box.stacking_context()) {
if (!z_index.has_value() || z_index.value() == 0)
@ -217,7 +217,7 @@ void StackingContext::paint_internal(PaintContext& context) const
// Draw other positioned descendants (step 9)
for (auto* child : m_children) {
if (child->m_box.computed_values().z_index().has_value() && child->m_box.computed_values().z_index().value() >= 1)
if (child->m_box->computed_values().z_index().has_value() && child->m_box->computed_values().z_index().value() >= 1)
paint_child(child);
}
@ -363,11 +363,11 @@ Gfx::AffineTransform StackingContext::affine_transform_matrix() const
void StackingContext::paint(PaintContext& context) const
{
Gfx::PainterStateSaver saver(context.painter());
if (m_box.is_fixed_position()) {
if (m_box->is_fixed_position()) {
context.painter().translate(-context.painter().translation());
}
auto opacity = m_box.computed_values().opacity();
auto opacity = m_box->computed_values().opacity();
if (opacity == 0.0f)
return;
@ -424,7 +424,7 @@ void StackingContext::paint(PaintContext& context) const
Gfx::FloatPoint StackingContext::compute_transform_origin() const
{
auto style_value = m_box.computed_values().transform_origin();
auto style_value = m_box->computed_values().transform_origin();
// FIXME: respect transform-box property
auto reference_box = paintable().absolute_border_box_rect();
auto x = reference_box.left() + style_value.x.resolved(m_box, CSS::Length::make_px(reference_box.width())).to_px(m_box);
@ -461,7 +461,7 @@ static TraversalDecision for_each_in_subtree_of_type_within_same_stacking_contex
Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTestType type) const
{
if (!m_box.is_visible())
if (!m_box->is_visible())
return {};
auto transform_origin = this->transform_origin().to_type<CSSPixels>();
@ -485,7 +485,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
// NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
for (ssize_t i = m_children.size() - 1; i >= 0; --i) {
auto const& child = *m_children[i];
if (child.m_box.computed_values().z_index().value_or(0) <= 0)
if (child.m_box->computed_values().z_index().value_or(0) <= 0)
break;
auto result = child.hit_test(transformed_position, type);
if (result.has_value() && result->paintable->visible_for_hit_testing())
@ -528,7 +528,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
// "child stacking contexts with stack level 0" is first in the step, so last here to match reverse order.
for (ssize_t i = m_children.size() - 1; i >= 0; --i) {
auto const& child = *m_children[i];
if (child.m_box.computed_values().z_index().value_or(0) != 0)
if (child.m_box->computed_values().z_index().value_or(0) != 0)
break;
auto result = child.hit_test(transformed_position, type);
if (result.has_value() && result->paintable->visible_for_hit_testing())
@ -536,7 +536,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
}
// 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
if (m_box.children_are_inline() && is<Layout::BlockContainer>(m_box)) {
if (m_box->children_are_inline() && is<Layout::BlockContainer>(*m_box)) {
auto result = paintable().hit_test(transformed_position, type);
if (result.has_value() && result->paintable->visible_for_hit_testing())
return result;
@ -563,7 +563,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
return result;
// 3. the in-flow, non-inline-level, non-positioned descendants.
if (!m_box.children_are_inline()) {
if (!m_box->children_are_inline()) {
for_each_in_subtree_of_type_within_same_stacking_context_in_reverse<PaintableBox>(paintable(), [&](auto const& paint_box) {
// FIXME: Support more overflow variations.
if (paint_box.computed_values().overflow_x() == CSS::Overflow::Hidden && paint_box.computed_values().overflow_y() == CSS::Overflow::Hidden) {
@ -588,7 +588,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
// NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
for (ssize_t i = m_children.size() - 1; i >= 0; --i) {
auto const& child = *m_children[i];
if (child.m_box.computed_values().z_index().value_or(0) >= 0)
if (child.m_box->computed_values().z_index().value_or(0) >= 0)
break;
auto result = child.hit_test(transformed_position, type);
if (result.has_value() && result->paintable->visible_for_hit_testing())
@ -610,9 +610,9 @@ void StackingContext::dump(int indent) const
StringBuilder builder;
for (int i = 0; i < indent; ++i)
builder.append(' ');
builder.appendff("SC for {} {} [children: {}] (z-index: ", m_box.debug_description(), paintable().absolute_rect(), m_children.size());
if (m_box.computed_values().z_index().has_value())
builder.appendff("{}", m_box.computed_values().z_index().value());
builder.appendff("SC for {} {} [children: {}] (z-index: ", m_box->debug_description(), paintable().absolute_rect(), m_children.size());
if (m_box->computed_values().z_index().has_value())
builder.appendff("{}", m_box->computed_values().z_index().value());
else
builder.append("auto"sv);
builder.append(')');

View file

@ -20,7 +20,7 @@ public:
StackingContext* parent() { return m_parent; }
StackingContext const* parent() const { return m_parent; }
PaintableBox const& paintable() const { return *m_box.paint_box(); }
PaintableBox const& paintable() const { return *m_box->paint_box(); }
enum class StackingContextPaintPhase {
BackgroundAndBorders,
@ -42,7 +42,7 @@ public:
void sort();
private:
Layout::Box& m_box;
JS::NonnullGCPtr<Layout::Box> m_box;
Gfx::FloatMatrix4x4 m_transform;
Gfx::FloatPoint m_transform_origin;
StackingContext* const m_parent { nullptr };

View file

@ -23,7 +23,7 @@ Optional<AK::URL> determine_requests_referrer(Fetch::Infrastructure::Request con
auto const& policy = request.referrer_policy();
// 2. Let environment be requests client.
auto* environment = request.client();
auto environment = request.client();
// 3. Switch on requests referrer:
auto referrer_source = request.referrer().visit(
@ -33,7 +33,7 @@ Optional<AK::URL> determine_requests_referrer(Fetch::Infrastructure::Request con
VERIFY(referrer == Fetch::Infrastructure::Request::Referrer::Client);
// FIXME: Add a const global_object() getter to ESO
auto& global_object = const_cast<HTML::EnvironmentSettingsObject*>(environment)->global_object();
auto& global_object = const_cast<HTML::EnvironmentSettingsObject&>(*environment).global_object();
// 1. If environments global object is a Window object, then
if (is<HTML::Window>(global_object)) {

View file

@ -48,15 +48,15 @@ JS::ThrowCompletionOr<void> URLSearchParamsIterator::initialize(JS::Realm& realm
void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_url_search_params);
visitor.visit(m_url_search_params);
}
JS::Object* URLSearchParamsIterator::next()
{
if (m_index >= m_url_search_params.m_list.size())
if (m_index >= m_url_search_params->m_list.size())
return create_iterator_result_object(vm(), JS::js_undefined(), true);
auto& entry = m_url_search_params.m_list[m_index++];
auto& entry = m_url_search_params->m_list[m_index++];
if (m_iteration_kind == JS::Object::PropertyKind::Key)
return create_iterator_result_object(vm(), JS::PrimitiveString::create(vm(), entry.name), false);
else if (m_iteration_kind == JS::Object::PropertyKind::Value)

View file

@ -27,7 +27,7 @@ private:
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
URLSearchParams const& m_url_search_params;
JS::NonnullGCPtr<URLSearchParams const> m_url_search_params;
JS::Object::PropertyKind m_iteration_kind;
size_t m_index { 0 };
};

View file

@ -37,7 +37,7 @@ JS::ThrowCompletionOr<void> WebAssemblyInstanceObject::initialize(JS::Realm& rea
for (auto& export_ : instance.exports()) {
TRY(export_.value().visit(
[&](Wasm::FunctionAddress const& address) -> JS::ThrowCompletionOr<void> {
Optional<JS::FunctionObject*> object = cache.function_instances.get(address);
Optional<JS::GCPtr<JS::FunctionObject>> object = cache.function_instances.get(address);
if (!object.has_value()) {
object = create_native_function(vm, address, export_.name());
cache.function_instances.set(address, *object);
@ -46,7 +46,7 @@ JS::ThrowCompletionOr<void> WebAssemblyInstanceObject::initialize(JS::Realm& rea
return {};
},
[&](Wasm::MemoryAddress const& address) -> JS::ThrowCompletionOr<void> {
Optional<WebAssemblyMemoryObject*> object = cache.memory_instances.get(address);
Optional<JS::GCPtr<WebAssemblyMemoryObject>> object = cache.memory_instances.get(address);
if (!object.has_value()) {
object = MUST_OR_THROW_OOM(heap().allocate<Web::Bindings::WebAssemblyMemoryObject>(realm, realm, address));
cache.memory_instances.set(address, *object);
@ -55,7 +55,7 @@ JS::ThrowCompletionOr<void> WebAssemblyInstanceObject::initialize(JS::Realm& rea
return {};
},
[&](Wasm::TableAddress const& address) -> JS::ThrowCompletionOr<void> {
Optional<WebAssemblyTableObject*> object = cache.table_instances.get(address);
Optional<JS::GCPtr<WebAssemblyTableObject>> object = cache.table_instances.get(address);
if (!object.has_value()) {
object = MUST_OR_THROW_OOM(heap().allocate<Web::Bindings::WebAssemblyTableObject>(realm, realm, address));
cache.table_instances.set(address, *object);

View file

@ -33,7 +33,7 @@ public:
private:
size_t m_index { 0 };
Object* m_exports_object { nullptr };
JS::GCPtr<Object> m_exports_object;
};
}

View file

@ -46,12 +46,12 @@ public:
// so ideally this would be a refcounted object, shared between
// WebAssemblyModuleObject's and WebAssemblyInstantiatedModuleObject's.
struct ModuleCache {
HashMap<Wasm::FunctionAddress, JS::FunctionObject*> function_instances;
HashMap<Wasm::MemoryAddress, WebAssemblyMemoryObject*> memory_instances;
HashMap<Wasm::TableAddress, WebAssemblyTableObject*> table_instances;
HashMap<Wasm::FunctionAddress, JS::GCPtr<JS::FunctionObject>> function_instances;
HashMap<Wasm::MemoryAddress, JS::GCPtr<WebAssemblyMemoryObject>> memory_instances;
HashMap<Wasm::TableAddress, JS::GCPtr<WebAssemblyTableObject>> table_instances;
};
struct GlobalModuleCache {
HashMap<Wasm::FunctionAddress, JS::NativeFunction*> function_instances;
HashMap<Wasm::FunctionAddress, JS::GCPtr<JS::NativeFunction>> function_instances;
};
static Vector<NonnullOwnPtr<CompiledWebAssemblyModule>> s_compiled_modules;

View file

@ -333,7 +333,7 @@ ExecuteScriptResultSerialized execute_async_script(Web::Page& page, DeprecatedSt
vm.pop_execution_context();
// 2. Append resolvingFunctions.[[Resolve]] to arguments.
arguments.append(&resolving_functions.resolve);
arguments.append(resolving_functions.resolve);
// 3. Let result be the result of calling execute a function body, with arguments body and arguments.
// FIXME: 'result' -> 'scriptResult' (spec issue)

View file

@ -95,7 +95,7 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Valu
auto& function_object = callback.callback;
// 4. If ! IsCallable(F) is false:
if (!function_object.is_function()) {
if (!function_object->is_function()) {
// 1. Note: This is only possible when the callback function came from an attribute marked with [LegacyTreatNonObjectAsNull].
// 2. Return the result of converting undefined to the callback functions return type.
@ -105,7 +105,7 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Valu
// 5. Let realm be Fs associated Realm.
// See the comment about associated realm on step 4 of call_user_object_operation.
auto& realm = function_object.shape().realm();
auto& realm = function_object->shape().realm();
// 6. Let relevant settings be realms settings object.
auto& relevant_settings = Bindings::host_defined_environment_settings_object(realm);
@ -117,14 +117,14 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Valu
relevant_settings.prepare_to_run_script();
// 9. Prepare to run a callback with stored settings.
stored_settings.prepare_to_run_callback();
stored_settings->prepare_to_run_callback();
// FIXME: 10. Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
// For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to.
// 11. Let callResult be Call(F, thisArg, esArgs).
auto& vm = function_object.vm();
auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(function_object), this_argument.value(), move(args));
auto& vm = function_object->vm();
auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(*function_object), this_argument.value(), move(args));
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
if (call_result.is_throw_completion()) {

View file

@ -58,7 +58,7 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, Deprec
auto& object = callback.callback;
// 4. Let realm be Os associated Realm.
auto& realm = object.shape().realm();
auto& realm = object->shape().realm();
// 5. Let relevant settings be realms settings object.
auto& relevant_settings = Bindings::host_defined_environment_settings_object(realm);
@ -70,15 +70,15 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, Deprec
relevant_settings.prepare_to_run_script();
// 8. Prepare to run a callback with stored settings.
stored_settings.prepare_to_run_callback();
stored_settings->prepare_to_run_callback();
// 9. Let X be O.
auto* actual_function_object = &object;
auto actual_function_object = object;
// 10. If ! IsCallable(O) is false, then:
if (!object.is_function()) {
if (!object->is_function()) {
// 1. Let getResult be Get(O, opName).
auto get_result = object.get(operation_name);
auto get_result = object->get(operation_name);
// 2. If getResult is an abrupt completion, set completion to getResult and jump to the step labeled return.
if (get_result.is_throw_completion()) {
@ -94,10 +94,10 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, Deprec
// 3. Set X to getResult.[[Value]].
// NOTE: This is done out of order because `actual_function_object` is of type JS::Object and we cannot assign to it until we know for sure getResult.[[Value]] is a JS::Object.
actual_function_object = &get_result.release_value().as_object();
actual_function_object = get_result.release_value().as_object();
// 5. Set thisArg to O (overriding the provided value).
this_argument = &object;
this_argument = object;
}
// FIXME: 11. Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
@ -105,7 +105,7 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, Deprec
// 12. Let callResult be Call(X, thisArg, esArgs).
VERIFY(actual_function_object);
auto& vm = object.vm();
auto& vm = object->vm();
auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(*actual_function_object), this_argument.value(), forward<Args>(args)...);
// 13. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
@ -129,7 +129,7 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Valu
{
auto& function_object = callback.callback;
JS::MarkedVector<JS::Value> arguments_list { function_object.vm().heap() };
JS::MarkedVector<JS::Value> arguments_list { function_object->vm().heap() };
(arguments_list.append(forward<Args>(args)), ...);
return invoke_callback(callback, move(this_argument), move(arguments_list));

View file

@ -20,7 +20,7 @@ StringView CallbackType::class_name() const { return "CallbackType"sv; }
void CallbackType::visit_edges(Cell::Visitor& visitor)
{
Cell::visit_edges(visitor);
visitor.visit(&callback);
visitor.visit(callback);
visitor.visit(callback_context);
}

View file

@ -17,10 +17,10 @@ class CallbackType final : public JS::Cell {
public:
CallbackType(JS::Object& callback, HTML::EnvironmentSettingsObject& callback_context);
JS::Object& callback;
JS::NonnullGCPtr<JS::Object> callback;
// https://webidl.spec.whatwg.org/#dfn-callback-context
HTML::EnvironmentSettingsObject& callback_context;
JS::NonnullGCPtr<HTML::EnvironmentSettingsObject> callback_context;
private:
virtual StringView class_name() const override;

View file

@ -48,17 +48,17 @@ JS::ThrowCompletionOr<void> FormDataIterator::initialize(JS::Realm& realm)
void FormDataIterator::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(&m_form_data);
visitor.visit(m_form_data);
}
JS::Object* FormDataIterator::next()
{
auto& vm = this->vm();
if (m_index >= m_form_data.m_entry_list.size())
if (m_index >= m_form_data->m_entry_list.size())
return create_iterator_result_object(vm, JS::js_undefined(), true);
auto& entry = m_form_data.m_entry_list[m_index++];
auto entry = m_form_data->m_entry_list[m_index++];
if (m_iterator_kind == JS::Object::PropertyKind::Key)
return create_iterator_result_object(vm, JS::PrimitiveString::create(vm, entry.name), false);

View file

@ -27,7 +27,7 @@ private:
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
FormData const& m_form_data;
JS::NonnullGCPtr<FormData const> m_form_data;
JS::Object::PropertyKind m_iterator_kind;
size_t m_index { 0 };
};

View file

@ -41,14 +41,14 @@ ErrorOr<DeprecatedString> resolve_xml_resource(XML::SystemID const&, Optional<XM
XMLDocumentBuilder::XMLDocumentBuilder(DOM::Document& document, XMLScriptingSupport scripting_support)
: m_document(document)
, m_current_node(&m_document)
, m_current_node(m_document)
, m_scripting_support(scripting_support)
{
}
void XMLDocumentBuilder::set_source(DeprecatedString source)
{
m_document.set_source(move(source));
m_document->set_source(move(source));
}
void XMLDocumentBuilder::element_start(const XML::Name& name, HashMap<XML::Name, DeprecatedString> const& attributes)
@ -100,14 +100,14 @@ void XMLDocumentBuilder::element_end(const XML::Name& name)
auto& script_element = static_cast<HTML::HTMLScriptElement&>(*m_current_node);
script_element.prepare_script(Badge<XMLDocumentBuilder> {});
// If this causes there to be a pending parsing-blocking script, then the user agent must run the following steps:
if (m_document.pending_parsing_blocking_script()) {
if (m_document->pending_parsing_blocking_script()) {
// Block this instance of the XML parser, such that the event loop will not run tasks that invoke it.
// NOTE: Noop.
// Spin the event loop until the parser's Document has no style sheet that is blocking scripts and the pending parsing-blocking script's "ready to be parser-executed" flag is set.
if (m_document.has_a_style_sheet_that_is_blocking_scripts() || !script_element.is_ready_to_be_parser_executed()) {
if (m_document->has_a_style_sheet_that_is_blocking_scripts() || !script_element.is_ready_to_be_parser_executed()) {
HTML::main_thread_event_loop().spin_until([&] {
return !m_document.has_a_style_sheet_that_is_blocking_scripts() && script_element.is_ready_to_be_parser_executed();
return !m_document->has_a_style_sheet_that_is_blocking_scripts() && script_element.is_ready_to_be_parser_executed();
});
}
@ -138,7 +138,7 @@ void XMLDocumentBuilder::text(StringView data)
auto string = DeprecatedString::empty();
if (!data.is_null())
string = data.to_deprecated_string();
auto node = m_document.create_text_node(string);
auto node = m_document->create_text_node(string);
MUST(m_current_node->append_child(node));
}
}
@ -150,7 +150,7 @@ void XMLDocumentBuilder::comment(StringView data)
auto string = DeprecatedString::empty();
if (!data.is_null())
string = data.to_deprecated_string();
MUST(m_document.append_child(m_document.create_comment(string)));
MUST(m_document->append_child(m_document->create_comment(string)));
}
void XMLDocumentBuilder::document_end()
@ -163,28 +163,28 @@ void XMLDocumentBuilder::document_end()
m_current_node = nullptr;
// Update the current document readiness to "interactive".
m_document.update_readiness(HTML::DocumentReadyState::Interactive);
m_document->update_readiness(HTML::DocumentReadyState::Interactive);
// Pop all the nodes off the stack of open elements.
// NOTE: Noop.
// While the list of scripts that will execute when the document has finished parsing is not empty:
while (!m_document.scripts_to_execute_when_parsing_has_finished().is_empty()) {
while (!m_document->scripts_to_execute_when_parsing_has_finished().is_empty()) {
// Spin the event loop until the first script in the list of scripts that will execute when the document has finished parsing has its "ready to be parser-executed" flag set
// and the parser's Document has no style sheet that is blocking scripts.
HTML::main_thread_event_loop().spin_until([&] {
return m_document.scripts_to_execute_when_parsing_has_finished().first()->is_ready_to_be_parser_executed()
&& !m_document.has_a_style_sheet_that_is_blocking_scripts();
return m_document->scripts_to_execute_when_parsing_has_finished().first()->is_ready_to_be_parser_executed()
&& !m_document->has_a_style_sheet_that_is_blocking_scripts();
});
// Execute the first script in the list of scripts that will execute when the document has finished parsing.
m_document.scripts_to_execute_when_parsing_has_finished().first()->execute_script();
m_document->scripts_to_execute_when_parsing_has_finished().first()->execute_script();
// Remove the first script element from the list of scripts that will execute when the document has finished parsing (i.e. shift out the first entry in the list).
(void)m_document.scripts_to_execute_when_parsing_has_finished().take_first();
(void)m_document->scripts_to_execute_when_parsing_has_finished().take_first();
}
// Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following substeps:
old_queue_global_task_with_document(HTML::Task::Source::DOMManipulation, m_document, [document = &m_document] {
old_queue_global_task_with_document(HTML::Task::Source::DOMManipulation, m_document, [document = m_document] {
// Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object.
document->load_timing_info().dom_content_loaded_event_start_time = HighResolutionTime::unsafe_shared_current_time();
@ -203,16 +203,16 @@ void XMLDocumentBuilder::document_end()
// Spin the event loop until the set of scripts that will execute as soon as possible and the list of scripts that will execute in order as soon as possible are empty.
HTML::main_thread_event_loop().spin_until([&] {
return m_document.scripts_to_execute_as_soon_as_possible().is_empty();
return m_document->scripts_to_execute_as_soon_as_possible().is_empty();
});
// Spin the event loop until there is nothing that delays the load event in the Document.
HTML::main_thread_event_loop().spin_until([&] {
return m_document.number_of_things_delaying_the_load_event() == 0;
return m_document->number_of_things_delaying_the_load_event() == 0;
});
// Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following steps:
old_queue_global_task_with_document(HTML::Task::Source::DOMManipulation, m_document, [document = &m_document] {
old_queue_global_task_with_document(HTML::Task::Source::DOMManipulation, m_document, [document = m_document] {
// Update the current document readiness to "complete".
document->update_readiness(HTML::DocumentReadyState::Complete);
@ -256,7 +256,7 @@ void XMLDocumentBuilder::document_end()
// FIXME: If the Document's print when loaded flag is set, then run the printing steps.
// The Document is now ready for post-load tasks.
m_document.set_ready_for_post_load_tasks(true);
m_document->set_ready_for_post_load_tasks(true);
}
}

View file

@ -36,8 +36,8 @@ private:
virtual void comment(StringView data) override;
virtual void document_end() override;
DOM::Document& m_document;
DOM::Node* m_current_node { nullptr };
JS::NonnullGCPtr<DOM::Document> m_document;
JS::GCPtr<DOM::Node> m_current_node;
XMLScriptingSupport m_scripting_support { XMLScriptingSupport::Enabled };
bool m_has_error { false };
StringBuilder text_builder;