@@ -1,6 +1,6 @@
1//! Helpers for building virtual DOM nodes.
1//! Helpers for building virtual DOM nodes.
3−use crate::{node::ElementNodeFlags, Attribute, Listener, Node, RootRender, VdomWeak};
3+use crate::{node::NodeKey, Attribute, Listener, Node, RootRender, VdomWeak};
4use bumpalo::Bump;
4use bumpalo::Bump;
6/// A virtual DOM element builder.
6/// A virtual DOM element builder.
@@ -16,7 +16,7 @@ where
16 Children: 'a + AsRef<[Node<'a>]>,
16 Children: 'a + AsRef<[Node<'a>]>,
18 bump: &'a Bump,
18 bump: &'a Bump,
19− flags: ElementNodeFlags,
19+ key: NodeKey,
20 tag_name: &'a str,
20 tag_name: &'a str,
21 listeners: Listeners,
21 listeners: Listeners,
22 attributes: Attributes,
22 attributes: Attributes,
@@ -62,7 +62,7 @@ impl<'a>
62 let bump = bump.into();
62 let bump = bump.into();
63 ElementBuilder {
63 ElementBuilder {
65− flags: Default::default(),
65+ key: NodeKey::NONE,
67 listeners: bumpalo::collections::Vec::new_in(bump),
67 listeners: bumpalo::collections::Vec::new_in(bump),
68 attributes: bumpalo::collections::Vec::new_in(bump),
68 attributes: bumpalo::collections::Vec::new_in(bump),
@@ -112,7 +112,7 @@ where
113 ElementBuilder {
113 ElementBuilder {
114 bump: self.bump,
114 bump: self.bump,
115− flags: self.flags,
115+ key: self.key,
116 tag_name: self.tag_name,
116 tag_name: self.tag_name,
117 listeners,
117 listeners,
118 attributes: self.attributes,
118 attributes: self.attributes,
@@ -151,7 +151,7 @@ where
152 ElementBuilder {
152 ElementBuilder {
153 bump: self.bump,
153 bump: self.bump,
154− flags: self.flags,
154+ key: self.key,
155 tag_name: self.tag_name,
155 tag_name: self.tag_name,
156 listeners: self.listeners,
156 listeners: self.listeners,
157 attributes,
157 attributes,
@@ -190,7 +190,7 @@ where
191 ElementBuilder {
191 ElementBuilder {
192 bump: self.bump,
192 bump: self.bump,
193− flags: self.flags,
193+ key: self.key,
194 tag_name: self.tag_name,
194 tag_name: self.tag_name,
195 listeners: self.listeners,
195 listeners: self.listeners,
196 attributes: self.attributes,
196 attributes: self.attributes,
@@ -217,7 +217,7 @@ where
217 pub fn namespace(self, namespace: Option<&'a str>) -> Self {
217 pub fn namespace(self, namespace: Option<&'a str>) -> Self {
218 ElementBuilder {
218 ElementBuilder {
219 bump: self.bump,
219 bump: self.bump,
220− flags: self.flags,
220+ key: self.key,
221 tag_name: self.tag_name,
221 tag_name: self.tag_name,
222 listeners: self.listeners,
222 listeners: self.listeners,
223 attributes: self.attributes,
223 attributes: self.attributes,
@@ -226,37 +226,25 @@ where
229− /// Set whether this node has keyed children or not. The default
229+ /// Set this element's key.
230− /// configuration is `false`.
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.
234− /// ```no_run
236+ /// Do not use keys if such a scenario does not apply. Keyed diffing is
235− /// use dodrio::{builder::*, bumpalo::Bump};
237+ /// generally more expensive than not, since it is putting greater
238+ /// constraints on the diffing algorithm.
237− /// let b = Bump::new();
240+ /// # Invariants You Must Uphold
239− /// // Create a `<ul>` with keyed children.
242+ /// The key may not be `u32::MAX`, which is a reserved key value.
240− /// let my_ul = ul(&b)
243+ ///
241− /// .has_keyed_children(true)
244+ /// Keys must be unique among siblings.
242− /// .children(create_keyed_children())
244− /// # fn create_keyed_children() -> [dodrio::Node<'static>; 0] { unimplemented!() }
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;
251− self.flags &= !ElementNodeFlags::HAS_KEYED_CHILDREN;
256− /// Set this element's key. The key must be less than or equal to `2^31 -
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.
261 /// # Example
249 /// # Example
@@ -271,8 +259,9 @@ where
272 #[inline]
260 #[inline]
273 pub fn key(mut self, key: u32) -> Self {
261 pub fn key(mut self, key: u32) -> Self {
274− debug_assert_eq!(key & (!ElementNodeFlags::KEY_MASK).bits(), 0);
262+ use std::u32;
275− self.flags.set_key(key);
263+ debug_assert!(key != u32::MAX);
264+ self.key = NodeKey(key);
@@ -295,7 +284,7 @@ where
295 pub fn finish(self) -> Node<'a> {
284 pub fn finish(self) -> Node<'a> {
296 Node::element(
285 Node::element(
297 self.bump,
286 self.bump,
298− self.flags,
287+ self.key,
299 self.tag_name,
288 self.tag_name,
300 self.listeners,
289 self.listeners,
301 self.attributes,
290 self.attributes,