mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 14:35:08 +00:00
LibWeb: Implement Element.insertAdjacentHTML() from DOM Parsing
One edge case is left as a TODO() for now, since I'm not entirely sure how to construct an element to those specifications. With this patch, we can now run the Speedometer benchmark! :^)
This commit is contained in:
parent
287a9b552a
commit
aa4dd6c1bc
5 changed files with 80 additions and 1 deletions
|
@ -730,4 +730,77 @@ void Element::serialize_pseudo_elements_as_json(JsonArraySerializer<StringBuilde
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/DOM-Parsing/#dom-element-insertadjacenthtml
|
||||||
|
DOM::ExceptionOr<void> Element::insert_adjacent_html(String position, String text)
|
||||||
|
{
|
||||||
|
JS::GCPtr<Node> context;
|
||||||
|
// 1. Use the first matching item from this list:
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "beforebegin"
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "afterend"
|
||||||
|
if (position.equals_ignoring_case("beforebegin"sv) || position.equals_ignoring_case("afterend"sv)) {
|
||||||
|
// Let context be the context object's parent.
|
||||||
|
context = this->parent();
|
||||||
|
|
||||||
|
// If context is null or a Document, throw a "NoModificationAllowedError" DOMException.
|
||||||
|
if (!context || context->is_document())
|
||||||
|
return NoModificationAllowedError::create(window(), "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"
|
||||||
|
else if (position.equals_ignoring_case("afterbegin"sv) || position.equals_ignoring_case("beforeend"sv)) {
|
||||||
|
// Let context be the context object.
|
||||||
|
context = this;
|
||||||
|
}
|
||||||
|
// Otherwise
|
||||||
|
else {
|
||||||
|
// Throw a "SyntaxError" DOMException.
|
||||||
|
return SyntaxError::create(window(), "insertAdjacentHTML: invalid position argument"sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. If context is not an Element or the following are all true:
|
||||||
|
// - context's node document is an HTML document,
|
||||||
|
// - context's local name is "html", and
|
||||||
|
// - context's namespace is the HTML namespace;
|
||||||
|
if (!is<Element>(*context)
|
||||||
|
|| (context->document().document_type() == Document::Type::HTML
|
||||||
|
&& static_cast<Element const&>(*context).local_name() == "html"sv
|
||||||
|
&& static_cast<Element const&>(*context).namespace_() == Namespace::HTML)) {
|
||||||
|
// FIXME: let context be a new Element with
|
||||||
|
// - body as its local name,
|
||||||
|
// - The HTML namespace as its namespace, and
|
||||||
|
// - The context object's node document as its node document.
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Let fragment be the result of invoking the fragment parsing algorithm with text as markup, and context as the context element.
|
||||||
|
auto fragment = TRY(DOMParsing::parse_fragment(text, verify_cast<Element>(*context)));
|
||||||
|
|
||||||
|
// 4. Use the first matching item from this list:
|
||||||
|
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "beforebegin"
|
||||||
|
if (position.equals_ignoring_case("beforebegin"sv)) {
|
||||||
|
// Insert fragment into the context object's parent before the context object.
|
||||||
|
parent()->insert_before(fragment, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "afterbegin"
|
||||||
|
else if (position.equals_ignoring_case("afterbegin"sv)) {
|
||||||
|
// Insert fragment into the context object before its first child.
|
||||||
|
insert_before(fragment, first_child());
|
||||||
|
}
|
||||||
|
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "beforeend"
|
||||||
|
else if (position.equals_ignoring_case("beforeend"sv)) {
|
||||||
|
// Append fragment to the context object.
|
||||||
|
TRY(append_child(fragment));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - If position is an ASCII case-insensitive match for the string "afterend"
|
||||||
|
else if (position.equals_ignoring_case("afterend"sv)) {
|
||||||
|
// Insert fragment into the context object's parent before the context object's next sibling.
|
||||||
|
parent()->insert_before(fragment, next_sibling());
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,8 @@ public:
|
||||||
String inner_html() const;
|
String inner_html() const;
|
||||||
ExceptionOr<void> set_inner_html(String const&);
|
ExceptionOr<void> set_inner_html(String const&);
|
||||||
|
|
||||||
|
ExceptionOr<void> insert_adjacent_html(String position, String text);
|
||||||
|
|
||||||
bool is_focused() const;
|
bool is_focused() const;
|
||||||
bool is_active() const;
|
bool is_active() const;
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ interface Element : Node {
|
||||||
readonly attribute long clientLeft;
|
readonly attribute long clientLeft;
|
||||||
readonly attribute long clientWidth;
|
readonly attribute long clientWidth;
|
||||||
readonly attribute long clientHeight;
|
readonly attribute long clientHeight;
|
||||||
|
|
||||||
|
[CEReactions] undefined insertAdjacentHTML(DOMString position, DOMString text);
|
||||||
};
|
};
|
||||||
|
|
||||||
Element includes ParentNode;
|
Element includes ParentNode;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace Web::DOMParsing {
|
namespace Web::DOMParsing {
|
||||||
|
|
||||||
// https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm
|
// https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm
|
||||||
static DOM::ExceptionOr<JS::NonnullGCPtr<DOM::DocumentFragment>> parse_fragment(String const& markup, DOM::Element& context_element)
|
DOM::ExceptionOr<JS::NonnullGCPtr<DOM::DocumentFragment>> parse_fragment(String const& markup, DOM::Element& context_element)
|
||||||
{
|
{
|
||||||
// FIXME: Handle XML documents.
|
// FIXME: Handle XML documents.
|
||||||
|
|
||||||
|
|
|
@ -16,4 +16,6 @@ namespace Web::DOMParsing {
|
||||||
// https://w3c.github.io/DOM-Parsing/#dom-innerhtml-innerhtml
|
// https://w3c.github.io/DOM-Parsing/#dom-innerhtml-innerhtml
|
||||||
DOM::ExceptionOr<void> inner_html_setter(JS::NonnullGCPtr<DOM::Node> context_object, String const& value);
|
DOM::ExceptionOr<void> inner_html_setter(JS::NonnullGCPtr<DOM::Node> context_object, String const& value);
|
||||||
|
|
||||||
|
DOM::ExceptionOr<JS::NonnullGCPtr<DOM::DocumentFragment>> parse_fragment(String const& markup, DOM::Element& context_element);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue