pad

minimal etherpad alternative  https://pad.ce9e.org
git clone https://git.ce9e.org/pad.git

commit
f25a4060c9a12a9de367bf0e24d1286a0e44ad10
parent
5117d0cc791d8e461bd4d8d322b80c121833abe6
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-11-17 12:40
protocol: more robust reset behavior

Typically, clients receive optimized messages as the first message when
connecting. In those cases, the client always starts with an empty
textarea and a change of the form `[0, 0, "", text]` applies cleanly.

However, it might be possible that clients receive optimized messages on
reconnect. In those cases, the optimized content is simply prepended,
basically duplicating everything.

Usually, the client is supposed to deactivate when it goes offline.
However, there might be cases where this is not triggered when the
computer is suspended. I was not yet able to reproduce this reliably
though.

The solution is to always reset the complete text on optimized messages.
I integrated this into `diff.apply()` to keep as much merge behavior as
possible.

An alternative approach would be to have a separate message type that
could distinguish resets from initial content. The current approach will
also take effect if two people start writing to an empty document at
the same time. I think this tradeoff is worth it.

Diffstat

M static/diff.js 5 +++++

1 files changed, 5 insertions, 0 deletions


diff --git a/static/diff.js b/static/diff.js

@@ -12,6 +12,11 @@ var _apply = function(text, [pos, before, after], selection) {
   12    12 };
   13    13 
   14    14 export var apply = function(text, [start, end, before, after], selection) {
   -1    15 	// special handling for resets
   -1    16 	if (start === 0 && end === 0 && before === '' && text !== '') {
   -1    17 		[start, end, before, after] = diff(text, after, 3);
   -1    18 	}
   -1    19 
   15    20 	// try exact match
   16    21 	if (text.slice(start).startsWith(before)) {
   17    22 		return _apply(text, [start, before, after], selection);