PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.13.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.13.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
← All changes | includes/classes/global-css-generator.php +262 -0 2.7.72.13.0 View file →
@@ -1,0 +1,262 @@
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 + $bp = \ABlocks\Helper::get_breakpoints();
102 + switch ( $media_query ) {
103 + case 'tablet':
104 + return $bp['tablet'] . 'px';
105 + case 'mobile':
106 + return $bp['mobile'] . 'px';
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 ) {
124 + // Safety net for styles that bypass the Typography control and set a
125 + // bare family name directly. FontStack leaves finished values alone.
126 + $value = FontStack::build( $value );
127 + }
128 + // Trim value to avoid whitespace-only entries
129 + $trimmed = trim( $value );
130 + // // Remove if empty, or if it matches only a unit (like 'px', '%', 'em') without any number
131 + if ( $trimmed === '' || preg_match( '/^(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc|%)$/i', $trimmed ) ) {
132 + continue;
133 + }
134 +
135 + $styles[ $prop ] = $trimmed;
136 + }
137 +
138 + return $styles;
139 + }
140 + private function filter_responsive_styles( $base_styles, $responsive_styles ) {
141 + if ( empty( $responsive_styles ) || ! is_array( $responsive_styles ) ) {
142 + return [];
143 + }
144 +
145 + $difference = [];
146 +
147 + foreach ( $responsive_styles as $prop => $value ) {
148 + $trimmed = trim( $value );
149 +
150 + // // Remove if empty, or if it matches only a unit (like 'px', '%', 'em') without any number
151 + if ( $trimmed === '' || preg_match( '/^(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc|%)$/i', $trimmed ) ) {
152 + continue;
153 + }
154 +
155 + // Only include if the value is different from base styles
156 + if ( ! isset( $base_styles[ $prop ] ) || $base_styles[ $prop ] !== $trimmed ) {
157 + $difference[ $prop ] = $trimmed;
158 + }
159 + }
160 +
161 + return $difference;
162 + }
163 +
164 +
165 + public function get_font_family_css( string $font_name, string $category = '' ): string {
166 + // Kept for back-compat; the stack is built centrally now.
167 + return FontStack::build( $font_name );
168 + }
169 +
170 +
171 + // Global CSS necessary method
172 + public function get_body_css( $attributes, $device = '' ) {
173 + $css = [];
174 + if ( ! empty( $attributes ['global_body_text_color'] ) ) {
175 + $css['color'] = $attributes ['global_body_text_color'];
176 + }
177 +
178 + return array_merge( $css, Typography::get_css( $attributes['global_body_typography'], '', $device ) );
179 + }
180 + public function get_body_paragraph_css( $attributes, $device = '' ) {
181 + $css = [];
182 + if ( ! empty( $attributes ['global_body_paragraph_space'] ) ) {
183 + return Range::get_css([
184 + 'attributeValue' => (array) $attributes ['global_body_paragraph_space'],
185 + 'isResponsive' => true,
186 + 'defaultValue' => '',
187 + 'defaultValueTablet' => '',
188 + 'defaultValueMobile' => '',
189 + 'hasUnit' => true,
190 + 'unitDefaultValue' => 'px',
191 + 'property' => 'margin-block-end'
192 + ]);
193 + }
194 + return $css;
195 + }
196 + public function get_body_anchor_css( $attributes, $device = '' ) {
197 + $css = [];
198 + if ( ! empty( $attributes ['global_link_color'] ) ) {
199 + $css['color'] = $attributes ['global_link_color'];
200 + }
201 +
202 + return array_merge( $css, Typography::get_css( $attributes['global_link_typography'], '', $device ) );
203 + }
204 + public function get_body_anchor_hover_css( $attributes, $device = '' ) {
205 + $css = [];
206 + if ( ! empty( $attributes ['global_link_hover_color'] ) ) {
207 + $css['color'] = $attributes ['global_link_hover_color'];
208 + }
209 +
210 + return array_merge( $css, Typography::get_css( $attributes['global_link_hover_typography'], '', $device ) );
211 + }
212 + public function get_global_h1_css( $attributes, $device = '' ) {
213 + $css = [];
214 + if ( ! empty( $attributes ['global_h1_color'] ) ) {
215 + $css['color'] = $attributes ['global_h1_color'];
216 + }
217 +
218 + return array_merge( $css, Typography::get_css( $attributes['global_h1_typography'], '', $device ) );
219 + }
220 + public function get_global_h2_css( $attributes, $device = '' ) {
221 + $css = [];
222 + if ( ! empty( $attributes ['global_h2_color'] ) ) {
223 + $css['color'] = $attributes ['global_h2_color'];
224 + }
225 +
226 + return array_merge( $css, Typography::get_css( $attributes['global_h2_typography'], '', $device ) );
227 + }
228 + public function get_global_h3_css( $attributes, $device = '' ) {
229 + $css = [];
230 + if ( ! empty( $attributes ['global_h3_color'] ) ) {
231 + $css['color'] = $attributes ['global_h3_color'];
232 + }
233 +
234 + return array_merge( $css, Typography::get_css( $attributes['global_h3_typography'], '', $device ) );
235 + }
236 + public function get_global_h4_css( $attributes, $device = '' ) {
237 + $css = [];
238 + if ( ! empty( $attributes ['global_h4_color'] ) ) {
239 + $css['color'] = $attributes ['global_h4_color'];
240 + }
241 +
242 + return array_merge( $css, Typography::get_css( $attributes['global_h4_typography'], '', $device ) );
243 + }
244 + public function get_global_h5_css( $attributes, $device = '' ) {
245 + $css = [];
246 + if ( ! empty( $attributes ['global_h5_color'] ) ) {
247 + $css['color'] = $attributes ['global_h5_color'];
248 + }
249 +
250 + return array_merge( $css, Typography::get_css( $attributes['global_h5_typography'], '', $device ) );
251 + }
252 + public function get_global_h6_css( $attributes, $device = '' ) {
253 + $css = [];
254 + if ( ! empty( $attributes ['global_h6_color'] ) ) {
255 + $css['color'] = $attributes ['global_h6_color'];
256 + }
257 +
258 + return array_merge( $css, Typography::get_css( $attributes['global_h6_typography'], '', $device ) );
259 + }
260 +
261 +}
262 +