From 79e5eea93f6ba2fd0e1be64a1562f97b668acbab Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Fri, 25 Sep 2026 21:15:06 +0600 Subject: [PATCH 1/2] fix(classicpress): register wp-polyfill fallback when missing Generated asset files list wp-polyfill as a dependency of every SCF script. ClassicPress never registers that handle so WordPress silently drops the whole acf chain and the footer inline code throws acf is not defined. Register a no-op fallback when the handle is missing, mirroring the existing react-jsx-runtime polyfill. On normal WordPress the handle already exists so this is a no-op. Fixes #285 --- includes/assets.php | 22 ++++++++++++++++++++++ tests/php/includes/test-assets.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/includes/assets.php b/includes/assets.php index d9d4b836..b47c215a 100644 --- a/includes/assets.php +++ b/includes/assets.php @@ -144,6 +144,27 @@ private function register_react_jsx_runtime_polyfill( $version ) { ); } + /** + * Registers a fallback for the wp-polyfill script handle. + * + * Generated asset files list this handle as a dependency of every SCF + * script. Systems that never register it, such as ClassicPress, silently + * drop each dependent script, which leaves the inline footer code + * running against a missing acf global. + * + * @since SCF 6.9.6 + * + * @param string $version The script version. + * @return void + */ + private function register_wp_polyfill_fallback( $version ) { + if ( wp_script_is( 'wp-polyfill', 'registered' ) ) { + return; + } + + wp_register_script( 'wp-polyfill', false, array(), $version, true ); + } + /** * Returns whether the legacy SCF block bindings editor script can run. * @@ -174,6 +195,7 @@ public function register_scripts() { $version = acf_get_setting( 'version' ); $this->register_react_jsx_runtime_polyfill( $version ); + $this->register_wp_polyfill_fallback( $version ); // Define path patterns. $js_path_patterns = array( diff --git a/tests/php/includes/test-assets.php b/tests/php/includes/test-assets.php index 67545793..0bfed6f1 100644 --- a/tests/php/includes/test-assets.php +++ b/tests/php/includes/test-assets.php @@ -52,6 +52,7 @@ public function set_up() { wp_dequeue_script( 'acf-pro-ui-options-page' ); wp_dequeue_script( 'scf-bindings' ); wp_deregister_script( 'react-jsx-runtime' ); + wp_deregister_script( 'wp-polyfill' ); wp_deregister_script( 'scf-commands-admin' ); wp_deregister_script( 'scf-bindings' ); } @@ -67,6 +68,7 @@ public function tear_down() { wp_dequeue_script( 'acf-pro-ui-options-page' ); wp_dequeue_script( 'scf-bindings' ); wp_deregister_script( 'react-jsx-runtime' ); + wp_deregister_script( 'wp-polyfill' ); wp_deregister_script( 'scf-commands-admin' ); wp_deregister_script( 'scf-bindings' ); @@ -107,6 +109,32 @@ public function test_register_scripts_adds_react_jsx_runtime_polyfill_when_missi ); } + /** + * Test installs without wp-polyfill get a fallback registration. + */ + public function test_register_scripts_adds_wp_polyfill_fallback_when_missing() { + acf_get_instance( 'ACF_Assets' )->register_scripts(); + + $wp_scripts = wp_scripts(); + + $this->assertTrue( wp_script_is( 'wp-polyfill', 'registered' ) ); + $this->assertContains( 'wp-polyfill', $wp_scripts->registered['acf']->deps ); + } + + /** + * Test an existing wp-polyfill registration is left untouched. + */ + public function test_register_scripts_keeps_existing_wp_polyfill_registration() { + wp_register_script( 'wp-polyfill', 'https://example.org/polyfill.js', array(), 'test-version', true ); + + acf_get_instance( 'ACF_Assets' )->register_scripts(); + + $wp_scripts = wp_scripts(); + + $this->assertSame( 'https://example.org/polyfill.js', $wp_scripts->registered['wp-polyfill']->src ); + $this->assertSame( 'test-version', $wp_scripts->registered['wp-polyfill']->ver ); + } + /** * Test command scripts include generated asset dependencies. */ From 57686b6b055e68b5cc6b041368304d75c55ed519 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Fri, 25 Sep 2026 23:07:08 +0600 Subject: [PATCH 2/2] fix(ci): resolve failing tests Remove the acf deps assertion that reads the gitignored acf.asset.php file. The PHPUnit workflow has no build step, so the asset file is absent in CI and the acf script has no wp-polyfill dependency there. The test now asserts only that the fallback registers wp-polyfill. Update the openPreviewPage fixture to click the preview menu item with a regex that matches both the old and the renamed WP trunk label. The pinned helper version only knows the old label, which times out the trunk E2E shards. Refs #550 --- tests/e2e/fixtures.js | 25 ++++++++++++++----------- tests/php/includes/test-assets.php | 3 --- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/e2e/fixtures.js b/tests/e2e/fixtures.js index 59d8b016..c8fee97e 100644 --- a/tests/e2e/fixtures.js +++ b/tests/e2e/fixtures.js @@ -144,22 +144,25 @@ const test = wpTest.extend( { 'role=button[name="View"i]' ); - if ( + const hasViewButton = ( await viewButton.count() ) > 0 && - ( await viewButton.first().isVisible() ) - ) { - return editor.openPreviewPage(); - } + ( await viewButton.first().isVisible() ); - await editorTopBar - .locator( 'role=button[name="Preview"i]' ) - .click(); + await ( hasViewButton + ? viewButton.first() + : editorTopBar.locator( 'role=button[name="Preview"i]' ) + ).click(); + // WordPress trunk renamed the menu item to + // "Preview (opens in a new tab)", so match on the shared + // "Preview ... new tab" text instead of the exact label. const [ previewPage ] = await Promise.all( [ context.waitForEvent( 'page' ), - page.click( - 'role=menuitem[name=/Preview in new tab/i]' - ), + page + .getByRole( 'menuitem', { + name: /Preview.*new tab/i, + } ) + .click(), ] ); return previewPage; diff --git a/tests/php/includes/test-assets.php b/tests/php/includes/test-assets.php index 0bfed6f1..b141999c 100644 --- a/tests/php/includes/test-assets.php +++ b/tests/php/includes/test-assets.php @@ -115,10 +115,7 @@ public function test_register_scripts_adds_react_jsx_runtime_polyfill_when_missi public function test_register_scripts_adds_wp_polyfill_fallback_when_missing() { acf_get_instance( 'ACF_Assets' )->register_scripts(); - $wp_scripts = wp_scripts(); - $this->assertTrue( wp_script_is( 'wp-polyfill', 'registered' ) ); - $this->assertContains( 'wp-polyfill', $wp_scripts->registered['acf']->deps ); } /**