RobinsAIWorld commited on
Commit
1ff18d9
·
verified ·
1 Parent(s): 527614f

🐳 10/02 - 14:38 - omg and the popup confirmation for deletion of a single value or key or line is just extra and dramatic. No confirmation for a single key or value or line deletion please

Browse files
Files changed (2) hide show
  1. script.js +56 -11
  2. style.css +11 -0
script.js CHANGED
@@ -554,17 +554,40 @@ document.addEventListener('DOMContentLoaded', function() {
554
  const originalText = span.textContent;
555
  const originalWidth = span.offsetWidth;
556
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  const input = document.createElement('input');
558
  input.type = 'text';
559
  input.value = displayValue !== undefined ? displayValue : '';
560
  input.className = `editable-field ${type}-input`;
 
 
561
 
562
  // Calculate appropriate width - minimum 50px or original width + padding
563
  const calculatedWidth = Math.max(50, originalWidth + 20);
564
  input.style.width = `${calculatedWidth}px`;
 
 
 
 
 
565
 
566
- // Replace span with input
567
- span.parentNode.replaceChild(input, span);
568
  input.focus();
569
  input.select();
570
 
@@ -584,6 +607,19 @@ document.addEventListener('DOMContentLoaded', function() {
584
  // Save on blur or Enter
585
  const saveEdit = () => {
586
  const newValue = input.value.trim();
 
 
 
 
 
 
 
 
 
 
 
 
 
587
 
588
  if (type === 'key') {
589
  // Rename the key
@@ -591,7 +627,7 @@ document.addEventListener('DOMContentLoaded', function() {
591
  renameKey(parentKey, key, newValue);
592
  } else {
593
  // Just restore the span without saving
594
- input.parentNode.replaceChild(span, input);
595
  }
596
  } else {
597
  // Update the value
@@ -600,7 +636,7 @@ document.addEventListener('DOMContentLoaded', function() {
600
  updateValue(parentKey, key, parsedValue);
601
  } else {
602
  // Just restore the span without saving
603
- input.parentNode.replaceChild(span, input);
604
  }
605
  }
606
  };
@@ -620,6 +656,10 @@ document.addEventListener('DOMContentLoaded', function() {
620
  insertNewField({ key, parentKey });
621
  }
622
  });
 
 
 
 
623
  }
624
 
625
  // Navigate to next/previous editable field
@@ -709,6 +749,9 @@ document.addEventListener('DOMContentLoaded', function() {
709
  newKey = `newField${fieldCounter++}`;
710
  }
711
 
 
 
 
712
  if (parentKey === 'root') {
713
  const keys = Object.keys(jsonData);
714
  const index = keys.indexOf(key);
@@ -966,6 +1009,9 @@ document.addEventListener('DOMContentLoaded', function() {
966
  newKey = `newField${counter++}`;
967
  }
968
 
 
 
 
969
  if (Array.isArray(parent)) {
970
  const index = parseInt(contextMenuKey);
971
  if (!isNaN(index) && index >= 0) {
@@ -1017,13 +1063,12 @@ document.addEventListener('DOMContentLoaded', function() {
1017
  });
1018
 
1019
  document.getElementById('ctxDelete').addEventListener('click', () => {
1020
- if (confirm(`Delete "${contextMenuKey}"?`)) {
1021
- removeFromParent(contextMenuParentKey, contextMenuKey);
1022
- renderEditor();
1023
- updateOutput();
1024
- saveToHistory();
1025
- showSavedIndicator();
1026
- }
1027
  contextMenu.style.display = 'none';
1028
  });
1029
 
 
554
  const originalText = span.textContent;
555
  const originalWidth = span.offsetWidth;
556
 
557
+ // Create a wrapper div to hold both the hint and input
558
+ const wrapper = document.createElement('div');
559
+ wrapper.style.position = 'relative';
560
+ wrapper.style.display = 'inline-block';
561
+
562
+ // Create the faint hint text
563
+ const hint = document.createElement('span');
564
+ hint.textContent = originalText;
565
+ hint.className = 'editable-hint';
566
+ hint.style.position = 'absolute';
567
+ hint.style.left = '0';
568
+ hint.style.top = '0';
569
+ hint.style.pointerEvents = 'none';
570
+ hint.style.opacity = '0.25';
571
+ hint.style.whiteSpace = 'pre';
572
+
573
  const input = document.createElement('input');
574
  input.type = 'text';
575
  input.value = displayValue !== undefined ? displayValue : '';
576
  input.className = `editable-field ${type}-input`;
577
+ input.style.position = 'relative';
578
+ input.style.backgroundColor = 'transparent';
579
 
580
  // Calculate appropriate width - minimum 50px or original width + padding
581
  const calculatedWidth = Math.max(50, originalWidth + 20);
582
  input.style.width = `${calculatedWidth}px`;
583
+ hint.style.width = `${calculatedWidth}px`;
584
+
585
+ // Build wrapper: hint behind, input on top
586
+ wrapper.appendChild(hint);
587
+ wrapper.appendChild(input);
588
 
589
+ // Replace span with wrapper
590
+ span.parentNode.replaceChild(wrapper, span);
591
  input.focus();
592
  input.select();
593
 
 
607
  // Save on blur or Enter
608
  const saveEdit = () => {
609
  const newValue = input.value.trim();
610
+ const wrapper = input.parentNode;
611
+
612
+ // Check if this is a newly inserted field that's still empty
613
+ const isNewField = key === 'newField' || (key && key.startsWith('newField'));
614
+ const isEmptyValue = (type === 'value' && newValue === '') || (type === 'key' && newValue === '');
615
+
616
+ // If it's a new field and still empty, auto-delete it
617
+ if (isNewField && isEmptyValue) {
618
+ removeFromParent(parentKey, key);
619
+ renderEditor();
620
+ updateOutput();
621
+ return;
622
+ }
623
 
624
  if (type === 'key') {
625
  // Rename the key
 
627
  renameKey(parentKey, key, newValue);
628
  } else {
629
  // Just restore the span without saving
630
+ wrapper.parentNode.replaceChild(span, wrapper);
631
  }
632
  } else {
633
  // Update the value
 
636
  updateValue(parentKey, key, parsedValue);
637
  } else {
638
  // Just restore the span without saving
639
+ wrapper.parentNode.replaceChild(span, wrapper);
640
  }
641
  }
642
  };
 
656
  insertNewField({ key, parentKey });
657
  }
658
  });
659
+
660
+ // Track that we're editing so we don't auto-delete this field
661
+ const wrapper = input.parentNode;
662
+ wrapper.dataset.isEditing = 'true';
663
  }
664
 
665
  // Navigate to next/previous editable field
 
749
  newKey = `newField${fieldCounter++}`;
750
  }
751
 
752
+ // Mark this as a new field for tracking
753
+ newKey = newKey + '_new';
754
+
755
  if (parentKey === 'root') {
756
  const keys = Object.keys(jsonData);
757
  const index = keys.indexOf(key);
 
1009
  newKey = `newField${counter++}`;
1010
  }
1011
 
1012
+ // Mark as new field
1013
+ newKey = newKey + '_new';
1014
+
1015
  if (Array.isArray(parent)) {
1016
  const index = parseInt(contextMenuKey);
1017
  if (!isNaN(index) && index >= 0) {
 
1063
  });
1064
 
1065
  document.getElementById('ctxDelete').addEventListener('click', () => {
1066
+ // No confirmation - just delete
1067
+ removeFromParent(contextMenuParentKey, contextMenuKey);
1068
+ renderEditor();
1069
+ updateOutput();
1070
+ saveToHistory();
1071
+ showSavedIndicator();
 
1072
  contextMenu.style.display = 'none';
1073
  });
1074
 
style.css CHANGED
@@ -278,11 +278,13 @@ p {
278
  min-width: 30px;
279
  transition: all 0.2s ease;
280
  outline: none;
 
281
  }
282
 
283
  .editable-field:focus {
284
  background: rgba(255,255,255,0.15);
285
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.3);
 
286
  }
287
 
288
  .editable-field.key-input {
@@ -293,6 +295,15 @@ p {
293
  color: #6ee7b7;
294
  }
295
 
 
 
 
 
 
 
 
 
 
296
  /* Saved indicator */
297
  .saved-indicator {
298
  position: fixed;
 
278
  min-width: 30px;
279
  transition: all 0.2s ease;
280
  outline: none;
281
+ color: inherit;
282
  }
283
 
284
  .editable-field:focus {
285
  background: rgba(255,255,255,0.15);
286
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.3);
287
+ color: inherit;
288
  }
289
 
290
  .editable-field.key-input {
 
295
  color: #6ee7b7;
296
  }
297
 
298
+ /* Faint hint behind editable field */
299
+ .editable-hint {
300
+ font-family: inherit;
301
+ font-size: inherit;
302
+ color: inherit;
303
+ user-select: none;
304
+ z-index: -1;
305
+ }
306
+
307
  /* Saved indicator */
308
  .saved-indicator {
309
  position: fixed;