diff --git a/blocks/editable/format-toolbar/index.js b/blocks/editable/format-toolbar/index.js index f8a3a1f452cb3..85f1e5e97fbaf 100644 --- a/blocks/editable/format-toolbar/index.js +++ b/blocks/editable/format-toolbar/index.js @@ -12,6 +12,7 @@ import { keycodes } from '@wordpress/utils'; import './style.scss'; import UrlInput from '../../url-input'; import { filterURLForDisplay } from '../../../editor/utils/url'; +import ToggleControl from '../../inspector-controls/toggle-control'; const { ESCAPE } = keycodes; @@ -39,10 +40,11 @@ const DEFAULT_CONTROLS = [ 'bold', 'italic', 'strikethrough', 'link' ]; class FormatToolbar extends Component { constructor() { super( ...arguments ); - this.state = { isAddingLink: false, isEditingLink: false, + settingsVisible: false, + opensInNewWindow: false, newLinkValue: '', }; @@ -52,6 +54,8 @@ class FormatToolbar extends Component { this.submitLink = this.submitLink.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); this.onChangeLinkValue = this.onChangeLinkValue.bind( this ); + this.toggleLinkSettingsVisibility = this.toggleLinkSettingsVisibility.bind( this ); + this.setLinkTarget = this.setLinkTarget.bind( this ); } componentDidMount() { @@ -76,6 +80,8 @@ class FormatToolbar extends Component { this.setState( { isAddingLink: false, isEditingLink: false, + settingsVisible: false, + opensInNewWindow: !! nextProps.formats.link && !! nextProps.formats.link.target, newLinkValue: '', } ); } @@ -93,6 +99,16 @@ class FormatToolbar extends Component { }; } + toggleLinkSettingsVisibility() { + this.setState( ( state ) => ( { settingsVisible: ! state.settingsVisible } ) ); + } + + setLinkTarget( event ) { + const opensInNewWindow = event.target.checked; + this.setState( { opensInNewWindow } ); + this.props.onChange( { link: { value: this.props.formats.link.value, target: opensInNewWindow ? '_blank' : '' } } ); + } + addLink() { this.setState( { isEditingLink: false, isAddingLink: true, newLinkValue: '' } ); } @@ -109,7 +125,7 @@ class FormatToolbar extends Component { submitLink( event ) { event.preventDefault(); - this.props.onChange( { link: { value: this.state.newLinkValue } } ); + this.props.onChange( { link: { value: this.state.newLinkValue, target: this.state.opensInNewWindow ? '_blank' : '' } } ); if ( this.state.isAddingLink ) { this.props.speak( __( 'Link inserted.' ), 'assertive' ); } @@ -117,7 +133,7 @@ class FormatToolbar extends Component { render() { const { formats, focusPosition, enabledControls = DEFAULT_CONTROLS } = this.props; - const { isAddingLink, isEditingLink, newLinkValue } = this.state; + const { isAddingLink, isEditingLink, newLinkValue, settingsVisible, opensInNewWindow } = this.state; const linkStyle = focusPosition ? { position: 'absolute', ...focusPosition } : null; @@ -130,6 +146,15 @@ class FormatToolbar extends Component { isActive: !! formats[ control.format ], } ) ); + const linkSettings = settingsVisible && ( +
+ +
+ ); + if ( enabledControls.indexOf( 'link' ) !== -1 ) { toolbarControls.push( { icon: 'admin-links', @@ -151,6 +176,8 @@ class FormatToolbar extends Component { + + { linkSettings } } @@ -165,6 +192,8 @@ class FormatToolbar extends Component { + + { linkSettings } } diff --git a/blocks/editable/format-toolbar/style.scss b/blocks/editable/format-toolbar/style.scss index 6a906bef855db..e6a80a1f27594 100644 --- a/blocks/editable/format-toolbar/style.scss +++ b/blocks/editable/format-toolbar/style.scss @@ -7,13 +7,18 @@ box-shadow: 0px 3px 20px rgba( 18, 24, 30, .1 ), 0px 1px 3px rgba( 18, 24, 30, .1 ); border: 1px solid #e0e5e9; background: #fff; - width: 300px; + width: 305px; display: inline-flex; + flex-wrap: wrap; align-items: center; font-family: $default-font; font-size: $default-font-size; line-height: $default-line-height; z-index: z-index( '.blocks-format-toolbar__link-modal' ); + + .blocks-url-input { + width: auto; + } } .blocks-format-toolbar__link-value { @@ -26,3 +31,13 @@ @include long-content-fade( $size: 40% ); } } + +.blocks-format-toolbar__link-settings { + border-top: 1px solid $light-gray-500; + width: 100%; + padding: 10px 8px; + + .blocks-base-control { + margin: 0; + } +} diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 07ca484d7c8e6..fa7732784164c 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -448,7 +448,7 @@ export default class Editable extends Component { const formats = {}; const link = find( parents, ( node ) => node.nodeName.toLowerCase() === 'a' ); if ( link ) { - formats.link = { value: link.getAttribute( 'href' ) || '', node: link }; + formats.link = { value: link.getAttribute( 'href' ) || '', target: link.getAttribute( 'target' ) || '', node: link }; } const activeFormats = this.editor.formatter.matchAll( [ 'bold', 'italic', 'strikethrough' ] ); activeFormats.forEach( ( activeFormat ) => formats[ activeFormat ] = true ); @@ -542,7 +542,7 @@ export default class Editable extends Component { if ( ! anchor ) { this.removeFormat( 'link' ); } - this.applyFormat( 'link', { href: formatValue.value }, anchor ); + this.applyFormat( 'link', { href: formatValue.value, target: formatValue.target }, anchor ); } else { this.editor.execCommand( 'Unlink' ); }