diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 75b51d4..5fd0995 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -44,6 +44,9 @@ jobs: - name: Build example run: cd examples/basic && pnpm run build + - name: Copy public + run: cp public/** examples/basic/dist + - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: diff --git a/README.md b/README.md index 909a61c..7baa795 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Html Diff -Generate HTML content with unified or side-by-side differences. +Compare HTML and generate the differences in either a unified view or a side-by-side comparison. ## Install @@ -20,15 +20,23 @@ const newHtml = `<div>hello world</div>` const diff = new HtmlDiff(oldHtml, newHtml) const unifiedContent = diff.getUnifiedContent() const sideBySideContents = diff.getSideBySideContents() + +// custom config +const diff = new HtmlDiff(oldHtml, newHtml, { + minMatchedSize: 3, + classNames: { + createText: 'cra-txt', + deleteText: 'del-txt', + createInline: 'cra-inl', + deleteInline: 'del-inl', + createBlock: 'cra-blo', + deleteBlock: 'del-blo', + }, +}) ``` ## Preview -### unified differences - - - -### side-by-side differences - - +[See online demo...](https://arman19941113.github.io/html-diff/) + diff --git a/doc/sidebyside.png b/doc/sidebyside.png deleted file mode 100644 index af5c77f..0000000 Binary files a/doc/sidebyside.png and /dev/null differ diff --git a/doc/unified.png b/doc/unified.png deleted file mode 100644 index 268164e..0000000 Binary files a/doc/unified.png and /dev/null differ diff --git a/packages/html-diff/src/dress-up.ts b/packages/html-diff/src/dress-up.ts deleted file mode 100644 index 500a0aa..0000000 --- a/packages/html-diff/src/dress-up.ts +++ /dev/null @@ -1,65 +0,0 @@ -type Operation = 'delete' | 'create' - -export const htmlTagReg = /^<[^>]+>/ -export const htmlImgTagReg = /^<img[^>]*>$/ -export const htmlVideoTagReg = /^<video[^>]*>.*?<\/video>$/ms - -export const createTextClass = 'html-diff-create-text-wrapper' -export const deleteTextClass = 'html-diff-delete-text-wrapper' -export const createBlockClass = 'html-diff-create-block-wrapper' -export const deleteBlockClass = 'html-diff-delete-block-wrapper' -export const createInlineClass = 'html-diff-create-inline-wrapper' -export const deleteInlineClass = 'html-diff-delete-inline-wrapper' - -export function dressUpDiffContent(type: Operation, words: string[]): string { - const wordsLength = words.length - if (!wordsLength) { - return '' - } - - let result = '' - let textStartIndex = 0 - for (let i = 0; i < wordsLength; i++) { - const word = words[i] - // this word is html tag - if (word.match(htmlTagReg)) { - // deal text words before - if (i > textStartIndex) { - result += dressUpText(type, words.slice(textStartIndex, i)) - } - // deal this tag - textStartIndex = i + 1 - if (word.match(htmlVideoTagReg)) { - result += dressUpBlockTag(type, word) - } else if ([htmlImgTagReg].some(item => word.match(item))) { - result += dressUpInlineTag(type, word) - } else { - result += word - } - } - } - if (textStartIndex < wordsLength) { - result += dressUpText(type, words.slice(textStartIndex)) - } - return result -} - -function dressUpText(type: Operation, words: string[]): string { - const text = words.join('') - if (!text.trim()) return '' - if (type === 'create') return `<span class="${createTextClass}">${text}</span>` - if (type === 'delete') return `<span class="${deleteTextClass}">${text}</span>` - return '' -} - -function dressUpInlineTag(type: Operation, word: string): string { - if (type === 'create') return `<span class="${createInlineClass}">${word}</span>` - if (type === 'delete') return `<span class="${deleteInlineClass}">${word}</span>` - return '' -} - -function dressUpBlockTag(type: Operation, word: string): string { - if (type === 'create') return `<div class="${createBlockClass}">${word}</div>` - if (type === 'delete') return `<div class="${deleteBlockClass}">${word}</div>` - return '' -} diff --git a/packages/html-diff/src/index.ts b/packages/html-diff/src/index.ts index 33d25d2..91c9067 100644 --- a/packages/html-diff/src/index.ts +++ b/packages/html-diff/src/index.ts @@ -1,4 +1,4 @@ -export interface MatchedBlock { +interface MatchedBlock { oldStart: number oldEnd: number newStart: number @@ -6,7 +6,7 @@ export interface MatchedBlock { size: number } -export interface Operation { +interface Operation { oldStart: number oldEnd: number newStart: number @@ -14,29 +14,78 @@ export interface Operation { type: 'equal' | 'delete' | 'create' | 'replace' } -import { - dressUpDiffContent, - htmlImgTagReg, - htmlTagReg, - htmlVideoTagReg, -} from './dress-up' +type BaseOpType = 'delete' | 'create' + +interface HtmlDiffConfig { + minMatchedSize: number + classNames: { + createText: string + deleteText: string + createInline: string + deleteInline: string + createBlock: string + deleteBlock: string + } +} + +export interface HtmlDiffOptions { + minMatchedSize?: number + classNames?: Partial<{ + createText?: string + deleteText?: string + createInline?: string + deleteInline?: string + createBlock?: string + deleteBlock?: string + }> +} const htmlStartTagReg = /^<(?<name>[^\s/>]+)[^>]*>$/ const htmlTagWithNameReg = /^<(?<isEnd>\/)?(?<name>[^\s>]+)[^>]*>$/ +const htmlTagReg = /^<[^>]+>/ +const htmlImgTagReg = /^<img[^>]*>$/ +const htmlVideoTagReg = /^<video[^>]*>.*?<\/video>$/ms + export default class HtmlDiff { - minMatchedSize: number + readonly config: HtmlDiffConfig readonly oldWords: string[] = [] readonly newWords: string[] = [] readonly matchedBlockList: MatchedBlock[] = [] readonly operationList: Operation[] = [] - unifiedContent?: string - sideBySideContents?: string[] + sideBySideContents?: [string, string] - constructor(oldHtml: string, newHtml: string, minMatchedSize = 2) { - this.minMatchedSize = minMatchedSize + constructor( + oldHtml: string, + newHtml: string, + { + minMatchedSize = 2, + classNames = { + createText: 'html-diff-create-text-wrapper', + deleteText: 'html-diff-delete-text-wrapper', + createInline: 'html-diff-create-inline-wrapper', + deleteInline: 'html-diff-delete-inline-wrapper', + createBlock: 'html-diff-create-block-wrapper', + deleteBlock: 'html-diff-delete-block-wrapper', + }, + }: HtmlDiffOptions = {}, + ) { + // init config + this.config = { + minMatchedSize, + classNames: { + createText: 'html-diff-create-text-wrapper', + deleteText: 'html-diff-delete-text-wrapper', + createInline: 'html-diff-create-inline-wrapper', + deleteInline: 'html-diff-delete-inline-wrapper', + createBlock: 'html-diff-create-block-wrapper', + deleteBlock: 'html-diff-delete-block-wrapper', + ...classNames, + }, + } + // no need to diff if (oldHtml === newHtml) { this.unifiedContent = oldHtml this.sideBySideContents = [oldHtml, newHtml] @@ -66,13 +115,13 @@ export default class HtmlDiff { } break case 'delete': - result += dressUpDiffContent( + result += this.dressUpDiffContent( 'delete', this.oldWords.slice(operation.oldStart, operation.oldEnd), ) break case 'create': - result += dressUpDiffContent( + result += this.dressUpDiffContent( 'create', this.newWords.slice(operation.newStart, operation.newEnd), ) @@ -119,7 +168,7 @@ export default class HtmlDiff { } // deal normal tag - result += dressUpDiffContent('delete', deleteOfWords) + result += this.dressUpDiffContent('delete', deleteOfWords) deleteOfWords.splice(0) let isTagInNewFind = false for ( @@ -136,7 +185,7 @@ export default class HtmlDiff { ) { // find first matched tag, but not maybe the expected tag(to optimize) isTagInNewFind = true - result += dressUpDiffContent('create', createOfWords) + result += this.dressUpDiffContent('create', createOfWords) result += createWord createOfWords.splice(0) createIndex = tempCreateIndex + 1 @@ -157,8 +206,8 @@ export default class HtmlDiff { if (createIndex < operation.newEnd) { createOfWords.push(...this.newWords.slice(createIndex, operation.newEnd)) } - result += dressUpDiffContent('delete', deleteOfWords) - result += dressUpDiffContent('create', createOfWords) + result += this.dressUpDiffContent('delete', deleteOfWords) + result += this.dressUpDiffContent('create', createOfWords) break default: const exhaustiveCheck: never = operation.type @@ -198,23 +247,23 @@ export default class HtmlDiff { break case 'delete': const deleteWords = this.oldWords.slice(operation.oldStart, operation.oldEnd) - oldHtml += dressUpDiffContent('delete', deleteWords) + oldHtml += this.dressUpDiffContent('delete', deleteWords) break case 'create': const createWords = this.newWords.slice(operation.newStart, operation.newEnd) - newHtml += dressUpDiffContent('create', createWords) + newHtml += this.dressUpDiffContent('create', createWords) break case 'replace': const deleteOfReplaceWords = this.oldWords.slice( operation.oldStart, operation.oldEnd, ) - oldHtml += dressUpDiffContent('delete', deleteOfReplaceWords) + oldHtml += this.dressUpDiffContent('delete', deleteOfReplaceWords) const createOfReplaceWords = this.newWords.slice( operation.newStart, operation.newEnd, ) - newHtml += dressUpDiffContent('create', createOfReplaceWords) + newHtml += this.dressUpDiffContent('create', createOfReplaceWords) break default: const exhaustiveCheck: never = operation.type @@ -222,7 +271,7 @@ export default class HtmlDiff { } }) - const result = [oldHtml, newHtml] + const result: [string, string] = [oldHtml, newHtml] this.sideBySideContents = result return result } @@ -325,7 +374,7 @@ export default class HtmlDiff { } } - return maxSize >= this.minMatchedSize ? bestMatchedBlock : null + return maxSize >= this.config.minMatchedSize ? bestMatchedBlock : null } // use matchedBlockList walk the words to find change description @@ -380,4 +429,63 @@ export default class HtmlDiff { } return operationList } + + private dressUpDiffContent(type: BaseOpType, words: string[]): string { + const wordsLength = words.length + if (!wordsLength) { + return '' + } + + let result = '' + let textStartIndex = 0 + for (let i = 0; i < wordsLength; i++) { + const word = words[i] + // this word is html tag + if (word.match(htmlTagReg)) { + // deal text words before + if (i > textStartIndex) { + result += this.dressUpText(type, words.slice(textStartIndex, i)) + } + // deal this tag + textStartIndex = i + 1 + if (word.match(htmlVideoTagReg)) { + result += this.dressUpBlockTag(type, word) + } else if ([htmlImgTagReg].some(item => word.match(item))) { + result += this.dressUpInlineTag(type, word) + } else { + result += word + } + } + } + if (textStartIndex < wordsLength) { + result += this.dressUpText(type, words.slice(textStartIndex)) + } + return result + } + + private dressUpText(type: BaseOpType, words: string[]): string { + const text = words.join('') + if (!text.trim()) return '' + if (type === 'create') + return `<span class="${this.config.classNames.createText}">${text}</span>` + if (type === 'delete') + return `<span class="${this.config.classNames.deleteText}">${text}</span>` + return '' + } + + private dressUpInlineTag(type: BaseOpType, word: string): string { + if (type === 'create') + return `<span class="${this.config.classNames.createInline}">${word}</span>` + if (type === 'delete') + return `<span class="${this.config.classNames.deleteInline}">${word}</span>` + return '' + } + + private dressUpBlockTag(type: BaseOpType, word: string): string { + if (type === 'create') + return `<div class="${this.config.classNames.createBlock}">${word}</div>` + if (type === 'delete') + return `<div class="${this.config.classNames.deleteBlock}">${word}</div>` + return '' + } } diff --git a/packages/html-diff/tests/__snapshots__/index.spec.ts.snap b/packages/html-diff/tests/__snapshots__/index.spec.ts.snap index 483457a..c2433c7 100644 --- a/packages/html-diff/tests/__snapshots__/index.spec.ts.snap +++ b/packages/html-diff/tests/__snapshots__/index.spec.ts.snap @@ -10,31 +10,31 @@ exports[`HtmlDiff > should work sample 1 2`] = ` `; exports[`HtmlDiff > should work sample 2 1`] = ` -"<h1><span class="html-diff-delete-text-wrapper">Hello</span><span class="html-diff-create-text-wrapper">Hello World</span></h1><h2><span class="html-diff-delete-text-wrapper">Let life be beautiful like summer flower and death like autumn leaves.</span></h2><p>She could fade and wither<span class="html-diff-delete-text-wrapper">- I didn't care</span>. I would still go mad with tenderness at the mere sight of her face.</p> -<p>她可以褪色,可以枯萎<span class="html-diff-delete-text-wrapper">,怎样都可以</span>。但只要我看她一眼,万般柔情便涌上<span class="html-diff-create-text-wrapper">了我的</span>心头。</p> -<p><span class="html-diff-delete-text-wrapper">夜已深 我心思思 你的丰姿</span><span class="html-diff-create-text-wrapper">让我靠着你的臂胳</span></p> -<p><span class="html-diff-delete-text-wrapper">只想你便是 我的天使</span><span class="html-diff-create-text-wrapper">流露我热爱心底说话</span></p> -<p><span class="html-diff-delete-text-wrapper">未见半秒 便控制不了</span><span class="html-diff-create-text-wrapper">孕育美丽温馨爱意</span></p> -<p><span class="html-diff-delete-text-wrapper">难以心安 于今晚</span><span class="html-diff-create-text-wrapper">做梦 都是你</span></p><span class="html-diff-delete-inline-wrapper"><img src="./dog.jpg" alt="dog"></span><span class="html-diff-create-inline-wrapper"><img src="./cat.jpg" alt="cat"></span><h2>Try video</h2> -<div class="html-diff-delete-block-wrapper"><video style="width: 100%;" controls><source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div><h2><span class="html-diff-create-text-wrapper">Set the bird's wings with gold and it will never again soar in the sky.</span></h2><div class="html-diff-create-block-wrapper"><video style="width: 100%;" controls src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>" +"<h1><span class="del-txt">Hello</span><span class="cra-txt">Hello World</span></h1><h2><span class="del-txt">Let life be beautiful like summer flower and death like autumn leaves.</span></h2><p>She could fade and wither<span class="del-txt">- I didn't care</span>. I would still go mad with tenderness at the mere sight of her face.</p> +<p>她可以褪色,可以枯萎<span class="del-txt">,怎样都可以</span>。但只要我看她一眼,万般柔情便涌上<span class="cra-txt">了我的</span>心头。</p> +<p><span class="del-txt">夜已深 我心思思 你的丰姿</span><span class="cra-txt">让我靠着你的臂胳</span></p> +<p><span class="del-txt">只想你便是 我的天使</span><span class="cra-txt">流露我热爱心底说话</span></p> +<p><span class="del-txt">未见半秒 便控制不了</span><span class="cra-txt">孕育美丽温馨爱意</span></p> +<p><span class="del-txt">难以心安 于今晚</span><span class="cra-txt">做梦 都是你</span></p><span class="del-inl"><img src="./dog.jpg" alt="dog"></span><span class="cra-inl"><img src="./cat.jpg" alt="cat"></span><h2>Try video</h2> +<div class="del-blo"><video style="width: 100%;" controls><source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div><h2><span class="cra-txt">Set the bird's wings with gold and it will never again soar in the sky.</span></h2><div class="cra-blo"><video style="width: 100%;" controls src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>" `; exports[`HtmlDiff > should work sample 2 2`] = ` [ - "<h1><span class="html-diff-delete-text-wrapper">Hello</span></h1><h2><span class="html-diff-delete-text-wrapper">Let life be beautiful like summer flower and death like autumn leaves.</span></h2><p data-seq="1">She could fade and wither<span class="html-diff-delete-text-wrapper">- I didn't care</span>. I would still go mad with tenderness at the mere sight of her face.</p> -<p data-seq="2">她可以褪色,可以枯萎<span class="html-diff-delete-text-wrapper">,怎样都可以</span>。但只要我看她一眼,万般柔情便涌上心头。</p> -<p data-seq="3"><span class="html-diff-delete-text-wrapper">夜已深 我心思思 你的丰姿</span></p> -<p data-seq="4"><span class="html-diff-delete-text-wrapper">只想你便是 我的天使</span></p> -<p data-seq="5"><span class="html-diff-delete-text-wrapper">未见半秒 便控制不了</span></p> -<p data-seq="6"><span class="html-diff-delete-text-wrapper">难以心安 于今晚</span></p><span class="html-diff-delete-inline-wrapper"><img src="./dog.jpg" alt="dog"></span><h2 data-seq="7">Try video</h2> -<div class="html-diff-delete-block-wrapper"><video style="width: 100%;" controls><source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>", - "<h1><span class="html-diff-create-text-wrapper">Hello World</span></h1><p data-seq="1">She could fade and wither. I would still go mad with tenderness at the mere sight of her face.</p> -<p data-seq="2">她可以褪色,可以枯萎。但只要我看她一眼,万般柔情便涌上<span class="html-diff-create-text-wrapper">了我的</span>心头。</p> -<p data-seq="3"><span class="html-diff-create-text-wrapper">让我靠着你的臂胳</span></p> -<p data-seq="4"><span class="html-diff-create-text-wrapper">流露我热爱心底说话</span></p> -<p data-seq="5"><span class="html-diff-create-text-wrapper">孕育美丽温馨爱意</span></p> -<p data-seq="6"><span class="html-diff-create-text-wrapper">做梦 都是你</span></p><span class="html-diff-create-inline-wrapper"><img src="./cat.jpg" alt="cat"></span><h2 data-seq="7">Try video</h2> -<h2><span class="html-diff-create-text-wrapper">Set the bird's wings with gold and it will never again soar in the sky.</span></h2><div class="html-diff-create-block-wrapper"><video style="width: 100%;" controls src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>", + "<h1><span class="del-txt">Hello</span></h1><h2><span class="del-txt">Let life be beautiful like summer flower and death like autumn leaves.</span></h2><p data-seq="1">She could fade and wither<span class="del-txt">- I didn't care</span>. I would still go mad with tenderness at the mere sight of her face.</p> +<p data-seq="2">她可以褪色,可以枯萎<span class="del-txt">,怎样都可以</span>。但只要我看她一眼,万般柔情便涌上心头。</p> +<p data-seq="3"><span class="del-txt">夜已深 我心思思 你的丰姿</span></p> +<p data-seq="4"><span class="del-txt">只想你便是 我的天使</span></p> +<p data-seq="5"><span class="del-txt">未见半秒 便控制不了</span></p> +<p data-seq="6"><span class="del-txt">难以心安 于今晚</span></p><span class="del-inl"><img src="./dog.jpg" alt="dog"></span><h2 data-seq="7">Try video</h2> +<div class="del-blo"><video style="width: 100%;" controls><source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>", + "<h1><span class="cra-txt">Hello World</span></h1><p data-seq="1">She could fade and wither. I would still go mad with tenderness at the mere sight of her face.</p> +<p data-seq="2">她可以褪色,可以枯萎。但只要我看她一眼,万般柔情便涌上<span class="cra-txt">了我的</span>心头。</p> +<p data-seq="3"><span class="cra-txt">让我靠着你的臂胳</span></p> +<p data-seq="4"><span class="cra-txt">流露我热爱心底说话</span></p> +<p data-seq="5"><span class="cra-txt">孕育美丽温馨爱意</span></p> +<p data-seq="6"><span class="cra-txt">做梦 都是你</span></p><span class="cra-inl"><img src="./cat.jpg" alt="cat"></span><h2 data-seq="7">Try video</h2> +<h2><span class="cra-txt">Set the bird's wings with gold and it will never again soar in the sky.</span></h2><div class="cra-blo"><video style="width: 100%;" controls src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video></div>", ] `; @@ -42,9 +42,9 @@ exports[`HtmlDiff > should work sample 3 1`] = ` "<h1>hello world</h1> <p>勤字功夫,第一贵早起,第二贵有恒。</p> <p>流水不争先,争的是滔滔不绝</p> -<p><span class="html-diff-delete-text-wrapper">即便再</span>痛苦,<span class="html-diff-delete-text-wrapper">也不</span>要选择放弃!</p> -<p>不相信自己的人,<span class="html-diff-delete-text-wrapper">连</span><span class="html-diff-create-text-wrapper">也有</span>努力的价值<span class="html-diff-delete-text-wrapper">都没有</span>!</p> -<p><span class="html-diff-delete-text-wrapper">今天和明天已经由昨天决定,你还可以决定后天。</span><span class="html-diff-create-text-wrapper">无休止的欲望像个黑洞,浸染了我们原本澄澈而简单的心</span></p> +<p><span class="del-txt">即便再</span>痛苦,<span class="del-txt">也不</span>要选择放弃!</p> +<p>不相信自己的人,<span class="del-txt">连</span><span class="cra-txt">也有</span>努力的价值<span class="del-txt">都没有</span>!</p> +<p><span class="del-txt">今天和明天已经由昨天决定,你还可以决定后天。</span><span class="cra-txt">无休止的欲望像个黑洞,浸染了我们原本澄澈而简单的心</span></p> <p>只有当你离开自己的舒适区时,你才会挑战自己的极限。</p> <p>一本有价值的书就是一盏智慧之灯,总有人不断从中提取光明。</p>" `; @@ -54,17 +54,17 @@ exports[`HtmlDiff > should work sample 3 2`] = ` "<h1 data-seq="1">hello world</h1> <p data-seq="2">勤字功夫,第一贵早起,第二贵有恒。</p> <p data-seq="3">流水不争先,争的是滔滔不绝</p> -<p data-seq="4"><span class="html-diff-delete-text-wrapper">即便再</span>痛苦,<span class="html-diff-delete-text-wrapper">也不</span>要选择放弃!</p> -<p data-seq="5">不相信自己的人,<span class="html-diff-delete-text-wrapper">连</span>努力的价值<span class="html-diff-delete-text-wrapper">都没有</span>!</p> -<p data-seq="6"><span class="html-diff-delete-text-wrapper">今天和明天已经由昨天决定,你还可以决定后天。</span></p> +<p data-seq="4"><span class="del-txt">即便再</span>痛苦,<span class="del-txt">也不</span>要选择放弃!</p> +<p data-seq="5">不相信自己的人,<span class="del-txt">连</span>努力的价值<span class="del-txt">都没有</span>!</p> +<p data-seq="6"><span class="del-txt">今天和明天已经由昨天决定,你还可以决定后天。</span></p> <p data-seq="7">只有当你离开自己的舒适区时,你才会挑战自己的极限。</p> <p data-seq="8">一本有价值的书就是一盏智慧之灯,总有人不断从中提取光明。</p>", "<h1 data-seq="1">hello world</h1> <p data-seq="2">勤字功夫,第一贵早起,第二贵有恒。</p> <p data-seq="3">流水不争先,争的是滔滔不绝</p> <p data-seq="4">痛苦,要选择放弃!</p> -<p data-seq="5">不相信自己的人,<span class="html-diff-create-text-wrapper">也有</span>努力的价值!</p> -<p data-seq="6"><span class="html-diff-create-text-wrapper">无休止的欲望像个黑洞,浸染了我们原本澄澈而简单的心</span></p> +<p data-seq="5">不相信自己的人,<span class="cra-txt">也有</span>努力的价值!</p> +<p data-seq="6"><span class="cra-txt">无休止的欲望像个黑洞,浸染了我们原本澄澈而简单的心</span></p> <p data-seq="7">只有当你离开自己的舒适区时,你才会挑战自己的极限。</p> <p data-seq="8">一本有价值的书就是一盏智慧之灯,总有人不断从中提取光明。</p>", ] diff --git a/packages/html-diff/tests/index.spec.ts b/packages/html-diff/tests/index.spec.ts index d7cc127..8a2040a 100644 --- a/packages/html-diff/tests/index.spec.ts +++ b/packages/html-diff/tests/index.spec.ts @@ -55,7 +55,17 @@ describe('HtmlDiff', () => { <h2>Set the bird's wings with gold and it will never again soar in the sky.</h2> <video style="width: 100%;" controls src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"></video>` - const diff = new HtmlDiff(oldHtml, newHtml, 3) + const diff = new HtmlDiff(oldHtml, newHtml, { + minMatchedSize: 3, + classNames: { + createText: 'cra-txt', + deleteText: 'del-txt', + createInline: 'cra-inl', + deleteInline: 'del-inl', + createBlock: 'cra-blo', + deleteBlock: 'del-blo', + }, + }) expect(diff.getUnifiedContent()).toMatchSnapshot() expect(diff.getSideBySideContents()).toMatchSnapshot() }) @@ -78,7 +88,16 @@ describe('HtmlDiff', () => { <p>只有当你离开自己的舒适区时,你才会挑战自己的极限。</p> <p>一本有价值的书就是一盏智慧之灯,总有人不断从中提取光明。</p>` - const diff = new HtmlDiff(oldHtml, newHtml) + const diff = new HtmlDiff(oldHtml, newHtml, { + classNames: { + createText: 'cra-txt', + deleteText: 'del-txt', + createInline: 'cra-inl', + deleteInline: 'del-inl', + createBlock: 'cra-blo', + deleteBlock: 'del-blo', + }, + }) expect(diff.getUnifiedContent()).toMatchSnapshot() expect(diff.getSideBySideContents()).toMatchSnapshot() }) diff --git a/public/demo.png b/public/demo.png new file mode 100644 index 0000000..ab006ac Binary files /dev/null and b/public/demo.png differ