keeps every
* attribute — defer, async, type, id — with only its src swapped. They
* are never inlined: inline scripts ignore defer/async, so inlining made
* deferred scripts run immediately and out of order and destroyed
* browser caching.
*
* 0.1.17 (BUG-018): sources that are ALREADY minified are left alone.
* Re-minifying a build-tool bundle gains 0-2% and the regex-based
* library mis-tokenises some large webpack bundles (Site Kit: a
* `"https://..."` string was eaten as a line comment -> SyntaxError).
* See looks_minified().
*
* @package CachingOut
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use MatthiasMullie\Minify\JS;
/**
* JavaScript minifier.
*
* Uses MatthiasMullie\Minify\JS for safe, parser-based minification
* instead of regex-based whitespace and comment stripping.
*
* @since 0.1.0
*/
class CachingOut_Minify_JS {
/**
* Average line length (bytes) above which a script is treated as
* already minified. Hand-written sources average 30-130; every
* build-tool bundle measured (WP core, Complianz, 60 Site Kit
* chunks) averages 300+ and most are a single multi-KB line.
*
* @since 0.1.17
* @var int
*/
const MINIFIED_LINE_LENGTH = 250;
/**
* Plugin settings instance.
*
* @since 0.1.0
* @var CachingOut_Settings
*/
private $settings;
/**
* Shared exclusions registry.
*
* @since 0.1.0
* @var CachingOut_Optimization_Exclusions
*/
private $exclusions;
/**
* Minified-file store.
*
* @since 0.1.16
* @var CachingOut_Minified_Files
*/
private $files;
/**
* Constructor.
*
* @since 0.1.0
*
* @param CachingOut_Settings $settings Settings instance.
* @param CachingOut_Optimization_Exclusions $exclusions Shared exclusions.
* @param CachingOut_Minified_Files|null $files Optional store (tests).
*/
public function __construct( CachingOut_Settings $settings, CachingOut_Optimization_Exclusions $exclusions, CachingOut_Minified_Files $files = null ) {
$this->settings = $settings;
$this->exclusions = $exclusions;
$this->files = $files ? $files : new CachingOut_Minified_Files();
}
/**
* Output buffer callback — applies JS minification to the full HTML.
*
* @since 0.1.0
*
* @param string $html Full page HTML.
* @return string Transformed HTML.
*/
public function filter( $html ) {
if ( '' === $html ) {
return $html;
}
// BUG-013: pipeline always invokes filter(); must re-check the toggle.
if ( ! $this->settings->get( 'file_optimization', 'minify_js', false ) ) {
return $html;
}
// Minify inline ' );
if ( false !== $pos_end_open && false !== $pos_begin_end ) {
$tag_head = substr( $full_tag, 0, $pos_end_open + 1 );
$tag_tail = substr( $full_tag, $pos_begin_end );
return $tag_head . $minified . $tag_tail;
}
return $full_tag;
}
/**
* Callback for