var versions = [ "Version control is a tool for understanding how ideas evolve over time - a record of the imperfect nature of our effort.", "Version control is a tool for understanding how ideas evolve over time - a record of the imperfect nature of human effort that is an expression of the human desire towards understanding.", "Version control is a tool for understanding how ideas evolve over time - a record of the nature of human effort that is simultaneously an expression of the human desire towards excellence and understanding.", "Version control is software about working, and it is a tool made for understanding how ideas evolve over time, how mistakes are made and fixed. It's a record of the imperfect nature of human effort that is simultaneously an expression of the human desire towards greater excellence and understanding.", "Version control is software about working, and it is a tool for understanding how ideas evolve over time, how mistakes are made and fixed. It is a record of the imperfect nature of human effort that is simultaneously an expression of the human desire towards excellence and understanding.", ] var diffsChar = [] var diffsWord = [] var patchDiffs = [] versions.forEach(function(v, i){ var p = i ? versions[i-1] : '' diffsChar.push(JsDiff.diffChars(p, v)) diffsWord.push(JsDiff.diffWords(p, v)) // diff_main() }) d3.select('#commit').on('click', addVersion) function render(){ d3.select('#char-diff').dataAppend(diffsChar, 'div.commit') .dataAppend(ƒ(), 'span') .text(ƒ('value')) .classed('added', ƒ('added')) .classed('removed', ƒ('removed')) d3.select('#word-diff').dataAppend(diffsWord, 'div.commit') .dataAppend(ƒ(), 'span') .text(ƒ('value')) .classed('added', ƒ('added')) .classed('removed', ƒ('removed')) d3.select('#editable').text(_.last(versions)) } render() function addVersion(){ var prev = _.last(versions) var text = d3.select('#editable').text() versions.push(text) diffsChar.push(JsDiff.diffChars(prev, text)) diffsWord.push(JsDiff.diffWords(prev, text)) render() } function diffToChars(diff){ var rv = [] diff.forEach(function(obj){ obj.value.split('').forEach(function(chr){ rv.push({value: chr, added: obj.added, removed: obj.removed, obj: obj}) }) }) return rv } function updateFalling(curDiffIndex){ var charDifs = diffToChars(diffsWord[curDiffIndex]) // .filter(function(d){ return !d.removed && !d.added }) d3.selectAll('#falling .falling').remove() d3.select('#falling').dataAppend(charDifs, 'span.falling') .text(ƒ('value')) .style('width', function(d){ return d.added ? '0.0px' : '7.8px' }) .style('top', function(d){ return d.added ? '-200px' : '0px' }) .transition().duration(0).delay(500) .style('color', function(d){ return d.added ? 'green' : d.removed ? 'red' : '' }) .transition().duration(2000).delay(1000) .style('width', function(d){ return d.removed ? '0.0px' : '7.8px' }) .style('top', function(d){ return d.removed ? '200px' : '0px' }) window.setTimeout(function(){ updateFalling(++curDiffIndex % diffsWord.length) }, 3500) } updateFalling(0) // d3.select('#width-calc').dataAppend(diffsWord, 'div') // // .style('position', 'absolute') // // .style('top', '-2000px') // .style('margin-top', '10px') // .dataAppend(ƒ(), 'span') // .style('border', '1px solid black') // .style('padding-right', '.5em') // .text(ƒ('value')) // .each(function(d){ // d.width = this.getBoundingClientRect().width // d.width = d.width + 8 + 'px' // }) function diffToWords(diff){ var rv = [] diff.forEach(function(obj, i){ obj.value.split(' ').forEach(function(chr, j, array){ var lastChar = ' ' var nextChar = diff[i + 1] && diff[i + 1].value[0] if (j >= array.length - 1 && nextChar){ lastChar = nextChar == '.' || nextChar == '-' || nextChar == ',' ? '' : ' ' } rv.push({ value: chr + lastChar, added: obj.added, removed: obj.removed, width: obj.width, obj: obj }) }) }) d3.select('#width-calc').append('div') .style('width', '100000px') // .style('position', 'absolute') // .style('top', '-2000px') .style('margin-top', '10px') .dataAppend(rv, 'div').append('span') // .style('padding-right', '.01em') // .style('border', '1px solid black') .text(ƒ('value')) .each(function(d){ d.width = this.getBoundingClientRect().width d.width = d.width + (_.last(d.value) == ' ' ? 4 : 0) + 'px' }) return rv } function updateFallingV(curDiffIndex){ var wordDiffs = diffToWords(diffsWord[curDiffIndex]) d3.selectAll('#falling-v .falling').remove() d3.select('#falling-v ').dataAppend(wordDiffs, 'span.falling') .text(ƒ('value')) .style('width', function(d){ return d.added ? '0.0px' : d.width }) .style('top', function(d){ return d.added ? '-200px' : '0px' }) .transition().duration(0).delay(500) .style('color', function(d){ return d.added ? 'green' : d.removed ? 'red' : '' }) .transition().duration(2000).delay(1000) .style('width', function(d){ return d.removed ? '0.0px' : d.width }) .style('top', function(d){ return d.removed ? '200px' : '0px' }) // debugger window.setTimeout(function(){ updateFallingV(++curDiffIndex % diffsWord.length) }, 3500) } updateFallingV(1)