<body style="background: auto; margin: 0px; padding: 0px"> <textarea id="texty" style="width: 100%; height: 100%; box-sizing: border-box" ></textarea> </body> <script src="https://braid.org/code/myers-diff1.js"></script> <script src="https://unpkg.com/braid-http@~1.3/braid-http-client.js"></script> <script src="/simpleton-client.js"></script> <script> let simpleton = simpleton_client(location.pathname, { apply_remote_update: ({ state, patches }) => { if (state !== undefined) texty.value = state; else apply_patches_and_update_selection(texty, patches); return texty.value; }, generate_local_diff_update: (prev_state) => { var patches = diff(prev_state, texty.value); if (patches.length === 0) return null; return { patches, new_state: texty.value }; }, on_error: (e) => { texty.disabled = true texty.style.background = '#fee' texty.style.border = '4px solid red' } }); texty.value = ""; texty.oninput = (e) => simpleton.changed(); function diff(before, after) { let diff = diff_main(before, after); let patches = []; let offset = 0; for (let d of diff) { let p = null; if (d[0] == 1) p = { range: [offset, offset], content: d[1] }; else if (d[0] == -1) { p = { range: [offset, offset + d[1].length], content: "" }; offset += d[1].length; } else offset += d[1].length; if (p) { p.unit = "text"; patches.push(p); } } return patches; } function apply_patches_and_update_selection(textarea, patches) { let offset = 0; for (let p of patches) { p.range[0] += offset; p.range[1] += offset; offset -= p.range[1] - p.range[0]; offset += p.content.length; } let original = textarea.value; let sel = [textarea.selectionStart, textarea.selectionEnd]; for (var p of patches) { let range = p.range; for (let i = 0; i < sel.length; i++) if (sel[i] > range[0]) if (sel[i] > range[1]) sel[i] -= range[1] - range[0]; else sel[i] = range[0]; for (let i = 0; i < sel.length; i++) if (sel[i] > range[0]) sel[i] += p.content.length; original = original.substring(0, range[0]) + p.content + original.substring(range[1]); } textarea.value = original; textarea.selectionStart = sel[0]; textarea.selectionEnd = sel[1]; } </script>