diff --git a/package.json b/package.json index a3bab88d45..496d8a7de6 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "classnames": "^2.1.2", "commonmark": "^0.27.0", "counterpart": "^0.18.0", - "draft-js": "^0.10.1", + "draft-js": "^0.11.0-alpha", "draft-js-export-html": "^0.5.0", "draft-js-export-markdown": "^0.2.0", "emojione": "2.2.7", diff --git a/src/RichText.js b/src/RichText.js index 225a1c212a..9876fcc93f 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -51,7 +51,8 @@ export const contentStateToHTML = (contentState: ContentState) => { }; export function htmlToContentState(html: string): ContentState { - return ContentState.createFromBlockArray(convertFromHTML(html)); + const blockArray = convertFromHTML(html).contentBlocks; + return ContentState.createFromBlockArray(blockArray); } function unicodeToEmojiUri(str) { @@ -90,7 +91,7 @@ function findWithRegex(regex, contentBlock: ContentBlock, callback: (start: numb // Workaround for https://github.com/facebook/draft-js/issues/414 let emojiDecorator = { - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { findWithRegex(EMOJI_REGEX, contentBlock, callback); }, component: (props) => { @@ -119,7 +120,7 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator { export function getScopedMDDecorators(scope: any): CompositeDecorator { let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map( (style) => ({ - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback); }, component: (props) => ( @@ -130,7 +131,7 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator { })); markdownDecorators.push({ - strategy: (contentBlock, callback) => { + strategy: (contentState, contentBlock, callback) => { return findWithRegex(MARKDOWN_REGEX.LINK, contentBlock, callback); }, component: (props) => ( @@ -238,7 +239,7 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor const existingEntityKey = block.getEntityAt(start); if (existingEntityKey) { // avoid manipulation in case the emoji already has an entity - const entity = Entity.get(existingEntityKey); + const entity = newContentState.getEntity(existingEntityKey); if (entity && entity.get('type') === 'emoji') { return; } @@ -248,7 +249,10 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor .set('anchorOffset', start) .set('focusOffset', end); const emojiText = plainText.substring(start, end); - const entityKey = Entity.create('emoji', 'IMMUTABLE', { emojiUnicode: emojiText }); + newContentState = newContentState.createEntity( + 'emoji', 'IMMUTABLE', { emojiUnicode: emojiText } + ); + const entityKey = newContentState.getLastCreatedEntityKey(); newContentState = Modifier.replaceText( newContentState, selection, diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 743caf3a76..c16348300f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -165,17 +165,18 @@ export default class MessageComposerInput extends React.Component { this.client = MatrixClientPeg.get(); } - findLinkEntities(contentBlock, callback) { + findLinkEntities(contentState: ContentState, contentBlock: ContentBlock, callback) { contentBlock.findEntityRanges( (character) => { const entityKey = character.getEntity(); return ( entityKey !== null && - Entity.get(entityKey).getType() === 'LINK' + contentState.getEntity(entityKey).getType() === 'LINK' ); }, callback, ); } + /* * "Does the right thing" to create an EditorState, based on: * - whether we've got rich text mode enabled @@ -188,7 +189,7 @@ export default class MessageComposerInput extends React.Component { strategy: this.findLinkEntities.bind(this), component: (entityProps) => { const Pill = sdk.getComponent('elements.Pill'); - const {url} = Entity.get(entityProps.entityKey).getData(); + const {url} = entityProps.contentState.getEntity(entityProps.entityKey).getData(); if (Pill.isPillUrl(url)) { return ; } @@ -713,7 +714,7 @@ export default class MessageComposerInput extends React.Component { const hasLink = blocks.some((block) => { return block.getCharacterList().filter((c) => { const entityKey = c.getEntity(); - return entityKey && Entity.get(entityKey).getType() === 'LINK'; + return entityKey && contentState.getEntity(entityKey).getType() === 'LINK'; }).size > 0; }); shouldSendHTML = hasLink; @@ -734,8 +735,8 @@ export default class MessageComposerInput extends React.Component { const pt = contentState.getBlocksAsArray().map((block) => { let blockText = block.getText(); let offset = 0; - this.findLinkEntities(block, (start, end) => { - const entity = Entity.get(block.getEntityAt(start)); + this.findLinkEntities(contentState, block, (start, end) => { + const entity = contentState.getEntity(block.getEntityAt(start)); if (entity.getType() !== 'LINK') { return; } @@ -936,32 +937,27 @@ export default class MessageComposerInput extends React.Component { } const {range = null, completion = '', href = null, suffix = ''} = displayedCompletion; + let contentState = activeEditorState.getCurrentContent(); let entityKey; - let mdCompletion; if (href) { - entityKey = Entity.create('LINK', 'IMMUTABLE', { + contentState = contentState.createEntity('LINK', 'IMMUTABLE', { url: href, isCompletion: true, }); + entityKey = contentState.getLastCreatedEntityKey(); } let selection; if (range) { selection = RichText.textOffsetsToSelectionState( - range, activeEditorState.getCurrentContent().getBlocksAsArray(), + range, contentState.getBlocksAsArray(), ); } else { selection = activeEditorState.getSelection(); } - let contentState = Modifier.replaceText( - activeEditorState.getCurrentContent(), - selection, - mdCompletion || completion, - null, - entityKey, - ); + contentState = Modifier.replaceText(contentState, selection, completion, null, entityKey); // Move the selection to the end of the block const afterSelection = contentState.getSelectionAfter(); @@ -1047,7 +1043,7 @@ export default class MessageComposerInput extends React.Component { offset -= sum; const entityKey = block.getEntityAt(offset); - const entity = entityKey ? Entity.get(entityKey) : null; + const entity = entityKey ? contentState.getEntity(entityKey) : null; if (entity && entity.getData().isCompletion) { // This is a completed mention, so do not insert MD link, just text return text;