Skip to content

Commit fa73805

Browse files
author
Dobromir Hristov
committed
refactor: update the HighlightMatches component
1 parent 29a2602 commit fa73805

File tree

1 file changed

+43
-19
lines changed

1 file changed

+43
-19
lines changed

src/components/Navigator/HighlightMatches.vue

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
<template>
2-
<span
3-
class="highlight"
4-
v-html="parsedText"
5-
/>
6-
</template>
71
<script>
82
/**
93
* Component used to mark plain text, based on a provided matcher string.
104
*/
11-
12-
import { escapeHtml } from 'docc-render/utils/strings';
13-
145
export default {
156
name: 'HighlightMatch',
167
props: {
@@ -23,16 +14,49 @@ export default {
2314
default: undefined,
2415
},
2516
},
26-
computed: {
27-
/**
28-
* Find a matching string in the text, and highlight it by wrapping with a `.match` element.
29-
* @param {string} matcher
30-
* @param {string} text
31-
* @return {string}
32-
*/
33-
parsedText: ({ matcher, text }) => (matcher
34-
? text.replace(matcher, match => `<span class="match">${escapeHtml(match)}</span>`)
35-
: escapeHtml(text)),
17+
render(createElement) {
18+
// Return a simple p no text is being highlighted
19+
const { matcher, text } = this;
20+
if (!matcher) {
21+
return createElement('p', text);
22+
}
23+
24+
const children = [];
25+
let lastIndex = 0;
26+
let match = null;
27+
28+
// Loop through each match for the highlighted text (case insensitive),
29+
// adding a span text node for the text leading up
30+
// to a match, and a `span.match` node for the actual text that
31+
// should be highlighted (case insensitive)
32+
// eslint-disable-next-line no-cond-assign
33+
while ((match = matcher.exec(text)) !== null) {
34+
const matchLength = match[0].length;
35+
36+
const nextIndex = match.index + matchLength;
37+
38+
// find text from last match upto current one
39+
const spanText = text.slice(lastIndex, match.index);
40+
if (spanText) {
41+
children.push(createElement('span', spanText));
42+
}
43+
44+
// find match text
45+
const matchText = text.slice(match.index, nextIndex);
46+
if (matchText) {
47+
children.push(createElement('span', { class: 'match' }, matchText));
48+
}
49+
50+
lastIndex = nextIndex;
51+
}
52+
// Add a normal text node for any non-highlighted text
53+
// after the last highlighted match (if any)
54+
const spanText = text.slice(lastIndex, text.length);
55+
if (spanText) {
56+
children.push(createElement('span', spanText));
57+
}
58+
59+
return createElement('p', { class: 'highlight' }, children);
3660
},
3761
};
3862
</script>

0 commit comments

Comments
 (0)