-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheditor.html
84 lines (75 loc) · 2.41 KB
/
editor.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<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>