PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.11.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.11.0
2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 All 80 releases
ablocks / includes / classes / global-css-generator.php

global-css-generator.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder 2.11.0, at includes/classes/global-css-generator.php

262 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace ABlocks\Classes;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 use ABlocks\Classes\AssetsGenerator;
9 use ABlocks\Classes\FontStack;
10 use ABlocks\Controls\Typography;
11 use ABlocks\Controls\Range;
12
13 class GlobalCssGenerator {
14 private $custom_css = '';
15 private $parent_class;
16 private $class_styles = [];
17
18 public function __construct( $attributes = [] ) {
19 $this->parent_class = '';
20 if ( isset( $attributes['_custom_css'] ) ) {
21 $this->custom_css = $attributes['_custom_css'];
22 }
23 }
24
25 public function add_class_styles( $class_name, $desktop_styles, $tablet_styles = [], $mobile_styles = [] ) {
26 $this->class_styles[] = [
27 'class_name' => $class_name,
28 'desktop_styles' => $desktop_styles,
29 'tablet_styles' => $tablet_styles,
30 'mobile_styles' => $mobile_styles
31 ];
32 }
33
34 public function generate_css() {
35 $css_output = '';
36
37 foreach ( $this->class_styles as $class_style ) {
38 $desktop_styles = $this->remove_empty_css( $class_style['desktop_styles'] );
39 $tablet_styles = $this->filter_responsive_styles( $desktop_styles, $class_style['tablet_styles'] );
40 $mobile_styles = $this->filter_responsive_styles( array_merge( $desktop_styles, $tablet_styles ), $class_style['mobile_styles'] );
41
42 $desktop_raw = $this->generate_css_for_media_query( 'desktop', $desktop_styles );
43 $tablet_raw = $this->generate_css_for_media_query( 'tablet', $tablet_styles );
44 $mobile_raw = $this->generate_css_for_media_query( 'mobile', $mobile_styles );
45
46 $desktop_css = AssetsGenerator::minify_css( $desktop_raw );
47 $tablet_css = AssetsGenerator::minify_css( $tablet_raw );
48 $mobile_css = AssetsGenerator::minify_css( $mobile_raw );
49
50 $parent_selector = $this->get_parent_selector( $class_style['class_name'] );
51 $css_blocks = [];
52
53 $addToCssBlocks = function ( $mediaQuery, $max_width, $css ) use ( &$css_blocks, $parent_selector ) {
54 if ( ! empty( $css ) ) {
55 $css_blocks[] = ( '' !== $mediaQuery )
56 ? "@media screen and (max-width: $max_width) {\n$parent_selector {\n$css\n}\n}"
57 : "$parent_selector {\n$css\n}";
58 }
59 };
60
61 // Always add desktop CSS
62 $addToCssBlocks( '', '', $desktop_css );
63
64 // Only add tablet CSS if it differs from desktop
65 if ( $tablet_raw !== $desktop_raw ) {
66 $addToCssBlocks( 'tablet', $this->get_breakpoint( 'tablet' ), $tablet_css );
67 }
68
69 // Only add mobile CSS if it differs from desktop AND tablet
70 if ( $mobile_raw !== $tablet_raw ) {
71 $addToCssBlocks( 'mobile', $this->get_breakpoint( 'mobile' ), $mobile_css );
72 }
73
74 $css_output .= implode( "\n\n", $css_blocks ) . "\n\n";
75 }//end foreach
76
77 $css_output .= $this->get_custom_css();
78
79 return preg_replace( '/\s+/', ' ', $css_output );
80 }
81
82 public function get_custom_css() {
83 return preg_replace( '/\bselector\b/', $this->parent_class, $this->custom_css );
84 }
85 public function generate_css_for_media_query( $media_query, $styles ) {
86 if ( empty( $styles ) ) {
87 return '';
88 }
89 $css_string = implode("\n", array_map(
90 function ( $property, $value ) {
91 return "$property: $value;";
92 },
93 array_keys( $styles ),
94 $styles
95 ));
96
97 return $css_string . "\n";
98 }
99
100 public function get_breakpoint( $media_query ) {
101 switch ( $media_query ) {
102 case 'tablet':
103 return '800px';
104 case 'mobile':
105 return '480px';
106 default:
107 return '1200px';
108 }
109 }
110
111 public function get_parent_selector( $class_name ) {
112 return $this->parent_class ? str_replace( '{{WRAPPER}}', $this->parent_class, $class_name ) : $class_name;
113 }
114 private function remove_empty_css( $base_styles ) {
115 if ( empty( $base_styles ) || ! is_array( $base_styles ) || ( is_array( $base_styles ) && ! count( $base_styles ) ) ) {
116 return [];
117 }
118
119 $styles = [];
120
121 foreach ( $base_styles as $prop => $value ) {
122 if ( 'font-family' === $prop ) {
123 // Safety net for styles that bypass the Typography control and set a
124 // bare family name directly. FontStack leaves finished values alone.
125 $value = FontStack::build( $value );
126 }
127 // Trim value to avoid whitespace-only entries
128 $trimmed = trim( $value );
129 // // Remove if empty, or if it matches only a unit (like 'px', '%', 'em') without any number
130 if ( $trimmed === '' || preg_match( '/^(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc|%)$/i', $trimmed ) ) {
131 continue;
132 }
133
134 $styles[ $prop ] = $trimmed;
135 }
136
137 return $styles;
138 }
139 private function filter_responsive_styles( $base_styles, $responsive_styles ) {
140 if ( empty( $responsive_styles ) || ! is_array( $responsive_styles ) ) {
141 return [];
142 }
143
144 $difference = [];
145
146 foreach ( $responsive_styles as $prop => $value ) {
147 $trimmed = trim( $value );
148
149 // // Remove if empty, or if it matches only a unit (like 'px', '%', 'em') without any number
150 if ( $trimmed === '' || preg_match( '/^(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc|%)$/i', $trimmed ) ) {
151 continue;
152 }
153
154 // Only include if the value is different from base styles
155 if ( ! isset( $base_styles[ $prop ] ) || $base_styles[ $prop ] !== $trimmed ) {
156 $difference[ $prop ] = $trimmed;
157 }
158 }
159
160 return $difference;
161 }
162
163
164 public function get_font_family_css( string $font_name, string $category = '' ): string {
165 // Kept for back-compat; the stack is built centrally now.
166 return FontStack::build( $font_name );
167 }
168
169
170 // Global CSS necessary method
171 public function get_body_css( $attributes, $device = '' ) {
172 $css = [];
173 if ( ! empty( $attributes ['global_body_text_color'] ) ) {
174 $css['color'] = $attributes ['global_body_text_color'];
175 }
176
177 return array_merge( $css, Typography::get_css( $attributes['global_body_typography'], '', $device ) );
178 }
179 public function get_body_paragraph_css( $attributes, $device = '' ) {
180 $css = [];
181 if ( ! empty( $attributes ['global_body_paragraph_space'] ) ) {
182 return Range::get_css([
183 'attributeValue' => (array) $attributes ['global_body_paragraph_space'],
184 'isResponsive' => true,
185 'defaultValue' => '',
186 'defaultValueTablet' => '',
187 'defaultValueMobile' => '',
188 'hasUnit' => true,
189 'unitDefaultValue' => 'px',
190 'property' => 'margin-block-end'
191 ]);
192 }
193 return $css;
194 }
195 public function get_body_anchor_css( $attributes, $device = '' ) {
196 $css = [];
197 if ( ! empty( $attributes ['global_link_color'] ) ) {
198 $css['color'] = $attributes ['global_link_color'];
199 }
200
201 return array_merge( $css, Typography::get_css( $attributes['global_link_typography'], '', $device ) );
202 }
203 public function get_body_anchor_hover_css( $attributes, $device = '' ) {
204 $css = [];
205 if ( ! empty( $attributes ['global_link_hover_color'] ) ) {
206 $css['color'] = $attributes ['global_link_hover_color'];
207 }
208
209 return array_merge( $css, Typography::get_css( $attributes['global_link_hover_typography'], '', $device ) );
210 }
211 public function get_global_h1_css( $attributes, $device = '' ) {
212 $css = [];
213 if ( ! empty( $attributes ['global_h1_color'] ) ) {
214 $css['color'] = $attributes ['global_h1_color'];
215 }
216
217 return array_merge( $css, Typography::get_css( $attributes['global_h1_typography'], '', $device ) );
218 }
219 public function get_global_h2_css( $attributes, $device = '' ) {
220 $css = [];
221 if ( ! empty( $attributes ['global_h2_color'] ) ) {
222 $css['color'] = $attributes ['global_h2_color'];
223 }
224
225 return array_merge( $css, Typography::get_css( $attributes['global_h2_typography'], '', $device ) );
226 }
227 public function get_global_h3_css( $attributes, $device = '' ) {
228 $css = [];
229 if ( ! empty( $attributes ['global_h3_color'] ) ) {
230 $css['color'] = $attributes ['global_h3_color'];
231 }
232
233 return array_merge( $css, Typography::get_css( $attributes['global_h3_typography'], '', $device ) );
234 }
235 public function get_global_h4_css( $attributes, $device = '' ) {
236 $css = [];
237 if ( ! empty( $attributes ['global_h4_color'] ) ) {
238 $css['color'] = $attributes ['global_h4_color'];
239 }
240
241 return array_merge( $css, Typography::get_css( $attributes['global_h4_typography'], '', $device ) );
242 }
243 public function get_global_h5_css( $attributes, $device = '' ) {
244 $css = [];
245 if ( ! empty( $attributes ['global_h5_color'] ) ) {
246 $css['color'] = $attributes ['global_h5_color'];
247 }
248
249 return array_merge( $css, Typography::get_css( $attributes['global_h5_typography'], '', $device ) );
250 }
251 public function get_global_h6_css( $attributes, $device = '' ) {
252 $css = [];
253 if ( ! empty( $attributes ['global_h6_color'] ) ) {
254 $css['color'] = $attributes ['global_h6_color'];
255 }
256
257 return array_merge( $css, Typography::get_css( $attributes['global_h6_typography'], '', $device ) );
258 }
259
260 }
261
262