diff --git a/packages/block-library/src/table/deprecated.js b/packages/block-library/src/table/deprecated.js index 01c0120d5307e..ed138c4518aa3 100644 --- a/packages/block-library/src/table/deprecated.js +++ b/packages/block-library/src/table/deprecated.js @@ -10,12 +10,10 @@ import { RichText, getColorClassName, useBlockProps, + __experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles, + __experimentalGetColorClassesAndStyles as getColorClassesAndStyles, } from '@wordpress/block-editor'; -const supports = { - align: true, -}; - // As the previous arbitrary colors won't match theme color palettes, the hex // value will be mapped to the style.color.background attribute as if it was // a custom color selection. @@ -26,380 +24,426 @@ const oldColors = { 'subtle-pale-pink': '#fcf0ef', }; -const deprecated = [ - // Deprecation migrating table block to use colors block support feature. - { - attributes: { - hasFixedLayout: { - type: 'boolean', - default: false, - }, - backgroundColor: { - type: 'string', - }, - caption: { - type: 'string', - source: 'html', - selector: 'figcaption', - default: '', - }, - head: { - type: 'array', - default: [], - source: 'query', - selector: 'thead tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, - align: { - type: 'string', - source: 'attribute', - attribute: 'data-align', - }, +// In #41140 support was added to global styles for caption elements which +// added a `wp-element-caption` classname to the embed figcaption element. +const v3 = { + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, + }, + caption: { + type: 'string', + source: 'html', + selector: 'figcaption', + default: '', + }, + head: { + type: 'array', + default: [], + source: 'query', + selector: 'thead tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, - body: { - type: 'array', - default: [], - source: 'query', - selector: 'tbody tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, - align: { - type: 'string', - source: 'attribute', - attribute: 'data-align', - }, + }, + body: { + type: 'array', + default: [], + source: 'query', + selector: 'tbody tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, - foot: { - type: 'array', - default: [], - source: 'query', - selector: 'tfoot tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, - align: { - type: 'string', - source: 'attribute', - attribute: 'data-align', - }, + }, + foot: { + type: 'array', + default: [], + source: 'query', + selector: 'tfoot tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, }, - supports: { - anchor: true, - align: true, - __experimentalSelector: '.wp-block-table > table', + }, + supports: { + anchor: true, + align: true, + color: { + __experimentalSkipSerialization: true, + gradients: true, + __experimentalDefaultControls: { + background: true, + text: true, + }, }, - save: ( { attributes } ) => { - const { - hasFixedLayout, - head, - body, - foot, - backgroundColor, - caption, - } = attributes; - const isEmpty = ! head.length && ! body.length && ! foot.length; - - if ( isEmpty ) { - return null; - } + spacing: { + margin: true, + padding: true, + }, + typography: { + fontSize: true, + lineHeight: true, + __experimentalFontFamily: true, + __experimentalFontStyle: true, + __experimentalFontWeight: true, + __experimentalLetterSpacing: true, + __experimentalTextTransform: true, + __experimentalTextDecoration: true, + __experimentalDefaultControls: { + fontSize: true, + }, + }, + __experimentalBorder: { + __experimentalSkipSerialization: true, + color: true, + style: true, + width: true, + __experimentalDefaultControls: { + color: true, + style: true, + width: true, + }, + }, + __experimentalSelector: '.wp-block-table > table', + }, + save( { attributes } ) { + const { hasFixedLayout, head, body, foot, caption } = attributes; + const isEmpty = ! head.length && ! body.length && ! foot.length; - const backgroundClass = getColorClassName( - 'background-color', - backgroundColor - ); + if ( isEmpty ) { + return null; + } + + const colorProps = getColorClassesAndStyles( attributes ); + const borderProps = getBorderClassesAndStyles( attributes ); - const classes = classnames( backgroundClass, { + const classes = classnames( + colorProps.className, + borderProps.className, + { 'has-fixed-layout': hasFixedLayout, - 'has-background': !! backgroundClass, - } ); - - const hasCaption = ! RichText.isEmpty( caption ); - - const Section = ( { type, rows } ) => { - if ( ! rows.length ) { - return null; - } - - const Tag = `t${ type }`; - - return ( - - { rows.map( ( { cells }, rowIndex ) => ( - - { cells.map( - ( - { content, tag, scope, align }, - cellIndex - ) => { - const cellClasses = classnames( { - [ `has-text-align-${ align }` ]: - align, - } ); - - return ( - - ); - } - ) } - - ) ) } - - ); - }; + } + ); + + const hasCaption = ! RichText.isEmpty( caption ); + + const Section = ( { type, rows } ) => { + if ( ! rows.length ) { + return null; + } + + const Tag = `t${ type }`; return ( -
- -
-
-
-
- { hasCaption && ( - - ) } -
+ + { rows.map( ( { cells }, rowIndex ) => ( + + { cells.map( + ( + { content, tag, scope, align }, + cellIndex + ) => { + const cellClasses = classnames( { + [ `has-text-align-${ align }` ]: align, + } ); + + return ( + + ); + } + ) } + + ) ) } + ); + }; + + return ( +
+ +
+
+
+
+ { hasCaption && ( + + ) } +
+ ); + }, +}; + +// Deprecation migrating table block to use colors block support feature. +const v2 = { + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, }, - isEligible: ( attributes ) => { - return ( - attributes.backgroundColor && - attributes.backgroundColor in oldColors && - ! attributes.style - ); + backgroundColor: { + type: 'string', }, - - // This version is the first to introduce the style attribute to the - // table block. As a result, we'll explicitly override that. - migrate: ( attributes ) => { - return { - ...attributes, - backgroundColor: undefined, - style: { - color: { - background: oldColors[ attributes.backgroundColor ], - }, - }, - }; + caption: { + type: 'string', + source: 'html', + selector: 'figcaption', + default: '', }, - }, - { - attributes: { - hasFixedLayout: { - type: 'boolean', - default: false, - }, - backgroundColor: { - type: 'string', - }, - head: { - type: 'array', - default: [], - source: 'query', - selector: 'thead tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, + head: { + type: 'array', + default: [], + source: 'query', + selector: 'thead tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, - body: { - type: 'array', - default: [], - source: 'query', - selector: 'tbody tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, + }, + body: { + type: 'array', + default: [], + source: 'query', + selector: 'tbody tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, - foot: { - type: 'array', - default: [], - source: 'query', - selector: 'tfoot tr', - query: { - cells: { - type: 'array', - default: [], - source: 'query', - selector: 'td,th', - query: { - content: { - type: 'string', - source: 'html', - }, - tag: { - type: 'string', - default: 'td', - source: 'tag', - }, - scope: { - type: 'string', - source: 'attribute', - attribute: 'scope', - }, + }, + foot: { + type: 'array', + default: [], + source: 'query', + selector: 'tfoot tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + align: { + type: 'string', + source: 'attribute', + attribute: 'data-align', }, }, }, }, }, - supports, - save( { attributes } ) { - const { hasFixedLayout, head, body, foot, backgroundColor } = - attributes; - const isEmpty = ! head.length && ! body.length && ! foot.length; + }, + supports: { + anchor: true, + align: true, + __experimentalSelector: '.wp-block-table > table', + }, + save: ( { attributes } ) => { + const { hasFixedLayout, head, body, foot, backgroundColor, caption } = + attributes; + const isEmpty = ! head.length && ! body.length && ! foot.length; + + if ( isEmpty ) { + return null; + } - if ( isEmpty ) { + const backgroundClass = getColorClassName( + 'background-color', + backgroundColor + ); + + const classes = classnames( backgroundClass, { + 'has-fixed-layout': hasFixedLayout, + 'has-background': !! backgroundClass, + } ); + + const hasCaption = ! RichText.isEmpty( caption ); + + const Section = ( { type, rows } ) => { + if ( ! rows.length ) { return null; } - const backgroundClass = getColorClassName( - 'background-color', - backgroundColor - ); + const Tag = `t${ type }`; - const classes = classnames( backgroundClass, { - 'has-fixed-layout': hasFixedLayout, - 'has-background': !! backgroundClass, - } ); - - const Section = ( { type, rows } ) => { - if ( ! rows.length ) { - return null; - } - - const Tag = `t${ type }`; - - return ( - - { rows.map( ( { cells }, rowIndex ) => ( - - { cells.map( - ( { content, tag, scope }, cellIndex ) => ( + return ( + + { rows.map( ( { cells }, rowIndex ) => ( + + { cells.map( + ( + { content, tag, scope, align }, + cellIndex + ) => { + const cellClasses = classnames( { + [ `has-text-align-${ align }` ]: align, + } ); + + return ( - ) - ) } - - ) ) } - - ); - }; + ); + } + ) } + + ) ) } + + ); + }; - return ( - + return ( +
+
- ); + { hasCaption && ( + + ) } + + ); + }, + isEligible: ( attributes ) => { + return ( + attributes.backgroundColor && + attributes.backgroundColor in oldColors && + ! attributes.style + ); + }, + + // This version is the first to introduce the style attribute to the + // table block. As a result, we'll explicitly override that. + migrate: ( attributes ) => { + return { + ...attributes, + backgroundColor: undefined, + style: { + color: { + background: oldColors[ attributes.backgroundColor ], + }, + }, + }; + }, +}; + +const v1 = { + attributes: { + hasFixedLayout: { + type: 'boolean', + default: false, + }, + backgroundColor: { + type: 'string', + }, + head: { + type: 'array', + default: [], + source: 'query', + selector: 'thead tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, + }, + body: { + type: 'array', + default: [], + source: 'query', + selector: 'tbody tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, + }, + foot: { + type: 'array', + default: [], + source: 'query', + selector: 'tfoot tr', + query: { + cells: { + type: 'array', + default: [], + source: 'query', + selector: 'td,th', + query: { + content: { + type: 'string', + source: 'html', + }, + tag: { + type: 'string', + default: 'td', + source: 'tag', + }, + scope: { + type: 'string', + source: 'attribute', + attribute: 'scope', + }, + }, + }, + }, }, }, -]; + supports: { + align: true, + }, + save( { attributes } ) { + const { hasFixedLayout, head, body, foot, backgroundColor } = + attributes; + const isEmpty = ! head.length && ! body.length && ! foot.length; + + if ( isEmpty ) { + return null; + } + + const backgroundClass = getColorClassName( + 'background-color', + backgroundColor + ); + + const classes = classnames( backgroundClass, { + 'has-fixed-layout': hasFixedLayout, + 'has-background': !! backgroundClass, + } ); + + const Section = ( { type, rows } ) => { + if ( ! rows.length ) { + return null; + } + + const Tag = `t${ type }`; -export default deprecated; + return ( + + { rows.map( ( { cells }, rowIndex ) => ( + + { cells.map( + ( { content, tag, scope }, cellIndex ) => ( + + ) + ) } + + ) ) } + + ); + }; + + return ( + +
+
+
+
+ ); + }, +}; + +/** + * New deprecations need to be placed first + * for them to have higher priority. + * + * Old deprecations may need to be updated as well. + * + * See block-deprecation.md + */ +export default [ v3, v2, v1 ]; diff --git a/test/integration/fixtures/blocks/core__table__deprecated-3.html b/test/integration/fixtures/blocks/core__table__deprecated-3.html new file mode 100644 index 0000000000000..a22436c55bdb1 --- /dev/null +++ b/test/integration/fixtures/blocks/core__table__deprecated-3.html @@ -0,0 +1,3 @@ + +
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
+ diff --git a/test/integration/fixtures/blocks/core__table__deprecated-3.json b/test/integration/fixtures/blocks/core__table__deprecated-3.json new file mode 100644 index 0000000000000..4f500a7691fa8 --- /dev/null +++ b/test/integration/fixtures/blocks/core__table__deprecated-3.json @@ -0,0 +1,144 @@ +[ + { + "name": "core/table", + "isValid": true, + "attributes": { + "hasFixedLayout": false, + "caption": "A table for testing", + "head": [ + { + "cells": [ + { + "content": "Version", + "tag": "th" + }, + { + "content": "Musician", + "tag": "th" + }, + { + "content": "Date", + "tag": "th" + } + ] + } + ], + "body": [ + { + "cells": [ + { + "content": ".70", + "tag": "td" + }, + { + "content": "No musician chosen.", + "tag": "td" + }, + { + "content": "May 27, 2003", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "1.0", + "tag": "td" + }, + { + "content": "Miles Davis", + "tag": "td" + }, + { + "content": "January 3, 2004", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "Lots of versions skipped, see the full list", + "tag": "td" + }, + { + "content": "…", + "tag": "td" + }, + { + "content": "…", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.4", + "tag": "td" + }, + { + "content": "Clifford Brown", + "tag": "td" + }, + { + "content": "December 8, 2015", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.5", + "tag": "td" + }, + { + "content": "Coleman Hawkins", + "tag": "td" + }, + { + "content": "April 12, 2016", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.6", + "tag": "td" + }, + { + "content": "Pepper Adams", + "tag": "td" + }, + { + "content": "August 16, 2016", + "tag": "td" + } + ] + }, + { + "cells": [ + { + "content": "4.7", + "tag": "td" + }, + { + "content": "Sarah Vaughan", + "tag": "td" + }, + { + "content": "December 6, 2016", + "tag": "td" + } + ] + } + ], + "foot": [] + }, + "innerBlocks": [] + } +] diff --git a/test/integration/fixtures/blocks/core__table__deprecated-3.parsed.json b/test/integration/fixtures/blocks/core__table__deprecated-3.parsed.json new file mode 100644 index 0000000000000..030ced272fcab --- /dev/null +++ b/test/integration/fixtures/blocks/core__table__deprecated-3.parsed.json @@ -0,0 +1,11 @@ +[ + { + "blockName": "core/table", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
\n", + "innerContent": [ + "\n
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
\n" + ] + } +] diff --git a/test/integration/fixtures/blocks/core__table__deprecated-3.serialized.html b/test/integration/fixtures/blocks/core__table__deprecated-3.serialized.html new file mode 100644 index 0000000000000..66246c83295a9 --- /dev/null +++ b/test/integration/fixtures/blocks/core__table__deprecated-3.serialized.html @@ -0,0 +1,3 @@ + +
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
A table for testing
+