Skip to content

Commit d1afb19

Browse files
committed
Fix overlapping highlighter issues
1 parent 3915fe5 commit d1afb19

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

index.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const SPLIT_CHARS = '[^a-zA-Z_]'
2121
const highlighters = [
2222
{
2323
name: 'keyword',
24-
regex: new RegExp(`(?:^|${SPLIT_CHARS})(?:${keywords.join('|')})(?=${SPLIT_CHARS}|$)`, 'g')
24+
group: 1,
25+
regex: new RegExp(`(^|${SPLIT_CHARS})(${keywords.join('|')})(?=${SPLIT_CHARS}|$)`, 'g')
2526
},
2627
{
2728
name: 'special',
@@ -54,13 +55,25 @@ function highlight (sqlString, options) {
5455
for (const hl of highlighters) {
5556
let match
5657

57-
// This is probably the one time when an assignment inside a condidion makes sense
58+
// This is probably the one time when an assignment inside a condition makes sense
5859
// eslint-disable-next-line no-cond-assign
5960
while (match = hl.regex.exec(sqlString)) {
61+
let text = match[0]
62+
let boringLength = 0
63+
64+
// If a specific group is requested, use that group instead, and make sure
65+
// we offset the index by the length of the preceding groups
66+
if (hl.group) {
67+
text = match[hl.group + 1]
68+
for (let i = 1; i <= hl.group; i++) {
69+
boringLength += match[i].length
70+
}
71+
}
72+
6073
matches.push({
6174
name: hl.name,
62-
start: match.index,
63-
length: (hl.trimEnd ? match[0].substr(0, match[0].length - hl.trimEnd) : match[0]).length
75+
start: match.index + boringLength,
76+
length: (hl.trimEnd ? text.substr(0, text.length - hl.trimEnd) : text).length
6477
})
6578
}
6679
}

index.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ describe('unicode', () => {
6767

6868
it('basic query', () => {
6969
expect(hlUni("SELECT * FROM `users` WHERE `email` = '[email protected]'"))
70-
.toBe("[keyword]SELECT[clear] [special]*[clear][keyword] FROM[clear] [string]`users`[clear][keyword] WHERE[clear] [string]`email`[clear] [special]=[clear] [string]'[email protected]'[clear]")
70+
.toBe("[keyword]SELECT[clear] [special]*[clear] [keyword]FROM[clear] [string]`users`[clear] [keyword]WHERE[clear] [string]`email`[clear] [special]=[clear] [string]'[email protected]'[clear]")
7171
})
7272

7373
it('complex query', () => {
7474
expect(hlUni("SELECT COUNT(id), `id`, `username` FROM `users` WHERE `email` = '[email protected]' AND `foo` = 'BAR' OR 1=1"))
75-
.toBe("[keyword]SELECT[clear] [function]COUNT[clear][bracket]([clear]id[bracket])[clear][special],[clear] [string]`id`[clear][special],[clear] [string]`username`[clear][keyword] FROM[clear] [string]`users`[clear][keyword] WHERE[clear] [string]`email`[clear] [special]=[clear] [string]'[email protected]'[clear][keyword] AND[clear] [string]`foo`[clear] [special]=[clear] [string]'BAR'[clear][keyword] OR[clear] [number]1[clear][special]=[clear][number]1[clear]")
75+
.toBe("[keyword]SELECT[clear] [function]COUNT[clear][bracket]([clear]id[bracket])[clear][special],[clear] [string]`id`[clear][special],[clear] [string]`username`[clear] [keyword]FROM[clear] [string]`users`[clear] [keyword]WHERE[clear] [string]`email`[clear] [special]=[clear] [string]'[email protected]'[clear] [keyword]AND[clear] [string]`foo`[clear] [special]=[clear] [string]'BAR'[clear] [keyword]OR[clear] [number]1[clear][special]=[clear][number]1[clear]")
7676
})
7777
})
7878

@@ -124,16 +124,16 @@ describe('html', () => {
124124

125125
it('basic query', () => {
126126
expect(hlHtml("SELECT * FROM `users` WHERE `email` = '[email protected]'"))
127-
.toBe("<span class=\"sql-hl-keyword\">SELECT</span> <span class=\"sql-hl-special\">*</span><span class=\"sql-hl-keyword\"> FROM</span> <span class=\"sql-hl-string\">`users`</span><span class=\"sql-hl-keyword\"> WHERE</span> <span class=\"sql-hl-string\">`email`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'[email protected]'</span>")
127+
.toBe("<span class=\"sql-hl-keyword\">SELECT</span> <span class=\"sql-hl-special\">*</span> <span class=\"sql-hl-keyword\">FROM</span> <span class=\"sql-hl-string\">`users`</span> <span class=\"sql-hl-keyword\">WHERE</span> <span class=\"sql-hl-string\">`email`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'[email protected]'</span>")
128128
})
129129

130130
it('complex query', () => {
131131
expect(hlHtml("SELECT COUNT(id), `id`, `username` FROM `users` WHERE `email` = '[email protected]' AND `foo` = 'BAR' OR 1=1"))
132-
.toBe("<span class=\"sql-hl-keyword\">SELECT</span> <span class=\"sql-hl-function\">COUNT</span><span class=\"sql-hl-bracket\">(</span>id<span class=\"sql-hl-bracket\">)</span><span class=\"sql-hl-special\">,</span> <span class=\"sql-hl-string\">`id`</span><span class=\"sql-hl-special\">,</span> <span class=\"sql-hl-string\">`username`</span><span class=\"sql-hl-keyword\"> FROM</span> <span class=\"sql-hl-string\">`users`</span><span class=\"sql-hl-keyword\"> WHERE</span> <span class=\"sql-hl-string\">`email`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'[email protected]'</span><span class=\"sql-hl-keyword\"> AND</span> <span class=\"sql-hl-string\">`foo`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'BAR'</span><span class=\"sql-hl-keyword\"> OR</span> <span class=\"sql-hl-number\">1</span><span class=\"sql-hl-special\">=</span><span class=\"sql-hl-number\">1</span>")
132+
.toBe("<span class=\"sql-hl-keyword\">SELECT</span> <span class=\"sql-hl-function\">COUNT</span><span class=\"sql-hl-bracket\">(</span>id<span class=\"sql-hl-bracket\">)</span><span class=\"sql-hl-special\">,</span> <span class=\"sql-hl-string\">`id`</span><span class=\"sql-hl-special\">,</span> <span class=\"sql-hl-string\">`username`</span> <span class=\"sql-hl-keyword\">FROM</span> <span class=\"sql-hl-string\">`users`</span> <span class=\"sql-hl-keyword\">WHERE</span> <span class=\"sql-hl-string\">`email`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'[email protected]'</span> <span class=\"sql-hl-keyword\">AND</span> <span class=\"sql-hl-string\">`foo`</span> <span class=\"sql-hl-special\">=</span> <span class=\"sql-hl-string\">'BAR'</span> <span class=\"sql-hl-keyword\">OR</span> <span class=\"sql-hl-number\">1</span><span class=\"sql-hl-special\">=</span><span class=\"sql-hl-number\">1</span>")
133133
})
134134

135135
it('query with identifiers without apostrophes', () => {
136136
expect(hlHtml('SELECT id FROM users'))
137-
.toBe('<span class="sql-hl-keyword">SELECT</span> id<span class="sql-hl-keyword"> FROM</span> users')
137+
.toBe('<span class="sql-hl-keyword">SELECT</span> id <span class="sql-hl-keyword">FROM</span> users')
138138
})
139139
})

0 commit comments

Comments
 (0)