diff options
19 files changed, 110 insertions, 63 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 5c92b018a8..29c2d1d1c5 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -76,6 +76,7 @@ set(SOURCES Cookie/ParsedCookie.cpp DOM/AbortController.cpp DOM/AbortSignal.cpp + DOM/AbstractRange.cpp DOM/Attribute.cpp DOM/Attribute.idl DOM/CDATASection.cpp diff --git a/Userland/Libraries/LibWeb/DOM/AbstractRange.cpp b/Userland/Libraries/LibWeb/DOM/AbstractRange.cpp new file mode 100644 index 0000000000..357a0da71f --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/AbstractRange.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibWeb/Bindings/AbstractRangePrototype.h> +#include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/DOM/AbstractRange.h> +#include <LibWeb/DOM/Document.h> + +namespace Web::DOM { + +AbstractRange::AbstractRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset) + : Bindings::PlatformObject(start_container.document().preferred_window_object().ensure_web_prototype<Bindings::AbstractRangePrototype>("AbstractRange")) + , m_start_container(start_container) + , m_start_offset(start_offset) + , m_end_container(end_container) + , m_end_offset(end_offset) +{ +} + +AbstractRange::~AbstractRange() = default; + +} diff --git a/Userland/Libraries/LibWeb/DOM/AbstractRange.h b/Userland/Libraries/LibWeb/DOM/AbstractRange.h index 0407de68f2..e0dded6372 100644 --- a/Userland/Libraries/LibWeb/DOM/AbstractRange.h +++ b/Userland/Libraries/LibWeb/DOM/AbstractRange.h @@ -1,23 +1,24 @@ /* * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include <AK/RefCounted.h> -#include <LibWeb/Bindings/Wrappable.h> +#include <LibWeb/Bindings/PlatformObject.h> +#include <LibWeb/Forward.h> namespace Web::DOM { -class AbstractRange - : public RefCounted<AbstractRange> - , public Bindings::Wrappable { +class AbstractRange : public Bindings::PlatformObject { + JS_OBJECT(AbstractRange, Bindings::PlatformObject); + public: - using WrapperType = Bindings::AbstractRangeWrapper; + virtual ~AbstractRange() override; - virtual ~AbstractRange() override = default; + AbstractRange& impl() { return *this; } Node* start_container() { return m_start_container; } Node const* start_container() const { return m_start_container; } @@ -35,13 +36,7 @@ public: } protected: - AbstractRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset) - : m_start_container(start_container) - , m_start_offset(start_offset) - , m_end_container(end_container) - , m_end_offset(end_offset) - { - } + AbstractRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset); NonnullRefPtr<Node> m_start_container; u32 m_start_offset; @@ -51,3 +46,8 @@ protected: }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::DOM::AbstractRange& object) { return &object; } +using AbstractRangeWrapper = Web::DOM::AbstractRange; +} diff --git a/Userland/Libraries/LibWeb/DOM/AbstractRange.idl b/Userland/Libraries/LibWeb/DOM/AbstractRange.idl index 0b29d41450..78d7b4a921 100644 --- a/Userland/Libraries/LibWeb/DOM/AbstractRange.idl +++ b/Userland/Libraries/LibWeb/DOM/AbstractRange.idl @@ -1,4 +1,4 @@ -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface AbstractRange { readonly attribute Node startContainer; readonly attribute unsigned long startOffset; diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 6f71447706..e53ace8fd8 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1154,7 +1154,7 @@ NonnullRefPtr<Comment> Document::create_comment(String const& data) return adopt_ref(*new Comment(*this, data)); } -NonnullRefPtr<Range> Document::create_range() +JS::NonnullGCPtr<Range> Document::create_range() { return Range::create(*this); } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index f0b579ae66..ccd0cd411f 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -203,8 +203,8 @@ public: NonnullRefPtr<DocumentFragment> create_document_fragment(); NonnullRefPtr<Text> create_text_node(String const& data); NonnullRefPtr<Comment> create_comment(String const& data); - NonnullRefPtr<Range> create_range(); ExceptionOr<JS::NonnullGCPtr<Event>> create_event(String const& interface); + JS::NonnullGCPtr<Range> create_range(); void set_pending_parsing_blocking_script(Badge<HTML::HTMLScriptElement>, HTML::HTMLScriptElement*); HTML::HTMLScriptElement* pending_parsing_blocking_script() { return m_pending_parsing_blocking_script; } diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index 71a5a66f38..eb8d1bceb8 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/RangePrototype.h> #include <LibWeb/DOM/Comment.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/DocumentFragment.h> @@ -24,22 +25,24 @@ HashTable<Range*>& Range::live_ranges() return ranges; } -NonnullRefPtr<Range> Range::create(HTML::Window& window) +JS::NonnullGCPtr<Range> Range::create(HTML::Window& window) { return Range::create(window.associated_document()); } -NonnullRefPtr<Range> Range::create(Document& document) +JS::NonnullGCPtr<Range> Range::create(Document& document) { - return adopt_ref(*new Range(document)); + auto& window_object = document.preferred_window_object(); + return *window_object.heap().allocate<Range>(window_object.realm(), document); } -NonnullRefPtr<Range> Range::create(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset) +JS::NonnullGCPtr<Range> Range::create(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset) { - return adopt_ref(*new Range(start_container, start_offset, end_container, end_offset)); + auto& window_object = start_container.document().preferred_window_object(); + return *window_object.heap().allocate<Range>(window_object.realm(), start_container, start_offset, end_container, end_offset); } -NonnullRefPtr<Range> Range::create_with_global_object(Bindings::WindowObject& window) +JS::NonnullGCPtr<Range> Range::create_with_global_object(Bindings::WindowObject& window) { return Range::create(window.impl()); } @@ -47,11 +50,13 @@ NonnullRefPtr<Range> Range::create_with_global_object(Bindings::WindowObject& wi Range::Range(Document& document) : Range(document, 0, document, 0) { + set_prototype(&document.preferred_window_object().ensure_web_prototype<Bindings::RangePrototype>("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.document().preferred_window_object().ensure_web_prototype<Bindings::RangePrototype>("Range")); live_ranges().set(this); } @@ -400,17 +405,17 @@ ExceptionOr<void> Range::select_node_contents(Node const& node) return {}; } -NonnullRefPtr<Range> Range::clone_range() const +JS::NonnullGCPtr<Range> Range::clone_range() const { - return adopt_ref(*new Range(const_cast<Node&>(*m_start_container), m_start_offset, const_cast<Node&>(*m_end_container), m_end_offset)); + return *heap().allocate<Range>(shape().realm(), const_cast<Node&>(*m_start_container), m_start_offset, const_cast<Node&>(*m_end_container), m_end_offset); } -NonnullRefPtr<Range> Range::inverted() const +JS::NonnullGCPtr<Range> Range::inverted() const { - return adopt_ref(*new Range(const_cast<Node&>(*m_end_container), m_end_offset, const_cast<Node&>(*m_start_container), m_start_offset)); + return *heap().allocate<Range>(shape().realm(), const_cast<Node&>(*m_end_container), m_end_offset, const_cast<Node&>(*m_start_container), m_start_offset); } -NonnullRefPtr<Range> Range::normalized() const +JS::NonnullGCPtr<Range> Range::normalized() const { if (m_start_container.ptr() == m_end_container.ptr()) { if (m_start_offset <= m_end_offset) diff --git a/Userland/Libraries/LibWeb/DOM/Range.h b/Userland/Libraries/LibWeb/DOM/Range.h index 57a784de26..a63b0e4baf 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.h +++ b/Userland/Libraries/LibWeb/DOM/Range.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -12,15 +13,19 @@ namespace Web::DOM { class Range final : public AbstractRange { + JS_OBJECT(Range, AbstractRange); + public: - using WrapperType = Bindings::RangeWrapper; + Range& impl() { return *this; } - virtual ~Range() override; + 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(Bindings::WindowObject&); - static NonnullRefPtr<Range> create(Document&); - static NonnullRefPtr<Range> create(HTML::Window&); - static NonnullRefPtr<Range> create(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset); - static NonnullRefPtr<Range> create_with_global_object(Bindings::WindowObject&); + 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. @@ -44,9 +49,9 @@ public: ExceptionOr<i16> compare_boundary_points(u16 how, Range const& source_range) const; - NonnullRefPtr<Range> inverted() const; - NonnullRefPtr<Range> normalized() const; - NonnullRefPtr<Range> clone_range() const; + JS::NonnullGCPtr<Range> inverted() const; + JS::NonnullGCPtr<Range> normalized() const; + JS::NonnullGCPtr<Range> clone_range() const; NonnullRefPtr<Node> common_ancestor_container() const; @@ -73,10 +78,6 @@ 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; @@ -97,3 +98,8 @@ private: }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::DOM::Range& object) { return &object; } +using RangeWrapper = Web::DOM::Range; +} diff --git a/Userland/Libraries/LibWeb/DOM/Range.idl b/Userland/Libraries/LibWeb/DOM/Range.idl index 677954eae0..9ebf6a4b9c 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.idl +++ b/Userland/Libraries/LibWeb/DOM/Range.idl @@ -1,7 +1,7 @@ #import <DOM/Node.idl> #import <DOM/AbstractRange.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface Range : AbstractRange { constructor(); diff --git a/Userland/Libraries/LibWeb/DOM/StaticRange.cpp b/Userland/Libraries/LibWeb/DOM/StaticRange.cpp index aadea6b36d..6027b4195e 100644 --- a/Userland/Libraries/LibWeb/DOM/StaticRange.cpp +++ b/Userland/Libraries/LibWeb/DOM/StaticRange.cpp @@ -1,11 +1,14 @@ /* * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <AK/TypeCasts.h> +#include <LibWeb/Bindings/StaticRangePrototype.h> #include <LibWeb/DOM/Attribute.h> +#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/DocumentType.h> #include <LibWeb/DOM/ExceptionOr.h> #include <LibWeb/DOM/StaticRange.h> @@ -15,10 +18,13 @@ 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().preferred_window_object().ensure_web_prototype<Bindings::StaticRangePrototype>("StaticRange")); } +StaticRange::~StaticRange() = default; + // https://dom.spec.whatwg.org/#dom-staticrange-staticrange -ExceptionOr<NonnullRefPtr<StaticRange>> StaticRange::create_with_global_object(JS::GlobalObject&, StaticRangeInit& init) +ExceptionOr<StaticRange*> StaticRange::create_with_global_object(Bindings::WindowObject& window_object, 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<Attribute>(*init.start_container)) @@ -28,7 +34,7 @@ ExceptionOr<NonnullRefPtr<StaticRange>> StaticRange::create_with_global_object(J return DOM::InvalidNodeTypeError::create("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 adopt_ref(*new StaticRange(*init.start_container, init.start_offset, *init.end_container, init.end_offset)); + return window_object.heap().allocate<StaticRange>(window_object.realm(), *init.start_container, init.start_offset, *init.end_container, init.end_offset); } } diff --git a/Userland/Libraries/LibWeb/DOM/StaticRange.h b/Userland/Libraries/LibWeb/DOM/StaticRange.h index 69dfaef249..7f44aefb27 100644 --- a/Userland/Libraries/LibWeb/DOM/StaticRange.h +++ b/Userland/Libraries/LibWeb/DOM/StaticRange.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -20,15 +21,20 @@ struct StaticRangeInit { }; class StaticRange final : public AbstractRange { -public: - using WrapperType = Bindings::StaticRangeWrapper; - - virtual ~StaticRange() override = default; + JS_OBJECT(StaticRange, JS::Object); - static ExceptionOr<NonnullRefPtr<StaticRange>> create_with_global_object(JS::GlobalObject&, StaticRangeInit& init); +public: + static ExceptionOr<StaticRange*> create_with_global_object(Bindings::WindowObject&, StaticRangeInit& init); -private: StaticRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset); + virtual ~StaticRange() override; + + StaticRange& impl() { return *this; } }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::DOM::StaticRange& object) { return &object; } +using StaticRangeWrapper = Web::DOM::StaticRange; +} diff --git a/Userland/Libraries/LibWeb/DOM/StaticRange.idl b/Userland/Libraries/LibWeb/DOM/StaticRange.idl index cc3b747f29..395fba77a9 100644 --- a/Userland/Libraries/LibWeb/DOM/StaticRange.idl +++ b/Userland/Libraries/LibWeb/DOM/StaticRange.idl @@ -1,7 +1,7 @@ #import <DOM/Node.idl> #import <DOM/AbstractRange.idl> -[Exposed=Window] +[Exposed=Window, NoInstanceWrapper] interface StaticRange : AbstractRange { constructor(StaticRangeInit init); }; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 60f6d5002e..1e4cfde06f 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -446,7 +446,6 @@ class URLSearchParamsIterator; } namespace Web::Bindings { -class AbstractRangeWrapper; class AbortControllerWrapper; class AbortSignalWrapper; class AttributeWrapper; @@ -564,11 +563,9 @@ class PerformanceWrapper; class ProcessingInstructionWrapper; class RangeConstructor; class RangePrototype; -class RangeWrapper; class ResizeObserverWrapper; class ScreenWrapper; class SelectionWrapper; -class StaticRangeWrapper; class StorageWrapper; class SubtleCryptoWrapper; class SVGAnimatedLengthWrapper; diff --git a/Userland/Libraries/LibWeb/Layout/LayoutPosition.cpp b/Userland/Libraries/LibWeb/Layout/LayoutPosition.cpp index c8dfc2bc30..aeb4163f8d 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutPosition.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutPosition.cpp @@ -33,7 +33,7 @@ LayoutRange LayoutRange::normalized() const return { m_end, m_start }; } -NonnullRefPtr<DOM::Range> LayoutRange::to_dom_range() const +JS::NonnullGCPtr<DOM::Range> LayoutRange::to_dom_range() const { VERIFY(is_valid()); diff --git a/Userland/Libraries/LibWeb/Layout/LayoutPosition.h b/Userland/Libraries/LibWeb/Layout/LayoutPosition.h index f924e75ebb..7ab85c4a07 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutPosition.h +++ b/Userland/Libraries/LibWeb/Layout/LayoutPosition.h @@ -7,6 +7,7 @@ #pragma once #include <AK/RefPtr.h> +#include <LibJS/Heap/GCPtr.h> #include <LibWeb/Forward.h> #include <LibWeb/Layout/Node.h> @@ -48,7 +49,7 @@ public: LayoutRange normalized() const; - NonnullRefPtr<DOM::Range> to_dom_range() const; + JS::NonnullGCPtr<DOM::Range> to_dom_range() const; private: LayoutPosition m_start; diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index 7e0864b451..383126c1a6 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -660,11 +660,11 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin m_browsing_context.set_cursor_position({ *range->start_container(), range->start_offset() }); if (key == KeyCode::Key_Backspace || key == KeyCode::Key_Delete) { - m_edit_event_handler->handle_delete(range); + m_edit_event_handler->handle_delete(*range); return true; } if (!should_ignore_keydown_event(code_point)) { - m_edit_event_handler->handle_delete(range); + m_edit_event_handler->handle_delete(*range); m_edit_event_handler->handle_insert(m_browsing_context.cursor_position(), code_point); m_browsing_context.increment_cursor_position_offset(); return true; diff --git a/Userland/Libraries/LibWeb/Selection/Selection.cpp b/Userland/Libraries/LibWeb/Selection/Selection.cpp index da989b2c60..4860da5e82 100644 --- a/Userland/Libraries/LibWeb/Selection/Selection.cpp +++ b/Userland/Libraries/LibWeb/Selection/Selection.cpp @@ -48,7 +48,7 @@ String Selection::type() const TODO(); } -NonnullRefPtr<DOM::Range> Selection::get_range_at(unsigned index) +DOM::Range* Selection::get_range_at(unsigned index) { (void)index; TODO(); diff --git a/Userland/Libraries/LibWeb/Selection/Selection.h b/Userland/Libraries/LibWeb/Selection/Selection.h index 56731c9aab..65fff1443b 100644 --- a/Userland/Libraries/LibWeb/Selection/Selection.h +++ b/Userland/Libraries/LibWeb/Selection/Selection.h @@ -27,7 +27,7 @@ public: bool is_collapsed() const; unsigned range_count() const; String type() const; - NonnullRefPtr<DOM::Range> get_range_at(unsigned index); + DOM::Range* get_range_at(unsigned index); void add_range(DOM::Range&); void remove_range(DOM::Range&); void remove_all_ranges(); diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 6e4691c772..ac5ad86e92 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -20,7 +20,7 @@ libweb_js_wrapper(CSS/MediaQueryListEvent NO_INSTANCE) libweb_js_wrapper(CSS/Screen) libweb_js_wrapper(CSS/StyleSheet NO_INSTANCE) libweb_js_wrapper(CSS/StyleSheetList NO_INSTANCE) -libweb_js_wrapper(DOM/AbstractRange) +libweb_js_wrapper(DOM/AbstractRange NO_INSTANCE) libweb_js_wrapper(DOM/Attribute) libweb_js_wrapper(DOM/AbortController) libweb_js_wrapper(DOM/AbortSignal) @@ -45,9 +45,9 @@ libweb_js_wrapper(DOM/Node) libweb_js_wrapper(DOM/NodeIterator NO_INSTANCE) libweb_js_wrapper(DOM/NodeList) libweb_js_wrapper(DOM/ProcessingInstruction) -libweb_js_wrapper(DOM/Range) +libweb_js_wrapper(DOM/Range NO_INSTANCE) libweb_js_wrapper(DOM/ShadowRoot) -libweb_js_wrapper(DOM/StaticRange) +libweb_js_wrapper(DOM/StaticRange NO_INSTANCE) libweb_js_wrapper(DOM/Text) libweb_js_wrapper(DOM/TreeWalker NO_INSTANCE) libweb_js_wrapper(DOMParsing/XMLSerializer) |