PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.8.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.8.0
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 1.2.0 1.2.1 All 78 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.8.0, at includes/classes/global-css-generator.php

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