Skip to content

Commit a6f34d6

Browse files
committed
fix(highlight): Remove zero width space when getting text range
1 parent f94610d commit a6f34d6

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

spec/highlight-support.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,36 @@ ke The <br> World Go Round`)
327327
expect(this.getHtml()).to.equal(expectedHtml)
328328
})
329329

330+
it('limits start and end values to text range', function () {
331+
setupHighlightEnv(this, 'ab')
332+
this.highlightRange('ab', 'myId', -1, 100)
333+
const expectedHtml = this.formatHtml(
334+
`<span class="highlight-comment" data-editable="ui-unwrap" data-highlight="comment" data-word-id="myId">ab</span>`
335+
)
336+
337+
expect(this.getHtml()).to.equal(expectedHtml)
338+
})
339+
340+
it('always selects the first character if values are too small', function () {
341+
setupHighlightEnv(this, 'ab')
342+
this.highlightRange('ab', 'myId', 0, 0)
343+
const expectedHtml = this.formatHtml(
344+
`<span class="highlight-comment" data-editable="ui-unwrap" data-highlight="comment" data-word-id="myId">a</span>b`
345+
)
346+
347+
expect(this.getHtml()).to.equal(expectedHtml)
348+
})
349+
350+
it('always selects the last character if values are too large', function () {
351+
setupHighlightEnv(this, 'ab')
352+
this.highlightRange('ab', 'myId', 2, 5)
353+
const expectedHtml = this.formatHtml(
354+
`a<span class="highlight-comment" data-editable="ui-unwrap" data-highlight="comment" data-word-id="myId">b</span>`
355+
)
356+
357+
expect(this.getHtml()).to.equal(expectedHtml)
358+
})
359+
330360
it('handles a <br> tag without whitespaces', function () {
331361
setupHighlightEnv(this, 'a<br>b')
332362
this.highlightRange('b', 'myId', 1, 2)

spec/selection.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ describe('Selection', function () {
142142
})
143143
})
144144

145+
describe('getTextRange()', function () {
146+
147+
it('handles a zero width non-break space', function () {
148+
const oneWord = createElement('<div>\uFEFFfoobar\uFEFF</div>')
149+
const range = createRange()
150+
range.selectNodeContents(oneWord)
151+
const selection = new Selection(oneWord, range)
152+
expect(selection.getTextRange()).to.deep.equal({start: 0, end: 6, text: 'foobar'})
153+
})
154+
})
155+
145156
describe('custom:', function () {
146157

147158
beforeEach(function () {

src/highlight-support.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ const highlightSupport = {
4545
this.win
4646
)
4747

48-
const actualStartIndex = startIndex
49-
const actualEndIndex = endIndex
48+
// Do not let highlight exceed text range - it should also be at least 1 character long
49+
const actualStartIndex = Math.min(Math.max(startIndex, 0), blockText.length - 1)
50+
const actualEndIndex = Math.min(Math.max(endIndex, 1), blockText.length)
5051

5152
highlightText.highlightMatches(editableHost, [{
5253
startIndex: actualStartIndex,

src/util/dom.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,10 @@ export const toCharacterRange = (range, container) => {
182182
startRange.setStart(container, 0)
183183
startRange.setEnd(range.startContainer, range.startOffset)
184184

185-
const rangeText = range.toString()
185+
// Remove zero width space to make selection more accurate,
186+
// because it will be removed on component blur via extractContent.
187+
const zeroWidthNonBreakingSpace = /\uFEFF/g
188+
const rangeText = range.toString().replace(zeroWidthNonBreakingSpace, '')
186189
const start = startRange.toString().length
187190
const end = start + rangeText.length
188191

0 commit comments

Comments
 (0)