ide-assi 0.434.0 → 0.436.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 +120 -1
- package/dist/bundle.esm.js +120 -1
- package/dist/components/ideDiff.js +121 -2
- package/package.json +1 -1
- package/src/components/ideDiff.js +121 -2
package/dist/bundle.cjs.js
CHANGED
|
@@ -234970,7 +234970,7 @@ class IdeDiff extends HTMLElement {
|
|
|
234970
234970
|
extensions: [
|
|
234971
234971
|
basicExtensions,
|
|
234972
234972
|
this.#languageCompartment.of(javascript()), // 초기 언어 설정
|
|
234973
|
-
EditorState.readOnly.of(true),
|
|
234973
|
+
//EditorState.readOnly.of(true),
|
|
234974
234974
|
tobeDiffDecorations, // TOBE Diff 데코레이션 필드
|
|
234975
234975
|
EditorView.updateListener.of((update) => {
|
|
234976
234976
|
if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
|
|
@@ -235065,9 +235065,17 @@ class IdeDiff extends HTMLElement {
|
|
|
235065
235065
|
const deletedLineDeco = Decoration.line({ class: "cm-deleted-line-bg" });
|
|
235066
235066
|
// const changedLineDeco = Decoration.line({ class: "cm-changed-line-bg" }); // 필요하다면
|
|
235067
235067
|
|
|
235068
|
+
// ⭐️ IdeDiff 인스턴스에 대한 참조를 위젯에 넘겨주기 위해 임시 변수 사용
|
|
235069
|
+
// 실제로는 Closure나 Bound method로 넘겨줄 수 있음
|
|
235070
|
+
const currentInstance = this;
|
|
235071
|
+
|
|
235068
235072
|
for (const [op, text] of diffs) {
|
|
235069
235073
|
const len = text.length;
|
|
235070
235074
|
|
|
235075
|
+
// ⭐️ 해당 diff 청크의 시작 오프셋을 저장 (버튼 위젯 위치 결정용)
|
|
235076
|
+
const currentAsisOffset = asisCursor;
|
|
235077
|
+
const currentTobeOffset = tobeCursor;
|
|
235078
|
+
|
|
235071
235079
|
switch (op) {
|
|
235072
235080
|
case diffMatchPatchExports.diff_match_patch.DIFF_INSERT:
|
|
235073
235081
|
console.log(diffMatchPatchExports.diff_match_patch.DIFF_INSERT, text);
|
|
@@ -235086,6 +235094,22 @@ class IdeDiff extends HTMLElement {
|
|
|
235086
235094
|
}
|
|
235087
235095
|
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
235088
235096
|
}
|
|
235097
|
+
|
|
235098
|
+
tobeLineBuilder.add(
|
|
235099
|
+
currentTobeOffset, // 이 Diff 청크의 시작 오프셋
|
|
235100
|
+
currentTobeOffset,
|
|
235101
|
+
Decoration.widget({
|
|
235102
|
+
widget: // #applyDiffDecorations 내 MergeButtonWidget 생성 시
|
|
235103
|
+
new MergeButtonWidget(
|
|
235104
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
235105
|
+
text, // 적용할 텍스트
|
|
235106
|
+
currentInstance.#tobeEditorView, // 적용 대상 에디터
|
|
235107
|
+
{ from: currentAsisOffset, to: currentAsisOffset + text.length }, // ⭐️ diffRange 전달
|
|
235108
|
+
currentInstance // ⭐️ IdeDiff 인스턴스 전달
|
|
235109
|
+
),
|
|
235110
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
235111
|
+
})
|
|
235112
|
+
);
|
|
235089
235113
|
break;
|
|
235090
235114
|
|
|
235091
235115
|
case diffMatchPatchExports.diff_match_patch.DIFF_DELETE:
|
|
@@ -235097,6 +235121,21 @@ class IdeDiff extends HTMLElement {
|
|
|
235097
235121
|
}
|
|
235098
235122
|
asisCursor += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
235099
235123
|
}
|
|
235124
|
+
|
|
235125
|
+
// ⭐️ ASIS 에디터에서 삭제된 청크의 경우, ASIS 쪽에 적용 버튼 (TOBE로 적용) 추가
|
|
235126
|
+
asisLineBuilder.add(
|
|
235127
|
+
currentAsisOffset, // 이 Diff 청크의 시작 오프셋
|
|
235128
|
+
currentAsisOffset,
|
|
235129
|
+
Decoration.widget({
|
|
235130
|
+
widget: new MergeButtonWidget(
|
|
235131
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
235132
|
+
text, // 적용할 텍스트 (이 경우 ASIS에서 가져올 내용)
|
|
235133
|
+
currentInstance.#tobeEditorView // 적용 대상은 TOBE 에디터
|
|
235134
|
+
),
|
|
235135
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
235136
|
+
})
|
|
235137
|
+
);
|
|
235138
|
+
|
|
235100
235139
|
break;
|
|
235101
235140
|
|
|
235102
235141
|
case diffMatchPatchExports.diff_match_patch.DIFF_EQUAL:
|
|
@@ -235116,6 +235155,21 @@ class IdeDiff extends HTMLElement {
|
|
|
235116
235155
|
};
|
|
235117
235156
|
};
|
|
235118
235157
|
|
|
235158
|
+
// IdeDiff 클래스 내부에 변경 후 Diff를 다시 계산하는 메서드 추가
|
|
235159
|
+
recalculateDiff = () => {
|
|
235160
|
+
const asisDoc = this.#asisEditorView.state.doc.toString();
|
|
235161
|
+
const tobeDoc = this.#tobeEditorView.state.doc.toString();
|
|
235162
|
+
|
|
235163
|
+
const { asisDecorations, tobeDecorations } = this.#applyDiffDecorations(asisDoc, tobeDoc);
|
|
235164
|
+
|
|
235165
|
+
this.#asisEditorView.dispatch({
|
|
235166
|
+
effects: [setAsisDecorationsEffect.of(asisDecorations)]
|
|
235167
|
+
});
|
|
235168
|
+
this.#tobeEditorView.dispatch({
|
|
235169
|
+
effects: [setTobeDecorationsEffect.of(tobeDecorations)]
|
|
235170
|
+
});
|
|
235171
|
+
};
|
|
235172
|
+
|
|
235119
235173
|
initialize = (src1, src2, language = 'javascript') => {
|
|
235120
235174
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
235121
235175
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -235164,6 +235218,71 @@ class IdeDiff extends HTMLElement {
|
|
|
235164
235218
|
};
|
|
235165
235219
|
}
|
|
235166
235220
|
|
|
235221
|
+
// IdeDiff 클래스 외부 (파일 상단 or 하단)에 추가
|
|
235222
|
+
class MergeButtonWidget extends WidgetType {
|
|
235223
|
+
constructor(isAsis, textToApply, targetEditorView, diffRange, hostComponent) {
|
|
235224
|
+
super();
|
|
235225
|
+
this.isAsis = isAsis; // ASIS 쪽 버튼인지 (true) TOBE 쪽 버튼인지 (false)
|
|
235226
|
+
this.textToApply = textToApply; // 적용할 텍스트
|
|
235227
|
+
this.targetEditorView = targetEditorView; // 텍스트를 적용할 에디터 뷰
|
|
235228
|
+
this.diffRange = diffRange; // ⭐️ 추가된 속성
|
|
235229
|
+
this.hostComponent = hostComponent; // ⭐️ IdeDiff 인스턴스 참조
|
|
235230
|
+
}
|
|
235231
|
+
|
|
235232
|
+
// 위젯이 차지할 공간을 텍스트 줄에 할당할지 여부. false로 설정하여 버튼이 줄 사이에 끼어들지 않도록 함.
|
|
235233
|
+
eq(other) { return false; }
|
|
235234
|
+
|
|
235235
|
+
// 위젯의 DOM 요소를 생성합니다.
|
|
235236
|
+
toDOM(view) {
|
|
235237
|
+
const button = document.createElement("button");
|
|
235238
|
+
button.className = `cm-merge-button ${this.isAsis ? 'accept' : 'revert'}`;
|
|
235239
|
+
button.textContent = this.isAsis ? "→ 적용" : "← 되돌리기"; // 버튼 텍스트
|
|
235240
|
+
|
|
235241
|
+
// 클릭 이벤트 핸들러
|
|
235242
|
+
button.addEventListener("click", () => {
|
|
235243
|
+
// 이 로직은 나중에 구현할 `applyChanges` 메서드를 호출할 것입니다.
|
|
235244
|
+
// 지금은 콘솔에 로그만 남깁니다.
|
|
235245
|
+
console.log(`버튼 클릭: ${this.isAsis ? 'ASIS -> TOBE' : 'TOBE -> ASIS'}`, this.textToApply);
|
|
235246
|
+
|
|
235247
|
+
// 실제 변경 로직 (아래 applyChanges 메서드 구현 후 주석 해제)
|
|
235248
|
+
this.applyChanges(this.textToApply, this.targetEditorView);
|
|
235249
|
+
});
|
|
235250
|
+
|
|
235251
|
+
const container = document.createElement("div");
|
|
235252
|
+
container.className = "cm-merge-button-container";
|
|
235253
|
+
container.appendChild(button);
|
|
235254
|
+
return container;
|
|
235255
|
+
}
|
|
235256
|
+
|
|
235257
|
+
// 실제 변경 적용 로직
|
|
235258
|
+
applyChanges(text, editorView) {
|
|
235259
|
+
if (!editorView || !this.diffRange) {
|
|
235260
|
+
console.error("Target editor view or diffRange is undefined.");
|
|
235261
|
+
return;
|
|
235262
|
+
}
|
|
235263
|
+
|
|
235264
|
+
// ⭐️ 해당 오프셋 범위의 내용을 교체 (삽입 또는 삭제)
|
|
235265
|
+
editorView.dispatch({
|
|
235266
|
+
changes: {
|
|
235267
|
+
from: this.diffRange.from,
|
|
235268
|
+
to: this.diffRange.to, // 삭제될 범위
|
|
235269
|
+
insert: text // 삽입될 내용
|
|
235270
|
+
}
|
|
235271
|
+
});
|
|
235272
|
+
|
|
235273
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트해야 합니다.
|
|
235274
|
+
// this.hostComponent.recalculateDiff(); 와 같은 메서드를 호출해야 함.
|
|
235275
|
+
// 이 부분은 IdeDiff 클래스 내에서 구현해야 합니다.
|
|
235276
|
+
// 일단은 콘솔 로그와 함께 작동하는지 확인합니다.
|
|
235277
|
+
console.log("Changes applied and diff recalculation needed!");
|
|
235278
|
+
|
|
235279
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트합니다.
|
|
235280
|
+
this.hostComponent.recalculateDiff(); // ⭐️ hostComponent를 통해 메서드 호출
|
|
235281
|
+
}
|
|
235282
|
+
|
|
235283
|
+
|
|
235284
|
+
}
|
|
235285
|
+
|
|
235167
235286
|
customElements.define("ide-diff", IdeDiff);
|
|
235168
235287
|
|
|
235169
235288
|
//import "./components/ideAssi.js";
|
package/dist/bundle.esm.js
CHANGED
|
@@ -234966,7 +234966,7 @@ class IdeDiff extends HTMLElement {
|
|
|
234966
234966
|
extensions: [
|
|
234967
234967
|
basicExtensions,
|
|
234968
234968
|
this.#languageCompartment.of(javascript()), // 초기 언어 설정
|
|
234969
|
-
EditorState.readOnly.of(true),
|
|
234969
|
+
//EditorState.readOnly.of(true),
|
|
234970
234970
|
tobeDiffDecorations, // TOBE Diff 데코레이션 필드
|
|
234971
234971
|
EditorView.updateListener.of((update) => {
|
|
234972
234972
|
if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
|
|
@@ -235061,9 +235061,17 @@ class IdeDiff extends HTMLElement {
|
|
|
235061
235061
|
const deletedLineDeco = Decoration.line({ class: "cm-deleted-line-bg" });
|
|
235062
235062
|
// const changedLineDeco = Decoration.line({ class: "cm-changed-line-bg" }); // 필요하다면
|
|
235063
235063
|
|
|
235064
|
+
// ⭐️ IdeDiff 인스턴스에 대한 참조를 위젯에 넘겨주기 위해 임시 변수 사용
|
|
235065
|
+
// 실제로는 Closure나 Bound method로 넘겨줄 수 있음
|
|
235066
|
+
const currentInstance = this;
|
|
235067
|
+
|
|
235064
235068
|
for (const [op, text] of diffs) {
|
|
235065
235069
|
const len = text.length;
|
|
235066
235070
|
|
|
235071
|
+
// ⭐️ 해당 diff 청크의 시작 오프셋을 저장 (버튼 위젯 위치 결정용)
|
|
235072
|
+
const currentAsisOffset = asisCursor;
|
|
235073
|
+
const currentTobeOffset = tobeCursor;
|
|
235074
|
+
|
|
235067
235075
|
switch (op) {
|
|
235068
235076
|
case diffMatchPatchExports.diff_match_patch.DIFF_INSERT:
|
|
235069
235077
|
console.log(diffMatchPatchExports.diff_match_patch.DIFF_INSERT, text);
|
|
@@ -235082,6 +235090,22 @@ class IdeDiff extends HTMLElement {
|
|
|
235082
235090
|
}
|
|
235083
235091
|
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
235084
235092
|
}
|
|
235093
|
+
|
|
235094
|
+
tobeLineBuilder.add(
|
|
235095
|
+
currentTobeOffset, // 이 Diff 청크의 시작 오프셋
|
|
235096
|
+
currentTobeOffset,
|
|
235097
|
+
Decoration.widget({
|
|
235098
|
+
widget: // #applyDiffDecorations 내 MergeButtonWidget 생성 시
|
|
235099
|
+
new MergeButtonWidget(
|
|
235100
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
235101
|
+
text, // 적용할 텍스트
|
|
235102
|
+
currentInstance.#tobeEditorView, // 적용 대상 에디터
|
|
235103
|
+
{ from: currentAsisOffset, to: currentAsisOffset + text.length }, // ⭐️ diffRange 전달
|
|
235104
|
+
currentInstance // ⭐️ IdeDiff 인스턴스 전달
|
|
235105
|
+
),
|
|
235106
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
235107
|
+
})
|
|
235108
|
+
);
|
|
235085
235109
|
break;
|
|
235086
235110
|
|
|
235087
235111
|
case diffMatchPatchExports.diff_match_patch.DIFF_DELETE:
|
|
@@ -235093,6 +235117,21 @@ class IdeDiff extends HTMLElement {
|
|
|
235093
235117
|
}
|
|
235094
235118
|
asisCursor += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
235095
235119
|
}
|
|
235120
|
+
|
|
235121
|
+
// ⭐️ ASIS 에디터에서 삭제된 청크의 경우, ASIS 쪽에 적용 버튼 (TOBE로 적용) 추가
|
|
235122
|
+
asisLineBuilder.add(
|
|
235123
|
+
currentAsisOffset, // 이 Diff 청크의 시작 오프셋
|
|
235124
|
+
currentAsisOffset,
|
|
235125
|
+
Decoration.widget({
|
|
235126
|
+
widget: new MergeButtonWidget(
|
|
235127
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
235128
|
+
text, // 적용할 텍스트 (이 경우 ASIS에서 가져올 내용)
|
|
235129
|
+
currentInstance.#tobeEditorView // 적용 대상은 TOBE 에디터
|
|
235130
|
+
),
|
|
235131
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
235132
|
+
})
|
|
235133
|
+
);
|
|
235134
|
+
|
|
235096
235135
|
break;
|
|
235097
235136
|
|
|
235098
235137
|
case diffMatchPatchExports.diff_match_patch.DIFF_EQUAL:
|
|
@@ -235112,6 +235151,21 @@ class IdeDiff extends HTMLElement {
|
|
|
235112
235151
|
};
|
|
235113
235152
|
};
|
|
235114
235153
|
|
|
235154
|
+
// IdeDiff 클래스 내부에 변경 후 Diff를 다시 계산하는 메서드 추가
|
|
235155
|
+
recalculateDiff = () => {
|
|
235156
|
+
const asisDoc = this.#asisEditorView.state.doc.toString();
|
|
235157
|
+
const tobeDoc = this.#tobeEditorView.state.doc.toString();
|
|
235158
|
+
|
|
235159
|
+
const { asisDecorations, tobeDecorations } = this.#applyDiffDecorations(asisDoc, tobeDoc);
|
|
235160
|
+
|
|
235161
|
+
this.#asisEditorView.dispatch({
|
|
235162
|
+
effects: [setAsisDecorationsEffect.of(asisDecorations)]
|
|
235163
|
+
});
|
|
235164
|
+
this.#tobeEditorView.dispatch({
|
|
235165
|
+
effects: [setTobeDecorationsEffect.of(tobeDecorations)]
|
|
235166
|
+
});
|
|
235167
|
+
};
|
|
235168
|
+
|
|
235115
235169
|
initialize = (src1, src2, language = 'javascript') => {
|
|
235116
235170
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
235117
235171
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -235160,6 +235214,71 @@ class IdeDiff extends HTMLElement {
|
|
|
235160
235214
|
};
|
|
235161
235215
|
}
|
|
235162
235216
|
|
|
235217
|
+
// IdeDiff 클래스 외부 (파일 상단 or 하단)에 추가
|
|
235218
|
+
class MergeButtonWidget extends WidgetType {
|
|
235219
|
+
constructor(isAsis, textToApply, targetEditorView, diffRange, hostComponent) {
|
|
235220
|
+
super();
|
|
235221
|
+
this.isAsis = isAsis; // ASIS 쪽 버튼인지 (true) TOBE 쪽 버튼인지 (false)
|
|
235222
|
+
this.textToApply = textToApply; // 적용할 텍스트
|
|
235223
|
+
this.targetEditorView = targetEditorView; // 텍스트를 적용할 에디터 뷰
|
|
235224
|
+
this.diffRange = diffRange; // ⭐️ 추가된 속성
|
|
235225
|
+
this.hostComponent = hostComponent; // ⭐️ IdeDiff 인스턴스 참조
|
|
235226
|
+
}
|
|
235227
|
+
|
|
235228
|
+
// 위젯이 차지할 공간을 텍스트 줄에 할당할지 여부. false로 설정하여 버튼이 줄 사이에 끼어들지 않도록 함.
|
|
235229
|
+
eq(other) { return false; }
|
|
235230
|
+
|
|
235231
|
+
// 위젯의 DOM 요소를 생성합니다.
|
|
235232
|
+
toDOM(view) {
|
|
235233
|
+
const button = document.createElement("button");
|
|
235234
|
+
button.className = `cm-merge-button ${this.isAsis ? 'accept' : 'revert'}`;
|
|
235235
|
+
button.textContent = this.isAsis ? "→ 적용" : "← 되돌리기"; // 버튼 텍스트
|
|
235236
|
+
|
|
235237
|
+
// 클릭 이벤트 핸들러
|
|
235238
|
+
button.addEventListener("click", () => {
|
|
235239
|
+
// 이 로직은 나중에 구현할 `applyChanges` 메서드를 호출할 것입니다.
|
|
235240
|
+
// 지금은 콘솔에 로그만 남깁니다.
|
|
235241
|
+
console.log(`버튼 클릭: ${this.isAsis ? 'ASIS -> TOBE' : 'TOBE -> ASIS'}`, this.textToApply);
|
|
235242
|
+
|
|
235243
|
+
// 실제 변경 로직 (아래 applyChanges 메서드 구현 후 주석 해제)
|
|
235244
|
+
this.applyChanges(this.textToApply, this.targetEditorView);
|
|
235245
|
+
});
|
|
235246
|
+
|
|
235247
|
+
const container = document.createElement("div");
|
|
235248
|
+
container.className = "cm-merge-button-container";
|
|
235249
|
+
container.appendChild(button);
|
|
235250
|
+
return container;
|
|
235251
|
+
}
|
|
235252
|
+
|
|
235253
|
+
// 실제 변경 적용 로직
|
|
235254
|
+
applyChanges(text, editorView) {
|
|
235255
|
+
if (!editorView || !this.diffRange) {
|
|
235256
|
+
console.error("Target editor view or diffRange is undefined.");
|
|
235257
|
+
return;
|
|
235258
|
+
}
|
|
235259
|
+
|
|
235260
|
+
// ⭐️ 해당 오프셋 범위의 내용을 교체 (삽입 또는 삭제)
|
|
235261
|
+
editorView.dispatch({
|
|
235262
|
+
changes: {
|
|
235263
|
+
from: this.diffRange.from,
|
|
235264
|
+
to: this.diffRange.to, // 삭제될 범위
|
|
235265
|
+
insert: text // 삽입될 내용
|
|
235266
|
+
}
|
|
235267
|
+
});
|
|
235268
|
+
|
|
235269
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트해야 합니다.
|
|
235270
|
+
// this.hostComponent.recalculateDiff(); 와 같은 메서드를 호출해야 함.
|
|
235271
|
+
// 이 부분은 IdeDiff 클래스 내에서 구현해야 합니다.
|
|
235272
|
+
// 일단은 콘솔 로그와 함께 작동하는지 확인합니다.
|
|
235273
|
+
console.log("Changes applied and diff recalculation needed!");
|
|
235274
|
+
|
|
235275
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트합니다.
|
|
235276
|
+
this.hostComponent.recalculateDiff(); // ⭐️ hostComponent를 통해 메서드 호출
|
|
235277
|
+
}
|
|
235278
|
+
|
|
235279
|
+
|
|
235280
|
+
}
|
|
235281
|
+
|
|
235163
235282
|
customElements.define("ide-diff", IdeDiff);
|
|
235164
235283
|
|
|
235165
235284
|
//import "./components/ideAssi.js";
|
|
@@ -4,7 +4,7 @@ import ninegrid from "ninegrid2";
|
|
|
4
4
|
import {
|
|
5
5
|
EditorView, lineNumbers, highlightSpecialChars, drawSelection,
|
|
6
6
|
dropCursor, keymap, highlightActiveLine, highlightActiveLineGutter,
|
|
7
|
-
Decoration
|
|
7
|
+
Decoration, WidgetType
|
|
8
8
|
} from "@codemirror/view";
|
|
9
9
|
import {
|
|
10
10
|
EditorState, Compartment, StateField,
|
|
@@ -178,7 +178,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
178
178
|
extensions: [
|
|
179
179
|
basicExtensions,
|
|
180
180
|
this.#languageCompartment.of(javascript()), // 초기 언어 설정
|
|
181
|
-
EditorState.readOnly.of(true),
|
|
181
|
+
//EditorState.readOnly.of(true),
|
|
182
182
|
tobeDiffDecorations, // TOBE Diff 데코레이션 필드
|
|
183
183
|
EditorView.updateListener.of((update) => {
|
|
184
184
|
if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
|
|
@@ -273,9 +273,17 @@ export class IdeDiff extends HTMLElement {
|
|
|
273
273
|
const deletedLineDeco = Decoration.line({ class: "cm-deleted-line-bg" });
|
|
274
274
|
// const changedLineDeco = Decoration.line({ class: "cm-changed-line-bg" }); // 필요하다면
|
|
275
275
|
|
|
276
|
+
// ⭐️ IdeDiff 인스턴스에 대한 참조를 위젯에 넘겨주기 위해 임시 변수 사용
|
|
277
|
+
// 실제로는 Closure나 Bound method로 넘겨줄 수 있음
|
|
278
|
+
const currentInstance = this;
|
|
279
|
+
|
|
276
280
|
for (const [op, text] of diffs) {
|
|
277
281
|
const len = text.length;
|
|
278
282
|
|
|
283
|
+
// ⭐️ 해당 diff 청크의 시작 오프셋을 저장 (버튼 위젯 위치 결정용)
|
|
284
|
+
const currentAsisOffset = asisCursor;
|
|
285
|
+
const currentTobeOffset = tobeCursor;
|
|
286
|
+
|
|
279
287
|
switch (op) {
|
|
280
288
|
case diff_match_patch.DIFF_INSERT:
|
|
281
289
|
console.log(diff_match_patch.DIFF_INSERT, text);
|
|
@@ -294,6 +302,22 @@ export class IdeDiff extends HTMLElement {
|
|
|
294
302
|
}
|
|
295
303
|
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
296
304
|
}
|
|
305
|
+
|
|
306
|
+
tobeLineBuilder.add(
|
|
307
|
+
currentTobeOffset, // 이 Diff 청크의 시작 오프셋
|
|
308
|
+
currentTobeOffset,
|
|
309
|
+
Decoration.widget({
|
|
310
|
+
widget: // #applyDiffDecorations 내 MergeButtonWidget 생성 시
|
|
311
|
+
new MergeButtonWidget(
|
|
312
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
313
|
+
text, // 적용할 텍스트
|
|
314
|
+
currentInstance.#tobeEditorView, // 적용 대상 에디터
|
|
315
|
+
{ from: currentAsisOffset, to: currentAsisOffset + text.length }, // ⭐️ diffRange 전달
|
|
316
|
+
currentInstance // ⭐️ IdeDiff 인스턴스 전달
|
|
317
|
+
),
|
|
318
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
319
|
+
})
|
|
320
|
+
);
|
|
297
321
|
break;
|
|
298
322
|
|
|
299
323
|
case diff_match_patch.DIFF_DELETE:
|
|
@@ -305,6 +329,21 @@ export class IdeDiff extends HTMLElement {
|
|
|
305
329
|
}
|
|
306
330
|
asisCursor += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
307
331
|
}
|
|
332
|
+
|
|
333
|
+
// ⭐️ ASIS 에디터에서 삭제된 청크의 경우, ASIS 쪽에 적용 버튼 (TOBE로 적용) 추가
|
|
334
|
+
asisLineBuilder.add(
|
|
335
|
+
currentAsisOffset, // 이 Diff 청크의 시작 오프셋
|
|
336
|
+
currentAsisOffset,
|
|
337
|
+
Decoration.widget({
|
|
338
|
+
widget: new MergeButtonWidget(
|
|
339
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
340
|
+
text, // 적용할 텍스트 (이 경우 ASIS에서 가져올 내용)
|
|
341
|
+
currentInstance.#tobeEditorView // 적용 대상은 TOBE 에디터
|
|
342
|
+
),
|
|
343
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
344
|
+
})
|
|
345
|
+
);
|
|
346
|
+
|
|
308
347
|
break;
|
|
309
348
|
|
|
310
349
|
case diff_match_patch.DIFF_EQUAL:
|
|
@@ -324,6 +363,21 @@ export class IdeDiff extends HTMLElement {
|
|
|
324
363
|
};
|
|
325
364
|
};
|
|
326
365
|
|
|
366
|
+
// IdeDiff 클래스 내부에 변경 후 Diff를 다시 계산하는 메서드 추가
|
|
367
|
+
recalculateDiff = () => {
|
|
368
|
+
const asisDoc = this.#asisEditorView.state.doc.toString();
|
|
369
|
+
const tobeDoc = this.#tobeEditorView.state.doc.toString();
|
|
370
|
+
|
|
371
|
+
const { asisDecorations, tobeDecorations } = this.#applyDiffDecorations(asisDoc, tobeDoc);
|
|
372
|
+
|
|
373
|
+
this.#asisEditorView.dispatch({
|
|
374
|
+
effects: [setAsisDecorationsEffect.of(asisDecorations)]
|
|
375
|
+
});
|
|
376
|
+
this.#tobeEditorView.dispatch({
|
|
377
|
+
effects: [setTobeDecorationsEffect.of(tobeDecorations)]
|
|
378
|
+
});
|
|
379
|
+
};
|
|
380
|
+
|
|
327
381
|
initialize = (src1, src2, language = 'javascript') => {
|
|
328
382
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
329
383
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -372,4 +426,69 @@ export class IdeDiff extends HTMLElement {
|
|
|
372
426
|
};
|
|
373
427
|
}
|
|
374
428
|
|
|
429
|
+
// IdeDiff 클래스 외부 (파일 상단 or 하단)에 추가
|
|
430
|
+
class MergeButtonWidget extends WidgetType {
|
|
431
|
+
constructor(isAsis, textToApply, targetEditorView, diffRange, hostComponent) {
|
|
432
|
+
super();
|
|
433
|
+
this.isAsis = isAsis; // ASIS 쪽 버튼인지 (true) TOBE 쪽 버튼인지 (false)
|
|
434
|
+
this.textToApply = textToApply; // 적용할 텍스트
|
|
435
|
+
this.targetEditorView = targetEditorView; // 텍스트를 적용할 에디터 뷰
|
|
436
|
+
this.diffRange = diffRange; // ⭐️ 추가된 속성
|
|
437
|
+
this.hostComponent = hostComponent; // ⭐️ IdeDiff 인스턴스 참조
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// 위젯이 차지할 공간을 텍스트 줄에 할당할지 여부. false로 설정하여 버튼이 줄 사이에 끼어들지 않도록 함.
|
|
441
|
+
eq(other) { return false; }
|
|
442
|
+
|
|
443
|
+
// 위젯의 DOM 요소를 생성합니다.
|
|
444
|
+
toDOM(view) {
|
|
445
|
+
const button = document.createElement("button");
|
|
446
|
+
button.className = `cm-merge-button ${this.isAsis ? 'accept' : 'revert'}`;
|
|
447
|
+
button.textContent = this.isAsis ? "→ 적용" : "← 되돌리기"; // 버튼 텍스트
|
|
448
|
+
|
|
449
|
+
// 클릭 이벤트 핸들러
|
|
450
|
+
button.addEventListener("click", () => {
|
|
451
|
+
// 이 로직은 나중에 구현할 `applyChanges` 메서드를 호출할 것입니다.
|
|
452
|
+
// 지금은 콘솔에 로그만 남깁니다.
|
|
453
|
+
console.log(`버튼 클릭: ${this.isAsis ? 'ASIS -> TOBE' : 'TOBE -> ASIS'}`, this.textToApply);
|
|
454
|
+
|
|
455
|
+
// 실제 변경 로직 (아래 applyChanges 메서드 구현 후 주석 해제)
|
|
456
|
+
this.applyChanges(this.textToApply, this.targetEditorView);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
const container = document.createElement("div");
|
|
460
|
+
container.className = "cm-merge-button-container";
|
|
461
|
+
container.appendChild(button);
|
|
462
|
+
return container;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// 실제 변경 적용 로직
|
|
466
|
+
applyChanges(text, editorView) {
|
|
467
|
+
if (!editorView || !this.diffRange) {
|
|
468
|
+
console.error("Target editor view or diffRange is undefined.");
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// ⭐️ 해당 오프셋 범위의 내용을 교체 (삽입 또는 삭제)
|
|
473
|
+
editorView.dispatch({
|
|
474
|
+
changes: {
|
|
475
|
+
from: this.diffRange.from,
|
|
476
|
+
to: this.diffRange.to, // 삭제될 범위
|
|
477
|
+
insert: text // 삽입될 내용
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트해야 합니다.
|
|
482
|
+
// this.hostComponent.recalculateDiff(); 와 같은 메서드를 호출해야 함.
|
|
483
|
+
// 이 부분은 IdeDiff 클래스 내에서 구현해야 합니다.
|
|
484
|
+
// 일단은 콘솔 로그와 함께 작동하는지 확인합니다.
|
|
485
|
+
console.log("Changes applied and diff recalculation needed!");
|
|
486
|
+
|
|
487
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트합니다.
|
|
488
|
+
this.hostComponent.recalculateDiff(); // ⭐️ hostComponent를 통해 메서드 호출
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
}
|
|
493
|
+
|
|
375
494
|
customElements.define("ide-diff", IdeDiff);
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import ninegrid from "ninegrid2";
|
|
|
4
4
|
import {
|
|
5
5
|
EditorView, lineNumbers, highlightSpecialChars, drawSelection,
|
|
6
6
|
dropCursor, keymap, highlightActiveLine, highlightActiveLineGutter,
|
|
7
|
-
Decoration
|
|
7
|
+
Decoration, WidgetType
|
|
8
8
|
} from "@codemirror/view";
|
|
9
9
|
import {
|
|
10
10
|
EditorState, Compartment, StateField,
|
|
@@ -178,7 +178,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
178
178
|
extensions: [
|
|
179
179
|
basicExtensions,
|
|
180
180
|
this.#languageCompartment.of(javascript()), // 초기 언어 설정
|
|
181
|
-
EditorState.readOnly.of(true),
|
|
181
|
+
//EditorState.readOnly.of(true),
|
|
182
182
|
tobeDiffDecorations, // TOBE Diff 데코레이션 필드
|
|
183
183
|
EditorView.updateListener.of((update) => {
|
|
184
184
|
if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
|
|
@@ -273,9 +273,17 @@ export class IdeDiff extends HTMLElement {
|
|
|
273
273
|
const deletedLineDeco = Decoration.line({ class: "cm-deleted-line-bg" });
|
|
274
274
|
// const changedLineDeco = Decoration.line({ class: "cm-changed-line-bg" }); // 필요하다면
|
|
275
275
|
|
|
276
|
+
// ⭐️ IdeDiff 인스턴스에 대한 참조를 위젯에 넘겨주기 위해 임시 변수 사용
|
|
277
|
+
// 실제로는 Closure나 Bound method로 넘겨줄 수 있음
|
|
278
|
+
const currentInstance = this;
|
|
279
|
+
|
|
276
280
|
for (const [op, text] of diffs) {
|
|
277
281
|
const len = text.length;
|
|
278
282
|
|
|
283
|
+
// ⭐️ 해당 diff 청크의 시작 오프셋을 저장 (버튼 위젯 위치 결정용)
|
|
284
|
+
const currentAsisOffset = asisCursor;
|
|
285
|
+
const currentTobeOffset = tobeCursor;
|
|
286
|
+
|
|
279
287
|
switch (op) {
|
|
280
288
|
case diff_match_patch.DIFF_INSERT:
|
|
281
289
|
console.log(diff_match_patch.DIFF_INSERT, text);
|
|
@@ -294,6 +302,22 @@ export class IdeDiff extends HTMLElement {
|
|
|
294
302
|
}
|
|
295
303
|
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
296
304
|
}
|
|
305
|
+
|
|
306
|
+
tobeLineBuilder.add(
|
|
307
|
+
currentTobeOffset, // 이 Diff 청크의 시작 오프셋
|
|
308
|
+
currentTobeOffset,
|
|
309
|
+
Decoration.widget({
|
|
310
|
+
widget: // #applyDiffDecorations 내 MergeButtonWidget 생성 시
|
|
311
|
+
new MergeButtonWidget(
|
|
312
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
313
|
+
text, // 적용할 텍스트
|
|
314
|
+
currentInstance.#tobeEditorView, // 적용 대상 에디터
|
|
315
|
+
{ from: currentAsisOffset, to: currentAsisOffset + text.length }, // ⭐️ diffRange 전달
|
|
316
|
+
currentInstance // ⭐️ IdeDiff 인스턴스 전달
|
|
317
|
+
),
|
|
318
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
319
|
+
})
|
|
320
|
+
);
|
|
297
321
|
break;
|
|
298
322
|
|
|
299
323
|
case diff_match_patch.DIFF_DELETE:
|
|
@@ -305,6 +329,21 @@ export class IdeDiff extends HTMLElement {
|
|
|
305
329
|
}
|
|
306
330
|
asisCursor += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
307
331
|
}
|
|
332
|
+
|
|
333
|
+
// ⭐️ ASIS 에디터에서 삭제된 청크의 경우, ASIS 쪽에 적용 버튼 (TOBE로 적용) 추가
|
|
334
|
+
asisLineBuilder.add(
|
|
335
|
+
currentAsisOffset, // 이 Diff 청크의 시작 오프셋
|
|
336
|
+
currentAsisOffset,
|
|
337
|
+
Decoration.widget({
|
|
338
|
+
widget: new MergeButtonWidget(
|
|
339
|
+
true, // ASIS 쪽 버튼 (적용)
|
|
340
|
+
text, // 적용할 텍스트 (이 경우 ASIS에서 가져올 내용)
|
|
341
|
+
currentInstance.#tobeEditorView // 적용 대상은 TOBE 에디터
|
|
342
|
+
),
|
|
343
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
344
|
+
})
|
|
345
|
+
);
|
|
346
|
+
|
|
308
347
|
break;
|
|
309
348
|
|
|
310
349
|
case diff_match_patch.DIFF_EQUAL:
|
|
@@ -324,6 +363,21 @@ export class IdeDiff extends HTMLElement {
|
|
|
324
363
|
};
|
|
325
364
|
};
|
|
326
365
|
|
|
366
|
+
// IdeDiff 클래스 내부에 변경 후 Diff를 다시 계산하는 메서드 추가
|
|
367
|
+
recalculateDiff = () => {
|
|
368
|
+
const asisDoc = this.#asisEditorView.state.doc.toString();
|
|
369
|
+
const tobeDoc = this.#tobeEditorView.state.doc.toString();
|
|
370
|
+
|
|
371
|
+
const { asisDecorations, tobeDecorations } = this.#applyDiffDecorations(asisDoc, tobeDoc);
|
|
372
|
+
|
|
373
|
+
this.#asisEditorView.dispatch({
|
|
374
|
+
effects: [setAsisDecorationsEffect.of(asisDecorations)]
|
|
375
|
+
});
|
|
376
|
+
this.#tobeEditorView.dispatch({
|
|
377
|
+
effects: [setTobeDecorationsEffect.of(tobeDecorations)]
|
|
378
|
+
});
|
|
379
|
+
};
|
|
380
|
+
|
|
327
381
|
initialize = (src1, src2, language = 'javascript') => {
|
|
328
382
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
329
383
|
console.warn('CodeMirror Editors not initialized yet.');
|
|
@@ -372,4 +426,69 @@ export class IdeDiff extends HTMLElement {
|
|
|
372
426
|
};
|
|
373
427
|
}
|
|
374
428
|
|
|
429
|
+
// IdeDiff 클래스 외부 (파일 상단 or 하단)에 추가
|
|
430
|
+
class MergeButtonWidget extends WidgetType {
|
|
431
|
+
constructor(isAsis, textToApply, targetEditorView, diffRange, hostComponent) {
|
|
432
|
+
super();
|
|
433
|
+
this.isAsis = isAsis; // ASIS 쪽 버튼인지 (true) TOBE 쪽 버튼인지 (false)
|
|
434
|
+
this.textToApply = textToApply; // 적용할 텍스트
|
|
435
|
+
this.targetEditorView = targetEditorView; // 텍스트를 적용할 에디터 뷰
|
|
436
|
+
this.diffRange = diffRange; // ⭐️ 추가된 속성
|
|
437
|
+
this.hostComponent = hostComponent; // ⭐️ IdeDiff 인스턴스 참조
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// 위젯이 차지할 공간을 텍스트 줄에 할당할지 여부. false로 설정하여 버튼이 줄 사이에 끼어들지 않도록 함.
|
|
441
|
+
eq(other) { return false; }
|
|
442
|
+
|
|
443
|
+
// 위젯의 DOM 요소를 생성합니다.
|
|
444
|
+
toDOM(view) {
|
|
445
|
+
const button = document.createElement("button");
|
|
446
|
+
button.className = `cm-merge-button ${this.isAsis ? 'accept' : 'revert'}`;
|
|
447
|
+
button.textContent = this.isAsis ? "→ 적용" : "← 되돌리기"; // 버튼 텍스트
|
|
448
|
+
|
|
449
|
+
// 클릭 이벤트 핸들러
|
|
450
|
+
button.addEventListener("click", () => {
|
|
451
|
+
// 이 로직은 나중에 구현할 `applyChanges` 메서드를 호출할 것입니다.
|
|
452
|
+
// 지금은 콘솔에 로그만 남깁니다.
|
|
453
|
+
console.log(`버튼 클릭: ${this.isAsis ? 'ASIS -> TOBE' : 'TOBE -> ASIS'}`, this.textToApply);
|
|
454
|
+
|
|
455
|
+
// 실제 변경 로직 (아래 applyChanges 메서드 구현 후 주석 해제)
|
|
456
|
+
this.applyChanges(this.textToApply, this.targetEditorView);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
const container = document.createElement("div");
|
|
460
|
+
container.className = "cm-merge-button-container";
|
|
461
|
+
container.appendChild(button);
|
|
462
|
+
return container;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// 실제 변경 적용 로직
|
|
466
|
+
applyChanges(text, editorView) {
|
|
467
|
+
if (!editorView || !this.diffRange) {
|
|
468
|
+
console.error("Target editor view or diffRange is undefined.");
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// ⭐️ 해당 오프셋 범위의 내용을 교체 (삽입 또는 삭제)
|
|
473
|
+
editorView.dispatch({
|
|
474
|
+
changes: {
|
|
475
|
+
from: this.diffRange.from,
|
|
476
|
+
to: this.diffRange.to, // 삭제될 범위
|
|
477
|
+
insert: text // 삽입될 내용
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트해야 합니다.
|
|
482
|
+
// this.hostComponent.recalculateDiff(); 와 같은 메서드를 호출해야 함.
|
|
483
|
+
// 이 부분은 IdeDiff 클래스 내에서 구현해야 합니다.
|
|
484
|
+
// 일단은 콘솔 로그와 함께 작동하는지 확인합니다.
|
|
485
|
+
console.log("Changes applied and diff recalculation needed!");
|
|
486
|
+
|
|
487
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트합니다.
|
|
488
|
+
this.hostComponent.recalculateDiff(); // ⭐️ hostComponent를 통해 메서드 호출
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
}
|
|
493
|
+
|
|
375
494
|
customElements.define("ide-diff", IdeDiff);
|