@@ -1,6 +1,6 @@
11//! Helpers for building virtual DOM nodes.
22
3−use crate::{node::ElementNodeFlags, Attribute, Listener, Node, RootRender, VdomWeak};
3+use crate::{node::NodeKey, Attribute, Listener, Node, RootRender, VdomWeak};
44use bumpalo::Bump;
55
66/// A virtual DOM element builder.
@@ -16,7 +16,7 @@ where
1616 Children: 'a + AsRef<[Node<'a>]>,
1717{
1818 bump: &'a Bump,
19− flags: ElementNodeFlags,
19+ key: NodeKey,
2020 tag_name: &'a str,
2121 listeners: Listeners,
2222 attributes: Attributes,
@@ -62,7 +62,7 @@ impl<'a>
6262 let bump = bump.into();
6363 ElementBuilder {
6464 bump,
65− flags: Default::default(),
65+ key: NodeKey::NONE,
6666 tag_name,
6767 listeners: bumpalo::collections::Vec::new_in(bump),
6868 attributes: bumpalo::collections::Vec::new_in(bump),
@@ -112,7 +112,7 @@ where
112112 {
113113 ElementBuilder {
114114 bump: self.bump,
115− flags: self.flags,
115+ key: self.key,
116116 tag_name: self.tag_name,
117117 listeners,
118118 attributes: self.attributes,
@@ -151,7 +151,7 @@ where
151151 {
152152 ElementBuilder {
153153 bump: self.bump,
154− flags: self.flags,
154+ key: self.key,
155155 tag_name: self.tag_name,
156156 listeners: self.listeners,
157157 attributes,
@@ -190,7 +190,7 @@ where
190190 {
191191 ElementBuilder {
192192 bump: self.bump,
193− flags: self.flags,
193+ key: self.key,
194194 tag_name: self.tag_name,
195195 listeners: self.listeners,
196196 attributes: self.attributes,
@@ -217,7 +217,7 @@ where
217217 pub fn namespace(self, namespace: Option<&'a str>) -> Self {
218218 ElementBuilder {
219219 bump: self.bump,
220− flags: self.flags,
220+ key: self.key,
221221 tag_name: self.tag_name,
222222 listeners: self.listeners,
223223 attributes: self.attributes,
@@ -226,37 +226,25 @@ where
226226 }
227227 }
228228
229− /// Set whether this node has keyed children or not. The default
230− /// configuration is `false`.
229+ /// Set this element's key.
231230 ///
232− /// # Example
231+ /// When diffing sets of siblings, if an old sibling and new sibling share a
232+ /// key, then they will always reuse the same physical DOM node. This is
233+ /// important when using CSS animations, web components, third party JS, or
234+ /// anything else that makes the diffing implementation observable.
233235 ///
234− /// ```no_run
235− /// use dodrio::{builder::*, bumpalo::Bump};
236+ /// Do not use keys if such a scenario does not apply. Keyed diffing is
237+ /// generally more expensive than not, since it is putting greater
238+ /// constraints on the diffing algorithm.
236239 ///
237− /// let b = Bump::new();
240+ /// # Invariants You Must Uphold
238241 ///
239− /// // Create a `<ul>` with keyed children.
240− /// let my_ul = ul(&b)
241− /// .has_keyed_children(true)
242− /// .children(create_keyed_children())
243− /// .finish();
244− /// # fn create_keyed_children() -> [dodrio::Node<'static>; 0] { unimplemented!() }
245− /// ```
246− #[inline]
247− pub fn has_keyed_children(mut self, has_keyed_children: bool) -> Self {
248− if has_keyed_children {
249− self.flags |= ElementNodeFlags::HAS_KEYED_CHILDREN;
250− } else {
251− self.flags &= !ElementNodeFlags::HAS_KEYED_CHILDREN;
252− }
253− self
254− }
255−
256− /// Set this element's key. The key must be less than or equal to `2^31 -
257− /// 1`.
242+ /// The key may not be `u32::MAX`, which is a reserved key value.
243+ ///
244+ /// Keys must be unique among siblings.
258245 ///
259− /// This element's parent must have `has_keyed_children(true)` set.
246+ /// All sibling nodes must be keyed, or they must all not be keyed. You may
247+ /// not mix keyed and unkeyed siblings.
260248 ///
261249 /// # Example
262250 ///
@@ -271,8 +259,9 @@ where
271259 /// ```
272260 #[inline]
273261 pub fn key(mut self, key: u32) -> Self {
274− debug_assert_eq!(key & (!ElementNodeFlags::KEY_MASK).bits(), 0);
275− self.flags.set_key(key);
262+ use std::u32;
263+ debug_assert!(key != u32::MAX);
264+ self.key = NodeKey(key);
276265 self
277266 }
278267
@@ -295,7 +284,7 @@ where
295284 pub fn finish(self) -> Node<'a> {
296285 Node::element(
297286 self.bump,
298− self.flags,
287+ self.key,
299288 self.tag_name,
300289 self.listeners,
301290 self.attributes,