ide-assi 0.345.0 → 0.347.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 +36 -42
- package/dist/bundle.esm.js +36 -42
- package/dist/components/ideDiff.js +39 -45
- package/package.json +1 -1
- package/src/components/ideDiff.js +39 -45
package/dist/bundle.cjs.js
CHANGED
|
@@ -234751,10 +234751,6 @@ function requireDiffMatchPatch () {
|
|
|
234751
234751
|
|
|
234752
234752
|
var diffMatchPatchExports = requireDiffMatchPatch();
|
|
234753
234753
|
|
|
234754
|
-
// ... (나머지 코드는 동일) ...
|
|
234755
|
-
|
|
234756
|
-
// --- 여기서부터 수정된 부분 ---
|
|
234757
|
-
|
|
234758
234754
|
// Diff 데코레이션을 위한 StateField 정의 (asis 에디터용)
|
|
234759
234755
|
const asisDiffDecorations = StateField.define({
|
|
234760
234756
|
create() { return Decoration.none; },
|
|
@@ -234784,12 +234780,10 @@ const tobeDiffDecorations = StateField.define({
|
|
|
234784
234780
|
});
|
|
234785
234781
|
|
|
234786
234782
|
// 데코레이션 업데이트를 위한 Effect (트랜잭션에 포함시켜 상태 변경 알림)
|
|
234787
|
-
//
|
|
234783
|
+
// StateEffect.define()을 사용하여 이펙트를 정의합니다.
|
|
234788
234784
|
const setAsisDecorationsEffect = StateEffect.define();
|
|
234789
234785
|
const setTobeDecorationsEffect = StateEffect.define();
|
|
234790
234786
|
|
|
234791
|
-
// --- 여기까지 수정된 부분 ---
|
|
234792
|
-
|
|
234793
234787
|
class IdeDiff extends HTMLElement {
|
|
234794
234788
|
|
|
234795
234789
|
#asisEditorView;
|
|
@@ -234943,6 +234937,7 @@ class IdeDiff extends HTMLElement {
|
|
|
234943
234937
|
});
|
|
234944
234938
|
};
|
|
234945
234939
|
|
|
234940
|
+
// ⭐️ #applyDiffDecorations 함수를 수정하여 Effect 객체를 반환하도록 변경
|
|
234946
234941
|
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
234947
234942
|
const dmp = new diffMatchPatchExports.diff_match_patch();
|
|
234948
234943
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
@@ -234970,8 +234965,16 @@ class IdeDiff extends HTMLElement {
|
|
|
234970
234965
|
let currentTobeLineOffset = tobeCursor;
|
|
234971
234966
|
const tobeLines = text.split('\n');
|
|
234972
234967
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
234973
|
-
//
|
|
234974
|
-
|
|
234968
|
+
// 중요한 변경: line.from/to는 현재 에디터 뷰의 doc에서 가져옵니다.
|
|
234969
|
+
// 이 함수는 initialize 내에서 텍스트 변경과 함께 호출되므로,
|
|
234970
|
+
// 이 시점의 this.#tobeEditorView.state.doc은 아직 이전 내용일 수 있습니다.
|
|
234971
|
+
// 그러나, Effect로 반환되어 트랜잭션에 포함될 때 CodeMirror는
|
|
234972
|
+
// Effect를 처리하는 시점에 이미 텍스트가 업데이트되었음을 보장합니다.
|
|
234973
|
+
// 따라서 여기서 doc.length로 유효성 검사하는 것은 새로운 src2 기준이어야 더 정확합니다.
|
|
234974
|
+
// 하지만, 이 라인은 결국 새로운 doc에서 실행될 것이므로,
|
|
234975
|
+
// 여기서의 this.#tobeEditorView.state.doc.length 검사는 불필요하거나 오해의 소지가 있습니다.
|
|
234976
|
+
// 대신, tobeCursor + len (또는 currentTobeLineOffset)이 tobeSrc의 길이를 벗어나지 않는지 확인하는 것이 좋습니다.
|
|
234977
|
+
if (currentTobeLineOffset < tobeSrc.length) { // src2 (새로운 텍스트)의 길이와 비교
|
|
234975
234978
|
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
234976
234979
|
tobeLineDecos.push({
|
|
234977
234980
|
from: line.from,
|
|
@@ -234979,11 +234982,8 @@ class IdeDiff extends HTMLElement {
|
|
|
234979
234982
|
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
234980
234983
|
});
|
|
234981
234984
|
}
|
|
234982
|
-
|
|
234983
|
-
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
234984
|
-
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
234985
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
234985
234986
|
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
234986
|
-
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
234987
234987
|
break;
|
|
234988
234988
|
}
|
|
234989
234989
|
}
|
|
@@ -235001,8 +235001,7 @@ class IdeDiff extends HTMLElement {
|
|
|
235001
235001
|
let currentAsisLineOffset = asisCursor;
|
|
235002
235002
|
const asisLines = text.split('\n');
|
|
235003
235003
|
for (let i = 0; i < asisLines.length; i++) {
|
|
235004
|
-
|
|
235005
|
-
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
235004
|
+
if (currentAsisLineOffset < asisSrc.length) { // src1 (새로운 텍스트)의 길이와 비교
|
|
235006
235005
|
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
235007
235006
|
asisLineDecos.push({
|
|
235008
235007
|
from: line.from,
|
|
@@ -235010,7 +235009,7 @@ class IdeDiff extends HTMLElement {
|
|
|
235010
235009
|
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
235011
235010
|
});
|
|
235012
235011
|
}
|
|
235013
|
-
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
235012
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
235014
235013
|
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
235015
235014
|
break;
|
|
235016
235015
|
}
|
|
@@ -235026,13 +235025,11 @@ class IdeDiff extends HTMLElement {
|
|
|
235026
235025
|
}
|
|
235027
235026
|
}
|
|
235028
235027
|
|
|
235029
|
-
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
235030
235028
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
235031
235029
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
235032
235030
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
235033
235031
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
235034
235032
|
|
|
235035
|
-
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235036
235033
|
const asisLineBuilder = new RangeSetBuilder();
|
|
235037
235034
|
for (const { from, to, deco } of asisLineDecos) {
|
|
235038
235035
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -235041,13 +235038,10 @@ class IdeDiff extends HTMLElement {
|
|
|
235041
235038
|
for (const { from, to, deco } of asisMarkDecos) {
|
|
235042
235039
|
asisMarkBuilder.add(from, to, deco);
|
|
235043
235040
|
}
|
|
235044
|
-
|
|
235045
|
-
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
235046
235041
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
235047
235042
|
add: asisMarkBuilder.finish().children
|
|
235048
235043
|
});
|
|
235049
235044
|
|
|
235050
|
-
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235051
235045
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
235052
235046
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
235053
235047
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -235056,21 +235050,18 @@ class IdeDiff extends HTMLElement {
|
|
|
235056
235050
|
for (const { from, to, deco } of tobeMarkDecos) {
|
|
235057
235051
|
tobeMarkBuilder.add(from, to, deco);
|
|
235058
235052
|
}
|
|
235059
|
-
|
|
235060
|
-
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
235061
235053
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
235062
235054
|
add: tobeMarkBuilder.finish().children
|
|
235063
235055
|
});
|
|
235064
235056
|
|
|
235065
|
-
// 데코레이션
|
|
235066
|
-
|
|
235067
|
-
|
|
235068
|
-
|
|
235069
|
-
|
|
235070
|
-
effects: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
235071
|
-
});
|
|
235057
|
+
// ⭐️ 중요: 데코레이션 효과를 반환합니다. 여기서 직접 dispatch 하지 않습니다.
|
|
235058
|
+
return {
|
|
235059
|
+
asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
|
|
235060
|
+
tobeEffect: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
235061
|
+
};
|
|
235072
235062
|
};
|
|
235073
235063
|
|
|
235064
|
+
// ⭐️ initialize 함수를 수정하여 텍스트 변경과 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235074
235065
|
initialize = (src1, src2, language = 'javascript') => {
|
|
235075
235066
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
235076
235067
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -235086,23 +235077,26 @@ class IdeDiff extends HTMLElement {
|
|
|
235086
235077
|
langExtension = javascript();
|
|
235087
235078
|
}
|
|
235088
235079
|
|
|
235089
|
-
|
|
235090
|
-
|
|
235091
|
-
});
|
|
235092
|
-
this.#tobeEditorView.dispatch({
|
|
235093
|
-
effects: this.#languageCompartment.reconfigure(langExtension)
|
|
235094
|
-
});
|
|
235080
|
+
// 먼저 데코레이션 효과를 계산하여 가져옵니다.
|
|
235081
|
+
const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
|
|
235095
235082
|
|
|
235096
|
-
// 텍스트
|
|
235083
|
+
// asis 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235097
235084
|
this.#asisEditorView.dispatch({
|
|
235098
|
-
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 }
|
|
235085
|
+
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 },
|
|
235086
|
+
effects: [
|
|
235087
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
235088
|
+
asisEffect // 계산된 데코레이션 효과를 포함
|
|
235089
|
+
]
|
|
235099
235090
|
});
|
|
235091
|
+
|
|
235092
|
+
// tobe 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235100
235093
|
this.#tobeEditorView.dispatch({
|
|
235101
|
-
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 }
|
|
235094
|
+
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 },
|
|
235095
|
+
effects: [
|
|
235096
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
235097
|
+
tobeEffect // 계산된 데코레이션 효과를 포함
|
|
235098
|
+
]
|
|
235102
235099
|
});
|
|
235103
|
-
|
|
235104
|
-
// Diff 데코레이션 적용
|
|
235105
|
-
this.#applyDiffDecorations(src1, src2);
|
|
235106
235100
|
};
|
|
235107
235101
|
|
|
235108
235102
|
disconnectedCallback() {
|
package/dist/bundle.esm.js
CHANGED
|
@@ -234747,10 +234747,6 @@ function requireDiffMatchPatch () {
|
|
|
234747
234747
|
|
|
234748
234748
|
var diffMatchPatchExports = requireDiffMatchPatch();
|
|
234749
234749
|
|
|
234750
|
-
// ... (나머지 코드는 동일) ...
|
|
234751
|
-
|
|
234752
|
-
// --- 여기서부터 수정된 부분 ---
|
|
234753
|
-
|
|
234754
234750
|
// Diff 데코레이션을 위한 StateField 정의 (asis 에디터용)
|
|
234755
234751
|
const asisDiffDecorations = StateField.define({
|
|
234756
234752
|
create() { return Decoration.none; },
|
|
@@ -234780,12 +234776,10 @@ const tobeDiffDecorations = StateField.define({
|
|
|
234780
234776
|
});
|
|
234781
234777
|
|
|
234782
234778
|
// 데코레이션 업데이트를 위한 Effect (트랜잭션에 포함시켜 상태 변경 알림)
|
|
234783
|
-
//
|
|
234779
|
+
// StateEffect.define()을 사용하여 이펙트를 정의합니다.
|
|
234784
234780
|
const setAsisDecorationsEffect = StateEffect.define();
|
|
234785
234781
|
const setTobeDecorationsEffect = StateEffect.define();
|
|
234786
234782
|
|
|
234787
|
-
// --- 여기까지 수정된 부분 ---
|
|
234788
|
-
|
|
234789
234783
|
class IdeDiff extends HTMLElement {
|
|
234790
234784
|
|
|
234791
234785
|
#asisEditorView;
|
|
@@ -234939,6 +234933,7 @@ class IdeDiff extends HTMLElement {
|
|
|
234939
234933
|
});
|
|
234940
234934
|
};
|
|
234941
234935
|
|
|
234936
|
+
// ⭐️ #applyDiffDecorations 함수를 수정하여 Effect 객체를 반환하도록 변경
|
|
234942
234937
|
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
234943
234938
|
const dmp = new diffMatchPatchExports.diff_match_patch();
|
|
234944
234939
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
@@ -234966,8 +234961,16 @@ class IdeDiff extends HTMLElement {
|
|
|
234966
234961
|
let currentTobeLineOffset = tobeCursor;
|
|
234967
234962
|
const tobeLines = text.split('\n');
|
|
234968
234963
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
234969
|
-
//
|
|
234970
|
-
|
|
234964
|
+
// 중요한 변경: line.from/to는 현재 에디터 뷰의 doc에서 가져옵니다.
|
|
234965
|
+
// 이 함수는 initialize 내에서 텍스트 변경과 함께 호출되므로,
|
|
234966
|
+
// 이 시점의 this.#tobeEditorView.state.doc은 아직 이전 내용일 수 있습니다.
|
|
234967
|
+
// 그러나, Effect로 반환되어 트랜잭션에 포함될 때 CodeMirror는
|
|
234968
|
+
// Effect를 처리하는 시점에 이미 텍스트가 업데이트되었음을 보장합니다.
|
|
234969
|
+
// 따라서 여기서 doc.length로 유효성 검사하는 것은 새로운 src2 기준이어야 더 정확합니다.
|
|
234970
|
+
// 하지만, 이 라인은 결국 새로운 doc에서 실행될 것이므로,
|
|
234971
|
+
// 여기서의 this.#tobeEditorView.state.doc.length 검사는 불필요하거나 오해의 소지가 있습니다.
|
|
234972
|
+
// 대신, tobeCursor + len (또는 currentTobeLineOffset)이 tobeSrc의 길이를 벗어나지 않는지 확인하는 것이 좋습니다.
|
|
234973
|
+
if (currentTobeLineOffset < tobeSrc.length) { // src2 (새로운 텍스트)의 길이와 비교
|
|
234971
234974
|
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
234972
234975
|
tobeLineDecos.push({
|
|
234973
234976
|
from: line.from,
|
|
@@ -234975,11 +234978,8 @@ class IdeDiff extends HTMLElement {
|
|
|
234975
234978
|
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
234976
234979
|
});
|
|
234977
234980
|
}
|
|
234978
|
-
|
|
234979
|
-
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
234980
|
-
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
234981
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
234981
234982
|
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
234982
|
-
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
234983
234983
|
break;
|
|
234984
234984
|
}
|
|
234985
234985
|
}
|
|
@@ -234997,8 +234997,7 @@ class IdeDiff extends HTMLElement {
|
|
|
234997
234997
|
let currentAsisLineOffset = asisCursor;
|
|
234998
234998
|
const asisLines = text.split('\n');
|
|
234999
234999
|
for (let i = 0; i < asisLines.length; i++) {
|
|
235000
|
-
|
|
235001
|
-
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
235000
|
+
if (currentAsisLineOffset < asisSrc.length) { // src1 (새로운 텍스트)의 길이와 비교
|
|
235002
235001
|
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
235003
235002
|
asisLineDecos.push({
|
|
235004
235003
|
from: line.from,
|
|
@@ -235006,7 +235005,7 @@ class IdeDiff extends HTMLElement {
|
|
|
235006
235005
|
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
235007
235006
|
});
|
|
235008
235007
|
}
|
|
235009
|
-
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
235008
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
235010
235009
|
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
235011
235010
|
break;
|
|
235012
235011
|
}
|
|
@@ -235022,13 +235021,11 @@ class IdeDiff extends HTMLElement {
|
|
|
235022
235021
|
}
|
|
235023
235022
|
}
|
|
235024
235023
|
|
|
235025
|
-
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
235026
235024
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
235027
235025
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
235028
235026
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
235029
235027
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
235030
235028
|
|
|
235031
|
-
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235032
235029
|
const asisLineBuilder = new RangeSetBuilder();
|
|
235033
235030
|
for (const { from, to, deco } of asisLineDecos) {
|
|
235034
235031
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -235037,13 +235034,10 @@ class IdeDiff extends HTMLElement {
|
|
|
235037
235034
|
for (const { from, to, deco } of asisMarkDecos) {
|
|
235038
235035
|
asisMarkBuilder.add(from, to, deco);
|
|
235039
235036
|
}
|
|
235040
|
-
|
|
235041
|
-
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
235042
235037
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
235043
235038
|
add: asisMarkBuilder.finish().children
|
|
235044
235039
|
});
|
|
235045
235040
|
|
|
235046
|
-
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235047
235041
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
235048
235042
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
235049
235043
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -235052,21 +235046,18 @@ class IdeDiff extends HTMLElement {
|
|
|
235052
235046
|
for (const { from, to, deco } of tobeMarkDecos) {
|
|
235053
235047
|
tobeMarkBuilder.add(from, to, deco);
|
|
235054
235048
|
}
|
|
235055
|
-
|
|
235056
|
-
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
235057
235049
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
235058
235050
|
add: tobeMarkBuilder.finish().children
|
|
235059
235051
|
});
|
|
235060
235052
|
|
|
235061
|
-
// 데코레이션
|
|
235062
|
-
|
|
235063
|
-
|
|
235064
|
-
|
|
235065
|
-
|
|
235066
|
-
effects: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
235067
|
-
});
|
|
235053
|
+
// ⭐️ 중요: 데코레이션 효과를 반환합니다. 여기서 직접 dispatch 하지 않습니다.
|
|
235054
|
+
return {
|
|
235055
|
+
asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
|
|
235056
|
+
tobeEffect: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
235057
|
+
};
|
|
235068
235058
|
};
|
|
235069
235059
|
|
|
235060
|
+
// ⭐️ initialize 함수를 수정하여 텍스트 변경과 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235070
235061
|
initialize = (src1, src2, language = 'javascript') => {
|
|
235071
235062
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
235072
235063
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -235082,23 +235073,26 @@ class IdeDiff extends HTMLElement {
|
|
|
235082
235073
|
langExtension = javascript();
|
|
235083
235074
|
}
|
|
235084
235075
|
|
|
235085
|
-
|
|
235086
|
-
|
|
235087
|
-
});
|
|
235088
|
-
this.#tobeEditorView.dispatch({
|
|
235089
|
-
effects: this.#languageCompartment.reconfigure(langExtension)
|
|
235090
|
-
});
|
|
235076
|
+
// 먼저 데코레이션 효과를 계산하여 가져옵니다.
|
|
235077
|
+
const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
|
|
235091
235078
|
|
|
235092
|
-
// 텍스트
|
|
235079
|
+
// asis 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235093
235080
|
this.#asisEditorView.dispatch({
|
|
235094
|
-
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 }
|
|
235081
|
+
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 },
|
|
235082
|
+
effects: [
|
|
235083
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
235084
|
+
asisEffect // 계산된 데코레이션 효과를 포함
|
|
235085
|
+
]
|
|
235095
235086
|
});
|
|
235087
|
+
|
|
235088
|
+
// tobe 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
235096
235089
|
this.#tobeEditorView.dispatch({
|
|
235097
|
-
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 }
|
|
235090
|
+
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 },
|
|
235091
|
+
effects: [
|
|
235092
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
235093
|
+
tobeEffect // 계산된 데코레이션 효과를 포함
|
|
235094
|
+
]
|
|
235098
235095
|
});
|
|
235099
|
-
|
|
235100
|
-
// Diff 데코레이션 적용
|
|
235101
|
-
this.#applyDiffDecorations(src1, src2);
|
|
235102
235096
|
};
|
|
235103
235097
|
|
|
235104
235098
|
disconnectedCallback() {
|
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
EditorState, Compartment, StateField,
|
|
11
11
|
RangeSetBuilder,
|
|
12
|
-
StateEffect
|
|
12
|
+
StateEffect // StateEffect를 올바르게 임포트
|
|
13
13
|
} from "@codemirror/state";
|
|
14
14
|
import { history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
|
15
15
|
import { defaultKeymap, selectAll } from "@codemirror/commands";
|
|
16
16
|
import { searchKeymap, highlightSelectionMatches } from "@codemirror/search";
|
|
17
|
-
//
|
|
17
|
+
// 올바른 import 구문: '=>' 대신 'from'
|
|
18
18
|
import { bracketMatching } from "@codemirror/language";
|
|
19
19
|
import { javascript } from "@codemirror/lang-javascript";
|
|
20
20
|
import { indentOnInput, syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
|
|
@@ -22,11 +22,7 @@ import { lintKeymap } from "@codemirror/lint";
|
|
|
22
22
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
23
23
|
|
|
24
24
|
// Diff 로직을 위해 diff-match-patch 사용
|
|
25
|
-
import { diff_match_patch } from 'diff-match-patch';
|
|
26
|
-
|
|
27
|
-
// ... (나머지 코드는 동일) ...
|
|
28
|
-
|
|
29
|
-
// --- 여기서부터 수정된 부분 ---
|
|
25
|
+
import { diff_match_patch } from 'diff-match-patch'; // 올바른 패키지 이름: 하이픈 '-'
|
|
30
26
|
|
|
31
27
|
// Diff 데코레이션을 위한 StateField 정의 (asis 에디터용)
|
|
32
28
|
const asisDiffDecorations = StateField.define({
|
|
@@ -57,12 +53,10 @@ const tobeDiffDecorations = StateField.define({
|
|
|
57
53
|
});
|
|
58
54
|
|
|
59
55
|
// 데코레이션 업데이트를 위한 Effect (트랜잭션에 포함시켜 상태 변경 알림)
|
|
60
|
-
//
|
|
56
|
+
// StateEffect.define()을 사용하여 이펙트를 정의합니다.
|
|
61
57
|
const setAsisDecorationsEffect = StateEffect.define();
|
|
62
58
|
const setTobeDecorationsEffect = StateEffect.define();
|
|
63
59
|
|
|
64
|
-
// --- 여기까지 수정된 부분 ---
|
|
65
|
-
|
|
66
60
|
export class IdeDiff extends HTMLElement {
|
|
67
61
|
|
|
68
62
|
#asisEditorView;
|
|
@@ -216,6 +210,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
216
210
|
});
|
|
217
211
|
};
|
|
218
212
|
|
|
213
|
+
// ⭐️ #applyDiffDecorations 함수를 수정하여 Effect 객체를 반환하도록 변경
|
|
219
214
|
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
220
215
|
const dmp = new diff_match_patch();
|
|
221
216
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
@@ -243,8 +238,16 @@ export class IdeDiff extends HTMLElement {
|
|
|
243
238
|
let currentTobeLineOffset = tobeCursor;
|
|
244
239
|
const tobeLines = text.split('\n');
|
|
245
240
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
246
|
-
//
|
|
247
|
-
|
|
241
|
+
// 중요한 변경: line.from/to는 현재 에디터 뷰의 doc에서 가져옵니다.
|
|
242
|
+
// 이 함수는 initialize 내에서 텍스트 변경과 함께 호출되므로,
|
|
243
|
+
// 이 시점의 this.#tobeEditorView.state.doc은 아직 이전 내용일 수 있습니다.
|
|
244
|
+
// 그러나, Effect로 반환되어 트랜잭션에 포함될 때 CodeMirror는
|
|
245
|
+
// Effect를 처리하는 시점에 이미 텍스트가 업데이트되었음을 보장합니다.
|
|
246
|
+
// 따라서 여기서 doc.length로 유효성 검사하는 것은 새로운 src2 기준이어야 더 정확합니다.
|
|
247
|
+
// 하지만, 이 라인은 결국 새로운 doc에서 실행될 것이므로,
|
|
248
|
+
// 여기서의 this.#tobeEditorView.state.doc.length 검사는 불필요하거나 오해의 소지가 있습니다.
|
|
249
|
+
// 대신, tobeCursor + len (또는 currentTobeLineOffset)이 tobeSrc의 길이를 벗어나지 않는지 확인하는 것이 좋습니다.
|
|
250
|
+
if (currentTobeLineOffset < tobeSrc.length) { // src2 (새로운 텍스트)의 길이와 비교
|
|
248
251
|
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
249
252
|
tobeLineDecos.push({
|
|
250
253
|
from: line.from,
|
|
@@ -252,11 +255,8 @@ export class IdeDiff extends HTMLElement {
|
|
|
252
255
|
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
253
256
|
});
|
|
254
257
|
}
|
|
255
|
-
|
|
256
|
-
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
257
|
-
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
258
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
258
259
|
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
259
|
-
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
260
260
|
break;
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -274,8 +274,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
274
274
|
let currentAsisLineOffset = asisCursor;
|
|
275
275
|
const asisLines = text.split('\n');
|
|
276
276
|
for (let i = 0; i < asisLines.length; i++) {
|
|
277
|
-
|
|
278
|
-
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
277
|
+
if (currentAsisLineOffset < asisSrc.length) { // src1 (새로운 텍스트)의 길이와 비교
|
|
279
278
|
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
280
279
|
asisLineDecos.push({
|
|
281
280
|
from: line.from,
|
|
@@ -283,7 +282,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
283
282
|
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
284
283
|
});
|
|
285
284
|
}
|
|
286
|
-
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
285
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
287
286
|
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
288
287
|
break;
|
|
289
288
|
}
|
|
@@ -299,13 +298,11 @@ export class IdeDiff extends HTMLElement {
|
|
|
299
298
|
}
|
|
300
299
|
}
|
|
301
300
|
|
|
302
|
-
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
303
301
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
304
302
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
305
303
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
306
304
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
307
305
|
|
|
308
|
-
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
309
306
|
const asisLineBuilder = new RangeSetBuilder();
|
|
310
307
|
for (const { from, to, deco } of asisLineDecos) {
|
|
311
308
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -314,13 +311,10 @@ export class IdeDiff extends HTMLElement {
|
|
|
314
311
|
for (const { from, to, deco } of asisMarkDecos) {
|
|
315
312
|
asisMarkBuilder.add(from, to, deco);
|
|
316
313
|
}
|
|
317
|
-
|
|
318
|
-
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
319
314
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
320
315
|
add: asisMarkBuilder.finish().children
|
|
321
316
|
});
|
|
322
317
|
|
|
323
|
-
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
324
318
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
325
319
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
326
320
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -329,21 +323,18 @@ export class IdeDiff extends HTMLElement {
|
|
|
329
323
|
for (const { from, to, deco } of tobeMarkDecos) {
|
|
330
324
|
tobeMarkBuilder.add(from, to, deco);
|
|
331
325
|
}
|
|
332
|
-
|
|
333
|
-
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
334
326
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
335
327
|
add: tobeMarkBuilder.finish().children
|
|
336
328
|
});
|
|
337
329
|
|
|
338
|
-
// 데코레이션
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
effects: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
344
|
-
});
|
|
330
|
+
// ⭐️ 중요: 데코레이션 효과를 반환합니다. 여기서 직접 dispatch 하지 않습니다.
|
|
331
|
+
return {
|
|
332
|
+
asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
|
|
333
|
+
tobeEffect: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
334
|
+
};
|
|
345
335
|
};
|
|
346
336
|
|
|
337
|
+
// ⭐️ initialize 함수를 수정하여 텍스트 변경과 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
347
338
|
initialize = (src1, src2, language = 'javascript') => {
|
|
348
339
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
349
340
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -359,23 +350,26 @@ export class IdeDiff extends HTMLElement {
|
|
|
359
350
|
langExtension = javascript();
|
|
360
351
|
}
|
|
361
352
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
});
|
|
365
|
-
this.#tobeEditorView.dispatch({
|
|
366
|
-
effects: this.#languageCompartment.reconfigure(langExtension)
|
|
367
|
-
});
|
|
353
|
+
// 먼저 데코레이션 효과를 계산하여 가져옵니다.
|
|
354
|
+
const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
|
|
368
355
|
|
|
369
|
-
// 텍스트
|
|
356
|
+
// asis 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
370
357
|
this.#asisEditorView.dispatch({
|
|
371
|
-
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 }
|
|
358
|
+
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 },
|
|
359
|
+
effects: [
|
|
360
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
361
|
+
asisEffect // 계산된 데코레이션 효과를 포함
|
|
362
|
+
]
|
|
372
363
|
});
|
|
364
|
+
|
|
365
|
+
// tobe 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
373
366
|
this.#tobeEditorView.dispatch({
|
|
374
|
-
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 }
|
|
367
|
+
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 },
|
|
368
|
+
effects: [
|
|
369
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
370
|
+
tobeEffect // 계산된 데코레이션 효과를 포함
|
|
371
|
+
]
|
|
375
372
|
});
|
|
376
|
-
|
|
377
|
-
// Diff 데코레이션 적용
|
|
378
|
-
this.#applyDiffDecorations(src1, src2);
|
|
379
373
|
};
|
|
380
374
|
|
|
381
375
|
disconnectedCallback() {
|
package/package.json
CHANGED
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
EditorState, Compartment, StateField,
|
|
11
11
|
RangeSetBuilder,
|
|
12
|
-
StateEffect
|
|
12
|
+
StateEffect // StateEffect를 올바르게 임포트
|
|
13
13
|
} from "@codemirror/state";
|
|
14
14
|
import { history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
|
15
15
|
import { defaultKeymap, selectAll } from "@codemirror/commands";
|
|
16
16
|
import { searchKeymap, highlightSelectionMatches } from "@codemirror/search";
|
|
17
|
-
//
|
|
17
|
+
// 올바른 import 구문: '=>' 대신 'from'
|
|
18
18
|
import { bracketMatching } from "@codemirror/language";
|
|
19
19
|
import { javascript } from "@codemirror/lang-javascript";
|
|
20
20
|
import { indentOnInput, syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
|
|
@@ -22,11 +22,7 @@ import { lintKeymap } from "@codemirror/lint";
|
|
|
22
22
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
23
23
|
|
|
24
24
|
// Diff 로직을 위해 diff-match-patch 사용
|
|
25
|
-
import { diff_match_patch } from 'diff-match-patch';
|
|
26
|
-
|
|
27
|
-
// ... (나머지 코드는 동일) ...
|
|
28
|
-
|
|
29
|
-
// --- 여기서부터 수정된 부분 ---
|
|
25
|
+
import { diff_match_patch } from 'diff-match-patch'; // 올바른 패키지 이름: 하이픈 '-'
|
|
30
26
|
|
|
31
27
|
// Diff 데코레이션을 위한 StateField 정의 (asis 에디터용)
|
|
32
28
|
const asisDiffDecorations = StateField.define({
|
|
@@ -57,12 +53,10 @@ const tobeDiffDecorations = StateField.define({
|
|
|
57
53
|
});
|
|
58
54
|
|
|
59
55
|
// 데코레이션 업데이트를 위한 Effect (트랜잭션에 포함시켜 상태 변경 알림)
|
|
60
|
-
//
|
|
56
|
+
// StateEffect.define()을 사용하여 이펙트를 정의합니다.
|
|
61
57
|
const setAsisDecorationsEffect = StateEffect.define();
|
|
62
58
|
const setTobeDecorationsEffect = StateEffect.define();
|
|
63
59
|
|
|
64
|
-
// --- 여기까지 수정된 부분 ---
|
|
65
|
-
|
|
66
60
|
export class IdeDiff extends HTMLElement {
|
|
67
61
|
|
|
68
62
|
#asisEditorView;
|
|
@@ -216,6 +210,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
216
210
|
});
|
|
217
211
|
};
|
|
218
212
|
|
|
213
|
+
// ⭐️ #applyDiffDecorations 함수를 수정하여 Effect 객체를 반환하도록 변경
|
|
219
214
|
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
220
215
|
const dmp = new diff_match_patch();
|
|
221
216
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
@@ -243,8 +238,16 @@ export class IdeDiff extends HTMLElement {
|
|
|
243
238
|
let currentTobeLineOffset = tobeCursor;
|
|
244
239
|
const tobeLines = text.split('\n');
|
|
245
240
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
246
|
-
//
|
|
247
|
-
|
|
241
|
+
// 중요한 변경: line.from/to는 현재 에디터 뷰의 doc에서 가져옵니다.
|
|
242
|
+
// 이 함수는 initialize 내에서 텍스트 변경과 함께 호출되므로,
|
|
243
|
+
// 이 시점의 this.#tobeEditorView.state.doc은 아직 이전 내용일 수 있습니다.
|
|
244
|
+
// 그러나, Effect로 반환되어 트랜잭션에 포함될 때 CodeMirror는
|
|
245
|
+
// Effect를 처리하는 시점에 이미 텍스트가 업데이트되었음을 보장합니다.
|
|
246
|
+
// 따라서 여기서 doc.length로 유효성 검사하는 것은 새로운 src2 기준이어야 더 정확합니다.
|
|
247
|
+
// 하지만, 이 라인은 결국 새로운 doc에서 실행될 것이므로,
|
|
248
|
+
// 여기서의 this.#tobeEditorView.state.doc.length 검사는 불필요하거나 오해의 소지가 있습니다.
|
|
249
|
+
// 대신, tobeCursor + len (또는 currentTobeLineOffset)이 tobeSrc의 길이를 벗어나지 않는지 확인하는 것이 좋습니다.
|
|
250
|
+
if (currentTobeLineOffset < tobeSrc.length) { // src2 (새로운 텍스트)의 길이와 비교
|
|
248
251
|
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
249
252
|
tobeLineDecos.push({
|
|
250
253
|
from: line.from,
|
|
@@ -252,11 +255,8 @@ export class IdeDiff extends HTMLElement {
|
|
|
252
255
|
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
253
256
|
});
|
|
254
257
|
}
|
|
255
|
-
|
|
256
|
-
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
257
|
-
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
258
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
258
259
|
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
259
|
-
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
260
260
|
break;
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -274,8 +274,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
274
274
|
let currentAsisLineOffset = asisCursor;
|
|
275
275
|
const asisLines = text.split('\n');
|
|
276
276
|
for (let i = 0; i < asisLines.length; i++) {
|
|
277
|
-
|
|
278
|
-
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
277
|
+
if (currentAsisLineOffset < asisSrc.length) { // src1 (새로운 텍스트)의 길이와 비교
|
|
279
278
|
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
280
279
|
asisLineDecos.push({
|
|
281
280
|
from: line.from,
|
|
@@ -283,7 +282,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
283
282
|
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
284
283
|
});
|
|
285
284
|
}
|
|
286
|
-
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
285
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
287
286
|
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
288
287
|
break;
|
|
289
288
|
}
|
|
@@ -299,13 +298,11 @@ export class IdeDiff extends HTMLElement {
|
|
|
299
298
|
}
|
|
300
299
|
}
|
|
301
300
|
|
|
302
|
-
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
303
301
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
304
302
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
305
303
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
306
304
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
307
305
|
|
|
308
|
-
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
309
306
|
const asisLineBuilder = new RangeSetBuilder();
|
|
310
307
|
for (const { from, to, deco } of asisLineDecos) {
|
|
311
308
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -314,13 +311,10 @@ export class IdeDiff extends HTMLElement {
|
|
|
314
311
|
for (const { from, to, deco } of asisMarkDecos) {
|
|
315
312
|
asisMarkBuilder.add(from, to, deco);
|
|
316
313
|
}
|
|
317
|
-
|
|
318
|
-
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
319
314
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
320
315
|
add: asisMarkBuilder.finish().children
|
|
321
316
|
});
|
|
322
317
|
|
|
323
|
-
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
324
318
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
325
319
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
326
320
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -329,21 +323,18 @@ export class IdeDiff extends HTMLElement {
|
|
|
329
323
|
for (const { from, to, deco } of tobeMarkDecos) {
|
|
330
324
|
tobeMarkBuilder.add(from, to, deco);
|
|
331
325
|
}
|
|
332
|
-
|
|
333
|
-
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
334
326
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
335
327
|
add: tobeMarkBuilder.finish().children
|
|
336
328
|
});
|
|
337
329
|
|
|
338
|
-
// 데코레이션
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
effects: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
344
|
-
});
|
|
330
|
+
// ⭐️ 중요: 데코레이션 효과를 반환합니다. 여기서 직접 dispatch 하지 않습니다.
|
|
331
|
+
return {
|
|
332
|
+
asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
|
|
333
|
+
tobeEffect: setTobeDecorationsEffect.of(finalTobeDecorations)
|
|
334
|
+
};
|
|
345
335
|
};
|
|
346
336
|
|
|
337
|
+
// ⭐️ initialize 함수를 수정하여 텍스트 변경과 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
347
338
|
initialize = (src1, src2, language = 'javascript') => {
|
|
348
339
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
349
340
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -359,23 +350,26 @@ export class IdeDiff extends HTMLElement {
|
|
|
359
350
|
langExtension = javascript();
|
|
360
351
|
}
|
|
361
352
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
});
|
|
365
|
-
this.#tobeEditorView.dispatch({
|
|
366
|
-
effects: this.#languageCompartment.reconfigure(langExtension)
|
|
367
|
-
});
|
|
353
|
+
// 먼저 데코레이션 효과를 계산하여 가져옵니다.
|
|
354
|
+
const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
|
|
368
355
|
|
|
369
|
-
// 텍스트
|
|
356
|
+
// asis 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
370
357
|
this.#asisEditorView.dispatch({
|
|
371
|
-
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 }
|
|
358
|
+
changes: { from: 0, to: this.#asisEditorView.state.doc.length, insert: src1 },
|
|
359
|
+
effects: [
|
|
360
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
361
|
+
asisEffect // 계산된 데코레이션 효과를 포함
|
|
362
|
+
]
|
|
372
363
|
});
|
|
364
|
+
|
|
365
|
+
// tobe 에디터의 텍스트 변경 및 데코레이션 효과를 단일 트랜잭션으로 디스패치합니다.
|
|
373
366
|
this.#tobeEditorView.dispatch({
|
|
374
|
-
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 }
|
|
367
|
+
changes: { from: 0, to: this.#tobeEditorView.state.doc.length, insert: src2 },
|
|
368
|
+
effects: [
|
|
369
|
+
this.#languageCompartment.reconfigure(langExtension),
|
|
370
|
+
tobeEffect // 계산된 데코레이션 효과를 포함
|
|
371
|
+
]
|
|
375
372
|
});
|
|
376
|
-
|
|
377
|
-
// Diff 데코레이션 적용
|
|
378
|
-
this.#applyDiffDecorations(src1, src2);
|
|
379
373
|
};
|
|
380
374
|
|
|
381
375
|
disconnectedCallback() {
|