Re: [whatwg/dom] Add convenient, ergonomic, performant API for sorting siblings (#586)

@chrishtr it's worth mentioning that abusing the API already allows diffing (at least per elements, not per mixed elements and text nodes (or comments) ... example:

```js
const diff = (parent, prev, curr) => {
  const {length: plength} = prev;
  const {length: clength} = curr;
  const childs = [];
  let i = 0, length = i;
  // order old nodes after
  while (i < plength)
    prev[i++].dataset.order = (clength + i);
  i = 0;
  // order new nodes before
  while (i < clength) {
    const child = curr[i++];
    child.dataset.order = i;
    if (child.parentNode !== parent)
      length = childs.push(child);
  }
  if (childs.length)
    parent.append(...childs);
  // reorder all by attribute
  parent.reorderChildren('data-order');
  // drop nodes still there
  length += plength;
  if (i < length) {
    const {children} = parent;
    const range = new Range;
    range.setStartBefore(children[i]);
    range.setEndAfter(children[length - 1]);
    range.deleteContents();
  }
  return curr;
};
```

Assuming for now the polyfill would be like:
```js
Element.prototype.reorderChildren = function (attributeName) {
  this.replaceChildren(
    ...[...this.children].sort(
      (a, b) => (
        parseInt(a.getAttribute(attributeName)) -
        parseInt(b.getAttribute(attributeName))
      )
    )
  );
};
```

Given the following operations would move, insert once, and drop all at once on every needed situation:
```js

document.body.innerHTML = `<ul><li>a</li><li>b</li><li>c</li></ul>`;
const ul = document.body.firstElementChild;
let children = [...ul.children];
// nothing happens
children = diff(ul, children, children);

// a swaps with c
children = diff(ul, children, [children[2], children[1], children[0]]);

let li = document.createElement('li');
li.textContent = 'd';
// result into c, b, a, d
children = diff(ul, children, children.concat(li));

// b, a remain
children = diff(ul, children, [children[1], children[2]]);

// d, b
children = diff(ul, children, [li, children[0]]);

// z
children = diff(ul, children, [document.createElement('li')]);
children[0].textContent = 'z';
```

After all this already helps diffing nodes in a *keyed* like way so maybe it's OK to have at least this helper and be creative around its full potentials.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/586#issuecomment-1420550548
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/586/1420550548@github.com>

Received on Tuesday, 7 February 2023 10:34:05 UTC