slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
43.59k stars 3.39k forks source link

The given range isn't in document. #1134

Closed fabienbranchel closed 7 years ago

fabienbranchel commented 7 years ago

I have a text in my Quill editor. I call setText (or deleteText) when clicking on a delete button, no problem. If I call setText (or deleteText) in the "text-change" callback , there is this error in console : "The given range isn't in document."

Steps for Reproduction

  1. Visit https://codepen.io/fabienpopup/pen/JbJQZv?editors=1010
  2. Click on the delete button, no error in console
  3. Re-run the Codepen
  4. Add a characters like "a" in Quill editor.
  5. Look your console, you can see the error

I expect no error in console for this operation.

Quill 1.1.5 Mac OSX 10.11.5 Chrome Version 54.0.2840.98

In Quill 1.0.6, we can reproduce the same error, but to do that, we need to have a break line in the text.

jhchen commented 7 years ago

The issue is text is being changed in a text-change handler. This pattern in general should be avoided (not just in Quill) but even so Quill tries to handle this but it appears Chrome does not respect the try catch block: https://jsfiddle.net/scwp779y/1/. There is no issue in other browsers and looking at similar bugs in Chromium, it does not appear they are amenable to suppressing the error.

I would suggest just avoiding triggering text-change in the handler for text-change. You can do this by wrapping your setText call in a _.defer or setTimeout.

R4DIC4L commented 7 years ago

Just noticed that this issue appears when first entering a character in the editor because of the following line of code in the setNativeRange function (which seems to be in quill.js): selection.addRange(range);

This seems to usually happen every time a character is entered for the first time.

GoranGjorgievski commented 6 years ago

@R4DIC4L Did you manage to get around this issue? I am having the same problem and it seems to be cutting the first N characters of a bigger string, but only the first time you try to edit, as you described.

R4DIC4L commented 6 years ago

@GoranGjorgievski No, unfortunately I have not found any solution. I have been trying to diagnose this issue, but couldn't find out why the addRange method throws this error. Furthermore, this error cannot be caught in a try-catch block ... I actually ended up using another editor for my application.

rbrugnollo commented 6 years ago

@GoranGjorgievski No, unfortunately I have not found any solution. I have been trying to diagnose this issue, but couldn't find out why the addRange method throws this error. Furthermore, this error cannot be caught in a try-catch block ... I actually ended up using another editor for my application.

which editor did you choose? I've been having this problem and can't find a solution either.

R4DIC4L commented 6 years ago

@GoranGjorgievski No, unfortunately I have not found any solution. I have been trying to diagnose this issue, but couldn't find out why the addRange method throws this error. Furthermore, this error cannot be caught in a try-catch block ... I actually ended up using another editor for my application.

which editor did you choose? I've been having this problem and can't find a solution either.

I actually ended using draft.js, or more specifically, a React implementation of it (react-draft-wysiwyg).

tenadolanter commented 5 years ago

i met the same question when i execute quill.setText(""). The reason is this func will remove instantiation of the eidtor

renaudtertrais commented 5 years ago

I had the same issue using react-quill. Issue was caused by changing the value in the handler (removing extra <p><br></p>). I solved it by creating a local state updated when value changed:

function MyEditor({ value, onChange }){
 const [state, setState] = useState({ value });

  useEffect(() => {
    if (state.value !== value) setState({ value });
  }, [value]);

  return (
     <Editor
        value={state.rawValue || state.value || ''}
        onChange={rawValue => {
          const cleanedValue = rawValue.replace(/<p><br><\/p>/g, '');
          setState({ rawValue, value: cleanedValue });
          onChange(cleanedValue);
        }}
    />
  );
}
nithisathish commented 5 years ago

Fixed it in Angular 7 by adding below code. @ViewChild('editor') editor: Editor; setTimeout(() => { this.editor.writeValue(data); this.editor.quill.setSelection(null, data.length, null); }, 100);

awdyson commented 4 years ago

For my particular use case, the solution was converting an HTML string to a delta and then using setContents instead of using dangerouslyPasteHTML or setting the innerHTML of the editor.

const delta = this.clipboard.convert(html);
return this.setContents(delta);
IanVS commented 4 years ago

In case it might help anyone else, I was experiencing this bug as well, and was able to fix it by removing an extra setState in my change handler. I was tracking dirty state with a simple flag, calling a method to toggle it, and then calling a different method to change the editor value state. Once I removed the dirty tracking, the error and focus loss stopped.

maimai123 commented 4 years ago

天啦撸! 遇到了换行光标不移动的问题 加个setTimeout就好咯