From 9f148d95634052a7fb37cceb478e7095562ba796 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Jan 2021 13:50:48 +1300 Subject: [PATCH 01/86] Update Gallery to nested image blocks --- packages/block-library/src/gallery/block.json | 65 +- .../block-library/src/gallery/deprecated.js | 1502 +++++++++-------- packages/block-library/src/gallery/edit.js | 376 ++--- .../block-library/src/gallery/editor.scss | 6 + .../src/gallery/gallery-image.js | 313 ---- packages/block-library/src/gallery/gallery.js | 80 +- packages/block-library/src/gallery/save.js | 61 +- packages/block-library/src/gallery/shared.js | 11 +- packages/block-library/src/gallery/style.scss | 157 +- .../block-library/src/gallery/transforms.js | 2 +- .../src/gallery/use-image-sizes.js | 54 + packages/block-library/src/gallery/utils.js | 68 + packages/block-library/src/image/block.json | 5 + packages/block-library/src/image/edit.js | 61 +- packages/block-library/src/image/image.js | 3 +- packages/block-library/src/image/save.js | 12 +- 16 files changed, 1284 insertions(+), 1492 deletions(-) delete mode 100644 packages/block-library/src/gallery/gallery-image.js create mode 100644 packages/block-library/src/gallery/use-image-sizes.js create mode 100644 packages/block-library/src/gallery/utils.js diff --git a/packages/block-library/src/gallery/block.json b/packages/block-library/src/gallery/block.json index 8beac02827f61..44f7d069c8bef 100644 --- a/packages/block-library/src/gallery/block.json +++ b/packages/block-library/src/gallery/block.json @@ -3,56 +3,12 @@ "name": "core/gallery", "category": "media", "attributes": { - "images": { + "imageUploads": { "type": "array", "default": [], - "source": "query", - "selector": ".blocks-gallery-item", - "query": { - "url": { - "type": "string", - "source": "attribute", - "selector": "img", - "attribute": "src" - }, - "fullUrl": { - "type": "string", - "source": "attribute", - "selector": "img", - "attribute": "data-full-url" - }, - "link": { - "type": "string", - "source": "attribute", - "selector": "img", - "attribute": "data-link" - }, - "alt": { - "type": "string", - "source": "attribute", - "selector": "img", - "attribute": "alt", - "default": "" - }, - "id": { - "type": "string", - "source": "attribute", - "selector": "img", - "attribute": "data-id" - }, - "caption": { - "type": "string", - "source": "html", - "selector": ".blocks-gallery-item__caption" - } - } - }, - "ids": { - "type": "array", "items": { - "type": "number" - }, - "default": [] + "type": "object" + } }, "columns": { "type": "number", @@ -68,14 +24,29 @@ "type": "boolean", "default": true }, + "linkTarget": { + "type": "string" + }, "linkTo": { "type": "string" }, "sizeSlug": { "type": "string", "default": "large" + }, + "allowResize": { + "type": "boolean", + "default": false + }, + "isListItem": { + "type": "boolean", + "default": true } }, + "providesContext": { + "allowResize": "allowResize", + "isListItem": "isListItem" + }, "supports": { "anchor": true, "align": true diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index 1b82131b89085..84bc9fca5bd97 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -15,690 +15,824 @@ import { RichText } from '@wordpress/block-editor'; import { defaultColumnsNumber } from './shared'; const deprecated = [ - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: '.blocks-gallery-item', - query: { - url: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - link: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - alt: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-item__caption', - }, - }, - }, - ids: { - type: 'array', - items: { - type: 'number', - }, - default: [], - }, - columns: { - type: 'number', - minimum: 1, - maximum: 8, - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-caption', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - sizeSlug: { - type: 'string', - default: 'large', - }, - }, - supports: { - align: true, - }, - isEligible( { linkTo } ) { - return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; - }, - migrate( attributes ) { - let linkTo = attributes.linkTo; - if ( ! attributes.linkTo ) { - linkTo = 'none'; - } else if ( attributes.linkTo === 'attachment' ) { - linkTo = 'post'; - } else if ( attributes.linkTo === 'media' ) { - linkTo = 'file'; - } - return { - ...attributes, - linkTo, - }; - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes ), - imageCrop, - caption, - linkTo, - } = attributes; - - return ( -
- - { ! RichText.isEmpty( caption ) && ( - - ) } -
- ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: '.blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-item__caption', - }, - }, - }, - ids: { - type: 'array', - default: [], - }, - columns: { - type: 'number', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-caption', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - isEligible( { ids } ) { - return ids && ids.some( ( id ) => typeof id === 'string' ); - }, - migrate( attributes ) { - return { - ...attributes, - ids: map( attributes.ids, ( id ) => { - const parsedId = parseInt( id, 10 ); - return Number.isInteger( parsedId ) ? parsedId : null; - } ), - }; - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes ), - imageCrop, - caption, - linkTo, - } = attributes; - - return ( -
- - { ! RichText.isEmpty( caption ) && ( - - ) } -
- ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: 'ul.wp-block-gallery .blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - caption: { - type: 'array', - source: 'children', - selector: 'figcaption', - }, - }, - }, - ids: { - type: 'array', - default: [], - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes ), - imageCrop, - linkTo, - } = attributes; - return ( - - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: 'ul.wp-block-gallery .blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - caption: { - type: 'array', - source: 'children', - selector: 'figcaption', - }, - }, - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - isEligible( { images, ids } ) { - return ( - images && - images.length > 0 && - ( ( ! ids && images ) || - ( ids && images && ids.length !== images.length ) || - some( images, ( id, index ) => { - if ( ! id && ids[ index ] !== null ) { - return true; - } - return parseInt( id, 10 ) !== ids[ index ]; - } ) ) - ); - }, - migrate( attributes ) { - return { - ...attributes, - ids: map( attributes.images, ( { id } ) => { - if ( ! id ) { - return null; - } - return parseInt( id, 10 ); - } ), - }; - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes ), - imageCrop, - linkTo, - } = attributes; - return ( - - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: - 'div.wp-block-gallery figure.blocks-gallery-image img', - query: { - url: { - source: 'attribute', - attribute: 'src', - }, - alt: { - source: 'attribute', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - attribute: 'data-id', - }, - }, - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - align: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes ), - align, - imageCrop, - linkTo, - } = attributes; - const className = classnames( `columns-${ columns }`, { - alignnone: align === 'none', - 'is-cropped': imageCrop, - } ); - return ( -
- { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
- { href ? { img } : img } -
- ); - } ) } -
- ); - }, - }, + // Just temporarily comment these out until new structure is finalised + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: '.blocks-gallery-item', + // query: { + // url: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'src', + // }, + // fullUrl: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-full-url', + // }, + // link: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-link', + // }, + // alt: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'alt', + // default: '', + // }, + // id: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-id', + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-item__caption', + // }, + // }, + // }, + // ids: { + // type: 'array', + // items: { + // type: 'number', + // }, + // default: [], + // }, + // columns: { + // type: 'number', + // minimum: 1, + // maximum: 8, + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-caption', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // }, + // sizeSlug: { + // type: 'string', + // default: 'large', + // }, + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // imageCrop, + // caption, + // linkTo, + // } = attributes; + // return ( + //
+ // + // { ! RichText.isEmpty( caption ) && ( + // + // ) } + //
+ // ); + // }, + // }, + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: '.blocks-gallery-item', + // query: { + // url: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'src', + // }, + // fullUrl: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-full-url', + // }, + // link: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-link', + // }, + // alt: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'alt', + // default: '', + // }, + // id: { + // type: 'string', + // source: 'attribute', + // selector: 'img', + // attribute: 'data-id', + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-item__caption', + // }, + // }, + // }, + // ids: { + // type: 'array', + // items: { + // type: 'number', + // }, + // default: [], + // }, + // columns: { + // type: 'number', + // minimum: 1, + // maximum: 8, + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-caption', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // default: 'none', + // }, + // sizeSlug: { + // type: 'string', + // default: 'large', + // }, + // }, + // supports: { + // align: true, + // }, + // isEligible( { linkTo } ) { + // return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; + // }, + // migrate( attributes ) { + // let linkTo = attributes.linkTo; + // if ( ! attributes.linkTo ) { + // linkTo = 'none'; + // } else if ( attributes.linkTo === 'attachment' ) { + // linkTo = 'post'; + // } else if ( attributes.linkTo === 'media' ) { + // linkTo = 'file'; + // } + // return { + // ...attributes, + // linkTo, + // }; + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // imageCrop, + // caption, + // linkTo, + // } = attributes; + // return ( + //
+ // + // { ! RichText.isEmpty( caption ) && ( + // + // ) } + //
+ // ); + // }, + // }, + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: '.blocks-gallery-item', + // query: { + // url: { + // source: 'attribute', + // selector: 'img', + // attribute: 'src', + // }, + // fullUrl: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-full-url', + // }, + // link: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-link', + // }, + // alt: { + // source: 'attribute', + // selector: 'img', + // attribute: 'alt', + // default: '', + // }, + // id: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-id', + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-item__caption', + // }, + // }, + // }, + // ids: { + // type: 'array', + // default: [], + // }, + // columns: { + // type: 'number', + // }, + // caption: { + // type: 'string', + // source: 'html', + // selector: '.blocks-gallery-caption', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // default: 'none', + // }, + // }, + // supports: { + // align: true, + // }, + // isEligible( { ids } ) { + // return ids && ids.some( ( id ) => typeof id === 'string' ); + // }, + // migrate( attributes ) { + // return { + // ...attributes, + // ids: map( attributes.ids, ( id ) => { + // const parsedId = parseInt( id, 10 ); + // return Number.isInteger( parsedId ) ? parsedId : null; + // } ), + // }; + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // imageCrop, + // caption, + // linkTo, + // } = attributes; + // return ( + //
+ // + // { ! RichText.isEmpty( caption ) && ( + // + // ) } + //
+ // ); + // }, + // }, + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: 'ul.wp-block-gallery .blocks-gallery-item', + // query: { + // url: { + // source: 'attribute', + // selector: 'img', + // attribute: 'src', + // }, + // fullUrl: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-full-url', + // }, + // alt: { + // source: 'attribute', + // selector: 'img', + // attribute: 'alt', + // default: '', + // }, + // id: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-id', + // }, + // link: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-link', + // }, + // caption: { + // type: 'array', + // source: 'children', + // selector: 'figcaption', + // }, + // }, + // }, + // ids: { + // type: 'array', + // default: [], + // }, + // columns: { + // type: 'number', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // default: 'none', + // }, + // }, + // supports: { + // align: true, + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // imageCrop, + // linkTo, + // } = attributes; + // return ( + // + // ); + // }, + // }, + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: 'ul.wp-block-gallery .blocks-gallery-item', + // query: { + // url: { + // source: 'attribute', + // selector: 'img', + // attribute: 'src', + // }, + // alt: { + // source: 'attribute', + // selector: 'img', + // attribute: 'alt', + // default: '', + // }, + // id: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-id', + // }, + // link: { + // source: 'attribute', + // selector: 'img', + // attribute: 'data-link', + // }, + // caption: { + // type: 'array', + // source: 'children', + // selector: 'figcaption', + // }, + // }, + // }, + // columns: { + // type: 'number', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // default: 'none', + // }, + // }, + // isEligible( { images, ids } ) { + // return ( + // images && + // images.length > 0 && + // ( ( ! ids && images ) || + // ( ids && images && ids.length !== images.length ) || + // some( images, ( id, index ) => { + // if ( ! id && ids[ index ] !== null ) { + // return true; + // } + // return parseInt( id, 10 ) !== ids[ index ]; + // } ) ) + // ); + // }, + // migrate( attributes ) { + // return { + // ...attributes, + // ids: map( attributes.images, ( { id } ) => { + // if ( ! id ) { + // return null; + // } + // return parseInt( id, 10 ); + // } ), + // }; + // }, + // supports: { + // align: true, + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // imageCrop, + // linkTo, + // } = attributes; + // return ( + // + // ); + // }, + // }, + // { + // attributes: { + // images: { + // type: 'array', + // default: [], + // source: 'query', + // selector: + // 'div.wp-block-gallery figure.blocks-gallery-image img', + // query: { + // url: { + // source: 'attribute', + // attribute: 'src', + // }, + // alt: { + // source: 'attribute', + // attribute: 'alt', + // default: '', + // }, + // id: { + // source: 'attribute', + // attribute: 'data-id', + // }, + // }, + // }, + // columns: { + // type: 'number', + // }, + // imageCrop: { + // type: 'boolean', + // default: true, + // }, + // linkTo: { + // type: 'string', + // default: 'none', + // }, + // align: { + // type: 'string', + // default: 'none', + // }, + // }, + // supports: { + // align: true, + // }, + // save( { attributes } ) { + // const { + // images, + // columns = defaultColumnsNumber( attributes ), + // align, + // imageCrop, + // linkTo, + // } = attributes; + // const className = classnames( `columns-${ columns }`, { + // alignnone: align === 'none', + // 'is-cropped': imageCrop, + // } ); + // return ( + //
+ // { images.map( ( image ) => { + // let href; + // switch ( linkTo ) { + // case 'media': + // href = image.url; + // break; + // case 'attachment': + // href = image.link; + // break; + // } + // const img = ( + // { + // ); + // return ( + //
+ // { href ? { img } : img } + //
+ // ); + // } ) } + //
+ // ); + // }, + // }, ]; export default deprecated; diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 8482e29812516..013c0d27ea93c 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,24 +1,14 @@ /** * External dependencies */ -import { - every, - filter, - find, - forEach, - get, - isEmpty, - map, - reduce, - some, - toString, -} from 'lodash'; +import { toString, isEqual, isEmpty, find } from 'lodash'; /** * WordPress dependencies */ import { compose } from '@wordpress/compose'; import { + Button, PanelBody, SelectControl, ToggleControl, @@ -32,22 +22,25 @@ import { } from '@wordpress/block-editor'; import { Platform, useEffect, useState, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob'; -import { useDispatch, withSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { withViewportMatch } from '@wordpress/viewport'; import { View } from '@wordpress/primitives'; +import { createBlock } from '@wordpress/blocks'; /** * Internal dependencies */ import { sharedIcon } from './shared-icon'; import { defaultColumnsNumber, pickRelevantMediaFiles } from './shared'; +import { getHrefAndDestination, getImageSizeAttributes } from './utils'; +import { getUpdatedLinkTargetSettings } from '../image/utils'; import Gallery from './gallery'; import { LINK_DESTINATION_ATTACHMENT, LINK_DESTINATION_MEDIA, LINK_DESTINATION_NONE, } from './constants'; +import useImageSizes from './use-image-sizes'; const MAX_COLUMNS = 8; const linkOptions = [ @@ -71,146 +64,104 @@ const MOBILE_CONTROL_PROPS_RANGE_CONTROL = Platform.select( { function GalleryEdit( props ) { const { + setAttributes, attributes, + clientId, + noticeOperations, isSelected, noticeUI, - noticeOperations, - mediaUpload, - imageSizes, - resizedImages, - onFocus, + insertBlocksAfter, } = props; + const { - columns = defaultColumnsNumber( attributes ), - imageCrop, - images, + linkTarget, linkTo, + columns = defaultColumnsNumber( images ), sizeSlug, + imageUploads, + imageCrop, } = attributes; - const [ selectedImage, setSelectedImage ] = useState(); - const [ attachmentCaptions, setAttachmentCaptions ] = useState(); + const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( 'core/block-editor' ); - function setAttributes( newAttrs ) { - if ( newAttrs.ids ) { - throw new Error( - 'The "ids" attribute should not be changed directly. It is managed automatically when "images" attribute changes' - ); - } - - if ( newAttrs.images ) { - newAttrs = { - ...newAttrs, - // Unlike images[ n ].id which is a string, always ensure the - // ids array contains numbers as per its attribute type. - ids: map( newAttrs.images, ( { id } ) => parseInt( id, 10 ) ), - }; - } + const currentImageOptions = { linkTarget, linkTo, sizeSlug }; - props.setAttributes( newAttrs ); - } + const [ images, setImages ] = useState( [] ); + const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); + const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); - function onSelectImage( index ) { - return () => { - setSelectedImage( index ); - }; - } + useEffect( () => { + const currentOptionsState = ! isEqual( + currentImageOptions, + imageSettings + ); + if ( currentOptionsState !== dirtyImageOptions ) { + setDirtyImageOptions( currentOptionsState ); + } + }, [ currentImageOptions, imageSettings ] ); - function onDeselectImage() { - return () => { - setSelectedImage(); + const { getBlock, getMedia, getSettings } = useSelect( ( select ) => { + return { + getBlock: select( 'core/block-editor' ).getBlock, + getSettings: select( 'core/block-editor' ).getSettings, + getMedia: select( 'core' ).getMedia, }; - } + }, [] ); - function onMove( oldIndex, newIndex ) { - const newImages = [ ...images ]; - newImages.splice( newIndex, 1, images[ oldIndex ] ); - newImages.splice( oldIndex, 1, images[ newIndex ] ); - setSelectedImage( newIndex ); - setAttributes( { images: newImages } ); - } + const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); - function onMoveForward( oldIndex ) { - return () => { - if ( oldIndex === images.length - 1 ) { - return; - } - onMove( oldIndex, oldIndex + 1 ); - }; - } + const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( + 'core/block-editor' + ); - function onMoveBackward( oldIndex ) { - return () => { - if ( oldIndex === 0 ) { - return; - } - onMove( oldIndex, oldIndex - 1 ); - }; - } + /** + * Determines the image attributes that should be applied to an image block + * after the gallery updates. + * + * The gallery will receive the full collection of images when a new image + * is added. As a result we need to reapply the image's original settings if + * it already existed in the gallery. If the image is in fact new, we need + * to apply the gallery's current settings to the image. + * + * @param {Object} existingBlock Existing Image block that still exists after gallery update. + * @param {Object} image Media object for the actual image. + * @return {Object} Attributes to set on the new image block. + */ + function buildImageAttributes( existingBlock, image ) { + if ( existingBlock ) { + return existingBlock.attributes; + } - function onRemoveImage( index ) { - return () => { - const newImages = filter( images, ( img, i ) => index !== i ); - setSelectedImage(); - setAttributes( { - images: newImages, - columns: attributes.columns - ? Math.min( newImages.length, attributes.columns ) - : attributes.columns, - } ); + return { + ...pickRelevantMediaFiles( image, sizeSlug ), + ...getHrefAndDestination( image, linkTo ), + ...getUpdatedLinkTargetSettings( linkTarget, attributes ), + sizeSlug, }; } - function selectCaption( newImage ) { - // The image id in both the images and attachmentCaptions arrays is a - // string, so ensure comparison works correctly by converting the - // newImage.id to a string. - const newImageId = toString( newImage.id ); - const currentImage = find( images, { id: newImageId } ); - const currentImageCaption = currentImage - ? currentImage.caption - : newImage.caption; - - if ( ! attachmentCaptions ) { - return currentImageCaption; - } + function onSelectImages( newImages ) { + const newBlocks = newImages.map( ( image ) => { + const existingBlock = find( + images, + ( img ) => img.id === image.id + ); - const attachment = find( attachmentCaptions, { - id: newImageId, + return createBlock( 'core/image', { + ...buildImageAttributes( existingBlock, image ), + id: image.id, + } ); } ); - // if the attachment caption is updated - if ( attachment && attachment.caption !== newImage.caption ) { - return newImage.caption; - } - - return currentImageCaption; - } - - function onSelectImages( newImages ) { - setAttachmentCaptions( + setImages( newImages.map( ( newImage ) => ( { - // Store the attachmentCaption id as a string for consistency - // with the type of the id in the images attribute. id: toString( newImage.id ), - caption: newImage.caption, + url: newImage.url, } ) ) ); - setAttributes( { - images: newImages.map( ( newImage ) => ( { - ...pickRelevantMediaFiles( newImage, sizeSlug ), - caption: selectCaption( newImage, images, attachmentCaptions ), - // The id value is stored in a data attribute, so when the - // block is parsed it's converted to a string. Converting - // to a string here ensures it's type is consistent. - id: toString( newImage.id ), - } ) ), - columns: attributes.columns - ? Math.min( newImages.length, attributes.columns ) - : attributes.columns, - } ); + replaceInnerBlocks( clientId, newBlocks ); } function onUploadError( message ) { @@ -236,81 +187,62 @@ function GalleryEdit( props ) { : __( 'Thumbnails are not cropped.' ); } - function onFocusGalleryCaption() { - setSelectedImage(); + function toggleOpenInNewTab() { + setAttributes( { linkTarget: linkTarget ? undefined : '_blank' } ); } - function setImageAttributes( index, newAttributes ) { - if ( ! images[ index ] ) { - return; - } + function applyImageOptions() { + getBlock( clientId ).innerBlocks.forEach( ( block ) => { + const image = block.attributes.id + ? find( images, { id: block.attributes.id } ) + : null; - setAttributes( { - images: [ - ...images.slice( 0, index ), - { - ...images[ index ], - ...newAttributes, - }, - ...images.slice( index + 1 ), - ], + updateBlockAttributes( block.clientId, { + ...getHrefAndDestination( image.imageData, linkTo ), + ...getUpdatedLinkTargetSettings( linkTarget, block.attributes ), + ...getImageSizeAttributes( image.imageData, sizeSlug ), + } ); } ); + setDirtyImageOptions( false ); + setImageSettings( currentImageOptions ); } - function getImagesSizeOptions() { - return map( - filter( imageSizes, ( { slug } ) => - some( resizedImages, ( sizes ) => sizes[ slug ] ) - ), - ( { name, slug } ) => ( { value: slug, label: name } ) - ); + function cancelImageOptions() { + setAttributes( imageSettings ); } function updateImagesSize( newSizeSlug ) { - const updatedImages = map( images, ( image ) => { - if ( ! image.id ) { - return image; - } - const url = get( resizedImages, [ - parseInt( image.id, 10 ), - newSizeSlug, - ] ); - return { - ...image, - ...( url && { url } ), - }; - } ); - - setAttributes( { images: updatedImages, sizeSlug: newSizeSlug } ); + setAttributes( { sizeSlug: newSizeSlug } ); } useEffect( () => { if ( Platform.OS === 'web' && - images && - images.length > 0 && - every( images, ( { url } ) => isBlobURL( url ) ) + imageUploads && + imageUploads.length > 0 ) { - const filesList = map( images, ( { url } ) => getBlobByURL( url ) ); - forEach( images, ( { url } ) => revokeBlobURL( url ) ); - mediaUpload( { - filesList, - onFileChange: onSelectImages, - allowedTypes: [ 'image' ], - } ); + onSelectImages( imageUploads ); + setAttributes( { imageUploads: undefined } ); } - }, [] ); + }, [ imageUploads ] ); useEffect( () => { - // Deselect images when deselecting the block - if ( ! isSelected ) { - setSelectedImage(); + const newImages = getBlock( clientId ).innerBlocks.map( ( block ) => { + return { + id: block.attributes.id, + url: block.attributes.url, + attributes: block.attributes, + imageData: getMedia( block.attributes.id ), + }; + } ); + + if ( ! isEqual( newImages, images ) ) { + setImages( newImages ); } - }, [ isSelected ] ); + } ); useEffect( () => { - // linkTo attribute must be saved so blocks don't break when changing - // image_default_link_type in options.php + // linkTo attribute must be saved so blocks don't break when changing image_default_link_type in options.php if ( ! linkTo ) { __unstableMarkNextChangeAsNotPersistent(); setAttributes( { @@ -340,7 +272,6 @@ function GalleryEdit( props ) { value={ images } onError={ onUploadError } notices={ hasImages ? undefined : noticeUI } - onFocus={ onFocus } /> ); @@ -350,8 +281,8 @@ function GalleryEdit( props ) { return { mediaPlaceholder }; } - const imageSizeOptions = getImagesSizeOptions(); const shouldShowSizeOptions = hasImages && ! isEmpty( imageSizeOptions ); + const hasLinkTo = linkTo && linkTo !== 'none'; return ( <> @@ -380,6 +311,13 @@ function GalleryEdit( props ) { onChange={ setLinkTo } options={ linkOptions } /> + { hasLinkTo && ( + + ) } { shouldShowSizeOptions && ( ) } + { dirtyImageOptions && ( +
+ + +
+ ) } { noticeUI } ); } - export default compose( [ - withSelect( ( select, { attributes: { ids }, isSelected } ) => { - const { getMedia } = select( 'core' ); - const { getSettings } = select( 'core/block-editor' ); - const { imageSizes, mediaUpload } = getSettings(); - - const resizedImages = useMemo( () => { - if ( isSelected ) { - return reduce( - ids, - ( currentResizedImages, id ) => { - if ( ! id ) { - return currentResizedImages; - } - const image = getMedia( id ); - const sizes = reduce( - imageSizes, - ( currentSizes, size ) => { - const defaultUrl = get( image, [ - 'sizes', - size.slug, - 'url', - ] ); - const mediaDetailsUrl = get( image, [ - 'media_details', - 'sizes', - size.slug, - 'source_url', - ] ); - return { - ...currentSizes, - [ size.slug ]: - defaultUrl || mediaDetailsUrl, - }; - }, - {} - ); - return { - ...currentResizedImages, - [ parseInt( id, 10 ) ]: sizes, - }; - }, - {} - ); - } - return {}; - }, [ isSelected, ids, imageSizes ] ); - - return { - imageSizes, - mediaUpload, - resizedImages, - }; - } ), withNotices, withViewportMatch( { isNarrow: '< small' } ), ] )( GalleryEdit ); diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 1b047b4e2b8f6..fb97846200e4f 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -129,3 +129,9 @@ figure.wp-block-gallery { margin-top: -9px; margin-left: -9px; } + +.gallery-settings-buttons { + .components-button:first-child { + margin-right: 8px; + } +} diff --git a/packages/block-library/src/gallery/gallery-image.js b/packages/block-library/src/gallery/gallery-image.js deleted file mode 100644 index 4dac396d289e0..0000000000000 --- a/packages/block-library/src/gallery/gallery-image.js +++ /dev/null @@ -1,313 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { get, omit } from 'lodash'; - -/** - * WordPress dependencies - */ -import { Component } from '@wordpress/element'; -import { Button, Spinner, ButtonGroup } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { BACKSPACE, DELETE } from '@wordpress/keycodes'; -import { withSelect, withDispatch } from '@wordpress/data'; -import { RichText, MediaPlaceholder } from '@wordpress/block-editor'; -import { isBlobURL } from '@wordpress/blob'; -import { compose } from '@wordpress/compose'; -import { - closeSmall, - chevronLeft, - chevronRight, - edit, - image as imageIcon, -} from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import { pickRelevantMediaFiles } from './shared'; -import { - LINK_DESTINATION_ATTACHMENT, - LINK_DESTINATION_MEDIA, -} from './constants'; - -const isTemporaryImage = ( id, url ) => ! id && isBlobURL( url ); - -class GalleryImage extends Component { - constructor() { - super( ...arguments ); - - this.onSelectImage = this.onSelectImage.bind( this ); - this.onSelectCaption = this.onSelectCaption.bind( this ); - this.onRemoveImage = this.onRemoveImage.bind( this ); - this.bindContainer = this.bindContainer.bind( this ); - this.onEdit = this.onEdit.bind( this ); - this.onSelectImageFromLibrary = this.onSelectImageFromLibrary.bind( - this - ); - this.onSelectCustomURL = this.onSelectCustomURL.bind( this ); - this.state = { - captionSelected: false, - isEditing: false, - }; - } - - bindContainer( ref ) { - this.container = ref; - } - - onSelectCaption() { - if ( ! this.state.captionSelected ) { - this.setState( { - captionSelected: true, - } ); - } - - if ( ! this.props.isSelected ) { - this.props.onSelect(); - } - } - - onSelectImage() { - if ( ! this.props.isSelected ) { - this.props.onSelect(); - } - - if ( this.state.captionSelected ) { - this.setState( { - captionSelected: false, - } ); - } - } - - onRemoveImage( event ) { - if ( - this.container === this.container.ownerDocument.activeElement && - this.props.isSelected && - [ BACKSPACE, DELETE ].indexOf( event.keyCode ) !== -1 - ) { - event.stopPropagation(); - event.preventDefault(); - this.props.onRemove(); - } - } - - onEdit() { - this.setState( { - isEditing: true, - } ); - } - - componentDidUpdate( prevProps ) { - const { - isSelected, - image, - url, - __unstableMarkNextChangeAsNotPersistent, - } = this.props; - if ( image && ! url ) { - __unstableMarkNextChangeAsNotPersistent(); - this.props.setAttributes( { - url: image.source_url, - alt: image.alt_text, - } ); - } - - // unselect the caption so when the user selects other image and comeback - // the caption is not immediately selected - if ( - this.state.captionSelected && - ! isSelected && - prevProps.isSelected - ) { - this.setState( { - captionSelected: false, - } ); - } - } - - deselectOnBlur() { - this.props.onDeselect(); - } - - onSelectImageFromLibrary( media ) { - const { setAttributes, id, url, alt, caption, sizeSlug } = this.props; - if ( ! media || ! media.url ) { - return; - } - - let mediaAttributes = pickRelevantMediaFiles( media, sizeSlug ); - - // If the current image is temporary but an alt text was meanwhile - // written by the user, make sure the text is not overwritten. - if ( isTemporaryImage( id, url ) ) { - if ( alt ) { - mediaAttributes = omit( mediaAttributes, [ 'alt' ] ); - } - } - - // If a caption text was meanwhile written by the user, - // make sure the text is not overwritten by empty captions. - if ( caption && ! get( mediaAttributes, [ 'caption' ] ) ) { - mediaAttributes = omit( mediaAttributes, [ 'caption' ] ); - } - - setAttributes( mediaAttributes ); - this.setState( { - isEditing: false, - } ); - } - - onSelectCustomURL( newURL ) { - const { setAttributes, url } = this.props; - if ( newURL !== url ) { - setAttributes( { - url: newURL, - id: undefined, - } ); - this.setState( { - isEditing: false, - } ); - } - } - - render() { - const { - url, - alt, - id, - linkTo, - link, - isFirstItem, - isLastItem, - isSelected, - caption, - onRemove, - onMoveForward, - onMoveBackward, - setAttributes, - 'aria-label': ariaLabel, - } = this.props; - const { isEditing } = this.state; - - let href; - - switch ( linkTo ) { - case LINK_DESTINATION_MEDIA: - href = url; - break; - case LINK_DESTINATION_ATTACHMENT: - href = link; - break; - } - - const img = ( - // Disable reason: Image itself is not meant to be interactive, but should - // direct image selection and unfocus caption fields. - /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ - <> - { - { isBlobURL( url ) && } - - /* eslint-enable jsx-a11y/no-noninteractive-element-interactions */ - ); - - const className = classnames( { - 'is-selected': isSelected, - 'is-transient': isBlobURL( url ), - } ); - - return ( -
- { ! isEditing && ( href ? { img } : img ) } - { isEditing && ( - - ) } - -
- ); - } -} - -export default compose( [ - withSelect( ( select, ownProps ) => { - const { getMedia } = select( 'core' ); - const { id } = ownProps; - - return { - image: id ? getMedia( parseInt( id, 10 ) ) : null, - }; - } ), - withDispatch( ( dispatch ) => { - const { __unstableMarkNextChangeAsNotPersistent } = dispatch( - 'core/block-editor' - ); - return { - __unstableMarkNextChangeAsNotPersistent, - }; - } ), -] )( GalleryImage ); diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index dc261bbf1e469..d716d319e6df8 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -6,15 +6,18 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { + RichText, + __experimentalUseInnerBlocksProps as useInnerBlocksProps, +} from '@wordpress/block-editor'; import { VisuallyHidden } from '@wordpress/components'; -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; +import { useRef, useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import GalleryImage from './gallery-image'; import { defaultColumnsNumber } from './shared'; export const Gallery = ( props ) => { @@ -22,29 +25,40 @@ export const Gallery = ( props ) => { attributes, isSelected, setAttributes, - selectedImage, mediaPlaceholder, - onMoveBackward, - onMoveForward, - onRemoveImage, - onSelectImage, - onDeselectImage, - onSetImageAttributes, - onFocusGalleryCaption, insertBlocksAfter, blockProps, + images, } = props; const { align, - columns = defaultColumnsNumber( attributes ), + columns = defaultColumnsNumber( images ), caption, imageCrop, - images, } = attributes; + const galleryRef = useRef(); + const innerBlocksProps = useInnerBlocksProps( + { + className: 'blocks-gallery-grid', + }, + { + allowedBlocks: [ 'core/image' ], + orientation: 'horizontal', + renderAppender: false, + __experimentalLayout: { type: 'default', alignments: [] }, + } + ); + + useEffect( () => { + if ( galleryRef.current && isSelected ) { + galleryRef.current.parentElement.focus(); + } + }, [ isSelected ] ); return (
{ 'is-cropped': imageCrop, } ) } > -
    - { images.map( ( img, index ) => { - const ariaLabel = sprintf( - /* translators: 1: the order number of the image. 2: the total number of images. */ - __( 'image %1$d of %2$d in gallery' ), - index + 1, - images.length - ); +
      - return ( -
    • - - onSetImageAttributes( index, attrs ) - } - caption={ img.caption } - aria-label={ ariaLabel } - sizeSlug={ attributes.sizeSlug } - /> -
    • - ); - } ) } -
    { mediaPlaceholder } { aria-label={ __( 'Gallery caption text' ) } placeholder={ __( 'Write gallery caption…' ) } value={ caption } - unstableOnFocus={ onFocusGalleryCaption } onChange={ ( value ) => setAttributes( { caption: value } ) } inlineToolbar __unstableOnSplitAtEnd={ () => diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 0c51884a5db95..45cd8ac41ab4a 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -1,73 +1,30 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ -import { RichText, useBlockProps } from '@wordpress/block-editor'; +import { RichText, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; /** * Internal dependencies */ import { defaultColumnsNumber } from './shared'; -import { - LINK_DESTINATION_ATTACHMENT, - LINK_DESTINATION_MEDIA, -} from './constants'; -export default function save( { attributes } ) { +export default function save( { attributes, innerBlocks } ) { const { - images, - columns = defaultColumnsNumber( attributes ), + columns = defaultColumnsNumber( innerBlocks ), imageCrop, caption, - linkTo, } = attributes; const className = `columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return (
      - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case LINK_DESTINATION_MEDIA: - href = image.fullUrl || image.url; - break; - case LINK_DESTINATION_ATTACHMENT: - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
    • -
      - { href ? { img } : img } - { ! RichText.isEmpty( image.caption ) && ( - - ) } -
      -
    • - ); - } ) } +
    { ! RichText.isEmpty( caption ) && ( { @@ -19,5 +24,7 @@ export const pickRelevantMediaFiles = ( image, sizeSlug = 'large' ) => { if ( fullUrl ) { imageProps.fullUrl = fullUrl; } + imageProps.alt = + imageProps.alt !== '' ? imageProps.alt : __( 'Image gallery image' ); return imageProps; }; diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 4a956bf899fa3..c6fa577831cea 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -1,71 +1,68 @@ -.wp-block-gallery, -.blocks-gallery-grid { - display: flex; - flex-wrap: wrap; - list-style-type: none; - padding: 0; - // Some themes give all
      default margin instead of padding. - margin: 0; - - .blocks-gallery-image, - .blocks-gallery-item { - // Add space between thumbnails, and unset right most thumbnails later. - margin: 0 1em 1em 0; +.wp-block-gallery { + ul.blocks-gallery-grid { display: flex; - flex-grow: 1; - flex-direction: column; - justify-content: center; - position: relative; - - // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. - width: calc(50% - 1em); - - &:nth-of-type(even) { - margin-right: 0; - } - - figure { - margin: 0; - height: 100%; - - // IE doesn't support flex so omit that. - @supports (position: sticky) { - display: flex; - align-items: flex-end; - justify-content: flex-start; + flex-wrap: wrap; + list-style-type: none; + padding: 0; + // Some themes give all
        default margin instead of padding. + margin: 0; + + // Need to add the bogus :not(#individual-image) to override long not:() specificity chain + // on default image block on front end. + // Add space between thumbnails, and unset right most thumbnails later. + li.wp-block-image:not(#individual-image) { + margin: 0 $grid-unit-20 $grid-unit-20 0; + &:last-child { + margin-right: 0; } } - img { - display: block; - max-width: 100%; - height: auto; - - // IE doesn't handle cropping, so we need an explicit width here. - width: 100%; + li.wp-block-image { + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: center; + position: relative; - // IE11 doesn't read rules inside this query. They are applied only to modern browsers. - @supports (position: sticky) { - width: auto; + figure, + figure > div { + margin: 0; + height: 100%; } - } - - figcaption { - position: absolute; - bottom: 0; - width: 100%; - max-height: 100%; - overflow: auto; - padding: 3em 0.77em 0.7em; - color: $white; - text-align: center; - font-size: 0.8em; - background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); - box-sizing: border-box; - margin: 0; img { - display: inline; + display: block; + max-width: 100%; + height: auto; + width: 100%; + // IE doesn't handle cropping, so we need an explicit width here. + // IE11 doesn't read rules inside this query. They are applied only to modern browsers. + @supports ( position: sticky ) { + width: auto; + } + } + + figcaption { + position: absolute; + margin-bottom: 0; + bottom: 0; + width: 100%; + max-height: 100%; + overflow: auto; + padding: 40px 10px 9px; + color: $white; + text-align: center; + font-size: $default-font-size; + background: linear-gradient( + 0deg, + rgba( $color: $black, $alpha: 0.7 ) 0, + rgba( $color: $black, $alpha: 0.3 ) 70%, + transparent + ); + + img { + display: inline; + } } } } @@ -75,8 +72,7 @@ } // Cropped - &.is-cropped .blocks-gallery-image, - &.is-cropped .blocks-gallery-item { + &.is-cropped ul.blocks-gallery-grid li.wp-block-image:not(#individual-image) { a, img { // IE11 doesn't support object-fit, so just make sure images aren't skewed. @@ -84,7 +80,7 @@ width: 100%; // IE11 doesn't read rules inside this query. They are applied only to modern browsers. - @supports (position: sticky) { + @supports ( position: sticky ) { height: 100%; flex: 1; object-fit: cover; @@ -92,8 +88,16 @@ } } - &.columns-1 .blocks-gallery-image, - &.columns-1 .blocks-gallery-item { + // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. + & .wp-block-image:not(#individual-image) { + width: calc( 50% - #{$grid-unit-20} ); + + &:nth-of-type( even ) { + margin-right: 0; + } + } + + &.columns-1 .wp-block-image:not(#individual-image) { width: 100%; margin-right: 0; } @@ -101,28 +105,25 @@ // Beyond mobile viewports, we allow up to 8 columns. @include break-small { @for $i from 3 through 8 { - &.columns-#{ $i } .blocks-gallery-image, - &.columns-#{ $i } .blocks-gallery-item { - width: calc(#{ 100% / $i } - #{ 1em * ( $i - 1 ) / $i }); - margin-right: 1em; + &.columns-#{ $i } .wp-block-image:not(#individual-image) { + width: calc( + #{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i} + ); + margin-right: $grid-unit-20; } } // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{ $column-count } .blocks-gallery-image:nth-of-type(#{ $column-count }n), - &.columns-#{ $column-count } .blocks-gallery-item:nth-of-type(#{ $column-count }n) { + &.columns-#{ + $column-count + } + .wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } } - // Last item always needs margins reset. - .blocks-gallery-image:last-child, - .blocks-gallery-item:last-child { - margin-right: 0; - } - // Apply max-width to floated items that have no intrinsic width. &.alignleft, &.alignright { @@ -132,7 +133,7 @@ // If the gallery is centered, center the content inside as well. &.aligncenter { - .blocks-gallery-item figure { + figure.wp-block-image { justify-content: center; } } diff --git a/packages/block-library/src/gallery/transforms.js b/packages/block-library/src/gallery/transforms.js index fa7fff8d46f9f..19b006c2d81a7 100644 --- a/packages/block-library/src/gallery/transforms.js +++ b/packages/block-library/src/gallery/transforms.js @@ -108,7 +108,7 @@ const transforms = { }, transform( files ) { const block = createBlock( 'core/gallery', { - images: files.map( ( file ) => + imageUploads: files.map( ( file ) => pickRelevantMediaFiles( { url: createBlobURL( file ), } ) diff --git a/packages/block-library/src/gallery/use-image-sizes.js b/packages/block-library/src/gallery/use-image-sizes.js new file mode 100644 index 0000000000000..e5888bb2e79ae --- /dev/null +++ b/packages/block-library/src/gallery/use-image-sizes.js @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import { get, reduce, map, filter, some } from 'lodash'; + +export default function useImageSizes( images, isSelected, getSettings ) { + const { imageSizes } = getSettings(); + + let resizedImages = {}; + + if ( isSelected ) { + resizedImages = reduce( + images, + ( currentResizedImages, img ) => { + if ( ! img.id ) { + return currentResizedImages; + } + const image = img.imageData; + const sizes = reduce( + imageSizes, + ( currentSizes, size ) => { + const defaultUrl = get( image, [ + 'sizes', + size.slug, + 'url', + ] ); + const mediaDetailsUrl = get( image, [ + 'media_details', + 'sizes', + size.slug, + 'source_url', + ] ); + return { + ...currentSizes, + [ size.slug ]: defaultUrl || mediaDetailsUrl, + }; + }, + {} + ); + return { + ...currentResizedImages, + [ parseInt( img.id, 10 ) ]: sizes, + }; + }, + {} + ); + } + return map( + filter( imageSizes, ( { slug } ) => + some( resizedImages, ( sizes ) => sizes[ slug ] ) + ), + ( { name, slug } ) => ( { value: slug, label: name } ) + ); +} diff --git a/packages/block-library/src/gallery/utils.js b/packages/block-library/src/gallery/utils.js new file mode 100644 index 0000000000000..60e952e212b23 --- /dev/null +++ b/packages/block-library/src/gallery/utils.js @@ -0,0 +1,68 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import { + LINK_DESTINATION_ATTACHMENT, + LINK_DESTINATION_MEDIA, + LINK_DESTINATION_NONE, +} from './constants'; +import { + LINK_DESTINATION_ATTACHMENT as IMAGE_LINK_DESTINATION_ATTACHMENT, + LINK_DESTINATION_MEDIA as IMAGE_LINK_DESTINATION_MEDIA, + LINK_DESTINATION_NONE as IMAGE_LINK_DESTINATION_NONE, +} from '../image/constants'; + +/** + * Determines new href and linkDestination values for an image block from the + * supplied Gallery link destination. + * + * @param {Object} image Gallery image. + * @param {string} destination Gallery's selected link destination. + * @return {Object} New attributes to assign to image block. + */ +export function getHrefAndDestination( image, destination ) { + // Need to determine the URL that the selected destination maps to. + // Gutenberg and WordPress use different constants so the new link + // destination also needs to be tweaked. + switch ( destination ) { + case LINK_DESTINATION_MEDIA: + return { + href: image?.source_url || image?.url, // eslint-disable-line camelcase + linkDestination: IMAGE_LINK_DESTINATION_MEDIA, + }; + case LINK_DESTINATION_ATTACHMENT: + return { + href: image?.link, + linkDestination: IMAGE_LINK_DESTINATION_ATTACHMENT, + }; + case LINK_DESTINATION_NONE: + return { + href: undefined, + linkDestination: IMAGE_LINK_DESTINATION_NONE, + }; + } + + return {}; +} + +/** + * Determines new Image block attributes affected by a change in Gallery image + * size selection. + * + * @param {Object} image Media file object for gallery image. + * @param {string} size Gallery's selected size slug to apply. + */ +export function getImageSizeAttributes( image, size ) { + const url = get( image, [ 'media_details', 'sizes', size, 'source_url' ] ); + + if ( url ) { + return { url, width: undefined, height: undefined, sizeSlug: size }; + } + + return {}; +} diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 3952230ded6a3..6fafddf148409 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -2,6 +2,7 @@ "apiVersion": 2, "name": "core/image", "category": "media", + "usesContext": [ "allowResize", "isListItem" ], "attributes": { "align": { "type": "string" @@ -68,6 +69,10 @@ "source": "attribute", "selector": "figure > a", "attribute": "target" + }, + "isListItem": { + "type": "boolean", + "default": false } }, "supports": { diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 17109a02f4a3b..9551a8a7550c7 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -17,7 +17,7 @@ import { MediaPlaceholder, useBlockProps, } from '@wordpress/block-editor'; -import { useEffect, useRef } from '@wordpress/element'; +import { useEffect, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { image as icon } from '@wordpress/icons'; @@ -80,6 +80,7 @@ export function ImageEdit( { insertBlocksAfter, noticeOperations, onReplace, + context: { allowResize = true, isListItem = false }, } ) { const { url = '', @@ -92,6 +93,7 @@ export function ImageEdit( { sizeSlug, } = attributes; + const [ tempUrl, setTempUrl ] = useState(); const altRef = useRef(); useEffect( () => { altRef.current = alt; @@ -253,14 +255,18 @@ export function ImageEdit( { // If an image is temporary, revoke the Blob url when it is uploaded (and is // no longer temporary). useEffect( () => { - if ( ! isTemp ) { + if ( isTemp ) { + setTempUrl( url ); return; } + revokeBlobURL( tempUrl ); + }, [ isTemp, url ] ); - return () => { - revokeBlobURL( url ); - }; - }, [ isTemp ] ); + useEffect( () => { + if ( isListItem ) { + setAttributes( { isListItem } ); + } + }, [ isListItem ] ); const isExternal = isExternalImage( id, url ); const controls = ( @@ -308,23 +314,40 @@ export function ImageEdit( { className: classes, } ); + const image = url && ( + + ); + + if ( isListItem ) { + return ( + <> + { controls } +
      • +
        + { image } + { mediaPlaceholder } +
        +
      • + + ); + } + return ( <> { controls }
        - { url && ( - - ) } + { image } { mediaPlaceholder }
        diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 0b7fb5f626c0b..36694379f0c54 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -84,6 +84,7 @@ export default function Image( { onSelectURL, onUploadError, containerRef, + allowResize, } ) { const captionRef = useRef(); const prevUrl = usePrevious( url ); @@ -135,7 +136,7 @@ export default function Image( { const [ isEditingImage, setIsEditingImage ] = useState( false ); const [ externalBlob, setExternalBlob ] = useState(); const clientWidth = useClientWidth( containerRef, [ align ] ); - const isResizable = ! isWideAligned && isLargeViewport; + const isResizable = allowResize && ! ( isWideAligned && isLargeViewport ); const imageSizeOptions = map( filter( imageSizes, ( { slug } ) => get( image, [ 'media_details', 'sizes', slug, 'source_url' ] ) diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index ccf816c121e90..590ae7a10489f 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -24,6 +24,7 @@ export default function save( { attributes } ) { linkTarget, sizeSlug, title, + isListItem, } = attributes; const newRel = isEmpty( rel ) ? undefined : rel; @@ -65,9 +66,18 @@ export default function save( { attributes } ) { ); + const blockProps = useBlockProps.save(); + if ( isListItem ) { + return ( +
      • +
        { figure }
        +
      • + ); + } + if ( 'left' === align || 'right' === align || 'center' === align ) { return ( -
        +
        { figure }
        ); From 7fa1397ab15aeec809bde662d79e0b1314e658ac Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 4 Nov 2020 15:30:24 +1300 Subject: [PATCH 02/86] Fix issue with images not loading on first selection from media gallery --- packages/block-library/src/gallery/edit.js | 39 +++++++++------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 013c0d27ea93c..0e9f10dbf6956 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { toString, isEqual, isEmpty, find } from 'lodash'; +import { isEqual, isEmpty, find } from 'lodash'; /** * WordPress dependencies @@ -87,8 +87,6 @@ function GalleryEdit( props ) { ); const currentImageOptions = { linkTarget, linkTo, sizeSlug }; - - const [ images, setImages ] = useState( [] ); const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); @@ -110,6 +108,20 @@ function GalleryEdit( props ) { }; }, [] ); + const images = useSelect( ( select ) => { + const newImages = select( 'core/block-editor' ) + .getBlock( clientId ) + .innerBlocks.map( ( block ) => { + return { + id: block.attributes.id, + url: block.attributes.url, + attributes: block.attributes, + imageData: getMedia( block.attributes.id ), + }; + } ); + return newImages; + } ); + const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( @@ -155,12 +167,6 @@ function GalleryEdit( props ) { } ); } ); - setImages( - newImages.map( ( newImage ) => ( { - id: toString( newImage.id ), - url: newImage.url, - } ) ) - ); replaceInnerBlocks( clientId, newBlocks ); } @@ -226,21 +232,6 @@ function GalleryEdit( props ) { } }, [ imageUploads ] ); - useEffect( () => { - const newImages = getBlock( clientId ).innerBlocks.map( ( block ) => { - return { - id: block.attributes.id, - url: block.attributes.url, - attributes: block.attributes, - imageData: getMedia( block.attributes.id ), - }; - } ); - - if ( ! isEqual( newImages, images ) ) { - setImages( newImages ); - } - } ); - useEffect( () => { // linkTo attribute must be saved so blocks don't break when changing image_default_link_type in options.php if ( ! linkTo ) { From 4dbf48fa9e74e7f2d3d04b167962ef850118aca0 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 4 Nov 2020 16:34:31 +1300 Subject: [PATCH 03/86] Remove the default columns setting as we don't have access to innerBlocks at the point that the block validation is run --- packages/block-library/src/gallery/edit.js | 8 +++++++- packages/block-library/src/gallery/gallery.js | 13 +------------ packages/block-library/src/gallery/save.js | 18 ++---------------- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 0e9f10dbf6956..87ae2aa1da41d 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -76,7 +76,7 @@ function GalleryEdit( props ) { const { linkTarget, linkTo, - columns = defaultColumnsNumber( images ), + columns, sizeSlug, imageUploads, imageCrop, @@ -122,6 +122,12 @@ function GalleryEdit( props ) { return newImages; } ); + useEffect( () => { + if ( ! columns && images.length > 0 ) { + setAttributes( { columns: defaultColumnsNumber( images ) } ); + } + }, [ images, columns ] ); + const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index d716d319e6df8..a9f6e84592c24 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -15,11 +15,6 @@ import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; import { useRef, useEffect } from '@wordpress/element'; -/** - * Internal dependencies - */ -import { defaultColumnsNumber } from './shared'; - export const Gallery = ( props ) => { const { attributes, @@ -28,15 +23,9 @@ export const Gallery = ( props ) => { mediaPlaceholder, insertBlocksAfter, blockProps, - images, } = props; - const { - align, - columns = defaultColumnsNumber( images ), - caption, - imageCrop, - } = attributes; + const { align, columns, caption, imageCrop } = attributes; const galleryRef = useRef(); const innerBlocksProps = useInnerBlocksProps( { diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 45cd8ac41ab4a..64f020d7ec910 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -1,24 +1,10 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ import { RichText, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; -/** - * Internal dependencies - */ -import { defaultColumnsNumber } from './shared'; - -export default function save( { attributes, innerBlocks } ) { - const { - columns = defaultColumnsNumber( innerBlocks ), - imageCrop, - caption, - } = attributes; +export default function save( { attributes } ) { + const { columns, imageCrop, caption } = attributes; const className = `columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return ( From 9d213194325e1036d4098cdfabd874f59f5b578e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 4 Nov 2020 16:40:27 +1300 Subject: [PATCH 04/86] Revert "Remove the default columns setting as we don't have access to innerBlocks at the point that the block validation is run" This reverts commit 4d95e95d50ae8410868a6d7aca6b9f4c4536d36b. --- packages/block-library/src/gallery/edit.js | 8 +------- packages/block-library/src/gallery/gallery.js | 13 ++++++++++++- packages/block-library/src/gallery/save.js | 18 ++++++++++++++++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 87ae2aa1da41d..0e9f10dbf6956 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -76,7 +76,7 @@ function GalleryEdit( props ) { const { linkTarget, linkTo, - columns, + columns = defaultColumnsNumber( images ), sizeSlug, imageUploads, imageCrop, @@ -122,12 +122,6 @@ function GalleryEdit( props ) { return newImages; } ); - useEffect( () => { - if ( ! columns && images.length > 0 ) { - setAttributes( { columns: defaultColumnsNumber( images ) } ); - } - }, [ images, columns ] ); - const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index a9f6e84592c24..d716d319e6df8 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -15,6 +15,11 @@ import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; import { useRef, useEffect } from '@wordpress/element'; +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from './shared'; + export const Gallery = ( props ) => { const { attributes, @@ -23,9 +28,15 @@ export const Gallery = ( props ) => { mediaPlaceholder, insertBlocksAfter, blockProps, + images, } = props; - const { align, columns, caption, imageCrop } = attributes; + const { + align, + columns = defaultColumnsNumber( images ), + caption, + imageCrop, + } = attributes; const galleryRef = useRef(); const innerBlocksProps = useInnerBlocksProps( { diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 64f020d7ec910..45cd8ac41ab4a 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -1,10 +1,24 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ import { RichText, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; -export default function save( { attributes } ) { - const { columns, imageCrop, caption } = attributes; +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from './shared'; + +export default function save( { attributes, innerBlocks } ) { + const { + columns = defaultColumnsNumber( innerBlocks ), + imageCrop, + caption, + } = attributes; const className = `columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return ( From fe7a91bb52246d21a326955baa0abc56c70a3cb7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 4 Nov 2020 16:49:19 +1300 Subject: [PATCH 05/86] Add image count so we can work out default columns as innerBlocks not available at point of block validation --- packages/block-library/src/gallery/block.json | 4 ++++ packages/block-library/src/gallery/edit.js | 9 ++++++++- packages/block-library/src/gallery/gallery.js | 4 ++-- packages/block-library/src/gallery/save.js | 10 +++------- packages/block-library/src/gallery/shared.js | 4 ++-- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/block-library/src/gallery/block.json b/packages/block-library/src/gallery/block.json index 44f7d069c8bef..8026ad6e7f14e 100644 --- a/packages/block-library/src/gallery/block.json +++ b/packages/block-library/src/gallery/block.json @@ -41,6 +41,10 @@ "isListItem": { "type": "boolean", "default": true + }, + "imageCount": { + "type": "number", + "default": 0 } }, "providesContext": { diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 0e9f10dbf6956..a9efe957d5fb5 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -74,9 +74,10 @@ function GalleryEdit( props ) { } = props; const { + imageCount, linkTarget, linkTo, - columns = defaultColumnsNumber( images ), + columns = defaultColumnsNumber( imageCount ), sizeSlug, imageUploads, imageCrop, @@ -122,6 +123,12 @@ function GalleryEdit( props ) { return newImages; } ); + useEffect( () => { + if ( images.length !== imageCount ) { + setAttributes( { imageCount: images.length } ); + } + }, [ images ] ); + const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index d716d319e6df8..9d36f2e4e0137 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -28,12 +28,12 @@ export const Gallery = ( props ) => { mediaPlaceholder, insertBlocksAfter, blockProps, - images, } = props; const { + imageCount, align, - columns = defaultColumnsNumber( images ), + columns = defaultColumnsNumber( imageCount ), caption, imageCrop, } = attributes; diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 45cd8ac41ab4a..b4c5dc8e770f6 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ @@ -13,9 +8,10 @@ import { RichText, useBlockProps, InnerBlocks } from '@wordpress/block-editor'; */ import { defaultColumnsNumber } from './shared'; -export default function save( { attributes, innerBlocks } ) { +export default function save( { attributes } ) { const { - columns = defaultColumnsNumber( innerBlocks ), + imageCount, + columns = defaultColumnsNumber( imageCount ), imageCrop, caption, } = attributes; diff --git a/packages/block-library/src/gallery/shared.js b/packages/block-library/src/gallery/shared.js index d356403ca1d8f..4c1852280effe 100644 --- a/packages/block-library/src/gallery/shared.js +++ b/packages/block-library/src/gallery/shared.js @@ -8,8 +8,8 @@ import { get, pick } from 'lodash'; */ import { __ } from '@wordpress/i18n'; -export function defaultColumnsNumber( images ) { - return images?.length ? Math.min( 3, images.length ) : 3; +export function defaultColumnsNumber( imageCount ) { + return imageCount ? Math.min( 3, imageCount ) : 3; } export const pickRelevantMediaFiles = ( image, sizeSlug = 'large' ) => { From 849f82ba0f6aa21f8a4f85c83a7d09a5e22318ea Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 5 Nov 2020 17:26:32 +1300 Subject: [PATCH 06/86] Disable the innerBlocks dropzones so drag drop works same as existing gallery - with the idea that we will improve the innerblocks drag and drop in a later PR --- packages/block-editor/src/components/inner-blocks/index.js | 4 +++- .../components/inner-blocks/use-nested-settings-update.js | 7 ++++++- .../src/components/use-block-drop-zone/index.js | 6 ++++-- packages/block-library/src/gallery/editor.scss | 5 +++++ packages/block-library/src/gallery/gallery.js | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 5485df3227af6..a8be7a24e6ff0 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -46,6 +46,7 @@ function UncontrolledInnerBlocks( props ) { __experimentalAppenderTagName, renderAppender, orientation, + dropZonesDisabled, placeholder, __experimentalLayout: layout = defaultLayout, } = props; @@ -55,7 +56,8 @@ function UncontrolledInnerBlocks( props ) { allowedBlocks, templateLock, captureToolbars, - orientation + orientation, + dropZonesDisabled, ); useInnerBlockTemplateSync( diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index ff0f94f637cea..9e99b8dfef3c3 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -33,7 +33,8 @@ export default function useNestedSettingsUpdate( allowedBlocks, templateLock, captureToolbars, - orientation + orientation, + dropZonesDisabled, ) { const { updateBlockListSettings } = useDispatch( blockEditorStore ); @@ -70,6 +71,9 @@ export default function useNestedSettingsUpdate( if ( orientation !== undefined ) { newSettings.orientation = orientation; } + if ( dropZonesDisabled !== undefined ) { + newSettings.dropZonesDisabled = dropZonesDisabled; + } if ( ! isShallowEqual( blockListSettings, newSettings ) ) { updateBlockListSettings( clientId, newSettings ); @@ -82,6 +86,7 @@ export default function useNestedSettingsUpdate( parentLock, captureToolbars, orientation, + dropZonesDisabled, updateBlockListSettings, ] ); } diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 717907a72f484..39975a6be90e7 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -99,12 +99,14 @@ export default function useBlockDropZone( { } ) { const [ targetBlockIndex, setTargetBlockIndex ] = useState( null ); - const { isLockedAll, orientation } = useSelect( + const { isLockedAll, orientation, isDropZonesDisabled } = useSelect( ( select ) => { const { getBlockListSettings, getTemplateLock } = select( blockEditorStore ); return { + isDropZonesDisabled: getBlockListSettings( targetRootClientId ) + ?.dropZonesDisabled, isLockedAll: getTemplateLock( targetRootClientId ) === 'all', orientation: getBlockListSettings( targetRootClientId ) ?.orientation, @@ -120,7 +122,7 @@ export default function useBlockDropZone( { const { position } = useDropZone( { element, - isDisabled: isLockedAll, + isDisabled: isLockedAll || isDropZonesDisabled, withPosition: true, ...dropEventHandlers, } ); diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index fb97846200e4f..a3abcb82a535f 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -2,8 +2,13 @@ // Override the default list style type _only in the editor_ // to avoid :not() selector specificity issues. // See https://github.com/WordPress/gutenberg/pull/10358 + li { list-style-type: none; + .components-drop-zone { + display: none; + pointer-events: none; + } } // @todo: this deserves a refactor, by being moved to the toolbar. diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 9d36f2e4e0137..3e52e1671efbe 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -44,6 +44,7 @@ export const Gallery = ( props ) => { }, { allowedBlocks: [ 'core/image' ], + dropZonesDisabled: true, orientation: 'horizontal', renderAppender: false, __experimentalLayout: { type: 'default', alignments: [] }, From 4553dc2d9d7260a9040cbe0297e7e6ab3d3d934f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 5 Nov 2020 17:27:07 +1300 Subject: [PATCH 07/86] Lint changes --- packages/block-editor/src/components/inner-blocks/index.js | 2 +- .../src/components/inner-blocks/use-nested-settings-update.js | 2 +- .../block-editor/src/components/use-block-drop-zone/index.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index a8be7a24e6ff0..b5f9585bd90d2 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -57,7 +57,7 @@ function UncontrolledInnerBlocks( props ) { templateLock, captureToolbars, orientation, - dropZonesDisabled, + dropZonesDisabled ); useInnerBlockTemplateSync( diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index 9e99b8dfef3c3..bb3fbc931a6e7 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -34,7 +34,7 @@ export default function useNestedSettingsUpdate( templateLock, captureToolbars, orientation, - dropZonesDisabled, + dropZonesDisabled ) { const { updateBlockListSettings } = useDispatch( blockEditorStore ); diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 39975a6be90e7..ffc17c8e776e0 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -106,7 +106,7 @@ export default function useBlockDropZone( { ); return { isDropZonesDisabled: getBlockListSettings( targetRootClientId ) - ?.dropZonesDisabled, + ?.dropZonesDisabled, isLockedAll: getTemplateLock( targetRootClientId ) === 'all', orientation: getBlockListSettings( targetRootClientId ) ?.orientation, From 500b9889737029d1b3d412f2a5881b192e7a368e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 6 Nov 2020 13:32:25 +1300 Subject: [PATCH 08/86] Revert "Lint changes" This reverts commit 9b0abccdc4dc706011e315457a95418f5325f5c1. --- packages/block-editor/src/components/inner-blocks/index.js | 2 +- .../src/components/inner-blocks/use-nested-settings-update.js | 2 +- .../block-editor/src/components/use-block-drop-zone/index.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index b5f9585bd90d2..a8be7a24e6ff0 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -57,7 +57,7 @@ function UncontrolledInnerBlocks( props ) { templateLock, captureToolbars, orientation, - dropZonesDisabled + dropZonesDisabled, ); useInnerBlockTemplateSync( diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index bb3fbc931a6e7..9e99b8dfef3c3 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -34,7 +34,7 @@ export default function useNestedSettingsUpdate( templateLock, captureToolbars, orientation, - dropZonesDisabled + dropZonesDisabled, ) { const { updateBlockListSettings } = useDispatch( blockEditorStore ); diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index ffc17c8e776e0..39975a6be90e7 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -106,7 +106,7 @@ export default function useBlockDropZone( { ); return { isDropZonesDisabled: getBlockListSettings( targetRootClientId ) - ?.dropZonesDisabled, + ?.dropZonesDisabled, isLockedAll: getTemplateLock( targetRootClientId ) === 'all', orientation: getBlockListSettings( targetRootClientId ) ?.orientation, From 540bbbd2e4b05f619e7c331db93fb95e9aad77aa Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 6 Nov 2020 13:32:40 +1300 Subject: [PATCH 09/86] Revert "Disable the innerBlocks dropzones so drag drop works same as existing gallery - with the idea that we will improve the innerblocks drag and drop in a later PR" This reverts commit cc05d60627d4c4970afef73306970762f39c4785. --- packages/block-editor/src/components/inner-blocks/index.js | 4 +--- .../components/inner-blocks/use-nested-settings-update.js | 7 +------ .../src/components/use-block-drop-zone/index.js | 6 ++---- packages/block-library/src/gallery/editor.scss | 5 ----- packages/block-library/src/gallery/gallery.js | 1 - 5 files changed, 4 insertions(+), 19 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index a8be7a24e6ff0..5485df3227af6 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -46,7 +46,6 @@ function UncontrolledInnerBlocks( props ) { __experimentalAppenderTagName, renderAppender, orientation, - dropZonesDisabled, placeholder, __experimentalLayout: layout = defaultLayout, } = props; @@ -56,8 +55,7 @@ function UncontrolledInnerBlocks( props ) { allowedBlocks, templateLock, captureToolbars, - orientation, - dropZonesDisabled, + orientation ); useInnerBlockTemplateSync( diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index 9e99b8dfef3c3..ff0f94f637cea 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -33,8 +33,7 @@ export default function useNestedSettingsUpdate( allowedBlocks, templateLock, captureToolbars, - orientation, - dropZonesDisabled, + orientation ) { const { updateBlockListSettings } = useDispatch( blockEditorStore ); @@ -71,9 +70,6 @@ export default function useNestedSettingsUpdate( if ( orientation !== undefined ) { newSettings.orientation = orientation; } - if ( dropZonesDisabled !== undefined ) { - newSettings.dropZonesDisabled = dropZonesDisabled; - } if ( ! isShallowEqual( blockListSettings, newSettings ) ) { updateBlockListSettings( clientId, newSettings ); @@ -86,7 +82,6 @@ export default function useNestedSettingsUpdate( parentLock, captureToolbars, orientation, - dropZonesDisabled, updateBlockListSettings, ] ); } diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 39975a6be90e7..717907a72f484 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -99,14 +99,12 @@ export default function useBlockDropZone( { } ) { const [ targetBlockIndex, setTargetBlockIndex ] = useState( null ); - const { isLockedAll, orientation, isDropZonesDisabled } = useSelect( + const { isLockedAll, orientation } = useSelect( ( select ) => { const { getBlockListSettings, getTemplateLock } = select( blockEditorStore ); return { - isDropZonesDisabled: getBlockListSettings( targetRootClientId ) - ?.dropZonesDisabled, isLockedAll: getTemplateLock( targetRootClientId ) === 'all', orientation: getBlockListSettings( targetRootClientId ) ?.orientation, @@ -122,7 +120,7 @@ export default function useBlockDropZone( { const { position } = useDropZone( { element, - isDisabled: isLockedAll || isDropZonesDisabled, + isDisabled: isLockedAll, withPosition: true, ...dropEventHandlers, } ); diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index a3abcb82a535f..fb97846200e4f 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -2,13 +2,8 @@ // Override the default list style type _only in the editor_ // to avoid :not() selector specificity issues. // See https://github.com/WordPress/gutenberg/pull/10358 - li { list-style-type: none; - .components-drop-zone { - display: none; - pointer-events: none; - } } // @todo: this deserves a refactor, by being moved to the toolbar. diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 3e52e1671efbe..9d36f2e4e0137 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -44,7 +44,6 @@ export const Gallery = ( props ) => { }, { allowedBlocks: [ 'core/image' ], - dropZonesDisabled: true, orientation: 'horizontal', renderAppender: false, __experimentalLayout: { type: 'default', alignments: [] }, From 4a13c9d26f926e045104ea45c3596d900f455226 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 6 Nov 2020 16:41:51 +1300 Subject: [PATCH 10/86] Suggested solution for handling multiple file drop into gallery --- .../src/components/use-on-block-drop/index.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/use-on-block-drop/index.js b/packages/block-editor/src/components/use-on-block-drop/index.js index 932d94d81b47f..27c5276516c1b 100644 --- a/packages/block-editor/src/components/use-on-block-drop/index.js +++ b/packages/block-editor/src/components/use-on-block-drop/index.js @@ -6,7 +6,7 @@ import { getBlockTransforms, pasteHandler, } from '@wordpress/blocks'; -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch, useSelect, select } from '@wordpress/data'; /** * Internal dependencies @@ -155,6 +155,27 @@ export function onFilesDrop( return; } + const parentBlock = select( 'core/block-editor' ).getBlock( + targetRootClientId + ); + + if ( parentBlock?.name === 'core/gallery' && files?.length > 1 ) { + const transformation = findTransform( + getBlockTransforms( 'from' ), + ( transform ) => + transform.type === 'files' && + transform.isMatch( [ files[ 0 ] ] ) + ); + if ( transformation ) { + const blocks = files.map( ( file ) => + transformation.transform( [ file ], updateBlockAttributes ) + ); + + insertBlocks( blocks, targetBlockIndex, targetRootClientId ); + } + return; + } + const transformation = findTransform( getBlockTransforms( 'from' ), ( transform ) => From bf5f8d95e68e950364118b6dbd932606f4393640 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 22 Jan 2021 11:28:20 +1300 Subject: [PATCH 11/86] Remove non image files from drag and drop and disable individual image drop zone --- .../src/components/use-on-block-drop/index.js | 9 ++++++--- packages/block-library/src/gallery/editor.scss | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/use-on-block-drop/index.js b/packages/block-editor/src/components/use-on-block-drop/index.js index 27c5276516c1b..d241595408e54 100644 --- a/packages/block-editor/src/components/use-on-block-drop/index.js +++ b/packages/block-editor/src/components/use-on-block-drop/index.js @@ -159,15 +159,18 @@ export function onFilesDrop( targetRootClientId ); - if ( parentBlock?.name === 'core/gallery' && files?.length > 1 ) { + const imageFiles = files.filter( + ( file ) => file.type.indexOf( 'image/' ) === 0 + ); + if ( parentBlock?.name === 'core/gallery' && imageFiles?.length > 0 ) { const transformation = findTransform( getBlockTransforms( 'from' ), ( transform ) => transform.type === 'files' && - transform.isMatch( [ files[ 0 ] ] ) + transform.isMatch( [ imageFiles[ 0 ] ] ) ); if ( transformation ) { - const blocks = files.map( ( file ) => + const blocks = imageFiles.map( ( file ) => transformation.transform( [ file ], updateBlockAttributes ) ); diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index fb97846200e4f..244c03effceb7 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -4,6 +4,10 @@ // See https://github.com/WordPress/gutenberg/pull/10358 li { list-style-type: none; + .components-drop-zone { + display: none; + pointer-events: none; + } } // @todo: this deserves a refactor, by being moved to the toolbar. @@ -30,14 +34,17 @@ figure.wp-block-gallery { } .blocks-gallery-item { - // Hide the focus outline that otherwise briefly appears when selecting a block. - figure:not(.is-selected):focus, + figure:not( .is-selected ):focus, img:focus { outline: none; } figure.is-selected { + box-shadow: 0 0 0 $border-width $white, + 0 0 0 3px var( --wp-admin-theme-color ); + border-radius: $radius-block-ui; + outline: 2px solid transparent; &::before { box-shadow: 0 0 0 $border-width $white inset, 0 0 0 3px var(--wp-admin-theme-color) inset; @@ -76,9 +83,9 @@ figure.wp-block-gallery { position: absolute; top: -2px; margin: $grid-unit-10; - z-index: z-index(".block-library-gallery-item__inline-menu"); + z-index: z-index( '.block-library-gallery-item__inline-menu' ); transition: box-shadow 0.2s ease-out; - @include reduce-motion("transition"); + @include reduce-motion( 'transition' ); border-radius: $radius-block-ui; background: $white; border: $border-width solid $gray-900; @@ -96,7 +103,7 @@ figure.wp-block-gallery { } .components-button.has-icon { - &:not(:focus) { + &:not( :focus ) { border: none; box-shadow: none; } @@ -121,7 +128,6 @@ figure.wp-block-gallery { } } - .blocks-gallery-item .components-spinner { position: absolute; top: 50%; From f896da9d8c053b415022707cf35c1415f1c1d237 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 9 Nov 2020 09:36:23 +1300 Subject: [PATCH 12/86] Fix transform to individual images --- .../block-library/src/gallery/transforms.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/gallery/transforms.js b/packages/block-library/src/gallery/transforms.js index 19b006c2d81a7..1f6a52619b48f 100644 --- a/packages/block-library/src/gallery/transforms.js +++ b/packages/block-library/src/gallery/transforms.js @@ -122,17 +122,20 @@ const transforms = { { type: 'block', blocks: [ 'core/image' ], - transform: ( { images, align, sizeSlug, ids } ) => { - if ( images.length > 0 ) { - return images.map( ( { url, alt, caption }, index ) => - createBlock( 'core/image', { - id: ids[ index ], - url, - alt, - caption, - align, - sizeSlug, - } ) + transform: ( { align }, innerBlocks ) => { + if ( innerBlocks.length > 0 ) { + return innerBlocks.map( + ( { + attributes: { id, url, alt, caption, sizeSlug }, + } ) => + createBlock( 'core/image', { + id, + url, + alt, + caption, + sizeSlug, + align, + } ) ); } return createBlock( 'core/image', { align } ); From bd06610dfcf89c156c575305cab769ec6795bde1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 9 Nov 2020 09:59:40 +1300 Subject: [PATCH 13/86] Fix transform from individual images --- .../block-library/src/gallery/transforms.js | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/gallery/transforms.js b/packages/block-library/src/gallery/transforms.js index 1f6a52619b48f..1af7f6689ee16 100644 --- a/packages/block-library/src/gallery/transforms.js +++ b/packages/block-library/src/gallery/transforms.js @@ -41,20 +41,19 @@ const transforms = { : undefined; const validImages = filter( attributes, ( { url } ) => url ); - - return createBlock( 'core/gallery', { - images: validImages.map( - ( { id, url, alt, caption } ) => ( { - id: toString( id ), - url, - alt, - caption, - } ) - ), - ids: validImages.map( ( { id } ) => parseInt( id, 10 ) ), - align, - sizeSlug, + const innerBlocks = validImages.map( ( image ) => { + return createBlock( 'core/image', image ); } ); + + return createBlock( + 'core/gallery', + { + imageCount: innerBlocks.length, + align, + sizeSlug, + }, + innerBlocks + ); }, }, { From 2dd49308f55c7f9b4b6c9d23ea41f2ee1b4ad081 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 10 Nov 2020 10:38:31 +1300 Subject: [PATCH 14/86] Revert drag and drop transform changes --- .../src/components/use-on-block-drop/index.js | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/packages/block-editor/src/components/use-on-block-drop/index.js b/packages/block-editor/src/components/use-on-block-drop/index.js index d241595408e54..932d94d81b47f 100644 --- a/packages/block-editor/src/components/use-on-block-drop/index.js +++ b/packages/block-editor/src/components/use-on-block-drop/index.js @@ -6,7 +6,7 @@ import { getBlockTransforms, pasteHandler, } from '@wordpress/blocks'; -import { useDispatch, useSelect, select } from '@wordpress/data'; +import { useDispatch, useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -155,30 +155,6 @@ export function onFilesDrop( return; } - const parentBlock = select( 'core/block-editor' ).getBlock( - targetRootClientId - ); - - const imageFiles = files.filter( - ( file ) => file.type.indexOf( 'image/' ) === 0 - ); - if ( parentBlock?.name === 'core/gallery' && imageFiles?.length > 0 ) { - const transformation = findTransform( - getBlockTransforms( 'from' ), - ( transform ) => - transform.type === 'files' && - transform.isMatch( [ imageFiles[ 0 ] ] ) - ); - if ( transformation ) { - const blocks = imageFiles.map( ( file ) => - transformation.transform( [ file ], updateBlockAttributes ) - ); - - insertBlocks( blocks, targetBlockIndex, targetRootClientId ); - } - return; - } - const transformation = findTransform( getBlockTransforms( 'from' ), ( transform ) => From 57b7d98b2b38974b7d7576e51d7de9daf6c6b1ae Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 10 Nov 2020 11:10:14 +1300 Subject: [PATCH 15/86] Add gallery transform to image block to override the default gallery transform when dragging multiple images onto the gallery --- .../block-library/src/gallery/transforms.js | 1 + .../block-library/src/image/transforms.js | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/packages/block-library/src/gallery/transforms.js b/packages/block-library/src/gallery/transforms.js index 1af7f6689ee16..1d0b64d77445c 100644 --- a/packages/block-library/src/gallery/transforms.js +++ b/packages/block-library/src/gallery/transforms.js @@ -96,6 +96,7 @@ const transforms = { { // When created by drag and dropping multiple files on an insertion point type: 'files', + priority: 1, isMatch( files ) { return ( files.length !== 1 && diff --git a/packages/block-library/src/image/transforms.js b/packages/block-library/src/image/transforms.js index 80750e8601bf5..e3b39810bda7f 100644 --- a/packages/block-library/src/image/transforms.js +++ b/packages/block-library/src/image/transforms.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { every } from 'lodash'; + /** * WordPress dependencies */ @@ -140,6 +145,29 @@ const transforms = { } ); }, }, + { + // When drag and dropping multiple files onto a gallery this overrrides the + // gallery transform in order to add new images to the gallery instead of + // creating a new gallery. + type: 'files', + isMatch( files ) { + return ( + files.length !== 1 && + every( + files, + ( file ) => file.type.indexOf( 'image/' ) === 0 + ) + ); + }, + transform( files ) { + const blocks = files.map( ( file ) => { + return createBlock( 'core/image', { + url: createBlobURL( file ), + } ); + } ); + return blocks; + }, + }, { type: 'shortcode', tag: 'caption', From 990cfb90cc0f20cf26eca6c1d1f4fcbfd2e506c5 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 17 Nov 2020 11:55:14 +1300 Subject: [PATCH 16/86] Move handling of file uploads to Gallery from media placeholder --- .../src/components/media-placeholder/index.js | 45 +++---------------- packages/block-library/src/gallery/edit.js | 42 +++++++++++++++-- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index c602c4ca8fea7..4cc634fcaa9e6 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -118,47 +118,16 @@ export function MediaPlaceholder( { }; const onFilesUpload = ( files ) => { + if ( addToGallery ) { + // Because the Gallery hands the files over to Image component InnerBlocks just + // hand the handling of the files over to the Gallery + onSelect( files ); + return; + } onFilesPreUpload( files ); let setMedia; if ( multiple ) { - if ( addToGallery ) { - // Since the setMedia function runs multiple times per upload group - // and is passed newMedia containing every item in its group each time, we must - // filter out whatever this upload group had previously returned to the - // gallery before adding and returning the image array with replacement newMedia - // values. - - // Define an array to store urls from newMedia between subsequent function calls. - let lastMediaPassed = []; - setMedia = ( newMedia ) => { - // Remove any images this upload group is responsible for (lastMediaPassed). - // Their replacements are contained in newMedia. - const filteredMedia = ( value ?? [] ).filter( ( item ) => { - // If Item has id, only remove it if lastMediaPassed has an item with that id. - if ( item.id ) { - return ! lastMediaPassed.some( - // Be sure to convert to number for comparison. - ( { id } ) => Number( id ) === Number( item.id ) - ); - } - // Compare transient images via .includes since gallery may append extra info onto the url. - return ! lastMediaPassed.some( ( { urlSlug } ) => - item.url.includes( urlSlug ) - ); - } ); - // Return the filtered media array along with newMedia. - onSelect( filteredMedia.concat( newMedia ) ); - // Reset lastMediaPassed and set it with ids and urls from newMedia. - lastMediaPassed = newMedia.map( ( media ) => { - // Add everything up to '.fileType' to compare via .includes. - const cutOffIndex = media.url.lastIndexOf( '.' ); - const urlSlug = media.url.slice( 0, cutOffIndex ); - return { id: media.id, urlSlug }; - } ); - }; - } else { - setMedia = onSelect; - } + setMedia = onSelect; } else { setMedia = ( [ media ] ) => onSelect( media ); } diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index a9efe957d5fb5..0728cd7e92ce2 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { isEqual, isEmpty, find } from 'lodash'; +import { isEqual, isEmpty, find, uniqBy, concat } from 'lodash'; /** * WordPress dependencies @@ -26,6 +26,7 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { withViewportMatch } from '@wordpress/viewport'; import { View } from '@wordpress/primitives'; import { createBlock } from '@wordpress/blocks'; +import { createBlobURL } from '@wordpress/blob'; /** * Internal dependencies @@ -161,8 +162,41 @@ function GalleryEdit( props ) { }; } - function onSelectImages( newImages ) { - const newBlocks = newImages.map( ( image ) => { + function onSelectImages( selectedImages ) { + const imageArray = + Object.prototype.toString.call( selectedImages ) === + '[object FileList]' + ? Array.from( selectedImages ).map( ( file ) => { + if ( ! file.url ) { + return pickRelevantMediaFiles( { + url: createBlobURL( file ), + } ); + } + + return file; + } ) + : selectedImages; + + const newImages = imageArray + .filter( + ( file ) => file.url || file.type?.indexOf( 'image/' ) === 0 + ) + .map( ( file ) => { + if ( ! file.url ) { + return pickRelevantMediaFiles( { + url: createBlobURL( file ), + } ); + } + + return file; + } ); + + const newAndExistingImages = uniqBy( + concat( newImages, images ), + 'url' + ); + + const newBlocks = newAndExistingImages.map( ( image ) => { const existingBlock = find( images, ( img ) => img.id === image.id @@ -255,7 +289,7 @@ function GalleryEdit( props ) { const mediaPlaceholder = ( Date: Tue, 17 Nov 2020 13:57:02 +1300 Subject: [PATCH 17/86] split innerblocks mapping into separate effect to reduce chatter --- packages/block-library/src/gallery/edit.js | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 0728cd7e92ce2..bdf302e9a052c 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -91,6 +91,7 @@ function GalleryEdit( props ) { const currentImageOptions = { linkTarget, linkTo, sizeSlug }; const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); + const [ images, setImages ] = useState( [] ); useEffect( () => { const currentOptionsState = ! isEqual( @@ -110,20 +111,22 @@ function GalleryEdit( props ) { }; }, [] ); - const images = useSelect( ( select ) => { - const newImages = select( 'core/block-editor' ) - .getBlock( clientId ) - .innerBlocks.map( ( block ) => { - return { - id: block.attributes.id, - url: block.attributes.url, - attributes: block.attributes, - imageData: getMedia( block.attributes.id ), - }; - } ); - return newImages; + const innerBlockImages = useSelect( ( select ) => { + return select( 'core/block-editor' ).getBlock( clientId ).innerBlocks; } ); + useEffect( () => { + const newImages = innerBlockImages.map( ( block ) => { + return { + id: block.attributes.id, + url: block.attributes.url, + attributes: block.attributes, + imageData: getMedia( block.attributes.id ), + }; + } ); + setImages( newImages ); + }, [ innerBlockImages ] ); + useEffect( () => { if ( images.length !== imageCount ) { setAttributes( { imageCount: images.length } ); @@ -207,7 +210,6 @@ function GalleryEdit( props ) { id: image.id, } ); } ); - replaceInnerBlocks( clientId, newBlocks ); } From c360f72e795a004332323ebb719b248c3623cf43 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 09:59:37 +1300 Subject: [PATCH 18/86] Add useMemo to currentImageOptions --- packages/block-library/src/gallery/edit.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index bdf302e9a052c..6ca3fdb56fc81 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -88,7 +88,14 @@ function GalleryEdit( props ) { 'core/block-editor' ); - const currentImageOptions = { linkTarget, linkTo, sizeSlug }; + const currentImageOptions = useMemo( + () => ( { + linkTarget, + linkTo, + sizeSlug, + } ), + [ linkTarget, linkTo, sizeSlug ] + ); const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); const [ images, setImages ] = useState( [] ); From 9509366c9d544884c5fc1e7693226f7f2a64119d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 11:03:00 +1300 Subject: [PATCH 19/86] reuse existing innerBlocks rather than recreating with every new image selection --- .../src/components/media-placeholder/index.js | 10 +++++- packages/block-library/src/gallery/edit.js | 32 +++++++++++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index 4cc634fcaa9e6..68a97cd6686df 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -117,6 +117,14 @@ export function MediaPlaceholder( { } }; + const onMediaLibrarySelection = ( files ) => { + if ( addToGallery ) { + onSelect( files, true ); + return; + } + onSelect( files ); + }; + const onFilesUpload = ( files ) => { if ( addToGallery ) { // Because the Gallery hands the files over to Image component InnerBlocks just @@ -275,7 +283,7 @@ export function MediaPlaceholder( { addToGallery={ addToGallery } gallery={ multiple && onlyAllowsImages() } multiple={ multiple } - onSelect={ onSelect } + onSelect={ onMediaLibrarySelection } allowedTypes={ allowedTypes } value={ Array.isArray( value ) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 6ca3fdb56fc81..8682f488c7c24 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { isEqual, isEmpty, find, uniqBy, concat } from 'lodash'; +import { isEqual, isEmpty, find, concat, differenceBy } from 'lodash'; /** * WordPress dependencies @@ -172,7 +172,7 @@ function GalleryEdit( props ) { }; } - function onSelectImages( selectedImages ) { + function onSelectImages( selectedImages, replace = false ) { const imageArray = Object.prototype.toString.call( selectedImages ) === '[object FileList]' @@ -187,7 +187,7 @@ function GalleryEdit( props ) { } ) : selectedImages; - const newImages = imageArray + const processedImages = imageArray .filter( ( file ) => file.url || file.type?.indexOf( 'image/' ) === 0 ) @@ -201,23 +201,27 @@ function GalleryEdit( props ) { return file; } ); - const newAndExistingImages = uniqBy( - concat( newImages, images ), - 'url' - ); + const existingImageBlocks = replace + ? innerBlockImages.filter( ( block ) => + processedImages.find( + ( img ) => img.url === block.attributes.url + ) + ) + : innerBlockImages; - const newBlocks = newAndExistingImages.map( ( image ) => { - const existingBlock = find( - images, - ( img ) => img.id === image.id - ); + const newImages = differenceBy( processedImages, images, 'url' ); + const newBlocks = newImages.map( ( image ) => { return createBlock( 'core/image', { - ...buildImageAttributes( existingBlock, image ), + ...buildImageAttributes( false, image ), id: image.id, } ); } ); - replaceInnerBlocks( clientId, newBlocks ); + + replaceInnerBlocks( + clientId, + concat( existingImageBlocks, newBlocks ) + ); } function onUploadError( message ) { From 570c702b366914e89571a202158a9c7f29014850 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 11:12:11 +1300 Subject: [PATCH 20/86] Switch to useMemo for updating local image const instead of local component state --- packages/block-library/src/gallery/edit.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 8682f488c7c24..1a6ad9424162e 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -98,7 +98,6 @@ function GalleryEdit( props ) { ); const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); - const [ images, setImages ] = useState( [] ); useEffect( () => { const currentOptionsState = ! isEqual( @@ -122,17 +121,16 @@ function GalleryEdit( props ) { return select( 'core/block-editor' ).getBlock( clientId ).innerBlocks; } ); - useEffect( () => { - const newImages = innerBlockImages.map( ( block ) => { - return { + const images = useMemo( + () => + innerBlockImages.map( ( block ) => ( { id: block.attributes.id, url: block.attributes.url, attributes: block.attributes, imageData: getMedia( block.attributes.id ), - }; - } ); - setImages( newImages ); - }, [ innerBlockImages ] ); + } ) ), + [ innerBlockImages ] + ); useEffect( () => { if ( images.length !== imageCount ) { From be26af818abe9f2cc0c228bce3bd9785f9bbb583 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 11:36:21 +1300 Subject: [PATCH 21/86] Fix issue with image sizing not being available on initial load of component some times --- packages/block-library/src/gallery/edit.js | 11 +++++++++-- packages/block-library/src/gallery/use-image-sizes.js | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 1a6ad9424162e..2dc7188f3de86 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -138,7 +138,12 @@ function GalleryEdit( props ) { } }, [ images ] ); - const imageSizeOptions = useImageSizes( images, isSelected, getSettings ); + const imageSizeOptions = useImageSizes( + images, + isSelected, + getSettings, + getMedia + ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( 'core/block-editor' @@ -254,7 +259,9 @@ function GalleryEdit( props ) { const image = block.attributes.id ? find( images, { id: block.attributes.id } ) : null; - + if ( ! image.imageData ) { + image.imageData = getMedia( image.id ); + } updateBlockAttributes( block.clientId, { ...getHrefAndDestination( image.imageData, linkTo ), ...getUpdatedLinkTargetSettings( linkTarget, block.attributes ), diff --git a/packages/block-library/src/gallery/use-image-sizes.js b/packages/block-library/src/gallery/use-image-sizes.js index e5888bb2e79ae..591d96e767b44 100644 --- a/packages/block-library/src/gallery/use-image-sizes.js +++ b/packages/block-library/src/gallery/use-image-sizes.js @@ -3,7 +3,12 @@ */ import { get, reduce, map, filter, some } from 'lodash'; -export default function useImageSizes( images, isSelected, getSettings ) { +export default function useImageSizes( + images, + isSelected, + getSettings, + getMedia +) { const { imageSizes } = getSettings(); let resizedImages = {}; @@ -15,7 +20,9 @@ export default function useImageSizes( images, isSelected, getSettings ) { if ( ! img.id ) { return currentResizedImages; } - const image = img.imageData; + const image = img.imageData + ? img.imageData + : getMedia( img.id ); const sizes = reduce( imageSizes, ( currentSizes, size ) => { From d152935276ed71ba3c660e4f8a845a2218d59880 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 11:52:15 +1300 Subject: [PATCH 22/86] Memoise the useImageSizes hook --- .../src/gallery/use-image-sizes.js | 98 ++++++++++--------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/packages/block-library/src/gallery/use-image-sizes.js b/packages/block-library/src/gallery/use-image-sizes.js index 591d96e767b44..a563663f6af9b 100644 --- a/packages/block-library/src/gallery/use-image-sizes.js +++ b/packages/block-library/src/gallery/use-image-sizes.js @@ -3,59 +3,67 @@ */ import { get, reduce, map, filter, some } from 'lodash'; +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; + export default function useImageSizes( images, isSelected, getSettings, getMedia ) { - const { imageSizes } = getSettings(); + return useMemo( () => getImageSizing(), [ images, isSelected ] ); - let resizedImages = {}; + function getImageSizing() { + const { imageSizes } = getSettings(); + let resizedImages = {}; - if ( isSelected ) { - resizedImages = reduce( - images, - ( currentResizedImages, img ) => { - if ( ! img.id ) { - return currentResizedImages; - } - const image = img.imageData - ? img.imageData - : getMedia( img.id ); - const sizes = reduce( - imageSizes, - ( currentSizes, size ) => { - const defaultUrl = get( image, [ - 'sizes', - size.slug, - 'url', - ] ); - const mediaDetailsUrl = get( image, [ - 'media_details', - 'sizes', - size.slug, - 'source_url', - ] ); - return { - ...currentSizes, - [ size.slug ]: defaultUrl || mediaDetailsUrl, - }; - }, - {} - ); - return { - ...currentResizedImages, - [ parseInt( img.id, 10 ) ]: sizes, - }; - }, - {} + if ( isSelected ) { + resizedImages = reduce( + images, + ( currentResizedImages, img ) => { + if ( ! img.id ) { + return currentResizedImages; + } + const image = img.imageData + ? img.imageData + : getMedia( img.id ); + const sizes = reduce( + imageSizes, + ( currentSizes, size ) => { + const defaultUrl = get( image, [ + 'sizes', + size.slug, + 'url', + ] ); + const mediaDetailsUrl = get( image, [ + 'media_details', + 'sizes', + size.slug, + 'source_url', + ] ); + return { + ...currentSizes, + [ size.slug ]: defaultUrl || mediaDetailsUrl, + }; + }, + {} + ); + return { + ...currentResizedImages, + [ parseInt( img.id, 10 ) ]: sizes, + }; + }, + {} + ); + } + return map( + filter( imageSizes, ( { slug } ) => + some( resizedImages, ( sizes ) => sizes[ slug ] ) + ), + ( { name, slug } ) => ( { value: slug, label: name } ) ); } - return map( - filter( imageSizes, ( { slug } ) => - some( resizedImages, ( sizes ) => sizes[ slug ] ) - ), - ( { name, slug } ) => ( { value: slug, label: name } ) - ); } From 719b76bd6144f4ca7d1f96cd168f71998f832a1c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 18 Nov 2020 12:23:04 +1300 Subject: [PATCH 23/86] Fix issue with media browser defaulting to edit gallery view --- .../block-editor/src/components/media-placeholder/index.js | 3 ++- packages/block-library/src/gallery/edit.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index 68a97cd6686df..d57309b69e040 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -63,6 +63,7 @@ export function MediaPlaceholder( { isAppender, accept, addToGallery, + isGallery = false, multiple = false, dropZoneUIOnly, disableDropZone, @@ -126,7 +127,7 @@ export function MediaPlaceholder( { }; const onFilesUpload = ( files ) => { - if ( addToGallery ) { + if ( isGallery ) { // Because the Gallery hands the files over to Image component InnerBlocks just // hand the handling of the files over to the Gallery onSelect( files ); diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 2dc7188f3de86..70aaa278ce25f 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -307,7 +307,8 @@ function GalleryEdit( props ) { const mediaPlaceholder = ( Date: Wed, 18 Nov 2020 12:42:31 +1300 Subject: [PATCH 24/86] Fix missed incorrect use of addToGallery --- packages/block-editor/src/components/media-placeholder/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index d57309b69e040..99edaadbd16ec 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -119,7 +119,7 @@ export function MediaPlaceholder( { }; const onMediaLibrarySelection = ( files ) => { - if ( addToGallery ) { + if ( isGallery ) { onSelect( files, true ); return; } From e6572477e7602c7447136d46075959bb9c4fb8d7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 19 Nov 2020 12:44:08 +1300 Subject: [PATCH 25/86] Add some extra effects for getting the imageData as the getMedia call is async so need to keep circling through the innerblocks updates until we have all the data we need --- packages/block-library/src/gallery/edit.js | 67 ++++++++++++++++--- .../src/gallery/use-image-sizes.js | 14 ++-- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 70aaa278ce25f..62d836304818d 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,7 +1,15 @@ /** * External dependencies */ -import { isEqual, isEmpty, find, concat, differenceBy } from 'lodash'; +import { + isEqual, + isEmpty, + find, + concat, + differenceBy, + some, + every, +} from 'lodash'; /** * WordPress dependencies @@ -98,6 +106,7 @@ function GalleryEdit( props ) { ); const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); + const [ imageData, setImageData ] = useState( [] ); useEffect( () => { const currentOptionsState = ! isEqual( @@ -127,11 +136,50 @@ function GalleryEdit( props ) { id: block.attributes.id, url: block.attributes.url, attributes: block.attributes, - imageData: getMedia( block.attributes.id ), } ) ), [ innerBlockImages ] ); + // Wait until all the blocks have an image id before we save the imageData array. + useEffect( () => { + if ( + innerBlockImages.length === 0 || + some( + innerBlockImages, + ( imageBlock ) => ! imageBlock.attributes.id + ) + ) { + return; + } + + const newImageData = innerBlockImages.map( ( imageBlock ) => { + return { + id: imageBlock.attributes.id, + data: getMedia( imageBlock.attributes.id ), + }; + } ); + setImageData( newImageData ); + }, [ innerBlockImages ] ); + + // The getMedia call is async so we need to keep resetting the imageData array until we + // have the imageData returned for every image. + useEffect( () => { + if ( + imageData.length === 0 || + every( imageData, ( img ) => img.data ) + ) { + return; + } + + const newImageData = imageData.map( ( img ) => { + return { + id: img.id, + data: img.data || getMedia( img.id ), + }; + } ); + setImageData( newImageData ); + }, [ imageData ] ); + useEffect( () => { if ( images.length !== imageCount ) { setAttributes( { imageCount: images.length } ); @@ -139,10 +187,9 @@ function GalleryEdit( props ) { }, [ images ] ); const imageSizeOptions = useImageSizes( - images, + imageData, isSelected, - getSettings, - getMedia + getSettings ); const { replaceInnerBlocks, updateBlockAttributes } = useDispatch( @@ -257,15 +304,15 @@ function GalleryEdit( props ) { function applyImageOptions() { getBlock( clientId ).innerBlocks.forEach( ( block ) => { const image = block.attributes.id - ? find( images, { id: block.attributes.id } ) + ? find( imageData, { id: block.attributes.id } ) : null; - if ( ! image.imageData ) { - image.imageData = getMedia( image.id ); + if ( ! image.data ) { + image.data = getMedia( image.id ); } updateBlockAttributes( block.clientId, { - ...getHrefAndDestination( image.imageData, linkTo ), + ...getHrefAndDestination( image.data, linkTo ), ...getUpdatedLinkTargetSettings( linkTarget, block.attributes ), - ...getImageSizeAttributes( image.imageData, sizeSlug ), + ...getImageSizeAttributes( image.data, sizeSlug ), } ); } ); setDirtyImageOptions( false ); diff --git a/packages/block-library/src/gallery/use-image-sizes.js b/packages/block-library/src/gallery/use-image-sizes.js index a563663f6af9b..cd41e7e54a8a8 100644 --- a/packages/block-library/src/gallery/use-image-sizes.js +++ b/packages/block-library/src/gallery/use-image-sizes.js @@ -8,15 +8,13 @@ import { get, reduce, map, filter, some } from 'lodash'; */ import { useMemo } from '@wordpress/element'; -export default function useImageSizes( - images, - isSelected, - getSettings, - getMedia -) { +export default function useImageSizes( images, isSelected, getSettings ) { return useMemo( () => getImageSizing(), [ images, isSelected ] ); function getImageSizing() { + if ( some( images, ( img ) => ! img.data ) ) { + return []; + } const { imageSizes } = getSettings(); let resizedImages = {}; @@ -27,9 +25,7 @@ export default function useImageSizes( if ( ! img.id ) { return currentResizedImages; } - const image = img.imageData - ? img.imageData - : getMedia( img.id ); + const image = img.data; const sizes = reduce( imageSizes, ( currentSizes, size ) => { From 537f7dafdd60eabeda57b48dc6bafa20bd918651 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 19 Nov 2020 14:51:36 +1300 Subject: [PATCH 26/86] Simplify the imageData by using a useSelect --- packages/block-library/src/gallery/edit.js | 76 ++++++------------- .../src/gallery/use-image-sizes.js | 6 +- 2 files changed, 28 insertions(+), 54 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 62d836304818d..52e653101a1db 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,15 +1,7 @@ /** * External dependencies */ -import { - isEqual, - isEmpty, - find, - concat, - differenceBy, - some, - every, -} from 'lodash'; +import { isEqual, isEmpty, find, concat, differenceBy, some } from 'lodash'; /** * WordPress dependencies @@ -106,7 +98,6 @@ function GalleryEdit( props ) { ); const [ imageSettings, setImageSettings ] = useState( currentImageOptions ); const [ dirtyImageOptions, setDirtyImageOptions ] = useState( false ); - const [ imageData, setImageData ] = useState( [] ); useEffect( () => { const currentOptionsState = ! isEqual( @@ -118,11 +109,10 @@ function GalleryEdit( props ) { } }, [ currentImageOptions, imageSettings ] ); - const { getBlock, getMedia, getSettings } = useSelect( ( select ) => { + const { getBlock, getSettings } = useSelect( ( select ) => { return { getBlock: select( 'core/block-editor' ).getBlock, getSettings: select( 'core/block-editor' ).getSettings, - getMedia: select( 'core' ).getMedia, }; }, [] ); @@ -140,45 +130,28 @@ function GalleryEdit( props ) { [ innerBlockImages ] ); - // Wait until all the blocks have an image id before we save the imageData array. - useEffect( () => { - if ( - innerBlockImages.length === 0 || - some( - innerBlockImages, - ( imageBlock ) => ! imageBlock.attributes.id - ) - ) { - return; - } - - const newImageData = innerBlockImages.map( ( imageBlock ) => { - return { - id: imageBlock.attributes.id, - data: getMedia( imageBlock.attributes.id ), - }; - } ); - setImageData( newImageData ); - }, [ innerBlockImages ] ); - - // The getMedia call is async so we need to keep resetting the imageData array until we - // have the imageData returned for every image. - useEffect( () => { - if ( - imageData.length === 0 || - every( imageData, ( img ) => img.data ) - ) { - return; - } + const imageData = useSelect( + ( select ) => { + if ( + innerBlockImages.length === 0 || + some( + innerBlockImages, + ( imageBlock ) => ! imageBlock.attributes.id + ) + ) { + return imageData; + } - const newImageData = imageData.map( ( img ) => { - return { - id: img.id, - data: img.data || getMedia( img.id ), - }; - } ); - setImageData( newImageData ); - }, [ imageData ] ); + const getMedia = select( 'core' ).getMedia; + return innerBlockImages.map( ( imageBlock ) => { + return { + id: imageBlock.attributes.id, + data: getMedia( imageBlock.attributes.id ), + }; + } ); + }, + [ innerBlockImages ] + ); useEffect( () => { if ( images.length !== imageCount ) { @@ -306,9 +279,6 @@ function GalleryEdit( props ) { const image = block.attributes.id ? find( imageData, { id: block.attributes.id } ) : null; - if ( ! image.data ) { - image.data = getMedia( image.id ); - } updateBlockAttributes( block.clientId, { ...getHrefAndDestination( image.data, linkTo ), ...getUpdatedLinkTargetSettings( linkTarget, block.attributes ), diff --git a/packages/block-library/src/gallery/use-image-sizes.js b/packages/block-library/src/gallery/use-image-sizes.js index cd41e7e54a8a8..dd6de3dcc8ea5 100644 --- a/packages/block-library/src/gallery/use-image-sizes.js +++ b/packages/block-library/src/gallery/use-image-sizes.js @@ -12,7 +12,11 @@ export default function useImageSizes( images, isSelected, getSettings ) { return useMemo( () => getImageSizing(), [ images, isSelected ] ); function getImageSizing() { - if ( some( images, ( img ) => ! img.data ) ) { + if ( + ! images || + images.length === 0 || + some( images, ( img ) => ! img.data ) + ) { return []; } const { imageSizes } = getSettings(); From c7de875855b084837a252128768e6519ce444f76 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 19 Nov 2020 15:37:47 +1300 Subject: [PATCH 27/86] Another optimisation - only return a new imageData reference if all images have data resolved --- packages/block-library/src/gallery/edit.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 52e653101a1db..c4e16933d8ff0 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -1,7 +1,15 @@ /** * External dependencies */ -import { isEqual, isEmpty, find, concat, differenceBy, some } from 'lodash'; +import { + isEqual, + isEmpty, + find, + concat, + differenceBy, + some, + every, +} from 'lodash'; /** * WordPress dependencies @@ -143,12 +151,18 @@ function GalleryEdit( props ) { } const getMedia = select( 'core' ).getMedia; - return innerBlockImages.map( ( imageBlock ) => { + const newImageData = innerBlockImages.map( ( imageBlock ) => { return { id: imageBlock.attributes.id, data: getMedia( imageBlock.attributes.id ), }; } ); + + if ( every( newImageData, ( img ) => img.data ) ) { + return newImageData; + } + + return imageData; }, [ innerBlockImages ] ); From b8fb9e54e444f3b9bed3354f46001b6b5ca30df2 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 20 Nov 2020 05:08:11 +1000 Subject: [PATCH 28/86] Refactored Gallery: Add loading state to gallery image size options (#27087) * Add loading spinner for image size options Co-authored-by: Glen Davies --- packages/block-library/src/gallery/edit.js | 20 +++++++++--- .../block-library/src/gallery/editor.scss | 31 +++++++++++++++---- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index c4e16933d8ff0..041cb2f0e8c23 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -16,12 +16,14 @@ import { */ import { compose } from '@wordpress/compose'; import { + BaseControl, Button, PanelBody, SelectControl, ToggleControl, withNotices, RangeControl, + Spinner, } from '@wordpress/components'; import { MediaPlaceholder, @@ -363,7 +365,7 @@ function GalleryEdit( props ) { return { mediaPlaceholder }; } - const shouldShowSizeOptions = hasImages && ! isEmpty( imageSizeOptions ); + const shouldShowSizeOptions = ! isEmpty( imageSizeOptions ); const hasLinkTo = linkTo && linkTo !== 'none'; return ( @@ -400,16 +402,26 @@ function GalleryEdit( props ) { onChange={ toggleOpenInNewTab } /> ) } - { shouldShowSizeOptions && ( + { shouldShowSizeOptions ? ( + ) : ( + + + { __( 'Image size' ) } + + + + { __( 'Loading options…' ) } + + ) } { dirtyImageOptions && ( -
        + @@ -420,7 +432,7 @@ function GalleryEdit( props ) { > { __( 'Cancel' ) } -
        + ) } diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 244c03effceb7..9a96eb2e975dd 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -35,14 +35,15 @@ figure.wp-block-gallery { .blocks-gallery-item { // Hide the focus outline that otherwise briefly appears when selecting a block. - figure:not( .is-selected ):focus, + figure:not(.is-selected):focus, img:focus { outline: none; } figure.is-selected { - box-shadow: 0 0 0 $border-width $white, - 0 0 0 3px var( --wp-admin-theme-color ); + box-shadow: + 0 0 0 $border-width $white, + 0 0 0 3px var(--wp-admin-theme-color); border-radius: $radius-block-ui; outline: 2px solid transparent; @@ -83,9 +84,9 @@ figure.wp-block-gallery { position: absolute; top: -2px; margin: $grid-unit-10; - z-index: z-index( '.block-library-gallery-item__inline-menu' ); + z-index: z-index(".block-library-gallery-item__inline-menu"); transition: box-shadow 0.2s ease-out; - @include reduce-motion( 'transition' ); + @include reduce-motion( "transition" ); border-radius: $radius-block-ui; background: $white; border: $border-width solid $gray-900; @@ -103,7 +104,7 @@ figure.wp-block-gallery { } .components-button.has-icon { - &:not( :focus ) { + &:not(:focus) { border: none; box-shadow: none; } @@ -141,3 +142,21 @@ figure.wp-block-gallery { margin-right: 8px; } } + +.gallery-image-sizes { + .components-base-control__label { + display: block; + margin-bottom: 4px; + } + + .gallery-image-sizes__loading { + display: flex; + align-items: center; + color: $gray-700; + font-size: $helptext-font-size; + } + + .components-spinner { + margin: 0 8px 0 4px; + } +} From 09b7f2bfe881203797ea25772b097f8fecc89fe9 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Jan 2021 13:52:02 +1300 Subject: [PATCH 29/86] Initial deprecations commit --- .../block-library/src/gallery/deprecated.js | 1696 +++++++++-------- 1 file changed, 877 insertions(+), 819 deletions(-) diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index 84bc9fca5bd97..057dae47228b4 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -7,832 +7,890 @@ import { map, some } from 'lodash'; /** * WordPress dependencies */ -import { RichText } from '@wordpress/block-editor'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; +import { createBlock } from '@wordpress/blocks'; /** * Internal dependencies */ import { defaultColumnsNumber } from './shared'; +import { + LINK_DESTINATION_ATTACHMENT, + LINK_DESTINATION_MEDIA, +} from './constants'; +import { getHrefAndDestination } from './utils'; const deprecated = [ - // Just temporarily comment these out until new structure is finalised - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: '.blocks-gallery-item', - // query: { - // url: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'src', - // }, - // fullUrl: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-full-url', - // }, - // link: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-link', - // }, - // alt: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'alt', - // default: '', - // }, - // id: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-id', - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-item__caption', - // }, - // }, - // }, - // ids: { - // type: 'array', - // items: { - // type: 'number', - // }, - // default: [], - // }, - // columns: { - // type: 'number', - // minimum: 1, - // maximum: 8, - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-caption', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // }, - // sizeSlug: { - // type: 'string', - // default: 'large', - // }, - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // imageCrop, - // caption, - // linkTo, - // } = attributes; - // return ( - //
        - //
          - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case LINK_DESTINATION_MEDIA: - // href = image.fullUrl || image.url; - // break; - // case LINK_DESTINATION_ATTACHMENT: - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        • - //
          - // { href ? ( - // { img } - // ) : ( - // img - // ) } - // { ! RichText.isEmpty( - // image.caption - // ) && ( - // - // ) } - //
          - //
        • - // ); - // } ) } - //
        - // { ! RichText.isEmpty( caption ) && ( - // - // ) } - //
        - // ); - // }, - // }, - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: '.blocks-gallery-item', - // query: { - // url: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'src', - // }, - // fullUrl: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-full-url', - // }, - // link: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-link', - // }, - // alt: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'alt', - // default: '', - // }, - // id: { - // type: 'string', - // source: 'attribute', - // selector: 'img', - // attribute: 'data-id', - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-item__caption', - // }, - // }, - // }, - // ids: { - // type: 'array', - // items: { - // type: 'number', - // }, - // default: [], - // }, - // columns: { - // type: 'number', - // minimum: 1, - // maximum: 8, - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-caption', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // default: 'none', - // }, - // sizeSlug: { - // type: 'string', - // default: 'large', - // }, - // }, - // supports: { - // align: true, - // }, - // isEligible( { linkTo } ) { - // return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; - // }, - // migrate( attributes ) { - // let linkTo = attributes.linkTo; - // if ( ! attributes.linkTo ) { - // linkTo = 'none'; - // } else if ( attributes.linkTo === 'attachment' ) { - // linkTo = 'post'; - // } else if ( attributes.linkTo === 'media' ) { - // linkTo = 'file'; - // } - // return { - // ...attributes, - // linkTo, - // }; - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // imageCrop, - // caption, - // linkTo, - // } = attributes; - // return ( - //
        - //
          - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case 'media': - // href = image.fullUrl || image.url; - // break; - // case 'attachment': - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        • - //
          - // { href ? ( - // { img } - // ) : ( - // img - // ) } - // { ! RichText.isEmpty( - // image.caption - // ) && ( - // - // ) } - //
          - //
        • - // ); - // } ) } - //
        - // { ! RichText.isEmpty( caption ) && ( - // - // ) } - //
        - // ); - // }, - // }, - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: '.blocks-gallery-item', - // query: { - // url: { - // source: 'attribute', - // selector: 'img', - // attribute: 'src', - // }, - // fullUrl: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-full-url', - // }, - // link: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-link', - // }, - // alt: { - // source: 'attribute', - // selector: 'img', - // attribute: 'alt', - // default: '', - // }, - // id: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-id', - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-item__caption', - // }, - // }, - // }, - // ids: { - // type: 'array', - // default: [], - // }, - // columns: { - // type: 'number', - // }, - // caption: { - // type: 'string', - // source: 'html', - // selector: '.blocks-gallery-caption', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // default: 'none', - // }, - // }, - // supports: { - // align: true, - // }, - // isEligible( { ids } ) { - // return ids && ids.some( ( id ) => typeof id === 'string' ); - // }, - // migrate( attributes ) { - // return { - // ...attributes, - // ids: map( attributes.ids, ( id ) => { - // const parsedId = parseInt( id, 10 ); - // return Number.isInteger( parsedId ) ? parsedId : null; - // } ), - // }; - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // imageCrop, - // caption, - // linkTo, - // } = attributes; - // return ( - //
        - //
          - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case 'media': - // href = image.fullUrl || image.url; - // break; - // case 'attachment': - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        • - //
          - // { href ? ( - // { img } - // ) : ( - // img - // ) } - // { ! RichText.isEmpty( - // image.caption - // ) && ( - // - // ) } - //
          - //
        • - // ); - // } ) } - //
        - // { ! RichText.isEmpty( caption ) && ( - // - // ) } - //
        - // ); - // }, - // }, - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: 'ul.wp-block-gallery .blocks-gallery-item', - // query: { - // url: { - // source: 'attribute', - // selector: 'img', - // attribute: 'src', - // }, - // fullUrl: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-full-url', - // }, - // alt: { - // source: 'attribute', - // selector: 'img', - // attribute: 'alt', - // default: '', - // }, - // id: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-id', - // }, - // link: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-link', - // }, - // caption: { - // type: 'array', - // source: 'children', - // selector: 'figcaption', - // }, - // }, - // }, - // ids: { - // type: 'array', - // default: [], - // }, - // columns: { - // type: 'number', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // default: 'none', - // }, - // }, - // supports: { - // align: true, - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // imageCrop, - // linkTo, - // } = attributes; - // return ( - //
          - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case 'media': - // href = image.fullUrl || image.url; - // break; - // case 'attachment': - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        • - //
          - // { href ? ( - // { img } - // ) : ( - // img - // ) } - // { image.caption && - // image.caption.length > 0 && ( - // - // ) } - //
          - //
        • - // ); - // } ) } - //
        - // ); - // }, - // }, - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: 'ul.wp-block-gallery .blocks-gallery-item', - // query: { - // url: { - // source: 'attribute', - // selector: 'img', - // attribute: 'src', - // }, - // alt: { - // source: 'attribute', - // selector: 'img', - // attribute: 'alt', - // default: '', - // }, - // id: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-id', - // }, - // link: { - // source: 'attribute', - // selector: 'img', - // attribute: 'data-link', - // }, - // caption: { - // type: 'array', - // source: 'children', - // selector: 'figcaption', - // }, - // }, - // }, - // columns: { - // type: 'number', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // default: 'none', - // }, - // }, - // isEligible( { images, ids } ) { - // return ( - // images && - // images.length > 0 && - // ( ( ! ids && images ) || - // ( ids && images && ids.length !== images.length ) || - // some( images, ( id, index ) => { - // if ( ! id && ids[ index ] !== null ) { - // return true; - // } - // return parseInt( id, 10 ) !== ids[ index ]; - // } ) ) - // ); - // }, - // migrate( attributes ) { - // return { - // ...attributes, - // ids: map( attributes.images, ( { id } ) => { - // if ( ! id ) { - // return null; - // } - // return parseInt( id, 10 ); - // } ), - // }; - // }, - // supports: { - // align: true, - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // imageCrop, - // linkTo, - // } = attributes; - // return ( - //
          - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case 'media': - // href = image.url; - // break; - // case 'attachment': - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        • - //
          - // { href ? ( - // { img } - // ) : ( - // img - // ) } - // { image.caption && - // image.caption.length > 0 && ( - // - // ) } - //
          - //
        • - // ); - // } ) } - //
        - // ); - // }, - // }, - // { - // attributes: { - // images: { - // type: 'array', - // default: [], - // source: 'query', - // selector: - // 'div.wp-block-gallery figure.blocks-gallery-image img', - // query: { - // url: { - // source: 'attribute', - // attribute: 'src', - // }, - // alt: { - // source: 'attribute', - // attribute: 'alt', - // default: '', - // }, - // id: { - // source: 'attribute', - // attribute: 'data-id', - // }, - // }, - // }, - // columns: { - // type: 'number', - // }, - // imageCrop: { - // type: 'boolean', - // default: true, - // }, - // linkTo: { - // type: 'string', - // default: 'none', - // }, - // align: { - // type: 'string', - // default: 'none', - // }, - // }, - // supports: { - // align: true, - // }, - // save( { attributes } ) { - // const { - // images, - // columns = defaultColumnsNumber( attributes ), - // align, - // imageCrop, - // linkTo, - // } = attributes; - // const className = classnames( `columns-${ columns }`, { - // alignnone: align === 'none', - // 'is-cropped': imageCrop, - // } ); - // return ( - //
        - // { images.map( ( image ) => { - // let href; - // switch ( linkTo ) { - // case 'media': - // href = image.url; - // break; - // case 'attachment': - // href = image.link; - // break; - // } - // const img = ( - // { - // ); - // return ( - //
        - // { href ? { img } : img } - //
        - // ); - // } ) } - //
        - // ); - // }, - // }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + items: { + type: 'number', + }, + default: [], + }, + columns: { + type: 'number', + minimum: 1, + maximum: 8, + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + sizeSlug: { + type: 'string', + default: 'large', + }, + }, + supports: { + align: true, + }, + isEligible( { linkTo } ) { + return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; + }, + migrate( attributes ) { + let linkTo = attributes.linkTo; + if ( ! attributes.linkTo ) { + linkTo = 'none'; + } else if ( attributes.linkTo === 'attachment' ) { + linkTo = 'post'; + } else if ( attributes.linkTo === 'media' ) { + linkTo = 'file'; + } + return { + ...attributes, + linkTo, + }; + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( + image.caption + ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, + }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + default: [], + }, + columns: { + type: 'number', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + isEligible( { ids } ) { + return ids && ids.some( ( id ) => typeof id === 'string' ); + }, + migrate( attributes ) { + return { + ...attributes, + ids: map( attributes.ids, ( id ) => { + const parsedId = parseInt( id, 10 ); + return Number.isInteger( parsedId ) ? parsedId : null; + } ), + }; + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( + image.caption + ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, + }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: 'ul.wp-block-gallery .blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + caption: { + type: 'array', + source: 'children', + selector: 'figcaption', + }, + }, + }, + ids: { + type: 'array', + default: [], + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + linkTo, + } = attributes; + return ( +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { image.caption && + image.caption.length > 0 && ( + + ) } +
          +
        • + ); + } ) } +
        + ); + }, + }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: 'ul.wp-block-gallery .blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + caption: { + type: 'array', + source: 'children', + selector: 'figcaption', + }, + }, + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + isEligible( { images, ids } ) { + return ( + images && + images.length > 0 && + ( ( ! ids && images ) || + ( ids && images && ids.length !== images.length ) || + some( images, ( id, index ) => { + if ( ! id && ids[ index ] !== null ) { + return true; + } + return parseInt( id, 10 ) !== ids[ index ]; + } ) ) + ); + }, + migrate( attributes ) { + return { + ...attributes, + ids: map( attributes.images, ( { id } ) => { + if ( ! id ) { + return null; + } + return parseInt( id, 10 ); + } ), + }; + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + linkTo, + } = attributes; + return ( +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { image.caption && + image.caption.length > 0 && ( + + ) } +
          +
        • + ); + } ) } +
        + ); + }, + }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: + 'div.wp-block-gallery figure.blocks-gallery-image img', + query: { + url: { + source: 'attribute', + attribute: 'src', + }, + alt: { + source: 'attribute', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + attribute: 'data-id', + }, + }, + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + align: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + align, + imageCrop, + linkTo, + } = attributes; + const className = classnames( `columns-${ columns }`, { + alignnone: align === 'none', + 'is-cropped': imageCrop, + } ); + return ( +
        + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        + { href ? { img } : img } +
        + ); + } ) } +
        + ); + }, + }, + { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + items: { + type: 'number', + }, + default: [], + }, + columns: { + type: 'number', + minimum: 1, + maximum: 8, + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + }, + sizeSlug: { + type: 'string', + default: 'large', + }, + }, + supports: { + anchor: true, + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + const className = `columns-${ columns } ${ + imageCrop ? 'is-cropped' : '' + }`; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case LINK_DESTINATION_MEDIA: + href = image.fullUrl || image.url; + break; + case LINK_DESTINATION_ATTACHMENT: + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( + image.caption + ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, + isEligible( { ids } ) { + return !! ids; + }, + migrate( { images, imageCrop, linkTo, sizeSlug } ) { + const imageBlocks = images.map( ( image ) => { + const { linkDestination } = getHrefAndDestination( + image, + linkTo + ); + return createBlock( 'core/image', { + id: parseInt( image.id ), + url: image.url, + alt: image.alt, + caption: image.caption, + sizeSlug, + linkDestination, + } ); + } ); + return [ + { + imageCrop, + linkTo, + sizeSlug, + imageCount: imageBlocks.length, + isListItem: true, + }, + imageBlocks, + ]; + }, + }, ]; export default deprecated; From 3ee43f1728b2aa5bf4936361aae7e48808473be0 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 20 Nov 2020 12:04:22 +1300 Subject: [PATCH 30/86] Fix issue with linkDestination not being applied in migration --- packages/block-library/src/gallery/deprecated.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index 057dae47228b4..07e76250bc9f8 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -866,17 +866,13 @@ const deprecated = [ }, migrate( { images, imageCrop, linkTo, sizeSlug } ) { const imageBlocks = images.map( ( image ) => { - const { linkDestination } = getHrefAndDestination( - image, - linkTo - ); return createBlock( 'core/image', { id: parseInt( image.id ), url: image.url, alt: image.alt, caption: image.caption, sizeSlug, - linkDestination, + ...getHrefAndDestination( image, linkTo ), } ); } ); return [ From 1ae1ba2ca1f025ceb99a8d158adec63a3c5501bb Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 20 Nov 2020 10:23:59 +1000 Subject: [PATCH 31/86] Refactor gallery deprecations --- .../block-library/src/gallery/deprecated.js | 892 ------------------ .../src/gallery/deprecated/index.js | 13 + .../src/gallery/deprecated/v1/index.js | 181 ++++ .../src/gallery/deprecated/v2/index.js | 167 ++++ .../src/gallery/deprecated/v3/index.js | 129 +++ .../src/gallery/deprecated/v4/index.js | 149 +++ .../src/gallery/deprecated/v5/index.js | 99 ++ .../src/gallery/deprecated/v6/index.js | 194 ++++ 8 files changed, 932 insertions(+), 892 deletions(-) delete mode 100644 packages/block-library/src/gallery/deprecated.js create mode 100644 packages/block-library/src/gallery/deprecated/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v1/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v2/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v3/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v4/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v5/index.js create mode 100644 packages/block-library/src/gallery/deprecated/v6/index.js diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js deleted file mode 100644 index 07e76250bc9f8..0000000000000 --- a/packages/block-library/src/gallery/deprecated.js +++ /dev/null @@ -1,892 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { map, some } from 'lodash'; - -/** - * WordPress dependencies - */ -import { RichText, useBlockProps } from '@wordpress/block-editor'; -import { createBlock } from '@wordpress/blocks'; - -/** - * Internal dependencies - */ -import { defaultColumnsNumber } from './shared'; -import { - LINK_DESTINATION_ATTACHMENT, - LINK_DESTINATION_MEDIA, -} from './constants'; -import { getHrefAndDestination } from './utils'; - -const deprecated = [ - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: '.blocks-gallery-item', - query: { - url: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - link: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - alt: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-item__caption', - }, - }, - }, - ids: { - type: 'array', - items: { - type: 'number', - }, - default: [], - }, - columns: { - type: 'number', - minimum: 1, - maximum: 8, - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-caption', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - sizeSlug: { - type: 'string', - default: 'large', - }, - }, - supports: { - align: true, - }, - isEligible( { linkTo } ) { - return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; - }, - migrate( attributes ) { - let linkTo = attributes.linkTo; - if ( ! attributes.linkTo ) { - linkTo = 'none'; - } else if ( attributes.linkTo === 'attachment' ) { - linkTo = 'post'; - } else if ( attributes.linkTo === 'media' ) { - linkTo = 'file'; - } - return { - ...attributes, - linkTo, - }; - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes.images.length ), - imageCrop, - caption, - linkTo, - } = attributes; - - return ( -
        -
          - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.fullUrl || image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        • -
          - { href ? ( - { img } - ) : ( - img - ) } - { ! RichText.isEmpty( - image.caption - ) && ( - - ) } -
          -
        • - ); - } ) } -
        - { ! RichText.isEmpty( caption ) && ( - - ) } -
        - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: '.blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-item__caption', - }, - }, - }, - ids: { - type: 'array', - default: [], - }, - columns: { - type: 'number', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-caption', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - isEligible( { ids } ) { - return ids && ids.some( ( id ) => typeof id === 'string' ); - }, - migrate( attributes ) { - return { - ...attributes, - ids: map( attributes.ids, ( id ) => { - const parsedId = parseInt( id, 10 ); - return Number.isInteger( parsedId ) ? parsedId : null; - } ), - }; - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes?.images.length ), - imageCrop, - caption, - linkTo, - } = attributes; - - return ( -
        -
          - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.fullUrl || image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        • -
          - { href ? ( - { img } - ) : ( - img - ) } - { ! RichText.isEmpty( - image.caption - ) && ( - - ) } -
          -
        • - ); - } ) } -
        - { ! RichText.isEmpty( caption ) && ( - - ) } -
        - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: 'ul.wp-block-gallery .blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - caption: { - type: 'array', - source: 'children', - selector: 'figcaption', - }, - }, - }, - ids: { - type: 'array', - default: [], - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes?.images.length ), - imageCrop, - linkTo, - } = attributes; - return ( -
          - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.fullUrl || image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        • -
          - { href ? ( - { img } - ) : ( - img - ) } - { image.caption && - image.caption.length > 0 && ( - - ) } -
          -
        • - ); - } ) } -
        - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: 'ul.wp-block-gallery .blocks-gallery-item', - query: { - url: { - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - alt: { - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - link: { - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - caption: { - type: 'array', - source: 'children', - selector: 'figcaption', - }, - }, - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - }, - isEligible( { images, ids } ) { - return ( - images && - images.length > 0 && - ( ( ! ids && images ) || - ( ids && images && ids.length !== images.length ) || - some( images, ( id, index ) => { - if ( ! id && ids[ index ] !== null ) { - return true; - } - return parseInt( id, 10 ) !== ids[ index ]; - } ) ) - ); - }, - migrate( attributes ) { - return { - ...attributes, - ids: map( attributes.images, ( { id } ) => { - if ( ! id ) { - return null; - } - return parseInt( id, 10 ); - } ), - }; - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes?.images.length ), - imageCrop, - linkTo, - } = attributes; - return ( -
          - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        • -
          - { href ? ( - { img } - ) : ( - img - ) } - { image.caption && - image.caption.length > 0 && ( - - ) } -
          -
        • - ); - } ) } -
        - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: - 'div.wp-block-gallery figure.blocks-gallery-image img', - query: { - url: { - source: 'attribute', - attribute: 'src', - }, - alt: { - source: 'attribute', - attribute: 'alt', - default: '', - }, - id: { - source: 'attribute', - attribute: 'data-id', - }, - }, - }, - columns: { - type: 'number', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - default: 'none', - }, - align: { - type: 'string', - default: 'none', - }, - }, - supports: { - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes?.images.length ), - align, - imageCrop, - linkTo, - } = attributes; - const className = classnames( `columns-${ columns }`, { - alignnone: align === 'none', - 'is-cropped': imageCrop, - } ); - return ( -
        - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case 'media': - href = image.url; - break; - case 'attachment': - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        - { href ? { img } : img } -
        - ); - } ) } -
        - ); - }, - }, - { - attributes: { - images: { - type: 'array', - default: [], - source: 'query', - selector: '.blocks-gallery-item', - query: { - url: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'src', - }, - fullUrl: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-full-url', - }, - link: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-link', - }, - alt: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'alt', - default: '', - }, - id: { - type: 'string', - source: 'attribute', - selector: 'img', - attribute: 'data-id', - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-item__caption', - }, - }, - }, - ids: { - type: 'array', - items: { - type: 'number', - }, - default: [], - }, - columns: { - type: 'number', - minimum: 1, - maximum: 8, - }, - caption: { - type: 'string', - source: 'html', - selector: '.blocks-gallery-caption', - }, - imageCrop: { - type: 'boolean', - default: true, - }, - linkTo: { - type: 'string', - }, - sizeSlug: { - type: 'string', - default: 'large', - }, - }, - supports: { - anchor: true, - align: true, - }, - save( { attributes } ) { - const { - images, - columns = defaultColumnsNumber( attributes?.images.length ), - imageCrop, - caption, - linkTo, - } = attributes; - const className = `columns-${ columns } ${ - imageCrop ? 'is-cropped' : '' - }`; - - return ( -
        -
          - { images.map( ( image ) => { - let href; - - switch ( linkTo ) { - case LINK_DESTINATION_MEDIA: - href = image.fullUrl || image.url; - break; - case LINK_DESTINATION_ATTACHMENT: - href = image.link; - break; - } - - const img = ( - { - ); - - return ( -
        • -
          - { href ? ( - { img } - ) : ( - img - ) } - { ! RichText.isEmpty( - image.caption - ) && ( - - ) } -
          -
        • - ); - } ) } -
        - { ! RichText.isEmpty( caption ) && ( - - ) } -
        - ); - }, - isEligible( { ids } ) { - return !! ids; - }, - migrate( { images, imageCrop, linkTo, sizeSlug } ) { - const imageBlocks = images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); - } ); - return [ - { - imageCrop, - linkTo, - sizeSlug, - imageCount: imageBlocks.length, - isListItem: true, - }, - imageBlocks, - ]; - }, - }, -]; - -export default deprecated; diff --git a/packages/block-library/src/gallery/deprecated/index.js b/packages/block-library/src/gallery/deprecated/index.js new file mode 100644 index 0000000000000..a3a13cc6bbcf7 --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/index.js @@ -0,0 +1,13 @@ +/** + * Internal dependencies + */ +import v1 from './v1'; +import v2 from './v2'; +import v3 from './v3'; +import v4 from './v4'; +import v5 from './v5'; +import v6 from './v6'; + +const deprecated = [ v1, v2, v3, v4, v5, v6 ]; + +export default deprecated; diff --git a/packages/block-library/src/gallery/deprecated/v1/index.js b/packages/block-library/src/gallery/deprecated/v1/index.js new file mode 100644 index 0000000000000..c5859d76eb52d --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v1/index.js @@ -0,0 +1,181 @@ +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + items: { + type: 'number', + }, + default: [], + }, + columns: { + type: 'number', + minimum: 1, + maximum: 8, + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + sizeSlug: { + type: 'string', + default: 'large', + }, + }, + supports: { + align: true, + }, + isEligible( { linkTo } ) { + return ! linkTo || linkTo === 'attachment' || linkTo === 'media'; + }, + migrate( attributes ) { + let linkTo = attributes.linkTo; + if ( ! attributes.linkTo ) { + linkTo = 'none'; + } else if ( attributes.linkTo === 'attachment' ) { + linkTo = 'post'; + } else if ( attributes.linkTo === 'media' ) { + linkTo = 'file'; + } + return { + ...attributes, + linkTo, + }; + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( image.caption ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, +}; diff --git a/packages/block-library/src/gallery/deprecated/v2/index.js b/packages/block-library/src/gallery/deprecated/v2/index.js new file mode 100644 index 0000000000000..dc87def816bc0 --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v2/index.js @@ -0,0 +1,167 @@ +/** + * External dependencies + */ +import { map } from 'lodash'; + +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + default: [], + }, + columns: { + type: 'number', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + isEligible( { ids } ) { + return ids && ids.some( ( id ) => typeof id === 'string' ); + }, + migrate( attributes ) { + return { + ...attributes, + ids: map( attributes.ids, ( id ) => { + const parsedId = parseInt( id, 10 ); + return Number.isInteger( parsedId ) ? parsedId : null; + } ), + }; + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( image.caption ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, +}; diff --git a/packages/block-library/src/gallery/deprecated/v3/index.js b/packages/block-library/src/gallery/deprecated/v3/index.js new file mode 100644 index 0000000000000..9e4ca741f964b --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v3/index.js @@ -0,0 +1,129 @@ +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: 'ul.wp-block-gallery .blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + caption: { + type: 'array', + source: 'children', + selector: 'figcaption', + }, + }, + }, + ids: { + type: 'array', + default: [], + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + linkTo, + } = attributes; + return ( +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.fullUrl || image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? { img } : img } + { image.caption && image.caption.length > 0 && ( + + ) } +
          +
        • + ); + } ) } +
        + ); + }, +}; diff --git a/packages/block-library/src/gallery/deprecated/v4/index.js b/packages/block-library/src/gallery/deprecated/v4/index.js new file mode 100644 index 0000000000000..e5df2a80ed5eb --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v4/index.js @@ -0,0 +1,149 @@ +/** + * External dependencies + */ +import { map, some } from 'lodash'; + +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: 'ul.wp-block-gallery .blocks-gallery-item', + query: { + url: { + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + alt: { + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + link: { + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + caption: { + type: 'array', + source: 'children', + selector: 'figcaption', + }, + }, + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + }, + isEligible( { images, ids } ) { + return ( + images && + images.length > 0 && + ( ( ! ids && images ) || + ( ids && images && ids.length !== images.length ) || + some( images, ( id, index ) => { + if ( ! id && ids[ index ] !== null ) { + return true; + } + return parseInt( id, 10 ) !== ids[ index ]; + } ) ) + ); + }, + migrate( attributes ) { + return { + ...attributes, + ids: map( attributes.images, ( { id } ) => { + if ( ! id ) { + return null; + } + return parseInt( id, 10 ); + } ), + }; + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + linkTo, + } = attributes; + return ( +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? { img } : img } + { image.caption && image.caption.length > 0 && ( + + ) } +
          +
        • + ); + } ) } +
        + ); + }, +}; diff --git a/packages/block-library/src/gallery/deprecated/v5/index.js b/packages/block-library/src/gallery/deprecated/v5/index.js new file mode 100644 index 0000000000000..9d30b126dee00 --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v5/index.js @@ -0,0 +1,99 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: 'div.wp-block-gallery figure.blocks-gallery-image img', + query: { + url: { + source: 'attribute', + attribute: 'src', + }, + alt: { + source: 'attribute', + attribute: 'alt', + default: '', + }, + id: { + source: 'attribute', + attribute: 'data-id', + }, + }, + }, + columns: { + type: 'number', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + default: 'none', + }, + align: { + type: 'string', + default: 'none', + }, + }, + supports: { + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + align, + imageCrop, + linkTo, + } = attributes; + const className = classnames( `columns-${ columns }`, { + alignnone: align === 'none', + 'is-cropped': imageCrop, + } ); + return ( +
        + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case 'media': + href = image.url; + break; + case 'attachment': + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        + { href ? { img } : img } +
        + ); + } ) } +
        + ); + }, +}; diff --git a/packages/block-library/src/gallery/deprecated/v6/index.js b/packages/block-library/src/gallery/deprecated/v6/index.js new file mode 100644 index 0000000000000..d7ad303f20132 --- /dev/null +++ b/packages/block-library/src/gallery/deprecated/v6/index.js @@ -0,0 +1,194 @@ +/** + * WordPress dependencies + */ +import { RichText, useBlockProps } from '@wordpress/block-editor'; +import { createBlock } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { defaultColumnsNumber } from '../../shared'; +import { + LINK_DESTINATION_ATTACHMENT, + LINK_DESTINATION_MEDIA, +} from '../../constants'; +import { getHrefAndDestination } from '../../utils'; + +export default { + attributes: { + images: { + type: 'array', + default: [], + source: 'query', + selector: '.blocks-gallery-item', + query: { + url: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'src', + }, + fullUrl: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-full-url', + }, + link: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-link', + }, + alt: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'alt', + default: '', + }, + id: { + type: 'string', + source: 'attribute', + selector: 'img', + attribute: 'data-id', + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-item__caption', + }, + }, + }, + ids: { + type: 'array', + items: { + type: 'number', + }, + default: [], + }, + columns: { + type: 'number', + minimum: 1, + maximum: 8, + }, + caption: { + type: 'string', + source: 'html', + selector: '.blocks-gallery-caption', + }, + imageCrop: { + type: 'boolean', + default: true, + }, + linkTo: { + type: 'string', + }, + sizeSlug: { + type: 'string', + default: 'large', + }, + }, + supports: { + anchor: true, + align: true, + }, + save( { attributes } ) { + const { + images, + columns = defaultColumnsNumber( attributes?.images.length ), + imageCrop, + caption, + linkTo, + } = attributes; + const className = `columns-${ columns } ${ + imageCrop ? 'is-cropped' : '' + }`; + + return ( +
        +
          + { images.map( ( image ) => { + let href; + + switch ( linkTo ) { + case LINK_DESTINATION_MEDIA: + href = image.fullUrl || image.url; + break; + case LINK_DESTINATION_ATTACHMENT: + href = image.link; + break; + } + + const img = ( + { + ); + + return ( +
        • +
          + { href ? ( + { img } + ) : ( + img + ) } + { ! RichText.isEmpty( image.caption ) && ( + + ) } +
          +
        • + ); + } ) } +
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
        + ); + }, + isEligible( { ids } ) { + return !! ids; + }, + migrate( { images, imageCrop, linkTo, sizeSlug } ) { + const imageBlocks = images.map( ( image ) => { + return createBlock( 'core/image', { + id: parseInt( image.id ), + url: image.url, + alt: image.alt, + caption: image.caption, + sizeSlug, + ...getHrefAndDestination( image, linkTo ), + } ); + } ); + return [ + { + imageCrop, + linkTo, + sizeSlug, + imageCount: imageBlocks.length, + isListItem: true, + }, + imageBlocks, + ]; + }, +}; From 15909d52b14036ae57ad9f90202f0bb2cdd396cb Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 20 Nov 2020 12:14:52 +1000 Subject: [PATCH 32/86] Fix missing attributes from migration --- packages/block-library/src/gallery/deprecated/v6/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/deprecated/v6/index.js b/packages/block-library/src/gallery/deprecated/v6/index.js index d7ad303f20132..5d779023fae12 100644 --- a/packages/block-library/src/gallery/deprecated/v6/index.js +++ b/packages/block-library/src/gallery/deprecated/v6/index.js @@ -169,7 +169,7 @@ export default { isEligible( { ids } ) { return !! ids; }, - migrate( { images, imageCrop, linkTo, sizeSlug } ) { + migrate( { images, imageCrop, linkTo, sizeSlug, columns, caption } ) { const imageBlocks = images.map( ( image ) => { return createBlock( 'core/image', { id: parseInt( image.id ), @@ -182,6 +182,8 @@ export default { } ); return [ { + caption, + columns, imageCrop, linkTo, sizeSlug, From b4fbe2e65b2fba57b036b5f7dcccf554ed3cc4b9 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Sun, 22 Nov 2020 18:20:53 +1000 Subject: [PATCH 33/86] Update deprecation to set allowResize The imageEdit component defaults the context value for allowResize to true. The refactored gallery sets this to false by default. Setting allowResize to false when migrating a deprecated gallery allows images to be cropped in the display the same as the gallery when the post is saved and gallery reloaded. --- packages/block-library/src/gallery/deprecated/v6/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-library/src/gallery/deprecated/v6/index.js b/packages/block-library/src/gallery/deprecated/v6/index.js index 5d779023fae12..4532706965544 100644 --- a/packages/block-library/src/gallery/deprecated/v6/index.js +++ b/packages/block-library/src/gallery/deprecated/v6/index.js @@ -188,6 +188,7 @@ export default { linkTo, sizeSlug, imageCount: imageBlocks.length, + allowResize: false, isListItem: true, }, imageBlocks, From 817a964c68a47794e38f2faa39ed5c3006bf4eaa Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 23 Nov 2020 12:00:41 +1300 Subject: [PATCH 34/86] Fix issue with crop not working when certain plugins are loaded --- packages/block-library/src/gallery/style.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index c6fa577831cea..bbd6cf3e592dd 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -73,8 +73,11 @@ // Cropped &.is-cropped ul.blocks-gallery-grid li.wp-block-image:not(#individual-image) { - a, - img { + figure > div { + display: flex; + } + + a, img { // IE11 doesn't support object-fit, so just make sure images aren't skewed. // The following rules are for all browsers. width: 100%; From 8eed7f4efcf69fb0a539af70597ece5761fd5e24 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Mon, 23 Nov 2020 09:42:27 +1000 Subject: [PATCH 35/86] Fix SCSS lint errors --- packages/block-library/src/gallery/style.scss | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index bbd6cf3e592dd..bc31de11c13a8 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -7,7 +7,7 @@ // Some themes give all
          default margin instead of padding. margin: 0; - // Need to add the bogus :not(#individual-image) to override long not:() specificity chain + // Need to add the bogus :not(#individual-image) to override long not:() specificity chain // on default image block on front end. // Add space between thumbnails, and unset right most thumbnails later. li.wp-block-image:not(#individual-image) { @@ -53,12 +53,7 @@ color: $white; text-align: center; font-size: $default-font-size; - background: linear-gradient( - 0deg, - rgba( $color: $black, $alpha: 0.7 ) 0, - rgba( $color: $black, $alpha: 0.3 ) 70%, - transparent - ); + background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); img { display: inline; @@ -77,7 +72,8 @@ display: flex; } - a, img { + a, + img { // IE11 doesn't support object-fit, so just make sure images aren't skewed. // The following rules are for all browsers. width: 100%; @@ -93,9 +89,9 @@ // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. & .wp-block-image:not(#individual-image) { - width: calc( 50% - #{$grid-unit-20} ); + width: calc(50% - #{$grid-unit-20}); - &:nth-of-type( even ) { + &:nth-of-type(even) { margin-right: 0; } } @@ -109,19 +105,14 @@ @include break-small { @for $i from 3 through 8 { &.columns-#{ $i } .wp-block-image:not(#individual-image) { - width: calc( - #{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i} - ); + width: calc(#{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i}); margin-right: $grid-unit-20; } } // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{ - $column-count - } - .wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { + &.columns-#{$column-count} .wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } From b07fe676fae4780b4ec961c9371a9b09a11ca238 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 23 Nov 2020 16:51:31 +1300 Subject: [PATCH 36/86] Update the block example --- packages/block-library/src/gallery/index.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/block-library/src/gallery/index.js b/packages/block-library/src/gallery/index.js index 677291252e7ce..b434e51397d0a 100644 --- a/packages/block-library/src/gallery/index.js +++ b/packages/block-library/src/gallery/index.js @@ -25,17 +25,18 @@ export const settings = { example: { attributes: { columns: 2, - images: [ - { - url: - 'https://s.w.org/images/core/5.3/Glacial_lakes%2C_Bhutan.jpg', - }, - { - url: - 'https://s.w.org/images/core/5.3/Sediment_off_the_Yucatan_Peninsula.jpg', - }, - ], + imageCount: 2, }, + innerBlocks: [ + { + name: 'core/image', + attributes: { url: 'https://s.w.org/images/core/5.3/Glacial_lakes%2C_Bhutan.jpg' }, + }, + { + name: 'core/image', + attributes: { url: 'https://s.w.org/images/core/5.3/Sediment_off_the_Yucatan_Peninsula.jpg' }, + }, + ], }, transforms, edit, From 0a325dc50b072efcbd1e6999e99d8cc85ef1f25a Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 23 Nov 2020 16:52:06 +1300 Subject: [PATCH 37/86] Linting fixes --- packages/block-library/src/gallery/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/index.js b/packages/block-library/src/gallery/index.js index b434e51397d0a..4e6431c19dbc0 100644 --- a/packages/block-library/src/gallery/index.js +++ b/packages/block-library/src/gallery/index.js @@ -30,11 +30,17 @@ export const settings = { innerBlocks: [ { name: 'core/image', - attributes: { url: 'https://s.w.org/images/core/5.3/Glacial_lakes%2C_Bhutan.jpg' }, + attributes: { + url: + 'https://s.w.org/images/core/5.3/Glacial_lakes%2C_Bhutan.jpg', + }, }, { name: 'core/image', - attributes: { url: 'https://s.w.org/images/core/5.3/Sediment_off_the_Yucatan_Peninsula.jpg' }, + attributes: { + url: + 'https://s.w.org/images/core/5.3/Sediment_off_the_Yucatan_Peninsula.jpg', + }, }, ], }, From 2c189482caa53eddd0f0d11ac1d773ba6ac21c6a Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 24 Nov 2020 01:30:27 +1300 Subject: [PATCH 38/86] Fix the e2e test and the accessibility issue with having aria group role on a list item --- packages/block-library/src/gallery/style.scss | 14 +++++++------- packages/block-library/src/image/edit.js | 4 ++-- packages/block-library/src/image/save.js | 4 ++-- .../e2e-tests/specs/editor/blocks/gallery.test.js | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index bc31de11c13a8..68e4792dfb7ef 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -10,14 +10,14 @@ // Need to add the bogus :not(#individual-image) to override long not:() specificity chain // on default image block on front end. // Add space between thumbnails, and unset right most thumbnails later. - li.wp-block-image:not(#individual-image) { + li.list-image:not(#individual-image) { margin: 0 $grid-unit-20 $grid-unit-20 0; &:last-child { margin-right: 0; } } - li.wp-block-image { + li.list-image { display: flex; flex-grow: 1; flex-direction: column; @@ -67,7 +67,7 @@ } // Cropped - &.is-cropped ul.blocks-gallery-grid li.wp-block-image:not(#individual-image) { + &.is-cropped ul.blocks-gallery-grid li.list-image:not(#individual-image) { figure > div { display: flex; } @@ -88,7 +88,7 @@ } // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. - & .wp-block-image:not(#individual-image) { + & li:not(#individual-image) { width: calc(50% - #{$grid-unit-20}); &:nth-of-type(even) { @@ -96,7 +96,7 @@ } } - &.columns-1 .wp-block-image:not(#individual-image) { + &.columns-1 li:not(#individual-image) { width: 100%; margin-right: 0; } @@ -104,7 +104,7 @@ // Beyond mobile viewports, we allow up to 8 columns. @include break-small { @for $i from 3 through 8 { - &.columns-#{ $i } .wp-block-image:not(#individual-image) { + &.columns-#{ $i } li.list-image:not(#individual-image) { width: calc(#{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i}); margin-right: $grid-unit-20; } @@ -112,7 +112,7 @@ // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{$column-count} .wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { + &.columns-#{$column-count} li.list-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 9551a8a7550c7..a4414ff85785d 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -333,8 +333,8 @@ export function ImageEdit( { return ( <> { controls } -
        • -
          +
        • +
          { image } { mediaPlaceholder }
          diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index 590ae7a10489f..4ac47c68772b8 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -69,8 +69,8 @@ export default function save( { attributes } ) { const blockProps = useBlockProps.save(); if ( isListItem ) { return ( -
        • -
          { figure }
          +
        • +
          { figure }
        • ); } diff --git a/packages/e2e-tests/specs/editor/blocks/gallery.test.js b/packages/e2e-tests/specs/editor/blocks/gallery.test.js index eff1b56a5d714..2b4e2d0218a33 100644 --- a/packages/e2e-tests/specs/editor/blocks/gallery.test.js +++ b/packages/e2e-tests/specs/editor/blocks/gallery.test.js @@ -47,7 +47,7 @@ describe( 'Gallery', () => { const filename = await upload( '.wp-block-gallery input[type="file"]' ); const regex = new RegExp( - `\\s*
        ); }; diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index b7ce05431b59a..06964ec5389f1 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -20,17 +20,17 @@ export default function save( { attributes } ) { }`; return ( -
        -
          +
          +
          -
        - { ! RichText.isEmpty( caption ) && ( - - ) } -
        + { ! RichText.isEmpty( caption ) && ( + + ) } +
    + ); } diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 3d8339f1bf610..b0df78b3eb0a6 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -3,16 +3,14 @@ // Styles for current version of gallery block. .wp-block-gallery.has-nested-images { - ul.blocks-gallery-grid { + display: block; + + figure.blocks-gallery-grid { display: flex; flex-wrap: wrap; - list-style-type: none; - margin: 0; // Some themes give all
      default margin instead of padding. - padding: 0; - // Need bogus :not(#individual-image) to override long :not() // specificity chain on default image block on front end. - li.list-image:not(#individual-image) { + figure.wp-block-image:not(#individual-image) { // Add space between thumbnails, and unset right most thumbnails later. margin: 0 $grid-unit-20 $grid-unit-20 0; @@ -21,7 +19,7 @@ } } - li.list-image { + figure.wp-block-image { display: flex; flex-grow: 1; justify-content: center; @@ -32,23 +30,8 @@ flex-direction: column; } - // Again, we need :not(#individual-image) to override long :not() - // chain on frontend styles. - figure:not(#individual-image) { - display: block; // IE11's lack of object-fit cover means flex will distort image as it fills space. - margin: 0; - max-width: 100%; // When aligned wide or full, this allows image to fill row. - - // Avoid applying flex styles to IE11. - @supports ( position: sticky ) { - display: flex; - flex-direction: column; // Needed for frontend when img isn't wrapped in div. - flex-grow: 1; - } - } - - figure > div, - figure > a { + > div, + > a { margin: 0; // Avoid applying flex styles to IE11. @@ -97,9 +80,9 @@ } // Cropped Images. - &.is-cropped ul.blocks-gallery-grid li.list-image:not(#individual-image) { - figure > div:not(.components-drop-zone), - figure > a { + &.is-cropped figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image) { + > div:not(.components-drop-zone), + > a { display: block; // Thanks to IE11 not supporting object-fit fall back to display: block. // Without IE11 object-fit support "display: flex;" here causes distortion of aspect ratio. @@ -122,7 +105,7 @@ } // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. - & li:not(#individual-image) { + & figure.wp-block-image:not(#individual-image) { width: calc(50% - #{$grid-unit-20}); &:nth-of-type(even) { @@ -130,7 +113,7 @@ } } - &.columns-1 li:not(#individual-image) { + &.columns-1 figure.wp-block-image:not(#individual-image) { margin-right: 0; width: 100%; } @@ -138,7 +121,7 @@ // Beyond mobile viewports, we allow up to 8 columns. @include break-small { @for $i from 3 through 8 { - &.columns-#{ $i } li.list-image:not(#individual-image) { + &.columns-#{ $i } figure.wp-block-image:not(#individual-image) { margin-right: $grid-unit-20; width: calc(#{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i}); } @@ -146,7 +129,7 @@ // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{$column-count} li.list-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { + &.columns-#{$column-count} figure.wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 11ac962e287e7..3053673f9dc3a 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -4,7 +4,7 @@ "category": "media", "usesContext": [ "allowResize", - "isListItem", + "isGrouped", "linkTo", "linkTarget", "sizeSlug" @@ -76,10 +76,6 @@ "selector": "figure > a", "attribute": "target" }, - "isListItem": { - "type": "boolean", - "default": false - }, "inheritedAttributes": { "type": "object", "default": { diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index e68ca3723aa15..6021c6e147069 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -94,7 +94,7 @@ export function ImageEdit( { sizeSlug, inhertedAttributes, } = attributes; - const { isListItem } = context; + const { isGrouped } = context; const [ tempUrl, setTempUrl ] = useState(); const altRef = useRef(); useEffect( () => { @@ -162,7 +162,7 @@ export function ImageEdit( { // Check if default link setting, or the one inherited from parent block should be used. let linkDestination = - isListItem && context.linkTo + isGrouped && context.linkTo ? context.linkTo : attributes.linkDestination; @@ -203,7 +203,7 @@ export function ImageEdit( { } mediaAttributes.href = href; - if ( isListItem ) { + if ( isGrouped ) { const parentSizeAttributes = getImageSizeAttributes( media, context.sizeSlug @@ -290,12 +290,6 @@ export function ImageEdit( { revokeBlobURL( tempUrl ); }, [ isTemp, url ] ); - useEffect( () => { - if ( isListItem ) { - setAttributes( { isListItem } ); - } - }, [ isListItem ] ); - const isExternal = isExternalImage( id, url ); const controls = ( @@ -335,7 +329,6 @@ export function ImageEdit( { 'is-resized': !! width || !! height, 'is-focused': isSelected, [ `size-${ sizeSlug }` ]: sizeSlug, - 'list-image': isListItem, } ); const blockProps = useBlockProps( { @@ -359,20 +352,6 @@ export function ImageEdit( { /> ); - if ( isListItem ) { - return ( - <> - { controls } -
    • -
      - { image } - { mediaPlaceholder } -
      -
    • - - ); - } - return ( <> { controls } diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 6f2f328d5b782..d000ea8c5bf2e 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -90,7 +90,7 @@ export default function Image( { } ) { const captionRef = useRef(); const prevUrl = usePrevious( url ); - const { allowResize = true, isListItem = false } = context; + const { allowResize = true, isGrouped = false } = context; const { block, currentId, image, multiImageSelection } = useSelect( ( select ) => { const { getMedia } = select( 'core' ); @@ -105,7 +105,7 @@ export default function Image( { block: getSelectedBlock(), currentId: getSelectedBlockClientId(), image: - id && ( isSelected || isListItem ) ? getMedia( id ) : null, + id && ( isSelected || isGrouped ) ? getMedia( id ) : null, multiImageSelection: multiSelectedClientIds.length && multiSelectedClientIds.every( @@ -114,7 +114,7 @@ export default function Image( { ), }; }, - [ id, isSelected, isListItem ] + [ id, isSelected, isGrouped ] ); const { imageEditing, imageSizes, maxWidth, mediaUpload } = useSelect( ( select ) => { diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index 868db590e9a58..65ecc35c4f8c5 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -24,7 +24,6 @@ export default function save( { attributes } ) { linkTarget, sizeSlug, title, - isListItem, } = attributes; const newRel = isEmpty( rel ) ? undefined : rel; @@ -33,7 +32,6 @@ export default function save( { attributes } ) { [ `align${ align }` ]: align, [ `size-${ sizeSlug }` ]: sizeSlug, 'is-resized': width || height, - 'list-image': isListItem, } ); const image = ( @@ -68,13 +66,6 @@ export default function save( { attributes } ) { ); const blockProps = useBlockProps.save( { className: classes } ); - if ( isListItem ) { - return ( -
    • -
      { figure }
      -
    • - ); - } if ( 'left' === align || 'right' === align || 'center' === align ) { return ( diff --git a/packages/block-library/src/image/use-parent-attributes.js b/packages/block-library/src/image/use-parent-attributes.js index 754315c7d6d2a..c837ae3b76e9f 100644 --- a/packages/block-library/src/image/use-parent-attributes.js +++ b/packages/block-library/src/image/use-parent-attributes.js @@ -24,14 +24,14 @@ export default function useParentAttributes( setAttributes ) { const { - isListItem, + isGrouped, linkTo: parentLinkDestination, linkTarget: parentLinkTarget, sizeSlug: parentSizeSlug, } = context; useEffect( () => { - if ( ! isListItem ) { + if ( ! isGrouped ) { return; } if ( inheritedAttributes.linkDestination && image ) { @@ -41,10 +41,10 @@ export default function useParentAttributes( linkDestination: parentLinkDestination, } ); } - }, [ image, parentLinkDestination, isListItem ] ); + }, [ image, parentLinkDestination, isGrouped ] ); useEffect( () => { - if ( ! isListItem ) { + if ( ! isGrouped ) { return; } if ( inheritedAttributes.linkTarget ) { @@ -52,10 +52,10 @@ export default function useParentAttributes( linkTarget: parentLinkTarget, } ); } - }, [ parentLinkTarget, isListItem ] ); + }, [ parentLinkTarget, isGrouped ] ); useEffect( () => { - if ( ! isListItem ) { + if ( ! isGrouped ) { return; } @@ -69,5 +69,5 @@ export default function useParentAttributes( ...sizeAttributes, } ); } - }, [ parentSizeSlug, isListItem ] ); + }, [ parentSizeSlug, isGrouped ] ); } From 8b06149cba609bd73980c5d23077d30c30a9ec4c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 22 Jan 2021 11:33:46 +1300 Subject: [PATCH 59/86] Remove wrapper div --- .../block-library/src/gallery/editor.scss | 4 + packages/block-library/src/gallery/gallery.js | 41 +++--- packages/block-library/src/gallery/save.js | 24 ++-- packages/block-library/src/gallery/style.scss | 123 +++++++++--------- 4 files changed, 95 insertions(+), 97 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 97eb352e502bf..2b219be895503 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -75,6 +75,10 @@ figure.wp-block-gallery { .components-placeholder__label { display: flex; } + .media-placeholder { + display: block; + width: 100%; + } } } diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 4586e015351ba..85c0650b2dc65 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -13,7 +13,7 @@ import { import { VisuallyHidden } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; -import { useRef, useEffect } from '@wordpress/element'; +import { useRef, useEffect, Fragment } from '@wordpress/element'; /** * Internal dependencies @@ -57,7 +57,7 @@ export const Gallery = ( props ) => { }, [ isSelected ] ); return ( -
      { 'is-cropped': imageCrop, } ) } > -
      - - { mediaPlaceholder } - setAttributes( { caption: value } ) } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> -
      + +
      + { mediaPlaceholder } + + setAttributes( { caption: value } ) + } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> +
      +
); }; diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 06964ec5389f1..aa870938cdb1c 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -15,22 +15,20 @@ export default function save( { attributes } ) { imageCrop, caption, } = attributes; - const className = `has-nested-images columns-${ columns } ${ + const className = `blocks-gallery-grid has-nested-images columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return ( -
-
- - { ! RichText.isEmpty( caption ) && ( - - ) } -
-
+
+ + { ! RichText.isEmpty( caption ) && ( + + ) } +
); } diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index b0df78b3eb0a6..32d1eee2e0546 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -3,74 +3,76 @@ // Styles for current version of gallery block. .wp-block-gallery.has-nested-images { - display: block; + display: flex; + flex-wrap: wrap; + // Need bogus :not(#individual-image) to override long :not() + // specificity chain on default image block on front end. + figure.wp-block-image:not(#individual-image) { + // Add space between thumbnails, and unset right most thumbnails later. + margin: 0 $grid-unit-20 $grid-unit-20 0; + + &:last-child { + margin-right: 0; + } + + width: calc(50% - #{$grid-unit-20}); + + &:nth-of-type(even) { + margin-right: 0; + } + } - figure.blocks-gallery-grid { + figure.wp-block-image { display: flex; - flex-wrap: wrap; - // Need bogus :not(#individual-image) to override long :not() - // specificity chain on default image block on front end. - figure.wp-block-image:not(#individual-image) { - // Add space between thumbnails, and unset right most thumbnails later. - margin: 0 $grid-unit-20 $grid-unit-20 0; - - &:last-child { - margin-right: 0; - } + flex-grow: 1; + justify-content: center; + position: relative; + + // IE11 doesn't like the "flex-direction: column;" here. + @supports ( position: sticky ) { + flex-direction: column; } - figure.wp-block-image { - display: flex; - flex-grow: 1; - justify-content: center; - position: relative; + > div, + > a { + margin: 0; - // IE11 doesn't like the "flex-direction: column;" here. + // Avoid applying flex styles to IE11. @supports ( position: sticky ) { flex-direction: column; + flex-grow: 1; } + } - > div, - > a { - margin: 0; + img { + display: block; + height: auto; + max-width: 100%; + width: 100%; - // Avoid applying flex styles to IE11. - @supports ( position: sticky ) { - flex-direction: column; - flex-grow: 1; - } + // IE doesn't handle cropping, so we need an explicit width here. + // IE11 doesn't read rules inside this query. They are applied only to modern browsers. + @supports ( position: sticky ) { + width: auto; } + } - img { - display: block; - height: auto; - max-width: 100%; - width: 100%; - - // IE doesn't handle cropping, so we need an explicit width here. - // IE11 doesn't read rules inside this query. They are applied only to modern browsers. - @supports ( position: sticky ) { - width: auto; - } - } + figcaption { + background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); + bottom: 0; + color: $white; + font-size: $default-font-size; + left: 0; + margin-bottom: 0; + max-height: 100%; + overflow: auto; + padding: 40px 10px 9px; + position: absolute; + text-align: center; + width: 100%; - figcaption { - background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); - bottom: 0; - color: $white; - font-size: $default-font-size; - left: 0; - margin-bottom: 0; - max-height: 100%; - overflow: auto; - padding: 40px 10px 9px; - position: absolute; - text-align: center; - width: 100%; - - img { - display: inline; - } + img { + display: inline; } } } @@ -80,7 +82,7 @@ } // Cropped Images. - &.is-cropped figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image) { + &.is-cropped figure.wp-block-image:not(#individual-image) { > div:not(.components-drop-zone), > a { display: block; // Thanks to IE11 not supporting object-fit fall back to display: block. @@ -104,15 +106,6 @@ } } - // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. - & figure.wp-block-image:not(#individual-image) { - width: calc(50% - #{$grid-unit-20}); - - &:nth-of-type(even) { - margin-right: 0; - } - } - &.columns-1 figure.wp-block-image:not(#individual-image) { margin-right: 0; width: 100%; From 260764d04e1339aef52d34b4788e851dd5aa8047 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Jan 2021 14:00:34 +1300 Subject: [PATCH 60/86] remove extra wrapper around media placeholder and caption and use flex css instead --- .../block-library/src/gallery/editor.scss | 5 ++- packages/block-library/src/gallery/gallery.js | 33 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 2b219be895503..ecb67180df55f 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -8,7 +8,10 @@ pointer-events: none; } } - + .components-form-file-upload, + .blocks-gallery-caption { + flex: 0 0 100%; + } // @todo: this deserves a refactor, by being moved to the toolbar. .block-editor-media-placeholder.is-appender { .components-placeholder__label { diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 85c0650b2dc65..f47131c4eeb47 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -67,24 +67,21 @@ export const Gallery = ( props ) => { } ) } > -
- { mediaPlaceholder } - - setAttributes( { caption: value } ) - } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> -
+ + { mediaPlaceholder } + setAttributes( { caption: value } ) } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> ); }; From 7cbea7ac43c667ad8e4d06eaf14fff7cf8a553d5 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Jan 2021 14:01:23 +1300 Subject: [PATCH 61/86] Revert "remove extra wrapper around media placeholder and caption and use flex css instead --- .../block-library/src/gallery/editor.scss | 5 +-- packages/block-library/src/gallery/gallery.js | 33 ++++++++++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index ecb67180df55f..2b219be895503 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -8,10 +8,7 @@ pointer-events: none; } } - .components-form-file-upload, - .blocks-gallery-caption { - flex: 0 0 100%; - } + // @todo: this deserves a refactor, by being moved to the toolbar. .block-editor-media-placeholder.is-appender { .components-placeholder__label { diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index f47131c4eeb47..85c0650b2dc65 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -67,21 +67,24 @@ export const Gallery = ( props ) => { } ) } > - - { mediaPlaceholder } - setAttributes( { caption: value } ) } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> +
+ { mediaPlaceholder } + + setAttributes( { caption: value } ) + } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> +
); }; From 55ff08b4900ce56e9e3a12cb0567fedf7090be7d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 22 Jan 2021 11:34:36 +1300 Subject: [PATCH 62/86] Revert "Remove external div wrapper by moving InnerBlocks to a fragment" --- packages/block-library/src/gallery/gallery.js | 41 +++--- packages/block-library/src/gallery/save.js | 24 ++-- packages/block-library/src/gallery/style.scss | 123 +++++++++--------- 3 files changed, 97 insertions(+), 91 deletions(-) diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 85c0650b2dc65..4586e015351ba 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -13,7 +13,7 @@ import { import { VisuallyHidden } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; -import { useRef, useEffect, Fragment } from '@wordpress/element'; +import { useRef, useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -57,7 +57,7 @@ export const Gallery = ( props ) => { }, [ isSelected ] ); return ( -
{ 'is-cropped': imageCrop, } ) } > - -
- { mediaPlaceholder } - - setAttributes( { caption: value } ) - } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> -
-
+
+ + { mediaPlaceholder } + setAttributes( { caption: value } ) } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> + ); }; diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index aa870938cdb1c..06964ec5389f1 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -15,20 +15,22 @@ export default function save( { attributes } ) { imageCrop, caption, } = attributes; - const className = `blocks-gallery-grid has-nested-images columns-${ columns } ${ + const className = `has-nested-images columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return ( -
- - { ! RichText.isEmpty( caption ) && ( - - ) } -
+
+
+ + { ! RichText.isEmpty( caption ) && ( + + ) } +
+
); } diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 32d1eee2e0546..b0df78b3eb0a6 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -3,76 +3,74 @@ // Styles for current version of gallery block. .wp-block-gallery.has-nested-images { - display: flex; - flex-wrap: wrap; - // Need bogus :not(#individual-image) to override long :not() - // specificity chain on default image block on front end. - figure.wp-block-image:not(#individual-image) { - // Add space between thumbnails, and unset right most thumbnails later. - margin: 0 $grid-unit-20 $grid-unit-20 0; - - &:last-child { - margin-right: 0; - } - - width: calc(50% - #{$grid-unit-20}); - - &:nth-of-type(even) { - margin-right: 0; - } - } + display: block; - figure.wp-block-image { + figure.blocks-gallery-grid { display: flex; - flex-grow: 1; - justify-content: center; - position: relative; - - // IE11 doesn't like the "flex-direction: column;" here. - @supports ( position: sticky ) { - flex-direction: column; + flex-wrap: wrap; + // Need bogus :not(#individual-image) to override long :not() + // specificity chain on default image block on front end. + figure.wp-block-image:not(#individual-image) { + // Add space between thumbnails, and unset right most thumbnails later. + margin: 0 $grid-unit-20 $grid-unit-20 0; + + &:last-child { + margin-right: 0; + } } - > div, - > a { - margin: 0; + figure.wp-block-image { + display: flex; + flex-grow: 1; + justify-content: center; + position: relative; - // Avoid applying flex styles to IE11. + // IE11 doesn't like the "flex-direction: column;" here. @supports ( position: sticky ) { flex-direction: column; - flex-grow: 1; } - } - img { - display: block; - height: auto; - max-width: 100%; - width: 100%; + > div, + > a { + margin: 0; - // IE doesn't handle cropping, so we need an explicit width here. - // IE11 doesn't read rules inside this query. They are applied only to modern browsers. - @supports ( position: sticky ) { - width: auto; + // Avoid applying flex styles to IE11. + @supports ( position: sticky ) { + flex-direction: column; + flex-grow: 1; + } } - } - - figcaption { - background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); - bottom: 0; - color: $white; - font-size: $default-font-size; - left: 0; - margin-bottom: 0; - max-height: 100%; - overflow: auto; - padding: 40px 10px 9px; - position: absolute; - text-align: center; - width: 100%; img { - display: inline; + display: block; + height: auto; + max-width: 100%; + width: 100%; + + // IE doesn't handle cropping, so we need an explicit width here. + // IE11 doesn't read rules inside this query. They are applied only to modern browsers. + @supports ( position: sticky ) { + width: auto; + } + } + + figcaption { + background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); + bottom: 0; + color: $white; + font-size: $default-font-size; + left: 0; + margin-bottom: 0; + max-height: 100%; + overflow: auto; + padding: 40px 10px 9px; + position: absolute; + text-align: center; + width: 100%; + + img { + display: inline; + } } } } @@ -82,7 +80,7 @@ } // Cropped Images. - &.is-cropped figure.wp-block-image:not(#individual-image) { + &.is-cropped figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image) { > div:not(.components-drop-zone), > a { display: block; // Thanks to IE11 not supporting object-fit fall back to display: block. @@ -106,6 +104,15 @@ } } + // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. + & figure.wp-block-image:not(#individual-image) { + width: calc(50% - #{$grid-unit-20}); + + &:nth-of-type(even) { + margin-right: 0; + } + } + &.columns-1 figure.wp-block-image:not(#individual-image) { margin-right: 0; width: 100%; From d312f7339d82b787ad95984b4d1b97e7f72d6f71 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Jan 2021 14:03:00 +1300 Subject: [PATCH 63/86] another update to image wrapper --- .../block-library/src/gallery/editor.scss | 4 ++ packages/block-library/src/gallery/gallery.js | 37 ++++++++++--------- packages/block-library/src/gallery/style.scss | 4 +- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 2b219be895503..9fb6095a9f651 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -7,6 +7,10 @@ display: none; pointer-events: none; } + > .components-form-file-upload, + > .blocks-gallery-caption { + flex: 0 0 100%; + } } // @todo: this deserves a refactor, by being moved to the toolbar. diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 4586e015351ba..36f5d16fd0c7d 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -38,7 +38,7 @@ export const Gallery = ( props ) => { imageCrop, } = attributes; const galleryRef = useRef(); - const innerBlocksProps = useInnerBlocksProps( + const { children, ...innerBlocksProps } = useInnerBlocksProps( { className: 'blocks-gallery-grid', }, @@ -66,22 +66,25 @@ export const Gallery = ( props ) => { 'is-cropped': imageCrop, } ) } > -
- - { mediaPlaceholder } - setAttributes( { caption: value } ) } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> +
+ { children } + { mediaPlaceholder } + + setAttributes( { caption: value } ) + } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> +
); }; diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index b0df78b3eb0a6..3b575edcac747 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -14,7 +14,7 @@ // Add space between thumbnails, and unset right most thumbnails later. margin: 0 $grid-unit-20 $grid-unit-20 0; - &:last-child { + &:last-of-type { margin-right: 0; } } @@ -129,7 +129,7 @@ // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{$column-count} figure.wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { + &.columns-#{$column-count} figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } From c465a0d38288be9c78421213db7fac12d2391737 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 18 Dec 2020 09:37:02 +1300 Subject: [PATCH 64/86] put media uploader outside figure so structure matches front end --- packages/block-library/src/gallery/editor.scss | 1 - packages/block-library/src/gallery/gallery.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 9fb6095a9f651..02b35c2317073 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -7,7 +7,6 @@ display: none; pointer-events: none; } - > .components-form-file-upload, > .blocks-gallery-caption { flex: 0 0 100%; } diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index 36f5d16fd0c7d..ceefe62801212 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -68,7 +68,6 @@ export const Gallery = ( props ) => { >
{ children } - { mediaPlaceholder } { } />
+ { mediaPlaceholder } ); }; From 31dcd5941df5ec361b47ab6ef1b0f4252e0427f6 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 18 Dec 2020 09:45:05 +1300 Subject: [PATCH 65/86] Replace div with View for the sake of native code --- packages/block-library/src/gallery/gallery.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index ceefe62801212..a0d1cb5e40714 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -14,6 +14,7 @@ import { VisuallyHidden } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; import { useRef, useEffect } from '@wordpress/element'; +import { View } from '@wordpress/primitives'; /** * Internal dependencies @@ -57,7 +58,7 @@ export const Gallery = ( props ) => { }, [ isSelected ] ); return ( -
{ />
{ mediaPlaceholder } - + ); }; From fa5f89bf11d072b3ce29cd2abad6f75b1d9a5e07 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 26 Jan 2021 15:17:26 +1300 Subject: [PATCH 66/86] Move setting of attributes to the child images --- packages/block-library/src/image/block.json | 8 +--- packages/block-library/src/image/edit.js | 12 +++--- packages/block-library/src/image/image.js | 13 +++++-- .../src/image/use-parent-attributes.js | 37 ++++++++----------- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 3053673f9dc3a..d2014d8a3c091 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -2,13 +2,7 @@ "apiVersion": 2, "name": "core/image", "category": "media", - "usesContext": [ - "allowResize", - "isGrouped", - "linkTo", - "linkTarget", - "sizeSlug" - ], + "usesContext": [ "allowResize", "linkTo", "linkTarget", "sizeSlug" ], "attributes": { "align": { "type": "string" diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 6021c6e147069..ffc9e92e4c23a 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; -import { get, omit, pick } from 'lodash'; +import { get, omit, pick, isEmpty } from 'lodash'; /** * WordPress dependencies @@ -94,7 +94,6 @@ export function ImageEdit( { sizeSlug, inhertedAttributes, } = attributes; - const { isGrouped } = context; const [ tempUrl, setTempUrl ] = useState(); const altRef = useRef(); useEffect( () => { @@ -161,10 +160,9 @@ export function ImageEdit( { } // Check if default link setting, or the one inherited from parent block should be used. - let linkDestination = - isGrouped && context.linkTo - ? context.linkTo - : attributes.linkDestination; + let linkDestination = context.linkTo + ? context.linkTo + : attributes.linkDestination; if ( ! linkDestination ) { // Use the WordPress option to determine the proper default. @@ -203,7 +201,7 @@ export function ImageEdit( { } mediaAttributes.href = href; - if ( isGrouped ) { + if ( ! isEmpty( context ) ) { const parentSizeAttributes = getImageSizeAttributes( media, context.sizeSlug diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index d000ea8c5bf2e..1ed72f3d23cac 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -90,7 +90,11 @@ export default function Image( { } ) { const captionRef = useRef(); const prevUrl = usePrevious( url ); - const { allowResize = true, isGrouped = false } = context; + const { + allowResize = true, + linkTo: parentLinkDestination, + sizeSlug: parentSizeSlug, + } = context; const { block, currentId, image, multiImageSelection } = useSelect( ( select ) => { const { getMedia } = select( 'core' ); @@ -105,7 +109,10 @@ export default function Image( { block: getSelectedBlock(), currentId: getSelectedBlockClientId(), image: - id && ( isSelected || isGrouped ) ? getMedia( id ) : null, + id && + ( isSelected || parentLinkDestination || parentSizeSlug ) + ? getMedia( id ) + : null, multiImageSelection: multiSelectedClientIds.length && multiSelectedClientIds.every( @@ -114,7 +121,7 @@ export default function Image( { ), }; }, - [ id, isSelected, isGrouped ] + [ id, isSelected, parentLinkDestination ] ); const { imageEditing, imageSizes, maxWidth, mediaUpload } = useSelect( ( select ) => { diff --git a/packages/block-library/src/image/use-parent-attributes.js b/packages/block-library/src/image/use-parent-attributes.js index c837ae3b76e9f..f17d4edba2421 100644 --- a/packages/block-library/src/image/use-parent-attributes.js +++ b/packages/block-library/src/image/use-parent-attributes.js @@ -24,50 +24,43 @@ export default function useParentAttributes( setAttributes ) { const { - isGrouped, linkTo: parentLinkDestination, linkTarget: parentLinkTarget, sizeSlug: parentSizeSlug, } = context; useEffect( () => { - if ( ! isGrouped ) { + if ( ! inheritedAttributes.linkDestination ) { return; } - if ( inheritedAttributes.linkDestination && image ) { + if ( image ) { const href = getUrl( image, parentLinkDestination ); setAttributes( { href, linkDestination: parentLinkDestination, } ); } - }, [ image, parentLinkDestination, isGrouped ] ); + }, [ image, parentLinkDestination ] ); useEffect( () => { - if ( ! isGrouped ) { + if ( ! inheritedAttributes.linkTarget ) { return; } - if ( inheritedAttributes.linkTarget ) { - setAttributes( { - linkTarget: parentLinkTarget, - } ); - } - }, [ parentLinkTarget, isGrouped ] ); + + setAttributes( { + linkTarget: parentLinkTarget, + } ); + }, [ parentLinkTarget ] ); useEffect( () => { - if ( ! isGrouped ) { + if ( ! inheritedAttributes.sizeSlug ) { return; } - if ( inheritedAttributes.sizeSlug ) { - const sizeAttributes = getImageSizeAttributes( - image, - parentSizeSlug - ); + const sizeAttributes = getImageSizeAttributes( image, parentSizeSlug ); - setAttributes( { - ...sizeAttributes, - } ); - } - }, [ parentSizeSlug, isGrouped ] ); + setAttributes( { + ...sizeAttributes, + } ); + }, [ parentSizeSlug ] ); } From 94b9ca290268101d1e0db52b170714b6216c08ac Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 23 Dec 2020 09:05:22 +1300 Subject: [PATCH 67/86] Gallery Block Refactor: Account for null image ids in gallery migrations (#27855) Co-authored-by: Glen Davies --- .../block-library/src/gallery/deprecated.js | 65 +++++++------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/packages/block-library/src/gallery/deprecated.js b/packages/block-library/src/gallery/deprecated.js index db306e258eb9b..41753817dc783 100644 --- a/packages/block-library/src/gallery/deprecated.js +++ b/packages/block-library/src/gallery/deprecated.js @@ -80,6 +80,26 @@ export function getHrefAndDestination( image, destination ) { return {}; } +/** + * Gets an Image block from gallery image data + * + * Used to migrate Galleries to nested Image InnerBlocks. + * + * @param {Object} image Image properties. + * @param {string} sizeSlug Gallery sizeSlug attribute. + * @param {string} linkTo Gallery linkTo attribute. + * @return {Object} Image block. + */ +export function getImageBlock( image, sizeSlug, linkTo ) { + return createBlock( 'core/image', { + ...( image.id && { id: parseInt( image.id ) } ), + url: image.url, + alt: image.alt, + caption: image.caption, + sizeSlug, + ...getHrefAndDestination( image, linkTo ), + } ); +} const v1 = { attributes: { images: { @@ -173,14 +193,7 @@ const v1 = { }, migrate( { images, imageCrop, linkTo, sizeSlug, columns, caption } ) { const imageBlocks = images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); + return getImageBlock( image, sizeSlug, linkTo ); } ); return [ { @@ -456,14 +469,7 @@ const v3 = { }, migrate( { images, imageCrop, linkTo, sizeSlug, columns, caption } ) { const imageBlocks = images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); + return getImageBlock( image, sizeSlug, linkTo ); } ); return [ @@ -552,14 +558,7 @@ const v4 = { }, migrate( { images, imageCrop, linkTo, sizeSlug, columns, caption } ) { const imageBlocks = images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); + return getImageBlock( image, sizeSlug, linkTo ); } ); return [ @@ -743,14 +742,7 @@ const v5 = { linkTo = 'none'; } const imageBlocks = attributes.images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug: attributes.sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); + return getImageBlock( image, attributes.sizeSlug, linkTo ); } ); return [ { @@ -1004,14 +996,7 @@ const v6 = { linkTo = 'media'; } const imageBlocks = images.map( ( image ) => { - return createBlock( 'core/image', { - id: parseInt( image.id ), - url: image.url, - alt: image.alt, - caption: image.caption, - sizeSlug, - ...getHrefAndDestination( image, linkTo ), - } ); + return getImageBlock( image, sizeSlug, linkTo ); } ); return [ { From 71129599b17b7e344225479c19be96561b844b60 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 24 Dec 2020 15:28:03 +1300 Subject: [PATCH 68/86] Remove the gradient and put caption under image if is-rounded style applied (#27869) * Add alignment fixes for non cropped images Co-authored-by: Glen Davies --- packages/block-library/src/gallery/style.scss | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 3b575edcac747..2849ea90c954d 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -24,7 +24,8 @@ flex-grow: 1; justify-content: center; position: relative; - + margin-top: auto; + margin-bottom: auto; // IE11 doesn't like the "flex-direction: column;" here. @supports ( position: sticky ) { flex-direction: column; @@ -72,6 +73,28 @@ display: inline; } } + + &.is-style-rounded { + > div, + > a { + // Not supported in IE11. + @supports ( position: sticky ) { + flex: 1 1 auto; + } + } + figcaption { + background: none; + // Not supported in IE11. + @supports ( position: sticky ) { + flex: initial; + background: none; + color: inherit; + margin: 0; + padding: 10px 10px 9px; + position: relative; + } + } + } } } @@ -79,6 +102,23 @@ flex-grow: 1; } + // Non cropped images. + &:not(.is-cropped) { + figure.blocks-gallery-grid { + figure.wp-block-image:not(#individual-image) { + margin-top: auto; + margin-bottom: auto; + img { + margin-bottom: $grid-unit-20; + } + + figcaption { + bottom: $grid-unit-20; + } + } + } + } + // Cropped Images. &.is-cropped figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image) { > div:not(.components-drop-zone), From 11ce2f241e4266c1721823fa8c983c52ba35222c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 22 Jan 2021 11:37:01 +1300 Subject: [PATCH 69/86] Remove outer div wrapper --- .../block-library/src/gallery/editor.scss | 28 +-- packages/block-library/src/gallery/gallery.js | 70 +++---- packages/block-library/src/gallery/save.js | 24 ++- packages/block-library/src/gallery/style.scss | 185 +++++++++--------- 4 files changed, 145 insertions(+), 162 deletions(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 02b35c2317073..aa3ef5cc9f2a2 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -1,17 +1,22 @@ -.wp-block-gallery { +figure.wp-block-gallery { // Override the default list style type _only in the editor_ // to avoid :not() selector specificity issues. // See https://github.com/WordPress/gutenberg/pull/10358 - figure { - .components-drop-zone { - display: none; - pointer-events: none; - } - > .blocks-gallery-caption { - flex: 0 0 100%; - } + + display: block; + margin: 0; + + .components-drop-zone { + display: none; + pointer-events: none; + } + > .blocks-gallery-caption { + flex: 0 0 100%; } + .components-form-file-upload { + flex-basis: 100%; + } // @todo: this deserves a refactor, by being moved to the toolbar. .block-editor-media-placeholder.is-appender { .components-placeholder__label { @@ -23,11 +28,6 @@ } } -figure.wp-block-gallery { - display: block; - margin: 0; -} - // Necessary to to override default editor ul styles. .blocks-gallery-grid.blocks-gallery-grid { padding-left: 0; diff --git a/packages/block-library/src/gallery/gallery.js b/packages/block-library/src/gallery/gallery.js index a0d1cb5e40714..1461cbe8cbfaf 100644 --- a/packages/block-library/src/gallery/gallery.js +++ b/packages/block-library/src/gallery/gallery.js @@ -14,7 +14,6 @@ import { VisuallyHidden } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; import { useRef, useEffect } from '@wordpress/element'; -import { View } from '@wordpress/primitives'; /** * Internal dependencies @@ -39,17 +38,12 @@ export const Gallery = ( props ) => { imageCrop, } = attributes; const galleryRef = useRef(); - const { children, ...innerBlocksProps } = useInnerBlocksProps( - { - className: 'blocks-gallery-grid', - }, - { - allowedBlocks: [ 'core/image' ], - orientation: 'horizontal', - renderAppender: false, - __experimentalLayout: { type: 'default', alignments: [] }, - } - ); + const { children, ...innerBlocksProps } = useInnerBlocksProps( blockProps, { + allowedBlocks: [ 'core/image' ], + orientation: 'horizontal', + renderAppender: false, + __experimentalLayout: { type: 'default', alignments: [] }, + } ); useEffect( () => { if ( galleryRef.current && isSelected ) { @@ -58,35 +52,35 @@ export const Gallery = ( props ) => { }, [ isSelected ] ); return ( - -
- { children } - - setAttributes( { caption: value } ) - } - inlineToolbar - __unstableOnSplitAtEnd={ () => - insertBlocksAfter( createBlock( 'core/paragraph' ) ) - } - /> -
+ { children } + setAttributes( { caption: value } ) } + inlineToolbar + __unstableOnSplitAtEnd={ () => + insertBlocksAfter( createBlock( 'core/paragraph' ) ) + } + /> { mediaPlaceholder } -
+
); }; diff --git a/packages/block-library/src/gallery/save.js b/packages/block-library/src/gallery/save.js index 06964ec5389f1..aa870938cdb1c 100644 --- a/packages/block-library/src/gallery/save.js +++ b/packages/block-library/src/gallery/save.js @@ -15,22 +15,20 @@ export default function save( { attributes } ) { imageCrop, caption, } = attributes; - const className = `has-nested-images columns-${ columns } ${ + const className = `blocks-gallery-grid has-nested-images columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }`; return ( -
-
- - { ! RichText.isEmpty( caption ) && ( - - ) } -
-
+
+ + { ! RichText.isEmpty( caption ) && ( + + ) } +
); } diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index 2849ea90c954d..d4f06a34a2e4d 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -2,97 +2,99 @@ @import "./deprecated.scss"; // Styles for current version of gallery block. -.wp-block-gallery.has-nested-images { - display: block; +.wp-block-gallery.blocks-gallery-grid.has-nested-images { + display: flex; + flex-wrap: wrap; + // Need bogus :not(#individual-image) to override long :not() + // specificity chain on default image block on front end. + figure.wp-block-image:not(#individual-image) { + // Add space between thumbnails, and unset right most thumbnails later. + margin: 0 $grid-unit-20 $grid-unit-20 0; + + &:last-of-type:not(#individual-image) { + margin-right: 0; + } - figure.blocks-gallery-grid { - display: flex; - flex-wrap: wrap; - // Need bogus :not(#individual-image) to override long :not() - // specificity chain on default image block on front end. - figure.wp-block-image:not(#individual-image) { - // Add space between thumbnails, and unset right most thumbnails later. - margin: 0 $grid-unit-20 $grid-unit-20 0; + width: calc(50% - #{$grid-unit-20}); - &:last-of-type { - margin-right: 0; - } + &:nth-of-type(even) { + margin-right: 0; } + } - figure.wp-block-image { - display: flex; - flex-grow: 1; - justify-content: center; - position: relative; - margin-top: auto; - margin-bottom: auto; - // IE11 doesn't like the "flex-direction: column;" here. + figure.wp-block-image { + display: flex; + flex-grow: 1; + justify-content: center; + position: relative; + margin-top: auto; + margin-bottom: auto; + // IE11 doesn't like the "flex-direction: column;" here. + @supports ( position: sticky ) { + flex-direction: column; + } + + > div, + > a { + margin: 0; + + // Avoid applying flex styles to IE11. @supports ( position: sticky ) { flex-direction: column; + flex-grow: 1; } + } - > div, - > a { - margin: 0; + img { + display: block; + height: auto; + max-width: 100%; + width: 100%; - // Avoid applying flex styles to IE11. - @supports ( position: sticky ) { - flex-direction: column; - flex-grow: 1; - } + // IE doesn't handle cropping, so we need an explicit width here. + // IE11 doesn't read rules inside this query. They are applied only to modern browsers. + @supports ( position: sticky ) { + width: auto; } + } + + figcaption { + background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); + bottom: 0; + color: $white; + font-size: $default-font-size; + left: 0; + margin-bottom: 0; + max-height: 100%; + overflow: auto; + padding: 40px 10px 9px; + position: absolute; + text-align: center; + width: 100%; img { - display: block; - height: auto; - max-width: 100%; - width: 100%; + display: inline; + } + } - // IE doesn't handle cropping, so we need an explicit width here. - // IE11 doesn't read rules inside this query. They are applied only to modern browsers. + &.is-style-rounded { + > div, + > a { + // Not supported in IE11. @supports ( position: sticky ) { - width: auto; + flex: 1 1 auto; } } - figcaption { - background: linear-gradient(0deg, rgba($color: $black, $alpha: 0.7) 0, rgba($color: $black, $alpha: 0.3) 70%, transparent); - bottom: 0; - color: $white; - font-size: $default-font-size; - left: 0; - margin-bottom: 0; - max-height: 100%; - overflow: auto; - padding: 40px 10px 9px; - position: absolute; - text-align: center; - width: 100%; - - img { - display: inline; - } - } - - &.is-style-rounded { - > div, - > a { - // Not supported in IE11. - @supports ( position: sticky ) { - flex: 1 1 auto; - } - } - figcaption { + background: none; + // Not supported in IE11. + @supports ( position: sticky ) { + flex: initial; background: none; - // Not supported in IE11. - @supports ( position: sticky ) { - flex: initial; - background: none; - color: inherit; - margin: 0; - padding: 10px 10px 9px; - position: relative; - } + color: inherit; + margin: 0; + padding: 10px 10px 9px; + position: relative; } } } @@ -100,27 +102,27 @@ figcaption { flex-grow: 1; + flex-basis: 100%; } // Non cropped images. &:not(.is-cropped) { - figure.blocks-gallery-grid { - figure.wp-block-image:not(#individual-image) { - margin-top: auto; - margin-bottom: auto; - img { - margin-bottom: $grid-unit-20; - } - figcaption { - bottom: $grid-unit-20; - } + figure.wp-block-image:not(#individual-image) { + margin-top: auto; + margin-bottom: auto; + img { + margin-bottom: $grid-unit-20; + } + + figcaption { + bottom: $grid-unit-20; } } } // Cropped Images. - &.is-cropped figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image) { + &.is-cropped figure.wp-block-image:not(#individual-image) { > div:not(.components-drop-zone), > a { display: block; // Thanks to IE11 not supporting object-fit fall back to display: block. @@ -144,15 +146,6 @@ } } - // On mobile and responsive viewports, we allow only 1 or 2 columns at the most. - & figure.wp-block-image:not(#individual-image) { - width: calc(50% - #{$grid-unit-20}); - - &:nth-of-type(even) { - margin-right: 0; - } - } - &.columns-1 figure.wp-block-image:not(#individual-image) { margin-right: 0; width: 100%; @@ -169,7 +162,7 @@ // Unset the right margin on every rightmost gallery item to ensure center balance. @for $column-count from 1 through 8 { - &.columns-#{$column-count} figure.blocks-gallery-grid figure.wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { + &.columns-#{$column-count} figure.wp-block-image:not(#individual-image):nth-of-type( #{ $column-count }n ) { margin-right: 0; } } @@ -184,8 +177,6 @@ // If the gallery is centered, center the content inside as well. &.aligncenter { - figure.wp-block-image { - justify-content: center; - } + justify-content: center; } } From a539edd78af23d0a0455cb5750806d4512aef69d Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 14 Jan 2021 16:52:19 +1000 Subject: [PATCH 70/86] Keep image margins while dragging sibling --- packages/block-library/src/gallery/style.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/block-library/src/gallery/style.scss b/packages/block-library/src/gallery/style.scss index d4f06a34a2e4d..dcbd90b2086da 100644 --- a/packages/block-library/src/gallery/style.scss +++ b/packages/block-library/src/gallery/style.scss @@ -158,6 +158,11 @@ margin-right: $grid-unit-20; width: calc(#{100% / $i} - #{$grid-unit-20 * ( $i - 1 ) / $i}); } + + // Prevent collapsing margin while sibling is being dragged. + &.columns-#{$i} figure.wp-block-image:not(#individual-image).is-dragging ~ figure.wp-block-image:not(#individual-image) { + margin-right: $grid-unit-20; + } } // Unset the right margin on every rightmost gallery item to ensure center balance. From 34aa703e6ac708b8a033cb7b1f711f94f2a7ed52 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 18 Jan 2021 14:12:21 +1300 Subject: [PATCH 71/86] Fix e2e test expected markup to match new structure --- packages/e2e-tests/specs/editor/blocks/gallery.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/gallery.test.js b/packages/e2e-tests/specs/editor/blocks/gallery.test.js index f383089b65740..12148aa8bf9b8 100644 --- a/packages/e2e-tests/specs/editor/blocks/gallery.test.js +++ b/packages/e2e-tests/specs/editor/blocks/gallery.test.js @@ -47,7 +47,7 @@ describe( 'Gallery', () => { const filename = await upload( '.wp-block-gallery input[type="file"]' ); const regex = new RegExp( - `\\s*\n", "innerContent": [ - "\n\n" + "\n\n\t", + null, + "\n\n\t", + null, + "\n\n" ] }, { diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__columns.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__columns.serialized.html index 022a6a9cb7396..8ab8ac176187f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__columns.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__columns.serialized.html @@ -1,3 +1,9 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.json b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.json index 41b1ca556bf5a..1fd2981834b5e 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.json +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.json @@ -4,22 +4,47 @@ "name": "core/gallery", "isValid": true, "attributes": { - "images": [ - { - "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", - "alt": "title" - }, - { - "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", - "alt": "title" - } - ], "columns": 2, "imageCrop": true, "linkTo": "none", - "align": "wide" + "imageCount": 2, + "allowResize": false, + "isGrouped": true }, - "innerBlocks": [], + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/image", + "isValid": true, + "attributes": { + "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", + "alt": "title", + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + }, + { + "clientId": "_clientId_1", + "name": "core/image", + "isValid": true, + "attributes": { + "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", + "alt": "title", + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + } + ], "originalContent": "" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.serialized.html index dd51c3ac37cac..0fafc2d079009 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-1.serialized.html @@ -1,3 +1,9 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.json b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.json index 84c8db20765a2..8dc4d57e24657 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.json +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.json @@ -4,27 +4,51 @@ "name": "core/gallery", "isValid": true, "attributes": { - "images": [ - { + "columns": 2, + "imageCrop": true, + "linkTo": "none", + "imageCount": 2, + "allowResize": false, + "isGrouped": true + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/image", + "isValid": true, + "attributes": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", "alt": "title", - "id": "1", - "caption": [] + "caption": [], + "id": 1, + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_1", + "name": "core/image", + "isValid": true, + "attributes": { "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", "alt": "title", - "id": "2", - "caption": [] - } - ], - "ids": [], - "columns": 2, - "imageCrop": true, - "linkTo": "none", - "align": "wide" - }, - "innerBlocks": [], + "caption": [], + "id": 2, + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + } + ], "originalContent": "" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.serialized.html index bd177026c8c5b..e4fd676aae739 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-2.serialized.html @@ -1,3 +1,9 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.json b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.json index a0325e960ab08..a8857fbb1b93f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.json +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.json @@ -4,27 +4,48 @@ "name": "core/gallery", "isValid": true, "attributes": { - "images": [ - { + "imageCrop": true, + "linkTo": "none", + "imageCount": 2, + "allowResize": false, + "isGrouped": true + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/image", + "isValid": true, + "attributes": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", "alt": "title", - "caption": [] + "caption": [], + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_1", + "name": "core/image", + "isValid": true, + "attributes": { "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", "alt": "title", - "caption": [] - } - ], - "ids": [ - null, - null - ], - "imageCrop": true, - "linkTo": "none", - "align": "wide" - }, - "innerBlocks": [], + "caption": [], + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + } + ], "originalContent": "" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.serialized.html index 0fc203739e6db..15934b1a87f2c 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-3.serialized.html @@ -1,3 +1,9 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.json b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.json index f74bed0428cb8..8a71f563250ce 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.json +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.json @@ -4,37 +4,69 @@ "name": "core/gallery", "isValid": true, "attributes": { - "images": [ - { + "caption": "", + "imageCrop": true, + "linkTo": "none", + "imageCount": 3, + "allowResize": false, + "isGrouped": true + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/image", + "isValid": true, + "attributes": { "url": "https://sergioestevaofolio.files.wordpress.com/2016/09/cropped-img_9054-1.jpg?w=190", "alt": "", - "id": "1421", - "caption": "" + "caption": "", + "id": 1421, + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_1", + "name": "core/image", + "isValid": true, + "attributes": { "url": "https://sergioestevaofolio.files.wordpress.com/2017/09/cropped-l1001498-1.jpg?w=580", "alt": "", - "id": "1440", - "caption": "" + "caption": "", + "id": 1440, + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_2", + "name": "core/image", + "isValid": true, + "attributes": { "url": "https://sergioestevaofolio.files.wordpress.com/2017/05/cropped-l1005945-2-2.jpg?w=580", "alt": "", - "id": "1362", - "caption": "" - } - ], - "ids": [ - 1421, - 1440, - 1362 - ], - "caption": "", - "imageCrop": true, - "linkTo": "none", - "align": "wide" - }, - "innerBlocks": [], + "caption": "", + "id": 1362, + "linkDestination": "none", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + } + ], "originalContent": "" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.serialized.html index e9bf8294c2f7e..9d7ba1cb1a7d7 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-4.serialized.html @@ -1,3 +1,13 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.json b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.json index 8cbe9760d13ba..5efc04f39036f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.json +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.json @@ -4,43 +4,76 @@ "name": "core/gallery", "isValid": true, "attributes": { - "images": [ - { + "caption": "", + "imageCrop": true, + "linkTo": "media", + "sizeSlug": "large", + "imageCount": 3, + "allowResize": false, + "isGrouped": true + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/image", + "isValid": true, + "attributes": { "url": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-1-682x1024.jpg", - "fullUrl": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-1-scaled.jpg", - "link": "http://wptest.local/classic/test-image-3/", "alt": "", - "id": "705", - "caption": "" + "caption": "", + "href": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-1-682x1024.jpg", + "id": 705, + "sizeSlug": "large", + "linkDestination": "media", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_1", + "name": "core/image", + "isValid": true, + "attributes": { "url": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-1024x682.jpg", - "fullUrl": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-scaled.jpg", - "link": "http://wptest.local/test-image-2/", "alt": "", - "id": "704", - "caption": "" + "caption": "", + "href": "http://wptest.local/wp-content/uploads/2020/09/test-image-edited-1024x682.jpg", + "id": 704, + "sizeSlug": "large", + "linkDestination": "media", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, - { + "innerBlocks": [] + }, + { + "clientId": "_clientId_2", + "name": "core/image", + "isValid": true, + "attributes": { "url": "http://wptest.local/wp-content/uploads/2020/04/test-image-1024x683.jpg", - "fullUrl": "http://wptest.local/wp-content/uploads/2020/04/test-image-scaled.jpg", - "link": "http://wptest.local/test-image/", "alt": "", - "id": "703", - "caption": "" - } - ], - "ids": [ - 705, - 704, - 703 - ], - "caption": "", - "imageCrop": true, - "linkTo": "file", - "sizeSlug": "large" - }, - "innerBlocks": [], + "caption": "", + "href": "http://wptest.local/wp-content/uploads/2020/04/test-image-1024x683.jpg", + "id": 703, + "sizeSlug": "large", + "linkDestination": "media", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } + }, + "innerBlocks": [] + } + ], "originalContent": "" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.serialized.html b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.serialized.html index f3afe00b34a31..d1294eccc0723 100644 --- a/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__gallery__deprecated-5.serialized.html @@ -1,3 +1,13 @@ - - + + diff --git a/packages/e2e-tests/fixtures/blocks/core__image.json b/packages/e2e-tests/fixtures/blocks/core__image.json index 1650156649dad..41a9bfe725a3a 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image.json +++ b/packages/e2e-tests/fixtures/blocks/core__image.json @@ -6,7 +6,12 @@ "attributes": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", "alt": "", - "caption": "" + "caption": "", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__attachment-link.json b/packages/e2e-tests/fixtures/blocks/core__image__attachment-link.json index 9a82085c205ee..a0a8000d9d4ef 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__attachment-link.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__attachment-link.json @@ -8,7 +8,12 @@ "alt": "", "caption": "", "href": "http://localhost:8888/?attachment_id=7", - "linkDestination": "attachment" + "linkDestination": "attachment", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__center-caption.json b/packages/e2e-tests/fixtures/blocks/core__image__center-caption.json index 174eba0a63e36..ef636205cc276 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__center-caption.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__center-caption.json @@ -7,7 +7,12 @@ "align": "center", "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", "alt": "", - "caption": "Give it a try. Press the \"really wide\" button on the image toolbar." + "caption": "Give it a try. Press the \"really wide\" button on the image toolbar.", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
Give it a try. Press the "really wide" button on the image toolbar.
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__custom-link-class.json b/packages/e2e-tests/fixtures/blocks/core__image__custom-link-class.json index 173999d24f169..fda8d466edb08 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__custom-link-class.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__custom-link-class.json @@ -9,7 +9,12 @@ "caption": "", "href": "https://wordpress.org/", "linkClass": "custom-link", - "linkDestination": "custom" + "linkDestination": "custom", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__custom-link-rel.json b/packages/e2e-tests/fixtures/blocks/core__image__custom-link-rel.json index c877e3cc5e4bd..a05702d6b6073 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__custom-link-rel.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__custom-link-rel.json @@ -9,7 +9,12 @@ "caption": "", "href": "https://wordpress.org/", "rel": "external", - "linkDestination": "custom" + "linkDestination": "custom", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__custom-link.json b/packages/e2e-tests/fixtures/blocks/core__image__custom-link.json index 58ac7320330cf..eabe16598d00c 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__custom-link.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__custom-link.json @@ -8,7 +8,12 @@ "alt": "", "caption": "", "href": "https://wordpress.org/", - "linkDestination": "custom" + "linkDestination": "custom", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/packages/e2e-tests/fixtures/blocks/core__image__media-link.json b/packages/e2e-tests/fixtures/blocks/core__image__media-link.json index 18be10b3db12b..6fd8c6b86da55 100644 --- a/packages/e2e-tests/fixtures/blocks/core__image__media-link.json +++ b/packages/e2e-tests/fixtures/blocks/core__image__media-link.json @@ -8,7 +8,12 @@ "alt": "", "caption": "", "href": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==", - "linkDestination": "media" + "linkDestination": "media", + "inheritedAttributes": { + "linkTo": false, + "linkTarget": false, + "sizeSlug": false + } }, "innerBlocks": [], "originalContent": "
\"\"
" diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 2a4ddbf8f5efa..ff3611643d7de 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -57,8 +57,8 @@ exports[`rawHandler should convert HTML post to blocks with minimal content chan

Shortcode

- - + + diff --git a/test/integration/fixtures/shortcode-matching-out.html b/test/integration/fixtures/shortcode-matching-out.html index 30a0e0679656b..2083767483201 100644 --- a/test/integration/fixtures/shortcode-matching-out.html +++ b/test/integration/fixtures/shortcode-matching-out.html @@ -1,7 +1,7 @@ - - + + diff --git a/test/integration/fixtures/wordpress-out.html b/test/integration/fixtures/wordpress-out.html index 159244b27659d..a8dd639b3216b 100644 --- a/test/integration/fixtures/wordpress-out.html +++ b/test/integration/fixtures/wordpress-out.html @@ -18,8 +18,8 @@

More tag

Shortcode

- - + + From 6af96d33362b1683bf9ea9a46a7c5f5293594017 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 26 Jan 2021 16:49:27 +1300 Subject: [PATCH 86/86] Fix broken e2e test --- packages/e2e-tests/specs/editor/blocks/gallery.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/gallery.test.js b/packages/e2e-tests/specs/editor/blocks/gallery.test.js index 12148aa8bf9b8..4b0d0925a0d16 100644 --- a/packages/e2e-tests/specs/editor/blocks/gallery.test.js +++ b/packages/e2e-tests/specs/editor/blocks/gallery.test.js @@ -47,7 +47,7 @@ describe( 'Gallery', () => { const filename = await upload( '.wp-block-gallery input[type="file"]' ); const regex = new RegExp( - `\\s*