Koala
Koala

Reputation: 78

React Quill - How do I show the differences between two text versions?

I'm currently designing a website with React where the user will work with a text editor. The text editor will already have text in it. The user will make some changes to the text and submit it. I would like to add a button that will show the user the differences between the original text and his new text, like Git but down to individual characters.

I'm currently trying to use Quill for that. I've found a lovely solution to my problem, but it's written in plain JavaScript. I've tried translating it to React by setting the Quill objects in the state:

  const [quill_old, set_quill_old] = React.useState(new Quill('#old', {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        ['image', 'code-block']
      ]
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'  // or 'bubble'
  }))
  const [quill_new, set_quill_new] = React.useState(new Quill('#new', {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        ['image', 'code-block']
      ]
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'  // or 'bubble'
  }))
  const [quill_diff, set_quill_diff] = React.useState(new Quill('#diff', {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        ['image', 'code-block']
      ]
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'  // or 'bubble'
  }))

but when initializing the code it gets stuck on the "findDiff" function, on this line:

var oldContent = quill_old.getContents();

and returns an error: TypeError: Cannot read property 'length' of undefined

Where "undefined" is "quill_old".

When trying to run the page without the function, the page shows properly, but I get multiple errors in the console like this: quill Invalid Quill container #old

Does somebody know how to properly implement this solution in React? Or has a suggestion on some other library I can use?


Thank you for your time

Upvotes: 1

Views: 739

Answers (1)

Mohit Goyal
Mohit Goyal

Reputation: 1

I have found this Snippet that shows the difference (addition/deletion of texts in quill).

var quill_old = new Quill('#old', {
  modules: {
    toolbar: [
      [{ header: [1, 2, false] }],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
  },
  placeholder: 'Compose an epic...',
  theme: 'snow'  // or 'bubble'
});
var quill_new = new Quill('#new', {
  modules: {
    toolbar: [
      [{ header: [1, 2, false] }],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
  },
  placeholder: 'Compose an epic...',
  theme: 'snow'  // or 'bubble'
});
var quill_diff = new Quill('#diff', {
  modules: {
    toolbar: [
      [{ header: [1, 2, false] }],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
  },
  placeholder: 'Compose an epic...',
  theme: 'snow'  // or 'bubble'
});

function findDiff() {
  var oldContent = quill_old.getContents();
  var newContent = quill_new.getContents();
  var diff = oldContent.diff(newContent);
  // console.log('old', oldContent);
  // console.log('new', newContent);
  for (var i = 0; i < diff.ops.length; i++) {
    var op = diff.ops[i];
    // if the change was an insertion
    if (op.hasOwnProperty('insert')) {
      // color it green
      op.attributes = {
        background: "#cce8cc",
        color: "#003700"
      };
    }
    // if the change was a deletion 
    if (op.hasOwnProperty('delete')) {
      // keep the text
      op.retain = op.delete;
      delete op.delete;
      // but color it red and struckthrough
      op.attributes = {
        background: "#e8cccc",
        color: "#370000",
        strike: true
      };
    }
  }
  // console.log('diff', diff);
  var adjusted = oldContent.compose(diff);
  // console.log('adjusted', adjusted);
  
  // profit!
  quill_diff.setContents(adjusted);
}

REF: https://codepen.io/percipient24/pen/eEBOjG

Upvotes: 0

Related Questions