PluginProbe
Elementor Website Builder – more than just a page builder / 3.25.2
Elementor Website Builder – more than just a page builder v3.25.2
4.3.2 4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 All 455 releases
← All changes | modules/atomic-widgets/styles/styles-renderer.php +86 -76 4.1.0-beta1 → 3.25.2 View file →
@@ -1,55 +1,47 @@
1 1 <?php
2 2
3 3 namespace Elementor\Modules\AtomicWidgets\Styles;
4 4
5 -use Elementor\Core\Utils\Collection;
6 -use Elementor\Modules\AtomicWidgets\Module;
7 -use Elementor\Plugin;
8 -use Elementor\Utils;
9 -use Elementor\Modules\AtomicWidgets\PropsResolver\Render_Props_Resolver;
5 +use Elementor\Modules\AtomicWidgets\Base\Style_Transformer_Base;
10 6
11 7 class Styles_Renderer {
12 - const DEFAULT_SELECTOR_PREFIX = '.elementor';
13 8
14 9 /**
15 - * @var array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}>
10 + * @var array<string, Style_Transformer_Base> $transformers
16 11 */
12 + private array $transformers;
13 +
14 + /**
15 + * @var array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}> $breakpoints
16 + */
17 17 private array $breakpoints;
18 18
19 - private $on_prop_transform;
20 -
21 - private string $selector_prefix;
22 -
23 19 /**
24 - * @param array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}> $breakpoints
25 - * @param string $selector_prefix
20 + * Styles_Renderer constructor.
21 + *
22 + * @param array{
23 + * transformers: array<string, Style_Transformer_Base>,
24 + * breakpoints: array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}>
25 + * } $config
26 26 */
27 - private function __construct( array $breakpoints, string $selector_prefix = self::DEFAULT_SELECTOR_PREFIX ) {
28 - $this->breakpoints = $breakpoints;
29 - $this->selector_prefix = $selector_prefix;
27 + public function __construct( array $config ) {
28 + $this->transformers = $config['transformers'];
29 + $this->breakpoints = $config['breakpoints'];
30 30 }
31 31
32 - public static function make( array $breakpoints, string $selector_prefix = self::DEFAULT_SELECTOR_PREFIX ): self {
33 - return new self( $breakpoints, $selector_prefix );
34 - }
35 -
36 32 /**
37 33 * Render the styles to a CSS string.
38 34 *
39 - * Styles format:
40 - * array<int, array{
35 + * @param array<int, array{
41 36 * id: string,
42 37 * type: string,
43 - * cssName: string | null,
44 38 * variants: array<int, array{
45 39 * props: array<string, mixed>,
46 40 * meta: array<string, mixed>
47 41 * }>
48 - * }>
42 + * }> $styles Array of style definitions.
49 43 *
50 - * @param array $styles Array of style definitions.
51 - *
52 44 * @return string Rendered CSS string.
53 45 */
54 46 public function render( array $styles ): string {
55 47 $css_style = [];
@@ -61,14 +53,8 @@
61 53
62 54 return implode( '', $css_style );
63 55 }
64 56
65 - public function on_prop_transform( callable $callback ): self {
66 - $this->on_prop_transform = $callback;
67 -
68 - return $this;
69 - }
70 -
71 57 private function style_definition_to_css_string( array $style ): string {
72 58 $base_selector = $this->get_base_selector( $style );
73 59
74 60 if ( ! $base_selector ) {
@@ -98,17 +84,9 @@
98 84 isset( $style_def['id'] ) &&
99 85 isset( $map[ $style_def['type'] ] ) &&
100 86 $style_def['id']
101 87 ) {
102 - $type = $map[ $style_def['type'] ];
103 - $name = $style_def['cssName'] ?? $style_def['id'];
104 -
105 - $selector_parts = array_filter( [
106 - $this->selector_prefix,
107 - "{$type}{$name}",
108 - ] );
109 -
110 - return implode( ' ', $selector_parts );
88 + return $map[ $style_def['type'] ] . $style_def['id'];
111 89 }
112 90
113 91 return null;
114 92 }
@@ -113,22 +91,18 @@
113 91 return null;
114 92 }
115 93
116 94 private function variant_to_css_string( string $base_selector, array $variant ): string {
117 - $css = $this->props_to_css_string( $variant['props'] ) ?? '';
118 - $custom_css = $this->custom_css_to_css_string( $variant['custom_css'] ?? null );
95 + $css = $this->props_to_css_string( $variant['props'] );
119 96
120 - if ( ! $css && ! $custom_css ) {
97 + if ( ! $css ) {
121 98 return '';
122 99 }
123 100
124 - if ( isset( $variant['meta']['state'] ) ) {
125 - $selector = Style_States::get_selector_with_state( $base_selector, $variant['meta']['state'] );
126 - } else {
127 - $selector = $base_selector;
128 - }
101 + $state = isset( $variant['meta']['state'] ) ? ':' . $variant['meta']['state'] : '';
102 + $selector = $base_selector . $state;
129 103
130 - $style_declaration = $selector . '{' . $css . $custom_css . '}';
104 + $style_declaration = $selector . '{' . $css . '}';
131 105
132 106 if ( isset( $variant['meta']['breakpoint'] ) ) {
133 107 $style_declaration = $this->wrap_with_media_query( $variant['meta']['breakpoint'], $style_declaration );
134 108 }
@@ -135,28 +109,25 @@
135 109
136 110 return $style_declaration;
137 111 }
138 112
113 + private function props_to_css_string( array $props ): string {
114 + $css = [];
139 115
140 - private function props_to_css_string( array $props ): string {
141 - $schema = Style_Schema::get();
116 + foreach ( $props as $prop => $raw_value ) {
117 + $prop = $this->camel_case_to_dash( $prop );
118 + $value = $this->transform_value( $raw_value );
142 119
143 - return Collection::make( Render_Props_Resolver::for_styles()->resolve( $schema, $props ) )
144 - ->filter()
145 - ->map( function ( $value, $prop ) {
146 - if ( $this->on_prop_transform ) {
147 - call_user_func( $this->on_prop_transform, $prop, $value );
148 - }
120 + if ( $prop && $value ) {
121 + $css[] = $prop . ':' . $value;
122 + }
123 + }
149 124
150 - return $prop . ':' . $value . ';';
151 - } )
152 - ->implode( '' );
125 + return implode( ';', $css );
153 126 }
154 127
155 - private function custom_css_to_css_string( ?array $custom_css ): string {
156 - return ! empty( $custom_css['raw'] )
157 - ? Utils::decode_string( $custom_css['raw'], '' ) . '\n'
158 - : '';
128 + private function camel_case_to_dash( string $str ): string {
129 + return strtolower( preg_replace( '/([a-zA-Z])(?=[A-Z])/', '$1-', $str ) );
159 130 }
160 131
161 132 private function wrap_with_media_query( string $breakpoint_id, string $css ): string {
162 133 if ( ! isset( $this->breakpoints[ $breakpoint_id ] ) ) {
@@ -167,26 +138,65 @@
167 138 if ( isset( $breakpoint['is_enabled'] ) && ! $breakpoint['is_enabled'] ) {
168 139 return '';
169 140 }
170 141
171 - $query = $this->get_media_query( $this->breakpoints[ $breakpoint_id ] );
142 + $size = $this->get_breakpoint_size( $this->breakpoints[ $breakpoint_id ] );
172 143
173 - return $query ? $query . '{' . $css . '}' : $css;
144 + return $size ? '@media(' . $size . '){' . $css . '}' : $css;
174 145 }
175 146
176 - public static function get_media_query( $breakpoint ): ?string {
177 - if ( isset( $breakpoint['is_enabled'] ) && ! $breakpoint['is_enabled'] ) {
178 - return null;
147 + private function get_breakpoint_size( array $breakpoint ): ?string {
148 + $bound = 'min' === $breakpoint['direction'] ? 'min-width' : 'max-width';
149 + $width = $breakpoint['value'] . 'px';
150 +
151 + return "{$bound}:{$width}";
152 + }
153 +
154 + private function transform_value( $value ): ?string {
155 + if ( is_string( $value ) ) {
156 + return $value;
179 157 }
180 158
181 - $size = self::get_breakpoint_size( $breakpoint );
159 + if ( ! $this->is_transformable( $value ) ) {
160 + return 'unset';
161 + }
182 162
183 - return $size ? '@media(' . $size . ')' : null;
163 + $transformer = $this->get_transformer( $value['$$type'] );
164 +
165 + if ( ! $transformer ) {
166 + return 'unset';
167 + }
168 +
169 + try {
170 + $transformed = $transformer->transform(
171 + $value['value'],
172 + fn( $value ) => $this->transform_value( $value )
173 + );
174 +
175 + return $this->transform_value( $transformed );
176 +
177 + } catch ( \Exception $e ) {
178 + return 'unset';
179 + }
184 180 }
185 181
186 - private static function get_breakpoint_size( array $breakpoint ): ?string {
187 - $bound = 'min' === $breakpoint['direction'] ? 'min-width' : 'max-width';
188 - $width = $breakpoint['value'] . 'px';
182 + private function is_transformable( $value ): bool {
183 + return (
184 + isset( $value['$$type'], $value['value'] ) &&
185 + is_string( $value['$$type'] )
186 + );
187 + }
189 188
190 - return "{$bound}:{$width}";
189 + private function get_transformer( $type ): ?Style_Transformer_Base {
190 + if ( ! isset( $this->transformers[ $type ] ) ) {
191 + return null;
192 + }
193 +
194 + $transformer = $this->transformers[ $type ];
195 +
196 + if ( ! $transformer instanceof Style_Transformer_Base ) {
197 + return null;
198 + }
199 +
200 + return $transformer;
191 201 }
192 202 }