I'm using Facebook Draft.js and I need to create a LINK entity when a valid url is detected in the text.
Currently, I'm using a decorator implementing a strategy detecting if there's a link in the text, like draft-js-linkify-plugin, but I'm having some troubles modifying that text into an immutable LINK entity.
Indeed, I decorate with the Editor props but I can't modify state of the Editor and so, apply this new LINK entity.
The decorator:
const decorator = new CompositeDecorator([{
strategy: findLinks,
component: decorateComponentWithProps(Link, {
getEditorState: this.getEditorState.bind(this),
setEditorState: this.onChange.bind(this)
}),
}]);
The strategy:
function findLinks(contentBlock, callback) {
const links = linkify.match(contentBlock.getText());
if (links) {
links.map(link => callback(link.index, link.lastIndex))
}
}
The component:
const Link = (props) => {
const editorState = props.getEditorState();
const contentState = editorState.getCurrentContent();
const selectionState = editorState.getSelection();
const contentStateWithEntity = contentState.createEntity(
'LINK',
'IMMUTABLE',
{ url: props.decoratedText }
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const contentStateWithLink = Modifier.applyEntity(
contentStateWithEntity,
selectionState,
entityKey
);
const entity = contentStateWithLink.getEntity(entityKey);
const { url } = entity.getData();
const type = entity.getType();
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity
});
props.setEditorState(newEditorState);
return <a href={url} target="_blank">{url}</a>;
};
I know there are issues in the slectionState or retrieving the text block and modify it instead of create a new entity, but I'm a bit lost. Am I even using the right logic for making this ?
Thanks for your help,
I've seen no solution for this specific problem that is building <a>
tag with decorators in React Draft and still have the possibility to edit them without having conflicts.
However, here's two alternatives :
Create a link entity when you select text and click on the link button as it is detailed in react draft example.
Use decorators for displaying links in your editor, then, on submit,
edit your content by retrieving links and replacing them by <a>
tag.
In all cases, I still think you need to sanitize your content server side for security matter. Take advantage of that, maybe shorten your links.
The first solution is better suited when you create article or blog contents. The second is more convenient when your using draft for a messaging system.