diff --git a/packages/text-vide/src/__tests__/index.test.ts b/packages/text-vide/src/__tests__/index.test.ts index ab3e68f..c5e53fb 100644 --- a/packages/text-vide/src/__tests__/index.test.ts +++ b/packages/text-vide/src/__tests__/index.test.ts @@ -321,6 +321,30 @@ describe('with html tags', () => { expect(textVide(text)).toBe(expected); }); + it('preserves tag ranges after an unterminated HTML comment opener', () => { + const text = 'aa |<[^>]+>/g; +const getHtmlTagRangeList = (text: string): MatchRange[] => { + const htmlTagRangeList: MatchRange[] = []; + let cursor = 0; + + while (cursor < text.length) { + const openIndex = text.indexOf('<', cursor); + if (openIndex === -1) { + break; + } + + if (text.startsWith('', openIndex + 4); + if (commentCloseIndex !== -1) { + htmlTagRangeList.push([openIndex, commentCloseIndex + 2]); + cursor = commentCloseIndex + 3; + continue; + } + // Unterminated `|<[^>]+>/g` regex). + } + + const closeIndex = text.indexOf('>', openIndex + 1); + if (closeIndex === -1) { + break; + } + + if (closeIndex > openIndex + 1) { + htmlTagRangeList.push([openIndex, closeIndex]); + } + + cursor = closeIndex + 1; + } + + return htmlTagRangeList; +}; export const useCheckIsHtmlTag = (text: string) => { - const htmlTagMatchList = text.matchAll(HTML_TAG_REGEX); - const htmlTagRangeList = extractMatchRangeList(htmlTagMatchList); + const htmlTagRangeList = getHtmlTagRangeList(text); const reversedHtmlTagRangeList = htmlTagRangeList.reverse(); return (match: RegExpMatchArray) => { diff --git a/packages/text-vide/src/utils.ts b/packages/text-vide/src/utils.ts index f74e9b1..1db0e6d 100644 --- a/packages/text-vide/src/utils.ts +++ b/packages/text-vide/src/utils.ts @@ -1,6 +1,8 @@ +export type MatchRange = [number, number]; + export const extractMatchRangeList = ( matchList: IterableIterator, -) => +): MatchRange[] => Array.from(matchList).map(match => { const startIndex = match.index!; const [matchedWord] = match;