Skip to content

Instantly share code, notes, and snippets.

@jackcallister
Last active August 31, 2020 19:48
Show Gist options
  • Save jackcallister/af55f3705add9d9ec34fd0cb25ef2f67 to your computer and use it in GitHub Desktop.
Save jackcallister/af55f3705add9d9ec34fd0cb25ef2f67 to your computer and use it in GitHub Desktop.
import { EditorState, Modifier, Entity, SelectionState } from 'draft-js'
import linkifyIt from 'linkify-it'
import tlds from 'tlds'
const linkify = linkifyIt()
linkify.tlds(tlds)
const linkifyEditorState = (editorState) => {
const contentState = editorState.getCurrentContent()
const blocks = contentState.getBlockMap()
let newContentState = contentState
blocks.forEach((block) => {
const plainText = block.getText()
const addEntityToLink = (start, end) => {
const existingEntityKey = block.getEntityAt(start)
if (existingEntityKey) {
// avoid manipulation in case the link already has an entity
const entity = Entity.get(existingEntityKey)
if (entity && entity.get('type') === 'link') {
return
}
}
const selection = SelectionState.createEmpty(block.getKey())
.set('anchorOffset', start)
.set('focusOffset', end)
const linkText = plainText.substring(start, end)
const entityKey = Entity.create('LINK', 'IMMUTABLE', { url: linkText })
newContentState = Modifier.replaceText(
newContentState,
selection,
linkText,
null,
entityKey,
)
}
findLinks(block, addEntityToLink)
})
if (!newContentState.equals(contentState)) {
return EditorState.push(
editorState,
newContentState,
'convert-to-links',
)
}
return editorState
}
const findLinks = (contentBlock, callback) => {
const links = linkify.match(contentBlock.get('text'))
if (typeof links !== 'undefined' && links !== null) {
for (let i = 0; i < links.length; i++) {
callback(links[i].index, links[i].lastIndex)
}
}
}
export default linkifyEditorState
@jackcallister
Copy link
Author

Cheers @dannyshisler - updated

@danii1
Copy link

danii1 commented Oct 16, 2016

Thanks @jarsbe, you saved me 👍

Updated the code to use actual url, instead of typed text, this fix issues with typed links without schema, like:
test@test.com, test.com

https://gist.github.com/danii1/ce569f1bc121398f6f2751a62320fe2f

@jurStv
Copy link

jurStv commented Dec 15, 2016

Thanks @jarsbe for such good solution
Could you also a bit point me how to use it . Right now I tried to apply this linkifyEditorState on editor's change
onChange = (editorState) => this.setState({ editorState: linkifyEditorState(editorState) })
but I'm getting unexpected editor's behavior when type hyperlink e.g. 'https://gith.......', then cursor is moving indifferent places, and start typing in wrong place
sorry if my question is too noob. I'm just trying with Draft and all this system around it

@melnik88
Copy link

I have the same problem and can't get a solution :((

@avk
Copy link

avk commented Jan 16, 2017

Ditto for @jurStv's and @melnik88's comments.

@avk
Copy link

avk commented Jan 16, 2017

@jarsbe yeah, selection state seems to be a problem. Are you or @danii1 having any issues?

@anders0l
Copy link

anders0l commented Jun 4, 2020

It's too outdated, but I rebuild logic and it works fine https://gist.github.com/anders0l/7a2c2b9a59b1c66a85089c597984d916

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