-
Notifications
You must be signed in to change notification settings - Fork 284
Expand file tree
/
Copy pathuse-code-review.ts
More file actions
109 lines (99 loc) · 3.85 KB
/
use-code-review.ts
File metadata and controls
109 lines (99 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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 { getSelectionParent, parseDiffCode } from '../utils';
export function useCodeReview(
props: CodeReviewProps,
ctx: SetupContext,
reviewContentRef: Ref<HTMLElement>,
updateLineNumberMap: (expandLineNumberInfo: IExpandLineNumberInfo, newCode: string, direction: 'up' | 'down') => void,
updateCheckedLine: (expandLineNumberInfo: IExpandLineNumberInfo, direction: 'up' | 'down') => void
) {
const { diff, outputFormat, allowExpand, showBlob } = toRefs(props);
const renderHtml = ref('');
const diffFile: Ref<DiffFile[]> = ref([]);
const ns = useNamespace('code-review');
const selectionSide = ref('');
const { insertExpandButton, onExpandButtonClick } = useCodeReviewExpand(reviewContentRef, props, updateLineNumberMap, updateCheckedLine);
const initDiffContent = () => {
diffFile.value = Diff2Html.parse(diff.value);
nextTick(() => {
if (inBrowser && !showBlob.value) {
parseDiffCode(reviewContentRef.value, diff.value, outputFormat.value, props.options);
allowExpand.value && insertExpandButton();
ctx.emit('contentRefresh', JSON.parse(JSON.stringify(diffFile.value)));
}
});
};
const onContentClick = (e: Event) => {
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 });
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 };
}