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-
145export 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