mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-20 23:46:14 -04:00
Pad: Don't create no-op revisions
This commit is contained in:
parent
56b7671422
commit
a370cfa5c6
6 changed files with 18 additions and 12 deletions
|
@ -82,6 +82,9 @@ Pad.prototype.appendRevision = async function (aChangeset, author) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAText = Changeset.applyToAText(aChangeset, this.atext, this.pool);
|
const newAText = Changeset.applyToAText(aChangeset, this.atext, this.pool);
|
||||||
|
if (newAText.text === this.atext.text && newAText.attribs === this.atext.attribs) {
|
||||||
|
return this.head;
|
||||||
|
}
|
||||||
Changeset.copyAText(newAText, this.atext);
|
Changeset.copyAText(newAText, this.atext);
|
||||||
|
|
||||||
const newRev = ++this.head;
|
const newRev = ++this.head;
|
||||||
|
@ -268,8 +271,7 @@ Pad.prototype.setText = async function (newText) {
|
||||||
changeset = Changeset.makeSplice(oldText, 0, oldText.length - 1, newText);
|
changeset = Changeset.makeSplice(oldText, 0, oldText.length - 1, newText);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append the changeset
|
await this.appendRevision(changeset);
|
||||||
if (newText !== oldText) await this.appendRevision(changeset);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Pad.prototype.appendText = async function (newText) {
|
Pad.prototype.appendText = async function (newText) {
|
||||||
|
|
|
@ -640,7 +640,9 @@ const handleUserChanges = async (socket, message) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const newRev = await pad.appendRevision(rebasedChangeset, thisSession.author);
|
const newRev = await pad.appendRevision(rebasedChangeset, thisSession.author);
|
||||||
assert.equal(newRev, r + 1);
|
// The head revision will either stay the same or increase by 1 depending on whether the
|
||||||
|
// changeset has a net effect.
|
||||||
|
assert([r, r + 1].includes(newRev));
|
||||||
|
|
||||||
const correctionChangeset = _correctMarkersInPad(pad.atext, pad.pool);
|
const correctionChangeset = _correctMarkersInPad(pad.atext, pad.pool);
|
||||||
if (correctionChangeset) {
|
if (correctionChangeset) {
|
||||||
|
@ -658,7 +660,7 @@ const handleUserChanges = async (socket, message) => {
|
||||||
assert.equal(thisSession.rev, r);
|
assert.equal(thisSession.rev, r);
|
||||||
socket.json.send({type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev}});
|
socket.json.send({type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev}});
|
||||||
thisSession.rev = newRev;
|
thisSession.rev = newRev;
|
||||||
thisSession.time = await pad.getRevisionDate(newRev);
|
if (newRev !== r) thisSession.time = await pad.getRevisionDate(newRev);
|
||||||
await exports.updatePadClients(pad);
|
await exports.updatePadClients(pad);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
socket.json.send({disconnect: 'badChangeset'});
|
socket.json.send({disconnect: 'badChangeset'});
|
||||||
|
|
|
@ -85,5 +85,5 @@ exports.setPadHTML = async (pad, html) => {
|
||||||
|
|
||||||
apiLogger.debug(`The changeset: ${theChangeset}`);
|
apiLogger.debug(`The changeset: ${theChangeset}`);
|
||||||
await pad.setText('\n');
|
await pad.setText('\n');
|
||||||
if (!Changeset.isIdentity(theChangeset)) await pad.appendRevision(theChangeset);
|
await pad.appendRevision(theChangeset);
|
||||||
};
|
};
|
||||||
|
|
|
@ -207,8 +207,10 @@ const getCollabClient = (ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
});
|
});
|
||||||
} else if (msg.type === 'ACCEPT_COMMIT') {
|
} else if (msg.type === 'ACCEPT_COMMIT') {
|
||||||
serverMessageTaskQueue.enqueue(() => {
|
serverMessageTaskQueue.enqueue(() => {
|
||||||
const newRev = msg.newRev;
|
const {newRev} = msg;
|
||||||
if (newRev !== (rev + 1)) {
|
// newRev will equal rev if the changeset has no net effect (identity changeset, or removing
|
||||||
|
// and re-adding the same characters with the same attributes).
|
||||||
|
if (![rev, rev + 1].includes(newRev)) {
|
||||||
window.console.warn(`bad message revision on ACCEPT_COMMIT: ${newRev} not ${rev + 1}`);
|
window.console.warn(`bad message revision on ACCEPT_COMMIT: ${newRev} not ${rev + 1}`);
|
||||||
// setChannelState("DISCONNECTED", "badmessage_acceptcommit");
|
// setChannelState("DISCONNECTED", "badmessage_acceptcommit");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -278,7 +278,7 @@ describe(__filename, function () {
|
||||||
const res = await agent.post(endPoint('setText'))
|
const res = await agent.post(endPoint('setText'))
|
||||||
.send({
|
.send({
|
||||||
padID: testPadId,
|
padID: testPadId,
|
||||||
text: 'testTextTwo',
|
text: 'testTextThree',
|
||||||
})
|
})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/);
|
.expect('Content-Type', /json/);
|
||||||
|
|
|
@ -84,19 +84,19 @@ describe(__filename, function () {
|
||||||
assert.equal(pad.text(), 'hello\n');
|
assert.equal(pad.text(), 'hello\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('identity changeset is accepted', async function () {
|
it('identity changeset is accepted, has no effect', async function () {
|
||||||
sendUserChanges('Z:1>5+5$hello');
|
sendUserChanges('Z:1>5+5$hello');
|
||||||
await assertAccepted(rev + 1);
|
await assertAccepted(rev + 1);
|
||||||
sendUserChanges('Z:6>0$');
|
sendUserChanges('Z:6>0$');
|
||||||
await assertAccepted(rev + 1);
|
await assertAccepted(rev);
|
||||||
assert.equal(pad.text(), 'hello\n');
|
assert.equal(pad.text(), 'hello\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('non-identity changeset with no net change is accepted', async function () {
|
it('non-identity changeset with no net change is accepted, has no effect', async function () {
|
||||||
sendUserChanges('Z:1>5+5$hello');
|
sendUserChanges('Z:1>5+5$hello');
|
||||||
await assertAccepted(rev + 1);
|
await assertAccepted(rev + 1);
|
||||||
sendUserChanges('Z:6>0-5+5$hello');
|
sendUserChanges('Z:6>0-5+5$hello');
|
||||||
await assertAccepted(rev + 1);
|
await assertAccepted(rev);
|
||||||
assert.equal(pad.text(), 'hello\n');
|
assert.equal(pad.text(), 'hello\n');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue