Commit 1a4ac92050 for woocommerce
commit 1a4ac920501f71c30226a034476580de88b5f75e
Author: Allison Levine <1689238+allilevine@users.noreply.github.com>
Date: Mon Jan 5 06:44:23 2026 -0500
Email editor: Add text alignment for has-text-align-* classes. (#62588)
* Email editor: Add text alignment for has-text-align-* classes.
* Add changefile(s) from automation for the following project(s): packages/php/email-editor
* Fix missing new line in changelog.
* Add changefile(s) from automation for the following project(s): packages/php/email-editor
---------
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Tony Arcangelini <33258733+arcangelini@users.noreply.github.com>
diff --git a/packages/php/email-editor/changelog/62588-add-text-alignment-by-class b/packages/php/email-editor/changelog/62588-add-text-alignment-by-class
new file mode 100644
index 0000000000..8e8c379ea7
--- /dev/null
+++ b/packages/php/email-editor/changelog/62588-add-text-alignment-by-class
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Email editor: Add text alignment for has-text-align-* classes.
\ No newline at end of file
diff --git a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
index ce2102bb92..9e5a7b59f6 100644
--- a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
+++ b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
@@ -30,20 +30,32 @@ class Text extends Abstract_Block_Renderer {
return '';
}
- $block_content = $this->adjustStyleAttribute( $block_content );
- $block_attributes = wp_parse_args(
+ $block_content = $this->adjustStyleAttribute( $block_content );
+ $block_attributes = wp_parse_args(
$parsed_block['attrs'] ?? array(),
array(
'textAlign' => 'left',
'style' => array(),
)
);
- $html = new \WP_HTML_Tag_Processor( $block_content );
- $classes = 'email-text-block';
+ $html = new \WP_HTML_Tag_Processor( $block_content );
+ $classes = 'email-text-block';
+ $alignment_from_class = null;
if ( $html->next_tag() ) {
/** @var string $block_classes */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort -- used for phpstan
$block_classes = $html->get_attribute( 'class' ) ?? '';
$classes .= ' ' . $block_classes;
+
+ // Extract text alignment from has-text-align-* classes before they're potentially modified.
+ $class_attr = (string) $block_classes;
+ if ( false !== strpos( $class_attr, 'has-text-align-center' ) ) {
+ $alignment_from_class = 'center';
+ } elseif ( false !== strpos( $class_attr, 'has-text-align-right' ) ) {
+ $alignment_from_class = 'right';
+ } elseif ( false !== strpos( $class_attr, 'has-text-align-left' ) ) {
+ $alignment_from_class = 'left';
+ }
+
// remove has-background to prevent double padding applied for wrapper and inner element.
$block_classes = str_replace( 'has-background', '', $block_classes );
// remove border related classes because we handle border on wrapping table cell.
@@ -69,6 +81,8 @@ class Text extends Abstract_Block_Renderer {
$additional_styles['text-align'] = $parsed_block['attrs']['textAlign'];
} elseif ( in_array( $parsed_block['attrs']['align'] ?? null, array( 'left', 'center', 'right' ), true ) ) {
$additional_styles['text-align'] = $parsed_block['attrs']['align'];
+ } elseif ( null !== $alignment_from_class ) {
+ $additional_styles['text-align'] = $alignment_from_class;
}
$block_styles = Styles_Helper::extend_block_styles( $block_styles, $additional_styles );
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
index 17e2f1cef1..9d0263bd0e 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
@@ -165,4 +165,60 @@ class Heading_Test extends \Email_Editor_Integration_Test_Case {
$this->assertStringContainsString( 'font-size:28px;', $rendered );
$this->assertStringContainsString( 'font-weight:900;', $rendered );
}
+
+ /**
+ * Test it extracts alignment from has-text-align-center class when no textAlign attribute is set
+ */
+ public function testItExtractsAlignmentFromHasTextAlignCenterClass(): void {
+ $parsed_heading = $this->parsed_heading;
+ // Ensure no textAlign or align attributes are set.
+ unset( $parsed_heading['attrs']['textAlign'] );
+ unset( $parsed_heading['attrs']['align'] );
+
+ $content = '<h1 class="has-text-align-center">Centered heading</h1>';
+ $parsed_heading['innerHTML'] = $content;
+ $parsed_heading['innerContent'] = array( $content );
+
+ $rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+ $this->assertStringContainsString( 'text-align:center;', $rendered );
+ $this->assertStringContainsString( 'align="center"', $rendered );
+ }
+
+ /**
+ * Test it extracts alignment from has-text-align-right class when no textAlign attribute is set
+ */
+ public function testItExtractsAlignmentFromHasTextAlignRightClass(): void {
+ $parsed_heading = $this->parsed_heading;
+ // Ensure no textAlign or align attributes are set.
+ unset( $parsed_heading['attrs']['textAlign'] );
+ unset( $parsed_heading['attrs']['align'] );
+
+ $content = '<h1 class="has-text-align-right">Right aligned heading</h1>';
+ $parsed_heading['innerHTML'] = $content;
+ $parsed_heading['innerContent'] = array( $content );
+
+ $rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+ $this->assertStringContainsString( 'text-align:right;', $rendered );
+ $this->assertStringContainsString( 'align="right"', $rendered );
+ }
+
+ /**
+ * Test it prioritizes textAlign attribute over has-text-align-* class
+ */
+ public function testItPrioritizesTextAlignAttributeOverClass(): void {
+ $parsed_heading = $this->parsed_heading;
+ $parsed_heading['attrs']['textAlign'] = 'right';
+ unset( $parsed_heading['attrs']['align'] );
+
+ $content = '<h1 class="has-text-align-center">Heading with center class but right attribute</h1>';
+ $parsed_heading['innerHTML'] = $content;
+ $parsed_heading['innerContent'] = array( $content );
+
+ $rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+ // Should use the attribute, not the class.
+ $this->assertStringContainsString( 'text-align:right;', $rendered );
+ $this->assertStringContainsString( 'align="right"', $rendered );
+ $this->assertStringNotContainsString( 'text-align:center;', $rendered );
+ $this->assertStringNotContainsString( 'align="center"', $rendered );
+ }
}
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
index c94e30e0c6..982b73089d 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
@@ -172,4 +172,78 @@ class Paragraph_Test extends \Email_Editor_Integration_Test_Case {
$rendered = $this->paragraph_renderer->render( '<p>Lorem Ipsum</p>', $parsed_paragraph, $this->rendering_context );
$this->assertStringContainsString( 'color:#ff0000;', $rendered );
}
+
+ /**
+ * Test it extracts alignment from has-text-align-center class when no textAlign attribute is set
+ */
+ public function testItExtractsAlignmentFromHasTextAlignCenterClass(): void {
+ $parsed_paragraph = $this->parsed_paragraph;
+ // Ensure no textAlign or align attributes are set.
+ unset( $parsed_paragraph['attrs']['textAlign'] );
+ unset( $parsed_paragraph['attrs']['align'] );
+
+ $content = '<p class="has-text-align-center">Centered text</p>';
+ $parsed_paragraph['innerHTML'] = $content;
+ $parsed_paragraph['innerContent'] = array( $content );
+
+ $rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+ $this->assertStringContainsString( 'text-align:center;', $rendered );
+ $this->assertStringContainsString( 'align="center"', $rendered );
+ }
+
+ /**
+ * Test it extracts alignment from has-text-align-right class when no textAlign attribute is set
+ */
+ public function testItExtractsAlignmentFromHasTextAlignRightClass(): void {
+ $parsed_paragraph = $this->parsed_paragraph;
+ // Ensure no textAlign or align attributes are set.
+ unset( $parsed_paragraph['attrs']['textAlign'] );
+ unset( $parsed_paragraph['attrs']['align'] );
+
+ $content = '<p class="has-text-align-right">Right aligned text</p>';
+ $parsed_paragraph['innerHTML'] = $content;
+ $parsed_paragraph['innerContent'] = array( $content );
+
+ $rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+ $this->assertStringContainsString( 'text-align:right;', $rendered );
+ $this->assertStringContainsString( 'align="right"', $rendered );
+ }
+
+ /**
+ * Test it extracts alignment from has-text-align-left class when no textAlign attribute is set
+ */
+ public function testItExtractsAlignmentFromHasTextAlignLeftClass(): void {
+ $parsed_paragraph = $this->parsed_paragraph;
+ // Ensure no textAlign or align attributes are set.
+ unset( $parsed_paragraph['attrs']['textAlign'] );
+ unset( $parsed_paragraph['attrs']['align'] );
+
+ $content = '<p class="has-text-align-left">Left aligned text</p>';
+ $parsed_paragraph['innerHTML'] = $content;
+ $parsed_paragraph['innerContent'] = array( $content );
+
+ $rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+ $this->assertStringContainsString( 'text-align:left;', $rendered );
+ $this->assertStringContainsString( 'align="left"', $rendered );
+ }
+
+ /**
+ * Test it prioritizes textAlign attribute over has-text-align-* class
+ */
+ public function testItPrioritizesTextAlignAttributeOverClass(): void {
+ $parsed_paragraph = $this->parsed_paragraph;
+ $parsed_paragraph['attrs']['textAlign'] = 'right';
+ unset( $parsed_paragraph['attrs']['align'] );
+
+ $content = '<p class="has-text-align-center">Text with center class but right attribute</p>';
+ $parsed_paragraph['innerHTML'] = $content;
+ $parsed_paragraph['innerContent'] = array( $content );
+
+ $rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+ // Should use the attribute, not the class.
+ $this->assertStringContainsString( 'text-align:right;', $rendered );
+ $this->assertStringContainsString( 'align="right"', $rendered );
+ $this->assertStringNotContainsString( 'text-align:center;', $rendered );
+ $this->assertStringNotContainsString( 'align="center"', $rendered );
+ }
}