Refactor BlocksWidth preprocessor to set string including units

I added pixels to calculated width for easier work with it in block rendering.
[MAILPOET-5591]
This commit is contained in:
Jan Lysý
2023-10-18 19:41:54 +02:00
committed by Jan Lysý
parent ac075c197e
commit 1250d81670
7 changed files with 60 additions and 47 deletions

View File

@@ -33,8 +33,14 @@ class EmailApiController {
public function getEmailDataSchema(): array { public function getEmailDataSchema(): array {
return Builder::object([ return Builder::object([
'layout_styles' => Builder::object([ 'layout_styles' => Builder::object([
'width' => Builder::integer(), 'width' => Builder::string(),
'background' => Builder::string(), 'background' => Builder::string(),
'padding' => Builder::object([
'bottom' => Builder::string(),
'left' => Builder::string(),
'right' => Builder::string(),
'top' => Builder::string(),
]),
]), ]),
])->toArray(); ])->toArray();
} }

View File

@@ -23,7 +23,7 @@ class PreprocessManager {
/** /**
* @param array $parsedBlocks * @param array $parsedBlocks
* @param array{width: int, background: string, padding: array{bottom: int, left: int, right: int, top: int}} $layoutStyles * @param array{width: string, background: string, padding: array{bottom: string, left: string, right: string, top: string}} $layoutStyles
* @return array * @return array
*/ */
public function preprocess(array $parsedBlocks, array $layoutStyles): array { public function preprocess(array $parsedBlocks, array $layoutStyles): array {

View File

@@ -7,11 +7,16 @@ namespace MailPoet\EmailEditor\Engine\Renderer\Preprocessors;
* The final width in pixels is stored in the email_attrs array because we would like to avoid changing the original attributes. * The final width in pixels is stored in the email_attrs array because we would like to avoid changing the original attributes.
*/ */
class BlocksWidthPreprocessor implements Preprocessor { class BlocksWidthPreprocessor implements Preprocessor {
const BLOCKS_WITHOUT_WIDTH = [
'core/paragraph',
];
public function preprocess(array $parsedBlocks, array $layoutStyles): array { public function preprocess(array $parsedBlocks, array $layoutStyles): array {
$layoutWidth = $layoutStyles['width']; $layoutWidth = $this->parseNumberFromStringWithPixels($layoutStyles['width']);
// Subtract padding from the width of the layout element // Subtract padding from the width of the layout element
$layoutWidth -= $layoutStyles['padding']['left'] ?? 0; $layoutWidth -= $this->parseNumberFromStringWithPixels($layoutStyles['padding']['left'] ?? '0px');
$layoutWidth -= $layoutStyles['padding']['right'] ?? 0; $layoutWidth -= $this->parseNumberFromStringWithPixels($layoutStyles['padding']['right'] ?? '0px');
foreach ($parsedBlocks as $key => $block) { foreach ($parsedBlocks as $key => $block) {
$width = $this->convertWithToPixels($block['attrs']['width'] ?? '100%', $layoutWidth); $width = $this->convertWithToPixels($block['attrs']['width'] ?? '100%', $layoutWidth);
@@ -21,12 +26,14 @@ class BlocksWidthPreprocessor implements Preprocessor {
// Copy layout styles and update width and padding // Copy layout styles and update width and padding
$modifiedLayoutStyles = $layoutStyles; $modifiedLayoutStyles = $layoutStyles;
$modifiedLayoutStyles['width'] = $width; $modifiedLayoutStyles['width'] = "{$width}px";
$modifiedLayoutStyles['padding']['left'] = $this->parseNumberFromStringWithPixels($block['attrs']['style']['spacing']['padding']['left'] ?? '0px'); $modifiedLayoutStyles['padding']['left'] = $block['attrs']['style']['spacing']['padding']['left'] ?? '0px';
$modifiedLayoutStyles['padding']['right'] = $this->parseNumberFromStringWithPixels($block['attrs']['style']['spacing']['padding']['right'] ?? '0px'); $modifiedLayoutStyles['padding']['right'] = $block['attrs']['style']['spacing']['padding']['right'] ?? '0px';
// Set current block values and reassign it to $parsedBlocks // Set current block values and reassign it to $parsedBlocks, but don't set width for blocks that are not supposed to have it
$block['email_attrs']['width'] = $width; if (!in_array($block['blockName'], self::BLOCKS_WITHOUT_WIDTH, true)) {
$block['email_attrs']['width'] = "{$width}px";
}
$block['innerBlocks'] = $this->preprocess($block['innerBlocks'], $modifiedLayoutStyles); $block['innerBlocks'] = $this->preprocess($block['innerBlocks'], $modifiedLayoutStyles);
$parsedBlocks[$key] = $block; $parsedBlocks[$key] = $block;
} }

View File

@@ -19,8 +19,8 @@
</head> </head>
<body style="word-spacing:normal;background:{{background}};"> <body style="word-spacing:normal;background:{{background}};">
<div class="email_layout_wrapper" style="background:{{background}}"> <div class="email_layout_wrapper" style="background:{{background}}">
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:{{width}}px;" width="{{width}}" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--> <!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:{{width}};" width="{{width}}" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div style="margin: 0px auto; max-width: {{width}}px"> <div style="margin: 0px auto; max-width: {{width}}">
<table <table
align="center" align="center"
border="0" border="0"
@@ -50,10 +50,10 @@
style=" style="
direction: ltr; direction: ltr;
font-size: 0px; font-size: 0px;
padding-bottom: {{padding_bottom}}px; padding-bottom: {{padding_bottom}};
padding-left: {{padding_left}}px; padding-left: {{padding_left}};
padding-right: {{padding_right}}px; padding-right: {{padding_right}};
padding-top: {{padding_top}}px; padding-top: {{padding_top}};
text-align: center; text-align: center;
" "
> >

View File

@@ -5,9 +5,9 @@ namespace MailPoet\EmailEditor\Engine;
class StylesController { class StylesController {
/** /**
* Width of the email in pixels. * Width of the email in pixels.
* @var int * @var string
*/ */
const EMAIL_WIDTH = 660; const EMAIL_WIDTH = '660px';
/** /**
* Width of the email in pixels. * Width of the email in pixels.
@@ -17,9 +17,9 @@ class StylesController {
/** /**
* Padding of the email in pixels. * Padding of the email in pixels.
* @var int * @var string
*/ */
const EMAIL_PADDING = 10; const EMAIL_PADDING = '10px';
/** /**
* Default styles applied to the email. These are going to be replaced by style settings. * Default styles applied to the email. These are going to be replaced by style settings.
@@ -43,7 +43,7 @@ class StylesController {
} }
/** /**
* @return array{width: int, background: string, padding: array{bottom: int, left: int, right: int, top: int}} * @return array{width: string, background: string, padding: array{bottom: string, left: string, right: string, top: string}}
*/ */
public function getEmailLayoutStyles(): array { public function getEmailLayoutStyles(): array {
return [ return [

View File

@@ -10,13 +10,13 @@ use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TopLevelPreprocessor;
class PreprocessManagerTest extends \MailPoetUnitTest { class PreprocessManagerTest extends \MailPoetUnitTest {
public function testItCallsPreprocessorsProperly(): void { public function testItCallsPreprocessorsProperly(): void {
$layoutStyles = [ $layoutStyles = [
'width' => 600, 'width' => '600px',
'background' => '#ffffff', 'background' => '#ffffff',
'padding' => [ 'padding' => [
'bottom' => 0, 'bottom' => '0px',
'left' => 0, 'left' => '0px',
'right' => 0, 'right' => '0px',
'top' => 0, 'top' => '0px',
], ],
]; ];
$topLevel = $this->createMock(TopLevelPreprocessor::class); $topLevel = $this->createMock(TopLevelPreprocessor::class);

View File

@@ -42,13 +42,13 @@ class BlocksWidthPreprocessorTest extends \MailPoetUnitTest {
], ],
], ],
]]; ]];
$result = $this->preprocessor->preprocess($blocks, ['width' => 660, 'padding' => ['left' => 0, 'right' => 0]]); $result = $this->preprocessor->preprocess($blocks, ['width' => '660px', 'padding' => ['left' => '0px', 'right' => '0px']]);
$result = $result[0]; $result = $result[0];
expect($result['email_attrs']['width'])->equals(660); expect($result['email_attrs']['width'])->equals('660px');
expect($result['innerBlocks'])->count(3); expect($result['innerBlocks'])->count(3);
expect($result['innerBlocks'][0]['email_attrs']['width'])->equals(330); // 660 * 0.5 expect($result['innerBlocks'][0]['email_attrs']['width'])->equals('330px'); // 660 * 0.5
expect($result['innerBlocks'][1]['email_attrs']['width'])->equals(165); // 660 * 0.25 expect($result['innerBlocks'][1]['email_attrs']['width'])->equals('165px'); // 660 * 0.25
expect($result['innerBlocks'][2]['email_attrs']['width'])->equals(100); expect($result['innerBlocks'][2]['email_attrs']['width'])->equals('100px');
} }
public function testItCalculatesWidthWithLayoutPadding(): void { public function testItCalculatesWidthWithLayoutPadding(): void {
@@ -79,12 +79,12 @@ class BlocksWidthPreprocessorTest extends \MailPoetUnitTest {
], ],
], ],
]]; ]];
$result = $this->preprocessor->preprocess($blocks, ['width' => 600, 'padding' => ['left' => 20, 'right' => 20]]); $result = $this->preprocessor->preprocess($blocks, ['width' => '600px', 'padding' => ['left' => '20px', 'right' => '20px']]);
$result = $result[0]; $result = $result[0];
expect($result['innerBlocks'])->count(3); expect($result['innerBlocks'])->count(3);
expect($result['innerBlocks'][0]['email_attrs']['width'])->equals(185); // (600 - 20 - 20) * 0.33 expect($result['innerBlocks'][0]['email_attrs']['width'])->equals('185px'); // (600 - 20 - 20) * 0.33
expect($result['innerBlocks'][1]['email_attrs']['width'])->equals(100); expect($result['innerBlocks'][1]['email_attrs']['width'])->equals('100px');
expect($result['innerBlocks'][2]['email_attrs']['width'])->equals(112); // (600 - 20 - 20) * 0.2 expect($result['innerBlocks'][2]['email_attrs']['width'])->equals('112px'); // (600 - 20 - 20) * 0.2
} }
public function testItCalculatesWidthOfBlockInColumn(): void { public function testItCalculatesWidthOfBlockInColumn(): void {
@@ -136,14 +136,14 @@ class BlocksWidthPreprocessorTest extends \MailPoetUnitTest {
], ],
], ],
]]; ]];
$result = $this->preprocessor->preprocess($blocks, ['width' => 660, 'padding' => ['left' => 15, 'right' => 15]]); $result = $this->preprocessor->preprocess($blocks, ['width' => '660px', 'padding' => ['left' => '15px', 'right' => '15px']]);
$innerBlocks = $result[0]['innerBlocks']; $innerBlocks = $result[0]['innerBlocks'];
expect($innerBlocks)->count(2); expect($innerBlocks)->count(2);
expect($innerBlocks[0]['email_attrs']['width'])->equals(252); // (660 - 15 - 15) * 0.4 expect($innerBlocks[0]['email_attrs']['width'])->equals('252px'); // (660 - 15 - 15) * 0.4
expect($innerBlocks[0]['innerBlocks'][0]['email_attrs']['width'])->equals(232); // paragraph: 252 - 10 - 10 expect($innerBlocks[0]['innerBlocks'][0])->hasNotKey('email_attrs'); // paragraph block should not have width
expect($innerBlocks[1]['email_attrs']['width'])->equals(378); // (660 - 15 - 15) * 0.6 expect($innerBlocks[1]['email_attrs']['width'])->equals('378px'); // (660 - 15 - 15) * 0.6
expect($innerBlocks[1]['innerBlocks'][0]['email_attrs']['width'])->equals(338); // paragraph: 378 - 25 - 15 expect($innerBlocks[1]['innerBlocks'][0])->hasNotKey('email_attrs'); // paragraph block should not have width
} }
public function testItAddsMissingColumnWidth(): void { public function testItAddsMissingColumnWidth(): void {
@@ -186,15 +186,15 @@ class BlocksWidthPreprocessorTest extends \MailPoetUnitTest {
], ],
], ],
]]; ]];
$result = $this->preprocessor->preprocess($blocks, ['width' => 660, 'padding' => ['left' => 30, 'right' => 30]]); $result = $this->preprocessor->preprocess($blocks, ['width' => '660px', 'padding' => ['left' => '30px', 'right' => '30px']]);
$innerBlocks = $result[0]['innerBlocks']; $innerBlocks = $result[0]['innerBlocks'];
expect($innerBlocks)->count(3); expect($innerBlocks)->count(3);
expect($innerBlocks[0]['email_attrs']['width'])->equals(200); // (660 - 30 - 30) * 0.33 expect($innerBlocks[0]['email_attrs']['width'])->equals('200px'); // (660 - 30 - 30) * 0.33
expect($innerBlocks[0]['innerBlocks'][0]['email_attrs']['width'])->equals(200); // paragraph: 200 expect($innerBlocks[0]['innerBlocks'][0])->hasNotKey('email_attrs'); // paragraph block should not have width
expect($innerBlocks[1]['email_attrs']['width'])->equals(200); // (660 - 30 - 30) * 0.33 expect($innerBlocks[1]['email_attrs']['width'])->equals('200px'); // (660 - 30 - 30) * 0.33
expect($innerBlocks[1]['innerBlocks'][0]['email_attrs']['width'])->equals(200); // paragraph: 200 expect($innerBlocks[1]['innerBlocks'][0])->hasNotKey('email_attrs'); // paragraph block should not have width
expect($innerBlocks[2]['email_attrs']['width'])->equals(200); // (660 - 30 - 30) * 0.33 expect($innerBlocks[2]['email_attrs']['width'])->equals('200px'); // (660 - 30 - 30) * 0.33
expect($innerBlocks[2]['innerBlocks'][0]['email_attrs']['width'])->equals(200); // paragraph: 200 expect($innerBlocks[2]['innerBlocks'][0])->hasNotKey('email_attrs'); // paragraph block should not have width
} }
} }