Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions html5ever/src/tree_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,8 +1376,31 @@ where
fn insert_phantom(&self, name: LocalName) -> Handle {
self.insert_element(Push, ns!(html), name, vec![])
}

/// <https://html.spec.whatwg.org/multipage/parsing.html#insert-an-element-at-the-adjusted-insertion-location>
fn insert_foreign_element(
&self,
tag: Tag,
ns: Namespace,
only_add_to_element_stack: bool,
) -> Handle {
let adjusted_insertion_location = self.appropriate_place_for_insertion(None);
let qname = QualName::new(None, ns, tag.name);
let elem = create_element(&self.sink, qname.clone(), tag.attrs.clone());

if !only_add_to_element_stack {
self.insert_at(adjusted_insertion_location, AppendNode(elem.clone()));
}

self.push(&elem);

elem
}
//§ END

/// <https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead>
///
/// A start tag whose tag name is "template"
fn should_attach_declarative_shadow(&self, tag: &Tag) -> bool {
let adjusted_insertion_location = self.appropriate_place_for_insertion(None);

Expand All @@ -1392,7 +1415,7 @@ where
// template start tag's shadowrootmode is not in the none state
let is_shadow_root_mode = tag.attrs.iter().any(|attr| {
attr.name.local == local_name!("shadowrootmode")
&& (attr.value.to_string() == *"open" || attr.value.to_string() == *"close")
&& (attr.value.as_ref() == "open" || attr.value.as_ref() == "closed")
});

// Check if intended_parent's document allows declarative shadow roots
Expand All @@ -1416,9 +1439,17 @@ where
is_shadow_root_mode && allow_declarative_shadow_roots && adjusted_current_node_not_topmost
}

fn attach_declarative_shadow(&self, tag: &Tag) -> Result<(), String> {
/// <https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead>
///
/// A start tag whose tag name is "template"
fn attach_declarative_shadow(
&self,
tag: &Tag,
shadow_host: &Handle,
template: &Handle,
) -> Result<(), String> {
self.sink
.attach_declarative_shadow(self.open_elems.borrow().last().unwrap(), tag.attrs.clone())
.attach_declarative_shadow(shadow_host, template, tag.attrs.clone())
}

fn create_formatting_element_for(&self, tag: Tag) -> Handle {
Expand Down
22 changes: 18 additions & 4 deletions html5ever/src/tree_builder/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,24 @@ where
self.template_modes.borrow_mut().push(InTemplate);

if (self.should_attach_declarative_shadow(&tag)) {
if self.attach_declarative_shadow(&tag).is_err() {
// TODO:
// insert at the adjusted insertion location
// with the result of insert a foreign element for template tag
// Attach shadow path

// Step 1. Let declarative shadow host element be adjusted current node.
let mut shadow_host = self.open_elems.borrow().last().unwrap().clone();
if self.is_fragment() && self.open_elems.borrow().len() == 1 {
shadow_host = self.context_elem.borrow().clone().unwrap();
}

// Step 2. Let template be the result of insert a foreign element for template start tag, with HTML namespace and true.
let template = self.insert_foreign_element(tag.clone(), ns!(html), true);

// Step 3 - 8.
// Attach a shadow root with declarative shadow host element, mode, clonable, serializable, delegatesFocus, and "named".
if self.attach_declarative_shadow(&tag, &shadow_host, &template).is_err() {
// Step 8.1.1. Insert an element at the adjusted insertion location with template.
// Pop the current template element created in step 2 first.
self.pop();
self.insert_element_for(tag);
}
} else {
self.insert_element_for(tag);
Expand Down
1 change: 1 addition & 0 deletions markup5ever/interface/tree_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ pub trait TreeSink {
fn attach_declarative_shadow(
&self,
_location: &Self::Handle,
_template: &Self::Handle,
_attrs: Vec<Attribute>,
) -> Result<(), String> {
Err(String::from(
Expand Down