Skip to content

Instantly share code, notes, and snippets.

@anders0l
Last active February 26, 2021 06:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anders0l/7a2c2b9a59b1c66a85089c597984d916 to your computer and use it in GitHub Desktop.
Save anders0l/7a2c2b9a59b1c66a85089c597984d916 to your computer and use it in GitHub Desktop.
Mutate Draft-js editor state to add new link entity with draft-js-linkify-plugin
import { EditorState, Modifier, SelectionState, ContentBlock } from 'draft-js'
import * as linkifyIt from 'linkify-it'
const linkify = linkifyIt()
// tslint:disable-next-line:no-var-requires
linkify.tlds(require('tlds'))
const findLinks = (
contentBlock: ContentBlock,
callback: (firstIndex: number, lastIndex: number, href: string) => void
) => {
const contentBlockText = contentBlock.get('text')
const links = linkify.match(contentBlockText)
if (typeof links !== 'undefined' && links !== null) {
for (const link of links) {
callback(link.index, link.lastIndex, link.url)
}
}
}
const linkifyEditorState = (editorState: EditorState): EditorState => {
const contentState = editorState.getCurrentContent()
const blocks = contentState.getBlockMap()
let newContentState = contentState
blocks.forEach(block => {
const plainText = block.getText()
const addEntityToLink = (start: number, end: number, href: string) => {
const existingEntityKey = block.getEntityAt(start)
if (existingEntityKey) {
// avoid manipulation in case the link already has an entity
const entity = contentState.getEntity(existingEntityKey)
if (entity && entity.getType() === 'LINK' && entity.getData().href === href) {
return
}
}
const selection = editorState
.getSelection()
.set('anchorOffset', start)
.set('focusOffset', end)
const linkText = plainText.substring(start, end)
const contentStateWithEntity = contentState.createEntity('LINK', 'IMMUTABLE', { text: linkText, href })
const entityKey = contentStateWithEntity.getLastCreatedEntityKey()
if (selection instanceof SelectionState) {
newContentState = Modifier.replaceText(newContentState, selection, linkText, null, entityKey)
}
}
findLinks(block, addEntityToLink)
})
if (!newContentState.equals(contentState)) {
return EditorState.push(editorState, newContentState, 'apply-entity')
}
return editorState
}
export default linkifyEditorState
@anders0l
Copy link
Author

anders0l commented Jun 4, 2020

  onChange = (editorState: EditorState) => {
    this.setState({ editorState: linkifyEditorState(editorState) })
  }

@anders0l
Copy link
Author

anders0l commented Jun 4, 2020

new version fixes google.co issue when last m skips

@vmc08
Copy link

vmc08 commented Feb 26, 2021

Hi @anders0l, seems not working properly when combined with https://www.draft-js-plugins.com/plugin/anchor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment