Skip to content

Commit 26517d5

Browse files
CopilotL3P3
andcommitted
Add debug assertion enforcing hook_dom in node_map and simplify reordering code
Co-authored-by: L3P3 <4629449+L3P3@users.noreply.github.com>
1 parent fc085b9 commit 26517d5

File tree

2 files changed

+10
-60
lines changed

2 files changed

+10
-60
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ The component you pass to `node_map` gets mounted for each item of the array you
121121
> [!IMPORTANT]
122122
> Allowed array items are numbers, strings and objects. If you pass objects, they must have an unique `id` property. There must not be two items of the same value or id.
123123
124+
> [!IMPORTANT]
125+
> Components used with `node_map` must use `hook_dom` to define their root element. This is required for efficient reordering of list items.
126+
124127
### DOM components
125128

126129
The leaves of your component tree are mostly made out of native dom elements. To use such a component, use `node_dom` instead of `node`. The signature is the same, except for the first argument being a descriptor, similar to css selectors: `tagName[attr1=value][attr2][...]`

src/lui.js

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -976,21 +976,22 @@ const instance_render = (dom_parent, dom_first) => {
976976
dom_first
977977
);
978978

979+
DEBUG &&
980+
!child.dom &&
981+
error('node_map item component must use hook_dom');
982+
979983
child.dom &&
980984
dom_parent.insertBefore(
981985
child.dom_first = child.dom,
982986
dom_first
983987
);
984988
}
985989
else {
986-
// TODO this algorithm still sucks
987-
const dom_last = instance_dom_last_get(child);
988990
if (
989-
dom_last &&
990-
dom_last.nextSibling !== dom_first
991+
child.dom.nextSibling !== dom_first
991992
) {
992-
VERBOSE && log('instance_reinsert ' + key);
993-
instance_reinsert(child, dom_parent, dom_first);
993+
VERBOSE && log('item reinsert ' + key);
994+
dom_parent.insertBefore(child.dom, dom_first);
994995
}
995996

996997
if (
@@ -1181,60 +1182,6 @@ const list_data_index = (list_data, items_map, items_order) => {
11811182
return items_objects;
11821183
}
11831184

1184-
/**
1185-
gets last node of an instance (only an ugly workaround!)
1186-
@param {TYPE_INSTANCE} instance
1187-
@return {?HTMLElement}
1188-
*/
1189-
const instance_dom_last_get = instance => {
1190-
if (instance.dom) return instance.dom;
1191-
let instance_childs;
1192-
let i = (
1193-
(instance_childs = instance.childs)
1194-
? instance_childs.length
1195-
: 0
1196-
);
1197-
let itm, itm_dom;
1198-
while (i > 0) {
1199-
if (
1200-
(
1201-
itm_dom = instance_childs[--i]
1202-
) &&
1203-
(
1204-
itm = instance_dom_last_get(itm_dom)
1205-
)
1206-
) return itm;
1207-
}
1208-
return null_;
1209-
};
1210-
1211-
/**
1212-
reinsert all dom nodes of an instance
1213-
@param {TYPE_INSTANCE} instance
1214-
@param {HTMLElement} dom_parent
1215-
@param {?HTMLElement} dom_first
1216-
@return {?HTMLElement}
1217-
*/
1218-
const instance_reinsert = (instance, dom_parent, dom_first) => {
1219-
if (instance.dom) {
1220-
return /** @type {HTMLElement} */ (dom_parent.insertBefore(instance.dom, dom_first));
1221-
}
1222-
if (instance.dom_first) {
1223-
let childs_index = instance.childs.length;
1224-
do {
1225-
instance.childs[--childs_index] && (
1226-
dom_first = instance_reinsert(
1227-
instance.childs[childs_index],
1228-
dom_parent,
1229-
dom_first
1230-
)
1231-
);
1232-
}
1233-
while (childs_index > 0);
1234-
}
1235-
return dom_first;
1236-
}
1237-
12381185
/**
12391186
return instance for slots
12401187
@param {TYPE_SLOTS} slots

0 commit comments

Comments
 (0)