on master help sign in
PR feedback
commit8b4eafc9062aa99e0425f8e3f3ca44febcc57218 authorRyan Levick <ryan.levick@gmail.com> dateTue 19 Mar 2019, 22:47 (8 years ago) parentbb64ad8
3 files changed+53−89
src/builder.rs+31−19 src/node.rs+5−23 src/vdom.rs+17−47
src/builder.rs+31−19
@@ -64,18 +64,6 @@ impl<'a>
6464 namespace: None,
6565 }
6666 }
67−
68− /// FIX ME
69− pub fn new_with_namespace(bump: &'a Bump, tag_name: &'a str, namespace: &'a str) -> Self {
70− ElementBuilder {
71− bump,
72− tag_name,
73− listeners: bumpalo::collections::Vec::new_in(bump),
74− attributes: bumpalo::collections::Vec::new_in(bump),
75− children: bumpalo::collections::Vec::new_in(bump),
76− namespace: Some(namespace),
77− }
78− }
7967}
8068
8169impl<'a, Listeners, Attributes, Children> ElementBuilder<'a, Listeners, Attributes, Children>
@@ -202,6 +190,32 @@ where
202190 }
203191 }
204192
193+ /// Set the namespace for this element.
194+ ///
195+ /// # Example
196+ ///
197+ /// ```no_run
198+ /// use dodrio::{builder::*, bumpalo::Bump};
199+ ///
200+ /// let b = Bump::new();
201+ ///
202+ /// // Create a `<td>` tag with an xhtml namespace
203+ /// let my_div = td(&b)
204+ /// .namepace(Some("http://www.w3.org/1999/xhtml"))
205+ /// .finish();
206+ /// ```
207+ #[inline]
208+ pub fn namespace(self, namespace: Option<&'a str>) -> Self {
209+ ElementBuilder {
210+ bump: self.bump,
211+ tag_name: self.tag_name,
212+ listeners: self.listeners,
213+ attributes: self.attributes,
214+ children: self.children,
215+ namespace,
216+ }
217+ }
218+
205219 /// Create the virtual DOM node described by this builder.
206220 ///
207221 /// # Example
@@ -219,17 +233,14 @@ where
219233 /// ```
220234 #[inline]
221235 pub fn finish(self) -> Node<'a> {
222− let element = Node::element_node(
236+ Node::element(
223237 self.bump,
224238 self.tag_name,
225239 self.listeners,
226240 self.attributes,
227241 self.children,
228− );
229− match self.namespace {
230− Some(namespace) => Node::NamespacedElement(namespace, element),
231− None => Node::Element(element),
232− }
242+ self.namespace,
243+ )
233244 }
234245}
235246
@@ -394,7 +405,8 @@ macro_rules! builder_constructors {
394405 bumpalo::collections::Vec<'a, Attribute<'a>>,
395406 bumpalo::collections::Vec<'a, Node<'a>>,
396407 > {
397− ElementBuilder::new_with_namespace(bump, stringify!($name), $namespace)
408+ let builder = ElementBuilder::new(bump, stringify!($name));
409+ builder.namespace(Some($namespace))
398410 }
399411 )*
400412 }
src/node.rs+5−23
@@ -11,9 +11,6 @@ pub enum Node<'a> {
1111
1212 /// An element potentially with attributes and children.
1313 Element(ElementNode<'a>),
14−
15− /// An element with a namespace and potentially with attributes and children.
16− NamespacedElement(&'a str, ElementNode<'a>),
1714}
1815
1916/// Text nodes are just a string of text. They cannot have attributes or
@@ -31,6 +28,7 @@ pub struct ElementNode<'a> {
3128 pub(crate) listeners: &'a [Listener<'a>],
3229 pub(crate) attributes: &'a [Attribute<'a>],
3330 pub(crate) children: &'a [Node<'a>],
31+ pub(crate) namespace: Option<&'a str>,
3432}
3533
3634/// An event listener callback function.
@@ -106,25 +104,8 @@ impl<'a> Node<'a> {
106104 listeners: Listeners,
107105 attributes: Attributes,
108106 children: Children,
107+ namespace: Option<&'a str>,
109108 ) -> Node<'a>
110− where
111− Listeners: 'a + AsRef<[Listener<'a>]>,
112− Attributes: 'a + AsRef<[Attribute<'a>]>,
113− Children: 'a + AsRef<[Node<'a>]>,
114− {
115− let element_node = Node::element_node(bump, tag_name, listeners, attributes, children);
116− Node::Element(element_node)
117− }
118−
119− /// Construct a new element node with the given tag name and children.
120− #[inline]
121− pub(crate) fn element_node<Listeners, Attributes, Children>(
122− bump: &'a Bump,
123− tag_name: &'a str,
124− listeners: Listeners,
125− attributes: Attributes,
126− children: Children,
127− ) -> ElementNode<'a>
128109 where
129110 Listeners: 'a + AsRef<[Listener<'a>]>,
130111 Attributes: 'a + AsRef<[Attribute<'a>]>,
@@ -139,12 +120,13 @@ impl<'a> Node<'a> {
139120 let attributes: &'a Attributes = bump.alloc(attributes);
140121 let attributes: &'a [Attribute<'a>] = attributes.as_ref();
141122
142− ElementNode {
123+ Node::Element(ElementNode {
143124 tag_name,
144125 listeners,
145126 attributes,
146127 children,
147− }
128+ namespace,
129+ })
148130 }
149131
150132 /// Is this node a text node?
src/vdom.rs+17−47
@@ -138,7 +138,7 @@ impl Vdom {
138138 container.set_inner_html("");
139139
140140 // Create a dummy `<div/>` in our container.
141− let current_root = Node::element(&dom_buffers[0], "div", [], [], []);
141+ let current_root = Node::element(&dom_buffers[0], "div", [], [], [], None);
142142 let current_root = Some(unsafe { extend_node_lifetime(current_root) });
143143 let window = web_sys::window().expect("should have acess to the Window");
144144 let document = window
@@ -287,43 +287,32 @@ impl VdomInnerExclusive {
287287 self.change_list.emit_set_text(new_text);
288288 }
289289 }
290− (&Node::Text(_), Node::Element(_))
291− | (&Node::Text(_), Node::NamespacedElement(_, _)) => {
290+ (&Node::Text(_), Node::Element(_)) => {
292291 debug!(" replacing a text node with an element");
293292 self.create(registry, new);
294293 self.change_list.emit_replace_with();
295294 }
296− (&Node::Element(_), Node::Text(_))
297− | (&Node::NamespacedElement(_, _), Node::Text(_)) => {
295+ (&Node::Element(_), Node::Text(_)) => {
298296 debug!(" replacing an element with a text node");
299297 self.create(registry, new);
300298 self.change_list.emit_replace_with();
301299 }
302− (&Node::Element(ref new_element_node), Node::Element(ref old_element_node))
303− | (
304− &Node::NamespacedElement(_, ref new_element_node),
305− Node::Element(ref old_element_node),
306− )
307− | (
308− &Node::Element(ref new_element_node),
309− Node::NamespacedElement(_, ref old_element_node),
310− )
311− | (
312− &Node::NamespacedElement(_, ref new_element_node),
313− Node::NamespacedElement(_, ref old_element_node),
314− ) => {
315− let ElementNode {
300+ (
301+ &Node::Element(ElementNode {
316302 tag_name: new_tag_name,
317303 listeners: new_listeners,
318304 attributes: new_attributes,
319305 children: new_children,
320− } = new_element_node;
321− let ElementNode {
306+ namespace: _,
307+ }),
308+ Node::Element(ElementNode {
322309 tag_name: old_tag_name,
323310 listeners: old_listeners,
324311 attributes: old_attributes,
325312 children: old_children,
326− } = old_element_node;
313+ namespace: _,
314+ }),
315+ ) => {
327316 debug!(" updating an element");
328317 if new_tag_name != old_tag_name {
329318 debug!(" different tag names; creating new element and replacing old element");
@@ -475,32 +464,13 @@ impl VdomInnerExclusive {
475464 listeners,
476465 attributes,
477466 children,
467+ namespace,
478468 }) => {
479− self.change_list.emit_create_element(tag_name);
480− for l in listeners {
481− unsafe {
482− registry.add(l);
483− }
484− self.change_list.emit_new_event_listener(l);
469+ if let Some(namespace) = namespace {
470+ self.change_list.emit_create_element_ns(tag_name, namespace);
471+ } else {
472+ self.change_list.emit_create_element(tag_name);
485473 }
486− for attr in attributes {
487− self.change_list.emit_set_attribute(&attr.name, &attr.value);
488− }
489− for child in children {
490− self.create(registry, child.clone());
491− self.change_list.emit_append_child();
492− }
493− }
494− Node::NamespacedElement(
495− namepsace,
496− ElementNode {
497− tag_name,
498− listeners,
499− attributes,
500− children,
501− },
502− ) => {
503− self.change_list.emit_create_element_ns(tag_name, namepsace);
504474 for l in listeners {
505475 unsafe {
506476 registry.add(l);
@@ -508,7 +478,7 @@ impl VdomInnerExclusive {
508478 self.change_list.emit_new_event_listener(l);
509479 }
510480 for attr in attributes {
511− if attr.name == "xmlns" {
481+ if namespace.is_none() || attr.name == "xmlns" {
512482 self.change_list.emit_set_attribute(&attr.name, &attr.value);
513483 } else {
514484 self.change_list