feat: implement ShadowRoot::setHTMLUnsafe (#36240)

Implements #36166

---------

Signed-off-by: TG <ebiritg@gmail.com>
This commit is contained in:
Kelechi Ebiri 2025-05-01 16:19:41 +01:00 committed by GitHub
parent 5cdb0865ba
commit 1a3f10bba4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 46 additions and 4940 deletions

View file

@ -3025,28 +3025,8 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
DomRoot::from_ref(self.upcast())
};
// Step 3. Unsafely set HTML given target, this, and compliantHTML.
// Let newChildren be the result of the HTML fragment parsing algorithm.
let new_children = ServoParser::parse_html_fragment(self, html, true, can_gc);
let context_document = {
if let Some(template) = self.downcast::<HTMLTemplateElement>() {
template.Content(can_gc).upcast::<Node>().owner_doc()
} else {
self.owner_document()
}
};
// Let fragment be a new DocumentFragment whose node document is contextElement's node document.
let frag = DocumentFragment::new(&context_document, can_gc);
// For each node in newChildren, append node to fragment.
for child in new_children {
frag.upcast::<Node>().AppendChild(&child, can_gc).unwrap();
}
// Replace all with fragment within target.
Node::replace_all(Some(frag.upcast()), &target, can_gc);
// Step 3. Unsafely set HTML given target, this, and compliantHTML
Node::unsafely_set_html(&target, self, html, can_gc);
}
/// <https://html.spec.whatwg.org/multipage/#dom-element-gethtml>

View file

@ -110,7 +110,7 @@ use crate::dom::pointerevent::{PointerEvent, PointerId};
use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::range::WeakRangeVec;
use crate::dom::raredata::NodeRareData;
use crate::dom::servoparser::serialize_html_fragment;
use crate::dom::servoparser::{ServoParser, serialize_html_fragment};
use crate::dom::shadowroot::{IsUserAgentWidget, LayoutShadowRootHelpers, ShadowRoot};
use crate::dom::stylesheetlist::StyleSheetListOwner;
use crate::dom::svgsvgelement::{LayoutSVGSVGElementHelpers, SVGSVGElement};
@ -316,6 +316,34 @@ impl Node {
}
}
/// Implements the "unsafely set HTML" algorithm as specified in:
/// <https://html.spec.whatwg.org/multipage/#concept-unsafely-set-html>
pub fn unsafely_set_html(
target: &Node,
context_element: &Element,
html: DOMString,
can_gc: CanGc,
) {
// Step 1. Let newChildren be the result of the HTML fragment parsing algorithm.
let new_children = ServoParser::parse_html_fragment(context_element, html, true, can_gc);
// Step 2. Let fragment be a new DocumentFragment whose node document is contextElement's node document.
let context_document = context_element.owner_document();
let fragment = DocumentFragment::new(&context_document, can_gc);
// Step 3. For each node in newChildren, append node to fragment.
for child in new_children {
fragment
.upcast::<Node>()
.AppendChild(&child, can_gc)
.unwrap();
}
// Step 4. Replace all with fragment within target.
Node::replace_all(Some(fragment.upcast()), target, can_gc);
}
pub(crate) fn clean_up_style_and_layout_data(&self) {
self.owner_doc().cancel_animations_for_node(self);
self.style_data.borrow_mut().take();

View file

@ -453,6 +453,15 @@ impl ShadowRootMethods<crate::DomTypeHolder> for ShadowRoot {
self.slot_assignment_mode
}
/// <https://html.spec.whatwg.org/multipage/#dom-shadowroot-sethtmlunsafe>
fn SetHTMLUnsafe(&self, html: DOMString, can_gc: CanGc) {
// Step 2. Unsafely set HTMl given this, this's shadow host, and complaintHTML
let target = self.upcast::<Node>();
let context_element = self.Host();
Node::unsafely_set_html(target, &context_element, html, can_gc);
}
// https://dom.spec.whatwg.org/#dom-shadowroot-onslotchange
event_handler!(onslotchange, GetOnslotchange, SetOnslotchange);
}