Skip to content

Commit

Permalink
added hyperlink feature
Browse files Browse the repository at this point in the history
  • Loading branch information
sofiarba committed Mar 28, 2021
1 parent 42b1f30 commit f5500ce
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
33 changes: 31 additions & 2 deletions client/src/components/TextEditor.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React from 'react';
import { Editor, RichUtils } from 'draft-js';
import { RichUtils, EditorState } from 'draft-js';
import 'draft-js/dist/Draft.css';
import Editor from 'draft-js-plugins-editor';
import addLinkPlugin from '../utils/addLink.js';

const TextEditor = props => {
const { editMode, editorState, onChange } = props;

const editing = editMode ? 'editing' : '';

const plugins = [addLinkPlugin];

const handleKeyCommand = command => {
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
Expand All @@ -26,6 +30,28 @@ const TextEditor = props => {
onChange(RichUtils.toggleInlineStyle(editorState, 'ITALIC'));
};

const onAddLinkClick = () => {
const selection = editorState.getSelection();
const link = window.prompt('Embed hyperlink here : ', 'https://');
if (!link) {
onChange(RichUtils.toggleLink(editorState, selection, null));
return 'handled';
} else if (!link.includes('http')) {
onChange(RichUtils.toggleLink(editorState, selection, null));
window.alert('Error: Must include "https://" in link');
return 'handled';
}
const content = editorState.getCurrentContent();
const contentWithEntity = content.createEntity('LINK', 'MUTABLE', { url: link });
const newEditorState = EditorState.push(
editorState,
contentWithEntity,
'create-entity',
);
const entityKey = contentWithEntity.getLastCreatedEntityKey();
onChange(RichUtils.toggleLink(newEditorState, selection, entityKey));
};

return (
<div className={'textBox ' + editing}>
{editMode && (
Expand All @@ -40,14 +66,17 @@ const TextEditor = props => {
<button className="editorButton" onClick={onItalicClick}>
<em>I</em>
</button>
<button className="editorButton" onClick={onAddLinkClick}>
Link
</button>
</div>
<div className="line" />
</>
)}
<Editor
editorState={editorState}
handleKeyCommand={handleKeyCommand}
onChange={onChange}
plugins={plugins}
readOnly={!editMode}
/>
</div>
Expand Down
75 changes: 75 additions & 0 deletions client/src/utils/addLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import { RichUtils, KeyBindingUtil, EditorState, CompositeDecorator } from 'draft-js';

export const linkStrategy = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges(character => {
const entityKey = character.getEntity();
return entityKey !== null && contentState.getEntity(entityKey).getType() === 'LINK';
}, callback);
};

const Link = props => {
const { contentState, entityKey } = props;
const { url } = contentState.getEntity(entityKey).getData();
return (
<a
className="link"
href={url}
rel="noopener noreferrer"
target="_blank"
aria-label={url}
>
{props.children}
</a>
);
};

const addLink = {
keyBindingFn(event, { getEditorState }) {
const editorState = getEditorState();
const selection = editorState.getSelection();
if (selection.isCollapsed()) {
return;
}
if (KeyBindingUtil.hasCommandModifier(event) && event.which === 75) {
return 'add-link';
}
},

handleKeyCommand(command, editorState, { getEditorState, setEditorState }) {
if (command !== 'add-link') {
return 'not-handled';
}
let link = window.prompt('Embed link here:');
const selection = editorState.getSelection();

if (!link) {
setEditorState(RichUtils.toggleLink(editorState, selection, null));
return 'handled';
}
console.log(link);

const content = editorState.getCurrentContent();
const contentWithEntity = content.createEntity('LINK', 'MUTABLE', {
url: link,
});

const newEditorState = EditorState.push(
editorState,
contentWithEntity,
'create-entity',
);
const entityKey = contentWithEntity.getLastCreatedEntityKey();
setEditorState(RichUtils.toggleLink(newEditorState, selection, entityKey));
return 'handled';
},

decorators: [
{
strategy: linkStrategy,
component: Link,
},
],
};

export default addLink;

0 comments on commit f5500ce

Please sign in to comment.