Skip to content

Commit 72c2904

Browse files
committed
Refactor wp_replace_in_html_tags()
1 parent c33e78c commit 72c2904

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
@@ -872,52 +872,89 @@ function _get_wptexturize_shortcode_regex( $tagnames ) {
872872
/**
873873
* Replaces characters or phrases within HTML elements only.
874874
*
875+
* This is a dangerous function which can break HTML syntax,
876+
* consider using methods from the HTML API instead.
877+
*
878+
* Example:
879+
*
880+
* '<p class="test">data-class</p>' === wp_replace_in_html_tags(
881+
* '<p data-class="test">data-class</p>',
882+
* array( 'data-class' => 'class' )
883+
* );
884+
*
875885
* @since 4.2.3
886+
* @since {WP_VERSION} Reliably parses HTML via the HTML API.
876887
*
877-
* @param string $haystack The text which has to be formatted.
888+
* @param string $html Replace matches inside the tags of this HTML.
878889
* @param array $replace_pairs In the form array('from' => 'to', ...).
879-
* @return string The formatted text.
890+
* @return string HTML after replacing the `$replace_pairs` matches, but only those
891+
* matches which appear inside HTML opening and closing tags.
880892
*/
881-
function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
882-
// Find all elements.
883-
$textarr = wp_html_split( $haystack );
884-
$changed = false;
893+
function wp_replace_in_html_tags( $html, $replace_pairs ) {
894+
$token_updater = new class( $html ) extends WP_HTML_Tag_Processor {
895+
public function extract_raw_token() {
896+
$this->set_bookmark( 'here' );
897+
$here = $this->bookmarks['here'];
898+
899+
return substr( $this->html, $here->start, $here->length );
900+
}
901+
902+
public function replace_raw_token( $new_raw_html ) {
903+
$this->set_bookmark( 'here' );
904+
$here = $this->bookmarks['here'];
905+
906+
$this->lexical_updates[] = new WP_HTML_Text_Replacement(
907+
$here->start,
908+
$here->length,
909+
$new_raw_html
910+
);
911+
}
912+
};
885913

886914
// Optimize when searching for one item.
887915
if ( 1 === count( $replace_pairs ) ) {
888916
// Extract $needle and $replace.
889917
$needle = array_key_first( $replace_pairs );
890918
$replace = $replace_pairs[ $needle ];
891919

892-
// Loop through delimiters (elements) only.
893-
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
894-
if ( str_contains( $textarr[ $i ], $needle ) ) {
895-
$textarr[ $i ] = str_replace( $needle, $replace, $textarr[ $i ] );
896-
$changed = true;
920+
while ( $token_updater->next_token() ) {
921+
if ( '#text' === $token_updater->get_token_name() ) {
922+
continue;
923+
}
924+
925+
$token = $token_updater->extract_raw_token();
926+
$updated = str_replace( $needle, $replace, $token );
927+
928+
if ( $token !== $updated ) {
929+
$token_updater->replace_raw_token( $updated );
897930
}
898931
}
899932
} else {
900933
// Extract all $needles.
901934
$needles = array_keys( $replace_pairs );
902935

903-
// Loop through delimiters (elements) only.
904-
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
936+
while ( $token_updater->next_token() ) {
937+
if ( '#text' === $token_updater->get_token_name() ) {
938+
continue;
939+
}
940+
941+
$token = $token_updater->extract_raw_token();
942+
$updated = $token;
943+
905944
foreach ( $needles as $needle ) {
906-
if ( str_contains( $textarr[ $i ], $needle ) ) {
907-
$textarr[ $i ] = strtr( $textarr[ $i ], $replace_pairs );
908-
$changed = true;
909-
// After one strtr() break out of the foreach loop and look at next element.
945+
if ( str_contains( $token, $needle ) ) {
946+
$updated = strtr( $updated, $replace_pairs );
910947
break;
911948
}
912949
}
913-
}
914-
}
915950

916-
if ( $changed ) {
917-
$haystack = implode( $textarr );
951+
if ( $token !== $updated ) {
952+
$token_updater->replace_raw_token( $updated );
953+
}
954+
}
918955
}
919956

920-
return $haystack;
957+
return $token_updater->get_updated_html();
921958
}
922959

923960
/**

0 commit comments

Comments
 (0)