From 5fb9c1cb1dc77863b4f9ec0bf55cd1c91eaa68b4 Mon Sep 17 00:00:00 2001 From: David Arenas Date: Wed, 21 Aug 2024 12:20:52 +0200 Subject: [PATCH] Interactivity API: Fix context inheritance from namespaces different than the current one (#64677) * Add failing test * Fix contextStack generation to include other namespaces * Update changelog Co-authored-by: DAreRodz Co-authored-by: luisherranz --- .../directive-context/render.php | 21 +++++++++++++++++++ packages/interactivity/CHANGELOG.md | 4 ++++ packages/interactivity/src/directives.tsx | 14 ++++++------- .../interactivity/directive-context.spec.ts | 15 +++++++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php index b52120debdc56..76635e37a2608 100644 --- a/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-context/render.php @@ -212,3 +212,24 @@ > + + +
+
+ + +
+
diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 52707b70ba5a7..9068e1780cc10 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fixes + +- Fix context inheritance from namespaces different than the current one ([#64677](https://github.com/WordPress/gutenberg/pull/64677)). + ## 6.5.0 (2024-08-07) ### Enhancements diff --git a/packages/interactivity/src/directives.tsx b/packages/interactivity/src/directives.tsx index 357fe203399be..715bc2ea7b16b 100644 --- a/packages/interactivity/src/directives.tsx +++ b/packages/interactivity/src/directives.tsx @@ -273,12 +273,11 @@ export default () => { const inheritedValue = useContext( inheritedContext ); const ns = defaultEntry!.namespace; - const currentValue = useRef( { - [ ns ]: proxifyState( ns, {} ), - } ); + const currentValue = useRef( proxifyState( ns, {} ) ); // No change should be made if `defaultEntry` does not exist. const contextStack = useMemo( () => { + const result = { ...inheritedValue }; if ( defaultEntry ) { const { namespace, value } = defaultEntry; // Check that the value is a JSON object. Send a console warning if not. @@ -288,15 +287,16 @@ export default () => { ); } updateContext( - currentValue.current[ namespace ], + currentValue.current, deepClone( value ) as object ); - currentValue.current[ namespace ] = proxifyContext( - currentValue.current[ namespace ], + currentValue.current = proxifyContext( + currentValue.current, inheritedValue[ namespace ] ); + result[ namespace ] = currentValue.current; } - return currentValue.current; + return result; }, [ defaultEntry, inheritedValue ] ); return createElement( Provider, { value: contextStack }, children ); diff --git a/test/e2e/specs/interactivity/directive-context.spec.ts b/test/e2e/specs/interactivity/directive-context.spec.ts index e806049ff55e7..0a27fe258d5a8 100644 --- a/test/e2e/specs/interactivity/directive-context.spec.ts +++ b/test/e2e/specs/interactivity/directive-context.spec.ts @@ -380,4 +380,19 @@ test.describe( 'data-wp-context', () => { expect( childContextAfter.obj2.prop6 ).toBe( 'child' ); expect( childContextAfter.obj2.overwritten ).toBeUndefined(); } ); + + test( 'properties from other namespaces defined in a parent context are inherited', async ( { + page, + } ) => { + const childProp = page + .getByTestId( 'inheritance from other namespaces' ) + .getByTestId( 'child' ); + + const parentProp = page + .getByTestId( 'inheritance from other namespaces' ) + .getByTestId( 'parent' ); + + await expect( childProp ).toHaveText( 'fromChildNs' ); + await expect( parentProp ).toHaveText( 'fromParentNs' ); + } ); } );