Overide default draft-js handling of pasting text/html

This is surprisingly needed to avoid an issue with draft-js that causes multi-line madness when pasting code and then applying format-as-code to it - https://github.com/vector-im/riot-web/issues/2120#issuecomment-271735729.

The issue sounds like it is https://github.com/facebook/draft-js/issues/170#issuecomment-195026203 and the suggstion is to override the text pasting handler https://github.com/facebook/draft-js/issues/170#issuecomment-215983216. Meanwhile they haven't modified the default pasting behaviour afaics.

I've discovered a separate issue that is apparent even after this suggested fix. (https://github.com/vector-im/riot-web/issues/4446)
This commit is contained in:
Luke Barnard 2017-06-27 17:10:28 +01:00
parent 4645ba1bba
commit 5307731dfd

View file

@ -121,6 +121,7 @@ export default class MessageComposerInput extends React.Component {
this.onEscape = this.onEscape.bind(this); this.onEscape = this.onEscape.bind(this);
this.setDisplayedCompletion = this.setDisplayedCompletion.bind(this); this.setDisplayedCompletion = this.setDisplayedCompletion.bind(this);
this.onMarkdownToggleClicked = this.onMarkdownToggleClicked.bind(this); this.onMarkdownToggleClicked = this.onMarkdownToggleClicked.bind(this);
this.onTextPasted = this.onTextPasted.bind(this);
const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false); const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false);
@ -432,6 +433,29 @@ export default class MessageComposerInput extends React.Component {
return false; return false;
} }
onTextPasted(text: string, html?: string) {
const currentSelection = this.state.editorState.getSelection();
const currentContent = this.state.editorState.getCurrentContent();
let contentState = null;
if (html) {
contentState = Modifier.replaceWithFragment(
currentContent,
currentSelection,
RichText.htmlToContentState(html).getBlockMap(),
);
} else {
contentState = Modifier.replaceText(currentContent, currentSelection, text);
}
let newEditorState = EditorState.push(this.state.editorState, contentState, 'insert-characters');
newEditorState = EditorState.forceSelection(newEditorState, contentState.getSelectionAfter());
this.onEditorContentChanged(newEditorState);
return true;
}
handleReturn(ev) { handleReturn(ev) {
if (ev.shiftKey) { if (ev.shiftKey) {
this.onEditorContentChanged(RichUtils.insertSoftNewline(this.state.editorState)); this.onEditorContentChanged(RichUtils.insertSoftNewline(this.state.editorState));
@ -713,6 +737,7 @@ export default class MessageComposerInput extends React.Component {
keyBindingFn={MessageComposerInput.getKeyBinding} keyBindingFn={MessageComposerInput.getKeyBinding}
handleKeyCommand={this.handleKeyCommand} handleKeyCommand={this.handleKeyCommand}
handleReturn={this.handleReturn} handleReturn={this.handleReturn}
handlePastedText={this.onTextPasted}
handlePastedFiles={this.props.onFilesPasted} handlePastedFiles={this.props.onFilesPasted}
stripPastedStyles={!this.state.isRichtextEnabled} stripPastedStyles={!this.state.isRichtextEnabled}
onTab={this.onTab} onTab={this.onTab}