@nine-lab/nine-mu 0.1.308 → 0.1.310

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-mu",
3
- "version": "0.1.308",
3
+ "version": "0.1.310",
4
4
  "description": "AI-Driven Full-Stack Code Fabrication Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-mu.umd.js",
@@ -166,6 +166,10 @@ export class NineDiff extends HTMLElement {
166
166
  #tobeEditorView;
167
167
  #asisEditorEl;
168
168
  #tobeEditorEl;
169
+ #isDirty = false;
170
+ #initialAsisSrc;
171
+ #initialTobeSrc;
172
+
169
173
 
170
174
  #languageCompartment = new Compartment();
171
175
 
@@ -181,6 +185,9 @@ export class NineDiff extends HTMLElement {
181
185
  return this.#tobeEditorView;
182
186
  }
183
187
 
188
+ get isDirty() {
189
+ return this.#isDirty;
190
+ }
184
191
 
185
192
  constructor() {
186
193
  super();
@@ -308,6 +315,10 @@ export class NineDiff extends HTMLElement {
308
315
  asisReady = true;
309
316
  checkAllReady(); // ASIS 준비 완료
310
317
  }
318
+
319
+ if (update.docChanged) {
320
+ this.#checkDirtyState();
321
+ }
311
322
  })
312
323
  ]
313
324
  }),
@@ -330,6 +341,10 @@ export class NineDiff extends HTMLElement {
330
341
  tobeReady = true;
331
342
  checkAllReady(); // ASIS 준비 완료
332
343
  }
344
+
345
+ if (update.docChanged) {
346
+ this.#checkDirtyState();
347
+ }
333
348
  })
334
349
  ]
335
350
  }),
@@ -339,6 +354,25 @@ export class NineDiff extends HTMLElement {
339
354
  this.#setupScrollSync();
340
355
  };
341
356
 
357
+ #checkDirtyState = () => {
358
+ const currentAsis = this.getAsisContents();
359
+ const currentTobe = this.getTobeContents();
360
+
361
+ // 원본 소스와 하나라도 다르면 dirty 상태로 판정
362
+ const nextDirty = (currentAsis !== this.#initialAsisSrc) || (currentTobe !== this.#initialTobeSrc);
363
+
364
+ // 상태가 바뀔 때만 이벤트를 디스패치해서 불필요한 이벤트 연발을 막음
365
+ if (this.#isDirty !== nextDirty) {
366
+ this.#isDirty = nextDirty;
367
+ this.dispatchEvent(new CustomEvent('change-dirty', {
368
+ detail: { isDirty: this.#isDirty },
369
+ bubbles: true,
370
+ composed: true
371
+ }));
372
+ trace.log(`[NineDiff] 상태 변경 - isDirty: ${this.#isDirty}`);
373
+ }
374
+ };
375
+
342
376
  #setupScrollSync = () => {
343
377
  if (this._asisScrollHandler) {
344
378
  this.#asisEditorView.scrollDOM.removeEventListener('scroll', this._asisScrollHandler);
@@ -506,6 +540,9 @@ export class NineDiff extends HTMLElement {
506
540
  //console.log(src1, src2, language);
507
541
 
508
542
  this.#isScrollSyncActive = false;
543
+ this.#isDirty = false;
544
+ this.#initialAsisSrc = src1 ?? "";
545
+ this.#initialTobeSrc = src2 ?? "";
509
546
 
510
547
  let langExtension;
511
548
  switch(language) {
@@ -39,7 +39,7 @@ export class NineMenuDiffPopup extends HTMLElement {
39
39
  </div>
40
40
  <div class="footer">
41
41
  <button class="btn btn-cancel">취소</button>
42
- <button class="btn btn-confirm">저장</button>
42
+ <button class="btn btn-confirm" disabled>저장</button>
43
43
  </div>
44
44
  </div>
45
45
  </nine-dialog>
@@ -48,8 +48,16 @@ export class NineMenuDiffPopup extends HTMLElement {
48
48
  this.#dialog = this.shadowRoot.querySelector('nine-dialog');
49
49
  this.#diffView = this.shadowRoot.querySelector('nine-diff');
50
50
 
51
- this.shadowRoot.querySelector('.btn-confirm').onclick = () => this.#handleConfirm();
51
+ const $btnConfirm = this.shadowRoot.querySelector('.btn-confirm');
52
+
53
+ $btnConfirm.onclick = () => this.#handleConfirm();
52
54
  this.shadowRoot.querySelector('.btn-cancel').onclick = () => this.#handleCancel();
55
+
56
+ this.#diffView.addEventListener('change-dirty', (e) => {
57
+ const { isDirty } = e.detail;
58
+ console.log(e);
59
+ $btnConfirm.disabled = !isDirty; // 수정되었을 때만 저장 버튼 활성화
60
+ });
53
61
  }
54
62
 
55
63
  popup() {