diff --git a/package.json b/package.json
index 837264bb..07a6fb79 100644
--- a/package.json
+++ b/package.json
@@ -78,6 +78,6 @@
"react-portal": "^2.2.1",
"selection-position": "^1.0.0",
"slate": "^0.11.0",
- "slate-markdown-serializer": "^0.1.3"
+ "slate-markdown-serializer": "^0.1.5"
}
}
diff --git a/src/components/Widgets/MarkdownControl.js b/src/components/Widgets/MarkdownControl.js
index d3251a92..15f27905 100644
--- a/src/components/Widgets/MarkdownControl.js
+++ b/src/components/Widgets/MarkdownControl.js
@@ -38,6 +38,7 @@ class MarkdownControl extends React.Component {
this.handleDocumentChange = this.handleDocumentChange.bind(this);
this.handleMarkStyleClick = this.handleMarkStyleClick.bind(this);
this.handleBlockStyleClick = this.handleBlockStyleClick.bind(this);
+ this.handleInlineClick = this.handleInlineClick.bind(this);
this.handleBlockTypeClick = this.handleBlockTypeClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.calculateMenuPositions = this.calculateMenuPositions.bind(this);
@@ -150,6 +151,42 @@ class MarkdownControl extends React.Component {
this.setState({ state });
}
+ /**
+ * When clicking a link, if the selection has a link in it, remove the link.
+ * Otherwise, add a new link with an href and text.
+ *
+ * @param {Event} e
+ */
+
+ handleInlineClick(type, isActive) {
+ let { state } = this.state;
+
+ if (type === 'link') {
+ if (!state.isExpanded) return;
+
+ if (isActive) {
+ state = state
+ .transform()
+ .unwrapInline('link')
+ .apply();
+ }
+
+ else {
+ const href = window.prompt('Enter the URL of the link:', 'http://www.');
+ state = state
+ .transform()
+ .wrapInline({
+ type: 'link',
+ data: { href }
+ })
+ .collapseToEnd()
+ .apply();
+ }
+ }
+ this.setState({ state });
+ }
+
+
handleBlockTypeClick(type) {
let { state } = this.state;
@@ -208,7 +245,9 @@ class MarkdownControl extends React.Component {
position={this.menuPositions.stylesMenu}
marks={this.state.state.marks}
blocks={this.state.state.blocks}
+ inlines={this.state.state.inlines}
onClickMark={this.handleMarkStyleClick}
+ onClickInline={this.handleInlineClick}
onClickBlock={this.handleBlockStyleClick}
/>
);
diff --git a/src/components/Widgets/MarkdownControlElements/StylesMenu.js b/src/components/Widgets/MarkdownControlElements/StylesMenu.js
index 12e27a3b..017ecfd3 100644
--- a/src/components/Widgets/MarkdownControlElements/StylesMenu.js
+++ b/src/components/Widgets/MarkdownControlElements/StylesMenu.js
@@ -16,8 +16,10 @@ export default class StylesMenu extends Component {
this.hasBlock = this.hasBlock.bind(this);
this.renderMarkButton = this.renderMarkButton.bind(this);
this.renderBlockButton = this.renderBlockButton.bind(this);
+ this.renderLinkButton = this.renderLinkButton.bind(this);
this.updateMenuPosition = this.updateMenuPosition.bind(this);
this.handleMarkClick = this.handleMarkClick.bind(this);
+ this.handleInlineClick = this.handleInlineClick.bind(this);
this.handleBlockClick = this.handleBlockClick.bind(this);
this.handleOpen = this.handleOpen.bind(this);
}
@@ -54,6 +56,10 @@ export default class StylesMenu extends Component {
const { blocks } = this.props;
return blocks.some(node => node.type == type);
}
+ hasLinks(type) {
+ const { inlines } = this.props;
+ return inlines.some(inline => inline.type == 'link');
+ }
handleMarkClick(e, type) {
e.preventDefault();
@@ -70,6 +76,21 @@ export default class StylesMenu extends Component {
);
}
+ handleInlineClick(e, type, isActive) {
+ e.preventDefault();
+ this.props.onClickInline(type, isActive);
+ }
+
+ renderLinkButton() {
+ const isActive = this.hasLinks();
+ const onMouseDown = e => this.handleInlineClick(e, 'link', isActive);
+ return (
+
+
+
+ );
+ }
+
handleBlockClick(e, type) {
e.preventDefault();
const isActive = this.hasBlock(type);
@@ -103,6 +124,7 @@ export default class StylesMenu extends Component {
{this.renderMarkButton('bold', 'bold')}
{this.renderMarkButton('italic', 'italic')}
{this.renderMarkButton('code', 'code')}
+ {this.renderLinkButton()}
{this.renderBlockButton('heading1', 'h1')}
{this.renderBlockButton('heading2', 'h2')}
{this.renderBlockButton('block-quote', 'quote-left')}
@@ -122,6 +144,8 @@ StylesMenu.propTypes = {
}),
marks: PropTypes.object.isRequired,
blocks: PropTypes.object.isRequired,
+ inlines: PropTypes.object.isRequired,
onClickBlock: PropTypes.func.isRequired,
- onClickMark: PropTypes.func.isRequired
+ onClickMark: PropTypes.func.isRequired,
+ onClickInline: PropTypes.func.isRequired
};
diff --git a/src/components/Widgets/MarkdownControlElements/localRenderers.js b/src/components/Widgets/MarkdownControlElements/localRenderers.js
index 1ab11ab5..32974536 100644
--- a/src/components/Widgets/MarkdownControlElements/localRenderers.js
+++ b/src/components/Widgets/MarkdownControlElements/localRenderers.js
@@ -1,7 +1,6 @@
import React from 'react';
import Block from './Block';
import BlockStatic from './BlockStatic';
-import { Icon } from '../../UI';
/* eslint react/prop-types: 0, react/no-multi-comp: 0 */
@@ -24,7 +23,7 @@ export const NODES = {
'link': (props) => {
const { data } = props.node;
const href = data.get('href');
- return {props.children};
+ return {props.children};
},
'image': (props) => {
const { node } = props;