diff --git a/includes/Modules/Features/Core_Block_Validation_Rules.php b/includes/Modules/Features/Core_Block_Validation_Rules.php index bb23b35..0dabd55 100644 --- a/includes/Modules/Features/Core_Block_Validation_Rules.php +++ b/includes/Modules/Features/Core_Block_Validation_Rules.php @@ -269,6 +269,18 @@ private function register_table_checks(): void { 'warning_msg' => __( 'Consider adding table headers.', 'accessibility-lab' ), ) ); + validation_api_register_block_check( + 'core/table', + array( + 'namespace' => self::NS, + 'name' => 'check_table_caption', + 'title' => __( 'Table caption recommended', 'accessibility-lab' ), + 'level' => 'none', + 'description' => __( 'Tables should have a caption to describe their purpose or content to screen reader users.', 'accessibility-lab' ), + 'error_msg' => __( 'This table is missing a caption.', 'accessibility-lab' ), + 'warning_msg' => __( 'Consider adding a caption to this table.', 'accessibility-lab' ), + ) + ); } /** diff --git a/src/editor/core-block-rules/table.ts b/src/editor/core-block-rules/table.ts index 60478c8..e9ffa55 100644 --- a/src/editor/core-block-rules/table.ts +++ b/src/editor/core-block-rules/table.ts @@ -12,6 +12,13 @@ type TableAttributes = { caption?: string; }; +function stripHtml( html: string ): string { + return html + .replace( /<[^>]*>/g, '' ) + .replace( / |\u00a0/g, ' ' ) + .trim(); +} + addFilter( 'editor.validateBlock', 'accessibility-lab-core-blocks/table', @@ -25,19 +32,28 @@ addFilter( return isValid; } - if ( checkName !== 'check_table_headers' ) { - return isValid; - } + switch ( checkName ) { + case 'check_table_headers': { + const hasHead = + Array.isArray( attributes.head ) && + attributes.head.length > 0; + if ( hasHead ) { + return true; + } + const firstRow = attributes.body?.[ 0 ]; + if ( firstRow?.cells?.every( ( c ) => c.tag === 'th' ) ) { + return true; + } + return false; + } - const hasHead = - Array.isArray( attributes.head ) && attributes.head.length > 0; - if ( hasHead ) { - return true; - } - const firstRow = attributes.body?.[ 0 ]; - if ( firstRow?.cells?.every( ( c ) => c.tag === 'th' ) ) { - return true; + case 'check_table_caption': { + const caption = stripHtml( String( attributes.caption ?? '' ) ); + return caption.length > 0; + } + + default: + return isValid; } - return false; } );