Skip to content

Commit f652599

Browse files
author
naort
committed
add wholeWordMatch option
1 parent 1de6bcd commit f652599

File tree

6 files changed

+81
-11
lines changed

6 files changed

+81
-11
lines changed

src/components/highlightChunks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { indicesOf, mergeRange } from '../utils';
33
export default function highlightChunks(
44
text,
55
queriesOrQuery,
6-
{ caseSensitive = false, diacriticsSensitive = false } = {},
6+
{ caseSensitive = false, diacriticsSensitive = false, wholeWordMatch = false } = {},
77
) {
88
let queries = queriesOrQuery;
99
if (typeof queriesOrQuery === 'string' || queriesOrQuery instanceof RegExp) {
@@ -19,7 +19,7 @@ export default function highlightChunks(
1919
const matches = [];
2020

2121
queries.forEach((query) => {
22-
matches.push(...indicesOf(text, query, { caseSensitive, diacriticsSensitive }));
22+
matches.push(...indicesOf(text, query, { caseSensitive, diacriticsSensitive, wholeWordMatch }));
2323
});
2424

2525
const highlights = mergeRange(matches);

src/components/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export default {
99
queries: [Array, String, RegExp],
1010
caseSensitive: Boolean,
1111
diacriticsSensitive: Boolean,
12+
wholeWordMatch: Boolean,
1213
highlightStyle: classAndStyleTypes,
1314
highlightClass: classAndStyleTypes,
1415
highlightComponent: {
@@ -83,8 +84,9 @@ export default {
8384
queries,
8485
caseSensitive,
8586
diacriticsSensitive,
87+
wholeWordMatch,
8688
} = this;
87-
return highlightChunks(text, queries, { caseSensitive, diacriticsSensitive });
89+
return highlightChunks(text, queries, { caseSensitive, diacriticsSensitive, wholeWordMatch });
8890
},
8991
},
9092
};

src/utils/indicesOf.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import cloneRegexp from 'clone-regexp';
22
import diacritics from 'diacritics';
33

4+
5+
const isDigit = char => /^\d+$/.test(char);
6+
const isLetter = char => char.toUpperCase() !== char.toLowerCase() || char.codePointAt(0) > 127;
7+
const isLetterOrDigit = char => isLetter(char) || isDigit(char);
8+
9+
410
export default function indicesOf(
511
text,
612
searchStringOrRegex,
7-
{ caseSensitive = false, diacriticsSensitive = false } = {},
13+
{ caseSensitive = false, diacriticsSensitive = false, wholeWordMatch = false } = {},
814
) {
915
if (searchStringOrRegex instanceof RegExp) {
1016
const re = cloneRegexp(searchStringOrRegex, { global: true });
@@ -47,5 +53,18 @@ export default function indicesOf(
4753
index = strCpy.indexOf(searchStringCpy, index + 1);
4854
}
4955

56+
if (wholeWordMatch) {
57+
const strLength = strCpy.length;
58+
return indices.filter((range) => {
59+
const [start, end] = range;
60+
const idxBefore = start - 1;
61+
const idxAfter = end;
62+
const idxBeforeIsLetterOrDigit = idxBefore > 0 && isLetterOrDigit(strCpy[idxBefore]);
63+
const idxAfterIsLetterOrDigit = idxAfter < strLength && isLetterOrDigit(strCpy[idxAfter]);
64+
debugger;
65+
return !(idxAfterIsLetterOrDigit || idxBeforeIsLetterOrDigit);
66+
});
67+
}
68+
5069
return indices;
5170
}

test/unit/specs/highlightChunks.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,23 @@ describe('highlightChunks', () => {
158158
},
159159
]);
160160
});
161+
test('should match whole word not part of other word', () => {
162+
const text = 'example amp';
163+
const string = 'amp';
164+
165+
const chunks = highlightChunks(text, string, { wholeWordMatch: true });
166+
console.log(chunks);
167+
expect(chunks)
168+
.toEqual([
169+
{
170+
isHighlighted: false,
171+
text: 'example ',
172+
},
173+
{
174+
isHighlighted: true,
175+
text: 'amp',
176+
highlightIndex: 0,
177+
},
178+
]);
179+
});
161180
});

web/App.vue

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<h1>
55
<text-highlight
66
queries="highlight"
7-
highlightClass="titleHighlight">vue text highlight</text-highlight>
7+
highlightClass="titleHighlight">vue text highlight
8+
</text-highlight>
89
</h1>
910
<div class="card">
1011
<div class="inputs">
@@ -17,27 +18,40 @@
1718
<check-box
1819
:defaultValue="split"
1920
@onchange="updateSplit"
20-
class="checkBox">Split by space</check-box>
21+
class="checkBox">Split by space
22+
</check-box>
2123
</div>
2224
<div class="column">
2325
<check-box
2426
:defaultValue="custom"
2527
@onchange="updateCustom"
26-
class="checkBox">Custom component</check-box>
28+
class="checkBox">Custom component
29+
</check-box>
2730
</div>
2831
</div>
2932
<div class="row">
3033
<div class="column">
3134
<check-box
3235
:defaultValue="caseSensitive"
3336
@onchange="updateCaseSensitive"
34-
class="checkBox">Case sensitive</check-box>
37+
class="checkBox">Case sensitive
38+
</check-box>
3539
</div>
3640
<div class="column">
3741
<check-box
3842
:defaultValue="diacriticsSensitive"
3943
@onchange="updateDiacriticsSensitive"
40-
class="checkBox">Diacritics sensitive</check-box>
44+
class="checkBox">Diacritics sensitive
45+
</check-box>
46+
</div>
47+
</div>
48+
<div class="row">
49+
<div class="column">
50+
<check-box
51+
:defaultValue="wholeWordMatch"
52+
@onchange="updateWholeWordMatch"
53+
class="checkBox">Match Whole Word
54+
</check-box>
4155
</div>
4256
</div>
4357
</div>
@@ -46,7 +60,9 @@
4660
:split="split"
4761
:custom="custom"
4862
:caseSensitive="caseSensitive"
49-
:diacriticsSensitive="diacriticsSensitive"></example-document>
63+
:diacriticsSensitive="diacriticsSensitive"
64+
:wholeWordMatch="wholeWordMatch"
65+
></example-document>
5066
</div>
5167
</div>
5268
</template>
@@ -74,6 +90,7 @@ export default {
7490
custom: false,
7591
caseSensitive: false,
7692
diacriticsSensitive: false,
93+
wholeWordMatch: false,
7794
};
7895
},
7996
methods: {
@@ -92,6 +109,9 @@ export default {
92109
updateDiacriticsSensitive(val) {
93110
this.diacriticsSensitive = val;
94111
},
112+
updateWholeWordMatch(val) {
113+
this.wholeWordMatch = val;
114+
},
95115
},
96116
};
97117
</script>
@@ -101,17 +121,20 @@ body {
101121
background-color: #FAFAFA;
102122
margin: 0;
103123
}
124+
104125
#app {
105126
font-family: 'Avenir', Helvetica, Arial, sans-serif;
106127
-webkit-font-smoothing: antialiased;
107128
-moz-osx-font-smoothing: grayscale;
108129
text-align: center;
109130
color: #2c3e50;
110131
margin-top: 5%;
132+
111133
.titleHighlight {
112134
background-color: #42b983;
113135
color: #FFFFFFF0;
114136
}
137+
115138
.card {
116139
width: 500px;
117140
max-width: 100vw;
@@ -122,17 +145,20 @@ body {
122145
padding-bottom: 30px;
123146
border-radius: 5px;
124147
box-sizing: border-box;
125-
box-shadow: 0 20px 50px rgba(0,0,0,.1);
148+
box-shadow: 0 20px 50px rgba(0, 0, 0, .1);
126149
}
150+
127151
.inputs {
128152
margin-bottom: 20px;
129153
padding: 15px;
130154
border-bottom: 1px solid rgba(0, 0, 0, .1);
155+
131156
.textField {
132157
flex-grow: 1;
133158
padding-bottom: 10px;
134159
width: 100%;
135160
}
161+
136162
.row {
137163
display: flex;
138164
flex-direction: row;

web/components/ExampleDocument.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
:displayHoverMe="true"
2020
:caseSensitive="caseSensitive"
2121
:diacriticsSensitive="diacriticsSensitive"
22+
:wholeWordMatch="wholeWordMatch"
2223
>
2324
{{ textEnglish }}
2425
</text-highlight>
@@ -33,6 +34,7 @@
3334
:displayHoverMe="true"
3435
:caseSensitive="caseSensitive"
3536
:diacriticsSensitive="diacriticsSensitive"
37+
:wholeWordMatch="wholeWordMatch"
3638
>
3739
{{ textSpanish }}
3840
</text-highlight>
@@ -46,6 +48,7 @@
4648
:activeIndex="activeIndex"
4749
:caseSensitive="caseSensitive"
4850
:diacriticsSensitive="diacriticsSensitive"
51+
:wholeWordMatch="wholeWordMatch"
4952
>
5053
{{ html }}
5154
</text-highlight>
@@ -65,6 +68,7 @@ export default {
6568
custom: Boolean,
6669
caseSensitive: Boolean,
6770
diacriticsSensitive: Boolean,
71+
wholeWordMatch: Boolean,
6872
},
6973
components: {
7074
TextHighlight,

0 commit comments

Comments
 (0)