Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pasting html from IE, Edge, and Safari #21

Merged
merged 18 commits into from
Feb 1, 2017

Conversation

intentionally-left-nil
Copy link

@intentionally-left-nil intentionally-left-nil commented Jan 27, 2017

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

Anil Kulkarni added 5 commits January 26, 2017 20:31
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!
@intentionally-left-nil intentionally-left-nil changed the title Topic rich paste Support pasting html from IE, Edge, and Safari Feb 1, 2017
// 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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I haven't looked but does the code use this pattern or const clipboard = e.clipboardData || window.clipboardData?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: in this code we are Draft so it seems strange to refer to Draft as a 3rd party

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

editor.setMode('paste');
const pasteTrap = editor._pasteTrap;
pasteTrap.focus();
setImmediate(() => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(() => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the code is known. (see slack)

@@ -102,7 +102,7 @@ function editOnPaste(editor: DraftEditor, e: DOMEvent): void {
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.
// 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)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Same comment as earlier. We shouldn't talk about Draft as a 3rd party here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

// 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)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Same comment as earlier, we shouldn't talk about Draft as if it were a 3rd party

Copy link

@colinjeanne colinjeanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants