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

Override Draft.js copy-paste to preserve full editor content #2

Merged
merged 21 commits into from
Jun 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2f899bc
chore(demo): add hr to demo site to test copy-paste idempotence
thibaudcolas May 20, 2018
4366190
feat(copy-paste): add wip internal clipboard reuse for copy-paste
thibaudcolas May 20, 2018
1869b10
feat(copy-paste): wip HTML injection implementation of idempotent paste
thibaudcolas May 20, 2018
7ce0af4
feat(copy-paste): finish copy source registration implementation
thibaudcolas May 21, 2018
0976c7e
feat(copy-paste): use DOMParser instead of regexes for paste handling
thibaudcolas May 23, 2018
2c37f74
feat(copy-paste): expose copy-paste functions in package
thibaudcolas May 23, 2018
adadf15
feat(copy-paste): simplify copy-paste API by storing scope at callsite
thibaudcolas May 26, 2018
4d1bc53
feat(copy-paste): add support for invalid JSON in copy-paste
thibaudcolas May 27, 2018
138ec99
feat(copy-paste): improve dom attr cleanup after copy event is over
thibaudcolas May 28, 2018
c68b8b6
docs(copy-paste): document new copy-paste related helper
thibaudcolas May 28, 2018
84d9ed8
chore(build): update react-scripts to latest
thibaudcolas Jun 2, 2018
c6d572f
test(copy-paste): use mount instead of shallow so enzyme tests use refs
thibaudcolas Jun 2, 2018
bd918be
chore(demo): add BR button to the demo to facilitate copy-paste testing
thibaudcolas Jun 2, 2018
52a33b3
chore(demo): fix highlight component taking too long to render
thibaudcolas Jun 3, 2018
49d5403
feat(copy-paste): update copy handler to use clipboardData
thibaudcolas Jun 3, 2018
8d0126d
chore(demo): preventDefault on line break button
thibaudcolas Jun 3, 2018
b207637
feat(copy-paste): add support for cut event
thibaudcolas Jun 3, 2018
a9da3dd
feat(copy-paste): opt-out copy-paste handling in IE11
thibaudcolas Jun 3, 2018
028425f
chore(demo): remove unused Prism dependency
thibaudcolas Jun 3, 2018
7593e8d
test(copy-paste): add unit tests for all copy-paste handling
thibaudcolas Jun 3, 2018
dbc5a3b
chore(demo): add missing tests for demo editor copy-paste
thibaudcolas Jun 3, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ By default, Draft.js only provides support for [5 list levels](https://github.co
Instead of manually writing and maintaining the list nesting styles, use this little helper:

```js
import { ListNestingStyles, blockDepthStyleFn } from 'draftjs-conductor';
import { ListNestingStyles, blockDepthStyleFn } from "draftjs-conductor";

<Editor blockStyleFn={blockDepthStyleFn} />
<ListNestingStyles max={6} />
Expand All @@ -32,6 +32,82 @@ Relevant Draft.js issues:
* [maxDepth param is greater than 4 in RichUtils.onTab – facebook/draft-js#997](https://github.com/facebook/draft-js/issues/997)
* Still problematic: [Nested list styles above 4 levels are not retained when copy-pasting between Draft instances. – facebook/draft-js#1605 (comment)](https://github.com/facebook/draft-js/pull/1605#pullrequestreview-87340460)

### Idempotent copy-paste between Draft.js editors

The default Draft.js copy-paste handlers lose a lot of the formatting when copy-pasting between Draft.js editors 😕. While this might be ok for some use cases, some sites will use multiple editors on the same page, and need them to reliably support copy-paste.

Here is a little override for the Draft.js copy-paste that makes it _just work_:

```js
import {
registerCopySource,
handleDraftEditorPastedText,
} from "draftjs-conductor";

class MyEditor extends Component {
constructor(props: Props) {
super(props);

this.state = {
editorState: EditorState.createEmpty(),
};

this.onChange = this.onChange.bind(this);
this.handlePastedText = this.handlePastedText.bind(this);
}

componentDidMount() {
this.copySource = registerCopySource(this.editorRef);
}

onChange(nextState: EditorState) {
this.setState({ editorState: nextState });
}

handlePastedText(text: string, html: ?string, editorState: EditorState) {
let newState = handleDraftEditorPastedText(html, editorState);

if (newState) {
this.onChange(newState);
return true;
}

return false;
}

componentWillUnmount() {
if (this.copySource) {
this.copySource.unregister();
}
}

render() {
const { editorState } = this.state;

return (
<Editor
ref={(ref) => {
this.editorRef = ref;
}}
editorState={editorState}
onChange={this.onChange}
handlePastedText={this.handlePastedText}
/>
);
}
}
```

`registerCopySource` will ensure the clipboard contains a full representation of the Draft.js content state on copy, while `handleDraftEditorPastedText` retrieves Draft.js content state from the clipboard. Voilà!

Relevant Draft.js issues:

* [Copy/paste between editors – facebook/draft-js#787](https://github.com/facebook/draft-js/issues/787)
* [Copy/paste between editors strips soft returns – facebook/draft-js#1154](https://github.com/facebook/draft-js/issues/1154)
* [Sequential unstyled blocks are merged into the same block on paste – facebook/draft-js#738](https://github.com/facebook/draft-js/issues/738)

Note: IE11 isn’t supported, as it doesn't support storing HTML in the clipboard.

## Contributing

See anything you like in here? Anything missing? We welcome all support, whether on bug reports, feature requests, code, design, reviews, tests, documentation, and more. Please have a look at our [contribution guidelines](.github/CONTRIBUTING.md).
Expand Down
Loading