script/dom/html/
htmltemplateelement.rs1use dom_struct::dom_struct;
6use html5ever::{LocalName, Prefix};
7use js::rust::HandleObject;
8
9use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
10use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
11use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
12use crate::dom::bindings::inheritance::Castable;
13use crate::dom::bindings::root::{DomRoot, MutNullableDom};
14use crate::dom::bindings::str::DOMString;
15use crate::dom::document::Document;
16use crate::dom::documentfragment::DocumentFragment;
17use crate::dom::html::htmlelement::HTMLElement;
18use crate::dom::node::{CloneChildrenFlag, Node, NodeTraits};
19use crate::dom::virtualmethods::VirtualMethods;
20use crate::script_runtime::CanGc;
21
22#[dom_struct]
23pub(crate) struct HTMLTemplateElement {
24 htmlelement: HTMLElement,
25
26 contents: MutNullableDom<DocumentFragment>,
28}
29
30impl HTMLTemplateElement {
31 fn new_inherited(
32 local_name: LocalName,
33 prefix: Option<Prefix>,
34 document: &Document,
35 ) -> HTMLTemplateElement {
36 HTMLTemplateElement {
37 htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
38 contents: MutNullableDom::new(None),
39 }
40 }
41
42 #[cfg_attr(crown, allow(crown::unrooted_must_root))]
43 pub(crate) fn new(
44 local_name: LocalName,
45 prefix: Option<Prefix>,
46 document: &Document,
47 proto: Option<HandleObject>,
48 can_gc: CanGc,
49 ) -> DomRoot<HTMLTemplateElement> {
50 let n = Node::reflect_node_with_proto(
51 Box::new(HTMLTemplateElement::new_inherited(
52 local_name, prefix, document,
53 )),
54 document,
55 proto,
56 can_gc,
57 );
58
59 n.upcast::<Node>().set_weird_parser_insertion_mode();
60 n
61 }
62
63 pub(crate) fn set_contents(&self, document_fragment: Option<&DocumentFragment>) {
64 self.contents.set(document_fragment);
65 }
66}
67
68#[allow(unused_doc_comments)]
69impl HTMLTemplateElementMethods<crate::DomTypeHolder> for HTMLTemplateElement {
70 make_enumerated_getter!(
72 ShadowRootMode,
73 "shadowrootmode",
74 "open" | "closed",
75 missing => "",
76 invalid => ""
77 );
78
79 make_atomic_setter!(SetShadowRootMode, "shadowrootmode");
81
82 make_bool_getter!(ShadowRootDelegatesFocus, "shadowrootdelegatesfocus");
84
85 make_bool_setter!(SetShadowRootDelegatesFocus, "shadowrootdelegatesfocus");
87
88 make_bool_getter!(ShadowRootClonable, "shadowrootclonable");
90
91 make_bool_setter!(SetShadowRootClonable, "shadowrootclonable");
93
94 make_bool_getter!(ShadowRootSerializable, "shadowrootserializable");
96
97 make_bool_setter!(SetShadowRootSerializable, "shadowrootserializable");
99
100 fn Content(&self, can_gc: CanGc) -> DomRoot<DocumentFragment> {
102 self.contents.or_init(|| {
103 let doc = self.owner_document();
104 doc.appropriate_template_contents_owner_document(can_gc)
105 .CreateDocumentFragment(can_gc)
106 })
107 }
108}
109
110impl VirtualMethods for HTMLTemplateElement {
111 fn super_type(&self) -> Option<&dyn VirtualMethods> {
112 Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
113 }
114
115 fn adopting_steps(&self, old_doc: &Document, can_gc: CanGc) {
117 self.super_type().unwrap().adopting_steps(old_doc, can_gc);
118 let doc = self
120 .owner_document()
121 .appropriate_template_contents_owner_document(CanGc::note());
122 Node::adopt(self.Content(CanGc::note()).upcast(), &doc, can_gc);
124 }
125
126 fn cloning_steps(
128 &self,
129 copy: &Node,
130 maybe_doc: Option<&Document>,
131 clone_children: CloneChildrenFlag,
132 can_gc: CanGc,
133 ) {
134 self.super_type()
135 .unwrap()
136 .cloning_steps(copy, maybe_doc, clone_children, can_gc);
137 if clone_children == CloneChildrenFlag::DoNotCloneChildren {
138 return;
140 }
141 let copy = copy.downcast::<HTMLTemplateElement>().unwrap();
142 let copy_contents = DomRoot::upcast::<Node>(copy.Content(CanGc::note()));
144 let copy_contents_doc = copy_contents.owner_doc();
145 for child in self.Content(CanGc::note()).upcast::<Node>().children() {
146 let copy_child = Node::clone(
147 &child,
148 Some(©_contents_doc),
149 CloneChildrenFlag::CloneChildren,
150 CanGc::note(),
151 );
152 copy_contents.AppendChild(©_child, can_gc).unwrap();
153 }
154 }
155}