Edit File by line
/home/zeestwma/redstone.../wp-inclu...
File: script-loader.php
'name' => $menu_slug . '-' . $submenu_item[2],
[3500] Fix | Delete
);
[3501] Fix | Delete
}
[3502] Fix | Delete
}
[3503] Fix | Delete
}
[3504] Fix | Delete
}
[3505] Fix | Delete
$command_palette_settings['menu_commands'] = $menu_commands;
[3506] Fix | Delete
}
[3507] Fix | Delete
[3508] Fix | Delete
wp_enqueue_script( 'wp-commands' );
[3509] Fix | Delete
wp_enqueue_style( 'wp-commands' );
[3510] Fix | Delete
wp_enqueue_script( 'wp-core-commands' );
[3511] Fix | Delete
[3512] Fix | Delete
wp_add_inline_script(
[3513] Fix | Delete
'wp-core-commands',
[3514] Fix | Delete
sprintf(
[3515] Fix | Delete
'wp.coreCommands.initializeCommandPalette( %s );',
[3516] Fix | Delete
wp_json_encode( $command_palette_settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
[3517] Fix | Delete
)
[3518] Fix | Delete
);
[3519] Fix | Delete
}
[3520] Fix | Delete
[3521] Fix | Delete
/**
[3522] Fix | Delete
* Removes leading and trailing _empty_ script tags.
[3523] Fix | Delete
*
[3524] Fix | Delete
* This is a helper meant to be used for literal script tag construction
[3525] Fix | Delete
* within `wp_get_inline_script_tag()` or `wp_print_inline_script_tag()`.
[3526] Fix | Delete
* It removes the literal values of "<script>" and "</script>" from
[3527] Fix | Delete
* around an inline script after trimming whitespace. Typically this
[3528] Fix | Delete
* is used in conjunction with output buffering, where `ob_get_clean()`
[3529] Fix | Delete
* is passed as the `$contents` argument.
[3530] Fix | Delete
*
[3531] Fix | Delete
* Example:
[3532] Fix | Delete
*
[3533] Fix | Delete
* // Strips exact literal empty SCRIPT tags.
[3534] Fix | Delete
* $js = '<script>sayHello();</script>;
[3535] Fix | Delete
* 'sayHello();' === wp_remove_surrounding_empty_script_tags( $js );
[3536] Fix | Delete
*
[3537] Fix | Delete
* // Otherwise if anything is different it warns in the JS console.
[3538] Fix | Delete
* $js = '<script type="text/javascript">console.log( "hi" );</script>';
[3539] Fix | Delete
* 'console.error( ... )' === wp_remove_surrounding_empty_script_tags( $js );
[3540] Fix | Delete
*
[3541] Fix | Delete
* @since 6.4.0
[3542] Fix | Delete
* @access private
[3543] Fix | Delete
*
[3544] Fix | Delete
* @see wp_print_inline_script_tag()
[3545] Fix | Delete
* @see wp_get_inline_script_tag()
[3546] Fix | Delete
*
[3547] Fix | Delete
* @param string $contents Script body with manually created SCRIPT tag literals.
[3548] Fix | Delete
* @return string Script body without surrounding script tag literals, or
[3549] Fix | Delete
* original contents if both exact literals aren't present.
[3550] Fix | Delete
*/
[3551] Fix | Delete
function wp_remove_surrounding_empty_script_tags( $contents ) {
[3552] Fix | Delete
$contents = trim( $contents );
[3553] Fix | Delete
$opener = '<SCRIPT>';
[3554] Fix | Delete
$closer = '</SCRIPT>';
[3555] Fix | Delete
[3556] Fix | Delete
if (
[3557] Fix | Delete
strlen( $contents ) > strlen( $opener ) + strlen( $closer ) &&
[3558] Fix | Delete
strtoupper( substr( $contents, 0, strlen( $opener ) ) ) === $opener &&
[3559] Fix | Delete
strtoupper( substr( $contents, -strlen( $closer ) ) ) === $closer
[3560] Fix | Delete
) {
[3561] Fix | Delete
return substr( $contents, strlen( $opener ), -strlen( $closer ) );
[3562] Fix | Delete
} else {
[3563] Fix | Delete
$error_message = __( 'Expected string to start with script tag (without attributes) and end with script tag, with optional whitespace.' );
[3564] Fix | Delete
_doing_it_wrong( __FUNCTION__, $error_message, '6.4' );
[3565] Fix | Delete
return sprintf(
[3566] Fix | Delete
'console.error(%s)',
[3567] Fix | Delete
wp_json_encode(
[3568] Fix | Delete
sprintf(
[3569] Fix | Delete
/* translators: %s: wp_remove_surrounding_empty_script_tags() */
[3570] Fix | Delete
__( 'Function %s used incorrectly in PHP.' ),
[3571] Fix | Delete
'wp_remove_surrounding_empty_script_tags()'
[3572] Fix | Delete
) . ' ' . $error_message
[3573] Fix | Delete
)
[3574] Fix | Delete
);
[3575] Fix | Delete
}
[3576] Fix | Delete
}
[3577] Fix | Delete
[3578] Fix | Delete
/**
[3579] Fix | Delete
* Adds hooks to load block styles on demand in classic themes.
[3580] Fix | Delete
*
[3581] Fix | Delete
* @since 6.9.0
[3582] Fix | Delete
*
[3583] Fix | Delete
* @see _add_default_theme_supports()
[3584] Fix | Delete
*/
[3585] Fix | Delete
function wp_load_classic_theme_block_styles_on_demand() {
[3586] Fix | Delete
// This is not relevant to block themes, as they are opted in to loading separate styles on demand via _add_default_theme_supports().
[3587] Fix | Delete
if ( wp_is_block_theme() ) {
[3588] Fix | Delete
return;
[3589] Fix | Delete
}
[3590] Fix | Delete
[3591] Fix | Delete
/*
[3592] Fix | Delete
* Make sure that wp_should_output_buffer_template_for_enhancement() returns true even if there aren't any
[3593] Fix | Delete
* `wp_template_enhancement_output_buffer` filters added, but do so at priority zero so that applications which
[3594] Fix | Delete
* wish to stream responses can more easily turn this off.
[3595] Fix | Delete
*/
[3596] Fix | Delete
add_filter( 'wp_should_output_buffer_template_for_enhancement', '__return_true', 0 );
[3597] Fix | Delete
[3598] Fix | Delete
// If a site has opted out of the template enhancement output buffer, then bail.
[3599] Fix | Delete
if ( ! wp_should_output_buffer_template_for_enhancement() ) {
[3600] Fix | Delete
return;
[3601] Fix | Delete
}
[3602] Fix | Delete
[3603] Fix | Delete
// The following two filters are added by default for block themes in _add_default_theme_supports().
[3604] Fix | Delete
[3605] Fix | Delete
/*
[3606] Fix | Delete
* Load separate block styles so that the large block-library stylesheet is not enqueued unconditionally, and so
[3607] Fix | Delete
* that block-specific styles will only be enqueued when they are used on the page. A priority of zero allows for
[3608] Fix | Delete
* this to be easily overridden by themes which wish to opt out. If a site has explicitly opted out of loading
[3609] Fix | Delete
* separate block styles, then abort.
[3610] Fix | Delete
*/
[3611] Fix | Delete
add_filter( 'should_load_separate_core_block_assets', '__return_true', 0 );
[3612] Fix | Delete
if ( ! wp_should_load_separate_core_block_assets() ) {
[3613] Fix | Delete
return;
[3614] Fix | Delete
}
[3615] Fix | Delete
[3616] Fix | Delete
/*
[3617] Fix | Delete
* Also ensure that block assets are loaded on demand (although the default value is from should_load_separate_core_block_assets).
[3618] Fix | Delete
* As above, a priority of zero allows for this to be easily overridden by themes which wish to opt out. If a site
[3619] Fix | Delete
* has explicitly opted out of loading block styles on demand, then abort.
[3620] Fix | Delete
*/
[3621] Fix | Delete
add_filter( 'should_load_block_assets_on_demand', '__return_true', 0 );
[3622] Fix | Delete
if ( ! wp_should_load_block_assets_on_demand() ) {
[3623] Fix | Delete
return;
[3624] Fix | Delete
}
[3625] Fix | Delete
[3626] Fix | Delete
// Add hooks which require the presence of the output buffer. Ideally the above two filters could be added here, but they run too early.
[3627] Fix | Delete
add_action( 'wp_template_enhancement_output_buffer_started', 'wp_hoist_late_printed_styles' );
[3628] Fix | Delete
}
[3629] Fix | Delete
[3630] Fix | Delete
/**
[3631] Fix | Delete
* Adds the hooks needed for CSS output to be delayed until after the content of the page has been established.
[3632] Fix | Delete
*
[3633] Fix | Delete
* @since 6.9.0
[3634] Fix | Delete
*
[3635] Fix | Delete
* @see wp_load_classic_theme_block_styles_on_demand()
[3636] Fix | Delete
* @see _wp_footer_scripts()
[3637] Fix | Delete
*/
[3638] Fix | Delete
function wp_hoist_late_printed_styles() {
[3639] Fix | Delete
// Skip the embed template on-demand styles aren't relevant, and there is no wp_head action.
[3640] Fix | Delete
if ( is_embed() ) {
[3641] Fix | Delete
return;
[3642] Fix | Delete
}
[3643] Fix | Delete
[3644] Fix | Delete
/*
[3645] Fix | Delete
* Add a placeholder comment into the inline styles for wp-block-library, after which where the late block styles
[3646] Fix | Delete
* can be hoisted from the footer to be printed in the header by means of a filter below on the template enhancement
[3647] Fix | Delete
* output buffer. The `wp_print_styles` action is used to ensure that if the inline style gets replaced at
[3648] Fix | Delete
* `enqueue_block_assets` or `wp_enqueue_scripts` that the placeholder will be sure to be present.
[3649] Fix | Delete
*/
[3650] Fix | Delete
$placeholder = sprintf( '/*%s*/', uniqid( 'wp_block_styles_on_demand_placeholder:' ) );
[3651] Fix | Delete
add_action(
[3652] Fix | Delete
'wp_print_styles',
[3653] Fix | Delete
static function () use ( $placeholder ) {
[3654] Fix | Delete
wp_add_inline_style( 'wp-block-library', $placeholder );
[3655] Fix | Delete
}
[3656] Fix | Delete
);
[3657] Fix | Delete
[3658] Fix | Delete
/*
[3659] Fix | Delete
* Create a substitute for `print_late_styles()` which is aware of block styles. This substitute does not print
[3660] Fix | Delete
* the styles, but it captures what would be printed for block styles and non-block styles so that they can be
[3661] Fix | Delete
* later hoisted to the HEAD in the template enhancement output buffer. This will run at `wp_print_footer_scripts`
[3662] Fix | Delete
* before `print_footer_scripts()` is called.
[3663] Fix | Delete
*/
[3664] Fix | Delete
$printed_block_styles = '';
[3665] Fix | Delete
$printed_late_styles = '';
[3666] Fix | Delete
$capture_late_styles = static function () use ( &$printed_block_styles, &$printed_late_styles ) {
[3667] Fix | Delete
// Gather the styles related to on-demand block enqueues.
[3668] Fix | Delete
$all_block_style_handles = array();
[3669] Fix | Delete
foreach ( WP_Block_Type_Registry::get_instance()->get_all_registered() as $block_type ) {
[3670] Fix | Delete
foreach ( $block_type->style_handles as $style_handle ) {
[3671] Fix | Delete
$all_block_style_handles[] = $style_handle;
[3672] Fix | Delete
}
[3673] Fix | Delete
}
[3674] Fix | Delete
$all_block_style_handles = array_merge(
[3675] Fix | Delete
$all_block_style_handles,
[3676] Fix | Delete
array(
[3677] Fix | Delete
'global-styles',
[3678] Fix | Delete
'block-style-variation-styles',
[3679] Fix | Delete
'core-block-supports',
[3680] Fix | Delete
'core-block-supports-duotone',
[3681] Fix | Delete
)
[3682] Fix | Delete
);
[3683] Fix | Delete
[3684] Fix | Delete
/*
[3685] Fix | Delete
* First print all styles related to blocks which should inserted right after the wp-block-library stylesheet
[3686] Fix | Delete
* to preserve the CSS cascade. The logic in this `if` statement is derived from `wp_print_styles()`.
[3687] Fix | Delete
*/
[3688] Fix | Delete
$enqueued_block_styles = array_values( array_intersect( $all_block_style_handles, wp_styles()->queue ) );
[3689] Fix | Delete
if ( count( $enqueued_block_styles ) > 0 ) {
[3690] Fix | Delete
ob_start();
[3691] Fix | Delete
wp_styles()->do_items( $enqueued_block_styles );
[3692] Fix | Delete
$printed_block_styles = ob_get_clean();
[3693] Fix | Delete
}
[3694] Fix | Delete
[3695] Fix | Delete
/*
[3696] Fix | Delete
* Print all remaining styles not related to blocks. This contains a subset of the logic from
[3697] Fix | Delete
* `print_late_styles()`, without admin-specific logic and the `print_late_styles` filter to control whether
[3698] Fix | Delete
* late styles are printed (since they are being hoisted anyway).
[3699] Fix | Delete
*/
[3700] Fix | Delete
ob_start();
[3701] Fix | Delete
wp_styles()->do_footer_items();
[3702] Fix | Delete
$printed_late_styles = ob_get_clean();
[3703] Fix | Delete
};
[3704] Fix | Delete
[3705] Fix | Delete
/*
[3706] Fix | Delete
* If `_wp_footer_scripts()` was unhooked from the `wp_print_footer_scripts` action, or if `wp_print_footer_scripts()`
[3707] Fix | Delete
* was unhooked from running at the `wp_footer` action, then only add a callback to `wp_footer` which will capture the
[3708] Fix | Delete
* late-printed styles.
[3709] Fix | Delete
*
[3710] Fix | Delete
* Otherwise, in the normal case where `_wp_footer_scripts()` will run at the `wp_print_footer_scripts` action, then
[3711] Fix | Delete
* swap out `_wp_footer_scripts()` with an alternative which captures the printed styles (for hoisting to HEAD) before
[3712] Fix | Delete
* proceeding with printing the footer scripts.
[3713] Fix | Delete
*/
[3714] Fix | Delete
$wp_print_footer_scripts_priority = has_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
[3715] Fix | Delete
if ( false === $wp_print_footer_scripts_priority || false === has_action( 'wp_footer', 'wp_print_footer_scripts' ) ) {
[3716] Fix | Delete
// The normal priority for wp_print_footer_scripts() is to run at 20.
[3717] Fix | Delete
add_action( 'wp_footer', $capture_late_styles, 20 );
[3718] Fix | Delete
} else {
[3719] Fix | Delete
remove_action( 'wp_print_footer_scripts', '_wp_footer_scripts', $wp_print_footer_scripts_priority );
[3720] Fix | Delete
add_action(
[3721] Fix | Delete
'wp_print_footer_scripts',
[3722] Fix | Delete
static function () use ( $capture_late_styles ) {
[3723] Fix | Delete
$capture_late_styles();
[3724] Fix | Delete
print_footer_scripts();
[3725] Fix | Delete
},
[3726] Fix | Delete
$wp_print_footer_scripts_priority
[3727] Fix | Delete
);
[3728] Fix | Delete
}
[3729] Fix | Delete
[3730] Fix | Delete
// Replace placeholder with the captured late styles.
[3731] Fix | Delete
add_filter(
[3732] Fix | Delete
'wp_template_enhancement_output_buffer',
[3733] Fix | Delete
static function ( $buffer ) use ( $placeholder, &$printed_block_styles, &$printed_late_styles ) {
[3734] Fix | Delete
[3735] Fix | Delete
// Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans.
[3736] Fix | Delete
$processor = new class( $buffer ) extends WP_HTML_Tag_Processor {
[3737] Fix | Delete
/**
[3738] Fix | Delete
* Gets the span for the current token.
[3739] Fix | Delete
*
[3740] Fix | Delete
* @return WP_HTML_Span Current token span.
[3741] Fix | Delete
*/
[3742] Fix | Delete
private function get_span(): WP_HTML_Span {
[3743] Fix | Delete
// Note: This call will never fail according to the usage of this class, given it is always called after ::next_tag() is true.
[3744] Fix | Delete
$this->set_bookmark( 'here' );
[3745] Fix | Delete
return $this->bookmarks['here'];
[3746] Fix | Delete
}
[3747] Fix | Delete
[3748] Fix | Delete
/**
[3749] Fix | Delete
* Inserts text before the current token.
[3750] Fix | Delete
*
[3751] Fix | Delete
* @param string $text Text to insert.
[3752] Fix | Delete
*/
[3753] Fix | Delete
public function insert_before( string $text ) {
[3754] Fix | Delete
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $this->get_span()->start, 0, $text );
[3755] Fix | Delete
}
[3756] Fix | Delete
[3757] Fix | Delete
/**
[3758] Fix | Delete
* Inserts text after the current token.
[3759] Fix | Delete
*
[3760] Fix | Delete
* @param string $text Text to insert.
[3761] Fix | Delete
*/
[3762] Fix | Delete
public function insert_after( string $text ) {
[3763] Fix | Delete
$span = $this->get_span();
[3764] Fix | Delete
[3765] Fix | Delete
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $text );
[3766] Fix | Delete
}
[3767] Fix | Delete
[3768] Fix | Delete
/**
[3769] Fix | Delete
* Removes the current token.
[3770] Fix | Delete
*/
[3771] Fix | Delete
public function remove() {
[3772] Fix | Delete
$span = $this->get_span();
[3773] Fix | Delete
[3774] Fix | Delete
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start, $span->length, '' );
[3775] Fix | Delete
}
[3776] Fix | Delete
};
[3777] Fix | Delete
[3778] Fix | Delete
/*
[3779] Fix | Delete
* Insert block styles right after wp-block-library (if it is present), and then insert any remaining styles
[3780] Fix | Delete
* at </head> (or else print everything there). The placeholder CSS comment will always be added to the
[3781] Fix | Delete
* wp-block-library inline style since it gets printed at `wp_head` before the blocks are rendered.
[3782] Fix | Delete
* This means that there may not actually be any block styles to hoist from the footer to insert after this
[3783] Fix | Delete
* inline style. The placeholder CSS comment needs to be added so that the inline style gets printed, but
[3784] Fix | Delete
* if the resulting inline style is empty after the placeholder is removed, then the inline style is
[3785] Fix | Delete
* removed.
[3786] Fix | Delete
*/
[3787] Fix | Delete
while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
[3788] Fix | Delete
if (
[3789] Fix | Delete
'STYLE' === $processor->get_tag() &&
[3790] Fix | Delete
'wp-block-library-inline-css' === $processor->get_attribute( 'id' )
[3791] Fix | Delete
) {
[3792] Fix | Delete
$css_text = $processor->get_modifiable_text();
[3793] Fix | Delete
[3794] Fix | Delete
/*
[3795] Fix | Delete
* A placeholder CSS comment is added to the inline style in order to force an inline STYLE tag to
[3796] Fix | Delete
* be printed. Now that we've located the inline style, the placeholder comment can be removed. If
[3797] Fix | Delete
* there is no CSS left in the STYLE tag after removing the placeholder (aside from the sourceURL
[3798] Fix | Delete
* comment, then remove the STYLE entirely.)
[3799] Fix | Delete
*/
[3800] Fix | Delete
$css_text = str_replace( $placeholder, '', $css_text );
[3801] Fix | Delete
if ( preg_match( ':^/\*# sourceURL=\S+? \*/$:', trim( $css_text ) ) ) {
[3802] Fix | Delete
$processor->remove();
[3803] Fix | Delete
} else {
[3804] Fix | Delete
$processor->set_modifiable_text( $css_text );
[3805] Fix | Delete
}
[3806] Fix | Delete
[3807] Fix | Delete
// Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade.
[3808] Fix | Delete
if ( '' !== $printed_block_styles ) {
[3809] Fix | Delete
$processor->insert_after( $printed_block_styles );
[3810] Fix | Delete
[3811] Fix | Delete
// Prevent printing them again at </head>.
[3812] Fix | Delete
$printed_block_styles = '';
[3813] Fix | Delete
}
[3814] Fix | Delete
[3815] Fix | Delete
// If there aren't any late styles, there's no need to continue to finding </head>.
[3816] Fix | Delete
if ( '' === $printed_late_styles ) {
[3817] Fix | Delete
break;
[3818] Fix | Delete
}
[3819] Fix | Delete
} elseif ( 'HEAD' === $processor->get_tag() && $processor->is_tag_closer() ) {
[3820] Fix | Delete
$processor->insert_before( $printed_block_styles . $printed_late_styles );
[3821] Fix | Delete
break;
[3822] Fix | Delete
}
[3823] Fix | Delete
}
[3824] Fix | Delete
[3825] Fix | Delete
return $processor->get_updated_html();
[3826] Fix | Delete
}
[3827] Fix | Delete
);
[3828] Fix | Delete
}
[3829] Fix | Delete
[3830] Fix | Delete
/**
[3831] Fix | Delete
* Return the corresponding JavaScript `dataset` name for an attribute
[3832] Fix | Delete
* if it represents a custom data attribute, or `null` if not.
[3833] Fix | Delete
*
[3834] Fix | Delete
* Custom data attributes appear in an element's `dataset` property in a
[3835] Fix | Delete
* browser, but there's a specific way the names are translated from HTML
[3836] Fix | Delete
* into JavaScript. This function indicates how the name would appear in
[3837] Fix | Delete
* JavaScript if a browser would recognize it as a custom data attribute.
[3838] Fix | Delete
*
[3839] Fix | Delete
* Example:
[3840] Fix | Delete
*
[3841] Fix | Delete
* // Dash-letter pairs turn into capital letters.
[3842] Fix | Delete
* 'postId' === wp_js_dataset_name( 'data-post-id' );
[3843] Fix | Delete
* 'Before' === wp_js_dataset_name( 'data--before' );
[3844] Fix | Delete
* '-One--Two---' === wp_js_dataset_name( 'data---one---two---' );
[3845] Fix | Delete
*
[3846] Fix | Delete
* // Not every attribute name will be interpreted as a custom data attribute.
[3847] Fix | Delete
* null === wp_js_dataset_name( 'post-id' );
[3848] Fix | Delete
* null === wp_js_dataset_name( 'data' );
[3849] Fix | Delete
*
[3850] Fix | Delete
* // Some very surprising names will; for example, a property whose name is the empty string.
[3851] Fix | Delete
* '' === wp_js_dataset_name( 'data-' );
[3852] Fix | Delete
* 0 === strlen( wp_js_dataset_name( 'data-' ) );
[3853] Fix | Delete
*
[3854] Fix | Delete
* @since 6.9.0
[3855] Fix | Delete
*
[3856] Fix | Delete
* @see https://html.spec.whatwg.org/#concept-domstringmap-pairs
[3857] Fix | Delete
* @see \wp_html_custom_data_attribute_name()
[3858] Fix | Delete
*
[3859] Fix | Delete
* @param string $html_attribute_name Raw attribute name as found in the source HTML.
[3860] Fix | Delete
* @return string|null Transformed `dataset` name, if interpretable as a custom data attribute, else `null`.
[3861] Fix | Delete
*/
[3862] Fix | Delete
function wp_js_dataset_name( string $html_attribute_name ): ?string {
[3863] Fix | Delete
if ( 0 !== substr_compare( $html_attribute_name, 'data-', 0, 5, true ) ) {
[3864] Fix | Delete
return null;
[3865] Fix | Delete
}
[3866] Fix | Delete
[3867] Fix | Delete
$end = strlen( $html_attribute_name );
[3868] Fix | Delete
[3869] Fix | Delete
/*
[3870] Fix | Delete
* If it contains characters which would end the attribute name parsing then
[3871] Fix | Delete
* something else is wrong and this contains more than just an attribute name.
[3872] Fix | Delete
*/
[3873] Fix | Delete
if ( ( $end - 5 ) !== strcspn( $html_attribute_name, "=/> \t\f\r\n", 5 ) ) {
[3874] Fix | Delete
return null;
[3875] Fix | Delete
}
[3876] Fix | Delete
[3877] Fix | Delete
/**
[3878] Fix | Delete
* > For each name in list, for each U+002D HYPHEN-MINUS character (-)
[3879] Fix | Delete
* > in the name that is followed by an ASCII lower alpha, remove the
[3880] Fix | Delete
* > U+002D HYPHEN-MINUS character (-) and replace the character that
[3881] Fix | Delete
* > followed it by the same character converted to ASCII uppercase.
[3882] Fix | Delete
*
[3883] Fix | Delete
* @see https://html.spec.whatwg.org/#concept-domstringmap-pairs
[3884] Fix | Delete
*/
[3885] Fix | Delete
$custom_name = '';
[3886] Fix | Delete
$at = 5;
[3887] Fix | Delete
$was_at = $at;
[3888] Fix | Delete
[3889] Fix | Delete
while ( $at < $end ) {
[3890] Fix | Delete
$next_dash_at = strpos( $html_attribute_name, '-', $at );
[3891] Fix | Delete
if ( false === $next_dash_at || $next_dash_at === $end - 1 ) {
[3892] Fix | Delete
break;
[3893] Fix | Delete
}
[3894] Fix | Delete
[3895] Fix | Delete
// Transform `-a` to `A`, for example.
[3896] Fix | Delete
$c = $html_attribute_name[ $next_dash_at + 1 ];
[3897] Fix | Delete
if ( ( $c >= 'A' && $c <= 'Z' ) || ( $c >= 'a' && $c <= 'z' ) ) {
[3898] Fix | Delete
$prefix = substr( $html_attribute_name, $was_at, $next_dash_at - $was_at );
[3899] Fix | Delete
$custom_name .= strtolower( $prefix );
[3900] Fix | Delete
$custom_name .= strtoupper( $c );
[3901] Fix | Delete
$at = $next_dash_at + 2;
[3902] Fix | Delete
$was_at = $at;
[3903] Fix | Delete
continue;
[3904] Fix | Delete
}
[3905] Fix | Delete
[3906] Fix | Delete
$at = $next_dash_at + 1;
[3907] Fix | Delete
}
[3908] Fix | Delete
[3909] Fix | Delete
// If nothing has been added it means there are no dash-letter pairs; return the name as-is.
[3910] Fix | Delete
return '' === $custom_name
[3911] Fix | Delete
? strtolower( substr( $html_attribute_name, 5 ) )
[3912] Fix | Delete
: ( $custom_name . strtolower( substr( $html_attribute_name, $was_at ) ) );
[3913] Fix | Delete
}
[3914] Fix | Delete
[3915] Fix | Delete
/**
[3916] Fix | Delete
* Returns a corresponding HTML attribute name for the given name,
[3917] Fix | Delete
* if that name were found in a JS element’s `dataset` property.
[3918] Fix | Delete
*
[3919] Fix | Delete
* Example:
[3920] Fix | Delete
*
[3921] Fix | Delete
* 'data-post-id' === wp_html_custom_data_attribute_name( 'postId' );
[3922] Fix | Delete
* 'data--before' === wp_html_custom_data_attribute_name( 'Before' );
[3923] Fix | Delete
* 'data---one---two---' === wp_html_custom_data_attribute_name( '-One--Two---' );
[3924] Fix | Delete
*
[3925] Fix | Delete
* // Not every attribute name will be interpreted as a custom data attribute.
[3926] Fix | Delete
* null === wp_html_custom_data_attribute_name( '/not-an-attribute/' );
[3927] Fix | Delete
* null === wp_html_custom_data_attribute_name( 'no spaces' );
[3928] Fix | Delete
*
[3929] Fix | Delete
* // Some very surprising names will; for example, a property whose name is the empty string.
[3930] Fix | Delete
* 'data-' === wp_html_custom_data_attribute_name( '' );
[3931] Fix | Delete
*
[3932] Fix | Delete
* @since 6.9.0
[3933] Fix | Delete
*
[3934] Fix | Delete
* @see https://html.spec.whatwg.org/#concept-domstringmap-pairs
[3935] Fix | Delete
* @see \wp_js_dataset_name()
[3936] Fix | Delete
*
[3937] Fix | Delete
* @param string $js_dataset_name Name of JS `dataset` property to transform.
[3938] Fix | Delete
* @return string|null Corresponding name of an HTML custom data attribute for the given dataset name,
[3939] Fix | Delete
* if possible to represent in HTML, otherwise `null`.
[3940] Fix | Delete
*/
[3941] Fix | Delete
function wp_html_custom_data_attribute_name( string $js_dataset_name ): ?string {
[3942] Fix | Delete
$end = strlen( $js_dataset_name );
[3943] Fix | Delete
if ( 0 === $end ) {
[3944] Fix | Delete
return 'data-';
[3945] Fix | Delete
}
[3946] Fix | Delete
[3947] Fix | Delete
/*
[3948] Fix | Delete
* If it contains characters which would end the attribute name parsing then
[3949] Fix | Delete
* something it’s not possible to represent this in HTML.
[3950] Fix | Delete
*/
[3951] Fix | Delete
if ( strcspn( $js_dataset_name, "=/> \t\f\r\n" ) !== $end ) {
[3952] Fix | Delete
return null;
[3953] Fix | Delete
}
[3954] Fix | Delete
[3955] Fix | Delete
$html_name = 'data-';
[3956] Fix | Delete
$at = 0;
[3957] Fix | Delete
$was_at = $at;
[3958] Fix | Delete
[3959] Fix | Delete
while ( $at < $end ) {
[3960] Fix | Delete
$next_upper_after = strcspn( $js_dataset_name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', $at );
[3961] Fix | Delete
$next_upper_at = $at + $next_upper_after;
[3962] Fix | Delete
if ( $next_upper_at >= $end ) {
[3963] Fix | Delete
break;
[3964] Fix | Delete
}
[3965] Fix | Delete
[3966] Fix | Delete
$prefix = substr( $js_dataset_name, $was_at, $next_upper_at - $was_at );
[3967] Fix | Delete
$html_name .= strtolower( $prefix );
[3968] Fix | Delete
$html_name .= '-' . strtolower( $js_dataset_name[ $next_upper_at ] );
[3969] Fix | Delete
$at = $next_upper_at + 1;
[3970] Fix | Delete
$was_at = $at;
[3971] Fix | Delete
}
[3972] Fix | Delete
[3973] Fix | Delete
if ( $was_at < $end ) {
[3974] Fix | Delete
$html_name .= strtolower( substr( $js_dataset_name, $was_at ) );
[3975] Fix | Delete
}
[3976] Fix | Delete
[3977] Fix | Delete
return $html_name;
[3978] Fix | Delete
}
[3979] Fix | Delete
[3980] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function