From cb34fa94f7dc809dce70de4b2a9abadb7c25d834 Mon Sep 17 00:00:00 2001 From: GreatZP Date: Thu, 23 Jan 2025 15:22:06 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(code-review):=20=E5=8F=8C=E6=A0=8F?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E6=94=AF=E6=8C=81=E5=8D=8A=E8=BE=B9?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E6=96=87=E6=9C=AC=20(#1931)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(code-review): 双栏模式下支持半边选中文本 --- .../devui/code-review/src/code-review.scss | 12 ++++ .../devui/code-review/src/code-review.tsx | 5 +- .../src/composables/use-code-review.ts | 71 ++++++++++++++++++- .../devui-vue/devui/code-review/src/utils.ts | 18 +++++ packages/devui-vue/package.json | 2 +- 5 files changed, 102 insertions(+), 6 deletions(-) diff --git a/packages/devui-vue/devui/code-review/src/code-review.scss b/packages/devui-vue/devui/code-review/src/code-review.scss index ef00494816..771f383b3a 100644 --- a/packages/devui-vue/devui/code-review/src/code-review.scss +++ b/packages/devui-vue/devui/code-review/src/code-review.scss @@ -304,4 +304,16 @@ box-shadow: 0 0 1px 1px rgba(37, 43, 58, 0.16); cursor: pointer; } + + &--left-selected { + .d-code-right span { + user-select: none; + } + } + + &--right-selected { + .d-code-left span { + user-select: none; + } + } } diff --git a/packages/devui-vue/devui/code-review/src/code-review.tsx b/packages/devui-vue/devui/code-review/src/code-review.tsx index e6beb4678d..73ab7c5795 100644 --- a/packages/devui-vue/devui/code-review/src/code-review.tsx +++ b/packages/devui-vue/devui/code-review/src/code-review.tsx @@ -31,7 +31,8 @@ export default defineComponent({ updateLineNumberMap, updateCheckedLine, } = useCodeReviewComment(reviewContentRef, props, ctx); - const { renderHtml, diffFile, onContentClick } = useCodeReview(props, ctx, reviewContentRef, updateLineNumberMap, updateCheckedLine); + const { renderHtml, diffFile, selectionSide, onContentClick } = + useCodeReview(props, ctx, reviewContentRef, updateLineNumberMap, updateCheckedLine); const { isFold, toggleFold } = useCodeReviewFold(props, ctx); onMounted(() => { @@ -51,7 +52,7 @@ export default defineComponent({ }); return () => ( -
+
(isFold.value = !isFold.value)} />
{props.showBlob ? ( diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts index 5bebeac5ef..dd0b8367f3 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts @@ -1,11 +1,12 @@ -import { toRefs, ref, watch, nextTick } from 'vue'; +import { toRefs, ref, watch, nextTick, onUnmounted } from 'vue'; import type { SetupContext, Ref } from 'vue'; import type { DiffFile } from 'diff2html/lib/types'; import * as Diff2Html from 'diff2html'; +import { useNamespace } from '../../../shared/hooks/use-namespace'; import { inBrowser } from '../../../shared/utils/common-var'; import type { CodeReviewProps, IExpandLineNumberInfo } from '../code-review-types'; import { useCodeReviewExpand } from './use-code-review-expand'; -import { parseDiffCode } from '../utils'; +import { getSelectionParent, parseDiffCode } from '../utils'; export function useCodeReview( props: CodeReviewProps, @@ -17,6 +18,8 @@ export function useCodeReview( const { diff, outputFormat, allowExpand, showBlob } = toRefs(props); const renderHtml = ref(''); const diffFile: Ref = ref([]); + const ns = useNamespace('code-review'); + const selectionSide = ref(''); const { insertExpandButton, onExpandButtonClick } = useCodeReviewExpand(reviewContentRef, props, updateLineNumberMap, updateCheckedLine); const initDiffContent = () => { @@ -34,11 +37,73 @@ export function useCodeReview( onExpandButtonClick(e, props.options); }; + function onSelectionChange() { + if (selectionSide.value) { + return; + } + if (typeof window === 'undefined') { + return; + } + const selection = window.getSelection(); + if (selection?.toString() && selection?.anchorNode) { + const side = getSelectionParent(selection.anchorNode as HTMLElement); + if (side) { + selectionSide.value = side; + } + } + } + function onMousedown(e: Event) { + if (typeof window === 'undefined') { + return; + } + const selection = window.getSelection(); + const composedPath = e.composedPath(); + const isLineNumber = composedPath.some((item: HTMLElement) => item.classList?.contains('d2h-code-side-linenumber')); + const isClickInner = composedPath.some((item: HTMLElement) => item.classList?.contains(ns.e('content'))); + const clickSide = getSelectionParent(e.target as HTMLElement); + if (selection && selection.toString()) { + const isInRange = selection?.getRangeAt(0).intersectsNode(e.target); + if ( + !isInRange || + !isClickInner || + (clickSide === 'left' && selectionSide.value === 'right') || + (clickSide === 'right' && selectionSide.value === 'left') || + isLineNumber + ) { + setTimeout(() => { + selectionSide.value = ''; + selection.removeAllRanges(); + }); + } + } else { + selectionSide.value = ''; + } + } + watch(showBlob, initDiffContent); watch(outputFormat, initDiffContent); watch(diff, initDiffContent, { immediate: true }); - return { renderHtml, diffFile, onContentClick }; + watch( + () => props.outputFormat, + (val) => { + if (val === 'side-by-side') { + document.addEventListener('selectionchange', onSelectionChange); + document.addEventListener('mousedown', onMousedown, true); + } else { + document.removeEventListener('selectionchange', onSelectionChange); + document.removeEventListener('mousedown', onMousedown, true); + } + }, + { immediate: true } + ); + + onUnmounted(() => { + document.removeEventListener('selectionchange', onSelectionChange); + document.removeEventListener('mousedown', onMousedown, true); + }); + + return { renderHtml, diffFile, selectionSide, onContentClick }; } diff --git a/packages/devui-vue/devui/code-review/src/utils.ts b/packages/devui-vue/devui/code-review/src/utils.ts index d8408bf387..fa838bee4e 100644 --- a/packages/devui-vue/devui/code-review/src/utils.ts +++ b/packages/devui-vue/devui/code-review/src/utils.ts @@ -721,3 +721,21 @@ export function addCommentCheckedForSingle( return result; } + +/* 双栏模式,选中文本时,根据选择的节点查找其父节点,用于判断左侧选中还是右侧选中 */ +export function getSelectionParent(el: HTMLElement) { + if (el.tagName === 'TR') { + return; + } + if (el.tagName === 'TD' && (el.classList.contains('d-code-left') || el.classList.contains('d-code-right'))) { + if (el.classList.contains('d-code-left')) { + return 'left'; + } + if (el.classList.contains('d-code-right')) { + return 'right'; + } + } + if (el.parentElement) { + return getSelectionParent(el.parentElement); + } +} diff --git a/packages/devui-vue/package.json b/packages/devui-vue/package.json index 7c8f8ed4cb..9bfc2d75a3 100644 --- a/packages/devui-vue/package.json +++ b/packages/devui-vue/package.json @@ -1,6 +1,6 @@ { "name": "vue-devui", - "version": "1.6.30", + "version": "1.6.31", "license": "MIT", "description": "DevUI components based on Vite and Vue3", "keywords": [ From a4f57560f0d8b3ed228669c1ca23f009978b8afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=8C=E8=A8=80?= <2311595895@qq.com> Date: Tue, 25 Mar 2025 19:24:55 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(CodeReview):=20=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E5=AD=97=E5=90=8E=EF=BC=8C=E5=86=8D=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=A1=86=E6=97=B6=EF=BC=8C=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=A1=86=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96=E7=84=A6=E7=82=B9?= =?UTF-8?q?=20(#1935)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(CodeReview): 选中文字后,再点击输入框时,输入框无法获取焦点 --- .../devui/code-review/src/composables/use-code-review.ts | 2 +- packages/devui-vue/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts index dd0b8367f3..7d60ab1717 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review.ts @@ -72,8 +72,8 @@ export function useCodeReview( ) { setTimeout(() => { selectionSide.value = ''; - selection.removeAllRanges(); }); + selection.removeRange(selection.getRangeAt(0)); } } else { selectionSide.value = ''; diff --git a/packages/devui-vue/package.json b/packages/devui-vue/package.json index 9bfc2d75a3..47c9032d7a 100644 --- a/packages/devui-vue/package.json +++ b/packages/devui-vue/package.json @@ -1,6 +1,6 @@ { "name": "vue-devui", - "version": "1.6.31", + "version": "1.6.32", "license": "MIT", "description": "DevUI components based on Vite and Vue3", "keywords": [ From c2b7f84a54ea0feb1a8c52a931588e4f42d59bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=8C=E8=A8=80?= <2311595895@qq.com> Date: Tue, 25 Mar 2025 19:54:43 +0800 Subject: [PATCH 3/3] =?UTF-8?q?build:=20=E4=BF=AE=E6=94=B9=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E8=84=9A=E6=9C=AC=EF=BC=8C=E9=94=81=E5=AE=9Apnpm?= =?UTF-8?q?=E7=89=88=E6=9C=AC=20(#1937)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/auto-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-publish.yml b/.github/workflows/auto-publish.yml index 59d58e9774..7c5916a5c4 100644 --- a/.github/workflows/auto-publish.yml +++ b/.github/workflows/auto-publish.yml @@ -35,7 +35,7 @@ jobs: run: | ls node -v - npm install pnpm -g + npm install pnpm@9.15.4 -g pnpm -v pnpm install --no-frozen-lockfile pnpm run build:lib