Skip to content

Commit

Permalink
Add link rel and link class to image block inspector (see #7504) (#7771)
Browse files Browse the repository at this point in the history
* Add link classes and rel attribute to image block (see #7504)

* Make labels consistent with classic editor.

* Fix coding standards error

* Add tests

* Consolidate check for presence of image link

* Rebase, incorporate upstream changes

* Changes as per review

* Fix tests

* Resolve final review comment

* Update CONTRIBUTORS.md
  • Loading branch information
Ned Zimmerman authored and gziolo committed Nov 19, 2018
1 parent 095d18f commit dfa4e04
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Expand Up @@ -117,3 +117,5 @@ This list is manually curated to include valuable contributions by volunteers th
| @amdrew | @sumobi |
| @MaedahBatool | @MaedahBatool |
| @luehrsen | @luehrsen |
| @getsource | @mikeschroder |
| @greatislander | @greatislander |
56 changes: 54 additions & 2 deletions packages/block-library/src/image/edit.js
Expand Up @@ -59,6 +59,7 @@ const LINK_DESTINATION_NONE = 'none';
const LINK_DESTINATION_MEDIA = 'media';
const LINK_DESTINATION_ATTACHMENT = 'attachment';
const LINK_DESTINATION_CUSTOM = 'custom';
const NEW_TAB_REL = 'noreferrer noopener';
const ALLOWED_MEDIA_TYPES = [ 'image' ];

export const pickRelevantMediaFiles = ( image ) => {
Expand Down Expand Up @@ -103,7 +104,10 @@ class ImageEdit extends Component {
this.updateHeight = this.updateHeight.bind( this );
this.updateDimensions = this.updateDimensions.bind( this );
this.onSetCustomHref = this.onSetCustomHref.bind( this );
this.onSetLinkClass = this.onSetLinkClass.bind( this );
this.onSetLinkRel = this.onSetLinkRel.bind( this );
this.onSetLinkDestination = this.onSetLinkDestination.bind( this );
this.onSetNewTab = this.onSetNewTab.bind( this );
this.getFilename = this.getFilename.bind( this );
this.toggleIsEditing = this.toggleIsEditing.bind( this );
this.onUploadError = this.onUploadError.bind( this );
Expand Down Expand Up @@ -216,6 +220,31 @@ class ImageEdit extends Component {
this.props.setAttributes( { href: value } );
}

onSetLinkClass( value ) {
this.props.setAttributes( { linkClass: value } );
}

onSetLinkRel( value ) {
this.props.setAttributes( { rel: value } );
}

onSetNewTab( value ) {
const { rel } = this.props.attributes;
const linkTarget = value ? '_blank' : undefined;

let updatedRel = rel;
if ( linkTarget && ! rel ) {
updatedRel = NEW_TAB_REL;
} else if ( ! linkTarget && rel === NEW_TAB_REL ) {
updatedRel = undefined;
}

this.props.setAttributes( {
linkTarget,
rel: updatedRel,
} );
}

onFocusCaption() {
if ( ! this.state.captionFocused ) {
this.setState( {
Expand Down Expand Up @@ -310,7 +339,20 @@ class ImageEdit extends Component {
toggleSelection,
isRTL,
} = this.props;
const { url, alt, caption, align, id, href, linkDestination, width, height, linkTarget } = attributes;
const {
url,
alt,
caption,
align,
id,
href,
rel,
linkClass,
linkDestination,
width,
height,
linkTarget,
} = attributes;
const isExternal = isExternalImage( id, url );
const imageSizeOptions = this.getImageSizeOptions();

Expand Down Expand Up @@ -480,8 +522,18 @@ class ImageEdit extends Component {
/>
<ToggleControl
label={ __( 'Open in New Tab' ) }
onChange={ () => setAttributes( { linkTarget: ! linkTarget ? '_blank' : undefined } ) }
onChange={ this.onSetNewTab }
checked={ linkTarget === '_blank' } />
<TextControl
label={ __( 'Link CSS Class' ) }
value={ linkClass || '' }
onChange={ this.onSetLinkClass }
/>
<TextControl
label={ __( 'Link Rel' ) }
value={ rel || '' }
onChange={ this.onSetLinkRel }
/>
</Fragment>
) }
</PanelBody>
Expand Down
55 changes: 51 additions & 4 deletions packages/block-library/src/image/index.js
Expand Up @@ -52,6 +52,18 @@ const blockAttributes = {
selector: 'figure > a',
attribute: 'href',
},
rel: {
type: 'string',
source: 'attribute',
selector: 'figure > a',
attribute: 'rel',
},
linkClass: {
type: 'string',
source: 'attribute',
selector: 'figure > a',
attribute: 'class',
},
id: {
type: 'number',
},
Expand Down Expand Up @@ -89,7 +101,7 @@ const schema = {
children: {
...imageSchema,
a: {
attributes: [ 'href', 'target' ],
attributes: [ 'href', 'rel', 'target' ],
children: imageSchema,
},
figcaption: {
Expand Down Expand Up @@ -132,7 +144,9 @@ export const settings = {
const anchorElement = node.querySelector( 'a' );
const linkDestination = anchorElement && anchorElement.href ? 'custom' : undefined;
const href = anchorElement && anchorElement.href ? anchorElement.href : undefined;
const attributes = getBlockAttributes( 'core/image', node.outerHTML, { align, id, linkDestination, href } );
const rel = anchorElement && anchorElement.rel ? anchorElement.rel : undefined;
const linkClass = anchorElement && anchorElement.className ? anchorElement.className : undefined;
const attributes = getBlockAttributes( 'core/image', node.outerHTML, { align, id, linkDestination, href, rel, linkClass } );
return createBlock( 'core/image', attributes );
},
},
Expand Down Expand Up @@ -181,6 +195,18 @@ export const settings = {
attribute: 'href',
selector: 'a',
},
rel: {
type: 'string',
source: 'attribute',
attribute: 'rel',
selector: 'a',
},
linkClass: {
type: 'string',
source: 'attribute',
attribute: 'class',
selector: 'a',
},
id: {
type: 'number',
shortcode: ( { named: { id } } ) => {
Expand Down Expand Up @@ -212,7 +238,19 @@ export const settings = {
edit,

save( { attributes } ) {
const { url, alt, caption, align, href, width, height, id, linkTarget } = attributes;
const {
url,
alt,
caption,
align,
href,
rel,
linkClass,
width,
height,
id,
linkTarget,
} = attributes;

const classes = classnames( {
[ `align${ align }` ]: align,
Expand All @@ -231,7 +269,16 @@ export const settings = {

const figure = (
<Fragment>
{ href ? <a href={ href } target={ linkTarget } rel={ linkTarget === '_blank' ? 'noreferrer noopener' : undefined }>{ image }</a> : image }
{ href ? (
<a
className={ linkClass }
href={ href }
target={ linkTarget }
rel={ rel }
>
{ image }
</a>
) : image }
{ ! RichText.isEmpty( caption ) && <RichText.Content tagName="figcaption" value={ caption } /> }
</Fragment>
);
Expand Down
@@ -0,0 +1,3 @@
<!-- wp:core/image {"linkDestination":"custom"} -->
<figure class="wp-block-image"><a class="custom-link" href="https://wordpress.org/"><img src="https://cldup.com/uuUqE_dXzy.jpg" alt="" /></a></figure>
<!-- /wp:core/image -->
@@ -0,0 +1,17 @@
[
{
"clientId": "_clientId_0",
"name": "core/image",
"isValid": true,
"attributes": {
"url": "https://cldup.com/uuUqE_dXzy.jpg",
"alt": "",
"caption": "",
"href": "https://wordpress.org/",
"linkDestination": "custom",
"linkClass": "custom-link"
},
"innerBlocks": [],
"originalContent": "<figure class=\"wp-block-image\"><a class=\"custom-link\" href=\"https://wordpress.org/\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>"
}
]
@@ -0,0 +1,22 @@
[
{
"blockName": "core/image",
"attrs": {
"linkDestination": "custom"
},
"innerBlocks": [],
"innerHTML": "\n<figure class=\"wp-block-image\"><a class=\"custom-link\" href=\"https://wordpress.org/\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>\n",
"innerContent": [
"\n<figure class=\"wp-block-image\"><a class=\"custom-link\" href=\"https://wordpress.org/\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>\n"
]
},
{
"attrs": {},
"blockName": null,
"innerBlocks": [],
"innerHTML": "\n",
"innerContent": [
"\n"
]
}
]
@@ -0,0 +1,3 @@
<!-- wp:image {"linkDestination":"custom"} -->
<figure class="wp-block-image"><a class="custom-link" href="https://wordpress.org/"><img src="https://cldup.com/uuUqE_dXzy.jpg" alt=""/></a></figure>
<!-- /wp:image -->
@@ -0,0 +1,3 @@
<!-- wp:core/image {"linkDestination":"custom"} -->
<figure class="wp-block-image"><a href="https://wordpress.org/" rel="external"><img src="https://cldup.com/uuUqE_dXzy.jpg" alt="" /></a></figure>
<!-- /wp:core/image -->
@@ -0,0 +1,17 @@
[
{
"clientId": "_clientId_0",
"name": "core/image",
"isValid": true,
"attributes": {
"url": "https://cldup.com/uuUqE_dXzy.jpg",
"alt": "",
"caption": "",
"href": "https://wordpress.org/",
"linkDestination": "custom",
"rel": "external"
},
"innerBlocks": [],
"originalContent": "<figure class=\"wp-block-image\"><a href=\"https://wordpress.org/\" rel=\"external\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>"
}
]
@@ -0,0 +1,22 @@
[
{
"blockName": "core/image",
"attrs": {
"linkDestination": "custom"
},
"innerBlocks": [],
"innerHTML": "\n<figure class=\"wp-block-image\"><a href=\"https://wordpress.org/\" rel=\"external\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>\n",
"innerContent": [
"\n<figure class=\"wp-block-image\"><a href=\"https://wordpress.org/\" rel=\"external\"><img src=\"https://cldup.com/uuUqE_dXzy.jpg\" alt=\"\" /></a></figure>\n"
]
},
{
"attrs": {},
"blockName": null,
"innerBlocks": [],
"innerHTML": "\n",
"innerContent": [
"\n"
]
}
]
@@ -0,0 +1,3 @@
<!-- wp:image {"linkDestination":"custom"} -->
<figure class="wp-block-image"><a href="https://wordpress.org/" rel="external"><img src="https://cldup.com/uuUqE_dXzy.jpg" alt=""/></a></figure>
<!-- /wp:image -->

0 comments on commit dfa4e04

Please sign in to comment.