diff --git a/includes/speed-functions.php b/includes/speed-functions.php index 5633840..04aadeb 100644 --- a/includes/speed-functions.php +++ b/includes/speed-functions.php @@ -1,19 +1,49 @@ ]+)\/?>/i', @@ -23,15 +53,98 @@ function wpa_superstar_lazy_load_images( $content ) { } catch ( Exception $e ) { wpa_superstar_log( "Lazy load error: " . $e->getMessage() ); } + return $content; } -add_filter( 'the_content', 'wpa_superstar_lazy_load_images' ); -add_filter( 'wp_get_attachment_image', 'wpa_superstar_lazy_load_images' ); +// Register the lazy load filters if add_filter exists +if ( function_exists( 'add_filter' ) ) { + add_filter( 'the_content', 'wpa_superstar_lazy_load_images' ); + add_filter( 'wp_get_attachment_image', 'wpa_superstar_lazy_load_images' ); +} + +/** + * Advanced CSS minification function + * + * This function takes CSS content and returns a minified version by: + * - Removing comments + * - Removing whitespace + * - Removing unnecessary semicolons + * - Shortening color values + * - Optimizing zero values + * + * @param string $css The CSS content to minify + * @return string The minified CSS content + */ +function wpa_superstar_minify_css_content( $css ) { + if ( empty( $css ) ) { + return $css; + } + + try { + // Remove comments + $css = preg_replace( '/\/\*[\s\S]*?\*\//', '', $css ); + + // Remove whitespace around key characters + $css = preg_replace( '/\s*([{}:;,])\s*/', '$1', $css ); + + // Remove trailing whitespace + $css = preg_replace( '/\s+/', ' ', $css ); + + // Remove unnecessary semicolons + $css = str_replace( ';}', '}', $css ); + + // Convert rgb to hex where shorter + $css = preg_replace_callback( '/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/i', function( $matches ) { + $r = intval( $matches[1] ); + $g = intval( $matches[2] ); + $b = intval( $matches[3] ); + + // Only convert if the hex representation would be shorter + if ( $r < 256 && $g < 256 && $b < 256 ) { + $hex = sprintf( "#%02x%02x%02x", $r, $g, $b ); + // Check if it can be shortened to #XXX format + if ( preg_match( '/#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3/i', $hex ) ) { + $hex = preg_replace( '/#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3/i', '#$1$2$3', $hex ); + } + return $hex; + } + return $matches[0]; + }, $css ); + + // Optimize zero values + $css = preg_replace( '/([:\s])0(?:px|pt|em|rem|%|in|cm|mm|pc|ex|vw|vh|vmin|vmax)/', '$10', $css ); + + // Shorten multiple zeros + $css = preg_replace( '/\b0 0 0 0\b/', '0', $css ); + $css = preg_replace( '/\b0 0 0\b/', '0', $css ); + $css = preg_replace( '/\b0 0\b/', '0', $css ); + + // Shorten colors where possible (e.g., #ffffff to #fff) + $css = preg_replace( '/#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3/i', '#$1$2$3', $css ); + + } catch ( Exception $e ) { + wpa_superstar_log( "CSS content minify error: " . $e->getMessage() ); + return $css; // Return original on error + } + + return trim( $css ); +} + +/** + * Minify CSS in HTML content to reduce file size + * + * @param string $html The HTML content to process + * @return string The processed HTML with minified CSS + */ function wpa_superstar_minify_css( $html ) { - if ( is_admin() || ! get_option( 'wpa_superstar_minify_css', 0 ) ) { + // Early return if admin or option disabled + if ( ( function_exists( 'is_admin' ) && is_admin() ) || + ( function_exists( 'get_option' ) && ! get_option( 'wpa_superstar_minify_css', 0 ) ) + ) { return $html; } + try { $html = preg_replace( array( '/\s+/', '/\/\*.*?\*\//s', '/;}/' ), @@ -41,14 +154,29 @@ function wpa_superstar_minify_css( $html ) { } catch ( Exception $e ) { wpa_superstar_log( "CSS minify error: " . $e->getMessage() ); } + return trim( $html ); } -add_filter( 'style_loader_tag', 'wpa_superstar_minify_css' ); +// Register the CSS minify filter if add_filter exists +if ( function_exists( 'add_filter' ) ) { + add_filter( 'style_loader_tag', 'wpa_superstar_minify_css' ); +} + +/** + * Minify JavaScript in HTML content to reduce file size + * + * @param string $html The HTML content to process + * @return string The processed HTML with minified JavaScript + */ function wpa_superstar_minify_js( $html ) { - if ( is_admin() || ! get_option( 'wpa_superstar_minify_js', 0 ) ) { + // Early return if admin or option disabled + if ( ( function_exists( 'is_admin' ) && is_admin() ) || + ( function_exists( 'get_option' ) && ! get_option( 'wpa_superstar_minify_js', 0 ) ) + ) { return $html; } + try { $html = preg_replace( array( '/\s+/', '/\/\*.*?\*\//s', '//.*?\n/' ), @@ -58,6 +186,48 @@ function wpa_superstar_minify_js( $html ) { } catch ( Exception $e ) { wpa_superstar_log( "JS minify error: " . $e->getMessage() ); } + return trim( $html ); } -add_filter( 'script_loader_tag', 'wpa_superstar_minify_js' ); \ No newline at end of file + +// Register the JS minify filter if add_filter exists +if ( function_exists( 'add_filter' ) ) { + add_filter( 'script_loader_tag', 'wpa_superstar_minify_js' ); +} + +/** + * Minify inline CSS in HTML content + * + * @param string $html The HTML content containing style tags + * @return string The HTML with minified inline CSS + */ +function wpa_superstar_minify_inline_css( $html ) { + // Early return if admin or option disabled + if ( ( function_exists( 'is_admin' ) && is_admin() ) || + ( function_exists( 'get_option' ) && ! get_option( 'wpa_superstar_minify_inline_css', 0 ) ) + ) { + return $html; + } + + try { + // Find and minify all inline style blocks + $html = preg_replace_callback( + '/]*>(.*?)<\/style>/si', + function( $matches ) { + $minified_css = wpa_superstar_minify_css_content( $matches[1] ); + return ''; + }, + $html + ); + } catch ( Exception $e ) { + wpa_superstar_log( "Inline CSS minify error: " . $e->getMessage() ); + } + + return $html; +} + +// Apply the inline CSS minify filters if add_filter exists +if ( function_exists( 'add_filter' ) ) { + add_filter( 'wp_head', 'wpa_superstar_minify_inline_css', 999 ); + add_filter( 'wp_footer', 'wpa_superstar_minify_inline_css', 999 ); +}