-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Open in new window" option to links #2628
Changes from 1 commit
d68baaa
8e77332
84c7233
6dfd3e3
79d54cb
8f5ff68
e0df077
1330124
02d0e6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,10 +39,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 +53,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 +79,8 @@ class FormatToolbar extends Component { | |
this.setState( { | ||
isAddingLink: false, | ||
isEditingLink: false, | ||
settingsVisible: false, | ||
opensInNewWindow: !! nextProps.formats.link && !! nextProps.formats.link.target, | ||
newLinkValue: '', | ||
} ); | ||
} | ||
|
@@ -93,6 +98,17 @@ class FormatToolbar extends Component { | |
}; | ||
} | ||
|
||
toggleLinkSettingsVisibility() { | ||
const settingsVisible = ! this.state.settingsVisible; | ||
this.setState( { settingsVisible } ); | ||
} | ||
|
||
setLinkTarget( event ) { | ||
const opensInNewWindow = event.target.checked; | ||
this.setState( { opensInNewWindow } ); | ||
this.props.onChange( { link: { value: this.props.formats.link.value, target: opensInNewWindow ? '_blank' : undefined } } ); | ||
} | ||
|
||
addLink() { | ||
this.setState( { isEditingLink: false, isAddingLink: true, newLinkValue: '' } ); | ||
} | ||
|
@@ -109,15 +125,15 @@ 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' : undefined } } ); | ||
if ( this.state.isAddingLink ) { | ||
this.props.speak( __( 'Link inserted.' ), 'assertive' ); | ||
} | ||
} | ||
|
||
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,13 @@ class FormatToolbar extends Component { | |
isActive: !! formats[ control.format ], | ||
} ) ); | ||
|
||
// TODO: make this not look hideous | ||
const linkSettings = settingsVisible && ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you considered using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, mainly because I didn't know what it was 😄 Looks like a good way to have this visibility state managed for us, although I don't think it would help with my awful design skills? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've switched this to use a popover, but it still looks really bad. I'm not sure what markup we need to have this render like the wireframes, and there's nowhere that we're actually using a PopoverContext for me to see how to get this rendering nicely, either. Also, there are focus issues once you toggle the checkbox (click the settings icon, toggle the checkbox, then you have to click the settings icon twice to close the Popover, as I think the first click takes the focus away from the Popover, which feels bad.) |
||
<div> | ||
{ __( 'Open in new window' ) }: <input type="checkbox" checked={ opensInNewWindow } label={ __( 'Open in new window' ) } onChange={ this.setLinkTarget } /> | ||
</div> | ||
); | ||
|
||
if ( enabledControls.indexOf( 'link' ) !== -1 ) { | ||
toolbarControls.push( { | ||
icon: 'admin-links', | ||
|
@@ -151,6 +174,8 @@ class FormatToolbar extends Component { | |
<UrlInput value={ newLinkValue } onChange={ this.onChangeLinkValue } /> | ||
<IconButton icon="editor-break" label={ __( 'Apply' ) } type="submit" /> | ||
<IconButton icon="editor-unlink" label={ __( 'Remove link' ) } onClick={ this.dropLink } /> | ||
<IconButton icon="admin-generic" onClick={ this.toggleLinkSettingsVisibility } /> | ||
{ linkSettings } | ||
</form> | ||
} | ||
|
||
|
@@ -165,6 +190,8 @@ class FormatToolbar extends Component { | |
</a> | ||
<IconButton icon="edit" label={ __( 'Edit' ) } onClick={ this.editLink } /> | ||
<IconButton icon="editor-unlink" label={ __( 'Remove link' ) } onClick={ this.dropLink } /> | ||
<IconButton icon="admin-generic" onClick={ this.toggleLinkSettingsVisibility } /> | ||
{ linkSettings } | ||
</div> | ||
} | ||
</div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's an implicit coding standard stating that if the next state depends on the previous, we should use the callback notation (I think we were trying to add an eslint for this in an old PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!