Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions packages/text-vide/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <!-- bb <div>cd</div>';
const expected = '<b>a</b>a <!-- bb <div><b>c</b>d</div>';
expect(textVide(text)).toBe(expected);
});

it('continues highlighting after an unterminated comment with multiple tags', () => {
const text = 'x <!-- unterminated <div>ab</div> yy <i>cd</i>';
const expected =
'x <!-- unterminated <div><b>a</b>b</div> <b>y</b>y <i><b>c</b>d</i>';
expect(textVide(text)).toBe(expected);
});

it('treats an unterminated comment opener like a regular tag opener', () => {
const text = 'a <!-- foo';
const expected = 'a <!-- <b>fo</b>o';
expect(textVide(text)).toBe(expected);
});

it('ignores empty angle brackets', () => {
const text = '<>';
expect(textVide(text)).toBe('<>');
});

it('complex html tags', () => {
const text = `<div class="bionic-reader-container">

Expand Down
42 changes: 38 additions & 4 deletions packages/text-vide/src/useCheckIsHtmlTag.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
import { extractMatchRangeList } from './utils';
import { MatchRange } from './utils';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fix unresolved MatchRange import

useCheckIsHtmlTag.ts now imports MatchRange from ./utils, but utils.ts does not export that symbol. This introduces a real TypeScript error (TS2305) during declaration generation (reproducible via pnpm --filter text-vide build), so any strict type-checking pipeline or downstream source type-check will fail until this type is exported or defined/imported correctly as a type.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9a91465. MatchRange is now exported from ./utils as export type MatchRange = [number, number], and extractMatchRangeList's return type is annotated to match. Verified locally: pnpm --filter text-vide build now completes declaration emit (vite-plugin-dts) without TS2305.


const HTML_TAG_REGEX = /<!--[^]*?-->|<[^>]+>/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)) {
const commentCloseIndex = text.indexOf('-->', openIndex + 4);
if (commentCloseIndex !== -1) {
htmlTagRangeList.push([openIndex, commentCloseIndex + 2]);
cursor = commentCloseIndex + 3;
continue;
}
// Unterminated `<!--`: fall through and treat the `<` as a normal
// tag opener so subsequent tags are still recognized (matches the
// behavior of the previous `/<!--[^]*?-->|<[^>]+>/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) => {
Expand Down
4 changes: 3 additions & 1 deletion packages/text-vide/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export type MatchRange = [number, number];

export const extractMatchRangeList = (
matchList: IterableIterator<RegExpMatchArray>,
) =>
): MatchRange[] =>
Array.from(matchList).map(match => {
const startIndex = match.index!;
const [matchedWord] = match;
Expand Down
Loading