enabled_modules = $this->get_enabled_modules(); $this->enabled_modules_js = $this->get_enabled_modules_js_with_context(); $this->enabled_modules_css = $this->get_enabled_modules_css_with_context(); $this->enabled_el_widgets = $this->get_enabled_el_widgets(); $this->enabled_widgets = $this->get_enabled_widgets_with_context(); $this->suffix = is_rtl() ? '-rtl' : ''; $this->dir = is_rtl() ? trailingslashit( 'rtl' ) : trailingslashit( 'css' ); $this->contextual_loading = Fns::is_contextual_loading(); } /** * Get bundled JS assets by context. * * @return array */ public function get_bundled_js_by_context() { $js_files_by_context = $this->get_contextual_assets( 'js' ); $bundled_contexts = []; foreach ( $js_files_by_context as $context => $files ) { if ( empty( $files ) ) { continue; } $bundler = new AssetBundler( "rtsb-bundled-$context", $files, 'js' ); $src = $bundler->build(); $deps = [ 'jquery', 'rtsb-tipsy' ]; $builder_page_id = BuilderFns::builder_page_id_by_page(); if ( Fns::is_elementor_page( $builder_page_id ) ) { $deps[] = 'imagesloaded'; } $bundled_contexts[ $context ] = [ 'handle' => "rtsb-bundled-$context", 'src' => $src, 'deps' => apply_filters( 'rtsb/optimizer/scripts/deps', $deps ), 'footer' => true, ]; } return $bundled_contexts; } /** * Returns assets grouped by context with `global` inherited for each. * * @param string $type 'css' or 'js'. * * @return array */ public function get_contextual_assets( $type ) { $all_contexts = 'js' === $type ? $this->get_scripts_by_context() : $this->get_styles_by_context(); $normalized = array_map( function ( $paths ) { return array_unique( $paths ); }, $all_contexts ); foreach ( $normalized as $context => $paths ) { if ( 'global' === $context ) { continue; } $normalized[ $context ] = array_unique( array_merge( $normalized['global'] ?? [], $paths ) ); } return $normalized; } /** * Returns scripts grouped by context. * * @return array */ public function get_scripts_by_context() { $context_scripts = []; // Add core-init globally. $core_path = $this->context()->get_assets_path( 'js/frontend/core-init.js' ); $context_scripts['global'][] = $core_path; $shared_registry = apply_filters( 'rtsb/optimizer/scripts/shared/components', [ 'coupon' => [ 'path' => rtsb()->get_assets_path( 'js/modules/shared/coupon.js' ), 'modules' => [ 'shopify-checkout', 'quick-checkout' ], 'widgets' => [ 'cart-coupon-form', 'coupon-form' ], 'context' => Fns::is_module_active( 'quick_checkout' ) ? [ 'global' ] : [ 'cart', 'checkout' ], ], 'quantity' => [ 'path' => rtsb()->get_assets_path( 'js/modules/shared/cart-quantity-handler.js' ), 'modules' => [ 'sticky-add-to-cart' ], 'widgets' => [ 'cart-table', 'product-add-to-cart' ], 'context' => Fns::is_module_active( 'quick_view' ) ? [ 'global' ] : [ 'product', 'cart' ], ], ] ); $shared_loaded = []; // Load module-based shared scripts. foreach ( $this->enabled_modules_js as $module_slug => $module ) { if ( ! $module['enabled'] ) { continue; } foreach ( $shared_registry as $key => $data ) { if ( in_array( $module_slug, $data['modules'], true ) ) { $shared_loaded[ $key ] = $data; } } $module_slug = apply_filters( 'rtsb/optimizer/module/remap', $module_slug ); $path = Fns::locate_asset( "js/modules/$module_slug.js" ); if ( $path ) { $category = ! empty( $module['category'] ) ? $module['category'] : [ 'global' ]; foreach ( $category as $cat ) { $context_scripts[ $cat ][] = $path; } } } // Elementor-specific widget scripts. if ( defined( 'ELEMENTOR_VERSION' ) && Fns::should_load_elementor_scripts() ) { foreach ( $this->enabled_widgets as $slug => $widget ) { if ( ! $widget['enabled'] ) { continue; } foreach ( $shared_registry as $key => $data ) { if ( isset( $shared_loaded[ $key ] ) ) { continue; } if ( in_array( $slug, $data['widgets'], true ) ) { $shared_loaded[ $key ] = $data; } } $path = Fns::locate_asset( "js/frontend/elementor/$slug.js" ); if ( $path ) { $category = ! empty( $widget['category'] ) ? $widget['category'] : 'global'; if ( 'general' === $category ) { $category = 'global'; } $context_scripts[ $category ][] = $path; } } $core_el = Fns::locate_asset( 'js/frontend/elementor/el-frontend-core.js' ); if ( $core_el ) { $context_scripts['global'][] = $core_el; } } foreach ( $shared_loaded as $data ) { if ( empty( $data['path'] ) ) { continue; } $contexts = $data['context'] ?? [ 'global' ]; foreach ( (array) $contexts as $ctx ) { $context_scripts[ $ctx ][] = $data['path']; } } $context_scripts = apply_filters( 'rtsb/optimizer/scripts/shared', $context_scripts, $this->enabled_modules, $this->enabled_widgets ); return apply_filters( 'rtsb/optimizer/scripts', $context_scripts ); } /** * Get structured JS scripts. * * @return array[] */ public function get_scripts() { $scripts = []; $shared_scripts = []; $shared_loaded = []; // Load core. $scripts[] = $this->context()->get_assets_path( 'js/frontend/core-init.js' ); $shared_registry = apply_filters( 'rtsb/optimizer/scripts/shared/components', [ 'coupon' => [ 'path' => rtsb()->get_assets_path( 'js/modules/shared/coupon.js' ), 'modules' => [ 'shopify-checkout', 'quick-checkout' ], 'widgets' => [ 'cart-coupon-form', 'coupon-form' ], ], 'quantity' => [ 'path' => rtsb()->get_assets_path( 'js/modules/shared/cart-quantity-handler.js' ), 'modules' => [ 'sticky-add-to-cart' ], 'widgets' => [ 'cart-table', 'product-add-to-cart' ], ], ] ); foreach ( $this->enabled_modules as $module ) { foreach ( $shared_registry as $key => $data ) { if ( in_array( $module, $data['modules'], true ) ) { $shared_loaded[ $key ] = true; } } $module = apply_filters( 'rtsb/optimizer/module/remap', $module ); $path = Fns::locate_asset( "js/modules/$module.js" ); if ( $path ) { $scripts[] = $path; } } if ( defined( 'ELEMENTOR_VERSION' ) && Fns::should_load_elementor_scripts() ) { foreach ( $this->enabled_el_widgets as $widget ) { foreach ( $shared_registry as $key => $data ) { if ( isset( $shared_loaded[ $key ] ) ) { continue; } if ( in_array( $widget, $data['widgets'], true ) ) { $shared_loaded[ $key ] = true; } } $path = Fns::locate_asset( "js/frontend/elementor/$widget.js" ); if ( $path ) { $scripts[] = $path; } } $scripts[] = Fns::locate_asset( 'js/frontend/elementor/el-frontend-core.js' ); } foreach ( $shared_loaded as $key => $_ ) { if ( isset( $shared_registry[ $key ]['path'] ) ) { $shared_scripts[] = $shared_registry[ $key ]['path']; } } $shared_scripts = apply_filters( 'rtsb/optimizer/scripts/shared', $shared_scripts, $this->enabled_modules, $this->enabled_el_widgets ); $scripts = array_merge( $scripts, array_unique( $shared_scripts ) ); return array_unique( apply_filters( 'rtsb/optimizer/scripts', $scripts ) ); } /** * Get structured CSS styles. * * @return array[] */ public function get_styles() { $elementor_styles = defined( 'ELEMENTOR_VERSION' ) && Fns::should_load_elementor_scripts() ? $this->get_elementor_styles() : []; return apply_filters( 'rtsb/optimizer/styles', array_merge( $this->get_base_styles(), $this->get_module_styles(), $elementor_styles ) ); } /** * Get structured CSS styles. * * @return array[] */ public function get_styles_by_context() { $core = $this->get_base_styles_by_context(); $modules = $this->get_module_styles_by_context(); $elementor = defined( 'ELEMENTOR_VERSION' ) && Fns::should_load_elementor_scripts() ? $this->get_elementor_styles_by_context() : []; $merged = []; foreach ( [ $core, $modules, $elementor ] as $group ) { foreach ( $group as $context => $paths ) { foreach ( $paths as $file ) { $merged[ $context ][] = $file; } } } return apply_filters( 'rtsb/optimizer/styles/by_context', $merged ); } /** * Get base styles. * * @return array */ protected function get_base_styles() { return apply_filters( 'rtsb/optimizer/styles/base', [ rtsb()->get_assets_path( 'css/frontend/rtsb-fonts.css' ), Fns::locate_asset( $this->dir . 'frontend/frontend-core' . $this->suffix . '.css' ), ] ); } /** * Get base styles. * * @return array */ protected function get_base_styles_by_context() { $styles = array_filter( [ rtsb()->get_assets_path( 'css/frontend/rtsb-fonts.css' ), Fns::locate_asset( $this->dir . 'frontend/frontend-core' . $this->suffix . '.css' ), ] ); return [ 'global' => $styles, ]; } /** * Get module styles. * * @return array */ protected function get_module_styles() { $styles = []; if ( empty( $this->enabled_modules ) ) { return $styles; } $styles = array_merge( $styles, $this->get_shared_module_styles() ); foreach ( $this->enabled_modules as $module ) { $module = apply_filters( 'rtsb/optimizer/module/remap', $module ); $path = Fns::locate_asset( "{$this->dir}modules/$module$this->suffix.css" ); if ( $path ) { $styles[] = $path; } } $styles = apply_filters( 'rtsb/optimizer/styles/module', $styles ); return array_unique( $styles ); } /** * Get module styles. * * @return array */ protected function get_module_styles_by_context() { $content_styles = []; if ( empty( $this->enabled_modules_css ) ) { return $content_styles; } $content_styles = array_merge( $content_styles, $this->get_shared_module_styles() ); foreach ( $this->enabled_modules_css as $module_slug => $module ) { if ( ! $module['enabled'] ) { continue; } $module_slug = apply_filters( 'rtsb/optimizer/module/remap', $module_slug ); $path = Fns::locate_asset( "{$this->dir}modules/$module_slug$this->suffix.css" ); if ( $path ) { $category = ! empty( $module['category'] ) ? $module['category'] : [ 'global' ]; foreach ( $category as $cat ) { $content_styles[ $cat ][] = $path; } } } return apply_filters( 'rtsb/optimizer/styles/module', $content_styles ); } /** * Get Elementor styles. * * @return array */ protected function get_elementor_styles() { $styles = [ Fns::locate_asset( $this->dir . 'frontend/elementor/el-frontend-core' . $this->suffix . '.css' ) ]; $shared = $this->contextual_loading ? $this->get_elementor_shared_widget_styles_by_context() : $this->get_elementor_shared_widget_styles(); $styles = array_merge( $styles, $shared ); foreach ( $this->enabled_el_widgets as $widget ) { $path = Fns::locate_asset( "{$this->dir}frontend/elementor/$widget$this->suffix.css" ); if ( $path ) { $styles[] = $path; } } return array_unique( $styles ); } /** * Get Elementor styles. * * @return array */ protected function get_elementor_styles_by_context() { $styles = []; $styles['global'] = [ Fns::locate_asset( $this->dir . 'frontend/elementor/el-frontend-core' . $this->suffix . '.css' ), ]; $shared_styles = $this->get_elementor_shared_widget_styles_by_context(); foreach ( $shared_styles as $context => $context_styles ) { foreach ( (array) $context_styles as $style ) { $styles[ $context ][] = $style; } } foreach ( $this->enabled_widgets as $widget_slug => $info ) { if ( empty( $info['enabled'] ) ) { continue; } $contexts = $info['category'] ?? [ 'global' ]; foreach ( (array) $contexts as $ctx ) { if ( 'general' === $ctx ) { $ctx = 'global'; } $path = Fns::locate_asset( "{$this->dir}frontend/elementor/{$widget_slug}{$this->suffix}.css" ); if ( $path ) { $styles[ $ctx ][] = $path; } } } return $styles; } /** * Get shared styles based on enabled modules. * * @return array */ protected function get_shared_module_styles() { $shared_styles_map = apply_filters( 'rtsb/optimizer/styles/modules/shared', [ [ 'modules' => [ 'wishlist', 'compare' ], 'file_name' => 'shared/module-buttons', 'context' => [ 'global' ], ], [ 'modules' => [ 'quick-view', 'product-size-chart', 'quick-checkout' ], 'file_name' => 'shared/modal-layouts', 'context' => [ 'global' ], ], ] ); // Add global shared. $shared_by_components = $this->get_shared_style_components(); if ( ! $this->contextual_loading ) { foreach ( $shared_by_components as $key => $data ) { if ( ! empty( $data['modules'] ) && array_intersect( $data['modules'], $this->enabled_modules ) ) { $shared_styles_map[] = [ 'modules' => $data['modules'], 'file_name' => $data['file_name'], ]; $this->shared_loaded[ $key ] = true; } } $styles = []; if ( empty( $this->enabled_modules ) ) { return $styles; } foreach ( $shared_styles_map as $group ) { if ( array_intersect( $group['modules'], $this->enabled_modules ) ) { $styles[] = Fns::locate_asset( "{$this->dir}modules/{$group['file_name']}{$this->suffix}.css" ); } } return array_unique( $styles ); } $enabled_widget_slugs = array_keys( array_filter( $this->enabled_widgets, fn( $w ) => ! empty( $w['enabled'] ) ) ); $enabled_module_slugs = array_keys( array_filter( $this->enabled_modules_css ?? [], fn( $m ) => ! empty( $m['enabled'] ) ) ); foreach ( $shared_by_components as $key => $data ) { $modules = $data['modules'] ?? []; $widgets = $data['widgets'] ?? []; if ( array_intersect( $modules, $enabled_module_slugs ) || array_intersect( $widgets, $enabled_widget_slugs ) ) { $shared_styles_map[] = [ 'modules' => $modules, 'widgets' => $widgets, 'file_name' => $data['file_name'], 'context' => $data['context'] ?? [ 'global' ], ]; $this->shared_loaded[ $key ] = true; } } $styles = []; foreach ( $shared_styles_map as $group ) { $modules = $group['modules'] ?? []; $widgets = $group['widgets'] ?? []; $has_enabled_module = array_intersect( $modules, $enabled_module_slugs ); $has_enabled_widget = array_intersect( $widgets, $enabled_widget_slugs ); if ( ! $has_enabled_module && ! $has_enabled_widget ) { continue; } foreach ( (array) $group['context'] as $ctx ) { $path = Fns::locate_asset( "{$this->dir}modules/{$group['file_name']}{$this->suffix}.css" ); if ( $path ) { $styles[ $ctx ][] = $path; } } } return $styles; } /** * Get shared Elementor widget styles based on enabled widgets. * * @return array */ protected function get_elementor_shared_widget_styles() { $shared_styles_map = $this->get_elementor_shared_styles_map(); // Add global shared. $shared_by_components = $this->get_shared_style_components(); $styles = []; foreach ( $shared_by_components as $key => $data ) { if ( isset( $this->shared_loaded[ $key ] ) ) { continue; } if ( ! empty( $data['widgets'] ) && array_intersect( $data['widgets'], $this->enabled_el_widgets ) ) { $path = Fns::locate_asset( "{$this->dir}modules/{$data['file_name']}{$this->suffix}.css" ); if ( $path ) { $styles[] = $path; } } } foreach ( $shared_styles_map as $group ) { if ( array_intersect( $group['widgets'], $this->enabled_el_widgets ) ) { $styles[] = Fns::locate_asset( "{$this->dir}frontend/elementor/{$group['file_name']}$this->suffix.css" ); } } return array_unique( $styles ); } /** * Get shared Elementor widget styles based on enabled widgets. * * @return array */ protected function get_elementor_shared_widget_styles_by_context() { $shared_styles_map = $this->get_elementor_shared_styles_map(); // Add global shared. $shared_by_components = $this->get_shared_style_components(); $styles = []; $enabled_widget_slugs = array_keys( array_filter( $this->enabled_widgets ?? [], fn( $widget ) => ! empty( $widget['enabled'] ) ) ); foreach ( $shared_by_components as $key => $data ) { if ( isset( $this->shared_loaded[ $key ] ) ) { continue; } if ( ! empty( $data['widgets'] ) && array_intersect( $data['widgets'], $enabled_widget_slugs ) ) { $contexts = $data['context'] ?? [ 'global' ]; foreach ( (array) $contexts as $ctx ) { if ( 'general' === $ctx ) { $ctx = 'global'; } $path = Fns::locate_asset( "{$this->dir}modules/{$data['file_name']}{$this->suffix}.css" ); if ( $path ) { $styles[ $ctx ][] = $path; } } $this->shared_loaded[ $key ] = true; } } foreach ( $shared_styles_map as $group ) { if ( ! empty( $group['widgets'] ) && array_intersect( $group['widgets'], $enabled_widget_slugs ) ) { $contexts = $group['context'] ?? [ 'global' ]; if ( ! is_array( $contexts ) ) { $contexts = [ $contexts ]; } foreach ( $contexts as $ctx ) { $path = Fns::locate_asset( "{$this->dir}frontend/elementor/{$group['file_name']}{$this->suffix}.css" ); if ( $path ) { $styles[ $ctx ][] = $path; } } } } return $styles; } /** * Get Elementor shared styles map. * * @return array */ private function get_elementor_shared_styles_map() { return apply_filters( 'rtsb/optimizer/styles/elementor/shared', [ [ 'widgets' => [ 'products-grid', 'products-list', 'products-slider', 'products-single-cateogory', 'product-cateogories', 'products-archive-catalog-custom', 'advanced-heading', 'dropcaps', 'shopbuilder-button', 'shopbuilder-cta', 'shopbuilder-info-box', 'shopbuilder-flip-box', 'shopbuilder-pricing-table', 'shopbuilder-counter', 'shopbuilder-countdown', 'shopbuilder-progress-bar', 'image-accordion', 'shopbuilder-faq', 'logo-slider-and-grid', 'testimonial', 'team-member', 'post-grid', 'post-list', 'upsells-product-custom', 'upsells-products-slider-custom', 'related-product-custom', 'related-products-slider-custom', 'cross-sells-custom', 'cross-sells-custom-slider', ], 'file_name' => 'shared/el-grid', 'context' => [ 'global' ], ], [ 'widgets' => [ 'shopbuilder-button', 'shopbuilder-cta', 'shopbuilder-info-box', 'shopbuilder-flip-box', 'shopbuilder-pricing-table', ], 'file_name' => 'shared/shopbuilder-button', 'context' => [ 'global' ], ], [ 'widgets' => [ 'products-grid', 'products-list', 'products-slider', 'products-single-cateogory', 'product-cateogories', 'products-archive-catalog-custom', 'upsells-product-custom', 'upsells-products-slider-custom', 'related-product-custom', 'related-products-slider-custom', 'cross-sells-custom', 'cross-sells-custom-slider', ], 'file_name' => 'shared/el-general-product', 'context' => [ 'global' ], ], [ 'widgets' => [ 'products-grid', 'products-slider', 'products-archive-catalog-custom', ], 'file_name' => 'shared/products-grid-slider', 'context' => [ 'global' ], ], [ 'widgets' => [ 'products-list', 'products-archive-catalog-custom', ], 'file_name' => 'shared/products-list', 'context' => [ 'global' ], ], [ 'widgets' => [ 'post-grid', 'post-list' ], 'file_name' => 'shared/post', 'context' => [ 'global' ], ], [ 'widgets' => [ 'products-archive-catalog', 'products-archive-catalog-custom', ], 'file_name' => 'shared/products-archive', 'context' => [ 'shop' ], ], [ 'widgets' => [ 'product-title', 'product-description', 'product-short-description', 'product-images', 'product-onsale', 'product-additional-info', 'product-price', 'product-meta', 'product-categories', 'product-rating', 'product-tags', 'product-sku', 'product-stock', 'actions-button', 'product-add-to-cart', 'product-share', 'product-tabs', 'product-reviews', 'upsells-product', 'related-product', ], 'file_name' => 'shared/single-product', 'context' => [ 'product' ], ], [ 'widgets' => [ 'cart-table', 'cart-totals', 'cross-sells', ], 'file_name' => 'shared/cart', 'context' => [ 'cart' ], ], ] ); } /** * Get enabled modules. Filterable. * * @return array */ protected function get_enabled_modules() { $module_list = Fns::get_modules_list(); $enabled = []; foreach ( $module_list as $slug => $info ) { if ( defined( 'RTWPVG_VERSION' ) && 'variation_gallery' === $slug ) { continue; } if ( defined( 'RTWPVS_VERSION' ) && 'variation_swatches' === $slug ) { continue; } if ( ! empty( $info['active'] ) ) { $enabled[] = str_replace( '_', '-', sanitize_key( $slug ) ); } } return $enabled; } /** * Get enabled modules JS with context. * * @return array */ protected function get_enabled_modules_js_with_context() { $module_list = Fns::get_modules_list(); $modules = []; $context = apply_filters( 'rtsb/optimizer/modules/js_context', [ 'checkout_fields_editor' => [ 'checkout' ], 'shopify_checkout' => [ 'checkout' ], ] ); foreach ( $module_list as $slug => $info ) { if ( defined( 'RTWPVG_VERSION' ) && 'variation_gallery' === $slug ) { continue; } if ( defined( 'RTWPVS_VERSION' ) && 'variation_swatches' === $slug ) { continue; } $clean_slug = str_replace( '_', '-', sanitize_key( $slug ) ); $is_enabled = isset( $info['active'] ) && 'on' === $info['active']; $modules[ $clean_slug ] = [ 'enabled' => $is_enabled, 'category' => ! empty( $context[ $slug ] ) ? $context[ $slug ] : [ 'global' ], ]; } return $modules; } /** * Get enabled modules CSS with context. * * @return array */ protected function get_enabled_modules_css_with_context() { $module_list = Fns::get_modules_list(); $modules = []; $context = apply_filters( 'rtsb/optimizer/modules/css_context', [ 'checkout_fields_editor' => [ 'checkout' ], 'shopify_checkout' => [ 'checkout' ], ] ); foreach ( $module_list as $slug => $info ) { if ( defined( 'RTWPVG_VERSION' ) && 'variation_gallery' === $slug ) { continue; } if ( defined( 'RTWPVS_VERSION' ) && 'variation_swatches' === $slug ) { continue; } $clean_slug = str_replace( '_', '-', sanitize_key( $slug ) ); $is_enabled = isset( $info['active'] ) && 'on' === $info['active']; $modules[ $clean_slug ] = [ 'enabled' => $is_enabled, 'category' => ! empty( $context[ $slug ] ) ? $context[ $slug ] : [ 'global' ], ]; } return $modules; } /** * Get enabled modules. * * @return array */ protected function get_enabled_el_widgets() { $widget_data = Fns::get_widgets_list(); $enabled = []; foreach ( $widget_data as $slug => $info ) { if ( isset( $info['active'] ) && 'on' === $info['active'] ) { $enabled[] = str_replace( '_', '-', sanitize_key( $slug ) ); } } return $enabled; } /** * Get enabled widgets with categories. * * @return array */ protected function get_enabled_widgets_with_context() { $widget_list = Fns::get_widgets_list(); $widgets = []; foreach ( $widget_list as $slug => $info ) { $clean_slug = str_replace( '_', '-', sanitize_key( $slug ) ); $is_enabled = isset( $info['active'] ) && 'on' === $info['active']; $widgets[ $clean_slug ] = [ 'enabled' => $is_enabled, 'category' => ! empty( $widget_list[ $slug ]['category'] ) ? $widget_list[ $slug ]['category'] : 'global', ]; } return $widgets; } /** * Populate JS/CSS file arrays based on active modules. * * @return void */ protected function collect_assets() { static $ran = false; if ( $ran ) { return; } $ran = true; $this->js_files = $this->contextual_loading ? $this->get_scripts_by_context() : array_unique( $this->get_scripts() ); $this->css_files = $this->contextual_loading ? $this->get_styles_by_context() : array_unique( $this->get_styles() ); } /** * Build and return the final bundled and minified CSS and JS. * * @return array */ public function get_bundled_assets() { if ( null !== $this->bundled_assets ) { return $this->bundled_assets; } $this->collect_assets(); $this->bundled_assets = [ 'js' => $this->contextual_loading ? $this->get_bundled_js_by_context() : $this->get_bundled_js(), 'css' => $this->contextual_loading ? $this->get_bundled_css_by_context() : $this->get_bundled_css(), ]; return $this->bundled_assets; } /** * Load optimized assets and return them by type * * @param string $type 'css' or 'js'. * * @return array */ public function load_optimized_assets( $type = 'css' ) { if ( isset( self::$loaded_types[ $type ] ) ) { return []; } $assets = []; $bundled = $this->get_bundled_assets(); $context = Fns::detect_context(); if ( $this->contextual_loading ) { if ( 'js' === $type && ! empty( $bundled['js'] ) ) { $ctx = isset( $bundled['js'][ $context ] ) ? $context : 'global'; if ( $ctx ) { $assets = (array) $bundled['js'][ $ctx ]; } } if ( 'css' === $type && ! empty( $bundled['css'] ) ) { $ctx = isset( $bundled['css'][ $context ] ) ? $context : 'global'; if ( $ctx ) { $assets = (array) $bundled['css'][ $ctx ]; } } } else { if ( 'js' === $type && ! empty( $bundled['js'] ) ) { $assets = (array) $this->bundled_assets['js']; } if ( 'css' === $type && ! empty( $bundled['css'] ) ) { $assets = (array) $this->bundled_assets['css']; } } self::$loaded_types[ $type ] = true; return $assets; } /** * Get bundled JS, with caching to prevent multiple builds. * * @return array|null */ protected function get_bundled_js() { if ( null !== $this->bundled_js ) { return $this->bundled_js; } if ( empty( $this->js_files ) ) { return null; } $handle = 'rtsb-bundled'; $bundler = new AssetBundler( $handle, $this->js_files, 'js' ); $src = $bundler->build(); $deps = [ 'jquery', 'rtsb-tipsy' ]; $builder_page_id = BuilderFns::builder_page_id_by_page(); if ( Fns::is_elementor_page( $builder_page_id ) ) { $deps[] = 'imagesloaded'; } $this->bundled_js = [ 'handle' => $handle, 'src' => $src, 'deps' => apply_filters( 'rtsb/optimizer/scripts/deps', $deps ), 'footer' => true, ]; return $this->bundled_js; } /** * Get bundled CSS, with caching to prevent multiple builds. * * @return array|null */ protected function get_bundled_css() { if ( null !== $this->bundled_css ) { return $this->bundled_css; } if ( empty( $this->css_files ) ) { return null; } $bundler = new AssetBundler( 'rtsb-bundled', $this->css_files, 'css' ); $src = $bundler->build(); $this->bundled_css = [ 'handle' => 'rtsb-bundled', 'src' => $src, ]; return $this->bundled_css; } /** * Get bundled CSS by context * * @return array|null */ public function get_bundled_css_by_context() { $css_files_by_context = $this->get_contextual_assets( 'css' ); $bundled_contexts = []; foreach ( $css_files_by_context as $context => $files ) { if ( empty( $files ) ) { continue; } $bundler = new AssetBundler( "rtsb-bundled-$context", $files, 'css' ); $src = $bundler->build(); $bundled_contexts[ $context ] = [ 'handle' => "rtsb-bundled-$context", 'src' => $src, ]; } return $bundled_contexts; } /** * Forcefully regenerate bundled JS and CSS assets. * * @return array */ public function regenerate_bundles() { $this->bundled_js = null; $this->bundled_css = null; $this->js_files = []; $this->css_files = []; $this->collect_assets(); return [ 'js' => $this->contextual_loading ? $this->get_bundled_js_by_context() : $this->get_bundled_js(), 'css' => $this->contextual_loading ? $this->get_bundled_css_by_context() : $this->get_bundled_css(), ]; } /** * Get context. * * @return object */ private function context() { return ( function_exists( 'rtsbpro' ) && rtsb()->has_pro() ) ? rtsbpro() : rtsb(); } /** * Get shared style mappings for modules and widgets. * * @return array */ private function get_shared_style_components() { return apply_filters( 'rtsb/optimizer/styles/shared/components', [ 'checkout' => [ 'file_name' => 'shared/checkout', 'modules' => [ 'quick-checkout', 'shopify-checkout' ], 'widgets' => [ 'billing-form', 'shipping-form', 'order-notes', 'order-review', 'checkout-payment', 'coupon-form', 'checkout-login-form', 'shipping-method', ], 'context' => [ 'global' ], ], 'slider' => [ 'file_name' => 'shared/slider-core', 'modules' => [ 'variation-gallery' ], 'widgets' => [ 'products-slider', 'team-member', 'upsells-products-slider-custom', 'related-products-slider-custom', 'cross-sells-custom-slider', 'hero-slider', ], 'context' => [ 'global' ], ], ] ); } }