ritical_css_content = str_replace( '\\', '\\\\', $critical_css_content ); $buffer = preg_replace( '##iU', '', $buffer, 1 ); return preg_replace( '##iU', $this->return_remove_cpcss_script() . '', $buffer, 1 ); } /** * Returns JS script to remove the critical css style from frontend. * * @since 3.6 * * @return string */ protected function return_remove_cpcss_script() { $filename = rocket_get_constant( 'SCRIPT_DEBUG' ) ? 'cpcss-removal.js' : 'cpcss-removal.min.js'; $script = rocket_get_constant( 'WP_ROCKET_PATH' ) . "assets/js/{$filename}"; if ( ! is_readable( $script ) ) { return ''; } return sprintf( '', $this->filesystem->get_contents( $script ) ); } /** * Adds wprRemoveCPCSS to excluded inline JS array. * * @since 3.6 * * @param array $excluded_inline Array of inline JS excluded from being combined. * * @return array */ public function exclude_inline_js( array $excluded_inline ) { $excluded_inline[] = 'wprRemoveCPCSS'; return $excluded_inline; } /** * Defer loading of CSS files. * * @since 2.10 * * @param string $buffer HTML code. * * @return string Updated HTML code */ public function async_css( $buffer ) { if ( ! $this->should_async_css() ) { return $buffer; } if ( empty( $this->critical_css->get_current_page_critical_css() ) && empty( $this->options->get( 'critical_css', '' ) ) ) { return $buffer; } $excluded_css = array_flip( $this->critical_css->get_exclude_async_css() ); /** * Filters the pattern used to get all stylesheets in the HTML. * * @since 2.10 * * @param string $css_pattern Regex pattern to get all stylesheets in the HTML. */ $css_pattern = apply_filters( 'rocket_async_css_regex_pattern', '/(?=]*\s(rel\s*=\s*[\'"]stylesheet["\']))]*\shref\s*=\s*[\'"]([^\'"]+)[\'"](.*)>/iU' ); // Remove comments from the buffer. $clean_buffer = $this->hide_comments( $buffer ); $clean_buffer = $this->hide_noscripts( $clean_buffer ); // Get all css files with this regex. preg_match_all( $css_pattern, $clean_buffer, $tags_match ); if ( ! isset( $tags_match[0] ) ) { return $buffer; } $noscripts = ''; return str_replace( '', $noscripts . '', $buffer ); } /** * Regenerates the CPCSS when switching theme if the option is active. * * @since 3.3 */ public function maybe_regenerate_cpcss() { if ( ! $this->options->get( 'async_css' ) ) { return; } if ( ! $this->is_mobile_cpcss_active() ) { $this->critical_css->process_handler( 'default', 'all' ); return; } $this->critical_css->process_handler( 'all' ); } /** * Checks if mobile CPCSS is active. * * @since 3.6 * * @return boolean CPCSS active or not. */ private function is_mobile_cpcss_active() { return ( $this->options->get( 'async_css', 0 ) && $this->options->get( 'cache_mobile', 0 ) && $this->options->get( 'do_caching_mobile_files', 0 ) ) && $this->options->get( 'async_css_mobile', 0 ); } /** * Checks if we should async CSS * * @since 3.6.2.1 * * @return boolean */ private function should_async_css() { if ( rocket_get_constant( 'DONOTROCKETOPTIMIZE' ) ) { return false; } if ( ! $this->options->get( 'async_css', 0 ) ) { return false; } return ! is_rocket_post_excluded_option( 'async_css' ); } /** * Stops the critical CSS generation. * * @since 3.10 * * @return void */ public function stop_critical_css_generation() { $this->critical_css->stop_generation(); delete_transient( 'rocket_critical_css_generation_process_running' ); delete_transient( 'rocket_critical_css_generation_process_complete' ); } /** * Display a notice to pass from CPCSS to RUCSS. * * @return void */ public function switch_to_rucss_notice() { $boxes = get_user_meta( get_current_user_id(), 'rocket_boxes', true ); if ( in_array( __FUNCTION__, (array) $boxes, true ) ) { return; } if ( ! $this->options->get( 'async_css', 0 ) ) { return; } if ( $this->user->is_license_expired() ) { return; } $screen = get_current_screen(); if ( isset( $screen->id ) && 'settings_page_wprocket' !== $screen->id ) { return; } /** * Filters the status of the RUCSS option. * * @param array $should_disable will return array with disable status and text. */ $rucss_status = apply_filters( 'rocket_disable_rucss_setting', [ 'disable' => false, 'text' => '', ] ); if ( is_array( $rucss_status ) && key_exists( 'disable', $rucss_status ) && $rucss_status['disable'] ) { return; } rocket_notice_html( [ 'status' => 'wpr-warning', 'dismissible' => '', 'dismiss_button' => __FUNCTION__, 'message' => sprintf( // translators: %1$ = opening bold tag, %2$ = closing bold tag. __( 'We highly recommend the %1$supdated Remove Unused CSS%2$s for a better CSS optimization. Load CSS Asynchronously is always available as a back-up.', 'rocket' ), '', '' ), 'action' => 'switch_to_rucss', 'dismiss_button_message' => __( 'Stay with the old option', 'rocket' ), ] ); } /** * Switch to RUCSS. * * @return void */ public function switch_to_rucss() { check_admin_referer( 'rucss_switch' ); if ( ! current_user_can( 'rocket_manage_options' ) ) { wp_safe_redirect( wp_get_referer() ); rocket_get_constant( 'WP_ROCKET_IS_TESTING', false ) ? wp_die() : exit; return; // phpcs:ignore Squiz.PHP.NonExecutableCode.Unreachable } $this->options->set( 'async_css', false ); $this->options->set( 'remove_unused_css', true ); $this->options_api->set( 'settings', $this->options->get_options() ); rocket_dismiss_box( 'switch_to_rucss_notice' ); wp_safe_redirect( wp_get_referer() ); rocket_get_constant( 'WP_ROCKET_IS_TESTING', false ) ? wp_die() : exit; } }