diff --git a/php-transformer/src/HtmlToBlocks/BlockFactory.php b/php-transformer/src/HtmlToBlocks/BlockFactory.php index ba7cb8c2..c5396fcd 100644 --- a/php-transformer/src/HtmlToBlocks/BlockFactory.php +++ b/php-transformer/src/HtmlToBlocks/BlockFactory.php @@ -202,6 +202,8 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri } if ( 'core/button' === $name ) { + $support = $this->buttonStyleSupport($attrs); + if ( 'button' === ($attrs['tagName'] ?? '') ) { $buttonAttrs = array_intersect_key($attrs, array_flip(array( 'type', 'role', 'aria-label', 'aria-controls', 'aria-expanded', 'aria-haspopup' ))); foreach ( $attrs as $attrName => $attrValue ) { @@ -211,8 +213,8 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri } $buttonAttrs = array_merge(array( 'id' => (string) ($attrs['anchor'] ?? ''), - 'class' => $this->mergeClassNames('wp-block-button__link wp-element-button', (string) ($attrs['className'] ?? '')), - 'style' => (string) ($attrs['style'] ?? ''), + 'class' => $this->mergeClassNames('wp-block-button__link', $support['classes'], 'wp-element-button', (string) ($attrs['className'] ?? '')), + 'style' => $support['style'], ), $buttonAttrs); return '
htmlAttrs($buttonAttrs) . '>' . ($attrs['text'] ?? '') . '
'; @@ -221,8 +223,8 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri $href = '' !== ($attrs['url'] ?? '') ? ' href="' . htmlspecialchars((string) $attrs['url'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '"' : ''; $wrapperClass = $this->mergeClassNames('wp-block-button', in_array('is-style-outline', preg_split('/\s+/', (string) ($attrs['className'] ?? '')) ?: array(), true) ? 'is-style-outline' : ''); $linkAttrs = array( - 'class' => $this->mergeClassNames('wp-block-button__link wp-element-button', (string) ($attrs['className'] ?? '')), - 'style' => (string) ($attrs['style'] ?? ''), + 'class' => $this->mergeClassNames('wp-block-button__link', $support['classes'], 'wp-element-button', (string) ($attrs['className'] ?? '')), + 'style' => $support['style'], ); return '
htmlAttrs($linkAttrs) . $href . '>' . ($attrs['text'] ?? '') . '
'; } @@ -404,6 +406,80 @@ private function searchHtml(array $attrs): string return '
blockSupportAttrs($attrs, 'wp-block-search') . '>htmlAttrs($labelAttrs) . '>' . $label . '
htmlAttrs($inputAttrs) . ' />' . $button . '
'; } + /** + * Translate a core/button block's native style support into the rendered + * has-* support classes and the inline style string WordPress emits for + * custom colors and borders. Accepts the canonical `style` object; falls back + * to a legacy raw `style` string when present for backward compatibility. + * + * @param array $attrs + * @return array{classes: string, style: string} + */ + private function buttonStyleSupport(array $attrs): array + { + $style = $attrs['style'] ?? null; + if ( ! is_array($style) ) { + return array( + 'classes' => '', + 'style' => is_string($style) ? $style : '', + ); + } + + $classes = array(); + $declarations = array(); + + $background = (string) ($style['color']['background'] ?? ''); + $text = (string) ($style['color']['text'] ?? ''); + if ( '' !== $text ) { + $classes[] = 'has-text-color'; + $declarations[] = 'color:' . $text; + } + if ( '' !== $background ) { + $classes[] = 'has-background'; + $declarations[] = 'background-color:' . $background; + } + + $border = is_array($style['border'] ?? null) ? $style['border'] : array(); + if ( isset($border['color']) && '' !== (string) $border['color'] ) { + $classes[] = 'has-border-color'; + $declarations[] = 'border-color:' . (string) $border['color']; + } + if ( isset($border['width']) && '' !== (string) $border['width'] ) { + $declarations[] = 'border-width:' . (string) $border['width']; + } + if ( isset($border['style']) && '' !== (string) $border['style'] ) { + $declarations[] = 'border-style:' . (string) $border['style']; + } + if ( isset($border['radius']) && '' !== (string) $border['radius'] ) { + $declarations[] = 'border-radius:' . (string) $border['radius']; + } + + $padding = is_array($style['spacing']['padding'] ?? null) ? $style['spacing']['padding'] : array(); + foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { + if ( isset($padding[$side]) && '' !== (string) $padding[$side] ) { + $declarations[] = 'padding-' . $side . ':' . (string) $padding[$side]; + } + } + + $typography = is_array($style['typography'] ?? null) ? $style['typography'] : array(); + $typographyMap = array( + 'fontSize' => 'font-size', + 'fontWeight' => 'font-weight', + 'lineHeight' => 'line-height', + 'textTransform' => 'text-transform', + ); + foreach ( $typographyMap as $attrName => $cssName ) { + if ( isset($typography[$attrName]) && '' !== (string) $typography[$attrName] ) { + $declarations[] = $cssName . ':' . (string) $typography[$attrName]; + } + } + + return array( + 'classes' => implode(' ', $classes), + 'style' => implode(';', $declarations), + ); + } + private function mergeClassNames(string ...$classNames): string { $classes = array(); diff --git a/php-transformer/src/HtmlToBlocks/HtmlTransformer.php b/php-transformer/src/HtmlToBlocks/HtmlTransformer.php index cc786234..a5cd5278 100644 --- a/php-transformer/src/HtmlToBlocks/HtmlTransformer.php +++ b/php-transformer/src/HtmlToBlocks/HtmlTransformer.php @@ -3182,7 +3182,7 @@ private function interactiveAttributes(DOMElement $element): array private function structureSignals(DOMElement $element, array $attrs): array { $className = strtolower(trim($this->attr($element, 'class') . ' ' . (string) ($attrs['className'] ?? ''))); - $style = strtolower(trim($this->attr($element, 'style') . ';' . (string) ($attrs['style'] ?? ''))); + $style = strtolower(trim($this->attr($element, 'style') . ';' . (is_string($attrs['style'] ?? null) ? $attrs['style'] : ''))); $signals = array(); if ( preg_match('/(?:^|[\s_-])(?:card|feature|service|provider|resource|post|project|stat|badge|tile|panel|item)(?:$|[\s_-])/', $className) || 'article' === strtolower($element->tagName) ) { diff --git a/php-transformer/src/HtmlToBlocks/Patterns/ButtonStyleResolver.php b/php-transformer/src/HtmlToBlocks/Patterns/ButtonStyleResolver.php new file mode 100644 index 00000000..3e3d2a93 --- /dev/null +++ b/php-transformer/src/HtmlToBlocks/Patterns/ButtonStyleResolver.php @@ -0,0 +1,269 @@ +`/linked CSS rules the transformer already matches to the element) + * into native WordPress core/button block attributes. + * + * This keeps imported buttons rendering with their source colors and borders + * instead of falling back to the theme's default (grey) button styling, because + * the styling lives in canonical block attributes (style.color.*, style.border.*) + * rather than a non-canonical inline style string that WordPress drops on + * block recovery. + * + * The translation is theme-independent and keys only off the resolved + * declarations: + * - Filled buttons get style.color.background + style.color.text (+ border radius). + * - Outline/ghost buttons (transparent background) get style.border.* + style.color.text + * and never a background. + * A button whose resolved CSS carries no paintable colors/border stays default. + */ +final class ButtonStyleResolver +{ + /** + * Build native core/button style attributes from a resolved CSS string. + * + * @return array Either an empty array (no native styling) or + * an array with a `style` object suitable for the + * core/button block attributes. + */ + public function nativeAttributes(string $resolvedStyle): array + { + $declarations = $this->declarations($resolvedStyle); + if ( array() === $declarations ) { + return array(); + } + + $style = array(); + + $background = $this->backgroundColor($declarations); + $text = $this->color($declarations['color'] ?? ''); + if ( '' !== $background ) { + $style['color']['background'] = $background; + } + if ( '' !== $text ) { + $style['color']['text'] = $text; + } + + $border = $this->border($declarations); + if ( array() !== $border ) { + $style['border'] = $border; + } + + $padding = $this->padding($declarations); + if ( array() !== $padding ) { + $style['spacing']['padding'] = $padding; + } + + $typography = $this->typography($declarations); + if ( array() !== $typography ) { + $style['typography'] = $typography; + } + + if ( array() === $style ) { + return array(); + } + + return array( 'style' => $style ); + } + + /** + * Resolve the background color, ignoring transparent/none/gradient/image + * backgrounds so outline/ghost buttons never receive a paintable fill. + * + * @param array $declarations + */ + private function backgroundColor(array $declarations): string + { + $value = trim((string) ($declarations['background-color'] ?? '')); + if ( '' === $value ) { + // `background` shorthand: only treat it as a fill when it is a bare color. + $value = trim((string) ($declarations['background'] ?? '')); + if ( '' === $value || preg_match('/\b(?:url\s*\(|gradient\s*\()/i', $value) ) { + return ''; + } + // Take the first token of the shorthand as the candidate color. + $value = preg_split('/\s+/', $value)[0] ?? ''; + } + + return $this->color($value); + } + + /** + * @param array $declarations + * @return array + */ + private function border(array $declarations): array + { + $border = array(); + + // Longhand declarations win over the shorthand. + $shorthand = $this->parseBorderShorthand((string) ($declarations['border'] ?? '')); + + $width = trim((string) ($declarations['border-width'] ?? $shorthand['width'] ?? '')); + $style = strtolower(trim((string) ($declarations['border-style'] ?? $shorthand['style'] ?? ''))); + $color = $this->color((string) ($declarations['border-color'] ?? $shorthand['color'] ?? '')); + + // `border: 0` / `border: none` means no border at all. + $noBorder = 'none' === $style || ( '' !== $width && (float) $width === 0.0 && '' === $color && '' === $style ); + if ( ! $noBorder ) { + if ( '' !== $width && (float) $width !== 0.0 ) { + $border['width'] = $width; + } + if ( '' !== $style && 'none' !== $style ) { + $border['style'] = $style; + } + if ( '' !== $color ) { + $border['color'] = $color; + } + } + + $radius = trim((string) ($declarations['border-radius'] ?? '')); + if ( '' !== $radius ) { + $border['radius'] = $radius; + } + + return $border; + } + + /** + * @return array{width?: string, style?: string, color?: string} + */ + private function parseBorderShorthand(string $value): array + { + $value = trim($value); + if ( '' === $value ) { + return array(); + } + + $parsed = array(); + foreach ( preg_split('/\s+/', $value) ?: array() as $token ) { + $lower = strtolower($token); + if ( in_array($lower, array( 'none', 'hidden', 'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'inset', 'outset' ), true) ) { + $parsed['style'] = $lower; + continue; + } + if ( preg_match('/^[0-9.]+(?:px|em|rem|%|pt|vw|vh)?$/i', $token) || in_array($lower, array( 'thin', 'medium', 'thick' ), true) ) { + $parsed['width'] = $token; + continue; + } + if ( '' !== $this->color($token) ) { + $parsed['color'] = $token; + } + } + + return $parsed; + } + + /** + * @param array $declarations + * @return array + */ + private function padding(array $declarations): array + { + $shorthand = trim((string) ($declarations['padding'] ?? '')); + $sides = array( 'top' => '', 'right' => '', 'bottom' => '', 'left' => '' ); + + if ( '' !== $shorthand ) { + $parts = preg_split('/\s+/', $shorthand) ?: array(); + $count = count($parts); + if ( 1 === $count ) { + $sides = array( 'top' => $parts[0], 'right' => $parts[0], 'bottom' => $parts[0], 'left' => $parts[0] ); + } elseif ( 2 === $count ) { + $sides = array( 'top' => $parts[0], 'right' => $parts[1], 'bottom' => $parts[0], 'left' => $parts[1] ); + } elseif ( 3 === $count ) { + $sides = array( 'top' => $parts[0], 'right' => $parts[1], 'bottom' => $parts[2], 'left' => $parts[1] ); + } elseif ( $count >= 4 ) { + $sides = array( 'top' => $parts[0], 'right' => $parts[1], 'bottom' => $parts[2], 'left' => $parts[3] ); + } + } + + foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { + $longhand = trim((string) ($declarations[ 'padding-' . $side ] ?? '')); + if ( '' !== $longhand ) { + $sides[ $side ] = $longhand; + } + } + + return array_filter($sides, static fn (string $value): bool => '' !== trim($value)); + } + + /** + * @param array $declarations + * @return array + */ + private function typography(array $declarations): array + { + $typography = array(); + $map = array( + 'font-size' => 'fontSize', + 'font-weight' => 'fontWeight', + 'line-height' => 'lineHeight', + 'text-transform' => 'textTransform', + ); + + foreach ( $map as $cssName => $attrName ) { + $value = trim((string) ($declarations[ $cssName ] ?? '')); + if ( '' !== $value ) { + $typography[ $attrName ] = $value; + } + } + + return $typography; + } + + /** + * Return the value when it is a usable CSS color, otherwise an empty string. + */ + private function color(string $value): string + { + $value = trim($value); + if ( '' === $value ) { + return ''; + } + + $lower = strtolower($value); + if ( in_array($lower, array( 'transparent', 'none', 'inherit', 'initial', 'unset', 'revert', 'auto' ), true) ) { + return ''; + } + + if ( preg_match('/^#[0-9a-f]{3,8}$/i', $value) ) { + return $value; + } + if ( preg_match('/^(?:rgb|rgba|hsl|hsla)\s*\(/i', $value) ) { + return $value; + } + if ( 'currentcolor' === $lower ) { + return 'currentColor'; + } + // Named colors (e.g. white, navy). Reject anything with whitespace/symbols. + if ( preg_match('/^[a-z]+$/', $lower) ) { + return $value; + } + + return ''; + } + + /** + * @return array + */ + private function declarations(string $style): array + { + $declarations = array(); + foreach ( explode(';', $style) as $declaration ) { + if ( ! str_contains($declaration, ':') ) { + continue; + } + [ $name, $value ] = array_map('trim', explode(':', $declaration, 2)); + $name = strtolower($name); + if ( '' !== $name && '' !== $value ) { + $declarations[ $name ] = preg_replace('/\s+/', ' ', $value) ?? $value; + } + } + + return $declarations; + } +} diff --git a/php-transformer/src/HtmlToBlocks/Patterns/ButtonsPattern.php b/php-transformer/src/HtmlToBlocks/Patterns/ButtonsPattern.php index 8ae88171..bd973730 100644 --- a/php-transformer/src/HtmlToBlocks/Patterns/ButtonsPattern.php +++ b/php-transformer/src/HtmlToBlocks/Patterns/ButtonsPattern.php @@ -9,6 +9,13 @@ final class ButtonsPattern { private const BLOCK_LEVEL_LABEL_TAGS = 'address|article|aside|blockquote|div|dl|fieldset|figcaption|figure|footer|form|h[1-6]|header|hr|main|nav|ol|p|pre|section|table|ul'; + private readonly ButtonStyleResolver $styleResolver; + + public function __construct() + { + $this->styleResolver = new ButtonStyleResolver(); + } + /** * @param callable(DOMElement): array|null $fileBlockFromAnchor * @param callable(DOMElement): array $presentationAttributes @@ -104,10 +111,22 @@ private function buttonText(string $html): string private function buttonPresentationAttributes(DOMElement $element, callable $presentationAttributes): array { $attrs = $presentationAttributes($element); - if ( $this->hasOutlineSignal($element, (string) ($attrs['style'] ?? '')) ) { + $resolvedStyle = (string) ($attrs['style'] ?? ''); + if ( $this->hasOutlineSignal($element, $resolvedStyle) ) { $attrs['className'] = trim((string) ($attrs['className'] ?? '') . ' is-style-outline'); } + // Translate the resolved source CSS (inline style merged with the matched + //
Buy now
" + }, + "expected_blocks": [ + { "path": "blocks.0", "name": "core/buttons" }, + { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Buy now", "url": "/buy", "className": "btn btn-primary", "style": { "color": { "background": "#13314f", "text": "#ffffff" }, "border": { "radius": "6px" }, "spacing": { "padding": { "top": "12px", "right": "24px", "bottom": "12px", "left": "24px" } } } } } + ], + "expected_fallbacks": [], + "expect": [ + { "path": "status", "assert": "equals", "value": "success" }, + { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link has-text-color has-background wp-element-button btn btn-primary\"" }, + { "path": "serialized_blocks", "assert": "contains", "value": "style=\"color:#ffffff;background-color:#13314f;border-radius:6px;padding-top:12px;padding-right:24px;padding-bottom:12px;padding-left:24px\"" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "is-style-outline" } + ] +} diff --git a/php-transformer/tests/fixtures/parity/html-button-style-fidelity-outline-from-css.json b/php-transformer/tests/fixtures/parity/html-button-style-fidelity-outline-from-css.json new file mode 100644 index 00000000..0e2b44b3 --- /dev/null +++ b/php-transformer/tests/fixtures/parity/html-button-style-fidelity-outline-from-css.json @@ -0,0 +1,31 @@ +{ + "schema": "blocks-engine/php-transformer/parity-fixture/v1", + "name": "html-button-style-fidelity-outline-from-css", + "description": "Outline/ghost CTA button whose styling lives only in page
Learn more
" + }, + "expected_blocks": [ + { "path": "blocks.0", "name": "core/buttons" }, + { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Learn more", "url": "/learn", "className": "btn btn-ghost is-style-outline", "style": { "color": { "text": "#135e96" }, "border": { "width": "2px", "style": "solid", "color": "#135e96", "radius": "8px" }, "spacing": { "padding": { "top": "12px", "right": "24px", "bottom": "12px", "left": "24px" } } } } } + ], + "expected_fallbacks": [], + "expect": [ + { "path": "status", "assert": "equals", "value": "success" }, + { "path": "serialized_blocks", "assert": "contains", "value": "
" }, + { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link has-text-color has-border-color wp-element-button btn btn-ghost is-style-outline\"" }, + { "path": "serialized_blocks", "assert": "contains", "value": "style=\"color:#135e96;border-color:#135e96;border-width:2px;border-style:solid;border-radius:8px;padding-top:12px;padding-right:24px;padding-bottom:12px;padding-left:24px\"" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "background-color" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "has-background" } + ] +} diff --git a/php-transformer/tests/fixtures/parity/html-button-style-fidelity-unstyled-default.json b/php-transformer/tests/fixtures/parity/html-button-style-fidelity-unstyled-default.json new file mode 100644 index 00000000..b6fb40cb --- /dev/null +++ b/php-transformer/tests/fixtures/parity/html-button-style-fidelity-unstyled-default.json @@ -0,0 +1,30 @@ +{ + "schema": "blocks-engine/php-transformer/parity-fixture/v1", + "name": "html-button-style-fidelity-unstyled-default", + "description": "Negative case: a button-class anchor with no resolvable source color/border CSS is not fabricated with colors. It converts to a default core/button with no style attribute, has-background, or inline color styling.", + "source_reference": { + "repo": "php-transformer", + "path": "tests/fixtures/parity/html-button-style-fidelity-unstyled-default.json", + "notes": "Generic style-fidelity negative fixture: unstyled buttons stay default (issue #233)." + }, + "legacy_comparison": { + "skip": true, + "reason": "New native button style-fidelity behavior has no legacy equivalent." + }, + "operation": "html_transformer.transform", + "input": { + "content": "
Go now
" + }, + "expected_blocks": [ + { "path": "blocks.0", "name": "core/buttons" }, + { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Go now", "url": "/go", "className": "btn cta-link" } } + ], + "expected_fallbacks": [], + "expect": [ + { "path": "status", "assert": "equals", "value": "success" }, + { "path": "serialized_blocks", "assert": "contains", "value": "" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "has-background" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "has-text-color" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "style=" } + ] +} diff --git a/php-transformer/tests/fixtures/parity/html-cta-container-static-css-button-style-signals.json b/php-transformer/tests/fixtures/parity/html-cta-container-static-css-button-style-signals.json index e0a5220b..0829135a 100644 --- a/php-transformer/tests/fixtures/parity/html-cta-container-static-css-button-style-signals.json +++ b/php-transformer/tests/fixtures/parity/html-cta-container-static-css-button-style-signals.json @@ -17,16 +17,16 @@ }, "expected_blocks": [ { "path": "blocks.0", "name": "core/buttons" }, - { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Book now", "url": "/book", "className": "primary", "style": "background-color:#2563eb;color:#fff;border:2px solid #2563eb;border-radius:999px;padding:14px 28px;font-weight:700" } }, - { "path": "blocks.0.innerBlocks.1", "name": "core/button", "attrs": { "text": "Learn more", "url": "/learn", "className": "secondary is-style-outline", "style": "background-color:transparent;color:#2563eb;border:2px solid currentColor;border-radius:999px;padding:14px 28px;font-weight:700" } } + { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Book now", "url": "/book", "className": "primary", "style": { "color": { "background": "#2563eb", "text": "#fff" }, "border": { "width": "2px", "style": "solid", "color": "#2563eb", "radius": "999px" }, "spacing": { "padding": { "top": "14px", "right": "28px", "bottom": "14px", "left": "28px" } }, "typography": { "fontWeight": "700" } } } }, + { "path": "blocks.0.innerBlocks.1", "name": "core/button", "attrs": { "text": "Learn more", "url": "/learn", "className": "secondary is-style-outline", "style": { "color": { "text": "#2563eb" }, "border": { "width": "2px", "style": "solid", "color": "currentColor", "radius": "999px" }, "spacing": { "padding": { "top": "14px", "right": "28px", "bottom": "14px", "left": "28px" } }, "typography": { "fontWeight": "700" } } } } ], "expected_fallbacks": [], "expect": [ { "path": "status", "assert": "equals", "value": "success" }, - { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link wp-element-button primary\"" }, - { "path": "serialized_blocks", "assert": "contains", "value": "background-color:#2563eb;color:#fff;border:2px solid #2563eb;border-radius:999px;padding:14px 28px;font-weight:700" }, + { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link has-text-color has-background has-border-color wp-element-button primary\"" }, + { "path": "serialized_blocks", "assert": "contains", "value": "style=\"color:#fff;background-color:#2563eb;border-color:#2563eb;border-width:2px;border-style:solid;border-radius:999px;padding-top:14px;padding-right:28px;padding-bottom:14px;padding-left:28px;font-weight:700\"" }, { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button is-style-outline\"" }, - { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link wp-element-button secondary is-style-outline\"" }, - { "path": "serialized_blocks", "assert": "contains", "value": "background-color:transparent;color:#2563eb;border:2px solid currentColor;border-radius:999px;padding:14px 28px;font-weight:700" } + { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link has-text-color has-border-color wp-element-button secondary is-style-outline\"" }, + { "path": "serialized_blocks", "assert": "contains", "value": "style=\"color:#2563eb;border-color:currentColor;border-width:2px;border-style:solid;border-radius:999px;padding-top:14px;padding-right:28px;padding-bottom:14px;padding-left:28px;font-weight:700\"" } ] } diff --git a/php-transformer/tests/fixtures/parity/html-source-styled-button-preserves-style.json b/php-transformer/tests/fixtures/parity/html-source-styled-button-preserves-style.json index 7e1634f4..b20ab17e 100644 --- a/php-transformer/tests/fixtures/parity/html-source-styled-button-preserves-style.json +++ b/php-transformer/tests/fixtures/parity/html-source-styled-button-preserves-style.json @@ -17,13 +17,14 @@ }, "expected_blocks": [ { "path": "blocks.0", "name": "core/buttons" }, - { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Buy now", "className": "checkout-button", "style": "background-color:#111827;color:#f9fafb;border:0;border-radius:6px;padding:10px 20px;font-weight:800;text-transform:uppercase" } } + { "path": "blocks.0.innerBlocks.0", "name": "core/button", "attrs": { "text": "Buy now", "className": "checkout-button", "style": { "color": { "background": "#111827", "text": "#f9fafb" }, "border": { "radius": "6px" }, "spacing": { "padding": { "top": "10px", "right": "20px", "bottom": "10px", "left": "20px" } }, "typography": { "fontWeight": "800", "textTransform": "uppercase" } } } } ], "expected_fallbacks": [], "expect": [ { "path": "status", "assert": "equals", "value": "success" }, - { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link wp-element-button checkout-button\"" }, - { "path": "serialized_blocks", "assert": "contains", "value": "style=\"background-color:#111827;color:#f9fafb;border:0;border-radius:6px;padding:10px 20px;font-weight:800;text-transform:uppercase\"" }, - { "path": "serialized_blocks", "assert": "not_contains", "value": "background-color:#f7f7f7" } + { "path": "serialized_blocks", "assert": "contains", "value": "class=\"wp-block-button__link has-text-color has-background wp-element-button checkout-button\"" }, + { "path": "serialized_blocks", "assert": "contains", "value": "style=\"color:#f9fafb;background-color:#111827;border-radius:6px;padding-top:10px;padding-right:20px;padding-bottom:10px;padding-left:20px;font-weight:800;text-transform:uppercase\"" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "background-color:#f7f7f7" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "border-width" } ] }