diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js
index bc524c53205250..97c88482295244 100644
--- a/blocks/components/editable/index.js
+++ b/blocks/components/editable/index.js
@@ -131,7 +131,7 @@ export default class Editable extends wp.element.Component {
}
onNodeChange( { parents } ) {
- this.formats = parents.reduce( ( result, node ) => {
+ const formats = parents.reduce( ( result, node ) => {
const tag = node.nodeName.toLowerCase();
if ( formatMap.hasOwnProperty( tag ) ) {
@@ -141,6 +141,14 @@ export default class Editable extends wp.element.Component {
return result;
}, {} );
+ // Link format
+ const link = parents.find( parent => parent.nodeName === 'A' );
+ if ( link ) {
+ formats.link = link.getAttribute( 'href' );
+ }
+
+ this.formats = formats;
+
this.props.onFormatChange( this.formats );
}
@@ -215,7 +223,9 @@ export default class Editable extends wp.element.Component {
if ( state !== currentState ) {
this.editor.focus();
- if ( state ) {
+ if ( format === 'link' ) {
+ this.editor.execCommand( 'mceInsertLink', true, state );
+ } else if ( state ) {
this.editor.formatter.apply( format );
} else {
this.editor.formatter.remove( format );
diff --git a/editor/components/format-toolbar/index.js b/editor/components/format-toolbar/index.js
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/editor/components/toolbar/index.js b/editor/components/toolbar/index.js
index 2a63d1cb38d9d4..da53845fc75f0e 100644
--- a/editor/components/toolbar/index.js
+++ b/editor/components/toolbar/index.js
@@ -9,27 +9,34 @@ import classNames from 'classnames';
import './style.scss';
import IconButton from 'components/icon-button';
-function Toolbar( { controls } ) {
+function Toolbar( { attributes, setAttributes, controls } ) {
if ( ! controls || ! controls.length ) {
return null;
}
return (
- { controls.map( ( control, index ) => (
- {
- event.stopPropagation();
- control.onClick();
- } }
- className={ classNames( 'editor-toolbar__control', {
- 'is-active': control.isActive && control.isActive()
- } ) } />
- ) ) }
+ { controls.map( ( control, index ) => {
+ if ( control.edit ) {
+ const element = wp.element.createElement( control.edit, { attributes, setAttributes } );
+ return wp.element.cloneElement( element, { key: index } );
+ }
+
+ return (
+ {
+ event.stopPropagation();
+ control.onClick( attributes, setAttributes );
+ } }
+ className={ classNames( 'editor-toolbar__control', {
+ 'is-active': control.isActive && control.isActive( attributes )
+ } ) } />
+ );
+ } ) }
);
}
diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js
index 6f7c705a697b13..fe9692977b2973 100644
--- a/editor/modes/visual-editor/block.js
+++ b/editor/modes/visual-editor/block.js
@@ -10,24 +10,7 @@ import classnames from 'classnames';
import Toolbar from 'components/toolbar';
import BlockMover from 'components/block-mover';
import BlockSwitcher from 'components/block-switcher';
-
-const formattingControls = [
- {
- icon: 'editor-bold',
- title: wp.i18n.__( 'Bold' ),
- format: 'bold'
- },
- {
- icon: 'editor-italic',
- title: wp.i18n.__( 'Italic' ),
- format: 'italic'
- },
- {
- icon: 'editor-strikethrough',
- title: wp.i18n.__( 'Strikethrough' ),
- format: 'strikethrough'
- }
-];
+import formattingControls from './format-controls';
class VisualEditorBlock extends wp.element.Component {
constructor() {
@@ -37,7 +20,7 @@ class VisualEditorBlock extends wp.element.Component {
this.maybeDeselect = this.maybeDeselect.bind( this );
this.maybeHover = this.maybeHover.bind( this );
this.onFormatChange = this.onFormatChange.bind( this );
- this.toggleFormat = this.toggleFormat.bind( this );
+ this.setFormats = this.setFormats.bind( this );
this.previousOffset = null;
this.state = {
formats: {}
@@ -56,13 +39,13 @@ class VisualEditorBlock extends wp.element.Component {
this.setState( { formats } );
}
- toggleFormat( format ) {
+ setFormats( newFormats ) {
const { formats } = this.state;
this.setState( {
formats: {
...formats,
- [ format ]: ! formats[ format ]
+ ...newFormats
}
} );
}
@@ -143,7 +126,6 @@ class VisualEditorBlock extends wp.element.Component {
tabIndex="0"
onFocus={ onSelect }
onBlur={ this.maybeDeselect }
- onKeyDown={ onStartTyping }
onMouseEnter={ onHover }
onMouseMove={ this.maybeHover }
onMouseLeave={ onMouseLeave }
@@ -155,31 +137,31 @@ class VisualEditorBlock extends wp.element.Component {
{ !! settings.controls && (
( {
- ...control,
- onClick: () => control.onClick( block.attributes, this.setAttributes ),
- isActive: () => control.isActive( block.attributes )
- } ) ) } />
+ controls={ settings.controls }
+ attributes={ block.attributes }
+ setAttributes={ this.setAttributes }
+ />
) }
{ this.state.hasEditable && (
( {
- ...control,
- onClick: () => this.toggleFormat( control.format ),
- isActive: () => !! this.state.formats[ control.format ]
- } ) ) } />
+ controls={ formattingControls }
+ attributes={ this.state.formats }
+ setAttributes={ this.setFormats }
+ />
) }
}
-
+
+
+
);
/* eslint-enable jsx-a11y/no-static-element-interactions */
diff --git a/editor/modes/visual-editor/format-controls.js b/editor/modes/visual-editor/format-controls.js
new file mode 100644
index 00000000000000..21121f08bbfc24
--- /dev/null
+++ b/editor/modes/visual-editor/format-controls.js
@@ -0,0 +1,105 @@
+/**
+ * External dependencies
+ */
+import classNames from 'classnames';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+import IconButton from 'components/icon-button';
+
+class LinkControl extends wp.element.Component {
+ constructor() {
+ super( ...arguments );
+ this.state = {
+ opened: false
+ };
+ this.toggleLinkModal = this.toggleLinkModal.bind( this );
+ this.submitLinkModal = this.submitLinkModal.bind( this );
+ this.updateLinkValue = this.updateLinkValue.bind( this );
+ }
+
+ componentWillMount() {
+ this.setState( { value: this.props.attributes.link } );
+ }
+
+ componentWillReceiveProps( nextProps ) {
+ this.setState( { value: nextProps.attributes.link } );
+ }
+
+ toggleLinkModal() {
+ this.setState( {
+ opened: ! this.state.opened
+ } );
+ }
+
+ submitLinkModal( event ) {
+ event.preventDefault();
+ this.props.setAttributes( { link: this.state.value } );
+ this.setState( {
+ opened: false
+ } );
+ }
+
+ updateLinkValue( event ) {
+ this.setState( {
+ value: event.target.value
+ } );
+ }
+
+ render() {
+ return (
+
+
+ { this.state.opened &&
+
+
+
+ }
+
+ );
+ }
+}
+
+const formattingControls = [
+ {
+ icon: 'editor-bold',
+ title: wp.i18n.__( 'Bold' ),
+ isActive: ( { bold } ) => !! bold,
+ onClick( attributes, setAttributes ) {
+ setAttributes( { bold: ! attributes.bold } );
+ },
+ },
+ {
+ icon: 'editor-italic',
+ title: wp.i18n.__( 'Italic' ),
+ isActive: ( { italic } ) => !! italic,
+ onClick( attributes, setAttributes ) {
+ setAttributes( { italic: ! attributes.italic } );
+ },
+ },
+ {
+ icon: 'editor-strikethrough',
+ title: wp.i18n.__( 'Strikethrough' ),
+ isActive: ( { strikethrough } ) => !! strikethrough,
+ onClick( attributes, setAttributes ) {
+ setAttributes( { strikethrough: ! attributes.strikethrough } );
+ },
+ },
+ {
+ edit: LinkControl
+ }
+];
+
+export default formattingControls;
diff --git a/editor/modes/visual-editor/style.scss b/editor/modes/visual-editor/style.scss
index e5815cd9c3108f..e95ab016362887 100644
--- a/editor/modes/visual-editor/style.scss
+++ b/editor/modes/visual-editor/style.scss
@@ -60,3 +60,22 @@
.editor-visual-editor .editor-inserter {
margin: $item-spacing;
}
+
+
+// joen make me pretty
+.editable-visual-editor__link-control {
+ position: relative;
+}
+
+.editable-visual-editor__link-modal {
+ position: absolute;
+ top: 42px;
+ box-shadow: 0px 3px 20px rgba( 18, 24, 30, .1 ), 0px 1px 3px rgba( 18, 24, 30, .1 );
+ border: 1px solid #e0e5e9;
+ background: #fff;
+ padding: 10px;
+
+ input {
+ font-size: 13px;
+ }
+}
diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot
index a26b05009d732f..37da5a4d2e188b 100644
--- a/languages/gutenberg.pot
+++ b/languages/gutenberg.pot
@@ -95,15 +95,23 @@ msgstr ""
msgid "Publish"
msgstr ""
-#: editor/modes/visual-editor/block.js:17
+#: editor/modes/visual-editor/format-controls.js:56
+msgid "Link"
+msgstr ""
+
+#: editor/modes/visual-editor/format-controls.js:66
+msgid "Add Link"
+msgstr ""
+
+#: editor/modes/visual-editor/format-controls.js:78
msgid "Bold"
msgstr ""
-#: editor/modes/visual-editor/block.js:22
+#: editor/modes/visual-editor/format-controls.js:86
msgid "Italic"
msgstr ""
-#: editor/modes/visual-editor/block.js:27
+#: editor/modes/visual-editor/format-controls.js:94
msgid "Strikethrough"
msgstr ""