From d540e2ec9802d7c0356d0f9ed80b3215f7a03742 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Sat, 1 Oct 2022 00:30:15 +0100 Subject: LibWeb: Implement Element.insertAdjacentElement --- Userland/Libraries/LibWeb/DOM/Element.cpp | 51 +++++++++++++++++++++++++++++++ Userland/Libraries/LibWeb/DOM/Element.h | 4 +++ Userland/Libraries/LibWeb/DOM/Element.idl | 1 + 3 files changed, 56 insertions(+) (limited to 'Userland/Libraries/LibWeb') diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index b9d8a62d9c..47a8e18b48 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -840,4 +840,55 @@ WebIDL::ExceptionOr Element::insert_adjacent_html(String position, String return {}; } +// https://dom.spec.whatwg.org/#insert-adjacent +WebIDL::ExceptionOr> Element::insert_adjacent(String const& where, JS::NonnullGCPtr node) +{ + // To insert adjacent, given an element element, string where, and a node node, run the steps associated with the first ASCII case-insensitive match for where: + if (where.equals_ignoring_case("beforebegin"sv)) { + // -> "beforebegin" + // If element’s parent is null, return null. + if (!parent()) + return JS::GCPtr { nullptr }; + + // Return the result of pre-inserting node into element’s parent before element. + return JS::GCPtr { TRY(parent()->pre_insert(move(node), this)) }; + } + + if (where.equals_ignoring_case("afterbegin"sv)) { + // -> "afterbegin" + // Return the result of pre-inserting node into element before element’s first child. + return JS::GCPtr { TRY(pre_insert(move(node), first_child())) }; + } + + if (where.equals_ignoring_case("beforeend"sv)) { + // -> "beforeend" + // Return the result of pre-inserting node into element before null. + return JS::GCPtr { TRY(pre_insert(move(node), nullptr)) }; + } + + if (where.equals_ignoring_case("afterend"sv)) { + // -> "afterend" + // If element’s parent is null, return null. + if (!parent()) + return JS::GCPtr { nullptr }; + + // Return the result of pre-inserting node into element’s parent before element’s next sibling. + return JS::GCPtr { TRY(parent()->pre_insert(move(node), next_sibling())) }; + } + + // -> 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)); +} + +// https://dom.spec.whatwg.org/#dom-element-insertadjacentelement +WebIDL::ExceptionOr> Element::insert_adjacent_element(String const& where, JS::NonnullGCPtr element) +{ + // The insertAdjacentElement(where, element) method steps are to return the result of running insert adjacent, give this, where, and element. + auto returned_node = TRY(insert_adjacent(where, move(element))); + if (!returned_node) + return JS::GCPtr { nullptr }; + return JS::GCPtr { verify_cast(*returned_node) }; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index 451dc3daea..08e4b42bc9 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -144,6 +144,8 @@ public: bool is_actually_disabled() const; + WebIDL::ExceptionOr> insert_adjacent_element(String const& where, JS::NonnullGCPtr element); + protected: Element(Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; @@ -155,6 +157,8 @@ protected: private: void make_html_uppercased_qualified_name(); + WebIDL::ExceptionOr> insert_adjacent(String const& where, JS::NonnullGCPtr node); + QualifiedName m_qualified_name; String m_html_uppercased_qualified_name; diff --git a/Userland/Libraries/LibWeb/DOM/Element.idl b/Userland/Libraries/LibWeb/DOM/Element.idl index 9d25de71b2..6b514f6173 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.idl +++ b/Userland/Libraries/LibWeb/DOM/Element.idl @@ -53,6 +53,7 @@ interface Element : Node { readonly attribute long clientWidth; readonly attribute long clientHeight; + [CEReactions] Element? insertAdjacentElement(DOMString where, Element element); [CEReactions] undefined insertAdjacentHTML(DOMString position, DOMString text); }; -- cgit v1.2.3