From 4eb7ee5642264e019f8b68dae30208455c48e46b Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Fri, 16 Nov 2018 02:48:58 +0200 Subject: [PATCH 01/40] Add fileWidth, fileHeight, userSet, editWidth props --- lib/compat.php | 228 ++++++++++++++ packages/block-library/src/image/edit.js | 281 +++++++++++++++--- .../block-library/src/image/image-size.js | 5 + packages/block-library/src/image/index.js | 19 +- 4 files changed, 478 insertions(+), 55 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index ff0938c496828a..f6f08989043f12 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -304,3 +304,231 @@ function gutenberg_warn_classic_about_blocks() { $size ) { + if ( array_key_exists( $size_name, $meta['sizes'] ) ) { + $response['sizes'][ $size_name ]['actual_size'] = array( + 'width' => (int) $meta['sizes'][ $size_name ]['width'], + 'height' => (int) $meta['sizes'][ $size_name ]['height'], + ); + } + } + } + + return $response; +} +add_filter( 'wp_prepare_attachment_for_js', 'gutenberg_prepare_attachment_for_js', 10, 3 ); + +/** + * Warm the object cache with post and meta information for all found + * image blocks to avoid making individual database calls + * (similarly to `wp_make_content_images_responsive()`). + * + * @access private + * @since 4.x.x + * + * @param string $content The post content. + * @return string $content Unchanged post content. + */ +function _gutenberg_cache_images_meta( $content ) { + // Need to find all image blocks and get the attachment IDs from them BEFORE the parser is run + // so we can get the image attachments meta all at once from the DB. + if ( preg_match_all( '/^$/m', $content, $matches ) ) { + _prime_post_caches( $matches[1], false, true ); + } + + return $content; +} + +// Run before blocks are parsed. +add_filter( 'the_content', '_gutenberg_cache_images_meta', 3 ); + +/** + * Calculates the image width and height based on $block_witdh and the `editWidth` block attribute. + * + * @since 4.x.x + * + * @param array $block_attributes The block attributes. + * @param array $image_meta Optional. The image attachment meta data. + * @return array|bool An array of the image width and height, in that order, or false if the image data is missing from $block_attributes. + */ +function gutenberg_get_image_width_height( $block_attributes, $image_meta = null ) { + if ( ! empty( $block_attributes['width'] ) && ! empty( $block_attributes['height'] ) ) { + // The image was resized. + $image_dimensions = array( + $block_attributes['width'], + $block_attributes['height'], + ); + + /* + * Here we can use `$block_attributes['editWidth']` to scale the image + * if we know the theme's "expected width" (in pixels). + * + * Note that if the `$block_attributes['userSet']` is set/true, the user has entered + * the width and height by hand, they shouldn't probably be changed. + * + * Something like: + * if ( empty( $block_attributes['userSet'] ) && ! empty( $block_attributes['editWidth'] ) && $content_width <> $block_attributes['editWidth'] ) { + * // Scale the image if the block width in the editor was different than the current theme width. + * $scale = $content_width / $block_attributes['editWidth']; + * $image_width = round( $block_attributes['width'] * $scale ); + * } + * $image_dimensions = wp_constrain_dimensions( $image_file_width, $image_file_height, $image_width ); + */ + } elseif ( ! empty( $block_attributes['fileWidth'] ) && ! empty( $block_attributes['fileHeight'] ) ) { + $image_dimensions = array( + $block_attributes['fileWidth'], + $block_attributes['fileHeight'], + ); + } else { + return false; + } + + /* + * Do not constrain images with "wide" and "full" allignment to the "large" image size. + * TODO: To reduce (fix) the need for upscaling or using the "full" size images + * add "xlarge" image size generated by default! + */ + if ( ! empty( $image_meta ) && + ( $block_attributes['align'] === 'wide' || $block_attributes['align'] === 'full' ) && + ! empty( $block_attributes['fileWidth'] ) && + $block_attributes['fileWidth'] < $image_meta['width'] && + max( (int) $image_meta['width'], (int) $image_meta['height'] ) < 4300 && // max 12 MP photo (that's still may be over 3MB, consider reducing). + ! empty( $image_meta['sizes']['large'] ) && + $block_attributes['fileWidth'] === (int) $image_meta['sizes']['large']['width'] && + wp_image_matches_ratio( $block_attributes['fileWidth'], $block_attributes['fileHeight'], $image_meta['width'], $image_meta['height'] ) + ) { + $image_dimensions = array( + $image_meta['width'], + $image_meta['height'], + ); + } + + /** + * Filters the image size for the image block. + * + * @since 4.x.x + * + * @param array $image_size The calculated image size width and height (in that order). + * @param array $block_attributes The block attributes. + * @param array $image_meta The image attachment meta data. + */ + return apply_filters( 'gutenberg_get_image_width_height', $image_dimensions, $block_attributes, $image_meta ); +} + +function gutenberg_render_block_core_image( $html, $block ) { + // Old post or... something's wrong. + if ( empty( $html ) || empty( $block['attrs'] ) ) { + return $html; + } + + $defaults = array( + 'url' => '', + 'alt' => '', + 'id' => 0, + 'align' => '', + ); + + $block_attributes = wp_parse_args( $block['attrs'], $defaults ); + + if ( empty( $block_attributes['url'] ) ) { + // We don't have enough data to construct new img tag. Fall back to the existing HTML. + return $html; + } + + if ( ! empty( $block_attributes['id'] ) ) { + $attachment_id = (int) $block_attributes['id']; + $image_meta = wp_get_attachment_metadata( $attachment_id ); + } else { + $image_meta = null; + $attachment_id = 0; + } + + $image_dimensions = gutenberg_get_image_width_height( $block_attributes, $image_meta ); + $image_src = ''; + $srcset = ''; + $sizes = ''; +//Q( $image_dimensions ); + if ( empty( $image_dimensions ) ) { + // We don't have enough data to construct new img tag. Fall back to the existing HTML. + return $html; + } + + $image_src = $block_attributes['url']; + + $image_attributes = array( + 'src' => $image_src, + 'alt' => empty( $block_attributes['alt'] ) ? '' : $block_attributes['alt'], + 'width' => $image_dimensions[0], + 'height' => $image_dimensions[1], + ); + + if ( $image_meta ) { + // TODO: pass `$block_attributes` to the filter. + $srcset = wp_calculate_image_srcset( $image_dimensions, $image_src, $image_meta, $attachment_id ); + + if ( ! empty( $srcset ) ) { + // TODO: pass `$block_attributes` to the filter. This will let themes generate better `sizes` attribute. + $sizes = wp_calculate_image_sizes( $image_dimensions, $image_src, $image_meta, $attachment_id ); + } + + if ( $srcset && $sizes ) { + $image_attributes['srcset'] = $srcset; + $image_attributes['sizes'] = $sizes; + } + } + + /** + * Filters the image tag attributes when rendering the core image block. + * + * @since 4.x.x + * + * @param array $image_attributes The (recalculated) image attributes. + * Note: expects valid HTML 5.0 attribute names. + * @param array $block_attributes The image block attributes. + * @param string $html The image block HTML coming from the editor. The img tag will be replaced. + */ + $image_attributes = apply_filters( 'render_block_core_image_tag_attributes', $image_attributes, $block_attributes, $html ); + + $attr = ''; + foreach ( $image_attributes as $name => $value ) { + // Sanitize for valid HTML 5.0 attribute names, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes. + $name = preg_replace( '/[^a-z0-9-]+/', '', strtolower( $name ) ); + + if ( empty( $name ) ) { + continue; + } + + if ( 'src' === $name ) { + $value = esc_url( $value ); + } elseif ( ( 'width' === $name || 'height' === $name ) && ! empty( $value ) ) { + $value = (int) $value; + } else { + $value = esc_attr( $value ); + } + + $attr .= sprintf( ' %s="%s"', $name, $value ); + } + + $image_tag = ''; + + // Replace the img tag. + $html = preg_replace( '/]+>/', $image_tag, $html ); + + return $html; +} +// Needs WP 5.0-beta4 to work. +add_filter( 'render_block', 'gutenberg_render_block_core_image', 10, 2 ); diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 3d0c3706d14e40..9417eb87af7cfe 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -7,6 +7,7 @@ import { isEmpty, map, pick, + round, compact, } from 'lodash'; @@ -45,7 +46,7 @@ import { compose } from '@wordpress/compose'; /** * Internal dependencies */ -import ImageSize from './image-size'; +import ImageSize, { getBlockWidth } from './image-size'; /** * Module constants @@ -95,7 +96,7 @@ class ImageEdit extends Component { this.updateImageURL = this.updateImageURL.bind( this ); this.updateWidth = this.updateWidth.bind( this ); this.updateHeight = this.updateHeight.bind( this ); - this.updateDimensions = this.updateDimensions.bind( this ); + this.resetWidthHeight = this.resetWidthHeight.bind( this ); this.onSetCustomHref = this.onSetCustomHref.bind( this ); this.onSetLinkDestination = this.onSetLinkDestination.bind( this ); this.toggleIsEditing = this.toggleIsEditing.bind( this ); @@ -128,7 +129,12 @@ class ImageEdit extends Component { componentDidUpdate( prevProps ) { const { id: prevID, url: prevURL = '' } = prevProps.attributes; - const { id, url = '' } = this.props.attributes; + const { id, url = '', fileWidth } = this.props.attributes; + const imageData = this.props.image; + const blockWidth = getBlockWidth(); + + // Store the current block width inside the editor. + this.props.setAttributes( { editWidth: blockWidth } ); if ( isTemporaryImage( prevID, prevURL ) && ! isTemporaryImage( id, url ) ) { revokeBlobURL( url ); @@ -139,6 +145,25 @@ class ImageEdit extends Component { captionFocused: false, } ); } + + if ( url && imageData && ! fileWidth ) { + // Old post or just uploaded image. Attempt to update the image props. + const sizeFull = get( imageData, [ 'media_details', 'sizes', 'full' ] ); + const sizeLarge = get( imageData, [ 'media_details', 'sizes', 'large' ] ); + + if ( sizeFull && url === sizeFull.source_url ) { + if ( sizeLarge && this.imageMatchesRatio( sizeFull.width, sizeFull.height, sizeLarge.width, sizeLarge.height ) ) { + // If the full size image was used, and there's a large size that matches the ratio, replace full with large size. + this.updateImageURL( sizeLarge.source_url, pick( sizeLarge, [ 'width', 'height' ] ) ); + } else { + // Add image file dimensions. + this.props.setAttributes( { + fileWidth: get( sizeFull, [ 'actual_size', 'width' ] ) || sizeFull.width, + fileHeight: get( sizeFull, [ 'actual_size', 'height' ] ) || sizeFull.height, + } ); + } + } + } } onUploadError( message ) { @@ -164,10 +189,30 @@ class ImageEdit extends Component { isEditing: false, } ); + const blockWidth = getBlockWidth(); + let src = media.url; + let img = {}; + let actualWidth; + let actualHeight; + + if ( media.sizes ) { + // The "full" size is already included in `sizes`. + img = media.sizes.large || media.sizes.full; + src = img.url; + actualWidth = get( img, [ 'actual_size', 'width' ] ) || img.width; + actualHeight = get( img, [ 'actual_size', 'height' ] ) || img.height; + } + + const attr = pickRelevantMediaFiles( media ); + attr.url = src; + this.props.setAttributes( { - ...pickRelevantMediaFiles( media ), - width: undefined, - height: undefined, + ...attr, + + // Not used in the editor, passed to the front-end in block attributes. + fileWidth: actualWidth, + fileHeight: actualHeight, + editWidth: blockWidth, } ); } @@ -197,7 +242,10 @@ class ImageEdit extends Component { this.props.setAttributes( { url: newURL, id: undefined, + fileWidth: undefined, + fileHeight: undefined, } ); + this.resetWidthHeight(); } this.setState( { @@ -230,27 +278,122 @@ class ImageEdit extends Component { } updateAlignment( nextAlign ) { - const extraUpdatedAttributes = [ 'wide', 'full' ].indexOf( nextAlign ) !== -1 ? - { width: undefined, height: undefined } : - {}; - this.props.setAttributes( { ...extraUpdatedAttributes, align: nextAlign } ); + if ( nextAlign === 'wide' || nextAlign === 'full' ) { + // Reset all sizing attributes. + this.resetWidthHeight(); + } + + this.props.setAttributes( { align: nextAlign } ); } - updateImageURL( url ) { - this.props.setAttributes( { url, width: undefined, height: undefined } ); + updateImageURL( url, imageSizeOptions ) { + this.resetWidthHeight(); + let fileWidth; + let fileHeight; + + if ( imageSizeOptions.width && imageSizeOptions.height ) { + fileWidth = imageSizeOptions.width; + fileHeight = imageSizeOptions.height; + } else { + // Find the image data. + map( imageSizeOptions, ( { value, imageData } ) => { + if ( value === url ) { + fileWidth = imageData.width; + fileHeight = imageData.height; + return false; + } + } ); + } + + this.props.setAttributes( { + url, + fileWidth, + fileHeight, + } ); } - updateWidth( width ) { - this.props.setAttributes( { width: parseInt( width, 10 ) } ); + updateWidth( width, imageWidth, imageHeight, userSet ) { + width = parseInt( width, 10 ); + + // Reset the image size when the user deletes the value. + if ( ! width || ! imageWidth || ! imageHeight ) { + this.resetWidthHeight(); + return; + } + + const height = round( imageHeight * ( width / imageWidth ) ); + this.setWidthHeight( width, height, imageWidth, imageHeight, userSet ); } - updateHeight( height ) { - this.props.setAttributes( { height: parseInt( height, 10 ) } ); + updateHeight( height, imageWidth, imageHeight, userSet ) { + height = parseInt( height, 10 ); + + // Reset the image size when the user deletes the value. + if ( ! height || ! imageWidth || ! imageHeight ) { + this.resetWidthHeight(); + return; + } + + const width = round( imageWidth * ( height / imageHeight ) ); + this.setWidthHeight( width, height, imageWidth, imageHeight, userSet ); } - updateDimensions( width = undefined, height = undefined ) { - return () => { - this.props.setAttributes( { width, height } ); + setWidthHeight( width, height, imageWidth, imageHeight, userSet ) { + // Set image size and also whether set directly by the user. + userSet = userSet || undefined; + + this.props.setAttributes( { + width, + height, + imageWidth, + imageHeight, + userSet, + } ); + } + + resetWidthHeight() { + this.props.setAttributes( { + width: undefined, + height: undefined, + userSet: undefined, + } ); + } + + /** + * Helper function to test if aspect ratios for two images match. + * + * @param {number} fullWidth Width of the image in pixels. + * @param {number} fullHeight Height of the image in pixels. + * @param {number} targetWidth Width of the smaller image in pixels. + * @param {number} targetHeight Height of the smaller image in pixels. + * @return {boolean} True if aspect ratios match within 1px. False if not. + */ + imageMatchesRatio( fullWidth, fullHeight, targetWidth, targetHeight ) { + if ( ! fullWidth || ! fullHeight || ! targetWidth || ! targetHeight ) { + return false; + } + + const { width, height } = this.constrainImageDimensions( fullWidth, fullHeight, targetWidth ); + + // If the image dimensions are within 1px of the expected size, we consider it a match. + return ( Math.abs( width - targetWidth ) <= 1 && Math.abs( height - targetHeight ) <= 1 ); + } + + constrainImageDimensions( fullWidth, fullHeight, targetWidth ) { + const ratio = targetWidth / fullWidth; + + // Very small dimensions may result in 0, 1 should be the minimum. + const height = Math.max( 1, round( fullHeight * ratio ) ); + let width = Math.max( 1, round( fullWidth * ratio ) ); + + // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short. + if ( width === targetWidth - 1 ) { + width = targetWidth; // Round it up + } + + return { + width: width, + height: height, }; } @@ -272,13 +415,14 @@ class ImageEdit extends Component { getImageSizeOptions() { const { imageSizes, image } = this.props; return compact( map( imageSizes, ( { name, slug } ) => { - const sizeUrl = get( image, [ 'media_details', 'sizes', slug, 'source_url' ] ); - if ( ! sizeUrl ) { + const imageData = get( image, [ 'media_details', 'sizes', slug ] ); + if ( ! imageData || ! imageData.source_url ) { return null; } return { - value: sizeUrl, label: name, + value: imageData.source_url, + imageData: imageData, }; } ) ); } @@ -296,7 +440,7 @@ 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, linkDestination, width, height, userSet, linkTarget } = attributes; const isExternal = isExternalImage( id, url ); const imageSizeOptions = this.getImageSizeOptions(); @@ -387,7 +531,9 @@ class ImageEdit extends Component { label={ __( 'Image Size' ) } value={ url } options={ imageSizeOptions } - onChange={ this.updateImageURL } + onChange={ ( src ) => { + this.updateImageURL( src, imageSizeOptions ); + } } /> ) } { isResizable && ( @@ -400,45 +546,57 @@ class ImageEdit extends Component { type="number" className="block-library-image__dimensions__width" label={ __( 'Width' ) } - value={ width !== undefined ? width : '' } + value={ userSet ? width : '' } placeholder={ imageWidth } min={ 1 } - onChange={ this.updateWidth } + onChange={ ( value ) => { + this.updateWidth( value, imageWidth, imageHeight, true ); + } } /> { + this.updateHeight( value, imageWidth, imageHeight, true ); + } } />
- { [ 25, 50, 75, 100 ].map( ( scale ) => { - const scaledWidth = Math.round( imageWidth * ( scale / 100 ) ); - const scaledHeight = Math.round( imageHeight * ( scale / 100 ) ); - - const isCurrent = width === scaledWidth && height === scaledHeight; + { [ 25, 50, 75, 100 ].map( ( percent ) => { + const blockWidth = getBlockWidth(); + + // Percentage is relative to the block width. + let scaledWidth = round( blockWidth * ( percent / 100 ) ); + let isCurrent = false; + + if ( scaledWidth > imageWidth ) { + scaledWidth = imageWidth; + isCurrent = percent === 100 && ( ! width || width === scaledWidth ); + } else { + isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > blockWidth ); + } return ( ); } ) } @@ -492,21 +650,36 @@ class ImageEdit extends Component { // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions const img = {; + // Floating a resized image can produce inaccurate `imageWidthWithinContainer`. + const ratio = imageWidth / imageHeight; + const blockWidth = getBlockWidth(); + let constrainedWidth; + let constrainedHeight; + + if ( ( align === 'wide' || align === 'full' ) && imageWidthWithinContainer > blockWidth ) { + // Do not limit the width. + constrainedWidth = imageWidthWithinContainer; + constrainedHeight = imageHeightWithinContainer; + } else { + constrainedWidth = width || imageWidth; + constrainedWidth = constrainedWidth > blockWidth ? blockWidth : constrainedWidth; + constrainedHeight = round( constrainedWidth / ratio ) || undefined; + } + if ( ! isResizable || ! imageWidthWithinContainer ) { return ( { getInspectorControls( imageWidth, imageHeight ) } -
+
{ img }
); } - const currentWidth = width || imageWidthWithinContainer; - const currentHeight = height || imageHeightWithinContainer; - - const ratio = imageWidth / imageHeight; const minWidth = imageWidth < imageHeight ? MIN_SIZE : MIN_SIZE * ratio; const minHeight = imageHeight < imageWidth ? MIN_SIZE : MIN_SIZE / ratio; @@ -544,9 +717,9 @@ class ImageEdit extends Component { { getInspectorControls( imageWidth, imageHeight ) } { - setAttributes( { - width: parseInt( currentWidth + delta.width, 10 ), - height: parseInt( currentHeight + delta.height, 10 ), - } ); + let newWidth = parseInt( constrainedWidth + delta.width, 10 ); + + // Snap-to-border for the last pixel when resizing by dragging. + // That highlights the 100% width button. + if ( Math.abs( constrainedWidth - newWidth ) < 2 ) { + newWidth = constrainedWidth; + } + + // Don't upscale. + if ( newWidth > imageWidth ) { + newWidth = imageWidth; + } + + this.updateWidth( newWidth, imageWidth, imageHeight ); toggleSelection( true ); } } > diff --git a/packages/block-library/src/image/image-size.js b/packages/block-library/src/image/image-size.js index 0a1b88aed12d71..cc43b400b005ac 100644 --- a/packages/block-library/src/image/image-size.js +++ b/packages/block-library/src/image/image-size.js @@ -9,6 +9,11 @@ import { noop } from 'lodash'; import { withGlobalEvents } from '@wordpress/compose'; import { Component } from '@wordpress/element'; +export function getBlockWidth() { + const node = document.querySelector( 'div.editor-block-list__block' ); + return node && node.clientWidth - 30; +} + class ImageSize extends Component { constructor() { super( ...arguments ); diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js index 4f6619a6c6e527..c2d94416038cdf 100644 --- a/packages/block-library/src/image/index.js +++ b/packages/block-library/src/image/index.js @@ -30,15 +30,9 @@ export const name = 'core/image'; const blockAttributes = { url: { type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'src', }, alt: { type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'alt', default: '', }, caption: { @@ -64,6 +58,19 @@ const blockAttributes = { height: { type: 'number', }, + fileWidth: { + type: 'number', + }, + fileHeight: { + type: 'number', + }, + userSet: { + type: 'boolean', + default: false, + }, + editWidth: { + type: 'number', + }, linkDestination: { type: 'string', default: 'none', From 110545190e6ac8bf456023368ebc90b351031171 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Fri, 16 Nov 2018 12:03:57 +0200 Subject: [PATCH 02/40] Fix upscaling --- packages/block-library/src/image/edit.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 01ca815fe9580a..9f1ad542685597 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -759,9 +759,9 @@ class ImageEdit extends Component { } : undefined } minWidth={ minWidth } - maxWidth={ maxWidthBuffer } + maxWidth={ imageWidth || maxWidthBuffer } minHeight={ minHeight } - maxHeight={ maxWidthBuffer / ratio } + maxHeight={ imageHeight || ( maxWidthBuffer / ratio ) } lockAspectRatio enable={ { top: false, @@ -775,8 +775,7 @@ class ImageEdit extends Component { onResizeStop={ ( event, direction, elt, delta ) => { let newWidth = parseInt( constrainedWidth + delta.width, 10 ); - // Snap-to-border for the last pixel when resizing by dragging. - // That highlights the 100% width button. + // Snap-to-border for the last pixel when resizing by dragging. Takes care of rounding of the last pixel. if ( Math.abs( constrainedWidth - newWidth ) < 2 ) { newWidth = constrainedWidth; } @@ -786,7 +785,13 @@ class ImageEdit extends Component { newWidth = imageWidth; } - this.updateWidth( newWidth, imageWidth, imageHeight ); + if ( newWidth >= blockWidth ) { + // The image was resized to greater than the block width. Reset the width and height (that will also highlight the 100% width button). + this.resetWidthHeight(); + } else { + this.updateWidth( newWidth, imageWidth, imageHeight ); + } + toggleSelection( true ); } } > From 1c5b8a01eeb13eb708c760ed7ab734e9793f163b Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Fri, 16 Nov 2018 13:29:54 +0200 Subject: [PATCH 03/40] Fix param/prop names --- lib/compat.php | 2 +- packages/block-library/src/image/edit.js | 37 ++++++++++++++---------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index f6f08989043f12..bc7f219f3638f4 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -461,7 +461,7 @@ function gutenberg_render_block_core_image( $html, $block ) { $image_src = ''; $srcset = ''; $sizes = ''; -//Q( $image_dimensions ); + if ( empty( $image_dimensions ) ) { // We don't have enough data to construct new img tag. Fall back to the existing HTML. return $html; diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 9f1ad542685597..f4d0a44a311f7b 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -318,46 +318,53 @@ class ImageEdit extends Component { } ); } - updateWidth( width, imageWidth, imageHeight, userSet ) { + updateWidth( width, fileWidth, fileHeight, userSet ) { width = parseInt( width, 10 ); // Reset the image size when the user deletes the value. - if ( ! width || ! imageWidth || ! imageHeight ) { + if ( ! width || ! fileWidth || ! fileHeight ) { this.resetWidthHeight(); return; } - const height = round( imageHeight * ( width / imageWidth ) ); - this.setWidthHeight( width, height, imageWidth, imageHeight, userSet ); + const height = round( fileHeight * ( width / fileWidth ) ); + this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); } - updateHeight( height, imageWidth, imageHeight, userSet ) { + updateHeight( height, fileWidth, fileHeight, userSet ) { height = parseInt( height, 10 ); // Reset the image size when the user deletes the value. - if ( ! height || ! imageWidth || ! imageHeight ) { + if ( ! height || ! fileWidth || ! fileHeight ) { this.resetWidthHeight(); return; } - const width = round( imageWidth * ( height / imageHeight ) ); - this.setWidthHeight( width, height, imageWidth, imageHeight, userSet ); + const width = round( fileWidth * ( height / fileHeight ) ); + this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); } - setWidthHeight( width, height, imageWidth, imageHeight, userSet ) { + setWidthHeight( width, height, fileWidth, fileHeight, userSet ) { // Set image size and also whether set directly by the user. userSet = userSet || undefined; this.props.setAttributes( { width, height, - imageWidth, - imageHeight, + fileWidth, + fileHeight, userSet, } ); } - resetWidthHeight() { + resetWidthHeight( fileWidth, fileHeight ) { + if ( fileWidth && fileHeight ) { + this.props.setAttributes( { + fileWidth, + fileHeight, + } ); + } + this.props.setAttributes( { width: undefined, height: undefined, @@ -609,7 +616,7 @@ class ImageEdit extends Component { @@ -786,8 +793,8 @@ class ImageEdit extends Component { } if ( newWidth >= blockWidth ) { - // The image was resized to greater than the block width. Reset the width and height (that will also highlight the 100% width button). - this.resetWidthHeight(); + // The image was resized to greater than the block width. Reset to 100% width and height (that will also highlight the 100% width button). + this.resetWidthHeight( imageWidth, imageHeight ); } else { this.updateWidth( newWidth, imageWidth, imageHeight ); } From 03444d7bdda0d79dcc540d0fbfa5141c2a14de78 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Sat, 17 Nov 2018 09:09:19 +0200 Subject: [PATCH 04/40] Better filter name, allow valueless attributes --- lib/compat.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index bc7f219f3638f4..ff39751613acff 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -426,7 +426,7 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * @param array $block_attributes The block attributes. * @param array $image_meta The image attachment meta data. */ - return apply_filters( 'gutenberg_get_image_width_height', $image_dimensions, $block_attributes, $image_meta ); + return apply_filters( 'block_core_image_get_width_height', $image_dimensions, $block_attributes, $image_meta ); } function gutenberg_render_block_core_image( $html, $block ) { @@ -520,7 +520,11 @@ function gutenberg_render_block_core_image( $html, $block ) { $value = esc_attr( $value ); } - $attr .= sprintf( ' %s="%s"', $name, $value ); + if ( empty( $value ) ) { + $attr .= ' ' . $name; + } else { + $attr .= sprintf( ' %s="%s"', $name, $value ); + } } $image_tag = ''; From 1aa5b35ad9ea290aa28a678c625d04885b82d677 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 09:59:17 -0500 Subject: [PATCH 05/40] Compat: Resolve PHP lint errors --- lib/compat.php | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 76b5320f5e2d26..f76afc7da46c0e 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -316,11 +316,11 @@ function gutenberg_warn_classic_about_blocks() { * @return array Array of prepared attachment data. */ function gutenberg_prepare_attachment_for_js( $response, $attachment, $meta ) { - if ( ! empty( $response['type'] ) && $response['type'] === 'image' && ! empty( $response['sizes'] ) ) { + if ( ! empty( $response['type'] ) && 'image' === $response['type'] && ! empty( $response['sizes'] ) ) { foreach ( $response['sizes'] as $size_name => $size ) { if ( array_key_exists( $size_name, $meta['sizes'] ) ) { $response['sizes'][ $size_name ]['actual_size'] = array( - 'width' => (int) $meta['sizes'][ $size_name ]['width'], + 'width' => (int) $meta['sizes'][ $size_name ]['width'], 'height' => (int) $meta['sizes'][ $size_name ]['height'], ); } @@ -402,7 +402,7 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * add "xlarge" image size generated by default! */ if ( ! empty( $image_meta ) && - ( $block_attributes['align'] === 'wide' || $block_attributes['align'] === 'full' ) && + ( 'wide' === $block_attributes['align'] || 'full' === $block_attributes['align'] ) && ! empty( $block_attributes['fileWidth'] ) && $block_attributes['fileWidth'] < $image_meta['width'] && max( (int) $image_meta['width'], (int) $image_meta['height'] ) < 4300 && // max 12 MP photo (that's still may be over 3MB, consider reducing). @@ -428,16 +428,25 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null return apply_filters( 'block_core_image_get_width_height', $image_dimensions, $block_attributes, $image_meta ); } +/** + * Filters the rendered output of the Image block to include generated HTML + * attributes for front-end display. + * + * @param string $html Original HTML. + * @param array $block Parsed block. + * + * @return string Filtered Image block HTML. + */ function gutenberg_render_block_core_image( $html, $block ) { - // Old post or... something's wrong. + // Old post or... something's wrong. if ( empty( $html ) || empty( $block['attrs'] ) ) { return $html; } $defaults = array( - 'url' => '', - 'alt' => '', - 'id' => 0, + 'url' => '', + 'alt' => '', + 'id' => 0, 'align' => '', ); @@ -450,16 +459,16 @@ function gutenberg_render_block_core_image( $html, $block ) { if ( ! empty( $block_attributes['id'] ) ) { $attachment_id = (int) $block_attributes['id']; - $image_meta = wp_get_attachment_metadata( $attachment_id ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); } else { - $image_meta = null; + $image_meta = null; $attachment_id = 0; } $image_dimensions = gutenberg_get_image_width_height( $block_attributes, $image_meta ); - $image_src = ''; - $srcset = ''; - $sizes = ''; + $image_src = ''; + $srcset = ''; + $sizes = ''; if ( empty( $image_dimensions ) ) { // We don't have enough data to construct new img tag. Fall back to the existing HTML. @@ -469,9 +478,9 @@ function gutenberg_render_block_core_image( $html, $block ) { $image_src = $block_attributes['url']; $image_attributes = array( - 'src' => $image_src, - 'alt' => empty( $block_attributes['alt'] ) ? '' : $block_attributes['alt'], - 'width' => $image_dimensions[0], + 'src' => $image_src, + 'alt' => empty( $block_attributes['alt'] ) ? '' : $block_attributes['alt'], + 'width' => $image_dimensions[0], 'height' => $image_dimensions[1], ); @@ -486,7 +495,7 @@ function gutenberg_render_block_core_image( $html, $block ) { if ( $srcset && $sizes ) { $image_attributes['srcset'] = $srcset; - $image_attributes['sizes'] = $sizes; + $image_attributes['sizes'] = $sizes; } } From 2a9fba9c11ab18be5016266c3801b4d1905ed1fb Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 10:17:41 -0500 Subject: [PATCH 06/40] Compat: Correct closing img tag --- lib/compat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat.php b/lib/compat.php index f76afc7da46c0e..073515998c58e0 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -535,7 +535,7 @@ function gutenberg_render_block_core_image( $html, $block ) { } } - $image_tag = ''; + $image_tag = ''; // Replace the img tag. $html = preg_replace( '/]+>/', $image_tag, $html ); From 04706dd63487a0008b9f9e18d4a32635438ac4e1 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 10:23:13 -0500 Subject: [PATCH 07/40] Compat: Allow optional space after img tag name --- lib/compat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat.php b/lib/compat.php index 073515998c58e0..279f4f87478e4e 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -538,7 +538,7 @@ function gutenberg_render_block_core_image( $html, $block ) { $image_tag = ''; // Replace the img tag. - $html = preg_replace( '/]+>/', $image_tag, $html ); + $html = preg_replace( '/]+>/', $image_tag, $html ); return $html; } From 08473d8f5532496e75f07083a5be05bf2f7df598 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 10:23:44 -0500 Subject: [PATCH 08/40] Compat: PHPDoc formatting and arrangement style --- lib/compat.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 279f4f87478e4e..8b0c17d880eec1 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -346,7 +346,11 @@ function _gutenberg_cache_images_meta( $content ) { // Need to find all image blocks and get the attachment IDs from them BEFORE the parser is run // so we can get the image attachments meta all at once from the DB. if ( preg_match_all( '/^$/m', $content, $matches ) ) { - _prime_post_caches( $matches[1], false, true ); + _prime_post_caches( + $matches[1], + /* $update_term_cache */ false, + /* $update_meta_cache */ true + ); } return $content; @@ -397,7 +401,7 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null } /* - * Do not constrain images with "wide" and "full" allignment to the "large" image size. + * Do not constrain images with "wide" and "full" alignment to the "large" image size. * TODO: To reduce (fix) the need for upscaling or using the "full" size images * add "xlarge" image size generated by default! */ @@ -421,9 +425,10 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * * @since 4.x.x * - * @param array $image_size The calculated image size width and height (in that order). + * @param array $image_size The calculated image size width and + * height (in that order). * @param array $block_attributes The block attributes. - * @param array $image_meta The image attachment meta data. + * @param array $image_meta The image attachment meta data. */ return apply_filters( 'block_core_image_get_width_height', $image_dimensions, $block_attributes, $image_meta ); } @@ -461,8 +466,8 @@ function gutenberg_render_block_core_image( $html, $block ) { $attachment_id = (int) $block_attributes['id']; $image_meta = wp_get_attachment_metadata( $attachment_id ); } else { - $image_meta = null; $attachment_id = 0; + $image_meta = null; } $image_dimensions = gutenberg_get_image_width_height( $block_attributes, $image_meta ); @@ -504,10 +509,11 @@ function gutenberg_render_block_core_image( $html, $block ) { * * @since 4.x.x * - * @param array $image_attributes The (recalculated) image attributes. - * Note: expects valid HTML 5.0 attribute names. - * @param array $block_attributes The image block attributes. - * @param string $html The image block HTML coming from the editor. The img tag will be replaced. + * @param array $image_attributes The (recalculated) image attributes. + * Note: expects valid HTML 5.0 attribute names. + * @param array $block_attributes The image block attributes. + * @param string $html The image block HTML coming from the + * editor. The img tag will be replaced. */ $image_attributes = apply_filters( 'render_block_core_image_tag_attributes', $image_attributes, $block_attributes, $html ); From 32d5c8c6948e3fad7881c5f8d8ebb2d66e98dbfc Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 10:30:07 -0500 Subject: [PATCH 09/40] Blocks: Use Math.round for image rounding --- packages/block-library/src/image/edit.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 88e520a62383e2..c2299c1881ca90 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -8,7 +8,6 @@ import { map, last, pick, - round, compact, } from 'lodash'; @@ -369,7 +368,7 @@ class ImageEdit extends Component { return; } - const height = round( fileHeight * ( width / fileWidth ) ); + const height = Math.round( fileHeight * ( width / fileWidth ) ); this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); } @@ -382,7 +381,7 @@ class ImageEdit extends Component { return; } - const width = round( fileWidth * ( height / fileHeight ) ); + const width = Math.round( fileWidth * ( height / fileHeight ) ); this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); } @@ -438,8 +437,8 @@ class ImageEdit extends Component { const ratio = targetWidth / fullWidth; // Very small dimensions may result in 0, 1 should be the minimum. - const height = Math.max( 1, round( fullHeight * ratio ) ); - let width = Math.max( 1, round( fullWidth * ratio ) ); + const height = Math.max( 1, Math.round( fullHeight * ratio ) ); + let width = Math.max( 1, Math.round( fullWidth * ratio ) ); // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short. if ( width === targetWidth - 1 ) { @@ -649,7 +648,7 @@ class ImageEdit extends Component { const blockWidth = getBlockWidth(); // Percentage is relative to the block width. - let scaledWidth = round( blockWidth * ( percent / 100 ) ); + let scaledWidth = Math.round( blockWidth * ( percent / 100 ) ); let isCurrent = false; if ( scaledWidth > imageWidth ) { @@ -767,7 +766,7 @@ class ImageEdit extends Component { } else { constrainedWidth = width || imageWidth; constrainedWidth = constrainedWidth > blockWidth ? blockWidth : constrainedWidth; - constrainedHeight = round( constrainedWidth / ratio ) || undefined; + constrainedHeight = Math.round( constrainedWidth / ratio ) || undefined; } if ( ! isResizable || ! imageWidthWithinContainer ) { From cf50aecd899ac5ae79a2e7a4c79e0b73b074477e Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 10:42:58 -0500 Subject: [PATCH 10/40] Blocks: Add deprecation for attribute-sourced URL, alt --- packages/block-library/src/image/index.js | 145 +++++++++++++--------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js index a27a7f500f81d0..b2e330133174e7 100644 --- a/packages/block-library/src/image/index.js +++ b/packages/block-library/src/image/index.js @@ -118,6 +118,69 @@ const schema = { }, }; +function save( { attributes } ) { + const { + url, + alt, + caption, + align, + href, + rel, + linkClass, + width, + height, + id, + linkTarget, + } = attributes; + + const classes = classnames( { + [ `align${ align }` ]: align, + 'is-resized': width || height, + } ); + + const image = ( + { + ); + + const figure = ( + + { href ? ( + + { image } + + ) : image } + { ! RichText.isEmpty( caption ) && } + + ); + + if ( 'left' === align || 'right' === align || 'center' === align ) { + return ( +
+
+ { figure } +
+
+ ); + } + + return ( +
+ { figure } +
+ ); +} + export const settings = { title: __( 'Image' ), @@ -244,68 +307,7 @@ export const settings = { edit, - save( { attributes } ) { - const { - url, - alt, - caption, - align, - href, - rel, - linkClass, - width, - height, - id, - linkTarget, - } = attributes; - - const classes = classnames( { - [ `align${ align }` ]: align, - 'is-resized': width || height, - } ); - - const image = ( - { - ); - - const figure = ( - - { href ? ( - - { image } - - ) : image } - { ! RichText.isEmpty( caption ) && } - - ); - - if ( 'left' === align || 'right' === align || 'center' === align ) { - return ( -
-
- { figure } -
-
- ); - } - - return ( -
- { figure } -
- ); - }, + save, deprecated: [ { @@ -382,5 +384,24 @@ export const settings = { ); }, }, + { + attributes: { + ...blockAttributes, + url: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + alt: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + }, + save, + }, ], }; From e4cfea37d57f78922d6eb0f6b9797b92077034ea Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:14:49 -0500 Subject: [PATCH 11/40] Blocks: Use hard-coded content width for block width --- packages/block-library/src/image/edit.js | 58 ++++++++++++------- .../block-library/src/image/image-size.js | 5 -- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index c2299c1881ca90..2339ddfd0bd046 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -50,7 +50,7 @@ import { compose } from '@wordpress/compose'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; -import ImageSize, { getBlockWidth } from './image-size'; +import ImageSize from './image-size'; /** * Module constants @@ -124,6 +124,8 @@ class ImageEdit extends Component { const { attributes, setAttributes } = this.props; const { id, url = '' } = attributes; + this.setEditWidth(); + if ( isTemporaryImage( id, url ) ) { const file = getBlobByURL( url ); @@ -143,10 +145,8 @@ class ImageEdit extends Component { const { id: prevID, url: prevURL = '' } = prevProps.attributes; const { id, url = '', fileWidth } = this.props.attributes; const imageData = this.props.image; - const blockWidth = getBlockWidth(); - // Store the current block width inside the editor. - this.props.setAttributes( { editWidth: blockWidth } ); + this.setEditWidth(); if ( isTemporaryImage( prevID, prevURL ) && ! isTemporaryImage( id, url ) ) { revokeBlobURL( url ); @@ -201,18 +201,17 @@ class ImageEdit extends Component { isEditing: false, } ); - const blockWidth = getBlockWidth(); let src = media.url; let img = {}; - let actualWidth; - let actualHeight; + let fileWidth; + let fileHeight; if ( media.sizes ) { // The "full" size is already included in `sizes`. img = media.sizes.large || media.sizes.full; src = img.url; - actualWidth = get( img, [ 'actual_size', 'width' ] ) || img.width; - actualHeight = get( img, [ 'actual_size', 'height' ] ) || img.height; + fileWidth = get( img, [ 'actual_size', 'width' ] ) || img.width; + fileHeight = get( img, [ 'actual_size', 'height' ] ) || img.height; } const attr = pickRelevantMediaFiles( media ); @@ -222,9 +221,8 @@ class ImageEdit extends Component { ...attr, // Not used in the editor, passed to the front-end in block attributes. - fileWidth: actualWidth, - fileHeight: actualHeight, - editWidth: blockWidth, + fileWidth, + fileHeight, } ); } @@ -451,6 +449,18 @@ class ImageEdit extends Component { }; } + /** + * Update the block's `editWidth` attribute if not aligned to the current + * `contentWidth` prop. + */ + setEditWidth() { + const { attributes, setAttributes, contentWidth } = this.props; + const { editWidth } = attributes; + if ( contentWidth !== editWidth ) { + setAttributes( { editWidth: contentWidth } ); + } + } + getFilename( url ) { const path = getPath( url ); if ( path ) { @@ -500,6 +510,7 @@ class ImageEdit extends Component { noticeUI, toggleSelection, isRTL, + contentWidth, } = this.props; const { url, @@ -645,17 +656,15 @@ class ImageEdit extends Component {
{ [ 25, 50, 75, 100 ].map( ( percent ) => { - const blockWidth = getBlockWidth(); - // Percentage is relative to the block width. - let scaledWidth = Math.round( blockWidth * ( percent / 100 ) ); + let scaledWidth = Math.round( contentWidth * ( percent / 100 ) ); let isCurrent = false; if ( scaledWidth > imageWidth ) { scaledWidth = imageWidth; isCurrent = percent === 100 && ( ! width || width === scaledWidth ); } else { - isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > blockWidth ); + isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > contentWidth ); } return ( @@ -755,17 +764,16 @@ class ImageEdit extends Component { // Floating a resized image can produce inaccurate `imageWidthWithinContainer`. const ratio = imageWidth / imageHeight; - const blockWidth = getBlockWidth(); let constrainedWidth; let constrainedHeight; - if ( ( align === 'wide' || align === 'full' ) && imageWidthWithinContainer > blockWidth ) { + if ( ( align === 'wide' || align === 'full' ) && imageWidthWithinContainer > contentWidth ) { // Do not limit the width. constrainedWidth = imageWidthWithinContainer; constrainedHeight = imageHeightWithinContainer; } else { constrainedWidth = width || imageWidth; - constrainedWidth = constrainedWidth > blockWidth ? blockWidth : constrainedWidth; + constrainedWidth = constrainedWidth > contentWidth ? contentWidth : constrainedWidth; constrainedHeight = Math.round( constrainedWidth / ratio ) || undefined; } @@ -859,7 +867,7 @@ class ImageEdit extends Component { newWidth = imageWidth; } - if ( newWidth >= blockWidth ) { + if ( newWidth >= contentWidth ) { // The image was resized to greater than the block width. Reset to 100% width and height (that will also highlight the 100% width button). this.resetWidthHeight( imageWidth, imageHeight ); } else { @@ -898,13 +906,21 @@ export default compose( [ const { getMedia } = select( 'core' ); const { getEditorSettings } = select( 'core/editor' ); const { id } = props.attributes; - const { maxWidth, isRTL, imageSizes } = getEditorSettings(); + const { + maxWidth, + isRTL, + imageSizes, + // Note: At the time of implementation, this value will never be + // found in settings and always default to the hard-coded value. + contentWidth = 580, + } = getEditorSettings(); return { image: id ? getMedia( id ) : null, maxWidth, isRTL, imageSizes, + contentWidth, }; } ), withViewportMatch( { isLargeViewport: 'medium' } ), diff --git a/packages/block-library/src/image/image-size.js b/packages/block-library/src/image/image-size.js index cc43b400b005ac..0a1b88aed12d71 100644 --- a/packages/block-library/src/image/image-size.js +++ b/packages/block-library/src/image/image-size.js @@ -9,11 +9,6 @@ import { noop } from 'lodash'; import { withGlobalEvents } from '@wordpress/compose'; import { Component } from '@wordpress/element'; -export function getBlockWidth() { - const node = document.querySelector( 'div.editor-block-list__block' ); - return node && node.clientWidth - 30; -} - class ImageSize extends Component { constructor() { super( ...arguments ); From 4c49a8dba1f5a87a467764822d7c2a356cbe975d Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:30:49 -0500 Subject: [PATCH 12/40] Blocks: Limit editWith assignment to insert, resize --- packages/block-library/src/image/edit.js | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 2339ddfd0bd046..f91b2d09763d16 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -124,8 +124,6 @@ class ImageEdit extends Component { const { attributes, setAttributes } = this.props; const { id, url = '' } = attributes; - this.setEditWidth(); - if ( isTemporaryImage( id, url ) ) { const file = getBlobByURL( url ); @@ -146,8 +144,6 @@ class ImageEdit extends Component { const { id, url = '', fileWidth } = this.props.attributes; const imageData = this.props.image; - this.setEditWidth(); - if ( isTemporaryImage( prevID, prevURL ) && ! isTemporaryImage( id, url ) ) { revokeBlobURL( url ); } @@ -223,6 +219,7 @@ class ImageEdit extends Component { // Not used in the editor, passed to the front-end in block attributes. fileWidth, fileHeight, + editWidth: this.props.contentWidth, } ); } @@ -393,6 +390,7 @@ class ImageEdit extends Component { fileWidth, fileHeight, userSet, + editWidth: this.props.contentwidth, } ); } @@ -408,6 +406,7 @@ class ImageEdit extends Component { width: undefined, height: undefined, userSet: undefined, + editWidth: this.props.contentwidth, } ); } @@ -449,18 +448,6 @@ class ImageEdit extends Component { }; } - /** - * Update the block's `editWidth` attribute if not aligned to the current - * `contentWidth` prop. - */ - setEditWidth() { - const { attributes, setAttributes, contentWidth } = this.props; - const { editWidth } = attributes; - if ( contentWidth !== editWidth ) { - setAttributes( { editWidth: contentWidth } ); - } - } - getFilename( url ) { const path = getPath( url ); if ( path ) { From f9da97f06e92cbf4bdd0a7b2ed135592b8f3a9cf Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:36:21 -0500 Subject: [PATCH 13/40] Blocks: Rename Image userSet to userSetDimensions --- lib/compat.php | 4 ++-- packages/block-library/src/image/edit.js | 22 +++++++++++----------- packages/block-library/src/image/index.js | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 8b0c17d880eec1..0a27c231bad967 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -380,11 +380,11 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * Here we can use `$block_attributes['editWidth']` to scale the image * if we know the theme's "expected width" (in pixels). * - * Note that if the `$block_attributes['userSet']` is set/true, the user has entered + * Note that if the `$block_attributes['userSetDimensions']` is set/true, the user has entered * the width and height by hand, they shouldn't probably be changed. * * Something like: - * if ( empty( $block_attributes['userSet'] ) && ! empty( $block_attributes['editWidth'] ) && $content_width <> $block_attributes['editWidth'] ) { + * if ( empty( $block_attributes['userSetDimensions'] ) && ! empty( $block_attributes['editWidth'] ) && $content_width <> $block_attributes['editWidth'] ) { * // Scale the image if the block width in the editor was different than the current theme width. * $scale = $content_width / $block_attributes['editWidth']; * $image_width = round( $block_attributes['width'] * $scale ); diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index f91b2d09763d16..c8c22ac83b2420 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -354,7 +354,7 @@ class ImageEdit extends Component { } ); } - updateWidth( width, fileWidth, fileHeight, userSet ) { + updateWidth( width, fileWidth, fileHeight, userSetDimensions ) { width = parseInt( width, 10 ); // Reset the image size when the user deletes the value. @@ -364,10 +364,10 @@ class ImageEdit extends Component { } const height = Math.round( fileHeight * ( width / fileWidth ) ); - this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); + this.setWidthHeight( width, height, fileWidth, fileHeight, userSetDimensions ); } - updateHeight( height, fileWidth, fileHeight, userSet ) { + updateHeight( height, fileWidth, fileHeight, userSetDimensions ) { height = parseInt( height, 10 ); // Reset the image size when the user deletes the value. @@ -377,19 +377,19 @@ class ImageEdit extends Component { } const width = Math.round( fileWidth * ( height / fileHeight ) ); - this.setWidthHeight( width, height, fileWidth, fileHeight, userSet ); + this.setWidthHeight( width, height, fileWidth, fileHeight, userSetDimensions ); } - setWidthHeight( width, height, fileWidth, fileHeight, userSet ) { + setWidthHeight( width, height, fileWidth, fileHeight, userSetDimensions ) { // Set image size and also whether set directly by the user. - userSet = userSet || undefined; + userSetDimensions = userSetDimensions || undefined; this.props.setAttributes( { width, height, fileWidth, fileHeight, - userSet, + userSetDimensions, editWidth: this.props.contentwidth, } ); } @@ -405,7 +405,7 @@ class ImageEdit extends Component { this.props.setAttributes( { width: undefined, height: undefined, - userSet: undefined, + userSetDimensions: undefined, editWidth: this.props.contentwidth, } ); } @@ -511,7 +511,7 @@ class ImageEdit extends Component { linkDestination, width, height, - userSet, + userSetDimensions, linkTarget, } = attributes; const isExternal = isExternalImage( id, url ); @@ -621,7 +621,7 @@ class ImageEdit extends Component { type="number" className="block-library-image__dimensions__width" label={ __( 'Width' ) } - value={ userSet ? width : '' } + value={ userSetDimensions ? width : '' } placeholder={ imageWidth } min={ 1 } onChange={ ( value ) => { @@ -632,7 +632,7 @@ class ImageEdit extends Component { type="number" className="block-library-image__dimensions__height" label={ __( 'Height' ) } - value={ userSet ? height : '' } + value={ userSetDimensions ? height : '' } placeholder={ imageHeight } min={ 1 } onChange={ ( value ) => { diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js index b2e330133174e7..c72640960a3b3e 100644 --- a/packages/block-library/src/image/index.js +++ b/packages/block-library/src/image/index.js @@ -76,7 +76,7 @@ const blockAttributes = { fileHeight: { type: 'number', }, - userSet: { + userSetDimensions: { type: 'boolean', default: false, }, From 8cef6ac8262cdc2e7c4b6ac3b8005a6d7edf9bcb Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:39:21 -0500 Subject: [PATCH 14/40] Blocks: Remove redundant userSetDimensions normalization --- packages/block-library/src/image/edit.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index c8c22ac83b2420..5bd8f6950815e4 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -381,9 +381,6 @@ class ImageEdit extends Component { } setWidthHeight( width, height, fileWidth, fileHeight, userSetDimensions ) { - // Set image size and also whether set directly by the user. - userSetDimensions = userSetDimensions || undefined; - this.props.setAttributes( { width, height, From 84d68660a8deb9a3df0f14d2f7d8c3c0570cc17d Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:44:51 -0500 Subject: [PATCH 15/40] Blocks: Document constrainImageDimensions as ported from PHP --- packages/block-library/src/image/edit.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 5bd8f6950815e4..fd47726e6df7b5 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -427,6 +427,19 @@ class ImageEdit extends Component { return ( Math.abs( width - targetWidth ) <= 1 && Math.abs( height - targetHeight ) <= 1 ); } + /** + * Calculates the new dimensions for a down-sampled image. + * + * Note that this is nearly a direct port of the equivalent PHP function + * `wp_constrain_dimensions`, and any refactorings should be made in mind + * of cross-environment applicability. + * + * @param {number} fullWidth Current width of the image. + * @param {number} fullHeight Current height of the image. + * @param {number} targetWidth Max width in pixels to constrain to. + * + * @return {Object} Object of `width`, `height` values. + */ constrainImageDimensions( fullWidth, fullHeight, targetWidth ) { const ratio = targetWidth / fullWidth; From db48c26e2b75dbabc6c6bd5bf6bbbecb6be545da Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:48:17 -0500 Subject: [PATCH 16/40] Blocks: Avoid mutative, unused Array#map result --- packages/block-library/src/image/edit.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index fd47726e6df7b5..05b07580226733 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -9,6 +9,7 @@ import { last, pick, compact, + find, } from 'lodash'; /** @@ -338,13 +339,11 @@ class ImageEdit extends Component { fileHeight = imageSizeOptions.height; } else { // Find the image data. - map( imageSizeOptions, ( { value, imageData } ) => { - if ( value === url ) { - fileWidth = imageData.width; - fileHeight = imageData.height; - return false; - } - } ); + const size = find( imageSizeOptions, { value: url } ); + if ( size ) { + fileWidth = size.imageData.width; + fileHeight = size.imageData.height; + } } this.props.setAttributes( { From b2bc0e7281997d1d8eb927b1ff25e4ad63390549 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 11:54:57 -0500 Subject: [PATCH 17/40] Block: Avoid overloading Image block updateImageURL --- packages/block-library/src/image/edit.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 05b07580226733..4889f5e292c98a 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -329,17 +329,25 @@ class ImageEdit extends Component { this.props.setAttributes( { align: nextAlign } ); } - updateImageURL( url, imageSizeOptions ) { + /** + * Sets the `url` attribute of the block to the provided value, optionally + * with an explicit dimensions. If `dimensions` are not provided, the + * equivalent image size values will be used instead, if known and exists. + * + * @param {string} url URL to assign as block attribute. + * @param {?Object} dimensions Optional object of width, height values. + */ + updateImageURL( url, dimensions ) { this.resetWidthHeight(); let fileWidth; let fileHeight; - if ( imageSizeOptions.width && imageSizeOptions.height ) { - fileWidth = imageSizeOptions.width; - fileHeight = imageSizeOptions.height; + if ( dimensions && dimensions.width && dimensions.height ) { + fileWidth = dimensions.width; + fileHeight = dimensions.height; } else { // Find the image data. - const size = find( imageSizeOptions, { value: url } ); + const size = find( this.getImageSizeOptions(), { value: url } ); if ( size ) { fileWidth = size.imageData.width; fileHeight = size.imageData.height; @@ -615,9 +623,7 @@ class ImageEdit extends Component { label={ __( 'Image Size' ) } value={ url } options={ imageSizeOptions } - onChange={ ( src ) => { - this.updateImageURL( src, imageSizeOptions ); - } } + onChange={ this.updateImageURL } /> ) } { isResizable && ( From f69ec357c24823e59162dd8c1cbca59137c4a6db Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 12:01:03 -0500 Subject: [PATCH 18/40] Blocks: Fix Image accidental inline tab character --- packages/block-library/src/image/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 4889f5e292c98a..08a47b7d92b90e 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -775,7 +775,7 @@ class ImageEdit extends Component { constrainedHeight = imageHeightWithinContainer; } else { constrainedWidth = width || imageWidth; - constrainedWidth = constrainedWidth > contentWidth ? contentWidth : constrainedWidth; + constrainedWidth = constrainedWidth > contentWidth ? contentWidth : constrainedWidth; constrainedHeight = Math.round( constrainedWidth / ratio ) || undefined; } From 009eceb730d8fb4581ae9307f71262ff9b8131fc Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 12:15:58 -0500 Subject: [PATCH 19/40] Compat: Avoid assumption of ID as non-last attribute of image --- lib/compat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat.php b/lib/compat.php index 0a27c231bad967..4f586d2201dd93 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -345,7 +345,7 @@ function gutenberg_prepare_attachment_for_js( $response, $attachment, $meta ) { function _gutenberg_cache_images_meta( $content ) { // Need to find all image blocks and get the attachment IDs from them BEFORE the parser is run // so we can get the image attachments meta all at once from the DB. - if ( preg_match_all( '/^$/m', $content, $matches ) ) { + if ( preg_match_all( '/^$/m', $content, $matches ) ) { _prime_post_caches( $matches[1], /* $update_term_cache */ false, From bf9d58c922e6b501626cdf44adc82873f408fa22 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 12:20:06 -0500 Subject: [PATCH 20/40] Compat: Document image block RegEx as temporary solution --- lib/compat.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 4f586d2201dd93..2138893c91d51c 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -343,8 +343,13 @@ function gutenberg_prepare_attachment_for_js( $response, $attachment, $meta ) { * @return string $content Unchanged post content. */ function _gutenberg_cache_images_meta( $content ) { - // Need to find all image blocks and get the attachment IDs from them BEFORE the parser is run - // so we can get the image attachments meta all at once from the DB. + // Need to find all image blocks and their attachment IDs BEFORE block + // filtering evaluates the rendered result so that attachements meta is + // retrieved all at once from the DB. + // + // [TODO]: When available, the regular expression should be avoided in + // favor of a filter on the parsed result of blocks, still prior to the + // rendered evaluation. if ( preg_match_all( '/^$/m', $content, $matches ) ) { _prime_post_caches( $matches[1], From 51e6c963eb2036b18d43c992712df21835923821 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 12:37:44 -0500 Subject: [PATCH 21/40] Blocks: Pick url, alt in raw transform from image node Since these are no longer sourced from attributes and instead assumed to exist in comment attributes, they must be passed explicitly --- packages/block-library/src/image/index.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js index c72640960a3b3e..0b6fdeb5a03fa8 100644 --- a/packages/block-library/src/image/index.js +++ b/packages/block-library/src/image/index.js @@ -216,7 +216,19 @@ export const settings = { const href = anchorElement && anchorElement.href ? anchorElement.href : undefined; 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 } ); + const imgElement = node.querySelector( 'img' ); + const url = imgElement.src; + const alt = imgElement.alt; + const attributes = getBlockAttributes( 'core/image', node.outerHTML, { + url, + alt, + align, + id, + linkDestination, + href, + rel, + linkClass, + } ); return createBlock( 'core/image', attributes ); }, }, From 174bee0757c5e13e050a5c0d188001c78124d288 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 12:47:53 -0500 Subject: [PATCH 22/40] Framework: Regenerate fixtures --- .../fixtures/core__audio.parsed.json | 8 ++++++-- .../fixtures/core__block.parsed.json | 4 +++- .../fixtures/core__button__center.parsed.json | 8 ++++++-- .../fixtures/core__categories.parsed.json | 4 +++- .../fixtures/core__code.parsed.json | 8 ++++++-- .../fixtures/core__column.parsed.json | 20 +++++++++++++++---- .../core__image__custom-link-class.json | 4 ++-- ...core__image__custom-link-class.parsed.json | 20 +++++++++---------- .../core__image__custom-link-rel.json | 4 ++-- .../core__image__custom-link-rel.parsed.json | 20 +++++++++---------- .../fixtures/core__missing.parsed.json | 8 ++++++-- .../fixtures/core__more.parsed.json | 8 ++++++-- ...core__more__custom-text-teaser.parsed.json | 8 ++++++-- .../fixtures/core__nextpage.parsed.json | 8 ++++++-- .../core__paragraph__align-right.parsed.json | 8 ++++++-- .../core__paragraph__deprecated.parsed.json | 8 ++++++-- .../fixtures/core__preformatted.parsed.json | 8 ++++++-- .../fixtures/core__pullquote.parsed.json | 8 ++++++-- ...re__pullquote__multi-paragraph.parsed.json | 8 ++++++-- .../fixtures/core__quote__style-1.parsed.json | 8 ++++++-- .../fixtures/core__quote__style-2.parsed.json | 8 ++++++-- .../fixtures/core__separator.parsed.json | 8 ++++++-- .../fixtures/core__shortcode.parsed.json | 8 ++++++-- .../fixtures/core__spacer.parsed.json | 8 ++++++-- .../fixtures/core__subhead.parsed.json | 8 ++++++-- .../fixtures/core__table.parsed.json | 8 ++++++-- .../fixtures/core__text-columns.parsed.json | 8 ++++++-- ...e__text__converts-to-paragraph.parsed.json | 8 ++++++-- .../fixtures/core__verse.parsed.json | 8 ++++++-- .../fixtures/core__video.parsed.json | 8 ++++++-- 30 files changed, 184 insertions(+), 76 deletions(-) diff --git a/test/integration/full-content/fixtures/core__audio.parsed.json b/test/integration/full-content/fixtures/core__audio.parsed.json index 6b0acbd0c4a1fb..8024c293a5498f 100644 --- a/test/integration/full-content/fixtures/core__audio.parsed.json +++ b/test/integration/full-content/fixtures/core__audio.parsed.json @@ -6,13 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n
\n \n
\n", - "innerContent": [ "\n
\n \n
\n" ] + "innerContent": [ + "\n
\n \n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__block.parsed.json b/test/integration/full-content/fixtures/core__block.parsed.json index 33c4d86f6c6c7c..4dda73b389eeb1 100644 --- a/test/integration/full-content/fixtures/core__block.parsed.json +++ b/test/integration/full-content/fixtures/core__block.parsed.json @@ -13,6 +13,8 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__button__center.parsed.json b/test/integration/full-content/fixtures/core__button__center.parsed.json index 352767e1c1a8f3..45ed5130cbf15e 100644 --- a/test/integration/full-content/fixtures/core__button__center.parsed.json +++ b/test/integration/full-content/fixtures/core__button__center.parsed.json @@ -6,13 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] + "innerContent": [ + "\n\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__categories.parsed.json b/test/integration/full-content/fixtures/core__categories.parsed.json index 60d03d7bc50625..102791b85219e0 100644 --- a/test/integration/full-content/fixtures/core__categories.parsed.json +++ b/test/integration/full-content/fixtures/core__categories.parsed.json @@ -15,6 +15,8 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__code.parsed.json b/test/integration/full-content/fixtures/core__code.parsed.json index d9bf0a215e82b8..4aa3fbe8c40d47 100644 --- a/test/integration/full-content/fixtures/core__code.parsed.json +++ b/test/integration/full-content/fixtures/core__code.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
export default function MyButton() {\n\treturn <Button>Click Me!</Button>;\n}
\n", - "innerContent": [ "\n
export default function MyButton() {\n\treturn <Button>Click Me!</Button>;\n}
\n" ] + "innerContent": [ + "\n
export default function MyButton() {\n\treturn <Button>Click Me!</Button>;\n}
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__column.parsed.json b/test/integration/full-content/fixtures/core__column.parsed.json index 10f1e1a07cf05b..91b566bf7e5c42 100644 --- a/test/integration/full-content/fixtures/core__column.parsed.json +++ b/test/integration/full-content/fixtures/core__column.parsed.json @@ -8,24 +8,36 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n\t

Column One, Paragraph One

\n\t", - "innerContent": [ "\n\t

Column One, Paragraph One

\n\t" ] + "innerContent": [ + "\n\t

Column One, Paragraph One

\n\t" + ] }, { "blockName": "core/paragraph", "attrs": {}, "innerBlocks": [], "innerHTML": "\n\t

Column One, Paragraph Two

\n\t", - "innerContent": [ "\n\t

Column One, Paragraph Two

\n\t" ] + "innerContent": [ + "\n\t

Column One, Paragraph Two

\n\t" + ] } ], "innerHTML": "\n
\n\t\n\t\n
\n", - "innerContent": [ "\n
\n\t", null, "\n\t", null, "\n
\n" ] + "innerContent": [ + "\n
\n\t", + null, + "\n\t", + null, + "\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.json b/test/integration/full-content/fixtures/core__image__custom-link-class.json index 7009c3f2dede0c..d47fe4162c9c62 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.json @@ -8,8 +8,8 @@ "alt": "", "caption": "", "href": "https://wordpress.org/", - "linkDestination": "custom", - "linkClass": "custom-link" + "linkClass": "custom-link", + "linkDestination": "custom" }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json b/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json index 73638304d13812..c69b53dcc08aa9 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json @@ -6,17 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n
\"\"
\n", - "innerContent": [ - "\n
\"\"
\n" - ] - }, + "innerContent": [ + "\n
\"\"
\n" + ] + }, { - "attrs": {}, - "blockName": null, - "innerBlocks": [], - "innerHTML": "\n", - "innerContent": [ + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ "\n" - ] + ] } ] diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.json b/test/integration/full-content/fixtures/core__image__custom-link-rel.json index 3826afc9861b8e..6000da69608e62 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.json @@ -8,8 +8,8 @@ "alt": "", "caption": "", "href": "https://wordpress.org/", - "linkDestination": "custom", - "rel": "external" + "rel": "external", + "linkDestination": "custom" }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json b/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json index a1c7d028f72c9d..91649db09a595f 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json @@ -5,18 +5,18 @@ "linkDestination": "custom" }, "innerBlocks": [], - "innerHTML": "\n
\"\"
\n", - "innerContent": [ - "\n
\"\"
\n" - ] - }, + "innerHTML": "\n
\"\"
\n", + "innerContent": [ + "\n
\"\"
\n" + ] + }, { - "attrs": {}, - "blockName": null, - "innerBlocks": [], + "blockName": null, + "attrs": {}, + "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ + "innerContent": [ "\n" - ] + ] } ] diff --git a/test/integration/full-content/fixtures/core__missing.parsed.json b/test/integration/full-content/fixtures/core__missing.parsed.json index 85ab1542c72a3b..59d7fb99eb59d4 100644 --- a/test/integration/full-content/fixtures/core__missing.parsed.json +++ b/test/integration/full-content/fixtures/core__missing.parsed.json @@ -7,13 +7,17 @@ }, "innerBlocks": [], "innerHTML": "\n

Testing missing block with some

\n
\n\tHTML content\n
\n", - "innerContent": [ "\n

Testing missing block with some

\n
\n\tHTML content\n
\n" ] + "innerContent": [ + "\n

Testing missing block with some

\n
\n\tHTML content\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__more.parsed.json b/test/integration/full-content/fixtures/core__more.parsed.json index b806b0c0af8dba..624431c0413032 100644 --- a/test/integration/full-content/fixtures/core__more.parsed.json +++ b/test/integration/full-content/fixtures/core__more.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] + "innerContent": [ + "\n\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__more__custom-text-teaser.parsed.json b/test/integration/full-content/fixtures/core__more__custom-text-teaser.parsed.json index e3096b9d7cdbb2..c58996ee1ef1c3 100644 --- a/test/integration/full-content/fixtures/core__more__custom-text-teaser.parsed.json +++ b/test/integration/full-content/fixtures/core__more__custom-text-teaser.parsed.json @@ -7,13 +7,17 @@ }, "innerBlocks": [], "innerHTML": "\n\n\n", - "innerContent": [ "\n\n\n" ] + "innerContent": [ + "\n\n\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__nextpage.parsed.json b/test/integration/full-content/fixtures/core__nextpage.parsed.json index ff3f2703bf69ae..600c2fa3c7a43a 100644 --- a/test/integration/full-content/fixtures/core__nextpage.parsed.json +++ b/test/integration/full-content/fixtures/core__nextpage.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] + "innerContent": [ + "\n\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__paragraph__align-right.parsed.json b/test/integration/full-content/fixtures/core__paragraph__align-right.parsed.json index e0c2ab7be237bc..a8f850f47f72b5 100644 --- a/test/integration/full-content/fixtures/core__paragraph__align-right.parsed.json +++ b/test/integration/full-content/fixtures/core__paragraph__align-right.parsed.json @@ -6,13 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n

... like this one, which is separate from the above and right aligned.

\n", - "innerContent": [ "\n

... like this one, which is separate from the above and right aligned.

\n" ] + "innerContent": [ + "\n

... like this one, which is separate from the above and right aligned.

\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__paragraph__deprecated.parsed.json b/test/integration/full-content/fixtures/core__paragraph__deprecated.parsed.json index e6b914e24e1110..523743bab9e465 100644 --- a/test/integration/full-content/fixtures/core__paragraph__deprecated.parsed.json +++ b/test/integration/full-content/fixtures/core__paragraph__deprecated.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\nUnwrapped is still valid.\n", - "innerContent": [ "\nUnwrapped is still valid.\n" ] + "innerContent": [ + "\nUnwrapped is still valid.\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__preformatted.parsed.json b/test/integration/full-content/fixtures/core__preformatted.parsed.json index c78497076e90d2..0eb6c9a5b30bc6 100644 --- a/test/integration/full-content/fixtures/core__preformatted.parsed.json +++ b/test/integration/full-content/fixtures/core__preformatted.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
Some preformatted text...
And more!
\n", - "innerContent": [ "\n
Some preformatted text...
And more!
\n" ] + "innerContent": [ + "\n
Some preformatted text...
And more!
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__pullquote.parsed.json b/test/integration/full-content/fixtures/core__pullquote.parsed.json index 033b311fa5a190..1126f70a2ed1d6 100644 --- a/test/integration/full-content/fixtures/core__pullquote.parsed.json +++ b/test/integration/full-content/fixtures/core__pullquote.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
\n
\n

Testing pullquote block...

...with a caption\n
\n
\n", - "innerContent": [ "\n
\n
\n

Testing pullquote block...

...with a caption\n
\n
\n" ] + "innerContent": [ + "\n
\n
\n

Testing pullquote block...

...with a caption\n
\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__pullquote__multi-paragraph.parsed.json b/test/integration/full-content/fixtures/core__pullquote__multi-paragraph.parsed.json index fe8abfce70a364..c025cf8cae24e7 100644 --- a/test/integration/full-content/fixtures/core__pullquote__multi-paragraph.parsed.json +++ b/test/integration/full-content/fixtures/core__pullquote__multi-paragraph.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
\n
\n

Paragraph one

\n

Paragraph two

\n by whomever\n\t
\n
\n", - "innerContent": [ "\n
\n
\n

Paragraph one

\n

Paragraph two

\n by whomever\n\t
\n
\n" ] + "innerContent": [ + "\n
\n
\n

Paragraph one

\n

Paragraph two

\n by whomever\n\t
\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__quote__style-1.parsed.json b/test/integration/full-content/fixtures/core__quote__style-1.parsed.json index 6a873438f17316..c86fe92fb11d8f 100644 --- a/test/integration/full-content/fixtures/core__quote__style-1.parsed.json +++ b/test/integration/full-content/fixtures/core__quote__style-1.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n

The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

Matt Mullenweg, 2017
\n", - "innerContent": [ "\n

The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

Matt Mullenweg, 2017
\n" ] + "innerContent": [ + "\n

The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

Matt Mullenweg, 2017
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__quote__style-2.parsed.json b/test/integration/full-content/fixtures/core__quote__style-2.parsed.json index 6470afbc17a2e1..5543ac33cfd6c1 100644 --- a/test/integration/full-content/fixtures/core__quote__style-2.parsed.json +++ b/test/integration/full-content/fixtures/core__quote__style-2.parsed.json @@ -6,13 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n

There is no greater agony than bearing an untold story inside you.

Maya Angelou
\n", - "innerContent": [ "\n

There is no greater agony than bearing an untold story inside you.

Maya Angelou
\n" ] + "innerContent": [ + "\n

There is no greater agony than bearing an untold story inside you.

Maya Angelou
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__separator.parsed.json b/test/integration/full-content/fixtures/core__separator.parsed.json index 48a8e742c35b05..cb5714d4df31b3 100644 --- a/test/integration/full-content/fixtures/core__separator.parsed.json +++ b/test/integration/full-content/fixtures/core__separator.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
\n", - "innerContent": [ "\n
\n" ] + "innerContent": [ + "\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__shortcode.parsed.json b/test/integration/full-content/fixtures/core__shortcode.parsed.json index b875770f15a452..85ae209c2a1d37 100644 --- a/test/integration/full-content/fixtures/core__shortcode.parsed.json +++ b/test/integration/full-content/fixtures/core__shortcode.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n[gallery ids=\"238,338\"]\n", - "innerContent": [ "\n[gallery ids=\"238,338\"]\n" ] + "innerContent": [ + "\n[gallery ids=\"238,338\"]\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__spacer.parsed.json b/test/integration/full-content/fixtures/core__spacer.parsed.json index c3c0938df5b9da..68591dd47de553 100644 --- a/test/integration/full-content/fixtures/core__spacer.parsed.json +++ b/test/integration/full-content/fixtures/core__spacer.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
\n", - "innerContent": [ "\n
\n" ] + "innerContent": [ + "\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__subhead.parsed.json b/test/integration/full-content/fixtures/core__subhead.parsed.json index d88b9ee4c90b69..c0dbef54853747 100644 --- a/test/integration/full-content/fixtures/core__subhead.parsed.json +++ b/test/integration/full-content/fixtures/core__subhead.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n

This is a subhead.

\n", - "innerContent": [ "\n

This is a subhead.

\n" ] + "innerContent": [ + "\n

This is a subhead.

\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__table.parsed.json b/test/integration/full-content/fixtures/core__table.parsed.json index 7a2d91003f4373..5462dae3908a8c 100644 --- a/test/integration/full-content/fixtures/core__table.parsed.json +++ b/test/integration/full-content/fixtures/core__table.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
\n", - "innerContent": [ "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
\n" ] + "innerContent": [ + "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__text-columns.parsed.json b/test/integration/full-content/fixtures/core__text-columns.parsed.json index 1a7db4e09ed3a3..b00a69b7e3f546 100644 --- a/test/integration/full-content/fixtures/core__text-columns.parsed.json +++ b/test/integration/full-content/fixtures/core__text-columns.parsed.json @@ -6,13 +6,17 @@ }, "innerBlocks": [], "innerHTML": "\n
\n
\n

One

\n
\n
\n

Two

\n
\n
\n", - "innerContent": [ "\n
\n
\n

One

\n
\n
\n

Two

\n
\n
\n" ] + "innerContent": [ + "\n
\n
\n

One

\n
\n
\n

Two

\n
\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__text__converts-to-paragraph.parsed.json b/test/integration/full-content/fixtures/core__text__converts-to-paragraph.parsed.json index 75a5ca1140907a..1e472910342844 100644 --- a/test/integration/full-content/fixtures/core__text__converts-to-paragraph.parsed.json +++ b/test/integration/full-content/fixtures/core__text__converts-to-paragraph.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n

This is an old-style text block. Changed to paragraph in #2135.

\n", - "innerContent": [ "\n

This is an old-style text block. Changed to paragraph in #2135.

\n" ] + "innerContent": [ + "\n

This is an old-style text block. Changed to paragraph in #2135.

\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__verse.parsed.json b/test/integration/full-content/fixtures/core__verse.parsed.json index 4cccc9383a50cb..2fbff3b1b326ed 100644 --- a/test/integration/full-content/fixtures/core__verse.parsed.json +++ b/test/integration/full-content/fixtures/core__verse.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
A verse
And more!
\n", - "innerContent": [ "\n
A verse
And more!
\n" ] + "innerContent": [ + "\n
A verse
And more!
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] diff --git a/test/integration/full-content/fixtures/core__video.parsed.json b/test/integration/full-content/fixtures/core__video.parsed.json index e9be9d8a2ea2c0..5fd5505e395f76 100644 --- a/test/integration/full-content/fixtures/core__video.parsed.json +++ b/test/integration/full-content/fixtures/core__video.parsed.json @@ -4,13 +4,17 @@ "attrs": {}, "innerBlocks": [], "innerHTML": "\n
\n", - "innerContent": [ "\n
\n" ] + "innerContent": [ + "\n
\n" + ] }, { "blockName": null, "attrs": {}, "innerBlocks": [], "innerHTML": "\n", - "innerContent": [ "\n" ] + "innerContent": [ + "\n" + ] } ] From c26abe2486226dbe439b0d42326bb1a87f51e252 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 13:11:06 -0500 Subject: [PATCH 23/40] Blocks: Update image fixtures per url, alt as comment attributes --- docs/language.md | 2 +- phpunit/fixtures/long-content.html | 4 ++-- post-content.php | 4 ++-- .../__snapshots__/blocks-raw-handling.spec.js.snap | 4 ++-- test/integration/fixtures/caption-shortcode-out.html | 2 +- test/integration/fixtures/evernote-out.html | 2 +- test/integration/fixtures/google-docs-out.html | 2 +- test/integration/fixtures/ms-word-online-out.html | 2 +- test/integration/fixtures/ms-word-out.html | 2 +- test/integration/fixtures/one-image-out.html | 2 +- test/integration/fixtures/two-images-out.html | 4 ++-- test/integration/full-content/fixtures/core__image.html | 2 +- test/integration/full-content/fixtures/core__image.json | 1 + .../integration/full-content/fixtures/core__image.parsed.json | 4 +++- .../full-content/fixtures/core__image.serialized.html | 2 +- .../full-content/fixtures/core__image__attachment-link.html | 2 +- .../full-content/fixtures/core__image__attachment-link.json | 1 + .../fixtures/core__image__attachment-link.parsed.json | 1 + .../fixtures/core__image__attachment-link.serialized.html | 2 +- .../full-content/fixtures/core__image__center-caption.html | 2 +- .../full-content/fixtures/core__image__center-caption.json | 1 + .../fixtures/core__image__center-caption.parsed.json | 1 + .../fixtures/core__image__center-caption.serialized.html | 2 +- .../full-content/fixtures/core__image__custom-link-class.html | 2 +- .../full-content/fixtures/core__image__custom-link-class.json | 1 + .../fixtures/core__image__custom-link-class.parsed.json | 1 + .../fixtures/core__image__custom-link-class.serialized.html | 2 +- .../full-content/fixtures/core__image__custom-link-rel.html | 2 +- .../full-content/fixtures/core__image__custom-link-rel.json | 1 + .../fixtures/core__image__custom-link-rel.parsed.json | 1 + .../fixtures/core__image__custom-link-rel.serialized.html | 2 +- .../full-content/fixtures/core__image__custom-link.html | 2 +- .../full-content/fixtures/core__image__custom-link.json | 1 + .../fixtures/core__image__custom-link.parsed.json | 1 + .../fixtures/core__image__custom-link.serialized.html | 2 +- .../full-content/fixtures/core__image__media-link.html | 2 +- .../full-content/fixtures/core__image__media-link.json | 1 + .../full-content/fixtures/core__image__media-link.parsed.json | 1 + .../fixtures/core__image__media-link.serialized.html | 2 +- 39 files changed, 45 insertions(+), 30 deletions(-) diff --git a/docs/language.md b/docs/language.md index 8a71e707619fbc..2247557b4dc44d 100644 --- a/docs/language.md +++ b/docs/language.md @@ -86,7 +86,7 @@ _N.B.:_ The defining aspect of blocks are their semantics and the isolation mech When blocks are saved to the content, after the editing session, its attributes—depending on the nature of the block—are serialized to these explicit comment delimiters. ```html - +
diff --git a/phpunit/fixtures/long-content.html b/phpunit/fixtures/long-content.html index 065b7c402c1495..baf610133860dc 100644 --- a/phpunit/fixtures/long-content.html +++ b/phpunit/fixtures/long-content.html @@ -19,7 +19,7 @@

A Picture is worth a Thousand Words

Handling images and media with the utmost care is a primary focus of the new editor. Hopefully, you'll find aspects of adding captions or going full-width with your pictures much easier and robust than before.

- +
Beautiful landscape
Give it a try. Press the "wide" button on the image toolbar.
@@ -81,7 +81,7 @@

Media Rich

If you combine the new wide and full-wide alignments with galleries, you can create a very media rich layout, very quickly:

- +
Accessibility is important don't forget image alt attribute
diff --git a/post-content.php b/post-content.php index f34262d1eed4c8..d3e120e0cd2058 100644 --- a/post-content.php +++ b/post-content.php @@ -26,7 +26,7 @@

- +
<?php esc_attr_e( 'Beautiful landscape', 'gutenberg' ); ?>
@@ -108,7 +108,7 @@

wide and full-wide alignments with galleries, you can create a very media rich layout, very quickly:', 'gutenberg' ); ?>

- +
<?php _e( 'Accessibility is important — don’t forget image alt attribute', 'gutenberg' ); ?>
diff --git a/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap b/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap index f92c383e637686..34e1e7b7a93d2c 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap @@ -5,8 +5,8 @@ exports[`Blocks raw handling rawHandler should convert HTML post to blocks with

Howdy

- -
\\"\\"/
+ +
\\"\\"/
diff --git a/test/integration/fixtures/caption-shortcode-out.html b/test/integration/fixtures/caption-shortcode-out.html index 2027b65d2feae6..81cc6003269996 100644 --- a/test/integration/fixtures/caption-shortcode-out.html +++ b/test/integration/fixtures/caption-shortcode-out.html @@ -1,3 +1,3 @@ - +
test
diff --git a/test/integration/fixtures/evernote-out.html b/test/integration/fixtures/evernote-out.html index 4d8c6c43b9c99e..07e10ceaca109d 100644 --- a/test/integration/fixtures/evernote-out.html +++ b/test/integration/fixtures/evernote-out.html @@ -26,6 +26,6 @@ - +
diff --git a/test/integration/fixtures/google-docs-out.html b/test/integration/fixtures/google-docs-out.html index 7733ca660bdd02..f7c8d4169f488c 100644 --- a/test/integration/fixtures/google-docs-out.html +++ b/test/integration/fixtures/google-docs-out.html @@ -30,6 +30,6 @@

This is a heading

An image:

- +
diff --git a/test/integration/fixtures/ms-word-online-out.html b/test/integration/fixtures/ms-word-online-out.html index 3088b7480877f7..3edcced6477806 100644 --- a/test/integration/fixtures/ms-word-online-out.html +++ b/test/integration/fixtures/ms-word-online-out.html @@ -22,6 +22,6 @@

An image: 

- +
diff --git a/test/integration/fixtures/ms-word-out.html b/test/integration/fixtures/ms-word-out.html index c53c5aaeba2e97..17cf55c0f54500 100644 --- a/test/integration/fixtures/ms-word-out.html +++ b/test/integration/fixtures/ms-word-out.html @@ -54,6 +54,6 @@

This is a heading level 2

An image:

- +
diff --git a/test/integration/fixtures/one-image-out.html b/test/integration/fixtures/one-image-out.html index defa0138370faf..32dd9a7292720a 100644 --- a/test/integration/fixtures/one-image-out.html +++ b/test/integration/fixtures/one-image-out.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/fixtures/two-images-out.html b/test/integration/fixtures/two-images-out.html index 4b96a052a52b7b..c502dbba43cbfc 100644 --- a/test/integration/fixtures/two-images-out.html +++ b/test/integration/fixtures/two-images-out.html @@ -1,7 +1,7 @@ - +
- +
diff --git a/test/integration/full-content/fixtures/core__image.html b/test/integration/full-content/fixtures/core__image.html index eda663561a38bf..26456a7c5951a4 100644 --- a/test/integration/full-content/fixtures/core__image.html +++ b/test/integration/full-content/fixtures/core__image.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image.json b/test/integration/full-content/fixtures/core__image.json index 4369150f0c9292..7af31c081cb808 100644 --- a/test/integration/full-content/fixtures/core__image.json +++ b/test/integration/full-content/fixtures/core__image.json @@ -7,6 +7,7 @@ "url": "https://cldup.com/uuUqE_dXzy.jpg", "alt": "", "caption": "", + "userSetDimensions": false, "linkDestination": "none" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image.parsed.json b/test/integration/full-content/fixtures/core__image.parsed.json index d7e16a440ddefb..da8061d041a90d 100644 --- a/test/integration/full-content/fixtures/core__image.parsed.json +++ b/test/integration/full-content/fixtures/core__image.parsed.json @@ -1,7 +1,9 @@ [ { "blockName": "core/image", - "attrs": {}, + "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg" + }, "innerBlocks": [], "innerHTML": "\n
\"\"
\n", "innerContent": [ diff --git a/test/integration/full-content/fixtures/core__image.serialized.html b/test/integration/full-content/fixtures/core__image.serialized.html index 5dfb0bac3e5b72..ce4733e9d58570 100644 --- a/test/integration/full-content/fixtures/core__image.serialized.html +++ b/test/integration/full-content/fixtures/core__image.serialized.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__attachment-link.html b/test/integration/full-content/fixtures/core__image__attachment-link.html index 908250d8ca249c..b7b119d196a375 100644 --- a/test/integration/full-content/fixtures/core__image__attachment-link.html +++ b/test/integration/full-content/fixtures/core__image__attachment-link.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__attachment-link.json b/test/integration/full-content/fixtures/core__image__attachment-link.json index 5d169589043a5c..e7cee2534174d0 100644 --- a/test/integration/full-content/fixtures/core__image__attachment-link.json +++ b/test/integration/full-content/fixtures/core__image__attachment-link.json @@ -8,6 +8,7 @@ "alt": "", "caption": "", "href": "http://localhost:8888/?attachment_id=7", + "userSetDimensions": false, "linkDestination": "attachment" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__attachment-link.parsed.json b/test/integration/full-content/fixtures/core__image__attachment-link.parsed.json index fae6604516028e..0313b05e487782 100644 --- a/test/integration/full-content/fixtures/core__image__attachment-link.parsed.json +++ b/test/integration/full-content/fixtures/core__image__attachment-link.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", "linkDestination": "attachment" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__attachment-link.serialized.html b/test/integration/full-content/fixtures/core__image__attachment-link.serialized.html index f5ebb9af4182c5..aa0077d5bb6dd1 100644 --- a/test/integration/full-content/fixtures/core__image__attachment-link.serialized.html +++ b/test/integration/full-content/fixtures/core__image__attachment-link.serialized.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__center-caption.html b/test/integration/full-content/fixtures/core__image__center-caption.html index bfe40d190fa66e..e55b77314c9fb4 100644 --- a/test/integration/full-content/fixtures/core__image__center-caption.html +++ b/test/integration/full-content/fixtures/core__image__center-caption.html @@ -1,3 +1,3 @@ - +
Give it a try. Press the "really wide" button on the image toolbar.
diff --git a/test/integration/full-content/fixtures/core__image__center-caption.json b/test/integration/full-content/fixtures/core__image__center-caption.json index f569bda22c81b2..7fe3773e95e1ad 100644 --- a/test/integration/full-content/fixtures/core__image__center-caption.json +++ b/test/integration/full-content/fixtures/core__image__center-caption.json @@ -8,6 +8,7 @@ "alt": "", "caption": "Give it a try. Press the \"really wide\" button on the image toolbar.", "align": "center", + "userSetDimensions": false, "linkDestination": "none" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__center-caption.parsed.json b/test/integration/full-content/fixtures/core__image__center-caption.parsed.json index 02ff95e3ae8cb7..9787338318131e 100644 --- a/test/integration/full-content/fixtures/core__image__center-caption.parsed.json +++ b/test/integration/full-content/fixtures/core__image__center-caption.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/YLYhpou2oq.jpg", "align": "center" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__center-caption.serialized.html b/test/integration/full-content/fixtures/core__image__center-caption.serialized.html index 3410b04fdf1214..28006a62ec21c7 100644 --- a/test/integration/full-content/fixtures/core__image__center-caption.serialized.html +++ b/test/integration/full-content/fixtures/core__image__center-caption.serialized.html @@ -1,3 +1,3 @@ - +
Give it a try. Press the "really wide" button on the image toolbar.
diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.html b/test/integration/full-content/fixtures/core__image__custom-link-class.html index 57cc46c9c39bbe..966033bc967f29 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.html +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.json b/test/integration/full-content/fixtures/core__image__custom-link-class.json index d47fe4162c9c62..b7e5fcc0e3ac1d 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.json @@ -9,6 +9,7 @@ "caption": "", "href": "https://wordpress.org/", "linkClass": "custom-link", + "userSetDimensions": false, "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json b/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json index c69b53dcc08aa9..d2ef1d381a4d21 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link-class.serialized.html b/test/integration/full-content/fixtures/core__image__custom-link-class.serialized.html index 9ac1f7a7a914e9..118472982fed7a 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-class.serialized.html +++ b/test/integration/full-content/fixtures/core__image__custom-link-class.serialized.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.html b/test/integration/full-content/fixtures/core__image__custom-link-rel.html index 3424ed3fff3d70..b87831ecc7bcb8 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.html +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.json b/test/integration/full-content/fixtures/core__image__custom-link-rel.json index 6000da69608e62..b9e7ea55bbba4d 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.json @@ -9,6 +9,7 @@ "caption": "", "href": "https://wordpress.org/", "rel": "external", + "userSetDimensions": false, "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json b/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json index 91649db09a595f..fe007512a4f546 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link-rel.serialized.html b/test/integration/full-content/fixtures/core__image__custom-link-rel.serialized.html index 92702548c11d9d..b02c24a59827d3 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link-rel.serialized.html +++ b/test/integration/full-content/fixtures/core__image__custom-link-rel.serialized.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__custom-link.html b/test/integration/full-content/fixtures/core__image__custom-link.html index 353dc5376b7a46..2fbfe8e42f13a3 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link.html +++ b/test/integration/full-content/fixtures/core__image__custom-link.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__custom-link.json b/test/integration/full-content/fixtures/core__image__custom-link.json index 735e5522826624..3a5609984b4c14 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link.json +++ b/test/integration/full-content/fixtures/core__image__custom-link.json @@ -8,6 +8,7 @@ "alt": "", "caption": "", "href": "https://wordpress.org/", + "userSetDimensions": false, "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link.parsed.json b/test/integration/full-content/fixtures/core__image__custom-link.parsed.json index a3625c6a1f683e..3fc24f2c979f7f 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link.parsed.json +++ b/test/integration/full-content/fixtures/core__image__custom-link.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", "linkDestination": "custom" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__custom-link.serialized.html b/test/integration/full-content/fixtures/core__image__custom-link.serialized.html index 47357bea6b9d48..67c61dceef8633 100644 --- a/test/integration/full-content/fixtures/core__image__custom-link.serialized.html +++ b/test/integration/full-content/fixtures/core__image__custom-link.serialized.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__media-link.html b/test/integration/full-content/fixtures/core__image__media-link.html index 90b3d227117b04..cb7dda5892dbeb 100644 --- a/test/integration/full-content/fixtures/core__image__media-link.html +++ b/test/integration/full-content/fixtures/core__image__media-link.html @@ -1,3 +1,3 @@ - +
diff --git a/test/integration/full-content/fixtures/core__image__media-link.json b/test/integration/full-content/fixtures/core__image__media-link.json index 690fa778b6fd5b..eda23729a692cb 100644 --- a/test/integration/full-content/fixtures/core__image__media-link.json +++ b/test/integration/full-content/fixtures/core__image__media-link.json @@ -8,6 +8,7 @@ "alt": "", "caption": "", "href": "https://cldup.com/uuUqE_dXzy.jpg", + "userSetDimensions": false, "linkDestination": "media" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__media-link.parsed.json b/test/integration/full-content/fixtures/core__image__media-link.parsed.json index 46458a7eec3d7b..64a3a790c01a33 100644 --- a/test/integration/full-content/fixtures/core__image__media-link.parsed.json +++ b/test/integration/full-content/fixtures/core__image__media-link.parsed.json @@ -2,6 +2,7 @@ { "blockName": "core/image", "attrs": { + "url": "https://cldup.com/uuUqE_dXzy.jpg", "linkDestination": "media" }, "innerBlocks": [], diff --git a/test/integration/full-content/fixtures/core__image__media-link.serialized.html b/test/integration/full-content/fixtures/core__image__media-link.serialized.html index 721abac903ff31..127603aa7deb9e 100644 --- a/test/integration/full-content/fixtures/core__image__media-link.serialized.html +++ b/test/integration/full-content/fixtures/core__image__media-link.serialized.html @@ -1,3 +1,3 @@ - +
From 579cf1244048bf56abb33e2bc070586d2be9caad Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 13:15:49 -0500 Subject: [PATCH 24/40] Compat: Align PHPDoc return --- lib/compat.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 2138893c91d51c..c1229136f7a8d5 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -307,8 +307,8 @@ function gutenberg_warn_classic_about_blocks() { /** * Add 'actual_size' to the prepared attachment data for the Media Library. * - * Needed as `wp_prepare_attachment_for_js()` (for the media modal) constrains the image sizes - * to the theme's `$content_width`. + * Needed as `wp_prepare_attachment_for_js()` (for the media modal) constrains + * the image sizes to the theme's `$content_width`. * * @param array $response Array of prepared attachment data. * @param WP_Post $attachment Attachment object. @@ -332,9 +332,9 @@ function gutenberg_prepare_attachment_for_js( $response, $attachment, $meta ) { add_filter( 'wp_prepare_attachment_for_js', 'gutenberg_prepare_attachment_for_js', 10, 3 ); /** - * Warm the object cache with post and meta information for all found - * image blocks to avoid making individual database calls - * (similarly to `wp_make_content_images_responsive()`). + * Warm the object cache with post and meta information for all found image + * blocks to avoid making individual database calls (similarly to + * `wp_make_content_images_responsive()`). * * @access private * @since 4.x.x @@ -365,13 +365,15 @@ function _gutenberg_cache_images_meta( $content ) { add_filter( 'the_content', '_gutenberg_cache_images_meta', 3 ); /** - * Calculates the image width and height based on $block_witdh and the `editWidth` block attribute. + * Calculates the image width and height based on $block_witdh and the + * `editWidth` block attribute. * - * @since 4.x.x + * @since 4.5.0 * * @param array $block_attributes The block attributes. - * @param array $image_meta Optional. The image attachment meta data. - * @return array|bool An array of the image width and height, in that order, or false if the image data is missing from $block_attributes. + * @param array $image_meta Optional. The image attachment meta data. + * @return array|bool An array of the image width and height, in that order, or + * false if the image data is missing from $block_attributes. */ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null ) { if ( ! empty( $block_attributes['width'] ) && ! empty( $block_attributes['height'] ) ) { @@ -444,7 +446,6 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * * @param string $html Original HTML. * @param array $block Parsed block. - * * @return string Filtered Image block HTML. */ function gutenberg_render_block_core_image( $html, $block ) { From 95630827e155812d4a9298e5a5194d2cb6fd092d Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 13:16:00 -0500 Subject: [PATCH 25/40] Compat: Add PHPDoc since tag --- lib/compat.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index c1229136f7a8d5..34356c71c3bf69 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -337,7 +337,7 @@ function gutenberg_prepare_attachment_for_js( $response, $attachment, $meta ) { * `wp_make_content_images_responsive()`). * * @access private - * @since 4.x.x + * @since 4.5.0 * * @param string $content The post content. * @return string $content Unchanged post content. @@ -430,7 +430,7 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null /** * Filters the image size for the image block. * - * @since 4.x.x + * @since 4.5.0 * * @param array $image_size The calculated image size width and * height (in that order). @@ -444,6 +444,8 @@ function gutenberg_get_image_width_height( $block_attributes, $image_meta = null * Filters the rendered output of the Image block to include generated HTML * attributes for front-end display. * + * @since 4.5.0 + * * @param string $html Original HTML. * @param array $block Parsed block. * @return string Filtered Image block HTML. @@ -513,7 +515,7 @@ function gutenberg_render_block_core_image( $html, $block ) { /** * Filters the image tag attributes when rendering the core image block. * - * @since 4.x.x + * @since 4.5.0 * * @param array $image_attributes The (recalculated) image attributes. * Note: expects valid HTML 5.0 attribute names. From a0a6dd911f8ffa563a8ba33a561040c132f7e0e7 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 14:19:57 -0500 Subject: [PATCH 26/40] Blocks: Remove outdated comment about floated images width accuracy --- packages/block-library/src/image/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 08a47b7d92b90e..9772516ac27c7a 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -764,7 +764,6 @@ class ImageEdit extends Component { /* eslint-enable jsx-a11y/no-noninteractive-element-interactions */ ); - // Floating a resized image can produce inaccurate `imageWidthWithinContainer`. const ratio = imageWidth / imageHeight; let constrainedWidth; let constrainedHeight; From 8e73feb27668b3837aae78ba6d59fab565d734c1 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 14:21:19 -0500 Subject: [PATCH 27/40] Compat: Remove any attributes containing invalid characters --- lib/compat.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 34356c71c3bf69..0cb00459b63b8c 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -528,9 +528,9 @@ function gutenberg_render_block_core_image( $html, $block ) { $attr = ''; foreach ( $image_attributes as $name => $value ) { // Sanitize for valid HTML 5.0 attribute names, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes. - $name = preg_replace( '/[^a-z0-9-]+/', '', strtolower( $name ) ); + $is_invalid_attribute = preg_match( '/[^a-z0-9-]+/', '', strtolower( $name ) ); - if ( empty( $name ) ) { + if ( $is_invalid_attribute ) { continue; } From 8535d73c5db4edf093848c619b338d8fad61c74f Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 14:24:04 -0500 Subject: [PATCH 28/40] Blocks: Reintegrate media attributes pick to setAttributes spread https: //github.com/WordPress/gutenberg/pull/11973#discussion_r235115253 Co-Authored-By: Dennis Snell --- packages/block-library/src/image/edit.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 9772516ac27c7a..01d417e38e7c7b 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -211,11 +211,9 @@ class ImageEdit extends Component { fileHeight = get( img, [ 'actual_size', 'height' ] ) || img.height; } - const attr = pickRelevantMediaFiles( media ); - attr.url = src; - this.props.setAttributes( { - ...attr, + ...pickRelevantMediaFiles( media ), + url: src, // Not used in the editor, passed to the front-end in block attributes. fileWidth, From 4d2d9598581dd113a8df7512b2a417bd762f4486 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 14:26:51 -0500 Subject: [PATCH 29/40] Blocks: Set Image fileWidth, fileHeight only if both present Co-Authored-By: Andrew Ozz --- packages/block-library/src/image/edit.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 01d417e38e7c7b..61b2073da3bea1 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -207,8 +207,15 @@ class ImageEdit extends Component { // The "full" size is already included in `sizes`. img = media.sizes.large || media.sizes.full; src = img.url; - fileWidth = get( img, [ 'actual_size', 'width' ] ) || img.width; - fileHeight = get( img, [ 'actual_size', 'height' ] ) || img.height; + fileWidth = get( img, [ 'actual_size', 'width' ] ); + fileHeight = get( img, [ 'actual_size', 'height' ] ); + + // Fall back to default image if either width or height is unset, + // in case the provided image metadata is inconsistent. + if ( ! fileWidth || ! fileHeight ) { + fileWidth = img.width; + fileHeight = img.height; + } } this.props.setAttributes( { From 19dad07cb158c6e5f08550821a1e22275d3986d0 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 14:36:44 -0500 Subject: [PATCH 30/40] Compat: Use spec standard for valid attribute characters --- lib/compat.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 0cb00459b63b8c..54d0c4ac331ac5 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -527,8 +527,10 @@ function gutenberg_render_block_core_image( $html, $block ) { $attr = ''; foreach ( $image_attributes as $name => $value ) { - // Sanitize for valid HTML 5.0 attribute names, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes. - $is_invalid_attribute = preg_match( '/[^a-z0-9-]+/', '', strtolower( $name ) ); + // Sanitize for valid HTML 5.0 attribute names + // + // See: https://www.w3.org/TR/html52/syntax.html#attribute-names . + $is_invalid_attribute = preg_match( '/[\\\\u007F-\\\\u009F "\'>\/="\\\\uFDD0-\\\\uFDEF]/', strtolower( $name ) ); if ( $is_invalid_attribute ) { continue; From 87130e40e4e6165aded72dbaeef42d9db5742360 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 15:08:56 -0500 Subject: [PATCH 31/40] Editor: Compute expected block width by DOM compute --- packages/block-library/src/image/edit.js | 29 ++++++++------------- packages/editor/src/utils/dom.js | 33 ++++++++++++++++++++++++ packages/editor/src/utils/index.js | 5 ++++ 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 61b2073da3bea1..3083e9401bef0c 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -43,6 +43,7 @@ import { MediaUploadCheck, BlockAlignmentToolbar, mediaUpload, + __unstableDOM, } from '@wordpress/editor'; import { withViewportMatch } from '@wordpress/viewport'; import { compose } from '@wordpress/compose'; @@ -225,7 +226,7 @@ class ImageEdit extends Component { // Not used in the editor, passed to the front-end in block attributes. fileWidth, fileHeight, - editWidth: this.props.contentWidth, + editWidth: __unstableDOM.getBlockWidth(), } ); } @@ -399,7 +400,7 @@ class ImageEdit extends Component { fileWidth, fileHeight, userSetDimensions, - editWidth: this.props.contentwidth, + editWidth: __unstableDOM.getBlockWidth(), } ); } @@ -415,7 +416,7 @@ class ImageEdit extends Component { width: undefined, height: undefined, userSetDimensions: undefined, - editWidth: this.props.contentwidth, + editWidth: __unstableDOM.getBlockWidth(), } ); } @@ -519,7 +520,6 @@ class ImageEdit extends Component { noticeUI, toggleSelection, isRTL, - contentWidth, } = this.props; const { url, @@ -538,6 +538,7 @@ class ImageEdit extends Component { } = attributes; const isExternal = isExternalImage( id, url ); const imageSizeOptions = this.getImageSizeOptions(); + const blockWidth = __unstableDOM.getBlockWidth(); let toolbarEditButton; if ( url ) { @@ -664,14 +665,14 @@ class ImageEdit extends Component { { [ 25, 50, 75, 100 ].map( ( percent ) => { // Percentage is relative to the block width. - let scaledWidth = Math.round( contentWidth * ( percent / 100 ) ); + let scaledWidth = Math.round( blockWidth * ( percent / 100 ) ); let isCurrent = false; if ( scaledWidth > imageWidth ) { scaledWidth = imageWidth; isCurrent = percent === 100 && ( ! width || width === scaledWidth ); } else { - isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > contentWidth ); + isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > blockWidth ); } return ( @@ -773,13 +774,13 @@ class ImageEdit extends Component { let constrainedWidth; let constrainedHeight; - if ( ( align === 'wide' || align === 'full' ) && imageWidthWithinContainer > contentWidth ) { + if ( ( align === 'wide' || align === 'full' ) && imageWidthWithinContainer > blockWidth ) { // Do not limit the width. constrainedWidth = imageWidthWithinContainer; constrainedHeight = imageHeightWithinContainer; } else { constrainedWidth = width || imageWidth; - constrainedWidth = constrainedWidth > contentWidth ? contentWidth : constrainedWidth; + constrainedWidth = constrainedWidth > blockWidth ? blockWidth : constrainedWidth; constrainedHeight = Math.round( constrainedWidth / ratio ) || undefined; } @@ -873,7 +874,7 @@ class ImageEdit extends Component { newWidth = imageWidth; } - if ( newWidth >= contentWidth ) { + if ( newWidth >= blockWidth ) { // The image was resized to greater than the block width. Reset to 100% width and height (that will also highlight the 100% width button). this.resetWidthHeight( imageWidth, imageHeight ); } else { @@ -912,21 +913,13 @@ export default compose( [ const { getMedia } = select( 'core' ); const { getEditorSettings } = select( 'core/editor' ); const { id } = props.attributes; - const { - maxWidth, - isRTL, - imageSizes, - // Note: At the time of implementation, this value will never be - // found in settings and always default to the hard-coded value. - contentWidth = 580, - } = getEditorSettings(); + const { maxWidth, isRTL, imageSizes } = getEditorSettings(); return { image: id ? getMedia( id ) : null, maxWidth, isRTL, imageSizes, - contentWidth, }; } ), withViewportMatch( { isLargeViewport: 'medium' } ), diff --git a/packages/editor/src/utils/dom.js b/packages/editor/src/utils/dom.js index 8ee6fef110d799..6842c0a9bf5063 100644 --- a/packages/editor/src/utils/dom.js +++ b/packages/editor/src/utils/dom.js @@ -25,6 +25,39 @@ export function getBlockFocusableWrapper( clientId ) { return getBlockDOMNode( clientId ).closest( '.editor-block-list__block' ); } +/** + * Returns the expected width of a block which would occupy the editor block + * list, in absolute pixels. This value is cached; the cache reset upon change + * in viewport size. + * + * @return {number} Expected block width in pixels. + */ +export const getBlockWidth = ( () => { + let width; + window.addEventListener( 'resize', () => width = undefined ); + + return () => { + if ( width === undefined ) { + const layout = document.querySelector( '.editor-block-list__layout' ); + if ( ! layout ) { + return; + } + + const measure = document.createElement( 'div' ); + measure.className = 'wp-block editor-block-list__block'; + layout.appendChild( measure ); + const { clientWidth } = measure; + layout.removeChild( measure ); + + // 30 = ( 2 * $block-padding ) + ( 2 * $border-width ) + // See: https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_variables.scss + width = clientWidth - 30; + } + + return width; + }; +} )(); + /** * Returns true if the given HTMLElement is a block focus stop. Blocks without * their own text fields rely on the focus stop to be keyboard navigable. diff --git a/packages/editor/src/utils/index.js b/packages/editor/src/utils/index.js index 0f246c16e4aec8..fb2b9cb87bc0e4 100644 --- a/packages/editor/src/utils/index.js +++ b/packages/editor/src/utils/index.js @@ -2,6 +2,11 @@ * Internal dependencies */ import mediaUpload from './media-upload'; +import { getBlockWidth } from './dom'; export { mediaUpload }; export { cleanForSlug } from './url.js'; + +export const __unstableDOM = { + getBlockWidth, +}; From e2f800759452bb87ea083b66b67614f8e7fc0095 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 15:22:58 -0500 Subject: [PATCH 32/40] Compat: Always write img attribute value, even empty --- lib/compat.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/compat.php b/lib/compat.php index 54d0c4ac331ac5..2cddbcf419d5e1 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -544,11 +544,7 @@ function gutenberg_render_block_core_image( $html, $block ) { $value = esc_attr( $value ); } - if ( empty( $value ) ) { - $attr .= ' ' . $name; - } else { - $attr .= sprintf( ' %s="%s"', $name, $value ); - } + $attr .= sprintf( ' %s="%s"', $name, $value ); } $image_tag = ''; From bf674089a464e2f70475c538f0b1cd31ffd674db Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 20 Nov 2018 15:30:44 -0500 Subject: [PATCH 33/40] Blocks: Avoid multiple calls to setAttributes in resetWidthHeight --- packages/block-library/src/image/edit.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 3083e9401bef0c..065ab178b7a35e 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -405,19 +405,19 @@ class ImageEdit extends Component { } resetWidthHeight( fileWidth, fileHeight ) { - if ( fileWidth && fileHeight ) { - this.props.setAttributes( { - fileWidth, - fileHeight, - } ); - } - - this.props.setAttributes( { + const nextAttributes = { width: undefined, height: undefined, userSetDimensions: undefined, editWidth: __unstableDOM.getBlockWidth(), - } ); + }; + + if ( fileWidth && fileHeight ) { + nextAttributes.fileWidth = fileWidth; + nextAttributes.fileHeight = fileHeight; + } + + this.props.setAttributes( nextAttributes ); } /** From d8d7d6e290c79bcabef39f6951ffb2d446cc02f9 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Fri, 23 Nov 2018 21:49:27 +0200 Subject: [PATCH 34/40] Update the 25-50-75-100% buttons - Add a "Relative Image Size" label. - DIsable buttons that don't apply when the image is narrower than the block width. --- packages/block-library/src/image/edit.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 065ab178b7a35e..2d7519656d2436 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -661,23 +661,25 @@ class ImageEdit extends Component { } } />
+

+ { __( 'Relative Image Size' ) } +

- + { [ 25, 50, 75, 100 ].map( ( percent ) => { // Percentage is relative to the block width. - let scaledWidth = Math.round( blockWidth * ( percent / 100 ) ); + const scaledWidth = Math.round( blockWidth * ( percent / 100 ) ); + const disabled = scaledWidth > imageWidth; let isCurrent = false; - if ( scaledWidth > imageWidth ) { - scaledWidth = imageWidth; - isCurrent = percent === 100 && ( ! width || width === scaledWidth ); - } else { + if ( ! disabled ) { isCurrent = ( width === scaledWidth ) || ( ! width && percent === 100 && imageWidth > blockWidth ); } return (