Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2021-01-23 19:32:53 +0300
committerJulius Härtl <jus@bitgrid.net>2021-01-26 10:34:18 +0300
commit7c7623222aeffdbf7ed2f513592d63b243f9dcbb (patch)
treecc100a49d65563ff83806f0e0fda28422590853e /src/extensions
parent886fd14249a02659b482b1aa6ba2b540bc9360e7 (diff)
Track authors by step rather than transaction
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'src/extensions')
-rw-r--r--src/extensions/UserColor.js14
-rw-r--r--src/extensions/tracking/TrackState.js59
-rw-r--r--src/extensions/tracking/models.js14
3 files changed, 27 insertions, 60 deletions
diff --git a/src/extensions/UserColor.js b/src/extensions/UserColor.js
index e3e4350c1..6ae68a0e6 100644
--- a/src/extensions/UserColor.js
+++ b/src/extensions/UserColor.js
@@ -60,20 +60,16 @@ export default class UserColor extends Extension {
let { tracked, decos } = instance
let tState = this.getState(oldState).tracked
if (tr.docChanged) {
+ if (!tr.getMeta('clientID')) {
+ // we have an undefined client id for own transactions
+ tr.setMeta('clientID', tr.steps.map(i => this.spec.clientID))
+ }
tracked = tracked.applyTransform(tr)
- const clientID = tr.getMeta('clientID') ? tr.getMeta('clientID') : this.spec.clientID
- tracked = tracked.applyCommit(clientID, new Date(tr.time), {
- clientID,
- color: this.spec.color(clientID),
- name: this.spec.name(clientID),
- })
tState = tracked
}
decos = tState.blameMap
- .filter(span => typeof tState.commits[span.commit]?.author?.color !== 'undefined')
.map(span => {
- const commit = tState.commits[span.commit]
- const clientID = commit.author.clientID
+ const clientID = span.author
return Decoration.inline(span.from, span.to, {
class: 'author-annotation',
style: 'background-color: ' + this.spec.color(clientID) + '66;',
diff --git a/src/extensions/tracking/TrackState.js b/src/extensions/tracking/TrackState.js
index 6a6d33d57..8193ecacb 100644
--- a/src/extensions/tracking/TrackState.js
+++ b/src/extensions/tracking/TrackState.js
@@ -20,32 +20,34 @@
*
*/
-import { Span, Commit } from './models'
+import { Span } from './models'
/*
* This code is heavily inspired by the change tracking example of prosemirror
* https://github.com/ProseMirror/website/blob/master/example/track/index.js
*/
-function updateBlameMap(map, transform, id) {
- const result = []; const mapping = transform.mapping
+function updateBlameMap(map, transform, clientIDs) {
+ const result = []
+ const mapping = transform.mapping
for (let i = 0; i < map.length; i++) {
const span = map[i]
- const from = mapping.map(span.from, 1); const to = mapping.map(span.to, -1)
- if (from < to) result.push(new Span(from, to, span.commit))
+ const from = mapping.map(span.from, 1)
+ const to = mapping.map(span.to, -1)
+ if (from < to) result.push(new Span(from, to, span.author))
}
for (let i = 0; i < mapping.maps.length; i++) {
const map = mapping.maps[i]; const after = mapping.slice(i + 1)
map.forEach((_s, _e, start, end) => {
- insertIntoBlameMap(result, after.map(start, 1), after.map(end, -1), id)
+ insertIntoBlameMap(result, after.map(start, 1), after.map(end, -1), clientIDs[i])
})
}
return result
}
-function insertIntoBlameMap(map, from, to, commit) {
+function insertIntoBlameMap(map, from, to, author) {
if (from >= to) {
return
}
@@ -53,11 +55,11 @@ function insertIntoBlameMap(map, from, to, commit) {
let next
for (; pos < map.length; pos++) {
next = map[pos]
- if (next.commit === commit) {
+ if (next.author === author) {
if (next.to >= from) break
- } else if (next.to > from) { // Different commit, not before
+ } else if (next.to > from) { // Different author, not before
if (next.from < from) { // Sticks out to the left (loop below will handle right side)
- const left = new Span(next.from, from, next.commit)
+ const left = new Span(next.from, from, next.author)
if (next.to > to) map.splice(pos++, 0, left)
else map[pos++] = left
}
@@ -67,7 +69,7 @@ function insertIntoBlameMap(map, from, to, commit) {
// eslint-ignore
while ((next = map[pos])) {
- if (next.commit === commit) {
+ if (next.author === author) {
if (next.from > to) break
from = Math.min(from, next.from)
to = Math.max(to, next.to)
@@ -75,7 +77,7 @@ function insertIntoBlameMap(map, from, to, commit) {
} else {
if (next.from >= to) break
if (next.to > to) {
- map[pos] = new Span(to, next.to, next.commit)
+ map[pos] = new Span(to, next.to, next.author)
break
} else {
map.splice(pos, 1)
@@ -83,45 +85,26 @@ function insertIntoBlameMap(map, from, to, commit) {
}
}
- map.splice(pos, 0, new Span(from, to, commit))
+ map.splice(pos, 0, new Span(from, to, author))
}
export default class TrackState {
- constructor(blameMap, commits, uncommittedSteps, uncommittedMaps) {
+ constructor(blameMap) {
// The blame map is a data structure that lists a sequence of
- // document ranges, along with the commit that inserted them. This
+ // document ranges, along with the author that inserted them. This
// can be used to, for example, highlight the part of the document
- // that was inserted by a commit.
+ // that was inserted by a author.
this.blameMap = blameMap
- // The commit history, as an array of objects.
- this.commits = commits
- // Inverted steps and their maps corresponding to the changes that
- // have been made since the last commit.
- this.uncommittedSteps = uncommittedSteps
- this.uncommittedMaps = uncommittedMaps
}
// Apply a transform to this state
applyTransform(transform) {
- // Invert the steps in the transaction, to be able to save them in
- // the next commit
- const inverted
- = transform.steps.map((step, i) => step.invert(transform.docs[i]))
- const newBlame = updateBlameMap(this.blameMap, transform, this.commits.length)
+ const clientID = transform.getMeta('clientID') ?? transform.steps.map(item => 'self')
+ const newBlame = updateBlameMap(this.blameMap, transform, clientID)
// Create a new state—since these are part of the editor state, a
// persistent data structure, they must not be mutated.
- return new TrackState(newBlame, this.commits,
- this.uncommittedSteps.concat(inverted),
- this.uncommittedMaps.concat(transform.mapping.maps))
- }
-
- // When a transaction is marked as a commit, this is used to put any
- // uncommitted steps into a new commit.
- applyCommit(message, time, author) {
- if (this.uncommittedSteps.length === 0) return this
- const commit = new Commit(message, time, this.uncommittedSteps, this.uncommittedMaps, author)
- return new TrackState(this.blameMap, this.commits.concat(commit), [], [])
+ return new TrackState(newBlame)
}
}
diff --git a/src/extensions/tracking/models.js b/src/extensions/tracking/models.js
index fbcacdb65..1c628f780 100644
--- a/src/extensions/tracking/models.js
+++ b/src/extensions/tracking/models.js
@@ -22,21 +22,9 @@
export class Span {
- constructor(from, to, commit) {
+ constructor(from, to, author) {
this.from = from
this.to = to
- this.commit = commit
- }
-
-}
-
-export class Commit {
-
- constructor(message, time, steps, maps, author) {
- this.message = message
- this.time = time
- this.steps = steps
- this.maps = maps
this.author = author
}