Skip to content

Commit

Permalink
Table Block: Support rowspan attribute in table HTML, including when …
Browse files Browse the repository at this point in the history
…pasting
  • Loading branch information
t-hamano committed Dec 18, 2022
1 parent 4b4c4be commit a1d414d
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 61 deletions.
15 changes: 15 additions & 0 deletions packages/block-library/src/table/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
"type": "string",
"source": "attribute",
"attribute": "colspan"
},
"rowspan": {
"type": "string",
"source": "attribute",
"attribute": "rowspan"
}
}
}
Expand Down Expand Up @@ -92,6 +97,11 @@
"type": "string",
"source": "attribute",
"attribute": "colspan"
},
"rowspan": {
"type": "string",
"source": "attribute",
"attribute": "rowspan"
}
}
}
Expand Down Expand Up @@ -132,6 +142,11 @@
"type": "string",
"source": "attribute",
"attribute": "colspan"
},
"rowspan": {
"type": "string",
"source": "attribute",
"attribute": "rowspan"
}
}
}
Expand Down
13 changes: 11 additions & 2 deletions packages/block-library/src/table/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
toggleSection,
isEmptyTableSection,
} from './state';
import { normalizeRowColSpan } from './utils';

const ALIGNMENT_CONTROLS = [
{
Expand Down Expand Up @@ -404,7 +405,14 @@ function TableEdit( {
<tr key={ rowIndex }>
{ cells.map(
(
{ content, tag: CellTag, scope, align, colspan },
{
content,
tag: CellTag,
scope,
align,
colspan,
rowspan,
},
columnIndex
) => (
<RichText
Expand All @@ -417,7 +425,8 @@ function TableEdit( {
'wp-block-table__cell-content'
) }
scope={ CellTag === 'th' ? scope : undefined }
colSpan={ colspan }
colSpan={ normalizeRowColSpan( colspan ) }
rowSpan={ normalizeRowColSpan( rowspan ) }
value={ content }
onChange={ onChange }
unstableOnFocus={ () => {
Expand Down
21 changes: 19 additions & 2 deletions packages/block-library/src/table/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import {
__experimentalGetElementClassName,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { normalizeRowColSpan } from './utils';

export default function save( { attributes } ) {
const { hasFixedLayout, head, body, foot, caption } = attributes;
const isEmpty = ! head.length && ! body.length && ! foot.length;
Expand Down Expand Up @@ -44,7 +49,14 @@ export default function save( { attributes } ) {
<tr key={ rowIndex }>
{ cells.map(
(
{ content, tag, scope, align, colspan },
{
content,
tag,
scope,
align,
colspan,
rowspan,
},
cellIndex
) => {
const cellClasses = classnames( {
Expand All @@ -65,7 +77,12 @@ export default function save( { attributes } ) {
scope={
tag === 'th' ? scope : undefined
}
colSpan={ colspan }
colSpan={ normalizeRowColSpan(
colspan
) }
rowSpan={ normalizeRowColSpan(
rowspan
) }
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/table/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ const tableContentPasteSchema = ( { phrasingContentSchema } ) => ( {
th: {
allowEmpty: true,
children: phrasingContentSchema,
attributes: [ 'scope', 'colspan' ],
attributes: [ 'scope', 'colspan', 'rowspan' ],
},
td: {
allowEmpty: true,
children: phrasingContentSchema,
attributes: [ 'colspan' ],
attributes: [ 'colspan', 'rowspan' ],
},
},
},
Expand Down
10 changes: 10 additions & 0 deletions packages/block-library/src/table/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Normalize the row or column span value.
*
* @param {number|undefined} rowColSpan normalized value.
*/
export function normalizeRowColSpan( rowColSpan ) {
return parseInt( rowColSpan, 10 ) && parseInt( rowColSpan, 10 ) !== 1
? parseInt( rowColSpan, 10 )
: undefined;
}
181 changes: 126 additions & 55 deletions packages/blocks/src/api/raw-handling/test/paste-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,52 @@ import { pasteHandler } from '@wordpress/blocks';
*/
import { init as initAndRegisterTableBlock } from '../../../../../block-library/src/table';

const tableWithHeaderFooterAndBodyUsingColspan = `
const tableWithHeaderFooterAndBodyUsingColspanAndRowspan = `
<table>
<thead>
<tr>
<th colspan="2">Colspan 2</th>
<th>Header Cell</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="2">Footer Cell</th>
<th>Footer Cell</th>
</tr>
</tfoot>
<tbody>
<tr>
<td colspan="2">Colspan 2</td>
<td>Cell Data</td>
</tr>
</tbody>
<tr>
<th>Header Cell</th>
<th>Header Cell</th>
<th rowspan="2">Rowspan 2</th>
</tr>
<tr>
<th colspan="2">Colspan 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Body Cell</td>
<td>Body Cell</td>
<td rowspan="2">Rowspan 2</td>
</tr>
<tr>
<td colspan="2">Colspan 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer Cell</td>
<td>Footer Cell</td>
<td rowspan="2">Rowspan 2</td>
</tr>
<tr>
<td colspan="2">Colspan 2</td>
</tr>
</tfoot>
</table>`;

const googleDocsTableWithColspan = `
<meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-b0f68bdd-7fff-a054-94d1-43c2fdedca2a">
<div dir="ltr" style="margin-left:0pt;" align="left">
<table style="border:none;border-collapse:collapse;">
<colgroup>
<col width="185"/>
<col width="439"/>
</colgroup>
<tbody>
<tr style="height:21pt">
<td colspan="2"
style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;">
<p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span
style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Test colspan</span>
</p></td>
</tr>
</tbody>
</table>
</div>
<br/><br/></b>
const googleDocsTableWithColspanAndRowspan = `
<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none"><colgroup><col width="100"/><col width="100"/><col width="100"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Body Cell&quot;}">Body Cell</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Body Cell&quot;}">Body Cell</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" rowspan="2" colspan="1" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Rowspan 2&quot;}"><span><div style="max-height:42px">Rowspan 2</div></span></td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" rowspan="1" colspan="2" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Colspan 2&quot;}">Colspan 2</td></tr></tbody></table>
`;

describe( 'pasteHandler', () => {
beforeAll( () => {
initAndRegisterTableBlock();
} );

it( 'can handle a table with thead, tbody and tfoot using colspan', () => {
it( 'can handle a table with thead, tbody and tfoot using colspan and rowspan', () => {
const [ result ] = pasteHandler( {
HTML: tableWithHeaderFooterAndBodyUsingColspan,
HTML: tableWithHeaderFooterAndBodyUsingColspanAndRowspan,
tagName: 'p',
preserveWhiteSpace: false,
} );
Expand All @@ -71,24 +65,84 @@ describe( 'pasteHandler', () => {
head: [
{
cells: [
{ content: 'Colspan 2', tag: 'th', colspan: '2' },
{ content: 'Header Cell', tag: 'th' },
{
content: 'Header Cell',
tag: 'th',
},
{
content: 'Header Cell',
tag: 'th',
},
{
content: 'Rowspan 2',
tag: 'th',
rowspan: '2',
},
],
},
{
cells: [
{
content: 'Colspan 2',
tag: 'th',
colspan: '2',
},
],
},
],
body: [
{
cells: [
{ content: 'Colspan 2', tag: 'td', colspan: '2' },
{ content: 'Cell Data', tag: 'td' },
{
content: 'Body Cell',
tag: 'td',
},
{
content: 'Body Cell',
tag: 'td',
},
{
content: 'Rowspan 2',
tag: 'td',
rowspan: '2',
},
],
},
{
cells: [
{
content: 'Colspan 2',
tag: 'td',
colspan: '2',
},
],
},
],
foot: [
{
cells: [
{ content: 'Footer Cell', tag: 'th', colspan: '2' },
{ content: 'Footer Cell', tag: 'th' },
{
content: 'Footer Cell',
tag: 'td',
},
{
content: 'Footer Cell',
tag: 'td',
},
{
content: 'Rowspan 2',
tag: 'td',
rowspan: '2',
},
],
},
{
cells: [
{
content: 'Colspan 2',
tag: 'td',
colspan: '2',
},
],
},
],
Expand All @@ -97,33 +151,50 @@ describe( 'pasteHandler', () => {
expect( result.isValid ).toBeTruthy();
} );

it( 'can handle a google docs table with colspan', () => {
it( 'can handle a google docs table with colspan and rowspan', () => {
const [ result ] = pasteHandler( {
HTML: googleDocsTableWithColspan,
HTML: googleDocsTableWithColspanAndRowspan,
tagName: 'p',
preserveWhiteSpace: false,
} );

expect( console ).toHaveLogged();

expect( result.attributes ).toEqual( {
hasFixedLayout: false,
caption: '',
body: [
{
cells: [
{
align: undefined,
colspan: '2',
content: 'Test colspan',
scope: undefined,
content: 'Body Cell',
tag: 'td',
},
{
content: 'Body Cell',
tag: 'td',
},
{
content: 'Rowspan 2',
tag: 'td',
colspan: '1',
rowspan: '2',
},
],
},
{
cells: [
{
content: 'Colspan 2',
tag: 'td',
colspan: '2',
rowspan: '1',
},
],
},
],
caption: '',
foot: [],
hasFixedLayout: false,
head: [],
foot: [],
} );
expect( result.name ).toEqual( 'core/table' );
expect( result.isValid ).toBeTruthy();
Expand Down

1 comment on commit a1d414d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/3723795326
📝 Reported issues:

Please sign in to comment.