diff --git a/packages/e2e-tests/plugins/interactive-blocks/store/block.json b/packages/e2e-tests/plugins/interactive-blocks/store/block.json new file mode 100644 index 00000000000000..cddd765ba3db53 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/store/block.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "test/store", + "title": "E2E Interactivity tests - store definition", + "category": "text", + "icon": "heart", + "description": "", + "supports": { + "interactivity": true + }, + "textdomain": "e2e-interactivity", + "viewScript": "store-view", + "render": "file:./render.php" +} diff --git a/packages/e2e-tests/plugins/interactive-blocks/store/render.php b/packages/e2e-tests/plugins/interactive-blocks/store/render.php new file mode 100644 index 00000000000000..295872137dbdae --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/store/render.php @@ -0,0 +1,17 @@ + + +
+
+
diff --git a/packages/e2e-tests/plugins/interactive-blocks/store/view.js b/packages/e2e-tests/plugins/interactive-blocks/store/view.js new file mode 100644 index 00000000000000..b4a987b5e85b5e --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/store/view.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { store, getElement } from '@wordpress/interactivity'; + + +const { state } = store( 'test/store', { + state: { + get isNotProxified() { + const { ref } = getElement(); + return state.elementRef === ref; + } + }, + callbacks: { + init() { + const { ref } = getElement(); + state.elementRef = ref; // HTMLElement + } + } +} ) diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 4312571046bbf8..0f905e735edf8e 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fixes + +- Only add proxies to plain objects inside the store. ([#59039](https://github.com/WordPress/gutenberg/pull/59039)) + ## 5.0.0 (2024-02-09) ### New Features diff --git a/packages/interactivity/src/store.ts b/packages/interactivity/src/store.ts index 3b877dac2d4143..bbdb167054e3b3 100644 --- a/packages/interactivity/src/store.ts +++ b/packages/interactivity/src/store.ts @@ -16,8 +16,8 @@ import { resetNamespace, } from './hooks'; -const isObject = ( item: unknown ): boolean => - !! item && typeof item === 'object' && ! Array.isArray( item ); +const isObject = ( item: unknown ): item is Record< string, unknown > => + item && typeof item === 'object' && item.constructor === Object; const deepMerge = ( target: any, source: any ) => { if ( isObject( target ) && isObject( source ) ) { diff --git a/test/e2e/specs/interactivity/store-tag.spec.ts b/test/e2e/specs/interactivity/interactivity-data.spec.ts similarity index 100% rename from test/e2e/specs/interactivity/store-tag.spec.ts rename to test/e2e/specs/interactivity/interactivity-data.spec.ts diff --git a/test/e2e/specs/interactivity/store.spec.ts b/test/e2e/specs/interactivity/store.spec.ts new file mode 100644 index 00000000000000..a97cf8c055be19 --- /dev/null +++ b/test/e2e/specs/interactivity/store.spec.ts @@ -0,0 +1,25 @@ +/** + * Internal dependencies + */ +import { test, expect } from './fixtures'; + +test.describe( 'data-wp-bind', () => { + test.beforeAll( async ( { interactivityUtils: utils } ) => { + await utils.activatePlugins(); + await utils.addPostWithBlock( 'test/store' ); + } ); + + test.beforeEach( async ( { interactivityUtils: utils, page } ) => { + await page.goto( utils.getLink( 'test/store' ) ); + } ); + + test.afterAll( async ( { interactivityUtils: utils } ) => { + await utils.deactivatePlugins(); + await utils.deleteAllPosts(); + } ); + + test( 'non-plain objects are not proxified', async ( { page } ) => { + const el = page.getByTestId( 'non-plain object' ); + await expect( el ).toHaveText( 'true' ); + } ); +} );