diff --git a/wp-includes/class-wp-embed.php b/wp-includes/class-wp-embed.php index 6e583b6b24..26c8ee6e08 100644 --- a/wp-includes/class-wp-embed.php +++ b/wp-includes/class-wp-embed.php @@ -312,11 +312,14 @@ class WP_Embed { * @return string Potentially modified $content. */ public function autoembed( $content ) { - // Strip newlines from all elements. - $content = wp_replace_in_html_tags( $content, array( "\n" => " " ) ); + // Replace line breaks from all HTML elements with placeholders. + $content = wp_replace_in_html_tags( $content, array( "\n" => '' ) ); // Find URLs that are on their own line. - return preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array( $this, 'autoembed_callback' ), $content ); + $content = preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array( $this, 'autoembed_callback' ), $content ); + + // Put the line breaks back. + return str_replace( '', "\n", $content ); } /** diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index f54b4e7785..5c9973f62a 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -410,8 +410,8 @@ function wpautop($pee, $br = true) { $pee = preg_replace('!()!', "$1\n\n", $pee); $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines - // Strip newlines from all elements. - $pee = wp_replace_in_html_tags( $pee, array( "\n" => " " ) ); + // Find newlines in all elements and add placeholders. + $pee = wp_replace_in_html_tags( $pee, array( "\n" => " " ) ); if ( strpos( $pee, ' ", "\n", $pee ); + return $pee; } +/** + * Separate HTML elements and comments from the text. + * + * @since 4.2.4 + * + * @param string $input The text which has to be formatted. + * @return array The formatted text. + */ +function wp_html_split( $input ) { + static $regex; + + if ( ! isset( $regex ) ) { + $comments = + '!' // Start of comment, after the <. + . '(?:' // Unroll the loop: Consume everything until --> is found. + . '-(?!->)' // Dash not followed by end of comment. + . '[^\-]*+' // Consume non-dashes. + . ')*+' // Loop possessively. + . '(?:-->)?'; // End of comment. If not found, match all input. + + $cdata = + '!\[CDATA\[' // Start of comment, after the <. + . '[^\]]*+' // Consume non-]. + . '(?:' // Unroll the loop: Consume everything until ]]> is found. + . '](?!]>)' // One ] not followed by end of comment. + . '[^\]]*+' // Consume non-]. + . ')*+' // Loop possessively. + . '(?:]]>)?'; // End of comment. If not found, match all input. + + $regex = + '/(' // Capture the entire match. + . '<' // Find start of element. + . '(?(?=!--)' // Is this a comment? + . $comments // Find end of comment. + . '|' + . '(?(?=!\[CDATA\[)' // Is this a comment? + . $cdata // Find end of comment. + . '|' + . '[^>]*>?' // Find end of element. If not found, match all input. + . ')' + . ')' + . ')/s'; + } + + return preg_split( $regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE ); +} + /** * Replace characters or phrases within HTML elements only. * @@ -478,25 +528,7 @@ function wpautop($pee, $br = true) { */ function wp_replace_in_html_tags( $haystack, $replace_pairs ) { // Find all elements. - $comments = - '!' // Start of comment, after the <. - . '(?:' // Unroll the loop: Consume everything until --> is found. - . '-(?!->)' // Dash not followed by end of comment. - . '[^\-]*+' // Consume non-dashes. - . ')*+' // Loop possessively. - . '(?:-->)?'; // End of comment. If not found, match all input. - - $regex = - '/(' // Capture the entire match. - . '<' // Find start of element. - . '(?(?=!--)' // Is this a comment? - . $comments // Find end of comment. - . '|' - . '[^>]*>?' // Find end of element. If not found, match all input. - . ')' - . ')/s'; - - $textarr = preg_split( $regex, $haystack, -1, PREG_SPLIT_DELIM_CAPTURE ); + $textarr = wp_html_split( $haystack ); $changed = false; // Optimize when searching for one item. diff --git a/wp-includes/shortcodes.php b/wp-includes/shortcodes.php index 42c6e16b40..f3bcaadd5f 100644 --- a/wp-includes/shortcodes.php +++ b/wp-includes/shortcodes.php @@ -325,29 +325,10 @@ function do_shortcodes_in_html_tags( $content, $ignore_html ) { $trans = array( '[' => '[', ']' => ']' ); $pattern = get_shortcode_regex(); - - $comment_regex = - '!' // Start of comment, after the <. - . '(?:' // Unroll the loop: Consume everything until --> is found. - . '-(?!->)' // Dash not followed by end of comment. - . '[^\-]*+' // Consume non-dashes. - . ')*+' // Loop possessively. - . '(?:-->)?'; // End of comment. If not found, match all input. - - $regex = - '/(' // Capture the entire match. - . '<' // Find start of element. - . '(?(?=!--)' // Is this a comment? - . $comment_regex // Find end of comment. - . '|' - . '[^>]*>?' // Find end of element. If not found, match all input. - . ')' - . ')/s'; - - $textarr = preg_split( $regex, $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); + $textarr = wp_html_split( $content ); foreach ( $textarr as &$element ) { - if ( '<' !== $element[0] ) { + if ( '' == $element || '<' !== $element[0] ) { continue; } @@ -362,7 +343,7 @@ function do_shortcodes_in_html_tags( $content, $ignore_html ) { continue; } - if ( $ignore_html || '