reconcile ranges of children
by mindplay
HTML
<ul id="foods"></ul>
<label><input type="radio" name="list" value="fruit" checked>Fruit</label>
<br>
<label><input type="radio" name="list" value="meat">Meat</label>
<br>
<button id="shuffle">Shuffle</button>
<button id="reverse">Reverse</button>
<br>
<button id="rotate-up">Rotate Up</button>
<button id="rotate-down">Rotate Down</button>
<br>
<button id="add-first">Add First</button>
<button id="add-last">Add Last</button>
<button id="add-random">Add Random</button>
<br>
<button id="delete-first">Delete First</button>
<button id="delete-last">Delete Last</button>
<button id="delete-random">Delete Random</button>
JavaScript
const fruit = "Pear|Apple|Cherry|Plum|Peach".split("|").map(newLI);
const meat = "Beef|Chicken|Lamb|Turkey|Fish".split("|").map(newLI);
let children = { fruit, meat };
let anchors = {
fruit: document.createComment("<end of fruit>"),
meat: document.createComment("<end of meat>")
}
let list = "fruit";
const parent = document.querySelector("#foods");
fruit.forEach(node => parent.appendChild(node));
parent.appendChild(anchors.fruit);
meat.forEach(node => parent.appendChild(node));
parent.appendChild(anchors.meat);
console.clear();
function newLI(text) {
let el = document.createElement("li");
el.innerText = text;
return el;
}
function shuffle(a) {
return a.map(n => [Math.random(), n]).sort().map(n => n[1]);
}
function rotate(arr, count) {
arr = arr.slice();
count -= arr.length * Math.floor(count / arr.length);
arr.push.apply(arr, arr.splice(0, count));
return arr;
}
const splice = (a,index,count,...items) => {
a = a.slice();
a.splice(index, count, ...items);
return a;
}
const reverse = a => {
a = a.slice();
return a.reverse();
};
let num = 1000;
const randomIndex = a => Math.floor((a.length-1) * Math.random());
const addFirst = a => [newLI(num++)].concat(...a);
const addLast = a => a.concat(newLI(num++));
const addRandom = a => splice(a, randomIndex(a), 0, newLI(num++));
const deleteFirst = a => splice(a, 0, 1);
const deleteLast = a => splice(a, a.length-1, 1);
const deleteRandom = a => splice(a, randomIndex(a), 1);
const update = fn => () => {
children[list] = diff(
parent,
children[list],
fn(children[list]),
anchors[list]
);
}
document.querySelectorAll("input[name=list]").forEach(input => {
input.addEventListener("input", () => { list = input.value })
});
document.querySelector("#shuffle").addEventListener("click", update(shuffle));
document.querySelector("#reverse").addEventListener("click", update(reverse));
document.querySelector("#rotate-up").addEventListener("click", update(a => rotate(a,...