From 9828569f97925b3f14376376e4776717ff6d8792 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 1 Sep 2026 17:42:25 +1000 Subject: [PATCH 1/2] getResolvedValue: stop writing the resolved URL onto the given object The resolved object can be the caller's own value or, when a ref was just resolved, the tree's own object, which aliases the user or theme config because mergeGlobalStyles keeps backgroundImage leaves atomic. Writing the resolved absolute URL in place could convert a portable theme-relative file: pointer into a hardcoded site URL in data that gets saved. Return a copy instead. --- packages/global-styles-engine/CHANGELOG.md | 4 ++++ .../src/test/utils.test.ts | 23 +++++++++++++++++++ .../global-styles-engine/src/utils/common.ts | 16 +++++++++---- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/global-styles-engine/CHANGELOG.md b/packages/global-styles-engine/CHANGELOG.md index cf7c7452955ca3..f78728ac1b19fe 100644 --- a/packages/global-styles-engine/CHANGELOG.md +++ b/packages/global-styles-engine/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fixes + +- `getResolvedValue`: Return a copy when resolving a theme-relative (`file:./…`) URL instead of writing the resolved URL onto the given object, which could be the caller's own value or, via a `ref`, an object aliased by the user or theme config ([#XXXXX](https://github.com/WordPress/gutenberg/pull/XXXXX)). + ## 1.21.0 (2026-08-26) ### Bug Fixes diff --git a/packages/global-styles-engine/src/test/utils.test.ts b/packages/global-styles-engine/src/test/utils.test.ts index 6969c43052821f..4e3a60ba1d4cfe 100644 --- a/packages/global-styles-engine/src/test/utils.test.ts +++ b/packages/global-styles-engine/src/test/utils.test.ts @@ -482,5 +482,28 @@ describe( 'editor utils', () => { ).toEqual( returnedValue ); } ); + + it( 'returns a copy instead of writing the resolved URL onto the given value', () => { + const ruleValue = { url: 'file:./assets/image.jpg' }; + expect( getResolvedValue( ruleValue, themeJson ) ).toEqual( { + url: 'https://wordpress.org/assets/image.jpg', + } ); + expect( ruleValue.url ).toBe( 'file:./assets/image.jpg' ); + } ); + + it( 'does not write the resolved URL into the tree when resolving a ref', () => { + const tree = JSON.parse( + JSON.stringify( themeJson ) + ) as GlobalStylesConfig; + expect( + getResolvedValue( + { ref: 'styles.background.backgroundImage' }, + tree + ) + ).toEqual( { url: 'https://wordpress.org/assets/image.jpg' } ); + expect( tree.styles?.background?.backgroundImage ).toEqual( { + url: 'file:./assets/image.jpg', + } ); + } ); } ); } ); diff --git a/packages/global-styles-engine/src/utils/common.ts b/packages/global-styles-engine/src/utils/common.ts index e5f5c0cfa02d27..07d80c2a2ab7bf 100644 --- a/packages/global-styles-engine/src/utils/common.ts +++ b/packages/global-styles-engine/src/utils/common.ts @@ -469,10 +469,18 @@ export function getResolvedValue( 'url' in resolvedValue && resolvedValue?.url ) { - resolvedValue.url = getResolvedThemeFilePath( - resolvedValue.url, - tree?._links?.[ 'wp:theme-file' ] - ); + /* + * Copy rather than write in place: `resolvedValue` is the caller's + * own object or, when a `ref` was just resolved, the tree's — which + * aliases the user or theme config. + */ + return { + ...resolvedValue, + url: getResolvedThemeFilePath( + resolvedValue.url, + tree?._links?.[ 'wp:theme-file' ] + ), + }; } return resolvedValue; From c66b760b007c33085481e1b700c05affdecfb663 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 1 Sep 2026 17:43:05 +1000 Subject: [PATCH 2/2] Fill in the changelog PR reference --- packages/global-styles-engine/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/global-styles-engine/CHANGELOG.md b/packages/global-styles-engine/CHANGELOG.md index f78728ac1b19fe..911ccaaf2fbe08 100644 --- a/packages/global-styles-engine/CHANGELOG.md +++ b/packages/global-styles-engine/CHANGELOG.md @@ -4,7 +4,7 @@ ### Bug Fixes -- `getResolvedValue`: Return a copy when resolving a theme-relative (`file:./…`) URL instead of writing the resolved URL onto the given object, which could be the caller's own value or, via a `ref`, an object aliased by the user or theme config ([#XXXXX](https://github.com/WordPress/gutenberg/pull/XXXXX)). +- `getResolvedValue`: Return a copy when resolving a theme-relative (`file:./…`) URL instead of writing the resolved URL onto the given object, which could be the caller's own value or, via a `ref`, an object aliased by the user or theme config ([#82278](https://github.com/WordPress/gutenberg/pull/82278)). ## 1.21.0 (2026-08-26)