(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": [