Repository navigation
Conversation
Introduces `wp_split_space_separated_tokens()`, which splits a plain-text string on ASCII whitespace, as a browser does for a set of space-separated tokens such as a list of class names. It performs no character reference decoding, deduplication, or case normalization. The helper replaces duplicated `strtok()` loops in `wp_render_elements_class_name()` and `wp_render_custom_css_class_name()`, and fixes class name parsing in the following functions: - `wp_render_block_style_variation_class_name()` and `wp_get_block_style_variation_name_from_class()` used a `\b` word boundary, which matched `is-style-*` inside another class name such as `custom-is-style-fancy--1`. - `wp_get_block_style_variation_name_from_registered_style()` split only on spaces, missing variations separated by tabs or newlines. Fixes #65466.
|
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 Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @RumanCodes. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Test reportEnvironment — WordPress 7.2-alpha (trunk The helper matches the spec
Behaviour changes at the call sitesI ran 16 edge cases through
Automated
The failing CI job looks unrelated
There is no call path from that test to A likely mechanism, which I could not reproduce locally — I had no way to enable memcached Suggested next step: re-run just that job. Green means ordering; red again points at Not testedThe memcached configuration itself (reason above), multisite, the full suite locally, and the One noteThis is 26 commits behind trunk, so it will want a refresh before commit. And since it adopts AI assistance: Yes (Claude Code), used for the edge-case comparison, running the suites, triaging |
| // @ticket 65466 | ||
| 'whitespace separators' => array( | ||
| 'class_string' => "is-style-light\tcustom-class\nis-style-outline", | ||
| 'expected' => array( 'light', 'outline' ), | ||
| ), | ||
| // @ticket 65466 | ||
| 'prefix inside another class name' => array( | ||
| 'class_string' => 'custom-is-style-outline', | ||
| 'expected' => array(), | ||
| ), | ||
| // @ticket 65466 | ||
| 'variation ending in a non-word character' => array( | ||
| 'class_string' => 'is-style-outline-', | ||
| 'expected' => array( 'outline-' ), | ||
| ), | ||
| // @ticket 65466 | ||
| 'default variation' => array( | ||
| 'class_string' => 'is-style-default is-style-outline', | ||
| 'expected' => array( 'outline' ), | ||
| ), |
There was a problem hiding this comment.
I don't think we need to add tests to all the functions that use this new method for token splitting for more cases.
There was a problem hiding this comment.
Thanks! I removed the test cases that were only checking token splitting (like a tab or newline between class names), since the helper's own tests already cover that. I kept the cases that test the actual bug this PR fixes, like 'prefix inside another class name' and 'instance number followed by a suffix', since those are not about token splitting, they check the real logic of these functions. Happy to remove more if you think any of these are still not needed.
| function wp_split_space_separated_tokens( string $input ): array { | ||
| $tokens = array(); | ||
| $delimiters = " \t\n\f\r"; | ||
| $length = strlen( $input ); | ||
| $offset = strspn( $input, $delimiters ); | ||
|
|
||
| while ( $offset < $length ) { | ||
| $token_length = strcspn( $input, $delimiters, $offset ); | ||
| $tokens[] = substr( $input, $offset, $token_length ); | ||
| $offset += $token_length; | ||
| $offset += strspn( $input, $delimiters, $offset ); | ||
| } | ||
|
|
||
| return $tokens; | ||
| } |
There was a problem hiding this comment.
Note that all the consumers are foreach loops. This would be better as a generator yielding the tokens.
All consumers iterate the tokens in a `foreach` loop, so yield each token instead of building an array. Also drop the call-site test cases that only exercise token splitting, which the helper's own tests already cover. See #65466.
…ns()`. The helper's own tests cover token splitting, so the functions that use it do not need additional cases. See #65466.
Use the same loop structure, boundary characters, and documentation style as `WP_HTML_Tag_Processor::class_list()`, and follow the same test conventions: a static data provider and an assertion message. See #65466.
The previous commit dropped these along with the token-splitting duplicates, but they are not about tokenization: they are the regression tests for the \b word-boundary bug this ticket fixes, and are referenced by name in the PR description's testing instructions. See #65466.
Trac ticket: https://core.trac.wordpress.org/ticket/65466
Introduces
wp_split_space_separated_tokens(), a generator that yields each token of a plain-text string split on ASCII whitespace (" \t\n\f\r"), as a browser does for a set of space-separated tokens such as a list of class names. It then uses the helper to fix class name parsing in block supports.Notes
classattribute. For HTML,WP_HTML_Tag_Processor::class_list()remains the right tool.foreachloop.functions.phpnext towp_parse_list(), which is not suitable here because it also splits on commas.wp_render_elements_class_name()andwp_render_custom_css_class_name()contained the samestrtok()loop. Both now use the helper, with no change in behavior.wp_render_block_style_variation_class_name()used/\bis-style-(\S+?--\d+)\b/. Because\bmatches after a hyphen,custom-is-style-fancy--1andis-style-fancy--1-extraboth causedis-style-fancy--1to be added to the block markup.wp_get_block_style_variation_name_from_class()used\bthe same way, so it matchedis-style-*inside another class name. This is the core counterpart ofgutenberg_get_block_style_variation_name_from_class()listed in the ticket.wp_get_block_style_variation_name_from_registered_style()usedexplode( ' ', … ), so a variation separated by a tab or newline was missed.wp_get_block_style_variation_name_from_class()still skips any variation whose name starts withdefault, as the(?!default)lookahead did.WP_Duotone::restore_image_outer_container()is not changed. It was already updated to use the HTML API class helpers in r62627, as noted in comment:3.class_list_from_string()method toWP_HTML_Tag_Processorwithout updating the call sites.gutenberg_*) will need the same change.Testing Instructions
npm run test:php -- --filter 'wpSplitSpaceSeparatedTokens|WpGetBlockStyleVariationNameFromClass|Tests_Block_Supports_Layout|Tests_Block_Supports_BlockStyleVariations|WpRenderElementsSupport|WpRenderCustomCssClassName'npm run test:php -- --group block-supports,functions,blocks.Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Verifying the ticket against trunk, implementing the helper and call-site changes, addressing review feedback, writing the tests, and drafting this description.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.