PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 2.25.0
Block Animations, Motion & Scroll Effects – Ghost Kit v2.25.0
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / classes / class-assets.php

class-assets.php in Block Animations, Motion & Scroll Effects – Ghost Kit 2.25.0, at classes/class-assets.php

691 lines 29.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Assets static and dynamic.
4 *
5 * @package ghostkit
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Class GhostKit_Assets
14 */
15 class GhostKit_Assets {
16 /**
17 * List with stored assets.
18 *
19 * @var array
20 */
21 private static $stored_assets = array(
22 'script' => array(),
23 'style' => array(),
24 'custom-css' => array(),
25 );
26
27 /**
28 * Already added custom assets in head.
29 *
30 * @var boolean
31 */
32 private static $already_added_custom_assets = false;
33
34 /**
35 * List with assets to skip from Autoptimize when CSS generated.
36 *
37 * @var array
38 */
39 protected static $skip_from_autoptimize = array(
40 'ghostkit-blocks-content-custom-css',
41 'ghostkit-blocks-widget-custom-css',
42 );
43
44 /**
45 * Visual_Portfolio_Extend constructor.
46 */
47 public function __construct() {
48 add_action( 'init', array( $this, 'register_scripts' ) );
49 add_action( 'plugins_loaded', array( $this, 'enqueue_scripts_action' ), 11 );
50 add_action( 'ghostkit_parse_blocks', array( $this, 'maybe_enqueue_blocks_assets' ), 11, 2 );
51 add_action( 'wp_enqueue_scripts', array( $this, 'add_custom_assets' ), 100 );
52
53 add_action( 'autoptimize_filter_css_exclude', 'GhostKit_Assets::autoptimize_filter_css_exclude' );
54 }
55
56 /**
57 * Store used assets, so we can enqueue it later.
58 *
59 * @param string $name - asset name.
60 * @param bool|string $value - just enqueue flag or url to asset.
61 * @param string $type - assets type [script|style|custom-css].
62 * @param int $priority - asset enqueue priority.
63 */
64 public static function store_used_assets( $name, $value = true, $type = 'script', $priority = 10 ) {
65 if ( ! isset( self::$stored_assets[ $type ] ) ) {
66 return;
67 }
68
69 if ( isset( self::$stored_assets[ $type ][ $name ] ) ) {
70 if ( 'custom-css' === $type ) {
71 if ( ! self::$stored_assets[ $type ][ $name ]['value'] ) {
72 self::$stored_assets[ $type ][ $name ]['value'] = '';
73 }
74
75 self::$stored_assets[ $type ][ $name ]['value'] .= $value;
76 }
77
78 do_action( 'gkt_assets_store', $name, $value, $type, $priority );
79
80 return;
81 }
82
83 self::$stored_assets[ $type ][ $name ] = array(
84 'value' => $value,
85 'priority' => $priority,
86 );
87
88 do_action( 'gkt_assets_store', $name, $value, $type, $priority );
89 }
90
91 /**
92 * Enqueue stored assets.
93 *
94 * @param string $type - assets type [script|style|custom-css].
95 */
96 public static function enqueue_stored_assets( $type = 'script' ) {
97 if ( ! isset( self::$stored_assets[ $type ] ) || empty( self::$stored_assets[ $type ] ) ) {
98 return;
99 }
100
101 uasort(
102 self::$stored_assets[ $type ],
103 function ( $a, $b ) {
104 if ( $a === $b ) {
105 return 0;
106 }
107
108 if ( isset( $a['priority'] ) && isset( $b['priority'] ) ) {
109 return $a['priority'] < $b['priority'] ? -1 : 1;
110 }
111
112 return 0;
113 }
114 );
115
116 foreach ( self::$stored_assets[ $type ] as $name => $data ) {
117 if ( isset( $data['value'] ) && $data['value'] ) {
118 if ( 'script' === $type ) {
119 wp_enqueue_script( $name );
120 } elseif ( 'style' === $type ) {
121 wp_enqueue_style( $name );
122 } elseif ( 'custom-css' === $type ) {
123 self::add_custom_css( $name, $data['value'] );
124 }
125
126 self::$stored_assets[ $type ]['value'] = false;
127 }
128 }
129 }
130
131 /**
132 * Enqueue assets for blocks.
133 *
134 * @param array $blocks - blocks array.
135 * @param string $location - blocks location [content,widget].
136 */
137 public static function enqueue( $blocks = array(), $location = 'content' ) {
138 self::store_used_assets( 'ghostkit', true, 'style', 9 );
139 self::store_used_assets( 'ghostkit', true, 'script', 11 );
140
141 // Prepare blocks assets.
142 foreach ( $blocks as $block ) {
143 // GhostKit blocks.
144 if ( isset( $block['blockName'] ) && strpos( $block['blockName'], 'ghostkit/' ) === 0 ) {
145 $block_name = preg_replace( '/^ghostkit\//', '', $block['blockName'] );
146
147 self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'style' );
148 self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'script' );
149 }
150 }
151
152 // Blocks custom CSS.
153 $blocks_css = self::parse_blocks_css( $blocks );
154
155 if ( ! empty( $blocks_css ) ) {
156 self::store_used_assets( 'ghostkit-blocks-' . $location . '-custom-css', ghostkit()->replace_vars( $blocks_css ), 'custom-css' );
157 }
158 }
159
160 /**
161 * Enqueue scripts and styles actions.
162 * We need this to be used inside 'plugins_loaded' action to prevent conflicts with plugins and themes.
163 *
164 * 1. Enqueue plugins assets
165 * 2. Enqueue Ghost Kit assets
166 * 3. Enqueue theme assets
167 * 4. Enqueue Ghost Kit custom css
168 */
169 public function enqueue_scripts_action() {
170 add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_assets' ) );
171 add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_assets' ) );
172
173 // Custom css with higher priority to overwrite theme styles.
174 add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_custom_assets' ), 11 );
175 add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_custom_assets' ), 11 );
176 }
177
178 /**
179 * Register scripts that will be used in the future when portfolio will be printed.
180 */
181 public function register_scripts() {
182 $css_deps = array();
183 $js_deps = array( 'jquery', 'ghostkit-helper' );
184
185 do_action( 'gkt_before_assets_register' );
186
187 // ScrollReveal.
188 if ( apply_filters( 'gkt_enqueue_plugin_scrollreveal', true ) ) {
189 // We need to use previous version, as in 4.0.9 `cleanup` is not working at all.
190 wp_register_script( 'scrollreveal', ghostkit()->plugin_url . 'assets/vendor/scrollreveal-4-0-7/scrollreveal.min.js', array(), '4.0.7', true );
191
192 $js_deps[] = 'scrollreveal';
193 }
194
195 // Jarallax.
196 if ( apply_filters( 'gkt_enqueue_plugin_jarallax', true ) ) {
197 wp_register_script( 'jarallax', ghostkit()->plugin_url . 'assets/vendor/jarallax/dist/jarallax.min.js', array( 'jquery' ), '2.0.1', true );
198 wp_register_script( 'jarallax-video', ghostkit()->plugin_url . 'assets/vendor/jarallax/dist/jarallax-video.min.js', array( 'jarallax' ), '2.0.1', true );
199 }
200
201 // Swiper.
202 if ( apply_filters( 'gkt_enqueue_plugin_swiper', true ) ) {
203 // Add legacy swiper version in order to support Elementor plugin.
204 // https://wordpress.org/support/topic/visual-portfolio-elementor-issue/.
205 if ( class_exists( '\Elementor\Plugin' ) ) {
206 wp_register_style( 'swiper', ghostkit()->plugin_url . 'assets/vendor/swiper-5-4-5/swiper.min.css', array(), '5.4.5' );
207 wp_register_script( 'swiper', ghostkit()->plugin_url . 'assets/vendor/swiper-5-4-5/swiper.min.js', array(), '5.4.5', true );
208 } else {
209 wp_register_style( 'swiper', ghostkit()->plugin_url . 'assets/vendor/swiper/swiper-bundle.min.css', array(), '8.4.0' );
210 wp_register_script( 'swiper', ghostkit()->plugin_url . 'assets/vendor/swiper/swiper-bundle.min.js', array(), '8.4.0', true );
211 }
212 }
213
214 // Luxon.
215 if ( apply_filters( 'gkt_enqueue_plugin_luxon', true ) ) {
216 wp_register_script( 'luxon', ghostkit()->plugin_url . 'assets/vendor/luxon/build/global/luxon.min.js', array(), '3.0.1', true );
217 }
218
219 // GistEmbed.
220 if ( apply_filters( 'gkt_enqueue_plugin_gist_simple', true ) ) {
221 wp_register_style( 'gist-simple', ghostkit()->plugin_url . 'assets/vendor/gist-simple/dist/gist-simple.css', array(), '1.0.1' );
222 wp_register_script( 'gist-simple', ghostkit()->plugin_url . 'assets/vendor/gist-simple/dist/gist-simple.min.js', array( 'jquery' ), '1.0.1', true );
223 }
224
225 // Google reCaptcha.
226 if ( apply_filters( 'gkt_enqueue_google_recaptcha', true ) ) {
227 $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' );
228 $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' );
229
230 if ( $recaptcha_site_key && $recaptcha_secret_key ) {
231 wp_register_script( 'google-recaptcha', 'https://www.google.com/recaptcha/api.js?render=' . esc_attr( $recaptcha_site_key ), array(), '3.0.0', true );
232 }
233 }
234
235 // Parsley.
236 if ( apply_filters( 'gkt_enqueue_plugin_parsley', true ) ) {
237 wp_register_script( 'parsley', ghostkit()->plugin_url . 'assets/vendor/parsleyjs/dist/parsley.min.js', array( 'jquery' ), '2.9.2', true );
238
239 $locale = get_locale();
240
241 // phpcs:disable
242 wp_add_inline_script(
243 'parsley',
244 'Parsley.addMessages("' . esc_attr( $locale ) . '", {
245 defaultMessage: "' . esc_attr__( 'This value seems to be invalid.', 'ghostkit' ) . '",
246 type: {
247 email: "' . esc_attr__( 'This value should be a valid email.', 'ghostkit' ) . '",
248 url: "' . esc_attr__( 'This value should be a valid url.', 'ghostkit' ) . '",
249 number: "' . esc_attr__( 'This value should be a valid number.', 'ghostkit' ) . '",
250 integer: "' . esc_attr__( 'This value should be a valid integer.', 'ghostkit' ) . '",
251 digits: "' . esc_attr__( 'This value should be digits.', 'ghostkit' ) . '",
252 alphanum: "' . esc_attr__( 'This value should be alphanumeric.', 'ghostkit' ) . '"
253 },
254 notblank: "' . esc_attr__( 'This value should not be blank.', 'ghostkit' ) . '",
255 required: "' . esc_attr__( 'This value is required.', 'ghostkit' ) . '",
256 pattern: "' . esc_attr__( 'This value seems to be invalid.', 'ghostkit' ) . '",
257 min: "' . esc_attr__( 'This value should be greater than or equal to %s.', 'ghostkit' ) . '",
258 max: "' . esc_attr__( 'This value should be lower than or equal to %s.', 'ghostkit' ) . '",
259 range: "' . esc_attr__( 'This value should be between %s and %s.', 'ghostkit' ) . '",
260 minlength: "' . esc_attr__( 'This value is too short. It should have %s characters or more.', 'ghostkit' ) . '",
261 maxlength: "' . esc_attr__( 'This value is too long. It should have %s characters or fewer.', 'ghostkit' ) . '",
262 length: "' . esc_attr__( 'This value length is invalid. It should be between %s and %s characters long.', 'ghostkit' ) . '",
263 mincheck: "' . esc_attr__( 'You must select at least %s choices.', 'ghostkit' ) . '",
264 maxcheck: "' . esc_attr__( 'You must select %s choices or fewer.', 'ghostkit' ) . '",
265 check: "' . esc_attr__( 'You must select between %s and %s choices.', 'ghostkit' ) . '",
266 equalto: "' . esc_attr__( 'This value should be the same.', 'ghostkit' ) . '",
267 euvatin: "' . esc_attr__( 'It\'s not a valid VAT Identification Number.', 'ghostkit' ) . '",
268 confirmEmail: "' . esc_attr__( 'These emails should match.', 'ghostkit' ) . '",
269 });
270
271 Parsley.setLocale("' . esc_attr( $locale ) . '");',
272 'after'
273 );
274 // phpcs:enable
275 }
276
277 // Get all sidebars.
278 $sidebars = array();
279 if ( ! empty( $GLOBALS['wp_registered_sidebars'] ) ) {
280 foreach ( $GLOBALS['wp_registered_sidebars'] as $k => $sidebar ) {
281 $sidebars[ $k ] = array(
282 'id' => $sidebar['id'],
283 'name' => $sidebar['name'],
284 );
285 }
286 }
287
288 // helper script.
289 wp_register_script(
290 'ghostkit-helper',
291 ghostkit()->plugin_url . 'assets/js/helper.min.js',
292 array( 'jquery' ),
293 '2.25.0',
294 true
295 );
296 $default_variant = array(
297 'default' => array(
298 'title' => esc_html__( 'Default', 'ghostkit' ),
299 ),
300 );
301
302 // Google Maps prepare localization as in WordPress settings.
303 $gmaps_locale = get_locale();
304 $gmaps_suffix = '.com';
305 switch ( $gmaps_locale ) {
306 case 'he_IL':
307 // Hebrew correction.
308 $gmaps_locale = 'iw';
309 break;
310 case 'zh_CN':
311 // Chinese integration.
312 $gmaps_suffix = '.cn';
313 break;
314 }
315 $gmaps_locale = substr( $gmaps_locale, 0, 2 );
316
317 $theme_data = wp_get_theme( get_template() );
318
319 $breakpoints = GhostKit_Breakpoints::get_breakpoints();
320
321 $timezone = wp_timezone_string();
322
323 if ( substr( $timezone, 0, 1 ) === '+' || substr( $timezone, 0, 1 ) === '-' ) {
324 $timezone = 'UTC' . $timezone;
325 }
326
327 wp_localize_script(
328 'ghostkit-helper',
329 'ghostkitVariables',
330 array(
331 'themeName' => $theme_data->get( 'Name' ),
332 'settings' => get_option( 'ghostkit_settings', array() ),
333 'disabledBlocks' => get_option( 'ghostkit_disabled_blocks', array() ),
334
335 // TODO: Due to different formats in scss and assets there is an offset.
336 'media_sizes' => array(
337 'sm' => $breakpoints['xs'],
338 'md' => $breakpoints['sm'],
339 'lg' => $breakpoints['md'],
340 'xl' => $breakpoints['lg'],
341 ),
342 'timezone' => $timezone,
343 'googleMapsAPIKey' => get_option( 'ghostkit_google_maps_api_key' ),
344 'googleMapsAPIUrl' => 'https://maps.googleapis' . $gmaps_suffix . '/maps/api/js?v=3.exp&language=' . esc_attr( $gmaps_locale ),
345 'googleMapsLibrary' => apply_filters( 'gkt_enqueue_plugin_gmaps', true ) ? array(
346 'url' => ghostkit()->plugin_url . 'assets/vendor/gmaps/gmaps.min.js?ver=0.4.25',
347 ) : false,
348 'googleReCaptchaAPISiteKey' => get_option( 'ghostkit_google_recaptcha_api_site_key' ),
349 'googleReCaptchaAPISecretKey' => is_admin() ? get_option( 'ghostkit_google_recaptcha_api_secret_key' ) : '',
350 'sidebars' => $sidebars,
351 'icons' => is_admin() ? apply_filters( 'gkt_icons_list', array() ) : array(),
352 'shapes' => is_admin() ? apply_filters( 'gkt_shapes_list', array() ) : array(),
353 'fonts' => is_admin() ? apply_filters( 'gkt_fonts_list', array() ) : array(),
354 'customTypographyList' => is_admin() ? apply_filters( 'gkt_custom_typography', array() ) : array(),
355 'variants' => array(
356 'accordion' => array_merge( $default_variant, apply_filters( 'gkt_accordion_variants', array() ) ),
357 'accordion_item' => array_merge( $default_variant, apply_filters( 'gkt_accordion_item_variants', array() ) ),
358 'alert' => array_merge( $default_variant, apply_filters( 'gkt_alert_variants', array() ) ),
359 'button_wrapper' => array_merge( $default_variant, apply_filters( 'gkt_button_wrapper_variants', array() ) ),
360 'button' => array_merge( $default_variant, apply_filters( 'gkt_button_variants', array() ) ),
361 'carousel' => array_merge( $default_variant, apply_filters( 'gkt_carousel_variants', array() ) ),
362 'carousel_slide' => array_merge( $default_variant, apply_filters( 'gkt_carousel_slide_variants', array() ) ),
363 'changelog' => array_merge( $default_variant, apply_filters( 'gkt_changelog_variants', array() ) ),
364 'counter_box' => array_merge( $default_variant, apply_filters( 'gkt_counter_box_variants', array() ) ),
365 'divider' => array_merge( $default_variant, apply_filters( 'gkt_divider_variants', array() ) ),
366 'gist' => array_merge( $default_variant, apply_filters( 'gkt_gist_variants', array() ) ),
367 'google_maps' => array_merge( $default_variant, apply_filters( 'gkt_google_maps_variants', array() ) ),
368 'grid' => array_merge( $default_variant, apply_filters( 'gkt_grid_variants', array() ) ),
369 'grid_column' => array_merge( $default_variant, apply_filters( 'gkt_grid_column_variants', array() ) ),
370 'icon_box' => array_merge( $default_variant, apply_filters( 'gkt_icon_box_variants', array() ) ),
371 'instagram' => array_merge( $default_variant, apply_filters( 'gkt_instagram_variants', array() ) ),
372 'pricing_table' => array_merge( $default_variant, apply_filters( 'gkt_pricing_table_variants', array() ) ),
373 'pricing_table_item' => array_merge( $default_variant, apply_filters( 'gkt_pricing_table_item_variants', array() ) ),
374 'progress' => array_merge( $default_variant, apply_filters( 'gkt_progress_variants', array() ) ),
375 'tabs' => array_merge( $default_variant, apply_filters( 'gkt_tabs_variants', array() ) ),
376 'tabs_tab' => array_merge( $default_variant, apply_filters( 'gkt_tabs_tab_variants', array() ) ),
377 'testimonial' => array_merge( $default_variant, apply_filters( 'gkt_testimonial_variants', array() ) ),
378 'twitter' => array_merge( $default_variant, apply_filters( 'gkt_twitter_variants', array() ) ),
379 'video' => array_merge( $default_variant, apply_filters( 'gkt_video_variants', array() ) ),
380 ),
381 'admin_url' => admin_url(),
382 'admin_templates_url' => admin_url( 'edit.php?post_type=ghostkit_template' ),
383 )
384 );
385
386 // Ghost Kit.
387 wp_register_style(
388 'ghostkit',
389 ghostkit()->plugin_url . 'gutenberg/style.min.css',
390 $css_deps,
391 '2.25.0'
392 );
393 wp_style_add_data( 'ghostkit', 'rtl', 'replace' );
394 wp_style_add_data( 'ghostkit', 'suffix', '.min' );
395
396 wp_register_script(
397 'ghostkit',
398 ghostkit()->plugin_url . 'assets/js/main.min.js',
399 $js_deps,
400 '2.25.0',
401 true
402 );
403
404 // Blocks.
405 foreach ( glob( ghostkit()->plugin_path . 'gutenberg/blocks/*/frontend.min.js' ) as $template ) {
406 $block_name = basename( dirname( $template ) );
407 $block_script_url = ghostkit()->plugin_url . 'gutenberg/blocks/' . $block_name . '/frontend.min.js';
408 $block_js_deps = array( 'ghostkit', 'jquery' );
409
410 switch ( $block_name ) {
411 case 'grid':
412 case 'grid-column':
413 if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
414 $block_js_deps[] = 'jarallax-video';
415 }
416 if ( wp_script_is( 'jarallax' ) || wp_script_is( 'jarallax', 'registered' ) ) {
417 $block_js_deps[] = 'jarallax';
418 }
419 break;
420 case 'video':
421 if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
422 $block_js_deps[] = 'jarallax-video';
423 }
424 break;
425 case 'gist':
426 if ( wp_script_is( 'gist-simple' ) || wp_script_is( 'gist-simple', 'registered' ) ) {
427 $block_js_deps[] = 'gist-simple';
428 }
429 break;
430 case 'carousel':
431 if ( wp_script_is( 'swiper' ) || wp_script_is( 'swiper', 'registered' ) ) {
432 $block_js_deps[] = 'swiper';
433 }
434 break;
435 case 'countdown':
436 $block_js_deps[] = 'luxon';
437 break;
438 case 'form':
439 if ( wp_script_is( 'parsley' ) || wp_script_is( 'parsley', 'registered' ) ) {
440 $block_js_deps[] = 'parsley';
441 }
442 if ( wp_script_is( 'google-recaptcha' ) || wp_script_is( 'google-recaptcha', 'registered' ) ) {
443 $block_js_deps[] = 'google-recaptcha';
444 }
445 break;
446 case 'tabs':
447 $block_name = 'tabs-v2';
448 break;
449 }
450
451 wp_register_script(
452 'ghostkit-block-' . $block_name,
453 $block_script_url,
454 array_unique( $block_js_deps ),
455 '2.25.0',
456 true
457 );
458 }
459 foreach ( glob( ghostkit()->plugin_path . 'gutenberg/blocks/*/styles/style.min.css' ) as $template ) {
460 $block_name = basename( dirname( dirname( $template ) ) );
461 $block_style_url = ghostkit()->plugin_url . 'gutenberg/blocks/' . $block_name . '/styles/style.min.css';
462 $block_css_deps = array( 'ghostkit' );
463
464 switch ( $block_name ) {
465 case 'gist':
466 $block_css_deps[] = 'gist-simple';
467 break;
468 case 'carousel':
469 $block_css_deps[] = 'swiper';
470 break;
471 case 'tabs':
472 $block_name = 'tabs-v2';
473 break;
474 }
475
476 wp_register_style(
477 'ghostkit-block-' . $block_name,
478 $block_style_url,
479 array_unique( $block_css_deps ),
480 '2.25.0'
481 );
482 wp_style_add_data( 'ghostkit-block-' . $block_name, 'rtl', 'replace' );
483 wp_style_add_data( 'ghostkit-block-' . $block_name, 'suffix', '.min' );
484 }
485
486 do_action( 'gkt_after_assets_register' );
487 }
488
489 /**
490 * Enqueue styles in head.
491 */
492 public function wp_enqueue_head_assets() {
493 self::enqueue_stored_assets( 'style' );
494 self::enqueue_stored_assets( 'script' );
495 }
496
497 /**
498 * Enqueue custom styles in head.
499 */
500 public function wp_enqueue_head_custom_assets() {
501 self::enqueue_stored_assets( 'custom-css' );
502 }
503
504 /**
505 * Enqueue scripts and styles in foot.
506 */
507 public function wp_enqueue_foot_assets() {
508 self::enqueue_stored_assets( 'style' );
509 self::enqueue_stored_assets( 'script' );
510 }
511
512 /**
513 * Enqueue custom styles in foot.
514 */
515 public function wp_enqueue_foot_custom_assets() {
516 self::enqueue_stored_assets( 'custom-css' );
517 }
518
519 /**
520 * Enqueue blocks assets.
521 *
522 * @param array $blocks - blocks array.
523 * @param array $location - blocks location [content,widget].
524 */
525 public function maybe_enqueue_blocks_assets( $blocks, $location ) {
526 if ( self::$already_added_custom_assets ) {
527 $location = 'widget';
528 }
529
530 self::enqueue( $blocks, $location );
531 }
532
533 /**
534 * Parse blocks and prepare styles
535 *
536 * @param array $blocks Blocks array with attributes.
537 * @return string
538 */
539 public static function parse_blocks_css( $blocks ) {
540 $styles = '';
541
542 foreach ( $blocks as $block ) {
543 if ( isset( $block['attrs'] ) ) {
544 $styles .= GhostKit_Block_Custom_Styles::get( $block['attrs'] );
545 $styles .= GhostKit_Block_Custom_CSS::get( $block['attrs'] );
546 }
547 }
548
549 return $styles;
550 }
551
552 /**
553 * Add styles from blocks to the head section.
554 *
555 * @param int $post_id - current post id.
556 */
557 public function add_custom_assets( $post_id ) {
558 $global_code = get_option( 'ghostkit_custom_code', array() );
559
560 if ( is_singular() && ! $post_id ) {
561 $post_id = get_the_ID();
562 }
563
564 $is_single = is_singular() && $post_id;
565
566 // Global custom CSS.
567 if ( $global_code && isset( $global_code['ghostkit_custom_css'] ) && $global_code['ghostkit_custom_css'] ) {
568 self::add_custom_css( 'ghostkit-global-custom-css', $global_code['ghostkit_custom_css'] );
569 }
570
571 // Local custom CSS.
572 if ( $is_single ) {
573 $meta_css = get_post_meta( $post_id, 'ghostkit_custom_css', true );
574
575 if ( ! empty( $meta_css ) ) {
576 self::add_custom_css( 'ghostkit-custom-css', $meta_css );
577 }
578 }
579
580 // Global custom JS head.
581 if ( $global_code && isset( $global_code['ghostkit_custom_js_head'] ) && $global_code['ghostkit_custom_js_head'] ) {
582 self::add_custom_js( 'ghostkit-global-custom-js-head', $global_code['ghostkit_custom_js_head'] );
583 }
584
585 // Local custom JS head.
586 if ( $is_single ) {
587 $meta_js_head = get_post_meta( $post_id, 'ghostkit_custom_js_head', true );
588
589 if ( ! empty( $meta_js_head ) ) {
590 self::add_custom_js( 'ghostkit-custom-js-head', $meta_js_head );
591 }
592 }
593
594 // Global custom JS foot.
595 if ( $global_code && isset( $global_code['ghostkit_custom_js_foot'] ) && $global_code['ghostkit_custom_js_foot'] ) {
596 self::add_custom_js( 'ghostkit-global-custom-js-foot', $global_code['ghostkit_custom_js_foot'], true );
597 }
598
599 // Local custom JS foot.
600 if ( $is_single ) {
601 $meta_js_foot = get_post_meta( $post_id, 'ghostkit_custom_js_foot', true );
602
603 if ( ! empty( $meta_js_foot ) ) {
604 self::add_custom_js( 'ghostkit-custom-js-foot', $meta_js_foot, true );
605 }
606 }
607
608 self::$already_added_custom_assets = true;
609 }
610
611 /**
612 * Skip custom styles from Autoptimize.
613 * We need this since generated CSS with custom breakpoints are excluded
614 * from Autoptimize by default and this cause conflicts.
615 *
616 * @param string $result - allowed list.
617 * @return string
618 */
619 public static function autoptimize_filter_css_exclude( $result ) {
620 // By default in Autoptimize excluded folder `wp-content/uploads/`.
621 // We need to check, if this folder is not excluded, then we
622 // don't need to use our hack.
623 if ( $result && strpos( $result, 'wp-content/uploads/' ) === false ) {
624 return $result;
625 }
626
627 foreach ( self::$skip_from_autoptimize as $name ) {
628 if ( $result ) {
629 $result .= ',';
630 } else {
631 $result = '';
632 }
633
634 $result .= $name;
635 }
636
637 return $result;
638 }
639
640 /**
641 * Add custom CSS.
642 *
643 * @param String $name - handle name.
644 * @param String $css - code.
645 */
646 public static function add_custom_css( $name, $css ) {
647 if ( ! wp_style_is( $name, 'enqueued' ) ) {
648 $css = wp_kses( $css, array( '\'', '\"' ) );
649 $css = str_replace( '&gt;', '>', $css );
650
651 // Enqueue custom CSS.
652 if ( ! self::$already_added_custom_assets ) {
653 wp_register_style( $name, false, array(), '2.25.0' );
654 wp_enqueue_style( $name );
655 wp_add_inline_style( $name, $css );
656
657 // Enqueue JS instead of CSS when rendering in <body> to prevent W3C errors.
658 } elseif ( ! wp_script_is( $name, 'enqueued' ) ) {
659 wp_register_script( $name, false, array(), '2.25.0', true );
660 wp_enqueue_script( $name );
661 wp_add_inline_script(
662 $name,
663 '(function(){
664 var styleTag = document.createElement("style");
665 styleTag.id = "' . esc_attr( $name ) . '-inline-css";
666 styleTag.innerHTML = ' . wp_json_encode( $css ) . ';
667 document.body.appendChild(styleTag);
668 }());'
669 );
670 }
671 }
672
673 self::$stored_assets[] = $name;
674 }
675
676 /**
677 * Add custom JS.
678 *
679 * @param String $name - handle name.
680 * @param String $js - code.
681 * @param Boolean $footer - print in footer.
682 */
683 public static function add_custom_js( $name, $js, $footer = false ) {
684 wp_register_script( $name, '', array(), '2.25.0', $footer );
685 wp_enqueue_script( $name );
686 wp_add_inline_script( $name, $js );
687 }
688 }
689
690 new GhostKit_Assets();
691