dubdiff/src/common/util/EditorsDiff.js

64 lines
1.6 KiB
JavaScript

import {Diff} from 'diff'
// EditorsDiff is a custom Diff implementation from the jsdiff library
// It allows diffing by phrases. Whitespace is ignored for the purpose of comparison,
// but is preserved and included in the output.
const TOKEN_BOUNDARYS = /([\s,.:])/
class EditorsDiff extends Diff {
constructor (tokenBoundaries=TOKEN_BOUNDARYS) {
super()
this.tokenBoundaries = tokenBoundaries
}
equals (left, right) {
return (
left.string == right.string
)
}
//splits the input string into a series of word and punctuation tokens
//each token is associated with an optional trailing array of spaces
tokenize (value) {
let tokens = value.split(this.tokenBoundaries)
let annotatedTokens = []
tokens.forEach( token => {
if (isSpace(token)) {
if (annotatedTokens.length == 0)
annotatedTokens.push({string:'', whitespace:[]})
let last = annotatedTokens[annotatedTokens.length-1]
last.whitespace.push(token)
}
else {
annotatedTokens.push({string:token, whitespace:[]})
}
})
//this final empty token is necessary for the jsdiff diffing engine to work properly
annotatedTokens.push({string:'', whitespace:[]})
return annotatedTokens
}
join(annotatedTokens) {
let tokens = []
annotatedTokens.forEach(annotatedToken => {
tokens.push(annotatedToken.string)
annotatedToken.whitespace.forEach(item => {
tokens.push(item)
})
})
return tokens.join('')
}
}
export default EditorsDiff
const isSpace = str => /[ ]+/.test(str)
const isNewline = str => /[\n]+/.test(str)