diff --git a/readme.txt b/readme.txt index a44374c8..27566ec5 100644 --- a/readme.txt +++ b/readme.txt @@ -280,6 +280,7 @@ Please make sure you make a backup of your database before updating any version = 2.6.3 = * Improved: the tracker script now loads asynchronously (like Plausible Analytics' own snippet) instead of deferred, so it can no longer hold up the rest of the page when it can't be reached. +* Added: Hummingbird compatibility. Its Asset Optimization and Delay JavaScript no longer touch the plugin's scripts, which could cause a "plausible is not a function" error (e.g. on search results pages). = 2.6.2 = * *Important!* This release rebuilds the WooCommerce (and EDD) purchase funnel for sites using WPML with a translated product base. If you built your own funnels using the same goals, please rebuild them after installing this update. diff --git a/src/Compatibility.php b/src/Compatibility.php index ff761c76..d070085e 100644 --- a/src/Compatibility.php +++ b/src/Compatibility.php @@ -33,6 +33,12 @@ public function __construct() { // Global Exclusion from Minification add_filter( 'plausible_analytics_script_params', [ $this, 'exclude_from_minification' ] ); + // Hummingbird + if ( defined( 'WPHB_VERSION' ) ) { + add_filter( 'wphb_dont_add_handle_to_collection', [ $this, 'exclude_from_hummingbird_asset_optimization' ], 10, 4 ); + add_filter( 'wphb_delay_js_exclusions', [ $this, 'exclude_from_hummingbird_delay_js' ] ); + } + // LiteSpeed Cache if ( defined( 'LSCWP_V' ) ) { add_filter( 'litespeed_optimize_js_excludes', [ $this, 'exclude_plausible_js' ] ); @@ -151,6 +157,49 @@ public function exclude_from_minification( $params ) { return $params; } + /** + * Dear Hummingbird, leave our scripts alone, please. Its Asset Optimization combines the tracker with other scripts + * and moves (or duplicates) the inline script that initializes it, which can leave calls to plausible() without the + * initialization ("plausible is not a function"), and serves its own copy of the tracker, which goes stale. + * + * Handles that aren't added to the collection are returned to WordPress untouched. + * + * @filter wphb_dont_add_handle_to_collection + * @since 2.6.3 + * + * @param bool $value Whether to leave the handle alone. + * @param string $handle Resource handle. + * @param string $source_url Resource URL. + * @param string $type scripts|styles + * + * @return bool + */ + public function exclude_from_hummingbird_asset_optimization( $value, $handle, $source_url, $type ) { + if ( $type === 'scripts' && strpos( (string) $handle, 'plausible-' ) === 0 ) { + return true; + } + + return $value; + } + + /** + * Dear Hummingbird, don't delay our scripts, please. The exclusions are matched against each script tag, including + * its inline code, so this covers our handles (plausible-*), our URLs (plausible.io, /plugins/plausible-analytics/) + * and the inline code calling window.plausible. + * + * @filter wphb_delay_js_exclusions + * @since 2.6.3 + * + * @param array $exclusions + * + * @return array + */ + public function exclude_from_hummingbird_delay_js( $exclusions ) { + $exclusions[] = 'plausible'; + + return $exclusions; + } + /** * Dear WP Rocket/SG Optimizer/Etc., don't minify/combine our inline JS, please. * diff --git a/tests/integration/CompatibilityTest.php b/tests/integration/CompatibilityTest.php index 2e69e04f..ccb57ed3 100644 --- a/tests/integration/CompatibilityTest.php +++ b/tests/integration/CompatibilityTest.php @@ -25,4 +25,31 @@ public function testTrackerScriptLoadsAsync() { $this->assertStringContainsString( " async data-cfasync='false'", $tag ); $this->assertStringNotContainsString( 'defer', $tag ); } + + /** + * Hummingbird's Asset Optimization should leave our scripts alone, and only ours. + * + * @see Compatibility::exclude_from_hummingbird_asset_optimization() + * @return void + */ + public function testExcludeFromHummingbirdAssetOptimization() { + $class = new Compatibility(); + + $this->assertTrue( $class->exclude_from_hummingbird_asset_optimization( false, 'plausible-analytics', '', 'scripts' ) ); + $this->assertTrue( $class->exclude_from_hummingbird_asset_optimization( false, 'plausible-form-submit-integration', '', 'scripts' ) ); + $this->assertFalse( $class->exclude_from_hummingbird_asset_optimization( false, 'jquery-core', '', 'scripts' ) ); + $this->assertFalse( $class->exclude_from_hummingbird_asset_optimization( false, 'plausible-analytics', '', 'styles' ) ); + // Another plugin's decision is kept. + $this->assertTrue( $class->exclude_from_hummingbird_asset_optimization( true, 'jquery-core', '', 'scripts' ) ); + } + + /** + * Hummingbird's Delay JavaScript should leave our scripts alone. + * + * @see Compatibility::exclude_from_hummingbird_delay_js() + * @return void + */ + public function testExcludeFromHummingbirdDelayJs() { + $this->assertEquals( [ 'existing', 'plausible' ], ( new Compatibility() )->exclude_from_hummingbird_delay_js( [ 'existing' ] ) ); + } }