| @@ -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. |