Support pasting html from IE, Edge, and Safari#21
Support pasting html from IE, Edge, and Safari#21intentionally-left-nil merged 18 commits into0.10-textiofrom
Conversation
This is currently a hacky solution because of the way it requires calling addEventListener to grab the paste event. Besides that unfortunate behavior, however, the codeflow seems to work pretty well!
| // the contentEditable div. So, e in this case comes from a direct editor.addEventListener | ||
| // Therefore, we need to replicate anything that the SyntheticClipboardEvent does that is used | ||
| // Currently, that is only getting the clipboard, which involves falling back to window for IE & Edge. | ||
| const clipboard = e.clipboardData ? e.clipboardData : window.clipboardData; |
There was a problem hiding this comment.
Minor: I haven't looked but does the code use this pattern or const clipboard = e.clipboardData || window.clipboardData?
There was a problem hiding this comment.
good, point I'll match react directly
return (
'clipboardData' in event ?
event.clipboardData :
window.clipboardData
);```
| if (text && !html) { | ||
| // The pasted content has text, but not HTML. For certain browsers (old versions of Safari, IE, and Edge) | ||
| // the html isn't provided as part of the clipboardData. To work around this, follow the following algorithm: | ||
| // Do NOT call e.preventDefault(). Instead, we want the browser to paste, just not in the draft element. |
There was a problem hiding this comment.
Minor: in this code we are Draft so it seems strange to refer to Draft as a 3rd party
| editor.setMode('paste'); | ||
| const pasteTrap = editor._pasteTrap; | ||
| pasteTrap.focus(); | ||
| setImmediate(() => { |
There was a problem hiding this comment.
Just to validate: there are no events to drive this off of?
If I paste and then very quickly type, what will happen? Are those typed characters dropped? Are they interpreted as being part of the paste?
There was a problem hiding this comment.
I agree that this is clearly the risky part of the code, but if it's the only way it's the only way. I'd be curious to see if we get some kind of event in the pasteTrap too
There was a problem hiding this comment.
Since focus moves to the pasteTrap, you would get browser-default behavior until the setTimeout elapses. Meaning if you did say, command-b, the bookmark toolbar would show up. Until the setTimeout fires.
The core draft editor should be safe because focus moved & the handlers are turned off.
| editor.setMode('paste'); | ||
| const pasteTrap = editor._pasteTrap; | ||
| pasteTrap.focus(); | ||
| setImmediate(() => { |
There was a problem hiding this comment.
I agree that this is clearly the risky part of the code, but if it's the only way it's the only way. I'd be curious to see if we get some kind of event in the pasteTrap too
| if (data.data.getData && !data.types.length) { | ||
| return undefined; | ||
| } | ||
| return data.getHTML(); |
There was a problem hiding this comment.
To your point in slack, do we have a good grasp on when this function will return text? It seems important as we're driving whether to use the paste trap on the html being present or not
There was a problem hiding this comment.
Yes, the code is known. (see slack)
| // Do NOT call e.preventDefault(). Instead, we want the browser to paste, just not in the editor element. | ||
| // Instead, move focus to a dummy contentEditable div (the pasteTrap), | ||
| // let the paste event through, and then copy the html out of the paste trap. | ||
| // It is important to call setMode('paste') to disable draft's event handlers (so it is blisfully unaware) |
There was a problem hiding this comment.
Minor: Same comment as earlier. We shouldn't talk about Draft as a 3rd party here.
| // Do NOT call e.preventDefault(). Instead, we want the browser to paste, just not in the editor element. | ||
| // Instead, move focus to a dummy contentEditable div (the pasteTrap), | ||
| // let the paste event through, and then copy the html out of the paste trap. | ||
| // It is important to call setMode('paste') to disable draft's event handlers (so it is blisfully unaware) |
There was a problem hiding this comment.
Minor: Same comment as earlier, we shouldn't talk about Draft as if it were a 3rd party
For browsers that don't support grabbing the html out of the clipboardData, instead allow the paste event to go to a dummy pasteTrap and then use that in the remainder of the code