ide-assi 0.344.0 → 0.345.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 -30
- package/dist/bundle.esm.js +36 -30
- package/dist/components/ideDiff.js +36 -30
- package/package.json +1 -1
- package/src/components/ideDiff.js +36 -30
package/dist/bundle.cjs.js
CHANGED
|
@@ -234948,7 +234948,6 @@ class IdeDiff extends HTMLElement {
|
|
|
234948
234948
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
234949
234949
|
dmp.diff_cleanupSemantic(diffs);
|
|
234950
234950
|
|
|
234951
|
-
// Separate collections for line decorations and mark decorations
|
|
234952
234951
|
const asisLineDecos = [];
|
|
234953
234952
|
const asisMarkDecos = [];
|
|
234954
234953
|
const tobeLineDecos = [];
|
|
@@ -234962,48 +234961,59 @@ class IdeDiff extends HTMLElement {
|
|
|
234962
234961
|
|
|
234963
234962
|
switch (op) {
|
|
234964
234963
|
case diffMatchPatchExports.diff_match_patch.DIFF_INSERT: // Added text
|
|
234965
|
-
// Inline mark decoration for tobe
|
|
234966
234964
|
tobeMarkDecos.push({
|
|
234967
234965
|
from: tobeCursor,
|
|
234968
234966
|
to: tobeCursor + len,
|
|
234969
234967
|
deco: Decoration.mark({ class: "cm-inserted-inline" })
|
|
234970
234968
|
});
|
|
234971
234969
|
|
|
234972
|
-
// Line background decoration for tobe (for each line in the inserted text)
|
|
234973
234970
|
let currentTobeLineOffset = tobeCursor;
|
|
234974
234971
|
const tobeLines = text.split('\n');
|
|
234975
234972
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
234976
|
-
|
|
234977
|
-
|
|
234978
|
-
|
|
234979
|
-
|
|
234980
|
-
|
|
234981
|
-
|
|
234982
|
-
|
|
234973
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
234974
|
+
if (currentTobeLineOffset < this.#tobeEditorView.state.doc.length) {
|
|
234975
|
+
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
234976
|
+
tobeLineDecos.push({
|
|
234977
|
+
from: line.from,
|
|
234978
|
+
to: line.to,
|
|
234979
|
+
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
234980
|
+
});
|
|
234981
|
+
}
|
|
234982
|
+
// 다음 줄의 시작 위치 계산. 마지막 줄이 아니면 +1 (개행문자)
|
|
234983
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
234984
|
+
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
234985
|
+
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
234986
|
+
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
234987
|
+
break;
|
|
234988
|
+
}
|
|
234983
234989
|
}
|
|
234984
234990
|
|
|
234985
234991
|
tobeCursor += len;
|
|
234986
234992
|
break;
|
|
234987
234993
|
|
|
234988
234994
|
case diffMatchPatchExports.diff_match_patch.DIFF_DELETE: // Deleted text
|
|
234989
|
-
// Inline mark decoration for asis
|
|
234990
234995
|
asisMarkDecos.push({
|
|
234991
234996
|
from: asisCursor,
|
|
234992
234997
|
to: asisCursor + len,
|
|
234993
234998
|
deco: Decoration.mark({ class: "cm-deleted-inline" })
|
|
234994
234999
|
});
|
|
234995
235000
|
|
|
234996
|
-
// Line background decoration for asis (for each line in the deleted text)
|
|
234997
235001
|
let currentAsisLineOffset = asisCursor;
|
|
234998
235002
|
const asisLines = text.split('\n');
|
|
234999
235003
|
for (let i = 0; i < asisLines.length; i++) {
|
|
235000
|
-
|
|
235001
|
-
|
|
235002
|
-
|
|
235003
|
-
|
|
235004
|
-
|
|
235005
|
-
|
|
235006
|
-
|
|
235004
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
235005
|
+
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
235006
|
+
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
235007
|
+
asisLineDecos.push({
|
|
235008
|
+
from: line.from,
|
|
235009
|
+
to: line.to,
|
|
235010
|
+
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
235011
|
+
});
|
|
235012
|
+
}
|
|
235013
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
235014
|
+
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
235015
|
+
break;
|
|
235016
|
+
}
|
|
235007
235017
|
}
|
|
235008
235018
|
|
|
235009
235019
|
asisCursor += len;
|
|
@@ -235016,14 +235026,13 @@ class IdeDiff extends HTMLElement {
|
|
|
235016
235026
|
}
|
|
235017
235027
|
}
|
|
235018
235028
|
|
|
235019
|
-
// Sort all collections by 'from' position
|
|
235020
|
-
// Although separating builders helps, sorting is still a good practice.
|
|
235029
|
+
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
235021
235030
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
235022
235031
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
235023
235032
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
235024
235033
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
235025
235034
|
|
|
235026
|
-
//
|
|
235035
|
+
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235027
235036
|
const asisLineBuilder = new RangeSetBuilder();
|
|
235028
235037
|
for (const { from, to, deco } of asisLineDecos) {
|
|
235029
235038
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -235033,14 +235042,12 @@ class IdeDiff extends HTMLElement {
|
|
|
235033
235042
|
asisMarkBuilder.add(from, to, deco);
|
|
235034
235043
|
}
|
|
235035
235044
|
|
|
235036
|
-
//
|
|
235037
|
-
// The `RangeSet.join()` static method is used to combine multiple RangeSets.
|
|
235045
|
+
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
235038
235046
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
235039
|
-
add: asisMarkBuilder.finish().children
|
|
235047
|
+
add: asisMarkBuilder.finish().children
|
|
235040
235048
|
});
|
|
235041
235049
|
|
|
235042
|
-
|
|
235043
|
-
// Build separate RangeSets for lines and marks for TOBE editor
|
|
235050
|
+
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235044
235051
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
235045
235052
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
235046
235053
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -235050,13 +235057,12 @@ class IdeDiff extends HTMLElement {
|
|
|
235050
235057
|
tobeMarkBuilder.add(from, to, deco);
|
|
235051
235058
|
}
|
|
235052
235059
|
|
|
235053
|
-
//
|
|
235060
|
+
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
235054
235061
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
235055
235062
|
add: tobeMarkBuilder.finish().children
|
|
235056
235063
|
});
|
|
235057
235064
|
|
|
235058
|
-
|
|
235059
|
-
// Dispatch effects to update decorations
|
|
235065
|
+
// 데코레이션 업데이트를 위한 Effect 디스패치
|
|
235060
235066
|
this.#asisEditorView.dispatch({
|
|
235061
235067
|
effects: setAsisDecorationsEffect.of(finalAsisDecorations)
|
|
235062
235068
|
});
|
package/dist/bundle.esm.js
CHANGED
|
@@ -234944,7 +234944,6 @@ class IdeDiff extends HTMLElement {
|
|
|
234944
234944
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
234945
234945
|
dmp.diff_cleanupSemantic(diffs);
|
|
234946
234946
|
|
|
234947
|
-
// Separate collections for line decorations and mark decorations
|
|
234948
234947
|
const asisLineDecos = [];
|
|
234949
234948
|
const asisMarkDecos = [];
|
|
234950
234949
|
const tobeLineDecos = [];
|
|
@@ -234958,48 +234957,59 @@ class IdeDiff extends HTMLElement {
|
|
|
234958
234957
|
|
|
234959
234958
|
switch (op) {
|
|
234960
234959
|
case diffMatchPatchExports.diff_match_patch.DIFF_INSERT: // Added text
|
|
234961
|
-
// Inline mark decoration for tobe
|
|
234962
234960
|
tobeMarkDecos.push({
|
|
234963
234961
|
from: tobeCursor,
|
|
234964
234962
|
to: tobeCursor + len,
|
|
234965
234963
|
deco: Decoration.mark({ class: "cm-inserted-inline" })
|
|
234966
234964
|
});
|
|
234967
234965
|
|
|
234968
|
-
// Line background decoration for tobe (for each line in the inserted text)
|
|
234969
234966
|
let currentTobeLineOffset = tobeCursor;
|
|
234970
234967
|
const tobeLines = text.split('\n');
|
|
234971
234968
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
234972
|
-
|
|
234973
|
-
|
|
234974
|
-
|
|
234975
|
-
|
|
234976
|
-
|
|
234977
|
-
|
|
234978
|
-
|
|
234969
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
234970
|
+
if (currentTobeLineOffset < this.#tobeEditorView.state.doc.length) {
|
|
234971
|
+
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
234972
|
+
tobeLineDecos.push({
|
|
234973
|
+
from: line.from,
|
|
234974
|
+
to: line.to,
|
|
234975
|
+
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
234976
|
+
});
|
|
234977
|
+
}
|
|
234978
|
+
// 다음 줄의 시작 위치 계산. 마지막 줄이 아니면 +1 (개행문자)
|
|
234979
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
234980
|
+
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
234981
|
+
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
234982
|
+
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
234983
|
+
break;
|
|
234984
|
+
}
|
|
234979
234985
|
}
|
|
234980
234986
|
|
|
234981
234987
|
tobeCursor += len;
|
|
234982
234988
|
break;
|
|
234983
234989
|
|
|
234984
234990
|
case diffMatchPatchExports.diff_match_patch.DIFF_DELETE: // Deleted text
|
|
234985
|
-
// Inline mark decoration for asis
|
|
234986
234991
|
asisMarkDecos.push({
|
|
234987
234992
|
from: asisCursor,
|
|
234988
234993
|
to: asisCursor + len,
|
|
234989
234994
|
deco: Decoration.mark({ class: "cm-deleted-inline" })
|
|
234990
234995
|
});
|
|
234991
234996
|
|
|
234992
|
-
// Line background decoration for asis (for each line in the deleted text)
|
|
234993
234997
|
let currentAsisLineOffset = asisCursor;
|
|
234994
234998
|
const asisLines = text.split('\n');
|
|
234995
234999
|
for (let i = 0; i < asisLines.length; i++) {
|
|
234996
|
-
|
|
234997
|
-
|
|
234998
|
-
|
|
234999
|
-
|
|
235000
|
-
|
|
235001
|
-
|
|
235002
|
-
|
|
235000
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
235001
|
+
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
235002
|
+
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
235003
|
+
asisLineDecos.push({
|
|
235004
|
+
from: line.from,
|
|
235005
|
+
to: line.to,
|
|
235006
|
+
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
235007
|
+
});
|
|
235008
|
+
}
|
|
235009
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
235010
|
+
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
235011
|
+
break;
|
|
235012
|
+
}
|
|
235003
235013
|
}
|
|
235004
235014
|
|
|
235005
235015
|
asisCursor += len;
|
|
@@ -235012,14 +235022,13 @@ class IdeDiff extends HTMLElement {
|
|
|
235012
235022
|
}
|
|
235013
235023
|
}
|
|
235014
235024
|
|
|
235015
|
-
// Sort all collections by 'from' position
|
|
235016
|
-
// Although separating builders helps, sorting is still a good practice.
|
|
235025
|
+
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
235017
235026
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
235018
235027
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
235019
235028
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
235020
235029
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
235021
235030
|
|
|
235022
|
-
//
|
|
235031
|
+
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235023
235032
|
const asisLineBuilder = new RangeSetBuilder();
|
|
235024
235033
|
for (const { from, to, deco } of asisLineDecos) {
|
|
235025
235034
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -235029,14 +235038,12 @@ class IdeDiff extends HTMLElement {
|
|
|
235029
235038
|
asisMarkBuilder.add(from, to, deco);
|
|
235030
235039
|
}
|
|
235031
235040
|
|
|
235032
|
-
//
|
|
235033
|
-
// The `RangeSet.join()` static method is used to combine multiple RangeSets.
|
|
235041
|
+
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
235034
235042
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
235035
|
-
add: asisMarkBuilder.finish().children
|
|
235043
|
+
add: asisMarkBuilder.finish().children
|
|
235036
235044
|
});
|
|
235037
235045
|
|
|
235038
|
-
|
|
235039
|
-
// Build separate RangeSets for lines and marks for TOBE editor
|
|
235046
|
+
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
235040
235047
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
235041
235048
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
235042
235049
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -235046,13 +235053,12 @@ class IdeDiff extends HTMLElement {
|
|
|
235046
235053
|
tobeMarkBuilder.add(from, to, deco);
|
|
235047
235054
|
}
|
|
235048
235055
|
|
|
235049
|
-
//
|
|
235056
|
+
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
235050
235057
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
235051
235058
|
add: tobeMarkBuilder.finish().children
|
|
235052
235059
|
});
|
|
235053
235060
|
|
|
235054
|
-
|
|
235055
|
-
// Dispatch effects to update decorations
|
|
235061
|
+
// 데코레이션 업데이트를 위한 Effect 디스패치
|
|
235056
235062
|
this.#asisEditorView.dispatch({
|
|
235057
235063
|
effects: setAsisDecorationsEffect.of(finalAsisDecorations)
|
|
235058
235064
|
});
|
|
@@ -221,7 +221,6 @@ export class IdeDiff extends HTMLElement {
|
|
|
221
221
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
222
222
|
dmp.diff_cleanupSemantic(diffs);
|
|
223
223
|
|
|
224
|
-
// Separate collections for line decorations and mark decorations
|
|
225
224
|
const asisLineDecos = [];
|
|
226
225
|
const asisMarkDecos = [];
|
|
227
226
|
const tobeLineDecos = [];
|
|
@@ -235,48 +234,59 @@ export class IdeDiff extends HTMLElement {
|
|
|
235
234
|
|
|
236
235
|
switch (op) {
|
|
237
236
|
case diff_match_patch.DIFF_INSERT: // Added text
|
|
238
|
-
// Inline mark decoration for tobe
|
|
239
237
|
tobeMarkDecos.push({
|
|
240
238
|
from: tobeCursor,
|
|
241
239
|
to: tobeCursor + len,
|
|
242
240
|
deco: Decoration.mark({ class: "cm-inserted-inline" })
|
|
243
241
|
});
|
|
244
242
|
|
|
245
|
-
// Line background decoration for tobe (for each line in the inserted text)
|
|
246
243
|
let currentTobeLineOffset = tobeCursor;
|
|
247
244
|
const tobeLines = text.split('\n');
|
|
248
245
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
246
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
247
|
+
if (currentTobeLineOffset < this.#tobeEditorView.state.doc.length) {
|
|
248
|
+
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
249
|
+
tobeLineDecos.push({
|
|
250
|
+
from: line.from,
|
|
251
|
+
to: line.to,
|
|
252
|
+
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
// 다음 줄의 시작 위치 계산. 마지막 줄이 아니면 +1 (개행문자)
|
|
256
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
257
|
+
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
258
|
+
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
259
|
+
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
tobeCursor += len;
|
|
259
265
|
break;
|
|
260
266
|
|
|
261
267
|
case diff_match_patch.DIFF_DELETE: // Deleted text
|
|
262
|
-
// Inline mark decoration for asis
|
|
263
268
|
asisMarkDecos.push({
|
|
264
269
|
from: asisCursor,
|
|
265
270
|
to: asisCursor + len,
|
|
266
271
|
deco: Decoration.mark({ class: "cm-deleted-inline" })
|
|
267
272
|
});
|
|
268
273
|
|
|
269
|
-
// Line background decoration for asis (for each line in the deleted text)
|
|
270
274
|
let currentAsisLineOffset = asisCursor;
|
|
271
275
|
const asisLines = text.split('\n');
|
|
272
276
|
for (let i = 0; i < asisLines.length; i++) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
277
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
278
|
+
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
279
|
+
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
280
|
+
asisLineDecos.push({
|
|
281
|
+
from: line.from,
|
|
282
|
+
to: line.to,
|
|
283
|
+
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
287
|
+
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
280
290
|
}
|
|
281
291
|
|
|
282
292
|
asisCursor += len;
|
|
@@ -289,14 +299,13 @@ export class IdeDiff extends HTMLElement {
|
|
|
289
299
|
}
|
|
290
300
|
}
|
|
291
301
|
|
|
292
|
-
// Sort all collections by 'from' position
|
|
293
|
-
// Although separating builders helps, sorting is still a good practice.
|
|
302
|
+
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
294
303
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
295
304
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
296
305
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
297
306
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
298
307
|
|
|
299
|
-
//
|
|
308
|
+
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
300
309
|
const asisLineBuilder = new RangeSetBuilder();
|
|
301
310
|
for (const { from, to, deco } of asisLineDecos) {
|
|
302
311
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -306,14 +315,12 @@ export class IdeDiff extends HTMLElement {
|
|
|
306
315
|
asisMarkBuilder.add(from, to, deco);
|
|
307
316
|
}
|
|
308
317
|
|
|
309
|
-
//
|
|
310
|
-
// The `RangeSet.join()` static method is used to combine multiple RangeSets.
|
|
318
|
+
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
311
319
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
312
|
-
add: asisMarkBuilder.finish().children
|
|
320
|
+
add: asisMarkBuilder.finish().children
|
|
313
321
|
});
|
|
314
322
|
|
|
315
|
-
|
|
316
|
-
// Build separate RangeSets for lines and marks for TOBE editor
|
|
323
|
+
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
317
324
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
318
325
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
319
326
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -323,13 +330,12 @@ export class IdeDiff extends HTMLElement {
|
|
|
323
330
|
tobeMarkBuilder.add(from, to, deco);
|
|
324
331
|
}
|
|
325
332
|
|
|
326
|
-
//
|
|
333
|
+
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
327
334
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
328
335
|
add: tobeMarkBuilder.finish().children
|
|
329
336
|
});
|
|
330
337
|
|
|
331
|
-
|
|
332
|
-
// Dispatch effects to update decorations
|
|
338
|
+
// 데코레이션 업데이트를 위한 Effect 디스패치
|
|
333
339
|
this.#asisEditorView.dispatch({
|
|
334
340
|
effects: setAsisDecorationsEffect.of(finalAsisDecorations)
|
|
335
341
|
});
|
package/package.json
CHANGED
|
@@ -221,7 +221,6 @@ export class IdeDiff extends HTMLElement {
|
|
|
221
221
|
const diffs = dmp.diff_main(asisSrc, tobeSrc);
|
|
222
222
|
dmp.diff_cleanupSemantic(diffs);
|
|
223
223
|
|
|
224
|
-
// Separate collections for line decorations and mark decorations
|
|
225
224
|
const asisLineDecos = [];
|
|
226
225
|
const asisMarkDecos = [];
|
|
227
226
|
const tobeLineDecos = [];
|
|
@@ -235,48 +234,59 @@ export class IdeDiff extends HTMLElement {
|
|
|
235
234
|
|
|
236
235
|
switch (op) {
|
|
237
236
|
case diff_match_patch.DIFF_INSERT: // Added text
|
|
238
|
-
// Inline mark decoration for tobe
|
|
239
237
|
tobeMarkDecos.push({
|
|
240
238
|
from: tobeCursor,
|
|
241
239
|
to: tobeCursor + len,
|
|
242
240
|
deco: Decoration.mark({ class: "cm-inserted-inline" })
|
|
243
241
|
});
|
|
244
242
|
|
|
245
|
-
// Line background decoration for tobe (for each line in the inserted text)
|
|
246
243
|
let currentTobeLineOffset = tobeCursor;
|
|
247
244
|
const tobeLines = text.split('\n');
|
|
248
245
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
246
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
247
|
+
if (currentTobeLineOffset < this.#tobeEditorView.state.doc.length) {
|
|
248
|
+
const line = this.#tobeEditorView.state.doc.lineAt(currentTobeLineOffset);
|
|
249
|
+
tobeLineDecos.push({
|
|
250
|
+
from: line.from,
|
|
251
|
+
to: line.to,
|
|
252
|
+
deco: Decoration.line({ class: "cm-inserted-line-bg" })
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
// 다음 줄의 시작 위치 계산. 마지막 줄이 아니면 +1 (개행문자)
|
|
256
|
+
currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length -1 ? 1 : 0);
|
|
257
|
+
// 만약 마지막 줄이 비어있다면, 더 이상 진행하지 않도록 방지
|
|
258
|
+
if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
259
|
+
// 마지막 줄이 빈 줄이고 텍스트가 개행으로 끝나지 않으면 (오프셋이 더 이상 증가할 필요 없음)
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
tobeCursor += len;
|
|
259
265
|
break;
|
|
260
266
|
|
|
261
267
|
case diff_match_patch.DIFF_DELETE: // Deleted text
|
|
262
|
-
// Inline mark decoration for asis
|
|
263
268
|
asisMarkDecos.push({
|
|
264
269
|
from: asisCursor,
|
|
265
270
|
to: asisCursor + len,
|
|
266
271
|
deco: Decoration.mark({ class: "cm-deleted-inline" })
|
|
267
272
|
});
|
|
268
273
|
|
|
269
|
-
// Line background decoration for asis (for each line in the deleted text)
|
|
270
274
|
let currentAsisLineOffset = asisCursor;
|
|
271
275
|
const asisLines = text.split('\n');
|
|
272
276
|
for (let i = 0; i < asisLines.length; i++) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
277
|
+
// ⭐️ 중요: lineAt() 호출 전에 유효한 문서 범위 내에 있는지 확인
|
|
278
|
+
if (currentAsisLineOffset < this.#asisEditorView.state.doc.length) {
|
|
279
|
+
const line = this.#asisEditorView.state.doc.lineAt(currentAsisLineOffset);
|
|
280
|
+
asisLineDecos.push({
|
|
281
|
+
from: line.from,
|
|
282
|
+
to: line.to,
|
|
283
|
+
deco: Decoration.line({ class: "cm-deleted-line-bg" })
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
currentAsisLineOffset += asisLines[i].length + (i < asisLines.length -1 ? 1 : 0);
|
|
287
|
+
if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
280
290
|
}
|
|
281
291
|
|
|
282
292
|
asisCursor += len;
|
|
@@ -289,14 +299,13 @@ export class IdeDiff extends HTMLElement {
|
|
|
289
299
|
}
|
|
290
300
|
}
|
|
291
301
|
|
|
292
|
-
// Sort all collections by 'from' position
|
|
293
|
-
// Although separating builders helps, sorting is still a good practice.
|
|
302
|
+
// Sort all collections by 'from' position (항상 좋은 습관)
|
|
294
303
|
asisLineDecos.sort((a, b) => a.from - b.from);
|
|
295
304
|
asisMarkDecos.sort((a, b) => a.from - b.from);
|
|
296
305
|
tobeLineDecos.sort((a, b) => a.from - b.from);
|
|
297
306
|
tobeMarkDecos.sort((a, b) => a.from - b.from);
|
|
298
307
|
|
|
299
|
-
//
|
|
308
|
+
// ASIS 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
300
309
|
const asisLineBuilder = new RangeSetBuilder();
|
|
301
310
|
for (const { from, to, deco } of asisLineDecos) {
|
|
302
311
|
asisLineBuilder.add(from, to, deco);
|
|
@@ -306,14 +315,12 @@ export class IdeDiff extends HTMLElement {
|
|
|
306
315
|
asisMarkBuilder.add(from, to, deco);
|
|
307
316
|
}
|
|
308
317
|
|
|
309
|
-
//
|
|
310
|
-
// The `RangeSet.join()` static method is used to combine multiple RangeSets.
|
|
318
|
+
// ASIS 에디터용 줄 및 마크 RangeSet 결합
|
|
311
319
|
const finalAsisDecorations = asisLineBuilder.finish().update({
|
|
312
|
-
add: asisMarkBuilder.finish().children
|
|
320
|
+
add: asisMarkBuilder.finish().children
|
|
313
321
|
});
|
|
314
322
|
|
|
315
|
-
|
|
316
|
-
// Build separate RangeSets for lines and marks for TOBE editor
|
|
323
|
+
// TOBE 에디터용 줄 및 마크 데코레이션을 위한 별도 RangeSetBuilder 생성
|
|
317
324
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
318
325
|
for (const { from, to, deco } of tobeLineDecos) {
|
|
319
326
|
tobeLineBuilder.add(from, to, deco);
|
|
@@ -323,13 +330,12 @@ export class IdeDiff extends HTMLElement {
|
|
|
323
330
|
tobeMarkBuilder.add(from, to, deco);
|
|
324
331
|
}
|
|
325
332
|
|
|
326
|
-
//
|
|
333
|
+
// TOBE 에디터용 줄 및 마크 RangeSet 결합
|
|
327
334
|
const finalTobeDecorations = tobeLineBuilder.finish().update({
|
|
328
335
|
add: tobeMarkBuilder.finish().children
|
|
329
336
|
});
|
|
330
337
|
|
|
331
|
-
|
|
332
|
-
// Dispatch effects to update decorations
|
|
338
|
+
// 데코레이션 업데이트를 위한 Effect 디스패치
|
|
333
339
|
this.#asisEditorView.dispatch({
|
|
334
340
|
effects: setAsisDecorationsEffect.of(finalAsisDecorations)
|
|
335
341
|
});
|