PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.2.6
ShopBuilder – WooCommerce Builder For Elementor v3.2.6
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
← All changes | app/Controllers/Hooks/ActionHooks.php +0 -105 3.4.23.2.6 View file →
@@ -13,9 +13,8 @@
13 13 use RadiusTheme\SB\Helpers\BuilderFns;
14 14 use RadiusTheme\SB\Models\TemplateSettings;
15 15 use RadiusTheme\SB\Elementor\Render\Render;
16 16 use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
17 -use RadiusTheme\SB\Modules\AbandonedCartRecovery\CartRecoveryCron;
18 17
19 18 defined( 'ABSPATH' ) || exit();
20 19
21 20 /**
@@ -28,15 +27,9 @@
28 27 * @return void
29 28 */
30 29 public static function init_hooks() {
31 30 add_action( 'rtsb/before/save/options', [ __CLASS__, 'clear_cron_schedule' ], 10, 3 );
32 - // Always register custom cron schedules so already-scheduled rtsb_* events
33 - // can reschedule even when the Abandoned Cart Recovery module is inactive,
34 - // preventing the "invalid_schedule" (Event schedule does not exist) error.
35 - add_filter( 'cron_schedules', [ CartRecoveryCron::instance(), 'abandoned_cart_cron' ] ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
36 31 add_action( 'wp_head', [ __CLASS__, 'og_metatags_for_sharing' ], 1 );
37 - add_action( 'wp_head', [ __CLASS__, 'reveal_builder_content_css' ], 2 );
38 - add_filter( 'style_loader_tag', [ __CLASS__, 'defer_non_critical_styles' ], 10, 4 );
39 32 add_action( 'woocommerce_share', [ __CLASS__, 'shopbuilder_share' ], 20 );
40 33 add_action( 'rtsb/wcqv/product/summary', [ __CLASS__, 'shopbuilder_share' ], 40 );
41 34 add_action( 'rtsb/shop/product/image', [ __CLASS__, 'render_image' ], 10, 2 );
42 35
@@ -87,9 +80,8 @@
87 80 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_login_form', 10 );
88 81 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
89 82 add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'woocommerce_checkout_login_form' ], 10 );
90 83 add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'woocommerce_checkout_coupon_form' ], 10 );
91 - add_action( 'woocommerce_after_checkout_form', [ __CLASS__, 'postcode_validation_placeholder' ] );
92 84 // My Account Order Page.
93 85 add_action( 'woocommerce_before_account_orders', [ __CLASS__, 'before_account_orders' ], 10 );
94 86 add_action( 'woocommerce_after_account_orders', [ __CLASS__, 'after_account_orders' ], 10 );
95 87
@@ -165,23 +157,10 @@
165 157 }
166 158
167 159
168 160 /**
169 - * Render postcode validation placeholder for fragment replacement.
170 - *
171 - * WooCommerce fragment replacement only targets existing DOM elements.
172 - * This placeholder ensures the server-side validation flag can be
173 - * injected via the update_order_review AJAX response.
174 - *
175 161 * @return void
176 162 */
177 - public static function postcode_validation_placeholder() {
178 - echo '<div class="rtsb-postcode-invalid" style="display:none;"></div>';
179 - }
180 -
181 - /**
182 - * @return void
183 - */
184 163 public static function woocommerce_checkout_coupon_form() {
185 164 echo '<div class="rtsb-notice">';
186 165 woocommerce_checkout_coupon_form();
187 166 echo '</div>';
@@ -336,92 +315,8 @@
336 315 }
337 316
338 317 Fns::print_html( '<meta property="og:site_name" content="' . get_bloginfo( 'name' ) . '" />', true );
339 318 Fns::print_html( '<meta name="twitter:card" content="summary" />', true );
340 - }
341 -
342 - /**
343 - * Reveal the builder content via a CSS-only failsafe.
344 - *
345 - * The builder wrapper is hidden by `.content-invisible`
346 - * (visibility:hidden;opacity:0) to avoid a flash of unstyled content, and is
347 - * normally un-hidden by JavaScript on DOMContentLoaded. On mobile that event
348 - * waits for the ShopBuilder JS bundle to download+parse, so the already-loaded
349 - * LCP product image cannot paint until the script runs — inflating LCP
350 - * "Element Render Delay".
351 - *
352 - * This inlines a tiny keyframe in the <head> that reveals the content from
353 - * CSS alone, capping the hidden window (default 200ms) regardless of when the
354 - * JS runs. First paint is therefore driven by HTML + CSS, not JavaScript. The
355 - * existing JS reveal still fires and simply removes the class earlier on fast
356 - * connections. Only emitted while the gate is active.
357 - *
358 - * @return void
359 - */
360 - public static function reveal_builder_content_css() {
361 - if ( is_admin() || ! Fns::content_invisible() ) {
362 - return;
363 - }
364 -
365 - /**
366 - * APPLY_FILTERS: rtsb/builder/content_reveal_delay
367 - *
368 - * Maximum time (ms) the builder content may stay hidden before the CSS
369 - * failsafe reveals it, independent of JavaScript. Lower = earlier paint,
370 - * higher = longer anti-FOUC window.
371 - *
372 - * @param int $delay Delay in milliseconds. Default 200.
373 - */
374 - $delay = (int) apply_filters( 'rtsb/builder/content_reveal_delay', 200 );
375 -
376 - $css = '.rtsb-builder-content.content-invisible{animation:rtsb-reveal-builder-content 1ms linear ' . absint( $delay ) . 'ms forwards}'
377 - . '@keyframes rtsb-reveal-builder-content{to{visibility:visible;opacity:1}}';
378 -
379 - Fns::print_html( '<style id="rtsb-content-reveal">' . $css . '</style>', true );
380 - }
381 -
382 - /**
383 - * Make non-critical ShopBuilder stylesheets non-render-blocking.
384 - *
385 - * Certain stylesheets (e.g. the icon font) are not required to paint the
386 - * first viewport, yet they sit in the <head> as render-blocking <link>s and
387 - * delay FCP. This loads them with `media="print"` and swaps to `all` on load,
388 - * with a <noscript> fallback so nothing breaks without JavaScript.
389 - *
390 - * @param string $tag The <link> tag for the enqueued style.
391 - * @param string $handle The style handle.
392 - * @param string $href The stylesheet source URL.
393 - * @param string $media The media attribute.
394 - *
395 - * @return string
396 - */
397 - public static function defer_non_critical_styles( $tag, $handle, $href, $media ) {
398 - if ( is_admin() ) {
399 - return $tag;
400 - }
401 -
402 - /**
403 - * APPLY_FILTERS: rtsb/frontend/non_critical_styles
404 - *
405 - * Handles of ShopBuilder stylesheets to load non-render-blocking. Only
406 - * include styles that are NOT needed to paint the first viewport.
407 - *
408 - * @param array $handles Style handles. Default: icon font.
409 - */
410 - $handles = (array) apply_filters( 'rtsb/frontend/non_critical_styles', [ 'rtsb-fonts' ] );
411 -
412 - if ( ! in_array( $handle, $handles, true ) || false !== strpos( $tag, "media='print'" ) ) {
413 - return $tag;
414 - }
415 -
416 - $deferred = preg_replace(
417 - "/media=(['\"])" . preg_quote( $media, '/' ) . "\\1/",
418 - 'media="print" onload="this.media=\'all\';this.onload=null;"',
419 - $tag
420 - );
421 -
422 - // Fallback to the original blocking tag when JavaScript is unavailable.
423 - return $deferred . '<noscript>' . $tag . '</noscript>';
424 319 }
425 320
426 321 /**
427 322 * Render image.