PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.7.2
Block Animations, Motion & Scroll Effects – Ghost Kit v3.7.2
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
← All changes | classes/class-assets.php +738 -582 2.25.03.7.2 View file →
@@ -5,9 +5,9 @@
5 5 * @package ghostkit
6 6 */
7 7
8 8 if ( ! defined( 'ABSPATH' ) ) {
9 - exit;
9 + exit;
10 10 }
11 11
12 12 /**
13 13 * Class GhostKit_Assets
@@ -12,679 +12,835 @@
12 12 /**
13 13 * Class GhostKit_Assets
14 14 */
15 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 - );
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 26
27 - /**
28 - * Already added custom assets in head.
29 - *
30 - * @var boolean
31 - */
32 - private static $already_added_custom_assets = false;
27 + /**
28 + * Already added custom assets in head.
29 + *
30 + * @var boolean
31 + */
32 + private static $already_added_custom_assets = false;
33 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 - );
34 + /**
35 + * Already add styles.
36 + *
37 + * @var array
38 + */
39 + private static $already_added_styles = array();
43 40
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 );
41 + /**
42 + * List with assets to skip from Autoptimize when CSS generated.
43 + *
44 + * @var array
45 + */
46 + protected static $skip_from_autoptimize = array(
47 + 'ghostkit-blocks-content-custom-css',
48 + 'ghostkit-blocks-widget-custom-css',
49 + );
52 50
53 - add_action( 'autoptimize_filter_css_exclude', 'GhostKit_Assets::autoptimize_filter_css_exclude' );
54 - }
51 + /**
52 + * GhostKit_Assets constructor.
53 + */
54 + public function __construct() {
55 + add_action( 'init', array( $this, 'register_scripts' ) );
56 + add_filter( 'render_block', array( $this, 'render_block_enqueue_assets' ), 9, 2 );
57 + add_action( 'plugins_loaded', array( $this, 'enqueue_scripts_action' ), 11 );
58 + add_action( 'ghostkit_parse_blocks', array( $this, 'maybe_enqueue_blocks_assets' ), 11, 2 );
59 + add_action( 'wp_enqueue_scripts', array( $this, 'add_custom_assets' ), 100 );
55 60
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 - }
61 + add_action( 'autoptimize_filter_css_exclude', 'GhostKit_Assets::autoptimize_filter_css_exclude' );
68 62
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 - }
63 + // enqueue runtime.
64 + add_action( 'enqueue_block_editor_assets', 'GhostKit_Assets::enqueue_runtime', 11 );
65 + add_action( 'wp_enqueue_scripts', 'GhostKit_Assets::enqueue_runtime', 8 );
66 + }
74 67
75 - self::$stored_assets[ $type ][ $name ]['value'] .= $value;
76 - }
68 + /**
69 + * Check if Webpack HMR file available.
70 + *
71 + * @return boolean
72 + */
73 + public static function is_webpack_hmr_support() {
74 + return file_exists( ghostkit()->plugin_path . 'build/runtime.js' );
75 + }
77 76
78 - do_action( 'gkt_assets_store', $name, $value, $type, $priority );
77 + /**
78 + * Enqueue runtime script.
79 + */
80 + public static function enqueue_runtime() {
81 + // HMR Webpack.
82 + if ( self::is_webpack_hmr_support() ) {
83 + self::enqueue_script( 'ghostkit-runtime', 'build/runtime', array(), null, false );
84 + }
85 + }
79 86
80 - return;
81 - }
87 + /**
88 + * Get .asset.php file data.
89 + *
90 + * @param string $filepath asset file path.
91 + * @param string $filetype asset file type [style|script].
92 + *
93 + * @return array
94 + */
95 + public static function get_asset_file( $filepath, $filetype = '' ) {
96 + $asset_path = ghostkit()->plugin_path . str_replace( '.min', '', $filepath ) . '.asset.php';
82 97
83 - self::$stored_assets[ $type ][ $name ] = array(
84 - 'value' => $value,
85 - 'priority' => $priority,
86 - );
98 + if ( file_exists( $asset_path ) ) {
99 + // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
100 + return include $asset_path;
101 + } elseif ( ! empty( $filetype ) ) {
102 + $file_ext = 'style' === $filetype ? 'css' : 'js';
103 + $full_file_path = ghostkit()->plugin_path . $filepath . '.' . $file_ext;
104 + $file_version = file_exists( $full_file_path ) ? filemtime( $full_file_path ) : null;
105 + }
87 106
88 - do_action( 'gkt_assets_store', $name, $value, $type, $priority );
89 - }
107 + return array(
108 + 'dependencies' => array(),
109 + 'version' => $file_version ?? GHOSTKIT_VERSION,
110 + );
111 + }
90 112
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 - }
113 + /**
114 + * Register script.
115 + *
116 + * @param string $name asset name.
117 + * @param string $path file path.
118 + * @param array $dependencies asset dependencies.
119 + * @param string $version asset version.
120 + * @param boolean $in_footer render in footer.
121 + */
122 + public static function register_script( $name, $path, $dependencies = array(), $version = null, $in_footer = true ) {
123 + global $current_screen;
100 124
101 - uasort(
102 - self::$stored_assets[ $type ],
103 - function ( $a, $b ) {
104 - if ( $a === $b ) {
105 - return 0;
106 - }
125 + $script_data = self::get_asset_file( $path, 'script' );
107 126
108 - if ( isset( $a['priority'] ) && isset( $b['priority'] ) ) {
109 - return $a['priority'] < $b['priority'] ? -1 : 1;
110 - }
127 + if ( ! empty( $dependencies ) ) {
128 + $script_data['dependencies'] = array_unique(
129 + array_merge(
130 + $script_data['dependencies'],
131 + $dependencies
132 + )
133 + );
134 + }
111 135
112 - return 0;
113 - }
114 - );
136 + // Fix for Widgets screen.
137 + if ( isset( $current_screen->id ) && 'widgets' === $current_screen->id ) {
138 + foreach ( array( 'wp-edit-post', 'wp-editor' ) as $skip ) {
139 + $key = array_search( $skip, $script_data['dependencies'], true );
115 140
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 - }
141 + if ( false !== $key ) {
142 + unset( $script_data['dependencies'][ $key ] );
143 + }
144 + }
145 + }
125 146
126 - self::$stored_assets[ $type ]['value'] = false;
127 - }
128 - }
129 - }
147 + wp_register_script(
148 + $name,
149 + ghostkit()->plugin_url . $path . '.js',
150 + $script_data['dependencies'],
151 + $version ?? $script_data['version'],
152 + $in_footer
153 + );
154 + }
130 155
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 );
156 + /**
157 + * Enqueue script.
158 + *
159 + * @param string $name asset name.
160 + * @param string $path file path.
161 + * @param array $dependencies asset dependencies.
162 + * @param string $version asset version.
163 + * @param boolean $in_footer render in footer.
164 + */
165 + public static function enqueue_script( $name, $path, $dependencies = array(), $version = null, $in_footer = true ) {
166 + self::register_script( $name, $path, $dependencies, $version, $in_footer );
140 167
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'] );
168 + wp_enqueue_script( $name );
169 + }
146 170
147 - self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'style' );
148 - self::store_used_assets( 'ghostkit-block-' . $block_name, true, 'script' );
149 - }
150 - }
171 + /**
172 + * Register style
173 + *
174 + * @param string $name asset name.
175 + * @param string $path file path.
176 + * @param array $dependencies asset dependencies.
177 + * @param string $version asset version.
178 + */
179 + public static function register_style( $name, $path, $dependencies = array(), $version = null ) {
180 + $style_data = self::get_asset_file( $path, 'style' );
151 181
152 - // Blocks custom CSS.
153 - $blocks_css = self::parse_blocks_css( $blocks );
182 + wp_register_style(
183 + $name,
184 + ghostkit()->plugin_url . $path . '.css',
185 + $dependencies,
186 + $version ?? $style_data['version']
187 + );
188 + }
154 189
155 - if ( ! empty( $blocks_css ) ) {
156 - self::store_used_assets( 'ghostkit-blocks-' . $location . '-custom-css', ghostkit()->replace_vars( $blocks_css ), 'custom-css' );
157 - }
158 - }
190 + /**
191 + * Enqueue style
192 + *
193 + * @param string $name asset name.
194 + * @param string $path file path.
195 + * @param array $dependencies asset dependencies.
196 + * @param string $version asset version.
197 + */
198 + public static function enqueue_style( $name, $path, $dependencies = array(), $version = null ) {
199 + self::register_style( $name, $path, $dependencies, $version );
159 200
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' ) );
201 + wp_enqueue_style( $name );
202 + }
172 203
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 - }
204 + /**
205 + * Store used assets, so we can enqueue it later.
206 + *
207 + * @param string $name - asset name.
208 + * @param bool|string $value - just enqueue flag or url to asset.
209 + * @param string $type - assets type [script|style|custom-css].
210 + * @param int $priority - asset enqueue priority.
211 + */
212 + public static function store_used_assets( $name, $value = true, $type = 'script', $priority = 10 ) {
213 + if ( ! isset( self::$stored_assets[ $type ] ) ) {
214 + return;
215 + }
177 216
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' );
217 + // We need to check for duplicate assets, which may be added because of custom locations.
218 + // Sometimes custom CSS is duplicated in Astra or Blocksy themes.
219 + if ( 'custom-css' === $type ) {
220 + if ( in_array( $value, self::$already_added_styles, true ) ) {
221 + return;
222 + }
223 + self::$already_added_styles[] = $value;
224 + }
184 225
185 - do_action( 'gkt_before_assets_register' );
226 + if ( isset( self::$stored_assets[ $type ][ $name ] ) ) {
227 + if ( 'custom-css' === $type ) {
228 + if ( ! self::$stored_assets[ $type ][ $name ]['value'] ) {
229 + self::$stored_assets[ $type ][ $name ]['value'] = '';
230 + }
186 231
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 );
232 + self::$stored_assets[ $type ][ $name ]['value'] .= $value;
233 + }
191 234
192 - $js_deps[] = 'scrollreveal';
193 - }
235 + do_action( 'gkt_assets_store', $name, $value, $type, $priority );
194 236
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 - }
237 + return;
238 + }
200 239
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 - }
240 + self::$stored_assets[ $type ][ $name ] = array(
241 + 'value' => $value,
242 + 'priority' => $priority,
243 + );
213 244
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 - }
245 + do_action( 'gkt_assets_store', $name, $value, $type, $priority );
246 + }
218 247
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 - }
248 + /**
249 + * Enqueue stored assets.
250 + *
251 + * @param string $type - assets type [script|style|custom-css].
252 + */
253 + public static function enqueue_stored_assets( $type = 'script' ) {
254 + if ( ! isset( self::$stored_assets[ $type ] ) || empty( self::$stored_assets[ $type ] ) ) {
255 + return;
256 + }
224 257
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' );
258 + uasort(
259 + self::$stored_assets[ $type ],
260 + function ( $a, $b ) {
261 + if ( $a === $b ) {
262 + return 0;
263 + }
229 264
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 - }
265 + if ( isset( $a['priority'] ) && isset( $b['priority'] ) ) {
266 + return $a['priority'] < $b['priority'] ? -1 : 1;
267 + }
234 268
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 );
269 + return 0;
270 + }
271 + );
238 272
239 - $locale = get_locale();
273 + foreach ( self::$stored_assets[ $type ] as $name => $data ) {
274 + if ( isset( $data['value'] ) && $data['value'] ) {
275 + if ( 'script' === $type ) {
276 + wp_enqueue_script( $name );
277 + } elseif ( 'style' === $type ) {
278 + wp_enqueue_style( $name );
279 + } elseif ( 'custom-css' === $type ) {
280 + self::add_custom_css( $name, $data['value'] );
281 + }
240 282
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 - });
283 + self::$stored_assets[ $type ][ $name ]['value'] = false;
284 + }
285 + }
286 + }
270 287
271 - Parsley.setLocale("' . esc_attr( $locale ) . '");',
272 - 'after'
273 - );
274 - // phpcs:enable
275 - }
288 + /**
289 + * Enqueue assets for blocks.
290 + *
291 + * @param array $blocks - blocks array.
292 + * @param string $location - blocks location [content,widget].
293 + */
294 + public static function enqueue( $blocks = array(), $location = 'content' ) {
295 + if ( ! empty( $blocks ) && is_array( $blocks ) ) {
296 + $detected_assets = GhostKit_Assets_Detector::detect_from_blocks( $blocks, 'parse' );
297 + GhostKit_Assets_Detector::store_detected_assets( $detected_assets );
298 + }
276 299
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 - }
300 + $blocks_css = '';
287 301
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 - );
302 + // Prepare blocks assets.
303 + foreach ( $blocks as $block ) {
304 + // Filter blocks custom CSS.
305 + if ( isset( $block['blockName'] ) ) {
306 + $custom_styles = apply_filters( 'gkt_block_custom_styles', '', $block );
301 307
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 );
308 + if ( ! empty( $custom_styles ) ) {
309 + if ( ! empty( $blocks_css ) ) {
310 + $blocks_css .= ' ';
311 + }
316 312
317 - $theme_data = wp_get_theme( get_template() );
313 + $blocks_css .= $custom_styles;
314 + }
315 + }
316 + }
318 317
319 - $breakpoints = GhostKit_Breakpoints::get_breakpoints();
318 + // Store custom CSS.
319 + if ( ! empty( $blocks_css ) && $blocks_css ) {
320 + self::store_used_assets( 'ghostkit-blocks-' . $location . '-custom-css', ghostkit()->replace_vars( $blocks_css ), 'custom-css' );
321 + }
322 + }
320 323
321 - $timezone = wp_timezone_string();
324 + /**
325 + * Enqueue extension, style-variant, and attr-based assets during block render.
326 + *
327 + * Block.json handles are detected at parse-time only; this callback covers
328 + * attrs and rendered HTML markers (e.g. effects, list style variants).
329 + *
330 + * @param string $block_content rendered block content.
331 + * @param array $block block data.
332 + *
333 + * @return string
334 + */
335 + public function render_block_enqueue_assets( $block_content, $block ) {
336 + if ( ! is_array( $block ) ) {
337 + return $block_content;
338 + }
322 339
323 - if ( substr( $timezone, 0, 1 ) === '+' || substr( $timezone, 0, 1 ) === '-' ) {
324 - $timezone = 'UTC' . $timezone;
325 - }
340 + $content = is_string( $block_content ) ? $block_content : '';
326 341
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() ),
342 + $detected_assets = GhostKit_Assets_Detector::detect_from_block( $block, 'render', $content );
343 + GhostKit_Assets_Detector::enqueue_detected_assets( $detected_assets );
334 344
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 - );
345 + return $block_content;
346 + }
385 347
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' );
348 + /**
349 + * Enqueue scripts and styles actions.
350 + * We need this to be used inside 'plugins_loaded' action to prevent conflicts with plugins and themes.
351 + *
352 + * 1. Enqueue plugins assets
353 + * 2. Enqueue Ghost Kit assets
354 + * 3. Enqueue theme assets
355 + * 4. Enqueue Ghost Kit custom css
356 + */
357 + public function enqueue_scripts_action() {
358 + add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_assets' ) );
359 + add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_assets' ) );
395 360
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 - );
361 + // Custom css with higher priority to overwrite theme styles.
362 + add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_head_custom_assets' ), 11 );
363 + add_action( 'wp_footer', array( $this, 'wp_enqueue_foot_custom_assets' ), 11 );
364 + }
403 365
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' );
366 + /**
367 + * Register scripts that will be used in the future when portfolio will be printed.
368 + */
369 + public function register_scripts() {
370 + $css_deps = array();
371 + $js_deps = array( 'ghostkit-helper', 'ghostkit-event-fallbacks' );
409 372
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 - }
373 + do_action( 'gkt_before_assets_register' );
450 374
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' );
375 + // Motion.
376 + if ( apply_filters( 'gkt_enqueue_plugin_motion', true ) ) {
377 + self::register_script( 'motion', 'assets/vendor/motion/dist/motion.min', array(), '11.15.0' );
463 378
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 - }
379 + $js_deps[] = 'motion';
380 + }
475 381
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 - }
382 + // Ivent.
383 + if ( apply_filters( 'gkt_enqueue_plugin_ivent', true ) ) {
384 + self::register_script( 'ivent', 'assets/vendor/ivent/dist/ivent.min', array(), '0.2.0' );
385 + }
485 386
486 - do_action( 'gkt_after_assets_register' );
487 - }
387 + // Jarallax.
388 + if ( apply_filters( 'gkt_enqueue_plugin_jarallax', true ) ) {
389 + self::register_script( 'jarallax', 'assets/vendor/jarallax/dist/jarallax.min', array(), '3.1.0' );
390 + self::register_script( 'jarallax-video', 'assets/vendor/jarallax/dist/jarallax-video.min', array( 'jarallax' ), '3.1.0' );
391 + }
488 392
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 - }
393 + // Swiper.
394 + if ( apply_filters( 'gkt_enqueue_plugin_swiper', true ) ) {
395 + // Add legacy swiper version in order to support Elementor plugin.
396 + // https://wordpress.org/support/topic/visual-portfolio-elementor-issue/.
397 + if ( class_exists( '\Elementor\Plugin' ) ) {
398 + self::register_style( 'swiper', 'assets/vendor/swiper-5-4-5/swiper.min', array(), '5.4.5' );
399 + self::register_script( 'swiper', 'assets/vendor/swiper-5-4-5/swiper.min', array(), '5.4.5' );
400 + } else {
401 + self::register_style( 'swiper', 'assets/vendor/swiper/swiper-bundle.min', array(), '8.4.6' );
402 + self::register_script( 'swiper', 'assets/vendor/swiper/swiper-bundle.min', array(), '8.4.6' );
403 + }
404 + }
496 405
497 - /**
498 - * Enqueue custom styles in head.
499 - */
500 - public function wp_enqueue_head_custom_assets() {
501 - self::enqueue_stored_assets( 'custom-css' );
502 - }
406 + // Luxon.
407 + if ( apply_filters( 'gkt_enqueue_plugin_luxon', true ) ) {
408 + self::register_script( 'luxon', 'assets/vendor/luxon/build/global/luxon.min', array(), '3.3.0' );
409 + }
503 410
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 - }
411 + // Lottie Player.
412 + if ( apply_filters( 'gkt_enqueue_plugin_lottie_player', true ) ) {
413 + self::register_script( 'lottie-player', 'assets/vendor/lottie-player/dist/lottie-player', array(), '2.0.12' );
414 + wp_script_add_data( 'lottie-player', 'async', true );
415 + }
511 416
512 - /**
513 - * Enqueue custom styles in foot.
514 - */
515 - public function wp_enqueue_foot_custom_assets() {
516 - self::enqueue_stored_assets( 'custom-css' );
517 - }
417 + // GistEmbed.
418 + if ( apply_filters( 'gkt_enqueue_plugin_gist_simple', true ) ) {
419 + self::register_style( 'gist-simple', 'assets/vendor/gist-simple/dist/gist-simple', array(), '2.1.0' );
420 + self::register_script( 'gist-simple', 'assets/vendor/gist-simple/dist/gist-simple.min', array(), '2.1.0' );
421 + }
518 422
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 - }
423 + // Google reCaptcha.
424 + $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' );
425 + $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' );
529 426
530 - self::enqueue( $blocks, $location );
531 - }
427 + if ( apply_filters( 'gkt_enqueue_google_recaptcha', true ) && $recaptcha_site_key && $recaptcha_secret_key ) {
428 + wp_register_script( 'google-recaptcha', 'https://www.google.com/recaptcha/api.js?render=' . esc_attr( $recaptcha_site_key ), array(), '3.0.0', true );
429 + }
532 430
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 = '';
431 + // Get all sidebars.
432 + $sidebars = array();
433 + if ( ! empty( $GLOBALS['wp_registered_sidebars'] ) ) {
434 + foreach ( $GLOBALS['wp_registered_sidebars'] as $k => $sidebar ) {
435 + $sidebars[ $k ] = array(
436 + 'id' => $sidebar['id'],
437 + 'name' => $sidebar['name'],
438 + );
439 + }
440 + }
541 441
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 - }
442 + // helper script.
443 + self::register_script(
444 + 'ghostkit-helper',
445 + 'build/assets/js/helper',
446 + array( 'ivent' )
447 + );
548 448
549 - return $styles;
550 - }
449 + // Google Maps prepare localization as in WordPress settings.
450 + $gmaps_locale = get_locale();
451 + $gmaps_suffix = '.com';
452 + switch ( $gmaps_locale ) {
453 + case 'he_IL':
454 + // Hebrew correction.
455 + $gmaps_locale = 'iw';
456 + break;
457 + case 'zh_CN':
458 + // Chinese integration.
459 + $gmaps_suffix = '.cn';
460 + break;
461 + }
462 + $gmaps_locale = substr( $gmaps_locale, 0, 2 );
551 463
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() );
464 + $theme_data = wp_get_theme( get_template() );
559 465
560 - if ( is_singular() && ! $post_id ) {
561 - $post_id = get_the_ID();
562 - }
466 + $breakpoints = GhostKit_Breakpoints::get_breakpoints();
563 467
564 - $is_single = is_singular() && $post_id;
468 + $timezone = wp_timezone_string();
565 469
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 - }
470 + if ( substr( $timezone, 0, 1 ) === '+' || substr( $timezone, 0, 1 ) === '-' ) {
471 + $timezone = 'UTC' . $timezone;
472 + }
570 473
571 - // Local custom CSS.
572 - if ( $is_single ) {
573 - $meta_css = get_post_meta( $post_id, 'ghostkit_custom_css', true );
474 + $global_data = array(
475 + 'version' => GHOSTKIT_VERSION,
476 + 'pro' => false,
574 477
575 - if ( ! empty( $meta_css ) ) {
576 - self::add_custom_css( 'ghostkit-custom-css', $meta_css );
577 - }
578 - }
478 + 'themeName' => $theme_data->get( 'Name' ),
479 + 'settings' => get_option( 'ghostkit_settings', array() ),
480 + 'disabledBlocks' => get_option( 'ghostkit_disabled_blocks', array() ),
579 481
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 - }
482 + // TODO: Due to different formats in scss and assets there is an offset.
483 + 'media_sizes' => array(
484 + 'sm' => $breakpoints['xs'],
485 + 'md' => $breakpoints['sm'],
486 + 'lg' => $breakpoints['md'],
487 + 'xl' => $breakpoints['lg'],
488 + ),
489 + 'timezone' => $timezone,
490 + 'googleMapsAPIKey' => get_option( 'ghostkit_google_maps_api_key' ),
491 + 'googleMapsAPIUrl' => 'https://maps.googleapis' . $gmaps_suffix . '/maps/api/js?v=3.exp&language=' . esc_attr( $gmaps_locale ),
492 + 'googleReCaptchaAPISiteKey' => $recaptcha_site_key,
493 + 'googleReCaptchaAPISecretKey' => is_admin() ? $recaptcha_secret_key : '',
494 + 'sidebars' => $sidebars,
495 + 'icons' => is_admin() ? apply_filters( 'gkt_icons_list', array() ) : array(),
496 + 'shapes' => is_admin() ? apply_filters( 'gkt_shapes_list', array() ) : array(),
497 + 'fonts' => is_admin() ? apply_filters( 'gkt_fonts_list', array() ) : array(),
498 + 'customTypographyList' => is_admin() ? apply_filters( 'gkt_custom_typography', array() ) : array(),
499 + 'admin_url' => admin_url(),
500 + 'admin_templates_url' => admin_url( 'edit.php?post_type=ghostkit_template' ),
501 + );
584 502
585 - // Local custom JS head.
586 - if ( $is_single ) {
587 - $meta_js_head = get_post_meta( $post_id, 'ghostkit_custom_js_head', true );
503 + $global_data = apply_filters( 'gkt_global_data', $global_data );
588 504
589 - if ( ! empty( $meta_js_head ) ) {
590 - self::add_custom_js( 'ghostkit-custom-js-head', $meta_js_head );
591 - }
592 - }
505 + wp_localize_script(
506 + 'ghostkit-helper',
507 + 'ghostkitVariables',
508 + $global_data
509 + );
593 510
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 - }
511 + // events fallback script.
512 + self::register_script(
513 + 'ghostkit-event-fallbacks',
514 + 'build/assets/js/event-fallbacks',
515 + array( 'ghostkit-helper' )
516 + );
598 517
599 - // Local custom JS foot.
600 - if ( $is_single ) {
601 - $meta_js_foot = get_post_meta( $post_id, 'ghostkit_custom_js_foot', true );
518 + // Fallback for classic themes.
519 + if ( ! wp_is_block_theme() ) {
520 + self::register_style(
521 + 'ghostkit-classic-theme-fallback',
522 + 'assets/css/fallback-classic-theme'
523 + );
524 + $css_deps[] = 'ghostkit-classic-theme-fallback';
525 + }
602 526
603 - if ( ! empty( $meta_js_foot ) ) {
604 - self::add_custom_js( 'ghostkit-custom-js-foot', $meta_js_foot, true );
605 - }
606 - }
527 + // Ghost Kit.
528 + self::register_style(
529 + 'ghostkit',
530 + 'build/gutenberg/style',
531 + $css_deps
532 + );
533 + wp_style_add_data( 'ghostkit', 'rtl', 'replace' );
607 534
608 - self::$already_added_custom_assets = true;
609 - }
535 + self::register_script(
536 + 'ghostkit',
537 + 'build/assets/js/main',
538 + $js_deps
539 + );
610 540
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 - }
541 + // Extensions.
542 + foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/extend/*/frontend.js' ) as $file ) {
543 + $ext_name = basename( dirname( $file ) );
544 + $ext_script_url = 'build/gutenberg/extend/' . $ext_name . '/frontend';
545 + $ext_js_deps = array( 'ghostkit' );
626 546
627 - foreach ( self::$skip_from_autoptimize as $name ) {
628 - if ( $result ) {
629 - $result .= ',';
630 - } else {
631 - $result = '';
632 - }
547 + switch ( $ext_name ) {
548 + case 'effects':
549 + $ext_js_deps[] = 'motion';
550 + break;
551 + }
633 552
634 - $result .= $name;
635 - }
553 + self::register_script(
554 + 'ghostkit-extension-' . $ext_name,
555 + $ext_script_url,
556 + array_unique( $ext_js_deps )
557 + );
558 + }
636 559
637 - return $result;
638 - }
560 + // Style Variants.
561 + foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/style-variants/*/frontend.js' ) as $template ) {
562 + $ext_name = basename( dirname( $template ) );
563 + $ext_script_url = 'build/gutenberg/style-variants/' . $ext_name . '/frontend';
564 + $ext_js_deps = array( 'ghostkit' );
639 565
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 );
566 + self::register_script(
567 + 'ghostkit-style-variant-' . $ext_name,
568 + $ext_script_url,
569 + array_unique( $ext_js_deps )
570 + );
571 + }
650 572
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 );
573 + // Blocks.
574 + foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/blocks/*/frontend.js' ) as $file ) {
575 + $block_name = basename( dirname( $file ) );
576 + $block_script_url = 'build/gutenberg/blocks/' . $block_name . '/frontend';
577 + $block_js_deps = array( 'ghostkit' );
656 578
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(){
579 + switch ( $block_name ) {
580 + case 'accordion':
581 + case 'alert':
582 + $block_js_deps[] = 'motion';
583 + break;
584 + case 'grid':
585 + case 'grid-column':
586 + if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
587 + $block_js_deps[] = 'jarallax-video';
588 + }
589 + if ( wp_script_is( 'jarallax' ) || wp_script_is( 'jarallax', 'registered' ) ) {
590 + $block_js_deps[] = 'jarallax';
591 + }
592 + break;
593 + case 'video':
594 + if ( wp_script_is( 'jarallax-video' ) || wp_script_is( 'jarallax-video', 'registered' ) ) {
595 + $block_js_deps[] = 'jarallax-video';
596 + }
597 + break;
598 + case 'gist':
599 + if ( wp_script_is( 'gist-simple' ) || wp_script_is( 'gist-simple', 'registered' ) ) {
600 + $block_js_deps[] = 'gist-simple';
601 + }
602 + break;
603 + case 'carousel':
604 + if ( wp_script_is( 'swiper' ) || wp_script_is( 'swiper', 'registered' ) ) {
605 + $block_js_deps[] = 'swiper';
606 + }
607 + break;
608 + case 'countdown':
609 + $block_js_deps[] = 'luxon';
610 + break;
611 + case 'form':
612 + if ( wp_script_is( 'google-recaptcha' ) || wp_script_is( 'google-recaptcha', 'registered' ) ) {
613 + $block_js_deps[] = 'google-recaptcha';
614 + }
615 + $block_js_deps[] = 'wp-i18n';
616 + break;
617 + case 'lottie':
618 + $block_js_deps[] = 'motion';
619 + $block_js_deps[] = 'lottie-player';
620 + break;
621 + case 'tabs':
622 + $block_name = 'tabs-v2';
623 + break;
624 + }
625 +
626 + self::register_script(
627 + 'ghostkit-block-' . $block_name,
628 + $block_script_url,
629 + array_unique( $block_js_deps )
630 + );
631 + }
632 + foreach ( glob( ghostkit()->plugin_path . 'build/gutenberg/blocks/*/styles/style.css' ) as $file ) {
633 + $block_name = basename( dirname( $file, 2 ) );
634 + $block_style_url = 'build/gutenberg/blocks/' . $block_name . '/styles/style';
635 + $block_css_deps = array( 'ghostkit' );
636 +
637 + switch ( $block_name ) {
638 + case 'gist':
639 + $block_css_deps[] = 'gist-simple';
640 + break;
641 + case 'carousel':
642 + $block_css_deps[] = 'swiper';
643 + break;
644 + case 'tabs':
645 + $block_name = 'tabs-v2';
646 + break;
647 + }
648 +
649 + self::register_style(
650 + 'ghostkit-block-' . $block_name,
651 + $block_style_url,
652 + array_unique( $block_css_deps )
653 + );
654 + wp_style_add_data( 'ghostkit-block-' . $block_name, 'rtl', 'replace' );
655 + }
656 +
657 + do_action( 'gkt_after_assets_register' );
658 + }
659 +
660 + /**
661 + * Enqueue styles in head.
662 + */
663 + public function wp_enqueue_head_assets() {
664 + self::enqueue_stored_assets( 'style' );
665 + self::enqueue_stored_assets( 'script' );
666 + }
667 +
668 + /**
669 + * Enqueue custom styles in head.
670 + */
671 + public function wp_enqueue_head_custom_assets() {
672 + self::enqueue_stored_assets( 'custom-css' );
673 + }
674 +
675 + /**
676 + * Enqueue scripts and styles in foot.
677 + */
678 + public function wp_enqueue_foot_assets() {
679 + self::enqueue_stored_assets( 'style' );
680 + self::enqueue_stored_assets( 'script' );
681 + }
682 +
683 + /**
684 + * Enqueue custom styles in foot.
685 + */
686 + public function wp_enqueue_foot_custom_assets() {
687 + self::enqueue_stored_assets( 'custom-css' );
688 + }
689 +
690 + /**
691 + * Enqueue blocks assets.
692 + *
693 + * @param array $blocks - blocks array.
694 + * @param array $location - blocks location [content,widget].
695 + */
696 + public function maybe_enqueue_blocks_assets( $blocks, $location ) {
697 + if ( self::$already_added_custom_assets ) {
698 + $location = 'widget';
699 + }
700 +
701 + self::enqueue( $blocks, $location );
702 + }
703 +
704 + /**
705 + * Add styles from blocks to the head section.
706 + *
707 + * @param int $post_id - current post id.
708 + */
709 + public function add_custom_assets( $post_id ) {
710 + $global_code = get_option( 'ghostkit_custom_code', array() );
711 +
712 + if ( is_singular() && ! $post_id ) {
713 + $post_id = get_the_ID();
714 + }
715 +
716 + $is_single = is_singular() && $post_id;
717 +
718 + // Global custom CSS.
719 + if ( $global_code && isset( $global_code['ghostkit_custom_css'] ) && $global_code['ghostkit_custom_css'] ) {
720 + self::add_custom_css( 'ghostkit-global-custom-css', $global_code['ghostkit_custom_css'] );
721 + }
722 +
723 + // Local custom CSS.
724 + if ( $is_single ) {
725 + $meta_css = get_post_meta( $post_id, 'ghostkit_custom_css', true );
726 +
727 + if ( ! empty( $meta_css ) ) {
728 + self::add_custom_css( 'ghostkit-custom-css', $meta_css );
729 + }
730 + }
731 +
732 + // Global custom JS head.
733 + if ( $global_code && isset( $global_code['ghostkit_custom_js_head'] ) && $global_code['ghostkit_custom_js_head'] ) {
734 + self::add_custom_js( 'ghostkit-global-custom-js-head', $global_code['ghostkit_custom_js_head'] );
735 + }
736 +
737 + // Local custom JS head.
738 + if ( $is_single ) {
739 + $meta_js_head = get_post_meta( $post_id, 'ghostkit_custom_js_head', true );
740 +
741 + if ( ! empty( $meta_js_head ) ) {
742 + self::add_custom_js( 'ghostkit-custom-js-head', $meta_js_head );
743 + }
744 + }
745 +
746 + // Global custom JS foot.
747 + if ( $global_code && isset( $global_code['ghostkit_custom_js_foot'] ) && $global_code['ghostkit_custom_js_foot'] ) {
748 + self::add_custom_js( 'ghostkit-global-custom-js-foot', $global_code['ghostkit_custom_js_foot'], true );
749 + }
750 +
751 + // Local custom JS foot.
752 + if ( $is_single ) {
753 + $meta_js_foot = get_post_meta( $post_id, 'ghostkit_custom_js_foot', true );
754 +
755 + if ( ! empty( $meta_js_foot ) ) {
756 + self::add_custom_js( 'ghostkit-custom-js-foot', $meta_js_foot, true );
757 + }
758 + }
759 +
760 + self::$already_added_custom_assets = true;
761 + }
762 +
763 + /**
764 + * Skip custom styles from Autoptimize.
765 + * We need this since generated CSS with custom breakpoints are excluded
766 + * from Autoptimize by default and this cause conflicts.
767 + *
768 + * @param string $result - allowed list.
769 + * @return string
770 + */
771 + public static function autoptimize_filter_css_exclude( $result ) {
772 + $upload_dir = defined( 'UPLOADS' ) ? UPLOADS : 'wp-content/uploads/';
773 +
774 + // By default in Autoptimize excluded folder `wp-content/uploads/`.
775 + // We need to check, if this folder is not excluded, then we
776 + // don't need to use our hack.
777 + if ( $result && strpos( $result, $upload_dir ) === false ) {
778 + return $result;
779 + }
780 +
781 + foreach ( self::$skip_from_autoptimize as $name ) {
782 + if ( $result ) {
783 + $result .= ',';
784 + } else {
785 + $result = '';
786 + }
787 +
788 + $result .= $name;
789 + }
790 +
791 + return $result;
792 + }
793 +
794 + /**
795 + * Add custom CSS.
796 + *
797 + * @param string $name - handle name.
798 + * @param string $css - code.
799 + */
800 + public static function add_custom_css( $name, $css ) {
801 + if ( ! wp_style_is( $name, 'enqueued' ) ) {
802 + $css = wp_kses( $css, array( '\'', '\"' ) );
803 + $css = str_replace( '&gt;', '>', $css );
804 +
805 + $allow_js_fallback = apply_filters( 'gkt_custom_css_allow_js_fallback', self::$already_added_custom_assets, $name, $css );
806 +
807 + // Enqueue custom CSS.
808 + if ( ! $allow_js_fallback ) {
809 + wp_register_style( $name, false, array(), GHOSTKIT_VERSION );
810 + wp_enqueue_style( $name );
811 + wp_add_inline_style( $name, $css );
812 +
813 + // Enqueue JS instead of CSS when rendering in <body> to prevent W3C errors.
814 + } elseif ( ! wp_script_is( $name, 'enqueued' ) ) {
815 + wp_register_script( $name, false, array(), GHOSTKIT_VERSION, true );
816 + wp_enqueue_script( $name );
817 + wp_add_inline_script(
818 + $name,
819 + '(function(){
664 820 var styleTag = document.createElement("style");
665 821 styleTag.id = "' . esc_attr( $name ) . '-inline-css";
666 822 styleTag.innerHTML = ' . wp_json_encode( $css ) . ';
667 823 document.body.appendChild(styleTag);
668 824 }());'
669 - );
670 - }
671 - }
825 + );
826 + }
827 + }
672 828
673 - self::$stored_assets[] = $name;
674 - }
829 + self::$stored_assets[] = $name;
830 + }
675 831
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 - }
832 + /**
833 + * Add custom JS.
834 + *
835 + * @param string $name - handle name.
836 + * @param string $js - code.
837 + * @param boolean $footer - print in footer.
838 + */
839 + public static function add_custom_js( $name, $js, $footer = false ) {
840 + wp_register_script( $name, '', array(), GHOSTKIT_VERSION, $footer );
841 + wp_enqueue_script( $name );
842 + wp_add_inline_script( $name, $js );
843 + }
688 844 }
689 845
690 846 new GhostKit_Assets();