Skip to content

Commit

Permalink
Interactivity API: fix namespaces in nested interactive regions (#57029)
Browse files Browse the repository at this point in the history
* Add failing test

* Turn namespaces into a stack inside `toVdom`

* Add changelog entry
  • Loading branch information
DAreRodz authored and artemiomorales committed Jan 4, 2024
1 parent 58473bd commit 3eb7c8d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,16 @@
</div>
</div>
</div>



<div data-wp-interactive='{ "namespace": "tovdom-islands" }'>
<div data-wp-interactive='{ "namespace": "something-new" }'></div>
<div data-wp-show-mock="state.falseValue">
<span data-testid="directive after different namespace">
The directive above should keep the `tovdom-island` namespace,
so this message should not be visible.
</span>
</div>
</div>
</div>
4 changes: 4 additions & 0 deletions packages/interactivity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Bug Fix

- Fix namespaces when there are nested interactive regions. ([#57029](https://github.com/WordPress/gutenberg/pull/57029))

## 3.1.0 (2023-12-13)

## 3.0.0 (2023-11-29)
Expand Down
10 changes: 7 additions & 3 deletions packages/interactivity/src/vdom.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { directivePrefix as p } from './constants';
const ignoreAttr = `data-${ p }-ignore`;
const islandAttr = `data-${ p }-interactive`;
const fullPrefix = `data-${ p }-`;
let namespace = null;
const namespaces = [];
const currentNamespace = () => namespaces[ namespaces.length - 1 ] ?? null;

// Regular expression for directive parsing.
const directiveParser = new RegExp(
Expand Down Expand Up @@ -79,7 +80,7 @@ export function toVdom( root ) {
} catch ( e ) {}
if ( n === islandAttr ) {
island = true;
namespace = value?.namespace ?? null;
namespaces.push( value?.namespace ?? null );
} else {
directives.push( [ n, ns, value ] );
}
Expand Down Expand Up @@ -107,7 +108,7 @@ export function toVdom( root ) {
directiveParser.exec( name );
if ( ! obj[ prefix ] ) obj[ prefix ] = [];
obj[ prefix ].push( {
namespace: ns ?? namespace,
namespace: ns ?? currentNamespace(),
value,
suffix,
} );
Expand All @@ -127,6 +128,9 @@ export function toVdom( root ) {
treeWalker.parentNode();
}

// Restore previous namespace.
if ( island ) namespaces.pop();

return [ h( node.localName, props, children ) ];
}

Expand Down
7 changes: 7 additions & 0 deletions test/e2e/specs/interactivity/tovdom-islands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,11 @@ test.describe( 'toVdom - islands', () => {
);
await expect( el ).toBeHidden();
} );

test( 'islands should recover their namespace if an inner island has changed it', async ( {
page,
} ) => {
const el = page.getByTestId( 'directive after different namespace' );
await expect( el ).toBeHidden();
} );
} );

0 comments on commit 3eb7c8d

Please sign in to comment.