-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interactivity API: Improve data-wp-context debugging by validating it as a stringified JSON Object. #61045
Interactivity API: Improve data-wp-context debugging by validating it as a stringified JSON Object. #61045
Conversation
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @cbravobernal! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
Size Change: -1.65 kB (0%) Total Size: 1.74 MB
ℹ️ View Unchanged
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on the debugging experience. Will you also add a changelog entry for this?
// translators: %s: store namespace. | ||
__( | ||
'The value of data-wp-context in "%s" store must be a valid stringified JSON object.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know whether translation data would be extracted from this package, but because it's a module and nothing about modules adds the translation data when they're enqueued (or in the importmap), I don't think localization will work here.
Since this is developer-facing and we don't have a good solution, it seems fine to use the untranslated text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove it. i18n would need a module version too.
// No change should be made if `defaultEntry` does not exist. | ||
const contextStack = useMemo( () => { | ||
if ( defaultEntry ) { | ||
const { namespace, value } = defaultEntry; | ||
// Check that the value is a JSON object. Send a console warning if not. | ||
if ( SCRIPT_DEBUG && typeof value !== 'object' ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null
and []
would both pass this check, but I think the intention is to allow "plain" objects.
We have this function in a couple places already in iAPI:
gutenberg/packages/interactivity/src/store.ts
Lines 19 to 20 in 2b1b80e
const isObject = ( item: unknown ): item is Record< string, unknown > => | |
item && typeof item === 'object' && item.constructor === Object; |
gutenberg/packages/interactivity/src/directives.js
Lines 25 to 26 in 2b1b80e
const isPlainObject = ( item ) => | |
item && typeof item === 'object' && item.constructor === Object; |
One of those is in this file, let's use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I completely missed it. Thanks!
0596b1e
to
af69f1c
Compare
const { sprintf, __ } = window.wp.i18n; | ||
const { warning } = window.wp; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const { sprintf, __ } = window.wp.i18n; | |
const { warning } = window.wp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I've removed it. I guess I messed with the push.
lib/interactivity-api.php
Outdated
if ( SCRIPT_DEBUG ) { | ||
wp_enqueue_script( 'wp-i18n' ); | ||
wp_enqueue_script( 'wp-warning' ); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ( SCRIPT_DEBUG ) { | |
wp_enqueue_script( 'wp-i18n' ); | |
wp_enqueue_script( 'wp-warning' ); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I've removed it. I guess I messed with the push.
if ( SCRIPT_DEBUG && isPlainObject(value) ) { | ||
console.warn('The value of data-wp-context in "%s" store must be a valid stringified JSON object.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the condition is off, there's a missing %s replacement, and the formatting looks off too. Maybe this would be good?
if ( SCRIPT_DEBUG && isPlainObject(value) ) { | |
console.warn('The value of data-wp-context in "%s" store must be a valid stringified JSON object.') | |
if ( SCRIPT_DEBUG && ! isPlainObject( value ) ) { | |
console.warn( 'Context values must be objects, found a value of type "%s" in the "%s" store.', typeof value, namespace ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I've changed it. I guess I messed with the push.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! One final change to make then this is good to ship.
@@ -241,6 +241,13 @@ export default () => { | |||
const contextStack = useMemo( () => { | |||
if ( defaultEntry ) { | |||
const { namespace, value } = defaultEntry; | |||
// Check that the value is a JSON object. Send a console warning if not. | |||
if ( SCRIPT_DEBUG && ! isPlainObject( value ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this is published as a package, we don't want to require these arbitrary global variables to be declared, so we should add a typeof
check like is done in the warning package (this may require formatting):
if ( SCRIPT_DEBUG && ! isPlainObject( value ) ) { | |
if ( typeof SCRIPT_DEBUG !== 'undefined' && SCRIPT_DEBUG === true && ! isPlainObject( value ) ) { |
gutenberg/packages/warning/src/index.js
Lines 6 to 8 in 649eddf
function isDev() { | |
return typeof SCRIPT_DEBUG !== 'undefined' && SCRIPT_DEBUG === true; | |
} |
Otherwise, when this is used in other environments we'd get a ReferenceError.
I'm a little bit concerned that we don't lint this type of thing 😕
Flaky tests detected in 7c34f41. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/8880285685
|
What?
Add a console warning if data-wp-context is not a JSON.
Why?
I'm afraid it may be too late to prevent developers from adding any string into
data-wp-context
, but we can at least add a warning if the content of the directive is not the expected one.How?
I did on the
directives.js
but, should we add adoing_it_wrong()
notice in the server instead?Testing Instructions
1.) Add an interactive block via
npx @wordpress/create-block@latest counter-block --template @wordpress/create-block-interactive-template
2.) Edit the render file to use a non stringified JSON object as
data-wp-context
. Something like3.) Add your block to a post or page.
4.) Check the warning on the frontend while running
npm run dev
.5.) Check the warning does not appear if it has a production build.
Screenshots or screencast