Skip to content

Commit bdfa35e

Browse files
committed
Refactor wp_replace_in_html_tags()
1 parent 085390b commit bdfa35e

File tree

1 file changed

+59
-22
lines changed

1 file changed

+59
-22
lines changed

src/wp-includes/formatting.php

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -849,52 +849,89 @@ function _get_wptexturize_shortcode_regex( $tagnames ) {
849849
/**
850850
* Replaces characters or phrases within HTML elements only.
851851
*
852+
* This is a dangerous function which can break HTML syntax,
853+
* consider using methods from the HTML API instead.
854+
*
855+
* Example:
856+
*
857+
* '<p class="test">data-class</p>' === wp_replace_in_html_tags(
858+
* '<p data-class="test">data-class</p>',
859+
* array( 'data-class' => 'class' )
860+
* );
861+
*
852862
* @since 4.2.3
863+
* @since {WP_VERSION} Reliably parses HTML via the HTML API.
853864
*
854-
* @param string $haystack The text which has to be formatted.
865+
* @param string $html Replace matches inside the tags of this HTML.
855866
* @param array $replace_pairs In the form array('from' => 'to', ...).
856-
* @return string The formatted text.
867+
* @return string HTML after replacing the `$replace_pairs` matches, but only those
868+
* matches which appear inside HTML opening and closing tags.
857869
*/
858-
function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
859-
// Find all elements.
860-
$textarr = wp_html_split( $haystack );
861-
$changed = false;
870+
function wp_replace_in_html_tags( $html, $replace_pairs ) {
871+
$token_updater = new class( $html ) extends WP_HTML_Tag_Processor {
872+
public function extract_raw_token() {
873+
$this->set_bookmark( 'here' );
874+
$here = $this->bookmarks['here'];
875+
876+
return substr( $this->html, $here->start, $here->length );
877+
}
878+
879+
public function replace_raw_token( $new_raw_html ) {
880+
$this->set_bookmark( 'here' );
881+
$here = $this->bookmarks['here'];
882+
883+
$this->lexical_updates[] = new WP_HTML_Text_Replacement(
884+
$here->start,
885+
$here->length,
886+
$new_raw_html
887+
);
888+
}
889+
};
862890

863891
// Optimize when searching for one item.
864892
if ( 1 === count( $replace_pairs ) ) {
865893
// Extract $needle and $replace.
866894
$needle = array_key_first( $replace_pairs );
867895
$replace = $replace_pairs[ $needle ];
868896

869-
// Loop through delimiters (elements) only.
870-
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
871-
if ( str_contains( $textarr[ $i ], $needle ) ) {
872-
$textarr[ $i ] = str_replace( $needle, $replace, $textarr[ $i ] );
873-
$changed = true;
897+
while ( $token_updater->next_token() ) {
898+
if ( '#text' === $token_updater->get_token_name() ) {
899+
continue;
900+
}
901+
902+
$token = $token_updater->extract_raw_token();
903+
$updated = str_replace( $needle, $replace, $token );
904+
905+
if ( $token !== $updated ) {
906+
$token_updater->replace_raw_token( $updated );
874907
}
875908
}
876909
} else {
877910
// Extract all $needles.
878911
$needles = array_keys( $replace_pairs );
879912

880-
// Loop through delimiters (elements) only.
881-
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
913+
while ( $token_updater->next_token() ) {
914+
if ( '#text' === $token_updater->get_token_name() ) {
915+
continue;
916+
}
917+
918+
$token = $token_updater->extract_raw_token();
919+
$updated = $token;
920+
882921
foreach ( $needles as $needle ) {
883-
if ( str_contains( $textarr[ $i ], $needle ) ) {
884-
$textarr[ $i ] = strtr( $textarr[ $i ], $replace_pairs );
885-
$changed = true;
886-
// After one strtr() break out of the foreach loop and look at next element.
922+
if ( str_contains( $token, $needle ) ) {
923+
$updated = strtr( $updated, $replace_pairs );
887924
break;
888925
}
889926
}
890-
}
891-
}
892927

893-
if ( $changed ) {
894-
$haystack = implode( $textarr );
928+
if ( $token !== $updated ) {
929+
$token_updater->replace_raw_token( $updated );
930+
}
931+
}
895932
}
896933

897-
return $haystack;
934+
return $token_updater->get_updated_html();
898935
}
899936

900937
/**

0 commit comments

Comments
 (0)