ide-assi 0.435.0 → 0.437.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 +200 -53
- package/dist/bundle.esm.js +200 -53
- package/dist/components/ideDiff.js +194 -59
- package/package.json +1 -1
- package/src/components/ideDiff.js +194 -59
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import ninegrid from "ninegrid2";
|
|
2
2
|
|
|
3
|
-
// CodeMirror 6 핵심 및 확장 임포트
|
|
4
3
|
import {
|
|
5
4
|
EditorView, lineNumbers, highlightSpecialChars, drawSelection,
|
|
6
5
|
dropCursor, keymap, highlightActiveLine, highlightActiveLineGutter,
|
|
7
|
-
Decoration
|
|
6
|
+
Decoration, WidgetType
|
|
8
7
|
} from "@codemirror/view";
|
|
9
8
|
import {
|
|
10
9
|
EditorState, Compartment, StateField,
|
|
@@ -12,17 +11,13 @@ import {
|
|
|
12
11
|
StateEffect,
|
|
13
12
|
Text
|
|
14
13
|
} from "@codemirror/state";
|
|
15
|
-
// ⭐️ indentWithTab, selectAll 함수로 임포트되었는지 확인하고, 아래에서 호출합니다.
|
|
16
14
|
import { history, historyKeymap, indentWithTab, selectAll, defaultKeymap } from "@codemirror/commands";
|
|
17
15
|
import { searchKeymap, highlightSelectionMatches } from "@codemirror/search";
|
|
18
|
-
// ⭐️ indentOnInput 함수도 여기서 임포트되었는지 확인합니다.
|
|
19
16
|
import { indentOnInput, bracketMatching, syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
|
|
20
17
|
import { javascript } from "@codemirror/lang-javascript";
|
|
21
|
-
|
|
22
18
|
import { lintKeymap } from "@codemirror/lint";
|
|
23
19
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
24
20
|
|
|
25
|
-
// Diff 로직을 위해 diff-match-patch 사용
|
|
26
21
|
import { diff_match_patch } from 'diff-match-patch';
|
|
27
22
|
|
|
28
23
|
// --- Diff 데코레이션을 위한 StateEffect 정의 ---
|
|
@@ -63,8 +58,71 @@ const tobeDiffDecorations = StateField.define({
|
|
|
63
58
|
});
|
|
64
59
|
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
// IdeDiff 클래스 외부 (파일 상단 or 하단)에 추가
|
|
62
|
+
class MergeButtonWidget extends WidgetType {
|
|
63
|
+
// ⭐️ diffRange는 변경이 발생할 대상 에디터의 범위입니다.
|
|
64
|
+
// ⭐️ isAsisButton: ASIS 에디터 쪽에 붙는 버튼인가? (true면 ASIS -> TOBE 적용)
|
|
65
|
+
// ⭐️ isAsisButton이 false면 TOBE 에디터 쪽에 붙는 버튼 (TOBE -> ASIS 되돌리기)
|
|
66
|
+
constructor(isAsisButton, textToApply, targetEditorView, diffRange, hostComponent) {
|
|
67
|
+
super();
|
|
68
|
+
this.isAsisButton = isAsisButton; // 이 버튼이 ASIS 에디터에 붙는 버튼인가 (true) TOBE 에디터에 붙는 버튼인가 (false)
|
|
69
|
+
this.textToApply = textToApply; // 적용할 텍스트
|
|
70
|
+
this.targetEditorView = targetEditorView; // 텍스트를 적용할 에디터 뷰 (상대편 에디터)
|
|
71
|
+
this.diffRange = diffRange; // 대상 에디터에서 변경이 일어날 정확한 from/to 오프셋
|
|
72
|
+
this.hostComponent = hostComponent; // IdeDiff 인스턴스 참조
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 위젯이 차지할 공간을 텍스트 줄에 할당할지 여부. false로 설정하여 버튼이 줄 사이에 끼어들지 않도록 함.
|
|
76
|
+
eq(other) { return false; }
|
|
77
|
+
|
|
78
|
+
// 위젯의 DOM 요소를 생성합니다.
|
|
79
|
+
toDOM(view) {
|
|
80
|
+
const button = document.createElement("button");
|
|
81
|
+
// 버튼 클래스 및 텍스트는 버튼의 위치(ASIS/TOBE)에 따라 결정됩니다.
|
|
82
|
+
button.className = `cm-merge-button ${this.isAsisButton ? 'accept' : 'revert'}`;
|
|
83
|
+
button.textContent = this.isAsisButton ? "→ 적용" : "← 되돌리기"; // ASIS 버튼: TOBE로 적용, TOBE 버튼: ASIS로 되돌리기
|
|
84
|
+
|
|
85
|
+
// 클릭 이벤트 핸들러
|
|
86
|
+
button.addEventListener("click", () => {
|
|
87
|
+
console.log(`버튼 클릭: ${this.isAsisButton ? 'ASIS -> TOBE' : 'TOBE -> ASIS'}`, this.textToApply);
|
|
88
|
+
console.log("대상 에디터:", this.targetEditorView === this.hostComponent.#asisEditorView ? "ASIS" : "TOBE");
|
|
89
|
+
console.log("대상 범위:", this.diffRange);
|
|
90
|
+
|
|
91
|
+
this.applyChanges(this.textToApply, this.targetEditorView, this.diffRange);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const container = document.createElement("div");
|
|
95
|
+
container.className = "cm-merge-button-container";
|
|
96
|
+
container.appendChild(button);
|
|
97
|
+
return container;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 실제 변경 적용 로직
|
|
101
|
+
applyChanges(text, editorView, range) {
|
|
102
|
+
if (!editorView || !range) {
|
|
103
|
+
console.error("Target editor view or range is undefined.", editorView, range);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
editorView.dispatch({
|
|
108
|
+
changes: {
|
|
109
|
+
from: range.from,
|
|
110
|
+
to: range.to,
|
|
111
|
+
insert: text
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// 변경 후 Diff를 다시 계산하고 데코레이션을 업데이트합니다.
|
|
116
|
+
// requestAnimationFrame으로 감싸서 다음 렌더링 사이클에서 Diff 계산이 이루어지도록 합니다.
|
|
117
|
+
// 이렇게 하면 UI 블로킹을 줄일 수 있습니다.
|
|
118
|
+
requestAnimationFrame(() => {
|
|
119
|
+
this.hostComponent.recalculateDiff();
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
67
124
|
|
|
125
|
+
export class IdeDiff extends HTMLElement {
|
|
68
126
|
#asisEditorView;
|
|
69
127
|
#tobeEditorView;
|
|
70
128
|
#asisEditorEl;
|
|
@@ -88,6 +146,62 @@ export class IdeDiff extends HTMLElement {
|
|
|
88
146
|
/* ninegrid CSS 및 필요한 기본 스타일 */
|
|
89
147
|
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ideDiff.css";
|
|
90
148
|
${ninegrid.getCustomPath(this, "ideDiff.css")}
|
|
149
|
+
|
|
150
|
+
/* --- 추가된 CSS 규칙 (버튼 및 선택 관련) --- */
|
|
151
|
+
.cm-line {
|
|
152
|
+
position: relative;
|
|
153
|
+
}
|
|
154
|
+
.cm-merge-button-container {
|
|
155
|
+
position: absolute;
|
|
156
|
+
right: 5px;
|
|
157
|
+
top: 50%;
|
|
158
|
+
transform: translateY(-50%);
|
|
159
|
+
z-index: 10;
|
|
160
|
+
display: flex;
|
|
161
|
+
gap: 5px;
|
|
162
|
+
}
|
|
163
|
+
.cm-merge-button {
|
|
164
|
+
background-color: #f0f0f0;
|
|
165
|
+
border: 1px solid #ccc;
|
|
166
|
+
border-radius: 3px;
|
|
167
|
+
padding: 2px 6px;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
font-size: 0.8em;
|
|
170
|
+
line-height: 1;
|
|
171
|
+
white-space: nowrap;
|
|
172
|
+
opacity: 0.7;
|
|
173
|
+
transition: opacity 0.2s ease-in-out;
|
|
174
|
+
}
|
|
175
|
+
.cm-merge-button:hover {
|
|
176
|
+
opacity: 1;
|
|
177
|
+
background-color: #e0e0e0;
|
|
178
|
+
}
|
|
179
|
+
.cm-merge-button.accept {
|
|
180
|
+
background-color: #4CAF50;
|
|
181
|
+
color: white;
|
|
182
|
+
border-color: #4CAF50;
|
|
183
|
+
}
|
|
184
|
+
.cm-merge-button.revert {
|
|
185
|
+
background-color: #f44336;
|
|
186
|
+
color: white;
|
|
187
|
+
border-color: #f44336;
|
|
188
|
+
}
|
|
189
|
+
/* Diff 데코레이션 CSS (ideDiff.css에 없으면 여기에 추가) */
|
|
190
|
+
.cm-inserted-line-bg { background-color: #e6ffed; border-left: 3px solid #66bb6a; }
|
|
191
|
+
.cm-deleted-line-bg { background-color: #ffebe9; border-left: 3px solid #ef5350; }
|
|
192
|
+
|
|
193
|
+
/* CodeMirror 선택 스타일 (ideDiff.css에 없으면 여기에 추가) */
|
|
194
|
+
.cm-selectionBackground {
|
|
195
|
+
background-color: #d7d4f9 !important;
|
|
196
|
+
}
|
|
197
|
+
.cm-editor ::selection {
|
|
198
|
+
background-color: #d7d4f9 !important;
|
|
199
|
+
color: inherit !important;
|
|
200
|
+
}
|
|
201
|
+
.cm-editor::-moz-selection {
|
|
202
|
+
background-color: #d7d4f9 !important;
|
|
203
|
+
color: inherit !important;
|
|
204
|
+
}
|
|
91
205
|
</style>
|
|
92
206
|
|
|
93
207
|
<div class="wrapper">
|
|
@@ -133,7 +247,7 @@ export class IdeDiff extends HTMLElement {
|
|
|
133
247
|
drawSelection(),
|
|
134
248
|
dropCursor(),
|
|
135
249
|
EditorState.allowMultipleSelections.of(true),
|
|
136
|
-
indentOnInput(),
|
|
250
|
+
indentOnInput(),
|
|
137
251
|
bracketMatching(),
|
|
138
252
|
highlightActiveLine(),
|
|
139
253
|
highlightActiveLineGutter(),
|
|
@@ -144,11 +258,11 @@ export class IdeDiff extends HTMLElement {
|
|
|
144
258
|
...historyKeymap,
|
|
145
259
|
...lintKeymap,
|
|
146
260
|
...completionKeymap,
|
|
147
|
-
|
|
148
|
-
|
|
261
|
+
indentWithTab, // ⭐️ 함수가 아닌 확장 자체를 전달
|
|
262
|
+
selectAll // ⭐️ 함수가 아닌 확장 자체를 전달
|
|
149
263
|
]),
|
|
150
|
-
syntaxHighlighting(defaultHighlightStyle),
|
|
151
|
-
autocompletion(),
|
|
264
|
+
syntaxHighlighting(defaultHighlightStyle),
|
|
265
|
+
autocompletion(),
|
|
152
266
|
];
|
|
153
267
|
|
|
154
268
|
// ASIS 에디터 뷰 초기화
|
|
@@ -157,9 +271,9 @@ export class IdeDiff extends HTMLElement {
|
|
|
157
271
|
doc: '',
|
|
158
272
|
extensions: [
|
|
159
273
|
basicExtensions,
|
|
160
|
-
this.#languageCompartment.of(javascript()),
|
|
161
|
-
EditorState.readOnly.of(true),
|
|
162
|
-
asisDiffDecorations,
|
|
274
|
+
this.#languageCompartment.of(javascript()),
|
|
275
|
+
EditorState.readOnly.of(true), // ASIS는 읽기 전용 유지
|
|
276
|
+
asisDiffDecorations,
|
|
163
277
|
EditorView.updateListener.of((update) => {
|
|
164
278
|
if (update.view.contentDOM.firstChild && !update.view._initialAsisContentLoaded) {
|
|
165
279
|
update.view._initialAsisContentLoaded = true;
|
|
@@ -177,9 +291,9 @@ export class IdeDiff extends HTMLElement {
|
|
|
177
291
|
doc: '',
|
|
178
292
|
extensions: [
|
|
179
293
|
basicExtensions,
|
|
180
|
-
this.#languageCompartment.of(javascript()),
|
|
181
|
-
EditorState.readOnly.of(true),
|
|
182
|
-
tobeDiffDecorations,
|
|
294
|
+
this.#languageCompartment.of(javascript()),
|
|
295
|
+
// EditorState.readOnly.of(true), // TOBE는 편집 가능하도록 주석 처리 유지
|
|
296
|
+
tobeDiffDecorations,
|
|
183
297
|
EditorView.updateListener.of((update) => {
|
|
184
298
|
if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
|
|
185
299
|
update.view._initialTobeContentLoaded = true;
|
|
@@ -232,72 +346,66 @@ export class IdeDiff extends HTMLElement {
|
|
|
232
346
|
#applyDiffDecorations = (asisSrc, tobeSrc) => {
|
|
233
347
|
const dmp = new diff_match_patch();
|
|
234
348
|
|
|
235
|
-
// dmp의 기본 cleanupThreshold를 줄여서 더 세밀한 차이를 감지하도록 시도
|
|
236
|
-
// 기본값은 0.5인데, 0으로 하면 더 많은 변화를 감지할 수 있습니다.
|
|
237
|
-
// 하지만 너무 낮추면 노이즈가 많아질 수 있습니다.
|
|
238
|
-
// dmp.Diff_EditCost = 4; // 편집 비용 조정, 기본 4
|
|
239
|
-
// dmp.Diff_DualThreshold = 0.5; // 불명확한 Diff에 대한 임계값. 기본 0.5
|
|
240
|
-
// dmp.Diff_Timeout = 1.0; // 타임아웃, 기본 1.0
|
|
241
|
-
|
|
242
|
-
// 텍스트를 줄 단위로 변환하여 Diff 수행
|
|
243
349
|
const a = dmp.diff_linesToChars_(asisSrc, tobeSrc);
|
|
244
350
|
const lineText1 = a.chars1;
|
|
245
351
|
const lineText2 = a.chars2;
|
|
246
352
|
const lineArray = a.lineArray;
|
|
247
353
|
|
|
248
|
-
// dmp.diff_main(text1, text2, checklines, deadline)
|
|
249
|
-
// checklines: true (기본값)는 줄 단위 최적화, false는 문자 단위로.
|
|
250
|
-
// 여기서는 diff_linesToChars_를 사용했으므로 true가 적절.
|
|
251
354
|
const diffs = dmp.diff_main(lineText1, lineText2, true);
|
|
252
|
-
|
|
253
|
-
// cleanupEfficiency를 먼저 적용하여 효율적인 Diff를 만듭니다.
|
|
254
|
-
// 이는 작은 변경사항이 인접해 있을 때 하나의 큰 변경으로 합치는 경향이 있습니다.
|
|
255
|
-
// dmp.diff_cleanupEfficiency(diffs); // 오히려 이동을 놓칠 수 있음
|
|
256
|
-
|
|
257
|
-
// 그 다음 의미론적 정리를 적용합니다.
|
|
258
355
|
dmp.diff_cleanupSemantic(diffs);
|
|
259
|
-
|
|
260
|
-
// 다시 문자열로 변환
|
|
261
356
|
dmp.diff_charsToLines_(diffs, lineArray);
|
|
262
357
|
|
|
263
|
-
console.log(diffs);
|
|
358
|
+
console.log("Calculated Diffs:", diffs); // Diff 결과 확인용
|
|
264
359
|
|
|
265
360
|
const asisLineBuilder = new RangeSetBuilder();
|
|
266
361
|
const tobeLineBuilder = new RangeSetBuilder();
|
|
267
362
|
|
|
268
|
-
let asisCursor = 0;
|
|
269
|
-
let tobeCursor = 0;
|
|
363
|
+
let asisCursor = 0; // ASIS 텍스트에서의 현재 오프셋
|
|
364
|
+
let tobeCursor = 0; // TOBE 텍스트에서의 현재 오프셋
|
|
270
365
|
|
|
271
|
-
// 변경된 줄에 대한 새로운 데코레이션 클래스를 추가할 수 있습니다.
|
|
272
366
|
const insertedLineDeco = Decoration.line({ class: "cm-inserted-line-bg" });
|
|
273
367
|
const deletedLineDeco = Decoration.line({ class: "cm-deleted-line-bg" });
|
|
274
|
-
|
|
368
|
+
|
|
369
|
+
const currentInstance = this;
|
|
275
370
|
|
|
276
371
|
for (const [op, text] of diffs) {
|
|
277
372
|
const len = text.length;
|
|
278
373
|
|
|
374
|
+
// 각 diff op 이전에 현재 커서 위치를 저장
|
|
375
|
+
const asisRangeStart = asisCursor;
|
|
376
|
+
const tobeRangeStart = tobeCursor;
|
|
377
|
+
|
|
279
378
|
switch (op) {
|
|
280
|
-
case diff_match_patch.DIFF_INSERT:
|
|
281
|
-
console.log(
|
|
379
|
+
case diff_match_patch.DIFF_INSERT: // TOBE에 추가된 내용 (ASIS에는 없음)
|
|
380
|
+
console.log("DIFF_INSERT (TOBE added):", JSON.stringify(text));
|
|
282
381
|
const tobeLines = text.split('\n');
|
|
283
|
-
|
|
284
382
|
for (let i = 0; i < tobeLines.length; i++) {
|
|
285
|
-
// 빈 줄이 아니고, 마지막 줄이면서 줄바꿈이 없는 경우가 아니면 데코레이션
|
|
286
|
-
/**
|
|
287
|
-
if (!(i === tobeLines.length - 1 && tobeLines[i] === '' && !text.endsWith('\n'))) {
|
|
288
|
-
tobeLineBuilder.add(tobeCursor, tobeCursor, insertedLineDeco);
|
|
289
|
-
}
|
|
290
|
-
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
291
|
-
*/
|
|
292
383
|
if (!(i === tobeLines.length - 1 && tobeLines[i] === '' && text.endsWith('\n'))) {
|
|
293
384
|
tobeLineBuilder.add(tobeCursor, tobeCursor, insertedLineDeco);
|
|
294
385
|
}
|
|
295
386
|
tobeCursor += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
|
|
296
387
|
}
|
|
388
|
+
|
|
389
|
+
// ⭐️ TOBE 에디터에 버튼 추가: TOBE의 추가 내용을 ASIS로 '되돌리기' (ASIS에서 삭제)
|
|
390
|
+
// 즉, TOBE에서 삽입된 내용을 ASIS에서 '없애는' 작업
|
|
391
|
+
tobeLineBuilder.add(
|
|
392
|
+
tobeRangeStart, // TOBE에서의 해당 Diff 청크 시작 오프셋
|
|
393
|
+
tobeRangeStart,
|
|
394
|
+
Decoration.widget({
|
|
395
|
+
widget: new MergeButtonWidget(
|
|
396
|
+
false, // 이 버튼은 TOBE 에디터에 붙는 버튼 (되돌리기)
|
|
397
|
+
"", // 텍스트를 ""로 삽입하면 삭제 효과 (ASIS에서 없앨 내용)
|
|
398
|
+
currentInstance.#asisEditorView, // 대상 에디터는 ASIS
|
|
399
|
+
{ from: asisRangeStart, to: asisRangeStart + 0 }, // ASIS에서의 대상 범위 (삽입 지점)
|
|
400
|
+
currentInstance
|
|
401
|
+
),
|
|
402
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
403
|
+
})
|
|
404
|
+
);
|
|
297
405
|
break;
|
|
298
406
|
|
|
299
|
-
case diff_match_patch.DIFF_DELETE:
|
|
300
|
-
console.log(
|
|
407
|
+
case diff_match_patch.DIFF_DELETE: // ASIS에서 삭제된 내용 (TOBE에는 없음)
|
|
408
|
+
console.log("DIFF_DELETE (ASIS deleted):", JSON.stringify(text));
|
|
301
409
|
const asisLines = text.split('\n');
|
|
302
410
|
for (let i = 0; i < asisLines.length; i++) {
|
|
303
411
|
if (!(i === asisLines.length - 1 && asisLines[i] === '' && text.endsWith('\n'))) {
|
|
@@ -305,16 +413,29 @@ export class IdeDiff extends HTMLElement {
|
|
|
305
413
|
}
|
|
306
414
|
asisCursor += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
|
|
307
415
|
}
|
|
416
|
+
|
|
417
|
+
// ⭐️ ASIS 에디터에 버튼 추가: ASIS의 삭제 내용을 TOBE로 '적용' (TOBE에 삽입)
|
|
418
|
+
// 즉, ASIS에서 삭제된 내용을 TOBE에 '넣는' 작업
|
|
419
|
+
asisLineBuilder.add(
|
|
420
|
+
asisRangeStart, // ASIS에서의 해당 Diff 청크 시작 오프셋
|
|
421
|
+
asisRangeStart,
|
|
422
|
+
Decoration.widget({
|
|
423
|
+
widget: new MergeButtonWidget(
|
|
424
|
+
true, // 이 버튼은 ASIS 에디터에 붙는 버튼 (적용)
|
|
425
|
+
text, // ASIS에서 삭제된 내용을 TOBE에 삽입
|
|
426
|
+
currentInstance.#tobeEditorView, // 대상 에디터는 TOBE
|
|
427
|
+
{ from: tobeRangeStart, to: tobeRangeStart + 0 }, // TOBE에서의 대상 범위 (삽입 지점)
|
|
428
|
+
currentInstance
|
|
429
|
+
),
|
|
430
|
+
side: 1 // 텍스트 뒤에 삽입
|
|
431
|
+
})
|
|
432
|
+
);
|
|
308
433
|
break;
|
|
309
434
|
|
|
310
|
-
case diff_match_patch.DIFF_EQUAL:
|
|
435
|
+
case diff_match_patch.DIFF_EQUAL: // 동일한 내용
|
|
311
436
|
asisCursor += len;
|
|
312
437
|
tobeCursor += len;
|
|
313
438
|
break;
|
|
314
|
-
|
|
315
|
-
default:
|
|
316
|
-
console.log(op);
|
|
317
|
-
break;
|
|
318
439
|
}
|
|
319
440
|
}
|
|
320
441
|
|
|
@@ -324,6 +445,20 @@ export class IdeDiff extends HTMLElement {
|
|
|
324
445
|
};
|
|
325
446
|
};
|
|
326
447
|
|
|
448
|
+
recalculateDiff = () => {
|
|
449
|
+
const asisDoc = this.#asisEditorView.state.doc.toString();
|
|
450
|
+
const tobeDoc = this.#tobeEditorView.state.doc.toString();
|
|
451
|
+
|
|
452
|
+
const { asisDecorations, tobeDecorations } = this.#applyDiffDecorations(asisDoc, tobeDoc);
|
|
453
|
+
|
|
454
|
+
this.#asisEditorView.dispatch({
|
|
455
|
+
effects: [setAsisDecorationsEffect.of(asisDecorations)]
|
|
456
|
+
});
|
|
457
|
+
this.#tobeEditorView.dispatch({
|
|
458
|
+
effects: [setTobeDecorationsEffect.of(tobeDecorations)]
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
|
|
327
462
|
initialize = (src1, src2, language = 'javascript') => {
|
|
328
463
|
if (!this.#asisEditorView || !this.#tobeEditorView) {
|
|
329
464
|
console.warn('CodeMirror Editors not initialized yet.');
|