diff --git a/includes/class-wc-frontend-scripts.php b/includes/class-wc-frontend-scripts.php index 3c8d03c3136..5050ad6dfcc 100644 --- a/includes/class-wc-frontend-scripts.php +++ b/includes/class-wc-frontend-scripts.php @@ -5,29 +5,40 @@ if ( ! defined( 'ABSPATH' ) ) { } /** - * Handle frontend forms + * Handle frontend scripts * * @class WC_Frontend_Scripts - * @version 2.2.0 + * @version 2.3.0 * @package WooCommerce/Classes/ * @category Class * @author WooThemes */ class WC_Frontend_Scripts { + /** + * Contains an array of script handles registered by WC + * @var array + */ + private static $scripts = array(); + + /** + * Contains an array of script handles localized by WC + * @var array + */ + private static $wp_localize_scripts = array(); + /** * Hook in methods */ public static function init() { add_action( 'wp_enqueue_scripts', array( __CLASS__, 'load_scripts' ) ); - add_action( 'wp_print_scripts', array( __CLASS__, 'check_jquery' ), 25 ); add_action( 'wp_print_scripts', array( __CLASS__, 'localize_printed_scripts' ), 5 ); add_action( 'wp_print_footer_scripts', array( __CLASS__, 'localize_printed_scripts' ), 5 ); - add_filter( 'woocommerce_enqueue_styles', array( __CLASS__, 'backwards_compat' ) ); } /** * Get styles for the frontend + * @access private * @return array */ public static function get_styles() { @@ -53,77 +64,97 @@ class WC_Frontend_Scripts { ) ); } + /** + * Register a script for use + * + * @uses wp_register_script() + * @access private + * @param string $handle [description] + * @param string $path [description] + * @param array $deps [description] + * @param string $version [description] + * @param boolean $in_footer [description] + */ + private static function register_script( $handle, $path, $deps = array( 'jquery' ), $version = WC_VERSION, $in_footer = true ) { + self::$scripts[] = $handle; + wp_register_script( $handle, $path, $deps, $version, $in_footer ); + } + + /** + * Register and enqueue a script for use + * + * @uses wp_enqueue_script() + * @access private + * @param string $handle [description] + * @param string $path [description] + * @param array $deps [description] + * @param string $version [description] + * @param boolean $in_footer [description] + */ + private static function enqueue_script( $handle, $path = '', $deps = array( 'jquery' ), $version = WC_VERSION, $in_footer = true ) { + if ( ! in_array( $handle, self::$scripts ) && $path ) { + self::register_script( $handle, $path, $deps, $version, $in_footer ); + } + wp_enqueue_script( $handle ); + } + /** * Register/queue frontend scripts. * * @access public - * @return void */ public static function load_scripts() { global $post; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; - $lightbox_en = get_option( 'woocommerce_enable_lightbox' ) == 'yes' ? true : false; - $ajax_cart_en = get_option( 'woocommerce_enable_ajax_add_to_cart' ) == 'yes' ? true : false; + $lightbox_en = 'yes' === get_option( 'woocommerce_enable_lightbox' ); + $ajax_cart_en = 'yes' === get_option( 'woocommerce_enable_ajax_add_to_cart' ); $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; $frontend_script_path = $assets_path . 'js/frontend/'; // Register any scripts for later use, or used as dependencies - wp_register_script( 'chosen', $assets_path . 'js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), '1.0.0', true ); - wp_register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.60', true ); - wp_register_script( 'jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array( 'jquery' ), '1.0.2', true ); - wp_register_script( 'wc-credit-card-form', $assets_path . 'js/frontend/credit-card-form' . $suffix . '.js', array( 'jquery', 'jquery-payment' ), WC_VERSION, true ); - - wp_register_script( 'wc-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); - wp_register_script( 'wc-single-product', $frontend_script_path . 'single-product' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); - wp_register_script( 'wc-country-select', $frontend_script_path . 'country-select' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); - wp_register_script( 'wc-address-i18n', $frontend_script_path . 'address-i18n' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); - wp_register_script( 'jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.3.1', true ); - - // Queue frontend scripts conditionally - if ( $ajax_cart_en ) - wp_enqueue_script( 'wc-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); - - if ( is_cart() ) - wp_enqueue_script( 'wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery', 'wc-country-select' ), WC_VERSION, true ); + self::register_script( 'chosen', $assets_path . 'js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), '1.0.0' ); + self::register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.60' ); + self::register_script( 'jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array( 'jquery' ), '1.0.2' ); + self::register_script( 'jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.3.1' ); + self::register_script( 'wc-credit-card-form', $frontend_script_path . 'credit-card-form' . $suffix . '.js', array( 'jquery', 'jquery-payment' ) ); + self::register_script( 'wc-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js' ); + self::register_script( 'wc-single-product', $frontend_script_path . 'single-product' . $suffix . '.js' ); + self::register_script( 'wc-country-select', $frontend_script_path . 'country-select' . $suffix . '.js' ); + self::register_script( 'wc-address-i18n', $frontend_script_path . 'address-i18n' . $suffix . '.js' ); + // Register frontend scripts conditionally + if ( $ajax_cart_en ) { + self::enqueue_script( 'wc-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js' ); + } + if ( is_cart() ) { + self::enqueue_script( 'wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery', 'wc-country-select' ) ); + } + if ( 'yes' === get_option( 'woocommerce_enable_chosen' ) && ( is_checkout() || is_page( get_option( 'woocommerce_myaccount_page_id' ) ) ) ) { + self::enqueue_script( 'wc-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ) ); + wp_enqueue_style( 'woocommerce_chosen_styles', $assets_path . 'css/chosen.css' ); + } if ( is_checkout() ) { - - if ( get_option( 'woocommerce_enable_chosen' ) == 'yes' ) { - wp_enqueue_script( 'wc-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), WC_VERSION, true ); - wp_enqueue_style( 'woocommerce_chosen_styles', $assets_path . 'css/chosen.css' ); - } - - wp_enqueue_script( 'wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ), WC_VERSION, true ); + self::enqueue_script( 'wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ) ); } - - if ( is_page( get_option( 'woocommerce_myaccount_page_id' ) ) ) { - if ( get_option( 'woocommerce_enable_chosen' ) == 'yes' ) { - wp_enqueue_script( 'wc-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), WC_VERSION, true ); - wp_enqueue_style( 'woocommerce_chosen_styles', $assets_path . 'css/chosen.css' ); - } + if ( is_add_payment_method_page() ) { + self::enqueue_script( 'wc-add-payment-method', $frontend_script_path . 'add-payment-method' . $suffix . '.js', array( 'jquery', 'woocommerce' ) ); } - - if ( is_add_payment_method_page() ) - wp_enqueue_script( 'wc-add-payment-method', $frontend_script_path . 'add-payment-method' . $suffix . '.js', array( 'jquery', 'woocommerce' ), WC_VERSION, true ); - if ( $lightbox_en && ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) ) { - wp_enqueue_script( 'prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true ); - wp_enqueue_script( 'prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery','prettyPhoto' ), WC_VERSION, true ); + self::enqueue_script( 'prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true ); + self::enqueue_script( 'prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery','prettyPhoto' ) ); wp_enqueue_style( 'woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css' ); } - - if ( is_product() ) - wp_enqueue_script( 'wc-single-product' ); + if ( is_product() ) { + self::enqueue_script( 'wc-single-product' ); + } // Global frontend scripts - wp_enqueue_script( 'woocommerce', $frontend_script_path . 'woocommerce' . $suffix . '.js', array( 'jquery', 'jquery-blockui' ), WC_VERSION, true ); - wp_enqueue_script( 'wc-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array( 'jquery', 'jquery-cookie' ), WC_VERSION, true ); + self::enqueue_script( 'woocommerce', $frontend_script_path . 'woocommerce' . $suffix . '.js', array( 'jquery', 'jquery-blockui' ) ); + self::enqueue_script( 'wc-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array( 'jquery', 'jquery-cookie' ) ); // CSS Styles - $enqueue_styles = self::get_styles(); - - if ( $enqueue_styles ) { + if ( $enqueue_styles = self::get_styles() ) { foreach ( $enqueue_styles as $handle => $args ) { wp_enqueue_style( $handle, $args['src'], $args['deps'], $args['version'], $args['media'] ); } @@ -131,117 +162,110 @@ class WC_Frontend_Scripts { } /** - * Localize scripts only when enqueued + * Localize a WC script once. + * @access private + * @since 2.3.0 this needs less wp_script_is() calls due to https://core.trac.wordpress.org/ticket/28404 being added in WP 4.0. + * @param string $handle */ - public static function localize_printed_scripts() { + private static function localize_script( $handle ) { + if ( ! in_array( $handle, self::$wp_localize_scripts ) && wp_script_is( $handle ) && ( $data = self::get_script_data( $handle ) ) ) { + $name = str_replace( '-', '_', $handle ) . '_params'; + self::$wp_localize_scripts[] = $handle; + wp_localize_script( $handle, $name, apply_filters( $name, $data ) ); + } + } + + /** + * Return data for script handles + * @access private + * @param string $handle + * @return array|bool + */ + private static function get_script_data( $handle ) { global $wp; - $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; - - if ( wp_script_is( 'woocommerce' ) ) { - wp_localize_script( 'woocommerce', 'woocommerce_params', apply_filters( 'woocommerce_params', array( - 'ajax_url' => WC()->ajax_url(), - 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), - ) ) ); - } - if ( wp_script_is( 'wc-single-product' ) ) { - wp_localize_script( 'wc-single-product', 'wc_single_product_params', apply_filters( 'wc_single_product_params', array( - 'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'woocommerce' ), - 'review_rating_required' => get_option( 'woocommerce_review_rating_required' ), - ) ) ); - } - if ( wp_script_is( 'wc-checkout' ) ) { - wp_localize_script( 'wc-checkout', 'wc_checkout_params', apply_filters( 'wc_checkout_params', array( - 'ajax_url' => WC()->ajax_url(), - 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), - 'update_order_review_nonce' => wp_create_nonce( "update-order-review" ), - 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ), - 'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ), - 'checkout_url' => add_query_arg( 'action', 'woocommerce_checkout', WC()->ajax_url() ), - 'is_checkout' => is_page( wc_get_page_id( 'checkout' ) ) && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0 - ) ) ); - } - if ( wp_script_is( 'wc-address-i18n' ) || wp_script_is( 'wc-checkout' ) ) { - wp_localize_script( 'wc-address-i18n', 'wc_address_i18n_params', apply_filters( 'wc_address_i18n_params', array( - 'locale' => json_encode( WC()->countries->get_country_locale() ), - 'locale_fields' => json_encode( WC()->countries->get_country_locale_field_selectors() ), - 'i18n_required_text' => esc_attr__( 'required', 'woocommerce' ), - ) ) ); - } - if ( wp_script_is( 'wc-cart' ) ) { - wp_localize_script( 'wc-cart', 'wc_cart_params', apply_filters( 'wc_cart_params', array( - 'ajax_url' => WC()->ajax_url(), - 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), - 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ), - ) ) ); - } - if ( wp_script_is( 'wc-cart-fragments' ) ) { - wp_localize_script( 'wc-cart-fragments', 'wc_cart_fragments_params', apply_filters( 'wc_cart_fragments_params', array( - 'ajax_url' => WC()->ajax_url(), - 'fragment_name' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments' ) - ) ) ); - } - if ( wp_script_is( 'wc-add-to-cart' ) ) { - wp_localize_script( 'wc-add-to-cart', 'wc_add_to_cart_params', apply_filters( 'wc_add_to_cart_params', array( - 'ajax_url' => WC()->ajax_url(), - 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), - 'i18n_view_cart' => esc_attr__( 'View Cart', 'woocommerce' ), - 'cart_url' => get_permalink( wc_get_page_id( 'cart' ) ), - 'is_cart' => is_cart(), - 'cart_redirect_after_add' => get_option( 'woocommerce_cart_redirect_after_add' ) - ) ) ); - } - if ( wp_script_is( 'wc-add-to-cart-variation' ) ) { - wp_localize_script( 'wc-add-to-cart-variation', 'wc_add_to_cart_variation_params', apply_filters( 'wc_add_to_cart_variation_params', array( - 'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'woocommerce' ), - 'i18n_unavailable_text' => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ), - ) ) ); - } - - if ( wp_script_is( 'wc-country-select' ) || wp_script_is( 'wc-cart' ) || wp_script_is( 'wc-checkout' ) ) { - wp_localize_script( 'wc-country-select', 'wc_country_select_params', apply_filters( 'wc_country_select_params', array( - 'countries' => json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ), - 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'woocommerce' ), - ) ) ); + switch ( $handle ) { + case 'woocommerce' : + $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; + return array( + 'ajax_url' => WC()->ajax_url(), + 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), + ); + break; + case 'wc-single-product' : + return array( + 'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'woocommerce' ), + 'review_rating_required' => get_option( 'woocommerce_review_rating_required' ), + ); + break; + case 'wc-checkout' : + $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; + return array( + 'ajax_url' => WC()->ajax_url(), + 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), + 'update_order_review_nonce' => wp_create_nonce( "update-order-review" ), + 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ), + 'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ), + 'checkout_url' => add_query_arg( 'action', 'woocommerce_checkout', WC()->ajax_url() ), + 'is_checkout' => is_page( wc_get_page_id( 'checkout' ) ) && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0 + ); + break; + case 'wc-address-i18n' : + return array( + 'locale' => json_encode( WC()->countries->get_country_locale() ), + 'locale_fields' => json_encode( WC()->countries->get_country_locale_field_selectors() ), + 'i18n_required_text' => esc_attr__( 'required', 'woocommerce' ), + ); + break; + case 'wc-cart' : + $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; + return array( + 'ajax_url' => WC()->ajax_url(), + 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), + 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ), + ); + break; + case 'wc-cart-fragments' : + return array( + 'ajax_url' => WC()->ajax_url(), + 'fragment_name' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments' ) + ); + break; + case 'wc-add-to-cart' : + $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; + return array( + 'ajax_url' => WC()->ajax_url(), + 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $assets_path . 'images/ajax-loader@2x.gif' ), + 'i18n_view_cart' => esc_attr__( 'View Cart', 'woocommerce' ), + 'cart_url' => get_permalink( wc_get_page_id( 'cart' ) ), + 'is_cart' => is_cart(), + 'cart_redirect_after_add' => get_option( 'woocommerce_cart_redirect_after_add' ) + ); + break; + case 'wc-add-to-cart-variation' : + return array( + 'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'woocommerce' ), + 'i18n_unavailable_text' => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ), + ); + break; + case 'wc-country-select' : + return array( + 'countries' => json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ), + 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'woocommerce' ), + ); + break; } + return false; } /** - * WC requires jQuery 1.8 since it uses functions like .on() for events and .parseHTML. - * If, by the time wp_print_scrips is called, jQuery is outdated (i.e not - * using the version in core) we need to deregister it and register the - * core version of the file. - * - * @access public - * @return void + * Localize scripts only when enqueued. */ - public static function check_jquery() { - global $wp_scripts; - - // Enforce minimum version of jQuery - if ( ! empty( $wp_scripts->registered['jquery']->ver ) && ! empty( $wp_scripts->registered['jquery']->src ) && 0 >= version_compare( $wp_scripts->registered['jquery']->ver, '1.8' ) ) { - wp_deregister_script( 'jquery' ); - wp_register_script( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.8' ); - wp_enqueue_script( 'jquery' ); + public static function localize_printed_scripts() { + foreach ( self::$scripts as $handle ) { + self::localize_script( $handle ); } } - - /** - * Provide backwards compat for old constant - * @param array $styles - * @return array - */ - public static function backwards_compat( $styles ) { - if ( defined( 'WOOCOMMERCE_USE_CSS' ) ) { - - _deprecated_function( 'WOOCOMMERCE_USE_CSS', '2.1', 'Styles should be removed using wp_deregister_style or the woocommerce_enqueue_styles filter rather than the WOOCOMMERCE_USE_CSS constant.' ); - - if ( ! WOOCOMMERCE_USE_CSS ) - return false; - } - - return $styles; - } } WC_Frontend_Scripts::init(); diff --git a/readme.txt b/readme.txt index 9187278d72f..bb8a1977acd 100644 --- a/readme.txt +++ b/readme.txt @@ -130,6 +130,9 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc == Changelog == += 2.3.0 = +* Refactor - Removed deprecated methods from WC_Frontend_Scripts and rewrote script registration and localization to run once. + = 2.2.5 = * Fix - Filters in admin screen for coupons and orders. * Fix - When bulk editing, don't allow sale price to be negative. diff --git a/woocommerce.php b/woocommerce.php index 9a0b80ce900..7827105d56e 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -6,7 +6,7 @@ * Version: 2.2.4 * Author: WooThemes * Author URI: http://woothemes.com - * Requires at least: 3.8 + * Requires at least: 4.0 * Tested up to: 4.0 * * Text Domain: woocommerce