ide-assi 0.333.0 → 0.334.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.cjs.js +185 -81
- package/dist/bundle.esm.js +185 -81
- package/dist/components/ideDiff.js +199 -88
- package/package.json +1 -1
- package/src/components/ideDiff.js +199 -88
package/dist/bundle.cjs.js
CHANGED
|
@@ -234751,15 +234751,49 @@ function requireDiffMatchPatch () {
|
|
|
234751
234751
|
|
|
234752
234752
|
var diffMatchPatchExports = requireDiffMatchPatch();
|
|
234753
234753
|
|
|
234754
|
-
//
|
|
234754
|
+
// Diff 데코레이션을 위한 StateField 정의 (asis 에디터용)
|
|
234755
|
+
const asisDiffDecorations = StateField.define({
|
|
234756
|
+
create() { return Decoration.none; }, // 초기 상태
|
|
234757
|
+
update(decorations, tr) {
|
|
234758
|
+
// 트랜잭션에 포함된 Effects를 처리하여 데코레이션을 업데이트
|
|
234759
|
+
// `#applyDiffDecorations` 함수에서 데코레이션 업데이트 요청을 보낼 때 사용
|
|
234760
|
+
return tr.effects.reduce((currentDecos, effect) => {
|
|
234761
|
+
if (effect.is(setAsisDecorationsEffect)) {
|
|
234762
|
+
return effect.value;
|
|
234763
|
+
}
|
|
234764
|
+
return currentDecos;
|
|
234765
|
+
}, decorations);
|
|
234766
|
+
},
|
|
234767
|
+
// 데코레이션을 뷰에 제공
|
|
234768
|
+
provide: f => EditorView.decorations.from(f)
|
|
234769
|
+
});
|
|
234770
|
+
|
|
234771
|
+
// Diff 데코레이션을 위한 StateField 정의 (tobe 에디터용)
|
|
234772
|
+
const tobeDiffDecorations = StateField.define({
|
|
234773
|
+
create() { return Decoration.none; },
|
|
234774
|
+
update(decorations, tr) {
|
|
234775
|
+
return tr.effects.reduce((currentDecos, effect) => {
|
|
234776
|
+
if (effect.is(setTobeDecorationsEffect)) {
|
|
234777
|
+
return effect.value;
|
|
234778
|
+
}
|
|
234779
|
+
return currentDecos;
|
|
234780
|
+
}, decorations);
|
|
234781
|
+
},
|
|
234782
|
+
provide: f => EditorView.decorations.from(f)
|
|
234783
|
+
});
|
|
234784
|
+
|
|
234785
|
+
// 데코레이션 업데이트를 위한 Effect (트랜잭션에 포함시켜 상태 변경 알림)
|
|
234786
|
+
const setAsisDecorationsEffect = EditorState.define.effect();
|
|
234787
|
+
const setTobeDecorationsEffect = EditorState.define.effect();
|
|
234788
|
+
|
|
234755
234789
|
|
|
234756
234790
|
class IdeDiff extends HTMLElement {
|
|
234757
|
-
#asisEditorView;
|
|
234758
|
-
#tobeEditorView;
|
|
234759
|
-
#asisEditorEl;
|
|
234760
|
-
#tobeEditorEl;
|
|
234791
|
+
#asisEditorView;
|
|
234792
|
+
#tobeEditorView;
|
|
234793
|
+
#asisEditorEl;
|
|
234794
|
+
#tobeEditorEl;
|
|
234761
234795
|
|
|
234762
|
-
#languageCompartment = new Compartment();
|
|
234796
|
+
#languageCompartment = new Compartment();
|
|
234763
234797
|
|
|
234764
234798
|
constructor() {
|
|
234765
234799
|
super();
|
|
@@ -234783,27 +234817,29 @@ class IdeDiff extends HTMLElement {
|
|
|
234783
234817
|
.panel {
|
|
234784
234818
|
flex: 1; /* 패널들이 남은 공간을 채우도록 */
|
|
234785
234819
|
overflow: hidden; /* CodeMirror EditorView 자체가 스크롤을 처리 */
|
|
234786
|
-
/* position: relative; */ /* CodeMirror가 자체적으로 관리하므로 필요 없을 수 있음 */
|
|
234787
234820
|
min-width: 0; /* Flexbox 아이템이 content 때문에 늘어나는 것을 방지 */
|
|
234788
234821
|
}
|
|
234789
234822
|
.cm-editor {
|
|
234790
234823
|
height: 100%; /* EditorView가 부모 div의 높이를 채우도록 */
|
|
234791
234824
|
}
|
|
234792
234825
|
|
|
234793
|
-
/* Diff 시각화를 위한
|
|
234794
|
-
|
|
234795
|
-
|
|
234796
|
-
}
|
|
234797
|
-
|
|
234798
|
-
|
|
234826
|
+
/* Diff 시각화를 위한 CSS 클래스 */
|
|
234827
|
+
/* 줄 전체 배경색 */
|
|
234828
|
+
.cm-inserted-line-bg { background-color: #e6ffe6; } /* 연한 녹색 */
|
|
234829
|
+
.cm-deleted-line-bg { background-color: #ffe6e6; } /* 연한 빨간색 */
|
|
234830
|
+
|
|
234831
|
+
/* 인라인(단어/문자) 변경 강조 */
|
|
234832
|
+
.cm-inserted-inline {
|
|
234833
|
+
background-color: #90ee90; /* 밝은 녹색 */
|
|
234834
|
+
font-weight: bold;
|
|
234799
234835
|
}
|
|
234800
234836
|
.cm-deleted-inline {
|
|
234801
|
-
background-color: #
|
|
234837
|
+
background-color: #ff9999; /* 밝은 빨간색 */
|
|
234802
234838
|
text-decoration: line-through;
|
|
234839
|
+
font-weight: bold;
|
|
234803
234840
|
}
|
|
234804
|
-
|
|
234805
|
-
|
|
234806
|
-
}
|
|
234841
|
+
/* 선택적: 동일하지만 이동된 줄 강조 (복잡함) */
|
|
234842
|
+
/* .cm-moved-line-bg {} */
|
|
234807
234843
|
</style>
|
|
234808
234844
|
|
|
234809
234845
|
<div class="wrapper">
|
|
@@ -234829,58 +234865,59 @@ class IdeDiff extends HTMLElement {
|
|
|
234829
234865
|
|
|
234830
234866
|
// CodeMirror 확장 기본 설정
|
|
234831
234867
|
const basicExtensions = [
|
|
234832
|
-
lineNumbers(),
|
|
234833
|
-
highlightSpecialChars(),
|
|
234834
|
-
history(),
|
|
234835
|
-
drawSelection(),
|
|
234836
|
-
dropCursor(),
|
|
234837
|
-
EditorState.allowMultipleSelections.of(true),
|
|
234838
|
-
indentOnInput(),
|
|
234839
|
-
bracketMatching(),
|
|
234840
|
-
highlightActiveLine(),
|
|
234841
|
-
highlightSelectionMatches(),
|
|
234868
|
+
lineNumbers(),
|
|
234869
|
+
highlightSpecialChars(),
|
|
234870
|
+
history(),
|
|
234871
|
+
drawSelection(),
|
|
234872
|
+
dropCursor(),
|
|
234873
|
+
EditorState.allowMultipleSelections.of(true),
|
|
234874
|
+
indentOnInput(),
|
|
234875
|
+
bracketMatching(),
|
|
234876
|
+
highlightActiveLine(),
|
|
234877
|
+
highlightSelectionMatches(),
|
|
234842
234878
|
keymap.of([
|
|
234843
|
-
...defaultKeymap,
|
|
234844
|
-
...searchKeymap,
|
|
234845
|
-
...historyKeymap,
|
|
234846
|
-
...lintKeymap,
|
|
234847
|
-
...completionKeymap,
|
|
234848
|
-
indentWithTab
|
|
234879
|
+
...defaultKeymap,
|
|
234880
|
+
...searchKeymap,
|
|
234881
|
+
...historyKeymap,
|
|
234882
|
+
...lintKeymap,
|
|
234883
|
+
...completionKeymap,
|
|
234884
|
+
indentWithTab,
|
|
234885
|
+
selectAll // selectAll 추가
|
|
234849
234886
|
]),
|
|
234850
|
-
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
|
234851
|
-
autocompletion(),
|
|
234852
|
-
// EditorState.readOnly.of(true) // 기본적으로 읽기 전용으로 설정
|
|
234887
|
+
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
|
234888
|
+
autocompletion(),
|
|
234853
234889
|
];
|
|
234854
234890
|
|
|
234855
234891
|
// asis 에디터 생성 (읽기 전용)
|
|
234856
234892
|
this.#asisEditorView = new EditorView({
|
|
234857
234893
|
state: EditorState.create({
|
|
234858
|
-
doc: '',
|
|
234894
|
+
doc: '',
|
|
234859
234895
|
extensions: [
|
|
234860
234896
|
basicExtensions,
|
|
234861
|
-
javascript(), // JS 언어 모드 (
|
|
234897
|
+
javascript(), // JS 언어 모드 (기본)
|
|
234862
234898
|
EditorState.readOnly.of(true), // asis는 읽기 전용
|
|
234863
|
-
this.#languageCompartment.of(javascript()) // 언어
|
|
234899
|
+
this.#languageCompartment.of(javascript()), // 언어 변경 compartment
|
|
234900
|
+
asisDiffDecorations // asis 에디터에 Diff 데코레이션 필드 추가
|
|
234864
234901
|
]
|
|
234865
234902
|
}),
|
|
234866
234903
|
parent: this.#asisEditorEl
|
|
234867
234904
|
});
|
|
234868
234905
|
|
|
234869
|
-
// tobe 에디터 생성 (읽기 전용,
|
|
234906
|
+
// tobe 에디터 생성 (읽기 전용, 필요 시 편집 가능하게 설정)
|
|
234870
234907
|
this.#tobeEditorView = new EditorView({
|
|
234871
234908
|
state: EditorState.create({
|
|
234872
|
-
doc: '',
|
|
234909
|
+
doc: '',
|
|
234873
234910
|
extensions: [
|
|
234874
234911
|
basicExtensions,
|
|
234875
|
-
javascript(), // JS 언어 모드 (
|
|
234876
|
-
EditorState.readOnly.of(true), // tobe도 읽기
|
|
234877
|
-
this.#languageCompartment.of(javascript()) // 언어
|
|
234912
|
+
javascript(), // JS 언어 모드 (기본)
|
|
234913
|
+
EditorState.readOnly.of(true), // tobe도 읽기 전용
|
|
234914
|
+
this.#languageCompartment.of(javascript()), // 언어 변경 compartment
|
|
234915
|
+
tobeDiffDecorations // tobe 에디터에 Diff 데코레이션 필드 추가
|
|
234878
234916
|
]
|
|
234879
234917
|
}),
|
|
234880
234918
|
parent: this.#tobeEditorEl
|
|
234881
234919
|
});
|
|
234882
234920
|
|
|
234883
|
-
// 스크롤 동기화 설정
|
|
234884
234921
|
this.#setupScrollSync();
|
|
234885
234922
|
};
|
|
234886
234923
|
|
|
@@ -234907,44 +234944,101 @@ class IdeDiff extends HTMLElement {
|
|
|
234907
234944
|
});
|
|
234908
234945
|
};
|
|
234909
234946
|
|
|
234910
|
-
// Diff
|
|
234911
|
-
#
|
|
234947
|
+
// ⭐️⭐️⭐️ Diff 데코레이션 적용 로직 구현 ⭐️⭐️⭐️
|
|
234948
|
+
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
234912
234949
|
const dmp = new diffMatchPatchExports.diff_match_patch();
|
|
234913
234950
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
234914
234951
|
dmp.diff_cleanupSemantic(diffs);
|
|
234915
234952
|
|
|
234916
|
-
|
|
234917
|
-
|
|
234918
|
-
|
|
234919
|
-
//
|
|
234920
|
-
//
|
|
234921
|
-
|
|
234922
|
-
//
|
|
234923
|
-
|
|
234924
|
-
|
|
234925
|
-
|
|
234926
|
-
//
|
|
234927
|
-
|
|
234928
|
-
|
|
234929
|
-
|
|
234930
|
-
|
|
234931
|
-
|
|
234932
|
-
|
|
234933
|
-
|
|
234934
|
-
|
|
234935
|
-
|
|
234936
|
-
|
|
234937
|
-
|
|
234938
|
-
|
|
234939
|
-
|
|
234940
|
-
|
|
234941
|
-
|
|
234942
|
-
|
|
234953
|
+
const asisBuilder = new RangeSetBuilder();
|
|
234954
|
+
const tobeBuilder = new RangeSetBuilder();
|
|
234955
|
+
|
|
234956
|
+
let asisCursor = 0; // asis 에디터에서의 현재 텍스트 오프셋
|
|
234957
|
+
let tobeCursor = 0; // tobe 에디터에서의 현재 텍스트 오프셋
|
|
234958
|
+
|
|
234959
|
+
// 줄 단위 데코레이션을 위해 줄 시작 위치를 추적
|
|
234960
|
+
const asisLineStartMap = new Map();
|
|
234961
|
+
const tobeLineStartMap = new Map();
|
|
234962
|
+
|
|
234963
|
+
// 각 텍스트에 대한 줄 시작 위치 미리 계산
|
|
234964
|
+
let currentPos = 0;
|
|
234965
|
+
for (const line of asisSrc.split('\n')) {
|
|
234966
|
+
asisLineStartMap.set(currentPos, true);
|
|
234967
|
+
currentPos += line.length + 1; // +1은 줄바꿈 문자 포함
|
|
234968
|
+
}
|
|
234969
|
+
currentPos = 0;
|
|
234970
|
+
for (const line of tobeSrc.split('\n')) {
|
|
234971
|
+
tobeLineStartMap.set(currentPos, true);
|
|
234972
|
+
currentPos += line.length + 1;
|
|
234973
|
+
}
|
|
234974
|
+
|
|
234975
|
+
for (const [op, text] of diffs) {
|
|
234976
|
+
const len = text.length;
|
|
234977
|
+
|
|
234978
|
+
switch (op) {
|
|
234979
|
+
case diffMatchPatchExports.diff_match_patch.DIFF_INSERT: // Added text
|
|
234980
|
+
// tobe 쪽에 인라인 데코레이션 추가
|
|
234981
|
+
tobeBuilder.add(
|
|
234982
|
+
tobeCursor, tobeCursor + len,
|
|
234983
|
+
Decoration.mark({ class: "cm-inserted-inline" })
|
|
234984
|
+
);
|
|
234985
|
+
|
|
234986
|
+
// tobe 쪽에 줄 전체 데코레이션 추가 (삽입된 줄)
|
|
234987
|
+
// text가 여러 줄일 수 있으므로 각 줄에 적용
|
|
234988
|
+
const tobeLines = text.split('\n');
|
|
234989
|
+
let currentLineOffset = tobeCursor;
|
|
234990
|
+
for(let i = 0; i < tobeLines.length; i++) {
|
|
234991
|
+
// 각 줄의 시작 위치를 찾기
|
|
234992
|
+
const lineStart = tobeEditorView.state.doc.lineAt(currentLineOffset).from;
|
|
234993
|
+
// 만약 다음 줄이 있다면 해당 줄의 끝까지, 마지막 줄이라면 텍스트의 끝까지
|
|
234994
|
+
const lineEnd = i === tobeLines.length - 1 ? currentLineOffset + tobeLines[i].length : tobeEditorView.state.doc.lineAt(currentLineOffset).to;
|
|
234995
|
+
tobeBuilder.add(
|
|
234996
|
+
lineStart, lineEnd, // 줄의 실제 시작부터 끝까지
|
|
234997
|
+
Decoration.line({ class: "cm-inserted-line-bg" })
|
|
234998
|
+
);
|
|
234999
|
+
currentLineOffset += tobeLines[i].length + 1; // 다음 줄 시작 위치로 이동
|
|
235000
|
+
}
|
|
235001
|
+
|
|
235002
|
+
|
|
235003
|
+
tobeCursor += len;
|
|
235004
|
+
break;
|
|
235005
|
+
|
|
235006
|
+
case diffMatchPatchExports.diff_match_patch.DIFF_DELETE: // Deleted text
|
|
235007
|
+
// asis 쪽에 인라인 데코레이션 추가
|
|
235008
|
+
asisBuilder.add(
|
|
235009
|
+
asisCursor, asisCursor + len,
|
|
235010
|
+
Decoration.mark({ class: "cm-deleted-inline" })
|
|
235011
|
+
);
|
|
235012
|
+
|
|
235013
|
+
// asis 쪽에 줄 전체 데코레이션 추가 (삭제된 줄)
|
|
235014
|
+
const asisLines = text.split('\n');
|
|
235015
|
+
let currentAsisLineOffset = asisCursor;
|
|
235016
|
+
for(let i = 0; i < asisLines.length; i++) {
|
|
235017
|
+
const lineStart = asisEditorView.state.doc.lineAt(currentAsisLineOffset).from;
|
|
235018
|
+
const lineEnd = i === asisLines.length - 1 ? currentAsisLineOffset + asisLines[i].length : asisEditorView.state.doc.lineAt(currentAsisLineOffset).to;
|
|
235019
|
+
asisBuilder.add(
|
|
235020
|
+
lineStart, lineEnd,
|
|
235021
|
+
Decoration.line({ class: "cm-deleted-line-bg" })
|
|
235022
|
+
);
|
|
235023
|
+
currentAsisLineOffset += asisLines[i].length + 1;
|
|
235024
|
+
}
|
|
235025
|
+
|
|
235026
|
+
asisCursor += len;
|
|
235027
|
+
break;
|
|
235028
|
+
|
|
235029
|
+
case diffMatchPatchExports.diff_match_patch.DIFF_EQUAL: // Unchanged text
|
|
235030
|
+
asisCursor += len;
|
|
235031
|
+
tobeCursor += len;
|
|
235032
|
+
break;
|
|
235033
|
+
}
|
|
235034
|
+
}
|
|
235035
|
+
|
|
235036
|
+
// 에디터 뷰에 데코레이션 업데이트 요청 디스패치
|
|
234943
235037
|
this.#asisEditorView.dispatch({
|
|
234944
|
-
|
|
235038
|
+
effects: setAsisDecorationsEffect.of(asisBuilder.finish())
|
|
234945
235039
|
});
|
|
234946
235040
|
this.#tobeEditorView.dispatch({
|
|
234947
|
-
|
|
235041
|
+
effects: setTobeDecorationsEffect.of(tobeBuilder.finish())
|
|
234948
235042
|
});
|
|
234949
235043
|
};
|
|
234950
235044
|
|
|
@@ -234961,13 +235055,15 @@ class IdeDiff extends HTMLElement {
|
|
|
234961
235055
|
langExtension = javascript();
|
|
234962
235056
|
break;
|
|
234963
235057
|
// case 'html':
|
|
234964
|
-
//
|
|
235058
|
+
// import { html } from "@codemirror/lang-html"; // 상단에 임포트 필요
|
|
235059
|
+
// langExtension = html();
|
|
234965
235060
|
// break;
|
|
234966
235061
|
// case 'css':
|
|
234967
|
-
//
|
|
235062
|
+
// import { css } from "@codemirror/lang-css"; // 상단에 임포트 필요
|
|
235063
|
+
// langExtension = css();
|
|
234968
235064
|
// break;
|
|
234969
235065
|
default:
|
|
234970
|
-
langExtension = javascript();
|
|
235066
|
+
langExtension = javascript();
|
|
234971
235067
|
}
|
|
234972
235068
|
|
|
234973
235069
|
// 언어 확장 업데이트
|
|
@@ -234978,11 +235074,19 @@ class IdeDiff extends HTMLElement {
|
|
|
234978
235074
|
effects: this.#languageCompartment.reconfigure(langExtension)
|
|
234979
235075
|
});
|
|
234980
235076
|
|
|
234981
|
-
|
|
235077
|
+
// 텍스트 내용 업데이트
|
|
235078
|
+
this.#asisEditorView.dispatch({
|
|
235079
|
+
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 }
|
|
235080
|
+
});
|
|
235081
|
+
this.#tobeEditorView.dispatch({
|
|
235082
|
+
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 }
|
|
235083
|
+
});
|
|
235084
|
+
|
|
235085
|
+
// Diff 데코레이션 적용
|
|
235086
|
+
this.#applyDiffDecorations(src1, src2);
|
|
234982
235087
|
};
|
|
234983
235088
|
|
|
234984
235089
|
disconnectedCallback() {
|
|
234985
|
-
// 컴포넌트가 DOM에서 제거될 때 에디터 인스턴스 정리
|
|
234986
235090
|
if (this.#asisEditorView) {
|
|
234987
235091
|
this.#asisEditorView.destroy();
|
|
234988
235092
|
}
|