diff --git a/lib/tests/weblib_test.php b/lib/tests/weblib_test.php index 1cdd34b6db0..ab5f019c970 100644 --- a/lib/tests/weblib_test.php +++ b/lib/tests/weblib_test.php @@ -117,15 +117,41 @@ class core_weblib_testcase extends advanced_testcase { } public function test_highlight() { - $this->assertSame('This is good', highlight('good', 'This is good')); - $this->assertSame('span', highlight('SpaN', 'span')); - $this->assertSame('SpaN', highlight('span', 'SpaN')); - $this->assertSame('span', highlight('span', 'span')); - $this->assertSame('He is good', highlight('good is', 'He is good')); - $this->assertSame('This is good', highlight('+good', 'This is good')); - $this->assertSame('This is good', highlight('-good', 'This is good')); - $this->assertSame('This is goodness', highlight('+good', 'This is goodness')); - $this->assertSame('This is goodness', highlight('good', 'This is goodness')); + $this->assertSame('This is good', + highlight('good', 'This is good')); + + $this->assertSame('span', + highlight('SpaN', 'span')); + + $this->assertSame('SpaN', + highlight('span', 'SpaN')); + + $this->assertSame('span', + highlight('span', 'span')); + + $this->assertSame('He is good', + highlight('good is', 'He is good')); + + $this->assertSame('This is good', + highlight('+good', 'This is good')); + + $this->assertSame('This is good', + highlight('-good', 'This is good')); + + $this->assertSame('This is goodness', + highlight('+good', 'This is goodness')); + + $this->assertSame('This is goodness', + highlight('good', 'This is goodness')); + + $this->assertSame('

test 1

1

', + highlight('test 1', '

test 1

1

', false, '', '')); + + $this->assertSame('

test 1

1

', + highlight('test +1', '

test 1

1

', false, '', '')); + + $this->assertSame('

test 1

1

', + highlight('test -1', '

test 1

1

', false, '', '')); } public function test_replace_ampersands() { diff --git a/lib/weblib.php b/lib/weblib.php index f2a6f153ee5..abeb2050fc3 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -1936,24 +1936,23 @@ function highlight($needle, $haystack, $matchcase = false, return $haystack; } - // Find all the HTML tags in the input, and store them in a placeholders array.. - $placeholders = array(); - $matches = array(); - preg_match_all('/<[^>]*>/', $haystack, $matches); - foreach (array_unique($matches[0]) as $key => $htmltag) { - $placeholders['<|' . $key . '|>'] = $htmltag; + // Split the string into HTML tags and real content. + $chunks = preg_split('/((?:<[^>]*>)+)/', $haystack, -1, PREG_SPLIT_DELIM_CAPTURE); + + // We have an array of alternating blocks of text, then HTML tags, then text, ... + // Loop through replacing search terms in the text, and leaving the HTML unchanged. + $ishtmlchunk = false; + $result = ''; + foreach ($chunks as $chunk) { + if ($ishtmlchunk) { + $result .= $chunk; + } else { + $result .= preg_replace($regexp, $prefix . '$1' . $suffix, $chunk); + } + $ishtmlchunk = !$ishtmlchunk; } - // In $hastack, replace each HTML tag with the corresponding placeholder. - $haystack = str_replace($placeholders, array_keys($placeholders), $haystack); - - // In the resulting string, Do the highlighting. - $haystack = preg_replace($regexp, $prefix . '$1' . $suffix, $haystack); - - // Turn the placeholders back into HTML tags. - $haystack = str_replace(array_keys($placeholders), $placeholders, $haystack); - - return $haystack; + return $result; } /**