mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:07:35 +00:00
LibWeb: Remove unecessary dependence on Window from DOM and WebIDL
These classes only needed Window to get at its realm. Pass a realm directly to construct DOM and WebIDL classes. This change importantly removes the guarantee that a Document will always have a non-null Window object. Only Documents created by a BrowsingContext will have a non-null Window object. Documents created by for example, DocumentFragment, will not have a Window (soon). This incremental commit leaves some workarounds in place to keep other parts of the code building.
This commit is contained in:
parent
8407bf60c5
commit
8de7e49a56
56 changed files with 364 additions and 326 deletions
|
@ -4,23 +4,24 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/AbortController.h>
|
||||
#include <LibWeb/DOM/AbortSignal.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<AbortController> AbortController::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<AbortController> AbortController::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
auto signal = AbortSignal::create_with_global_object(window);
|
||||
return *window.heap().allocate<AbortController>(window.realm(), window, move(signal));
|
||||
auto signal = AbortSignal::construct_impl(realm);
|
||||
return *realm.heap().allocate<AbortController>(realm, realm, move(signal));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller
|
||||
AbortController::AbortController(HTML::Window& window, JS::NonnullGCPtr<AbortSignal> signal)
|
||||
: PlatformObject(window.realm())
|
||||
AbortController::AbortController(JS::Realm& realm, JS::NonnullGCPtr<AbortSignal> signal)
|
||||
: PlatformObject(realm)
|
||||
, m_signal(move(signal))
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("AbortController"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "AbortController"));
|
||||
}
|
||||
|
||||
AbortController::~AbortController() = default;
|
||||
|
|
|
@ -16,7 +16,7 @@ class AbortController final : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(AbortController, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<AbortController> create_with_global_object(HTML::Window&);
|
||||
static JS::NonnullGCPtr<AbortController> construct_impl(JS::Realm&);
|
||||
|
||||
virtual ~AbortController() override;
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
void abort(JS::Value reason);
|
||||
|
||||
private:
|
||||
AbortController(HTML::Window&, JS::NonnullGCPtr<AbortSignal>);
|
||||
AbortController(JS::Realm&, JS::NonnullGCPtr<AbortSignal>);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/AbortSignal.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/EventDispatcher.h>
|
||||
|
@ -11,15 +12,20 @@
|
|||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<AbortSignal> AbortSignal::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<AbortSignal> AbortSignal::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
return *window.heap().allocate<AbortSignal>(window.realm(), window);
|
||||
return *realm.heap().allocate<AbortSignal>(realm, realm);
|
||||
}
|
||||
|
||||
AbortSignal::AbortSignal(JS::Realm& realm)
|
||||
: EventTarget(realm)
|
||||
{
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "AbortSignal"));
|
||||
}
|
||||
|
||||
AbortSignal::AbortSignal(HTML::Window& window)
|
||||
: EventTarget(window.realm())
|
||||
: AbortSignal(window.realm())
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("AbortSignal"));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#abortsignal-add
|
||||
|
@ -44,7 +50,7 @@ void AbortSignal::signal_abort(JS::Value reason)
|
|||
if (!reason.is_undefined())
|
||||
m_abort_reason = reason;
|
||||
else
|
||||
m_abort_reason = WebIDL::AbortError::create(global_object(), "Aborted without reason").ptr();
|
||||
m_abort_reason = WebIDL::AbortError::create(realm(), "Aborted without reason").ptr();
|
||||
|
||||
// 3. For each algorithm in signal’s abort algorithms: run algorithm.
|
||||
for (auto& algorithm : m_abort_algorithms)
|
||||
|
@ -54,7 +60,7 @@ void AbortSignal::signal_abort(JS::Value reason)
|
|||
m_abort_algorithms.clear();
|
||||
|
||||
// 5. Fire an event named abort at signal.
|
||||
dispatch_event(*Event::create(global_object(), HTML::EventNames::abort));
|
||||
dispatch_event(*Event::create(realm(), HTML::EventNames::abort));
|
||||
}
|
||||
|
||||
void AbortSignal::set_onabort(WebIDL::CallbackType* event_handler)
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <AK/Weakable.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -19,7 +18,7 @@ class AbortSignal final : public EventTarget {
|
|||
WEB_PLATFORM_OBJECT(AbortSignal, EventTarget);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<AbortSignal> create_with_global_object(HTML::Window&);
|
||||
static JS::NonnullGCPtr<AbortSignal> construct_impl(JS::Realm&);
|
||||
|
||||
virtual ~AbortSignal() override = default;
|
||||
|
||||
|
@ -40,6 +39,7 @@ public:
|
|||
JS::ThrowCompletionOr<void> throw_if_aborted() const;
|
||||
|
||||
private:
|
||||
explicit AbortSignal(JS::Realm&);
|
||||
explicit AbortSignal(HTML::Window&);
|
||||
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/AbstractRange.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
AbstractRange::AbstractRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset)
|
||||
: Bindings::PlatformObject(start_container.document().window().cached_web_prototype("AbstractRange"))
|
||||
: Bindings::PlatformObject(Bindings::cached_web_prototype(start_container.realm(), "AbstractRange"))
|
||||
, m_start_container(start_container)
|
||||
, m_start_offset(start_offset)
|
||||
, m_end_container(end_container)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Attr.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
|
@ -23,7 +24,7 @@ Attr::Attr(Document& document, FlyString local_name, String value, Element const
|
|||
, m_value(move(value))
|
||||
, m_owner_element(owner_element)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("Attr"));
|
||||
set_prototype(&Bindings::cached_web_prototype(document.realm(), "Attr"));
|
||||
}
|
||||
|
||||
void Attr::visit_edges(Cell::Visitor& visitor)
|
||||
|
@ -69,7 +70,7 @@ void Attr::set_value(String value)
|
|||
void Attr::handle_attribute_changes(Element& element, String const& old_value, [[maybe_unused]] String const& new_value)
|
||||
{
|
||||
// 1. Queue a mutation record of "attributes" for element with attribute’s local name, attribute’s namespace, oldValue, « », « », null, and null.
|
||||
element.queue_mutation_record(MutationType::attributes, local_name(), namespace_uri(), old_value, StaticNodeList::create(window(), {}), StaticNodeList::create(window(), {}), nullptr, nullptr);
|
||||
element.queue_mutation_record(MutationType::attributes, local_name(), namespace_uri(), old_value, StaticNodeList::create(realm(), {}), StaticNodeList::create(realm(), {}), nullptr, nullptr);
|
||||
|
||||
// FIXME: 2. If element is custom, then enqueue a custom element callback reaction with element, callback name "attributeChangedCallback", and an argument list containing attribute’s local name, oldValue, newValue, and attribute’s namespace.
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Web::DOM {
|
|||
CDATASection::CDATASection(Document& document, String const& data)
|
||||
: Text(document, NodeType::CDATA_SECTION_NODE, data)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("CDATASection"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm(), "CDATASection"));
|
||||
}
|
||||
|
||||
CDATASection::~CDATASection() = default;
|
||||
|
|
|
@ -17,7 +17,7 @@ CharacterData::CharacterData(Document& document, NodeType type, String const& da
|
|||
: Node(document, type)
|
||||
, m_data(data)
|
||||
{
|
||||
set_prototype(&window().ensure_web_prototype<Bindings::CharacterDataPrototype>("CharacterData"));
|
||||
set_prototype(&Bindings::ensure_web_prototype<Bindings::CharacterDataPrototype>(document.realm(), "CharacterData"));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
|
@ -38,7 +38,7 @@ WebIDL::ExceptionOr<String> CharacterData::substring_data(size_t offset, size_t
|
|||
|
||||
// 2. If offset is greater than length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > length)
|
||||
return WebIDL::IndexSizeError::create(global_object(), "Substring offset out of range.");
|
||||
return WebIDL::IndexSizeError::create(realm(), "Substring offset out of range.");
|
||||
|
||||
// 3. If offset plus count is greater than length, return a string whose value is the code units from the offsetth code unit
|
||||
// to the end of node’s data, and then return.
|
||||
|
@ -57,14 +57,14 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
|
||||
// 2. If offset is greater than length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > length)
|
||||
return WebIDL::IndexSizeError::create(global_object(), "Replacement offset out of range.");
|
||||
return WebIDL::IndexSizeError::create(realm(), "Replacement offset out of range.");
|
||||
|
||||
// 3. If offset plus count is greater than length, then set count to length minus offset.
|
||||
if (offset + count > length)
|
||||
count = length - offset;
|
||||
|
||||
// 4. Queue a mutation record of "characterData" for node with null, null, node’s data, « », « », null, and null.
|
||||
queue_mutation_record(MutationType::characterData, {}, {}, m_data, StaticNodeList::create(window(), {}), StaticNodeList::create(window(), {}), nullptr, nullptr);
|
||||
queue_mutation_record(MutationType::characterData, {}, {}, m_data, StaticNodeList::create(realm(), {}), StaticNodeList::create(realm(), {}), nullptr, nullptr);
|
||||
|
||||
// 5. Insert data into node’s data after offset code units.
|
||||
// 6. Let delete offset be offset + data’s length.
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
WebIDL::ExceptionOr<void> replace_data(size_t offset, size_t count, String const&);
|
||||
|
||||
protected:
|
||||
explicit CharacterData(Document&, NodeType, String const&);
|
||||
CharacterData(Document&, NodeType, String const&);
|
||||
|
||||
private:
|
||||
String m_data;
|
||||
|
|
|
@ -16,9 +16,10 @@ Comment::Comment(Document& document, String const& data)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-comment-comment
|
||||
JS::NonnullGCPtr<Comment> Comment::create_with_global_object(HTML::Window& window, String const& data)
|
||||
JS::NonnullGCPtr<Comment> Comment::construct_impl(JS::Realm& realm, String const& data)
|
||||
{
|
||||
return *window.heap().allocate<Comment>(window.realm(), window.associated_document(), data);
|
||||
auto& window = verify_cast<HTML::Window>(realm.global_object());
|
||||
return *realm.heap().allocate<Comment>(realm, window.associated_document(), data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ class Comment final : public CharacterData {
|
|||
WEB_PLATFORM_OBJECT(Comment, CharacterData);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<Comment> create_with_global_object(HTML::Window&, String const& data);
|
||||
static JS::NonnullGCPtr<Comment> construct_impl(JS::Realm&, String const& data);
|
||||
virtual ~Comment() override = default;
|
||||
|
||||
virtual FlyString node_name() const override { return "#comment"; }
|
||||
|
||||
private:
|
||||
explicit Comment(Document&, String const&);
|
||||
Comment(Document&, String const&);
|
||||
};
|
||||
|
||||
template<>
|
||||
|
|
|
@ -5,32 +5,27 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/CustomEvent.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
CustomEvent* CustomEvent::create(HTML::Window& window_object, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
CustomEvent* CustomEvent::create(JS::Realm& realm, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
{
|
||||
return window_object.heap().allocate<CustomEvent>(window_object.realm(), window_object, event_name, event_init);
|
||||
return realm.heap().allocate<CustomEvent>(realm, realm, event_name, event_init);
|
||||
}
|
||||
|
||||
CustomEvent* CustomEvent::create_with_global_object(HTML::Window& window_object, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
CustomEvent* CustomEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
{
|
||||
return create(window_object, event_name, event_init);
|
||||
return create(realm, event_name, event_init);
|
||||
}
|
||||
|
||||
CustomEvent::CustomEvent(HTML::Window& window_object, FlyString const& event_name)
|
||||
: Event(window_object, event_name)
|
||||
{
|
||||
set_prototype(&window_object.cached_web_prototype("CustomEvent"));
|
||||
}
|
||||
|
||||
CustomEvent::CustomEvent(HTML::Window& window_object, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
: Event(window_object, event_name, event_init)
|
||||
CustomEvent::CustomEvent(JS::Realm& realm, FlyString const& event_name, CustomEventInit const& event_init)
|
||||
: Event(realm, event_name, event_init)
|
||||
, m_detail(event_init.detail)
|
||||
{
|
||||
set_prototype(&window_object.cached_web_prototype("CustomEvent"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "CustomEvent"));
|
||||
}
|
||||
|
||||
CustomEvent::~CustomEvent() = default;
|
||||
|
|
|
@ -20,11 +20,8 @@ class CustomEvent : public Event {
|
|||
WEB_PLATFORM_OBJECT(CustomEvent, Event);
|
||||
|
||||
public:
|
||||
static CustomEvent* create(HTML::Window&, FlyString const& event_name, CustomEventInit const& event_init = {});
|
||||
static CustomEvent* create_with_global_object(HTML::Window&, FlyString const& event_name, CustomEventInit const& event_init);
|
||||
|
||||
CustomEvent(HTML::Window&, FlyString const& event_name);
|
||||
CustomEvent(HTML::Window&, FlyString const& event_name, CustomEventInit const& event_init);
|
||||
static CustomEvent* create(JS::Realm&, FlyString const& event_name, CustomEventInit const& event_init = {});
|
||||
static CustomEvent* construct_impl(JS::Realm&, FlyString const& event_name, CustomEventInit const& event_init);
|
||||
|
||||
virtual ~CustomEvent() override;
|
||||
|
||||
|
@ -36,6 +33,8 @@ public:
|
|||
void init_custom_event(String const& type, bool bubbles, bool cancelable, JS::Value detail);
|
||||
|
||||
private:
|
||||
CustomEvent(JS::Realm&, FlyString const& event_name, CustomEventInit const& event_init);
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-customevent-initcustomevent-type-bubbles-cancelable-detail-detail
|
||||
JS::Value m_detail { JS::js_null() };
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/DOM/DOMImplementation.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
@ -12,19 +13,18 @@
|
|||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/HTML/Origin.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<DOMImplementation> DOMImplementation::create(Document& document)
|
||||
{
|
||||
auto& window = document.window();
|
||||
return *window.heap().allocate<DOMImplementation>(document.realm(), document);
|
||||
auto& realm = document.realm();
|
||||
return *realm.heap().allocate<DOMImplementation>(realm, document);
|
||||
}
|
||||
|
||||
DOMImplementation::DOMImplementation(Document& document)
|
||||
: PlatformObject(document.window().cached_web_prototype("DOMImplementation"))
|
||||
: PlatformObject(Bindings::cached_web_prototype(document.realm(), "DOMImplementation"))
|
||||
, m_document(document)
|
||||
{
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ void DOMImplementation::visit_edges(Cell::Visitor& visitor)
|
|||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Document>> DOMImplementation::create_document(String const& namespace_, String const& qualified_name, JS::GCPtr<DocumentType> doctype) const
|
||||
{
|
||||
// FIXME: This should specifically be an XML document.
|
||||
auto xml_document = Document::create(Bindings::main_thread_internal_window_object());
|
||||
auto xml_document = Document::create(realm());
|
||||
|
||||
xml_document->set_ready_for_post_load_tasks(true);
|
||||
|
||||
|
@ -71,7 +71,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Document>> DOMImplementation::create_docume
|
|||
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||||
JS::NonnullGCPtr<Document> DOMImplementation::create_html_document(String const& title) const
|
||||
{
|
||||
auto html_document = Document::create(Bindings::main_thread_internal_window_object());
|
||||
auto html_document = Document::create(realm());
|
||||
|
||||
html_document->set_content_type("text/html");
|
||||
html_document->set_ready_for_post_load_tasks(true);
|
||||
|
@ -105,7 +105,7 @@ JS::NonnullGCPtr<Document> DOMImplementation::create_html_document(String const&
|
|||
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentType>> DOMImplementation::create_document_type(String const& qualified_name, String const& public_id, String const& system_id)
|
||||
{
|
||||
TRY(Document::validate_qualified_name(global_object(), qualified_name));
|
||||
TRY(Document::validate_qualified_name(realm(), qualified_name));
|
||||
auto document_type = DocumentType::create(document());
|
||||
document_type->set_name(qualified_name);
|
||||
document_type->set_public_id(public_id);
|
||||
|
|
|
@ -61,7 +61,7 @@ DOMTokenList* DOMTokenList::create(Element const& associated_element, FlyString
|
|||
|
||||
// https://dom.spec.whatwg.org/#ref-for-domtokenlist%E2%91%A0%E2%91%A2
|
||||
DOMTokenList::DOMTokenList(Element const& associated_element, FlyString associated_attribute)
|
||||
: Bindings::LegacyPlatformObject(associated_element.window().cached_web_prototype("DOMTokenList"))
|
||||
: Bindings::LegacyPlatformObject(Bindings::cached_web_prototype(associated_element.realm(), "DOMTokenList"))
|
||||
, m_associated_element(associated_element)
|
||||
, m_associated_attribute(move(associated_attribute))
|
||||
{
|
||||
|
@ -234,9 +234,9 @@ void DOMTokenList::set_value(String value)
|
|||
WebIDL::ExceptionOr<void> DOMTokenList::validate_token(StringView token) const
|
||||
{
|
||||
if (token.is_empty())
|
||||
return WebIDL::SyntaxError::create(global_object(), "Non-empty DOM tokens are not allowed");
|
||||
return WebIDL::SyntaxError::create(realm(), "Non-empty DOM tokens are not allowed");
|
||||
if (any_of(token, is_ascii_space))
|
||||
return WebIDL::InvalidCharacterError::create(global_object(), "DOM tokens containing ASCII whitespace are not allowed");
|
||||
return WebIDL::InvalidCharacterError::create(realm(), "DOM tokens containing ASCII whitespace are not allowed");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -223,9 +223,9 @@ JS::NonnullGCPtr<Document> Document::create_and_initialize(Type type, String con
|
|||
// FIXME: and cross-origin opener policy is navigationParams's cross-origin opener policy,
|
||||
// FIXME: load timing info is loadTimingInfo,
|
||||
// and navigation id is navigationParams's id.
|
||||
auto document = Document::create(*window);
|
||||
auto document = Document::create(window->realm());
|
||||
document->m_type = type;
|
||||
document->m_content_type = content_type;
|
||||
document->m_content_type = move(content_type);
|
||||
document->set_origin(navigation_params.origin);
|
||||
document->m_policy_container = navigation_params.policy_container;
|
||||
document->m_active_sandboxing_flag_set = navigation_params.final_sandboxing_flag_set;
|
||||
|
@ -276,24 +276,27 @@ JS::NonnullGCPtr<Document> Document::create_and_initialize(Type type, String con
|
|||
return document;
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Document> Document::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<Document> Document::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
return Document::create(window);
|
||||
return Document::create(realm);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Document> Document::create(JS::Realm& realm, AK::URL const& url)
|
||||
{
|
||||
return *realm.heap().allocate<Document>(realm, realm, url);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Document> Document::create(HTML::Window& window, AK::URL const& url)
|
||||
{
|
||||
auto& realm = window.realm();
|
||||
return *realm.heap().allocate<Document>(realm, window, url);
|
||||
return create(window.realm(), url);
|
||||
}
|
||||
|
||||
Document::Document(HTML::Window& window, const AK::URL& url)
|
||||
: ParentNode(window.realm(), *this, NodeType::DOCUMENT_NODE)
|
||||
Document::Document(JS::Realm& realm, const AK::URL& url)
|
||||
: ParentNode(realm, *this, NodeType::DOCUMENT_NODE)
|
||||
, m_style_computer(make<CSS::StyleComputer>(*this))
|
||||
, m_url(url)
|
||||
, m_window(window)
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("Document"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "Document"));
|
||||
|
||||
HTML::main_thread_event_loop().register_document({}, *this);
|
||||
|
||||
|
@ -374,11 +377,11 @@ WebIDL::ExceptionOr<void> Document::run_the_document_write_steps(String input)
|
|||
{
|
||||
// 1. If document is an XML document, then throw an "InvalidStateError" DOMException.
|
||||
if (m_type == Type::XML)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "write() called on XML document.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "write() called on XML document.");
|
||||
|
||||
// 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.
|
||||
if (m_throw_on_dynamic_markup_insertion_counter > 0)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
|
||||
// 3. If document's active parser was aborted is true, then return.
|
||||
if (m_active_parser_was_aborted)
|
||||
|
@ -409,18 +412,18 @@ WebIDL::ExceptionOr<Document*> Document::open(String const&, String const&)
|
|||
{
|
||||
// 1. If document is an XML document, then throw an "InvalidStateError" DOMException exception.
|
||||
if (m_type == Type::XML)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "open() called on XML document.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "open() called on XML document.");
|
||||
|
||||
// 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.
|
||||
if (m_throw_on_dynamic_markup_insertion_counter > 0)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
|
||||
// FIXME: 3. Let entryDocument be the entry global object's associated Document.
|
||||
auto& entry_document = *this;
|
||||
|
||||
// 4. If document's origin is not same origin to entryDocument's origin, then throw a "SecurityError" DOMException.
|
||||
if (origin() != entry_document.origin())
|
||||
return WebIDL::SecurityError::create(global_object(), "Document.origin() not the same as entryDocument's.");
|
||||
return WebIDL::SecurityError::create(realm(), "Document.origin() not the same as entryDocument's.");
|
||||
|
||||
// 5. If document has an active parser whose script nesting level is greater than 0, then return document.
|
||||
if (m_parser && m_parser->script_nesting_level() > 0)
|
||||
|
@ -480,11 +483,11 @@ WebIDL::ExceptionOr<void> Document::close()
|
|||
{
|
||||
// 1. If document is an XML document, then throw an "InvalidStateError" DOMException exception.
|
||||
if (m_type == Type::XML)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "close() called on XML document.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "close() called on XML document.");
|
||||
|
||||
// 2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.
|
||||
if (m_throw_on_dynamic_markup_insertion_counter > 0)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "throw-on-dynamic-markup-insertion-counter greater than zero.");
|
||||
|
||||
// 3. If there is no script-created parser associated with the document, then return.
|
||||
if (!m_parser)
|
||||
|
@ -588,7 +591,7 @@ HTML::HTMLElement* Document::body()
|
|||
WebIDL::ExceptionOr<void> Document::set_body(HTML::HTMLElement* new_body)
|
||||
{
|
||||
if (!is<HTML::HTMLBodyElement>(new_body) && !is<HTML::HTMLFrameSetElement>(new_body))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid document body element, must be 'body' or 'frameset'");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid document body element, must be 'body' or 'frameset'");
|
||||
|
||||
auto* existing_body = body();
|
||||
if (existing_body) {
|
||||
|
@ -598,7 +601,7 @@ WebIDL::ExceptionOr<void> Document::set_body(HTML::HTMLElement* new_body)
|
|||
|
||||
auto* document_element = this->document_element();
|
||||
if (!document_element)
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Missing document element");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Missing document element");
|
||||
|
||||
(void)TRY(document_element->append_child(*new_body));
|
||||
return {};
|
||||
|
@ -1118,7 +1121,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> Document::create_element(FlyStrin
|
|||
|
||||
// 1. If localName does not match the Name production, then throw an "InvalidCharacterError" DOMException.
|
||||
if (!is_valid_name(local_name))
|
||||
return WebIDL::InvalidCharacterError::create(global_object(), "Invalid character in tag name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm(), "Invalid character in tag name.");
|
||||
|
||||
// 2. If this is an HTML document, then set localName to localName in ASCII lowercase.
|
||||
if (document_type() == Type::HTML)
|
||||
|
@ -1142,7 +1145,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> Document::create_element(FlyStrin
|
|||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> Document::create_element_ns(String const& namespace_, String const& qualified_name)
|
||||
{
|
||||
// 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
|
||||
auto extracted_qualified_name = TRY(validate_and_extract(global_object(), namespace_, qualified_name));
|
||||
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_, qualified_name));
|
||||
|
||||
// FIXME: 2. Let is be null.
|
||||
// FIXME: 3. If options is a dictionary and options["is"] exists, then set is to it.
|
||||
|
@ -1174,7 +1177,8 @@ JS::NonnullGCPtr<Range> Document::create_range()
|
|||
// https://dom.spec.whatwg.org/#dom-document-createevent
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Event>> Document::create_event(String const& interface)
|
||||
{
|
||||
auto& window_object = window();
|
||||
auto& realm = this->realm();
|
||||
auto& window = verify_cast<HTML::Window>(realm.global_object());
|
||||
|
||||
// NOTE: This is named event here, since we do step 5 and 6 as soon as possible for each case.
|
||||
// 1. Let constructor be null.
|
||||
|
@ -1184,46 +1188,46 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Event>> Document::create_event(String const
|
|||
// then set constructor to the interface in the second column on the same row as the matching string:
|
||||
auto interface_lowercase = interface.to_lowercase();
|
||||
if (interface_lowercase == "beforeunloadevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create BeforeUnloadEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create BeforeUnloadEvent
|
||||
} else if (interface_lowercase == "compositionevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create CompositionEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create CompositionEvent
|
||||
} else if (interface_lowercase == "customevent") {
|
||||
event = CustomEvent::create(window_object, "");
|
||||
event = CustomEvent::create(realm, "");
|
||||
} else if (interface_lowercase == "devicemotionevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create DeviceMotionEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create DeviceMotionEvent
|
||||
} else if (interface_lowercase == "deviceorientationevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create DeviceOrientationEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create DeviceOrientationEvent
|
||||
} else if (interface_lowercase == "dragevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create DragEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create DragEvent
|
||||
} else if (interface_lowercase.is_one_of("event", "events")) {
|
||||
event = Event::create(window_object, "");
|
||||
event = Event::create(realm, "");
|
||||
} else if (interface_lowercase == "focusevent") {
|
||||
event = UIEvents::FocusEvent::create(window_object, "");
|
||||
event = UIEvents::FocusEvent::create(window, "");
|
||||
} else if (interface_lowercase == "hashchangeevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create HashChangeEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create HashChangeEvent
|
||||
} else if (interface_lowercase == "htmlevents") {
|
||||
event = Event::create(window_object, "");
|
||||
event = Event::create(realm, "");
|
||||
} else if (interface_lowercase == "keyboardevent") {
|
||||
event = UIEvents::KeyboardEvent::create(window_object, "");
|
||||
event = UIEvents::KeyboardEvent::create(window, "");
|
||||
} else if (interface_lowercase == "messageevent") {
|
||||
event = HTML::MessageEvent::create(window_object, "");
|
||||
event = HTML::MessageEvent::create(window, "");
|
||||
} else if (interface_lowercase.is_one_of("mouseevent", "mouseevents")) {
|
||||
event = UIEvents::MouseEvent::create(window_object, "");
|
||||
event = UIEvents::MouseEvent::create(window, "");
|
||||
} else if (interface_lowercase == "storageevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create StorageEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create StorageEvent
|
||||
} else if (interface_lowercase == "svgevents") {
|
||||
event = Event::create(window_object, "");
|
||||
event = Event::create(realm, "");
|
||||
} else if (interface_lowercase == "textevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create CompositionEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create CompositionEvent
|
||||
} else if (interface_lowercase == "touchevent") {
|
||||
event = Event::create(window_object, ""); // FIXME: Create TouchEvent
|
||||
event = Event::create(realm, ""); // FIXME: Create TouchEvent
|
||||
} else if (interface_lowercase.is_one_of("uievent", "uievents")) {
|
||||
event = UIEvents::UIEvent::create(window_object, "");
|
||||
event = UIEvents::UIEvent::create(window, "");
|
||||
}
|
||||
|
||||
// 3. If constructor is null, then throw a "NotSupportedError" DOMException.
|
||||
if (!event) {
|
||||
return WebIDL::NotSupportedError::create(global_object(), "No constructor for interface found");
|
||||
return WebIDL::NotSupportedError::create(realm, "No constructor for interface found");
|
||||
}
|
||||
|
||||
// FIXME: 4. If the interface indicated by constructor is not exposed on the relevant global object of this, then throw a "NotSupportedError" DOMException.
|
||||
|
@ -1293,7 +1297,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Document::import_node(JS::NonnullGCP
|
|||
{
|
||||
// 1. If node is a document or shadow root, then throw a "NotSupportedError" DOMException.
|
||||
if (is<Document>(*node) || is<ShadowRoot>(*node))
|
||||
return WebIDL::NotSupportedError::create(global_object(), "Cannot import a document or shadow root.");
|
||||
return WebIDL::NotSupportedError::create(realm(), "Cannot import a document or shadow root.");
|
||||
|
||||
// 2. Return a clone of node, with this and the clone children flag set if deep is true.
|
||||
return node->clone_node(this, deep);
|
||||
|
@ -1340,10 +1344,10 @@ void Document::adopt_node(Node& node)
|
|||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Document::adopt_node_binding(JS::NonnullGCPtr<Node> node)
|
||||
{
|
||||
if (is<Document>(*node))
|
||||
return WebIDL::NotSupportedError::create(global_object(), "Cannot adopt a document into a document");
|
||||
return WebIDL::NotSupportedError::create(realm(), "Cannot adopt a document into a document");
|
||||
|
||||
if (is<ShadowRoot>(*node))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Cannot adopt a shadow root into a document");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Cannot adopt a shadow root into a document");
|
||||
|
||||
if (is<DocumentFragment>(*node) && verify_cast<DocumentFragment>(*node).host())
|
||||
return node;
|
||||
|
@ -1447,7 +1451,7 @@ void Document::update_readiness(HTML::DocumentReadyState readiness_value)
|
|||
}
|
||||
|
||||
// 4. Fire an event named readystatechange at document.
|
||||
dispatch_event(*Event::create(window(), HTML::EventNames::readystatechange));
|
||||
dispatch_event(*Event::create(realm(), HTML::EventNames::readystatechange));
|
||||
}
|
||||
|
||||
Page* Document::page()
|
||||
|
@ -1465,7 +1469,7 @@ EventTarget* Document::get_parent(Event const& event)
|
|||
if (event.type() == HTML::EventNames::load)
|
||||
return nullptr;
|
||||
|
||||
return &window();
|
||||
return m_window;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#completely-loaded
|
||||
|
@ -1495,7 +1499,7 @@ void Document::completely_finish_loading()
|
|||
// 5. Otherwise, if container is non-null, then queue an element task on the DOM manipulation task source given container to fire an event named load at container.
|
||||
else if (container) {
|
||||
container->queue_an_element_task(HTML::Task::Source::DOMManipulation, [container]() mutable {
|
||||
container->dispatch_event(*DOM::Event::create(container->window(), HTML::EventNames::load));
|
||||
container->dispatch_event(*DOM::Event::create(container->realm(), HTML::EventNames::load));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1625,7 +1629,7 @@ void Document::update_the_visibility_state(HTML::VisibilityState visibility_stat
|
|||
// FIXME: 3. Run any page visibility change steps which may be defined in other specifications, with visibility state and document.
|
||||
|
||||
// 4. Fire an event named visibilitychange at document, with its bubbles attribute initialized to true.
|
||||
auto event = DOM::Event::create(window(), HTML::EventNames::visibilitychange);
|
||||
auto event = DOM::Event::create(realm(), HTML::EventNames::visibilitychange);
|
||||
event->set_bubbles(true);
|
||||
dispatch_event(event);
|
||||
}
|
||||
|
@ -1646,7 +1650,7 @@ void Document::run_the_resize_steps()
|
|||
return;
|
||||
m_last_viewport_size = viewport_size;
|
||||
|
||||
window().dispatch_event(*DOM::Event::create(window(), UIEvents::EventNames::resize));
|
||||
window().dispatch_event(*DOM::Event::create(realm(), UIEvents::EventNames::resize));
|
||||
|
||||
update_layout();
|
||||
}
|
||||
|
@ -1658,14 +1662,14 @@ void Document::run_the_scroll_steps()
|
|||
for (auto& target : m_pending_scroll_event_targets) {
|
||||
// 1. If target is a Document, fire an event named scroll that bubbles at target and fire an event named scroll at the VisualViewport that is associated with target.
|
||||
if (is<Document>(*target)) {
|
||||
auto event = DOM::Event::create(window(), HTML::EventNames::scroll);
|
||||
auto event = DOM::Event::create(realm(), HTML::EventNames::scroll);
|
||||
event->set_bubbles(true);
|
||||
target->dispatch_event(*event);
|
||||
// FIXME: Fire at the associated VisualViewport
|
||||
}
|
||||
// 2. Otherwise, fire an event named scroll at target.
|
||||
else {
|
||||
auto event = DOM::Event::create(window(), HTML::EventNames::scroll);
|
||||
auto event = DOM::Event::create(realm(), HTML::EventNames::scroll);
|
||||
target->dispatch_event(*event);
|
||||
}
|
||||
}
|
||||
|
@ -1802,14 +1806,14 @@ bool Document::is_valid_name(String const& name)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#validate
|
||||
WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_name(JS::Object& global_object, String const& qualified_name)
|
||||
WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_name(JS::Realm& realm, String const& qualified_name)
|
||||
{
|
||||
if (qualified_name.is_empty())
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Empty string is not a valid qualified name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Empty string is not a valid qualified name.");
|
||||
|
||||
Utf8View utf8view { qualified_name };
|
||||
if (!utf8view.validate())
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Invalid qualified name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Invalid qualified name.");
|
||||
|
||||
Optional<size_t> colon_offset;
|
||||
|
||||
|
@ -1819,19 +1823,19 @@ WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_nam
|
|||
auto code_point = *it;
|
||||
if (code_point == ':') {
|
||||
if (colon_offset.has_value())
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "More than one colon (:) in qualified name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "More than one colon (:) in qualified name.");
|
||||
colon_offset = utf8view.byte_offset_of(it);
|
||||
at_start_of_name = true;
|
||||
continue;
|
||||
}
|
||||
if (at_start_of_name) {
|
||||
if (!is_valid_name_start_character(code_point))
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Invalid start of qualified name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Invalid start of qualified name.");
|
||||
at_start_of_name = false;
|
||||
continue;
|
||||
}
|
||||
if (!is_valid_name_character(code_point))
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Invalid character in qualified name.");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Invalid character in qualified name.");
|
||||
}
|
||||
|
||||
if (!colon_offset.has_value())
|
||||
|
@ -1841,10 +1845,10 @@ WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_nam
|
|||
};
|
||||
|
||||
if (*colon_offset == 0)
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Qualified name can't start with colon (:).");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Qualified name can't start with colon (:).");
|
||||
|
||||
if (*colon_offset >= (qualified_name.length() - 1))
|
||||
return WebIDL::InvalidCharacterError::create(global_object, "Qualified name can't end with colon (:).");
|
||||
return WebIDL::InvalidCharacterError::create(realm, "Qualified name can't end with colon (:).");
|
||||
|
||||
return Document::PrefixAndTagName {
|
||||
.prefix = qualified_name.substring_view(0, *colon_offset),
|
||||
|
@ -2164,7 +2168,7 @@ void Document::unload(bool recursive_flag, Optional<DocumentUnloadTimingInfo> un
|
|||
// then fire an event named unload at document's relevant global object, with legacy target override flag set.
|
||||
// FIXME: The legacy target override flag is currently set by a virtual override of dispatch_event()
|
||||
// We should reorganize this so that the flag appears explicitly here instead.
|
||||
auto event = DOM::Event::create(global_object(), HTML::EventNames::unload);
|
||||
auto event = DOM::Event::create(realm(), HTML::EventNames::unload);
|
||||
global_object().dispatch_event(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <LibWeb/Cookie/Cookie.h>
|
||||
#include <LibWeb/DOM/NonElementParentNode.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/CrossOrigin/CrossOriginOpenerPolicy.h>
|
||||
#include <LibWeb/HTML/DocumentReadyState.h>
|
||||
#include <LibWeb/HTML/HTMLScriptElement.h>
|
||||
|
@ -82,8 +83,9 @@ public:
|
|||
|
||||
static JS::NonnullGCPtr<Document> create_and_initialize(Type, String content_type, HTML::NavigationParams);
|
||||
|
||||
static JS::NonnullGCPtr<Document> create(JS::Realm&, AK::URL const& url = "about:blank"sv);
|
||||
static JS::NonnullGCPtr<Document> create(HTML::Window&, AK::URL const& url = "about:blank"sv);
|
||||
static JS::NonnullGCPtr<Document> create_with_global_object(HTML::Window&);
|
||||
static JS::NonnullGCPtr<Document> construct_impl(JS::Realm&);
|
||||
virtual ~Document() override;
|
||||
|
||||
size_t next_layout_node_serial_id(Badge<Layout::Node>) { return m_next_layout_node_serial_id++; }
|
||||
|
@ -367,7 +369,7 @@ public:
|
|||
FlyString prefix;
|
||||
FlyString tag_name;
|
||||
};
|
||||
static WebIDL::ExceptionOr<PrefixAndTagName> validate_qualified_name(JS::Object& global_object, String const& qualified_name);
|
||||
static WebIDL::ExceptionOr<PrefixAndTagName> validate_qualified_name(JS::Realm&, String const& qualified_name);
|
||||
|
||||
JS::NonnullGCPtr<NodeIterator> create_node_iterator(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);
|
||||
JS::NonnullGCPtr<TreeWalker> create_tree_walker(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);
|
||||
|
@ -440,7 +442,7 @@ protected:
|
|||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
Document(HTML::Window&, AK::URL const&);
|
||||
Document(JS::Realm&, AK::URL const&);
|
||||
|
||||
// ^HTML::GlobalEventHandlers
|
||||
virtual EventTarget& global_event_handlers_to_event_target(FlyString const&) final { return *this; }
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Web::DOM {
|
|||
DocumentFragment::DocumentFragment(Document& document)
|
||||
: ParentNode(document, NodeType::DOCUMENT_FRAGMENT_NODE)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("DocumentFragment"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm(), "DocumentFragment"));
|
||||
}
|
||||
|
||||
void DocumentFragment::visit_edges(Cell::Visitor& visitor)
|
||||
|
@ -27,9 +27,10 @@ void DocumentFragment::set_host(Web::DOM::Element* element)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-documentfragment-documentfragment
|
||||
JS::NonnullGCPtr<DocumentFragment> DocumentFragment::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<DocumentFragment> DocumentFragment::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
return *window.heap().allocate<DocumentFragment>(window.realm(), window.associated_document());
|
||||
auto& window = verify_cast<HTML::Window>(realm.global_object());
|
||||
return *realm.heap().allocate<DocumentFragment>(realm, window.associated_document());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class DocumentFragment
|
|||
WEB_PLATFORM_OBJECT(DocumentFragment, ParentNode);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<DocumentFragment> create_with_global_object(HTML::Window& window);
|
||||
static JS::NonnullGCPtr<DocumentFragment> construct_impl(JS::Realm& realm);
|
||||
|
||||
virtual ~DocumentFragment() override = default;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ JS::NonnullGCPtr<DocumentType> DocumentType::create(Document& document)
|
|||
DocumentType::DocumentType(Document& document)
|
||||
: Node(document, NodeType::DOCUMENT_TYPE_NODE)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("DocumentType"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm(), "DocumentType"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ Element::Element(Document& document, DOM::QualifiedName qualified_name)
|
|||
: ParentNode(document, NodeType::ELEMENT_NODE)
|
||||
, m_qualified_name(move(qualified_name))
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("Element"));
|
||||
set_prototype(&Bindings::cached_web_prototype(document.realm(), "Element"));
|
||||
make_html_uppercased_qualified_name();
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ WebIDL::ExceptionOr<void> Element::set_attribute(FlyString const& name, String c
|
|||
// 1. If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException.
|
||||
// FIXME: Proper name validation
|
||||
if (name.is_empty())
|
||||
return WebIDL::InvalidCharacterError::create(global_object(), "Attribute name must not be empty");
|
||||
return WebIDL::InvalidCharacterError::create(realm(), "Attribute name must not be empty");
|
||||
|
||||
// 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
|
||||
// FIXME: Handle the second condition, assume it is an HTML document for now.
|
||||
|
@ -126,14 +126,14 @@ WebIDL::ExceptionOr<void> Element::set_attribute(FlyString const& name, String c
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#validate-and-extract
|
||||
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Object& global_object, FlyString namespace_, FlyString qualified_name)
|
||||
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, FlyString namespace_, FlyString qualified_name)
|
||||
{
|
||||
// 1. If namespace is the empty string, then set it to null.
|
||||
if (namespace_.is_empty())
|
||||
namespace_ = {};
|
||||
|
||||
// 2. Validate qualifiedName.
|
||||
TRY(Document::validate_qualified_name(global_object, qualified_name));
|
||||
TRY(Document::validate_qualified_name(realm, qualified_name));
|
||||
|
||||
// 3. Let prefix be null.
|
||||
FlyString prefix = {};
|
||||
|
@ -150,19 +150,19 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Object& global_objec
|
|||
|
||||
// 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException.
|
||||
if (!prefix.is_null() && namespace_.is_null())
|
||||
return WebIDL::NamespaceError::create(global_object, "Prefix is non-null and namespace is null.");
|
||||
return WebIDL::NamespaceError::create(realm, "Prefix is non-null and namespace is null.");
|
||||
|
||||
// 7. If prefix is "xml" and namespace is not the XML namespace, then throw a "NamespaceError" DOMException.
|
||||
if (prefix == "xml"sv && namespace_ != Namespace::XML)
|
||||
return WebIDL::NamespaceError::create(global_object, "Prefix is 'xml' and namespace is not the XML namespace.");
|
||||
return WebIDL::NamespaceError::create(realm, "Prefix is 'xml' and namespace is not the XML namespace.");
|
||||
|
||||
// 8. If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace, then throw a "NamespaceError" DOMException.
|
||||
if ((qualified_name == "xmlns"sv || prefix == "xmlns"sv) && namespace_ != Namespace::XMLNS)
|
||||
return WebIDL::NamespaceError::create(global_object, "Either qualifiedName or prefix is 'xmlns' and namespace is not the XMLNS namespace.");
|
||||
return WebIDL::NamespaceError::create(realm, "Either qualifiedName or prefix is 'xmlns' and namespace is not the XMLNS namespace.");
|
||||
|
||||
// 9. If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns", then throw a "NamespaceError" DOMException.
|
||||
if (namespace_ == Namespace::XMLNS && !(qualified_name == "xmlns"sv || prefix == "xmlns"sv))
|
||||
return WebIDL::NamespaceError::create(global_object, "Namespace is the XMLNS namespace and neither qualifiedName nor prefix is 'xmlns'.");
|
||||
return WebIDL::NamespaceError::create(realm, "Namespace is the XMLNS namespace and neither qualifiedName nor prefix is 'xmlns'.");
|
||||
|
||||
// 10. Return namespace, prefix, and localName.
|
||||
return QualifiedName { local_name, prefix, namespace_ };
|
||||
|
@ -172,7 +172,7 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Object& global_objec
|
|||
WebIDL::ExceptionOr<void> Element::set_attribute_ns(FlyString const& namespace_, FlyString const& qualified_name, String const& value)
|
||||
{
|
||||
// 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
|
||||
auto extracted_qualified_name = TRY(validate_and_extract(global_object(), namespace_, qualified_name));
|
||||
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_, qualified_name));
|
||||
|
||||
// FIXME: 2. Set an attribute value for this using localName, value, and also prefix and namespace.
|
||||
|
||||
|
@ -203,7 +203,7 @@ WebIDL::ExceptionOr<bool> Element::toggle_attribute(FlyString const& name, Optio
|
|||
// 1. If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException.
|
||||
// FIXME: Proper name validation
|
||||
if (name.is_empty())
|
||||
return WebIDL::InvalidCharacterError::create(global_object(), "Attribute name must not be empty");
|
||||
return WebIDL::InvalidCharacterError::create(realm(), "Attribute name must not be empty");
|
||||
|
||||
// 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
|
||||
// FIXME: Handle the second condition, assume it is an HTML document for now.
|
||||
|
@ -451,7 +451,7 @@ WebIDL::ExceptionOr<bool> Element::matches(StringView selectors) const
|
|||
{
|
||||
auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(static_cast<ParentNode&>(const_cast<Element&>(*this))), selectors);
|
||||
if (!maybe_selectors.has_value())
|
||||
return WebIDL::SyntaxError::create(global_object(), "Failed to parse selector");
|
||||
return WebIDL::SyntaxError::create(realm(), "Failed to parse selector");
|
||||
|
||||
auto sel = maybe_selectors.value();
|
||||
for (auto& s : sel) {
|
||||
|
@ -466,7 +466,7 @@ WebIDL::ExceptionOr<DOM::Element const*> Element::closest(StringView selectors)
|
|||
{
|
||||
auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(static_cast<ParentNode&>(const_cast<Element&>(*this))), selectors);
|
||||
if (!maybe_selectors.has_value())
|
||||
return WebIDL::SyntaxError::create(global_object(), "Failed to parse selector");
|
||||
return WebIDL::SyntaxError::create(realm(), "Failed to parse selector");
|
||||
|
||||
auto matches_selectors = [](CSS::SelectorList const& selector_list, Element const* element) {
|
||||
for (auto& selector : selector_list) {
|
||||
|
@ -780,7 +780,7 @@ WebIDL::ExceptionOr<void> Element::insert_adjacent_html(String position, String
|
|||
|
||||
// If context is null or a Document, throw a "NoModificationAllowedError" DOMException.
|
||||
if (!context || context->is_document())
|
||||
return WebIDL::NoModificationAllowedError::create(window(), "insertAdjacentHTML: context is null or a Document"sv);
|
||||
return WebIDL::NoModificationAllowedError::create(realm(), "insertAdjacentHTML: context is null or a Document"sv);
|
||||
}
|
||||
// - If position is an ASCII case-insensitive match for the string "afterbegin"
|
||||
// - If position is an ASCII case-insensitive match for the string "beforeend"
|
||||
|
@ -791,7 +791,7 @@ WebIDL::ExceptionOr<void> Element::insert_adjacent_html(String position, String
|
|||
// Otherwise
|
||||
else {
|
||||
// Throw a "SyntaxError" DOMException.
|
||||
return WebIDL::SyntaxError::create(window(), "insertAdjacentHTML: invalid position argument"sv);
|
||||
return WebIDL::SyntaxError::create(realm(), "insertAdjacentHTML: invalid position argument"sv);
|
||||
}
|
||||
|
||||
// 2. If context is not an Element or the following are all true:
|
||||
|
@ -878,7 +878,7 @@ WebIDL::ExceptionOr<JS::GCPtr<Node>> Element::insert_adjacent(String const& wher
|
|||
|
||||
// -> Otherwise
|
||||
// Throw a "SyntaxError" DOMException.
|
||||
return WebIDL::SyntaxError::create(global_object(), String::formatted("Unknown position '{}'. Must be one of 'beforebegin', 'afterbegin', 'beforeend' or 'afterend'"sv, where));
|
||||
return WebIDL::SyntaxError::create(realm(), String::formatted("Unknown position '{}'. Must be one of 'beforebegin', 'afterbegin', 'beforeend' or 'afterend'"sv, where));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
|
||||
|
|
|
@ -179,6 +179,6 @@ private:
|
|||
template<>
|
||||
inline bool Node::fast_is<Element>() const { return is_element(); }
|
||||
|
||||
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Object& global_object, FlyString namespace_, FlyString qualified_name);
|
||||
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm&, FlyString namespace_, FlyString qualified_name);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/DOM/ShadowRoot.h>
|
||||
|
@ -14,25 +15,30 @@
|
|||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<Event> Event::create(HTML::Window& window_object, FlyString const& event_name, EventInit const& event_init)
|
||||
JS::NonnullGCPtr<Event> Event::create(JS::Realm& realm, FlyString const& event_name, EventInit const& event_init)
|
||||
{
|
||||
return *window_object.heap().allocate<Event>(window_object.realm(), window_object, event_name, event_init);
|
||||
return *realm.heap().allocate<Event>(realm, realm, event_name, event_init);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Event> Event::create_with_global_object(HTML::Window& window_object, FlyString const& event_name, EventInit const& event_init)
|
||||
JS::NonnullGCPtr<Event> Event::create(HTML::Window& window, FlyString const& event_name, EventInit const& event_init)
|
||||
{
|
||||
return create(window_object, event_name, event_init);
|
||||
return create(window.realm(), event_name, event_init);
|
||||
}
|
||||
|
||||
Event::Event(HTML::Window& window, FlyString const& type)
|
||||
: PlatformObject(window.cached_web_prototype("Event"))
|
||||
JS::NonnullGCPtr<Event> Event::construct_impl(JS::Realm& realm, FlyString const& event_name, EventInit const& event_init)
|
||||
{
|
||||
return create(realm, event_name, event_init);
|
||||
}
|
||||
|
||||
Event::Event(JS::Realm& realm, FlyString const& type)
|
||||
: PlatformObject(Bindings::cached_web_prototype(realm, "Event"))
|
||||
, m_type(type)
|
||||
, m_initialized(true)
|
||||
{
|
||||
}
|
||||
|
||||
Event::Event(HTML::Window& window, FlyString const& type, EventInit const& event_init)
|
||||
: PlatformObject(window.cached_web_prototype("Event"))
|
||||
Event::Event(JS::Realm& realm, FlyString const& type, EventInit const& event_init)
|
||||
: PlatformObject(Bindings::cached_web_prototype(realm, "Event"))
|
||||
, m_type(type)
|
||||
, m_bubbles(event_init.bubbles)
|
||||
, m_cancelable(event_init.cancelable)
|
||||
|
@ -41,6 +47,16 @@ Event::Event(HTML::Window& window, FlyString const& type, EventInit const& event
|
|||
{
|
||||
}
|
||||
|
||||
Event::Event(HTML::Window& window, FlyString const& type, EventInit const& event_init)
|
||||
: Event(window.realm(), type, event_init)
|
||||
{
|
||||
}
|
||||
|
||||
Event::Event(HTML::Window& window, FlyString const& type)
|
||||
: Event(window.realm(), type)
|
||||
{
|
||||
}
|
||||
|
||||
void Event::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <AK/FlyString.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -46,9 +45,12 @@ public:
|
|||
|
||||
using Path = Vector<PathEntry>;
|
||||
|
||||
static JS::NonnullGCPtr<Event> create(JS::Realm&, FlyString const& event_name, EventInit const& event_init = {});
|
||||
static JS::NonnullGCPtr<Event> create(HTML::Window&, FlyString const& event_name, EventInit const& event_init = {});
|
||||
static JS::NonnullGCPtr<Event> create_with_global_object(HTML::Window&, FlyString const& event_name, EventInit const& event_init);
|
||||
static JS::NonnullGCPtr<Event> construct_impl(JS::Realm&, FlyString const& event_name, EventInit const& event_init);
|
||||
|
||||
Event(JS::Realm&, FlyString const& type);
|
||||
Event(JS::Realm&, FlyString const& type, EventInit const& event_init);
|
||||
Event(HTML::Window&, FlyString const& type);
|
||||
Event(HTML::Window&, FlyString const& type, EventInit const& event_init);
|
||||
|
||||
|
|
|
@ -227,10 +227,10 @@ WebIDL::ExceptionOr<bool> EventTarget::dispatch_event_binding(Event& event)
|
|||
{
|
||||
// 1. If event’s dispatch flag is set, or if its initialized flag is not set, then throw an "InvalidStateError" DOMException.
|
||||
if (event.dispatched())
|
||||
return WebIDL::InvalidStateError::create(global_object(), "The event is already being dispatched.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "The event is already being dispatched.");
|
||||
|
||||
if (!event.initialized())
|
||||
return WebIDL::InvalidStateError::create(global_object(), "Cannot dispatch an uninitialized event.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "Cannot dispatch an uninitialized event.");
|
||||
|
||||
// 2. Initialize event’s isTrusted attribute to false.
|
||||
event.set_is_trusted(false);
|
||||
|
|
|
@ -22,7 +22,7 @@ class EventTarget : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(EventTarget, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~EventTarget();
|
||||
virtual ~EventTarget() override;
|
||||
|
||||
virtual bool is_focusable() const { return false; }
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/HTMLCollection.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
@ -19,7 +19,7 @@ JS::NonnullGCPtr<HTMLCollection> HTMLCollection::create(ParentNode& root, Functi
|
|||
}
|
||||
|
||||
HTMLCollection::HTMLCollection(ParentNode& root, Function<bool(Element const&)> filter)
|
||||
: LegacyPlatformObject(root.window().cached_web_prototype("HTMLCollection"))
|
||||
: LegacyPlatformObject(Bindings::cached_web_prototype(root.realm(), "HTMLCollection"))
|
||||
, m_root(root)
|
||||
, m_filter(move(filter))
|
||||
{
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<NodeList> LiveNodeList::create(HTML::Window& window, Node& root, Function<bool(Node const&)> filter)
|
||||
JS::NonnullGCPtr<NodeList> LiveNodeList::create(JS::Realm& realm, Node& root, Function<bool(Node const&)> filter)
|
||||
{
|
||||
return *window.heap().allocate<LiveNodeList>(window.realm(), window, root, move(filter));
|
||||
return *realm.heap().allocate<LiveNodeList>(realm, realm, root, move(filter));
|
||||
}
|
||||
|
||||
LiveNodeList::LiveNodeList(HTML::Window& window, Node& root, Function<bool(Node const&)> filter)
|
||||
: NodeList(window)
|
||||
LiveNodeList::LiveNodeList(JS::Realm& realm, Node& root, Function<bool(Node const&)> filter)
|
||||
: NodeList(realm)
|
||||
, m_root(root)
|
||||
, m_filter(move(filter))
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ class LiveNodeList final : public NodeList {
|
|||
WEB_PLATFORM_OBJECT(LiveNodeList, NodeList);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<NodeList> create(HTML::Window&, Node& root, Function<bool(Node const&)> filter);
|
||||
static JS::NonnullGCPtr<NodeList> create(JS::Realm&, Node& root, Function<bool(Node const&)> filter);
|
||||
virtual ~LiveNodeList() override;
|
||||
|
||||
virtual u32 length() const override;
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
private:
|
||||
LiveNodeList(HTML::Window&, Node& root, Function<bool(Node const&)> filter);
|
||||
LiveNodeList(JS::Realm&, Node& root, Function<bool(Node const&)> filter);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
|
|
@ -4,29 +4,29 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/DOM/MutationObserver.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<MutationObserver> MutationObserver::create_with_global_object(HTML::Window& window, JS::GCPtr<WebIDL::CallbackType> callback)
|
||||
JS::NonnullGCPtr<MutationObserver> MutationObserver::construct_impl(JS::Realm& realm, JS::GCPtr<WebIDL::CallbackType> callback)
|
||||
{
|
||||
return *window.heap().allocate<MutationObserver>(window.realm(), window, callback);
|
||||
return *realm.heap().allocate<MutationObserver>(realm, realm, callback);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-mutationobserver-mutationobserver
|
||||
MutationObserver::MutationObserver(HTML::Window& window, JS::GCPtr<WebIDL::CallbackType> callback)
|
||||
: PlatformObject(window.realm())
|
||||
MutationObserver::MutationObserver(JS::Realm& realm, JS::GCPtr<WebIDL::CallbackType> callback)
|
||||
: PlatformObject(realm)
|
||||
, m_callback(move(callback))
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("MutationObserver"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "MutationObserver"));
|
||||
|
||||
// 1. Set this’s callback to callback.
|
||||
|
||||
// 2. Append this to this’s relevant agent’s mutation observers.
|
||||
auto* agent_custom_data = verify_cast<Bindings::WebEngineCustomData>(window.vm().custom_data());
|
||||
auto* agent_custom_data = verify_cast<Bindings::WebEngineCustomData>(realm.vm().custom_data());
|
||||
agent_custom_data->mutation_observers.append(*this);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class MutationObserver final : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(MutationObserver, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<MutationObserver> create_with_global_object(HTML::Window&, JS::GCPtr<WebIDL::CallbackType>);
|
||||
static JS::NonnullGCPtr<MutationObserver> construct_impl(JS::Realm&, JS::GCPtr<WebIDL::CallbackType>);
|
||||
virtual ~MutationObserver() override;
|
||||
|
||||
WebIDL::ExceptionOr<void> observe(Node& target, MutationObserverInit options = {});
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
MutationObserver(HTML::Window&, JS::GCPtr<WebIDL::CallbackType>);
|
||||
MutationObserver(JS::Realm&, JS::GCPtr<WebIDL::CallbackType>);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/MutationRecord.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/DOM/NodeList.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<MutationRecord> MutationRecord::create(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value)
|
||||
JS::NonnullGCPtr<MutationRecord> MutationRecord::create(JS::Realm& realm, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value)
|
||||
{
|
||||
return *window.heap().allocate<MutationRecord>(window.realm(), window, type, target, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, old_value);
|
||||
return *realm.heap().allocate<MutationRecord>(realm, realm, type, target, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, old_value);
|
||||
}
|
||||
|
||||
MutationRecord::MutationRecord(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value)
|
||||
: PlatformObject(window.realm())
|
||||
MutationRecord::MutationRecord(JS::Realm& realm, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value)
|
||||
: PlatformObject(realm)
|
||||
, m_type(type)
|
||||
, m_target(JS::make_handle(target))
|
||||
, m_added_nodes(added_nodes)
|
||||
|
@ -29,7 +29,7 @@ MutationRecord::MutationRecord(HTML::Window& window, FlyString const& type, Node
|
|||
, m_attribute_namespace(attribute_namespace)
|
||||
, m_old_value(old_value)
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("MutationRecord"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "MutationRecord"));
|
||||
}
|
||||
|
||||
MutationRecord::~MutationRecord() = default;
|
||||
|
|
|
@ -15,7 +15,7 @@ class MutationRecord : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(MutationRecord, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<MutationRecord> create(HTML::Window&, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value);
|
||||
static JS::NonnullGCPtr<MutationRecord> create(JS::Realm&, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value);
|
||||
|
||||
virtual ~MutationRecord() override;
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
String const& old_value() const { return m_old_value; }
|
||||
|
||||
private:
|
||||
MutationRecord(HTML::Window& window, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value);
|
||||
MutationRecord(JS::Realm& realm, FlyString const& type, Node& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, String const& attribute_name, String const& attribute_namespace, String const& old_value);
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
FlyString m_type;
|
||||
|
|
|
@ -19,7 +19,7 @@ JS::NonnullGCPtr<NamedNodeMap> NamedNodeMap::create(Element& element)
|
|||
}
|
||||
|
||||
NamedNodeMap::NamedNodeMap(Element& element)
|
||||
: Bindings::LegacyPlatformObject(element.window().cached_web_prototype("NamedNodeMap"))
|
||||
: Bindings::LegacyPlatformObject(Bindings::cached_web_prototype(element.realm(), "NamedNodeMap"))
|
||||
, m_element(element)
|
||||
{
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ WebIDL::ExceptionOr<Attr const*> NamedNodeMap::remove_named_item(StringView qual
|
|||
|
||||
// 2. If attr is null, then throw a "NotFoundError" DOMException.
|
||||
if (!attribute)
|
||||
return WebIDL::NotFoundError::create(global_object(), String::formatted("Attribute with name '{}' not found", qualified_name));
|
||||
return WebIDL::NotFoundError::create(realm(), String::formatted("Attribute with name '{}' not found", qualified_name));
|
||||
|
||||
// 3. Return attr.
|
||||
return nullptr;
|
||||
|
@ -137,7 +137,7 @@ WebIDL::ExceptionOr<Attr const*> NamedNodeMap::set_attribute(Attr& attribute)
|
|||
{
|
||||
// 1. If attr’s element is neither null nor element, throw an "InUseAttributeError" DOMException.
|
||||
if ((attribute.owner_element() != nullptr) && (attribute.owner_element() != &associated_element()))
|
||||
return WebIDL::InUseAttributeError::create(global_object(), "Attribute must not already be in use"sv);
|
||||
return WebIDL::InUseAttributeError::create(realm(), "Attribute must not already be in use"sv);
|
||||
|
||||
// 2. Let oldAttr be the result of getting an attribute given attr’s namespace, attr’s local name, and element.
|
||||
// FIXME: When getNamedItemNS is implemented, use that instead.
|
||||
|
|
|
@ -315,24 +315,24 @@ WebIDL::ExceptionOr<void> Node::ensure_pre_insertion_validity(JS::NonnullGCPtr<N
|
|||
{
|
||||
// 1. If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
||||
if (!is<Document>(this) && !is<DocumentFragment>(this) && !is<Element>(this))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Can only insert into a document, document fragment or element");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Can only insert into a document, document fragment or element");
|
||||
|
||||
// 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException.
|
||||
if (node->is_host_including_inclusive_ancestor_of(*this))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "New node is an ancestor of this node");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "New node is an ancestor of this node");
|
||||
|
||||
// 3. If child is non-null and its parent is not parent, then throw a "NotFoundError" DOMException.
|
||||
if (child && child->parent() != this)
|
||||
return WebIDL::NotFoundError::create(global_object(), "This node is not the parent of the given child");
|
||||
return WebIDL::NotFoundError::create(realm(), "This node is not the parent of the given child");
|
||||
|
||||
// FIXME: All the following "Invalid node type for insertion" messages could be more descriptive.
|
||||
// 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
|
||||
if (!is<DocumentFragment>(*node) && !is<DocumentType>(*node) && !is<Element>(*node) && !is<Text>(*node) && !is<Comment>(*node) && !is<ProcessingInstruction>(*node))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
|
||||
// 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException.
|
||||
if ((is<Text>(*node) && is<Document>(this)) || (is<DocumentType>(*node) && !is<Document>(this)))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
|
||||
// 6. If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "HierarchyRequestError" DOMException.
|
||||
if (is<Document>(this)) {
|
||||
|
@ -343,18 +343,18 @@ WebIDL::ExceptionOr<void> Node::ensure_pre_insertion_validity(JS::NonnullGCPtr<N
|
|||
auto node_element_child_count = verify_cast<DocumentFragment>(*node).child_element_count();
|
||||
if ((node_element_child_count > 1 || node->has_child_of_type<Text>())
|
||||
|| (node_element_child_count == 1 && (has_child_of_type<Element>() || is<DocumentType>(child.ptr()) || (child && child->has_following_node_of_type_in_tree_order<DocumentType>())))) {
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
}
|
||||
} else if (is<Element>(*node)) {
|
||||
// Element
|
||||
// If parent has an element child, child is a doctype, or child is non-null and a doctype is following child.
|
||||
if (has_child_of_type<Element>() || is<DocumentType>(child.ptr()) || (child && child->has_following_node_of_type_in_tree_order<DocumentType>()))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
} else if (is<DocumentType>(*node)) {
|
||||
// DocumentType
|
||||
// parent has a doctype child, child is non-null and an element is preceding child, or child is null and parent has an element child.
|
||||
if (has_child_of_type<DocumentType>() || (child && child->has_preceding_node_of_type_in_tree_order<Element>()) || (!child && has_child_of_type<Element>()))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@ void Node::insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, boo
|
|||
|
||||
// 2. Queue a tree mutation record for node with « », nodes, null, and null.
|
||||
// NOTE: This step intentionally does not pay attention to the suppress observers flag.
|
||||
node->queue_tree_mutation_record(StaticNodeList::create(window(), {}), StaticNodeList::create(window(), nodes), nullptr, nullptr);
|
||||
node->queue_tree_mutation_record(StaticNodeList::create(realm(), {}), StaticNodeList::create(realm(), nodes), nullptr, nullptr);
|
||||
}
|
||||
|
||||
// 5. If child is non-null, then:
|
||||
|
@ -447,7 +447,7 @@ void Node::insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, boo
|
|||
|
||||
// 8. If suppress observers flag is unset, then queue a tree mutation record for parent with nodes, « », previousSibling, and child.
|
||||
if (!suppress_observers)
|
||||
queue_tree_mutation_record(StaticNodeList::create(window(), move(nodes)), StaticNodeList::create(window(), {}), previous_sibling.ptr(), child.ptr());
|
||||
queue_tree_mutation_record(StaticNodeList::create(realm(), move(nodes)), StaticNodeList::create(realm(), {}), previous_sibling.ptr(), child.ptr());
|
||||
|
||||
// 9. Run the children changed steps for parent.
|
||||
children_changed();
|
||||
|
@ -487,7 +487,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::pre_remove(JS::NonnullGCPtr<No
|
|||
{
|
||||
// 1. If child’s parent is not parent, then throw a "NotFoundError" DOMException.
|
||||
if (child->parent() != this)
|
||||
return WebIDL::NotFoundError::create(global_object(), "Child does not belong to this node");
|
||||
return WebIDL::NotFoundError::create(realm(), "Child does not belong to this node");
|
||||
|
||||
// 2. Remove child.
|
||||
child->remove();
|
||||
|
@ -598,7 +598,7 @@ void Node::remove(bool suppress_observers)
|
|||
if (!suppress_observers) {
|
||||
Vector<JS::Handle<Node>> removed_nodes;
|
||||
removed_nodes.append(JS::make_handle(*this));
|
||||
parent->queue_tree_mutation_record(StaticNodeList::create(window(), {}), StaticNodeList::create(window(), move(removed_nodes)), old_previous_sibling.ptr(), old_next_sibling.ptr());
|
||||
parent->queue_tree_mutation_record(StaticNodeList::create(realm(), {}), StaticNodeList::create(realm(), move(removed_nodes)), old_previous_sibling.ptr(), old_next_sibling.ptr());
|
||||
}
|
||||
|
||||
// 21. Run the children changed steps for parent.
|
||||
|
@ -612,25 +612,25 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::replace_child(JS::NonnullGCPtr
|
|||
{
|
||||
// If parent is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
||||
if (!is<Document>(this) && !is<DocumentFragment>(this) && !is<Element>(this))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Can only insert into a document, document fragment or element");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Can only insert into a document, document fragment or element");
|
||||
|
||||
// 2. If node is a host-including inclusive ancestor of parent, then throw a "HierarchyRequestError" DOMException.
|
||||
if (node->is_host_including_inclusive_ancestor_of(*this))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "New node is an ancestor of this node");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "New node is an ancestor of this node");
|
||||
|
||||
// 3. If child’s parent is not parent, then throw a "NotFoundError" DOMException.
|
||||
if (child->parent() != this)
|
||||
return WebIDL::NotFoundError::create(global_object(), "This node is not the parent of the given child");
|
||||
return WebIDL::NotFoundError::create(realm(), "This node is not the parent of the given child");
|
||||
|
||||
// FIXME: All the following "Invalid node type for insertion" messages could be more descriptive.
|
||||
|
||||
// 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
|
||||
if (!is<DocumentFragment>(*node) && !is<DocumentType>(*node) && !is<Element>(*node) && !is<Text>(*node) && !is<Comment>(*node) && !is<ProcessingInstruction>(*node))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
|
||||
// 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException.
|
||||
if ((is<Text>(*node) && is<Document>(this)) || (is<DocumentType>(*node) && !is<Document>(this)))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
|
||||
// If parent is a document, and any of the statements below, switched on the interface node implements, are true, then throw a "HierarchyRequestError" DOMException.
|
||||
if (is<Document>(this)) {
|
||||
|
@ -641,18 +641,18 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::replace_child(JS::NonnullGCPtr
|
|||
auto node_element_child_count = verify_cast<DocumentFragment>(*node).child_element_count();
|
||||
if ((node_element_child_count > 1 || node->has_child_of_type<Text>())
|
||||
|| (node_element_child_count == 1 && (first_child_of_type<Element>() != child || child->has_following_node_of_type_in_tree_order<DocumentType>()))) {
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
}
|
||||
} else if (is<Element>(*node)) {
|
||||
// Element
|
||||
// parent has an element child that is not child or a doctype is following child.
|
||||
if (first_child_of_type<Element>() != child || child->has_following_node_of_type_in_tree_order<DocumentType>())
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
} else if (is<DocumentType>(*node)) {
|
||||
// DocumentType
|
||||
// parent has a doctype child that is not child, or an element is preceding child.
|
||||
if (first_child_of_type<DocumentType>() != node || child->has_preceding_node_of_type_in_tree_order<Element>())
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Invalid node type for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,7 +690,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::replace_child(JS::NonnullGCPtr
|
|||
insert_before(node, reference_child, true);
|
||||
|
||||
// 14. Queue a tree mutation record for parent with nodes, removedNodes, previousSibling, and referenceChild.
|
||||
queue_tree_mutation_record(StaticNodeList::create(window(), move(nodes)), StaticNodeList::create(window(), move(removed_nodes)), previous_sibling.ptr(), reference_child.ptr());
|
||||
queue_tree_mutation_record(StaticNodeList::create(realm(), move(nodes)), StaticNodeList::create(realm(), move(removed_nodes)), previous_sibling.ptr(), reference_child.ptr());
|
||||
|
||||
// 15. Return child.
|
||||
return child;
|
||||
|
@ -723,7 +723,7 @@ JS::NonnullGCPtr<Node> Node::clone_node(Document* document, bool clone_children)
|
|||
else if (is<Document>(this)) {
|
||||
// Document
|
||||
auto document_ = verify_cast<Document>(this);
|
||||
auto document_copy = Document::create(Bindings::main_thread_internal_window_object(), document_->url());
|
||||
auto document_copy = Document::create(this->realm(), document_->url());
|
||||
|
||||
// Set copy’s encoding, content type, URL, origin, type, and mode to those of node.
|
||||
document_copy->set_encoding(document_->encoding());
|
||||
|
@ -796,7 +796,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> Node::clone_node_binding(bool deep)
|
|||
{
|
||||
// 1. If this is a shadow root, then throw a "NotSupportedError" DOMException.
|
||||
if (is<ShadowRoot>(*this))
|
||||
return WebIDL::NotSupportedError::create(global_object(), "Cannot clone shadow root");
|
||||
return WebIDL::NotSupportedError::create(realm(), "Cannot clone shadow root");
|
||||
|
||||
// 2. Return a clone of this, with the clone children flag set if deep is true.
|
||||
return clone_node(nullptr, deep);
|
||||
|
@ -863,7 +863,7 @@ ParentNode* Node::parent_or_shadow_host()
|
|||
JS::NonnullGCPtr<NodeList> Node::child_nodes()
|
||||
{
|
||||
if (!m_child_nodes) {
|
||||
m_child_nodes = LiveNodeList::create(window(), *this, [this](auto& node) {
|
||||
m_child_nodes = LiveNodeList::create(realm(), *this, [this](auto& node) {
|
||||
return is_parent_of(node);
|
||||
});
|
||||
}
|
||||
|
@ -1143,7 +1143,7 @@ void Node::replace_all(JS::GCPtr<Node> node)
|
|||
|
||||
// 7. If either addedNodes or removedNodes is not empty, then queue a tree mutation record for parent with addedNodes, removedNodes, null, and null.
|
||||
if (!added_nodes.is_empty() || !removed_nodes.is_empty())
|
||||
queue_tree_mutation_record(StaticNodeList::create(window(), move(added_nodes)), StaticNodeList::create(window(), move(removed_nodes)), nullptr, nullptr);
|
||||
queue_tree_mutation_record(StaticNodeList::create(realm(), move(added_nodes)), StaticNodeList::create(realm(), move(removed_nodes)), nullptr, nullptr);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#string-replace-all
|
||||
|
@ -1382,7 +1382,7 @@ void Node::queue_mutation_record(FlyString const& type, String attribute_name, S
|
|||
for (auto& interested_observer : interested_observers) {
|
||||
// 1. Let record be a new MutationRecord object with its type set to type, target set to target, attributeName set to name, attributeNamespace set to namespace, oldValue set to mappedOldValue,
|
||||
// addedNodes set to addedNodes, removedNodes set to removedNodes, previousSibling set to previousSibling, and nextSibling set to nextSibling.
|
||||
auto record = MutationRecord::create(window(), type, *this, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, /* mappedOldValue */ interested_observer.value);
|
||||
auto record = MutationRecord::create(realm(), type, *this, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, /* mappedOldValue */ interested_observer.value);
|
||||
|
||||
// 2. Enqueue record to observer’s record queue.
|
||||
interested_observer.key->enqueue_record({}, move(record));
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace Web::DOM {
|
||||
|
||||
NodeIterator::NodeIterator(Node& root)
|
||||
: PlatformObject(root.window().cached_web_prototype("NodeIterator"))
|
||||
: PlatformObject(Bindings::cached_web_prototype(root.realm(), "NodeIterator"))
|
||||
, m_root(root)
|
||||
, m_reference({ root })
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> NodeIterator::filter(Node& node)
|
|||
{
|
||||
// 1. If traverser’s active flag is set, then throw an "InvalidStateError" DOMException.
|
||||
if (m_active)
|
||||
return throw_completion(WebIDL::InvalidStateError::create(global_object(), "NodeIterator is already active"));
|
||||
return throw_completion(WebIDL::InvalidStateError::create(realm(), "NodeIterator is already active"));
|
||||
|
||||
// 2. Let n be node’s nodeType attribute value − 1.
|
||||
auto n = node.node_type() - 1;
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/DOM/NodeList.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
NodeList::NodeList(HTML::Window& window)
|
||||
: LegacyPlatformObject(window.cached_web_prototype("NodeList"))
|
||||
NodeList::NodeList(JS::Realm& realm)
|
||||
: LegacyPlatformObject(Bindings::cached_web_prototype(realm, "NodeList"))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
protected:
|
||||
explicit NodeList(HTML::Window&);
|
||||
explicit NodeList(JS::Realm&);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ WebIDL::ExceptionOr<JS::GCPtr<Element>> ParentNode::query_selector(StringView se
|
|||
{
|
||||
auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(*this), selector_text);
|
||||
if (!maybe_selectors.has_value())
|
||||
return WebIDL::SyntaxError::create(global_object(), "Failed to parse selector");
|
||||
return WebIDL::SyntaxError::create(realm(), "Failed to parse selector");
|
||||
|
||||
auto selectors = maybe_selectors.value();
|
||||
|
||||
|
@ -45,7 +45,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeList>> ParentNode::query_selector_all(S
|
|||
{
|
||||
auto maybe_selectors = parse_selector(CSS::Parser::ParsingContext(*this), selector_text);
|
||||
if (!maybe_selectors.has_value())
|
||||
return WebIDL::SyntaxError::create(global_object(), "Failed to parse selector");
|
||||
return WebIDL::SyntaxError::create(realm(), "Failed to parse selector");
|
||||
|
||||
auto selectors = maybe_selectors.value();
|
||||
|
||||
|
@ -60,7 +60,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeList>> ParentNode::query_selector_all(S
|
|||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
return StaticNodeList::create(window(), move(elements));
|
||||
return StaticNodeList::create(realm(), move(elements));
|
||||
}
|
||||
|
||||
JS::GCPtr<Element> ParentNode::first_element_child()
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/RefPtr.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentFragment.h>
|
||||
|
@ -31,31 +32,32 @@ JS::NonnullGCPtr<Range> Range::create(HTML::Window& window)
|
|||
|
||||
JS::NonnullGCPtr<Range> Range::create(Document& document)
|
||||
{
|
||||
auto& window_object = document.window();
|
||||
return *window_object.heap().allocate<Range>(window_object.realm(), document);
|
||||
auto& realm = document.realm();
|
||||
return *realm.heap().allocate<Range>(realm, document);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Range> Range::create(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset)
|
||||
{
|
||||
auto& window_object = start_container.document().window();
|
||||
return *window_object.heap().allocate<Range>(window_object.realm(), start_container, start_offset, end_container, end_offset);
|
||||
auto& realm = start_container.realm();
|
||||
return *realm.heap().allocate<Range>(realm, start_container, start_offset, end_container, end_offset);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<Range> Range::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<Range> Range::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
auto& window = verify_cast<HTML::Window>(realm.global_object());
|
||||
return Range::create(window);
|
||||
}
|
||||
|
||||
Range::Range(Document& document)
|
||||
: Range(document, 0, document, 0)
|
||||
{
|
||||
set_prototype(&document.window().cached_web_prototype("Range"));
|
||||
set_prototype(&Bindings::cached_web_prototype(document.realm(), "Range"));
|
||||
}
|
||||
|
||||
Range::Range(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset)
|
||||
: AbstractRange(start_container, start_offset, end_container, end_offset)
|
||||
{
|
||||
set_prototype(&start_container.window().cached_web_prototype("Range"));
|
||||
set_prototype(&Bindings::cached_web_prototype(start_container.realm(), "Range"));
|
||||
live_ranges().set(this);
|
||||
}
|
||||
|
||||
|
@ -137,11 +139,11 @@ WebIDL::ExceptionOr<void> Range::set_start_or_end(Node& node, u32 offset, StartO
|
|||
|
||||
// 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<DocumentType>(node))
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Node cannot be a DocumentType.");
|
||||
|
||||
// 2. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > node.length())
|
||||
return WebIDL::IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
return WebIDL::IndexSizeError::create(realm(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
|
||||
// 3. Let bp be the boundary point (node, offset).
|
||||
|
||||
|
@ -196,7 +198,7 @@ WebIDL::ExceptionOr<void> Range::set_start_before(Node& node)
|
|||
|
||||
// 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (!parent)
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Given node has no parent.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Given node has no parent.");
|
||||
|
||||
// 3. Set the start of this to boundary point (parent, node’s index).
|
||||
return set_start_or_end(*parent, node.index(), StartOrEnd::Start);
|
||||
|
@ -210,7 +212,7 @@ WebIDL::ExceptionOr<void> Range::set_start_after(Node& node)
|
|||
|
||||
// 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (!parent)
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Given node has no parent.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Given node has no parent.");
|
||||
|
||||
// 3. Set the start of this to boundary point (parent, node’s index plus 1).
|
||||
return set_start_or_end(*parent, node.index() + 1, StartOrEnd::Start);
|
||||
|
@ -224,7 +226,7 @@ WebIDL::ExceptionOr<void> Range::set_end_before(Node& node)
|
|||
|
||||
// 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (!parent)
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Given node has no parent.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Given node has no parent.");
|
||||
|
||||
// 3. Set the end of this to boundary point (parent, node’s index).
|
||||
return set_start_or_end(*parent, node.index(), StartOrEnd::End);
|
||||
|
@ -238,7 +240,7 @@ WebIDL::ExceptionOr<void> Range::set_end_after(Node& node)
|
|||
|
||||
// 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (!parent)
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Given node has no parent.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Given node has no parent.");
|
||||
|
||||
// 3. Set the end of this to boundary point (parent, node’s index plus 1).
|
||||
return set_start_or_end(*parent, node.index() + 1, StartOrEnd::End);
|
||||
|
@ -254,11 +256,11 @@ WebIDL::ExceptionOr<i16> Range::compare_boundary_points(u16 how, Range const& so
|
|||
// - END_TO_START,
|
||||
// then throw a "NotSupportedError" DOMException.
|
||||
if (how != HowToCompareBoundaryPoints::START_TO_START && how != HowToCompareBoundaryPoints::START_TO_END && how != HowToCompareBoundaryPoints::END_TO_END && how != HowToCompareBoundaryPoints::END_TO_START)
|
||||
return WebIDL::NotSupportedError::create(global_object(), String::formatted("Expected 'how' to be one of START_TO_START (0), START_TO_END (1), END_TO_END (2) or END_TO_START (3), got {}", how));
|
||||
return WebIDL::NotSupportedError::create(realm(), String::formatted("Expected 'how' to be one of START_TO_START (0), START_TO_END (1), END_TO_END (2) or END_TO_START (3), got {}", how));
|
||||
|
||||
// 2. If this’s root is not the same as sourceRange’s root, then throw a "WrongDocumentError" DOMException.
|
||||
if (&root() != &source_range.root())
|
||||
return WebIDL::WrongDocumentError::create(global_object(), "This range is not in the same tree as the source range.");
|
||||
return WebIDL::WrongDocumentError::create(realm(), "This range is not in the same tree as the source range.");
|
||||
|
||||
JS::GCPtr<Node> this_point_node;
|
||||
u32 this_point_offset = 0;
|
||||
|
@ -339,7 +341,7 @@ WebIDL::ExceptionOr<void> Range::select(Node& node)
|
|||
|
||||
// 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (!parent)
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Given node has no parent.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Given node has no parent.");
|
||||
|
||||
// 3. Let index be node’s index.
|
||||
auto index = node.index();
|
||||
|
@ -381,7 +383,7 @@ WebIDL::ExceptionOr<void> Range::select_node_contents(Node const& node)
|
|||
{
|
||||
// 1. If node is a doctype, throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<DocumentType>(node))
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Node cannot be a DocumentType.");
|
||||
|
||||
// 2. Let length be the length of node.
|
||||
auto length = node.length();
|
||||
|
@ -474,11 +476,11 @@ WebIDL::ExceptionOr<bool> Range::is_point_in_range(Node const& node, u32 offset)
|
|||
|
||||
// 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<DocumentType>(node))
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Node cannot be a DocumentType.");
|
||||
|
||||
// 3. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > node.length())
|
||||
return WebIDL::IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
return WebIDL::IndexSizeError::create(realm(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
|
||||
// 4. If (node, offset) is before start or after end, return false.
|
||||
auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset);
|
||||
|
@ -495,15 +497,15 @@ WebIDL::ExceptionOr<i16> Range::compare_point(Node const& node, u32 offset) cons
|
|||
{
|
||||
// 1. If node’s root is different from this’s root, then throw a "WrongDocumentError" DOMException.
|
||||
if (&node.root() != &root())
|
||||
return WebIDL::WrongDocumentError::create(global_object(), "Given node is not in the same document as the range.");
|
||||
return WebIDL::WrongDocumentError::create(realm(), "Given node is not in the same document as the range.");
|
||||
|
||||
// 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<DocumentType>(node))
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Node cannot be a DocumentType.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Node cannot be a DocumentType.");
|
||||
|
||||
// 3. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > node.length())
|
||||
return WebIDL::IndexSizeError::create(global_object(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
return WebIDL::IndexSizeError::create(realm(), String::formatted("Node does not contain a child at offset {}", offset));
|
||||
|
||||
// 4. If (node, offset) is before start, return −1.
|
||||
auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset);
|
||||
|
@ -636,7 +638,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> Range::extract()
|
|||
// 12. If any member of contained children is a doctype, then throw a "HierarchyRequestError" DOMException.
|
||||
for (auto const& child : contained_children) {
|
||||
if (is<DocumentType>(*child))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Contained child is a DocumentType");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Contained child is a DocumentType");
|
||||
}
|
||||
|
||||
JS::GCPtr<Node> new_node;
|
||||
|
@ -783,7 +785,7 @@ WebIDL::ExceptionOr<void> Range::insert(JS::NonnullGCPtr<Node> node)
|
|||
if ((is<ProcessingInstruction>(*m_start_container) || is<Comment>(*m_start_container))
|
||||
|| (is<Text>(*m_start_container) && !m_start_container->parent_node())
|
||||
|| m_start_container.ptr() == node.ptr()) {
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Range has inappropriate start node for insertion");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Range has inappropriate start node for insertion");
|
||||
}
|
||||
|
||||
// 2. Let referenceNode be null.
|
||||
|
@ -854,11 +856,11 @@ WebIDL::ExceptionOr<void> Range::surround_contents(JS::NonnullGCPtr<Node> new_pa
|
|||
if (is<Text>(*end_non_text_node))
|
||||
end_non_text_node = end_non_text_node->parent_node();
|
||||
if (start_non_text_node != end_non_text_node)
|
||||
return WebIDL::InvalidStateError::create(global_object(), "Non-Text node is partially contained in range.");
|
||||
return WebIDL::InvalidStateError::create(realm(), "Non-Text node is partially contained in range.");
|
||||
|
||||
// 2. If newParent is a Document, DocumentType, or DocumentFragment node, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<Document>(*new_parent) || is<DocumentType>(*new_parent) || is<DocumentFragment>(*new_parent))
|
||||
return WebIDL::InvalidNodeTypeError::create(global_object(), "Invalid parent node type");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm(), "Invalid parent node type");
|
||||
|
||||
// 3. Let fragment be the result of extracting this.
|
||||
auto fragment = TRY(extract());
|
||||
|
@ -962,7 +964,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> Range::clone_the_content
|
|||
// 12. If any member of contained children is a doctype, then throw a "HierarchyRequestError" DOMException.
|
||||
for (auto const& child : contained_children) {
|
||||
if (is<DocumentType>(*child))
|
||||
return WebIDL::HierarchyRequestError::create(global_object(), "Contained child is a DocumentType");
|
||||
return WebIDL::HierarchyRequestError::create(realm(), "Contained child is a DocumentType");
|
||||
}
|
||||
|
||||
// 13. If first partially contained child is a CharacterData node, then:
|
||||
|
|
|
@ -19,10 +19,8 @@ public:
|
|||
static JS::NonnullGCPtr<Range> create(Document&);
|
||||
static JS::NonnullGCPtr<Range> create(HTML::Window&);
|
||||
static JS::NonnullGCPtr<Range> create(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset);
|
||||
static JS::NonnullGCPtr<Range> create_with_global_object(HTML::Window&);
|
||||
static JS::NonnullGCPtr<Range> construct_impl(JS::Realm&);
|
||||
|
||||
explicit Range(Document&);
|
||||
Range(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset);
|
||||
virtual ~Range() override;
|
||||
|
||||
// FIXME: There are a ton of methods missing here.
|
||||
|
@ -76,6 +74,9 @@ public:
|
|||
static HashTable<Range*>& live_ranges();
|
||||
|
||||
private:
|
||||
explicit Range(Document&);
|
||||
Range(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset);
|
||||
|
||||
Node& root();
|
||||
Node const& root() const;
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibWeb/DOM/StaticNodeList.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
JS::NonnullGCPtr<NodeList> StaticNodeList::create(HTML::Window& window, Vector<JS::Handle<Node>> static_nodes)
|
||||
JS::NonnullGCPtr<NodeList> StaticNodeList::create(JS::Realm& realm, Vector<JS::Handle<Node>> static_nodes)
|
||||
{
|
||||
return *window.heap().allocate<StaticNodeList>(window.realm(), window, move(static_nodes));
|
||||
return *realm.heap().allocate<StaticNodeList>(realm, realm, move(static_nodes));
|
||||
}
|
||||
|
||||
StaticNodeList::StaticNodeList(HTML::Window& window, Vector<JS::Handle<Node>> static_nodes)
|
||||
: NodeList(window)
|
||||
StaticNodeList::StaticNodeList(JS::Realm& realm, Vector<JS::Handle<Node>> static_nodes)
|
||||
: NodeList(realm)
|
||||
{
|
||||
for (auto& node : static_nodes)
|
||||
m_static_nodes.append(*node);
|
||||
|
|
|
@ -16,7 +16,7 @@ class StaticNodeList final : public NodeList {
|
|||
WEB_PLATFORM_OBJECT(StaticNodeList, NodeList);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<NodeList> create(HTML::Window&, Vector<JS::Handle<Node>>);
|
||||
static JS::NonnullGCPtr<NodeList> create(JS::Realm&, Vector<JS::Handle<Node>>);
|
||||
|
||||
virtual ~StaticNodeList() override;
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
private:
|
||||
StaticNodeList(HTML::Window&, Vector<JS::Handle<Node>>);
|
||||
StaticNodeList(JS::Realm&, Vector<JS::Handle<Node>>);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Attr.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentType.h>
|
||||
#include <LibWeb/DOM/StaticRange.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
@ -17,23 +17,23 @@ namespace Web::DOM {
|
|||
StaticRange::StaticRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset)
|
||||
: AbstractRange(start_container, start_offset, end_container, end_offset)
|
||||
{
|
||||
set_prototype(&start_container.document().window().cached_web_prototype("StaticRange"));
|
||||
set_prototype(&Bindings::cached_web_prototype(start_container.realm(), "StaticRange"));
|
||||
}
|
||||
|
||||
StaticRange::~StaticRange() = default;
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-staticrange-staticrange
|
||||
WebIDL::ExceptionOr<StaticRange*> StaticRange::create_with_global_object(HTML::Window& window, StaticRangeInit& init)
|
||||
WebIDL::ExceptionOr<StaticRange*> StaticRange::construct_impl(JS::Realm& realm, StaticRangeInit& init)
|
||||
{
|
||||
// 1. If init["startContainer"] or init["endContainer"] is a DocumentType or Attr node, then throw an "InvalidNodeTypeError" DOMException.
|
||||
if (is<DocumentType>(*init.start_container) || is<Attr>(*init.start_container))
|
||||
return WebIDL::InvalidNodeTypeError::create(window, "startContainer cannot be a DocumentType or Attribute node.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm, "startContainer cannot be a DocumentType or Attribute node.");
|
||||
|
||||
if (is<DocumentType>(*init.end_container) || is<Attr>(*init.end_container))
|
||||
return WebIDL::InvalidNodeTypeError::create(window, "endContainer cannot be a DocumentType or Attribute node.");
|
||||
return WebIDL::InvalidNodeTypeError::create(realm, "endContainer cannot be a DocumentType or Attribute node.");
|
||||
|
||||
// 2. Set this’s start to (init["startContainer"], init["startOffset"]) and end to (init["endContainer"], init["endOffset"]).
|
||||
return window.heap().allocate<StaticRange>(window.realm(), *init.start_container, init.start_offset, *init.end_container, init.end_offset);
|
||||
return realm.heap().allocate<StaticRange>(realm, *init.start_container, init.start_offset, *init.end_container, init.end_offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class StaticRange final : public AbstractRange {
|
|||
WEB_PLATFORM_OBJECT(StaticRange, JS::Object);
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<StaticRange*> create_with_global_object(HTML::Window&, StaticRangeInit& init);
|
||||
static WebIDL::ExceptionOr<StaticRange*> construct_impl(JS::Realm&, StaticRangeInit& init);
|
||||
|
||||
StaticRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset);
|
||||
virtual ~StaticRange() override;
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Layout/TextNode.h>
|
||||
|
||||
|
@ -15,13 +17,13 @@ namespace Web::DOM {
|
|||
Text::Text(Document& document, String const& data)
|
||||
: CharacterData(document, NodeType::TEXT_NODE, data)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("Text"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm(), "Text"));
|
||||
}
|
||||
|
||||
Text::Text(Document& document, NodeType type, String const& data)
|
||||
: CharacterData(document, type, data)
|
||||
{
|
||||
set_prototype(&window().cached_web_prototype("Text"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm(), "Text"));
|
||||
}
|
||||
|
||||
void Text::visit_edges(Cell::Visitor& visitor)
|
||||
|
@ -31,9 +33,11 @@ void Text::visit_edges(Cell::Visitor& visitor)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-text-text
|
||||
JS::NonnullGCPtr<Text> Text::create_with_global_object(HTML::Window& window, String const& data)
|
||||
JS::NonnullGCPtr<Text> Text::construct_impl(JS::Realm& realm, String const& data)
|
||||
{
|
||||
return *window.heap().allocate<Text>(window.realm(), window.associated_document(), data);
|
||||
// The new Text(data) constructor steps are to set this’s data to data and this’s node document to current global object’s associated Document.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::current_global_object());
|
||||
return *realm.heap().allocate<Text>(realm, window.associated_document(), data);
|
||||
}
|
||||
|
||||
void Text::set_owner_input_element(Badge<HTML::HTMLInputElement>, HTML::HTMLInputElement& input_element)
|
||||
|
@ -50,7 +54,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> Text::split_text(size_t offset)
|
|||
|
||||
// 2. If offset is greater than length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > length)
|
||||
return WebIDL::IndexSizeError::create(global_object(), "Split offset is greater than length");
|
||||
return WebIDL::IndexSizeError::create(realm(), "Split offset is greater than length");
|
||||
|
||||
// 3. Let count be length minus offset.
|
||||
auto count = length - offset;
|
||||
|
|
|
@ -18,7 +18,7 @@ class Text : public CharacterData {
|
|||
public:
|
||||
virtual ~Text() override = default;
|
||||
|
||||
static JS::NonnullGCPtr<Text> create_with_global_object(HTML::Window& window, String const& data);
|
||||
static JS::NonnullGCPtr<Text> construct_impl(JS::Realm& window, String const& data);
|
||||
|
||||
// ^Node
|
||||
virtual FlyString node_name() const override { return "#text"; }
|
||||
|
@ -32,7 +32,7 @@ public:
|
|||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> split_text(size_t offset);
|
||||
|
||||
protected:
|
||||
explicit Text(Document&, String const&);
|
||||
Text(Document&, String const&);
|
||||
Text(Document&, NodeType, String const&);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
namespace Web::DOM {
|
||||
|
||||
TreeWalker::TreeWalker(Node& root)
|
||||
: PlatformObject(root.window().cached_web_prototype("TreeWalker"))
|
||||
: PlatformObject(Bindings::cached_web_prototype(root.realm(), "TreeWalker"))
|
||||
, m_root(root)
|
||||
, m_current(root)
|
||||
{
|
||||
|
@ -231,7 +231,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> TreeWalker::filter(Node& node)
|
|||
{
|
||||
// 1. If traverser’s active flag is set, then throw an "InvalidStateError" DOMException.
|
||||
if (m_active)
|
||||
return throw_completion(WebIDL::InvalidStateError::create(global_object(), "NodeIterator is already active"));
|
||||
return throw_completion(WebIDL::InvalidStateError::create(realm(), "NodeIterator is already active"));
|
||||
|
||||
// 2. Let n be node’s nodeType attribute value − 1.
|
||||
auto n = node.node_type() - 1;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibWeb/DOM/DocumentFragment.h>
|
||||
#include <LibWeb/DOMParsing/InnerHTML.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
|
|
|
@ -20,15 +20,15 @@
|
|||
|
||||
namespace Web::DOMParsing {
|
||||
|
||||
JS::NonnullGCPtr<XMLSerializer> XMLSerializer::create_with_global_object(HTML::Window& window)
|
||||
JS::NonnullGCPtr<XMLSerializer> XMLSerializer::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
return *window.heap().allocate<XMLSerializer>(window.realm(), window);
|
||||
return *realm.heap().allocate<XMLSerializer>(realm, realm);
|
||||
}
|
||||
|
||||
XMLSerializer::XMLSerializer(HTML::Window& window)
|
||||
: PlatformObject(window.realm())
|
||||
XMLSerializer::XMLSerializer(JS::Realm& realm)
|
||||
: PlatformObject(realm)
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("XMLSerializer"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "XMLSerializer"));
|
||||
}
|
||||
|
||||
XMLSerializer::~XMLSerializer() = default;
|
||||
|
@ -308,7 +308,7 @@ struct LocalNameSetEntry {
|
|||
// https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-of-the-attributes
|
||||
static WebIDL::ExceptionOr<String> serialize_element_attributes(DOM::Element const& element, HashMap<FlyString, Vector<String>>& namespace_prefix_map, u64& prefix_index, HashMap<String, String> const& local_prefixes_map, bool ignore_namespace_definition_attribute, RequireWellFormed require_well_formed)
|
||||
{
|
||||
auto& global_object = element.global_object();
|
||||
auto& realm = element.realm();
|
||||
|
||||
// 1. Let result be the empty string.
|
||||
StringBuilder result;
|
||||
|
@ -331,7 +331,7 @@ static WebIDL::ExceptionOr<String> serialize_element_attributes(DOM::Element con
|
|||
});
|
||||
|
||||
if (local_name_set_iterator != local_name_set.end())
|
||||
return WebIDL::InvalidStateError::create(global_object, "Element contains two attributes with identical namespaces and local names");
|
||||
return WebIDL::InvalidStateError::create(realm, "Element contains two attributes with identical namespaces and local names");
|
||||
}
|
||||
|
||||
// 2. Create a new tuple consisting of attr's namespaceURI attribute and localName attribute, and add it to the localname set.
|
||||
|
@ -384,12 +384,12 @@ static WebIDL::ExceptionOr<String> serialize_element_attributes(DOM::Element con
|
|||
// 2. If the require well-formed flag is set (its value is true), and the value of attr's value attribute matches the XMLNS namespace,
|
||||
// then throw an exception; the serialization of this attribute would produce invalid XML because the XMLNS namespace is reserved and cannot be applied as an element's namespace via XML parsing.
|
||||
if (require_well_formed == RequireWellFormed::Yes && attribute->value() == Namespace::XMLNS)
|
||||
return WebIDL::InvalidStateError::create(global_object, "The XMLNS namespace cannot be used as an element's namespace");
|
||||
return WebIDL::InvalidStateError::create(realm, "The XMLNS namespace cannot be used as an element's namespace");
|
||||
|
||||
// 3. If the require well-formed flag is set (its value is true), and the value of attr's value attribute is the empty string,
|
||||
// then throw an exception; namespace prefix declarations cannot be used to undeclare a namespace (use a default namespace declaration instead).
|
||||
if (require_well_formed == RequireWellFormed::Yes && attribute->value().is_empty())
|
||||
return WebIDL::InvalidStateError::create(global_object, "Attribute's value is empty");
|
||||
return WebIDL::InvalidStateError::create(realm, "Attribute's value is empty");
|
||||
|
||||
// 4. [If] the attr's prefix matches the string "xmlns", then let candidate prefix be the string "xmlns".
|
||||
if (attribute->prefix() == "xmlns"sv)
|
||||
|
@ -432,12 +432,12 @@ static WebIDL::ExceptionOr<String> serialize_element_attributes(DOM::Element con
|
|||
// or does not match the XML Name production or equals "xmlns" and attribute namespace is null, then throw an exception; the serialization of this attr would not be a well-formed attribute.
|
||||
if (require_well_formed == RequireWellFormed::Yes) {
|
||||
if (attribute->local_name().view().contains(':'))
|
||||
return WebIDL::InvalidStateError::create(global_object, "Attribute's local name contains a colon");
|
||||
return WebIDL::InvalidStateError::create(realm, "Attribute's local name contains a colon");
|
||||
|
||||
// FIXME: Check attribute's local name against the XML Name production.
|
||||
|
||||
if (attribute->local_name() == "xmlns"sv && attribute_namespace.is_null())
|
||||
return WebIDL::InvalidStateError::create(global_object, "Attribute's local name is 'xmlns' and the attribute has no namespace");
|
||||
return WebIDL::InvalidStateError::create(realm, "Attribute's local name is 'xmlns' and the attribute has no namespace");
|
||||
}
|
||||
|
||||
// 9. Append the following strings to result, in the order listed:
|
||||
|
@ -461,13 +461,13 @@ static WebIDL::ExceptionOr<String> serialize_element_attributes(DOM::Element con
|
|||
// https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node
|
||||
static WebIDL::ExceptionOr<String> serialize_element(DOM::Element const& element, Optional<FlyString>& namespace_, HashMap<FlyString, Vector<String>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed)
|
||||
{
|
||||
auto& global_object = element.global_object();
|
||||
auto& realm = element.realm();
|
||||
|
||||
// 1. If the require well-formed flag is set (its value is true), and this node's localName attribute contains the character ":" (U+003A COLON) or does not match the XML Name production,
|
||||
// then throw an exception; the serialization of this node would not be a well-formed element.
|
||||
if (require_well_formed == RequireWellFormed::Yes) {
|
||||
if (element.local_name().view().contains(':'))
|
||||
return WebIDL::InvalidStateError::create(global_object, "Element's local name contains a colon");
|
||||
return WebIDL::InvalidStateError::create(realm, "Element's local name contains a colon");
|
||||
|
||||
// FIXME: Check element's local name against the XML Char production.
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ static WebIDL::ExceptionOr<String> serialize_element(DOM::Element const& element
|
|||
if (prefix == "xmlns"sv) {
|
||||
// 1. If the require well-formed flag is set, then throw an error. An Element with prefix "xmlns" will not legally round-trip in a conforming XML parser.
|
||||
if (require_well_formed == RequireWellFormed::Yes)
|
||||
return WebIDL::InvalidStateError::create(global_object, "Elements prefix is 'xmlns'");
|
||||
return WebIDL::InvalidStateError::create(realm, "Elements prefix is 'xmlns'");
|
||||
|
||||
// 2. Let candidate prefix be the value of prefix.
|
||||
candidate_prefix = prefix;
|
||||
|
@ -706,7 +706,7 @@ static WebIDL::ExceptionOr<String> serialize_document(DOM::Document const& docum
|
|||
// If the require well-formed flag is set (its value is true), and this node has no documentElement (the documentElement attribute's value is null),
|
||||
// then throw an exception; the serialization of this node would not be a well-formed document.
|
||||
if (require_well_formed == RequireWellFormed::Yes && !document.document_element())
|
||||
return WebIDL::InvalidStateError::create(document.global_object(), "Document has no document element");
|
||||
return WebIDL::InvalidStateError::create(document.realm(), "Document has no document element");
|
||||
|
||||
// Otherwise, run the following steps:
|
||||
// 1. Let serialized document be an empty string.
|
||||
|
@ -730,10 +730,10 @@ static WebIDL::ExceptionOr<String> serialize_comment(DOM::Comment const& comment
|
|||
// FIXME: Check comment's data against the XML Char production.
|
||||
|
||||
if (comment.data().contains("--"sv))
|
||||
return WebIDL::InvalidStateError::create(comment.global_object(), "Comment data contains two adjacent hyphens");
|
||||
return WebIDL::InvalidStateError::create(comment.realm(), "Comment data contains two adjacent hyphens");
|
||||
|
||||
if (comment.data().ends_with('-'))
|
||||
return WebIDL::InvalidStateError::create(comment.global_object(), "Comment data ends with a hyphen");
|
||||
return WebIDL::InvalidStateError::create(comment.realm(), "Comment data ends with a hyphen");
|
||||
}
|
||||
|
||||
// Otherwise, return the concatenation of "<!--", node's data, and "-->".
|
||||
|
@ -788,7 +788,7 @@ static WebIDL::ExceptionOr<String> serialize_document_type(DOM::DocumentType con
|
|||
// both a """ (U+0022 QUOTATION MARK) and a "'" (U+0027 APOSTROPHE), then throw an exception; the serialization of this node would not be a well-formed document type declaration.
|
||||
// FIXME: Check systemId against the XML Char production.
|
||||
if (document_type.system_id().contains('"') && document_type.system_id().contains('\''))
|
||||
return WebIDL::InvalidStateError::create(document_type.global_object(), "Document type system ID contains both a quotation mark and an apostrophe");
|
||||
return WebIDL::InvalidStateError::create(document_type.realm(), "Document type system ID contains both a quotation mark and an apostrophe");
|
||||
}
|
||||
|
||||
// 3. Let markup be an empty string.
|
||||
|
@ -850,16 +850,16 @@ static WebIDL::ExceptionOr<String> serialize_processing_instruction(DOM::Process
|
|||
// 1. If the require well-formed flag is set (its value is true), and node's target contains a ":" (U+003A COLON) character
|
||||
// or is an ASCII case-insensitive match for the string "xml", then throw an exception; the serialization of this node's target would not be well-formed.
|
||||
if (processing_instruction.target().contains(':'))
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction target contains a colon");
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.realm(), "Processing instruction target contains a colon");
|
||||
|
||||
if (processing_instruction.target().equals_ignoring_case("xml"sv))
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction target is equal to 'xml'");
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.realm(), "Processing instruction target is equal to 'xml'");
|
||||
|
||||
// 2. If the require well-formed flag is set (its value is true), and node's data contains characters that are not matched by the XML Char production or contains
|
||||
// the string "?>" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN), then throw an exception; the serialization of this node's data would not be well-formed.
|
||||
// FIXME: Check data against the XML Char production.
|
||||
if (processing_instruction.data().contains("?>"sv))
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.global_object(), "Processing instruction data contains a terminator");
|
||||
return WebIDL::InvalidStateError::create(processing_instruction.realm(), "Processing instruction data contains a terminator");
|
||||
}
|
||||
|
||||
// 3. Let markup be the concatenation of the following, in the order listed:
|
||||
|
|
|
@ -14,14 +14,14 @@ class XMLSerializer final : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(XMLSerializer, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<XMLSerializer> create_with_global_object(HTML::Window&);
|
||||
static JS::NonnullGCPtr<XMLSerializer> construct_impl(JS::Realm&);
|
||||
|
||||
virtual ~XMLSerializer() override;
|
||||
|
||||
WebIDL::ExceptionOr<String> serialize_to_string(JS::NonnullGCPtr<DOM::Node> root);
|
||||
|
||||
private:
|
||||
explicit XMLSerializer(HTML::Window&);
|
||||
explicit XMLSerializer(JS::Realm&);
|
||||
};
|
||||
|
||||
enum class RequireWellFormed {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/HTML/MessageEvent.h>
|
||||
#include <LibWeb/HTML/MessagePort.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/Origin.h>
|
||||
|
||||
|
|
|
@ -4,29 +4,27 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
|
||||
namespace Web::WebIDL {
|
||||
|
||||
JS::NonnullGCPtr<DOMException> DOMException::create(JS::Object& global_object, FlyString const& name, FlyString const& message)
|
||||
JS::NonnullGCPtr<DOMException> DOMException::create(JS::Realm& realm, FlyString const& name, FlyString const& message)
|
||||
{
|
||||
auto& window = verify_cast<HTML::Window>(global_object);
|
||||
return *window.heap().allocate<DOMException>(window.realm(), window, name, message);
|
||||
return *realm.heap().allocate<DOMException>(realm, realm, name, message);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMException> DOMException::create_with_global_object(JS::Object& global_object, FlyString const& message, FlyString const& name)
|
||||
JS::NonnullGCPtr<DOMException> DOMException::construct_impl(JS::Realm& realm, FlyString const& message, FlyString const& name)
|
||||
{
|
||||
auto& window = verify_cast<HTML::Window>(global_object);
|
||||
return *window.heap().allocate<DOMException>(window.realm(), window, name, message);
|
||||
return *realm.heap().allocate<DOMException>(realm, realm, name, message);
|
||||
}
|
||||
|
||||
DOMException::DOMException(HTML::Window& window, FlyString const& name, FlyString const& message)
|
||||
: PlatformObject(window.realm())
|
||||
DOMException::DOMException(JS::Realm& realm, FlyString const& name, FlyString const& message)
|
||||
: PlatformObject(realm)
|
||||
, m_name(name)
|
||||
, m_message(message)
|
||||
{
|
||||
set_prototype(&window.cached_web_prototype("DOMException"));
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "DOMException"));
|
||||
}
|
||||
|
||||
DOMException::~DOMException() = default;
|
||||
|
|
|
@ -9,17 +9,18 @@
|
|||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
|
||||
namespace Web::WebIDL {
|
||||
|
||||
#define TRY_OR_RETURN_OOM(global_object, expression) \
|
||||
({ \
|
||||
auto _temporary_result = (expression); \
|
||||
if (_temporary_result.is_error()) { \
|
||||
VERIFY(_temporary_result.error().code() == ENOMEM); \
|
||||
return WebIDL::UnknownError::create(global_object, "Out of memory."sv); \
|
||||
} \
|
||||
_temporary_result.release_value(); \
|
||||
#define TRY_OR_RETURN_OOM(realm, expression) \
|
||||
({ \
|
||||
auto _temporary_result = (expression); \
|
||||
if (_temporary_result.is_error()) { \
|
||||
VERIFY(_temporary_result.error().code() == ENOMEM); \
|
||||
return WebIDL::UnknownError::create(realm, "Out of memory."sv); \
|
||||
} \
|
||||
_temporary_result.release_value(); \
|
||||
})
|
||||
|
||||
// The following have a legacy code value but *don't* produce it as
|
||||
|
@ -102,13 +103,11 @@ class DOMException final : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(DOMException, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Object& global_object, FlyString const& name, FlyString const& message);
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Realm& realm, FlyString const& name, FlyString const& message);
|
||||
|
||||
// JS constructor has message first, name second
|
||||
// FIXME: This is a completely pointless footgun, let's use the same order for both factories.
|
||||
static JS::NonnullGCPtr<DOMException> create_with_global_object(JS::Object& global_object, FlyString const& message, FlyString const& name);
|
||||
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Realm& realm, FlyString const& message);
|
||||
static JS::NonnullGCPtr<DOMException> construct_impl(JS::Realm& realm, FlyString const& message, FlyString const& name);
|
||||
|
||||
virtual ~DOMException() override;
|
||||
|
||||
|
@ -117,20 +116,24 @@ public:
|
|||
u16 code() const { return get_legacy_code_for_name(m_name); }
|
||||
|
||||
protected:
|
||||
DOMException(HTML::Window&, FlyString const& name, FlyString const& message);
|
||||
DOMException(JS::Realm&, FlyString const& name, FlyString const& message);
|
||||
|
||||
private:
|
||||
FlyString m_name;
|
||||
FlyString m_message;
|
||||
};
|
||||
|
||||
#define __ENUMERATE(ErrorName) \
|
||||
class ErrorName final { \
|
||||
public: \
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Object& global_object, FlyString const& message) \
|
||||
{ \
|
||||
return DOMException::create(global_object, #ErrorName, message); \
|
||||
} \
|
||||
#define __ENUMERATE(ErrorName) \
|
||||
class ErrorName final { \
|
||||
public: \
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Realm& realm, FlyString const& message) \
|
||||
{ \
|
||||
return DOMException::create(realm, #ErrorName, message); \
|
||||
} \
|
||||
static JS::NonnullGCPtr<DOMException> create(JS::Object const& global_object, FlyString const& message) \
|
||||
{ \
|
||||
return create(HTML::relevant_realm(global_object), message); \
|
||||
} \
|
||||
};
|
||||
ENUMERATE_DOM_EXCEPTION_ERROR_NAMES
|
||||
#undef __ENUMERATE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue