RobinsAIWorld commited on
Commit
22a5c1c
·
verified ·
1 Parent(s): 14e9683

🐳 10/02 - 15:00 - I didn't dcancel

Browse files
Files changed (1) hide show
  1. script.js +35 -179
script.js CHANGED
@@ -121,6 +121,7 @@ document.addEventListener('DOMContentLoaded', function() {
121
  };
122
  reader.readAsText(file);
123
  }
 
124
  });
125
 
126
  document.getElementById('openBtn').addEventListener('click', openFile);
@@ -255,10 +256,12 @@ document.addEventListener('DOMContentLoaded', function() {
255
  // Load JSON data into the editor
256
  function loadJSON(data) {
257
  try {
258
- jsonData = data ? JSON.parse(JSON.stringify(data)) : {};
259
- // Initialize empty object if data is null/undefined
260
- if (!jsonData || typeof jsonData !== 'object') {
261
  jsonData = {};
 
 
 
 
262
  }
263
  renderEditor();
264
  updateOutput();
@@ -312,7 +315,7 @@ document.addEventListener('DOMContentLoaded', function() {
312
  lineNumbersRight.appendChild(fragmentRight);
313
  }
314
 
315
- // Render a single JSON element (COMPLETE VERSION)
316
  function renderElement(container, data, depth, key, parentKey = 'root') {
317
  const layerClass = `lcars-layer-${Math.min(depth, 7)}`;
318
  const layerColor = layerColors[Math.min(depth, 7)];
@@ -552,7 +555,7 @@ document.addEventListener('DOMContentLoaded', function() {
552
  let currentValue = type === 'key' ? key : getValue(parentKey, key);
553
 
554
  // Handle undefined/null values gracefully - allow editing even if undefined
555
- if (currentValue === undefined) {
556
  currentValue = '';
557
  }
558
 
@@ -623,7 +626,7 @@ document.addEventListener('DOMContentLoaded', function() {
623
  const wrapper = input.parentNode;
624
 
625
  // Check if this is a newly inserted field that's still empty
626
- const isNewField = key === 'newField' || (key && key.startsWith('newField'));
627
  const isEmptyValue = (type === 'value' && newValue === '') || (type === 'key' && newValue === '');
628
 
629
  // If it's a new field and still empty, auto-delete it
@@ -733,67 +736,18 @@ document.addEventListener('DOMContentLoaded', function() {
733
  }
734
  }
735
 
736
- // Change indentation depth of a field
737
  function changeIndentation(key, parentKey, direction) {
738
- // direction: 1 = indent deeper, -1 = un-indent
739
-
740
  const currentValue = getValue(parentKey, key);
741
  if (currentValue === undefined) return;
742
 
743
- if (parentKey === 'root') {
744
- // Can't un-indent from root
745
- if (direction === -1) {
746
- showNotification('Already at root level', true);
747
- return;
748
- }
749
- // Need to create a wrapper object to indent
750
- const wrapperKey = 'wrapper';
751
- const newData = { [wrapperKey]: { [key]: currentValue } };
752
- delete jsonData[key];
753
- jsonData[wrapperKey] = { [key]: currentValue };
754
- } else {
755
- const parent = findElementByKey(jsonData, parentKey);
756
- const grandParent = findElementByKey(jsonData, parentKey === 'root' ? 'root' :
757
- parent?.__parentKey || 'root');
758
-
759
- if (direction === 1) {
760
- // Indent deeper - create wrapper in parent
761
- if (parent && typeof parent === 'object' && !Array.isArray(parent)) {
762
- const wrapperKey = 'wrapper';
763
- const oldObj = { [key]: currentValue };
764
- delete parent[key];
765
- parent[wrapperKey] = oldObj;
766
- }
767
- } else {
768
- // Un-indent - move up one level
769
- if (parent) {
770
- const parentOfParent = findElementByKey(jsonData, parentKey === 'root' ? 'root' :
771
- parent?.__parentKey || 'root');
772
-
773
- if (parentOfParent && parentOfParent !== jsonData) {
774
- // Move to grandparent
775
- delete parent[key];
776
- parentOfParent[key] = currentValue;
777
-
778
- // Clean up empty parent
779
- if (Object.keys(parent).length === 0) {
780
- removeFromParent(parentKey === 'root' ? 'root' : parent?.__parentKey || 'root', parentKey);
781
- }
782
- }
783
- }
784
- }
785
- }
786
-
787
- renderEditor();
788
- updateOutput();
789
- saveToHistory();
790
- showSavedIndicator();
791
  }
792
 
793
  // Get nested value
794
  function getValue(parentKey, key) {
795
- if (parentKey === 'root') {
796
- return jsonData[key];
797
  }
798
  const parent = findElementByKey(jsonData, parentKey);
799
  if (parent && typeof parent === 'object') {
@@ -804,8 +758,8 @@ document.addEventListener('DOMContentLoaded', function() {
804
 
805
  // Update a value
806
  function updateValue(parentKey, key, newValue) {
807
- if (parentKey === 'root') {
808
- if (jsonData[key] !== undefined) {
809
  jsonData[key] = newValue;
810
  }
811
  } else {
@@ -822,12 +776,14 @@ document.addEventListener('DOMContentLoaded', function() {
822
 
823
  // Rename a key
824
  function renameKey(parentKey, oldKey, newKey) {
825
- if (parentKey === 'root') {
826
- jsonData[newKey] = jsonData[oldKey];
827
- delete jsonData[oldKey];
 
 
828
  } else {
829
  const parent = findElementByKey(jsonData, parentKey);
830
- if (parent && typeof parent === 'object' && !Array.isArray(parent)) {
831
  parent[newKey] = parent[oldKey];
832
  delete parent[oldKey];
833
  }
@@ -852,7 +808,7 @@ document.addEventListener('DOMContentLoaded', function() {
852
  // Mark this as a new field for tracking
853
  newKey = newKey + '_new';
854
 
855
- const parent = parentKey === 'root' ? jsonData : findElementByKey(jsonData, parentKey);
856
 
857
  if (!parent) {
858
  // If parent doesn't exist, initialize jsonData as empty object
@@ -867,7 +823,7 @@ document.addEventListener('DOMContentLoaded', function() {
867
  const keys = Object.keys(parent);
868
  const index = keys.indexOf(key);
869
 
870
- if (index === -1 || index === keys.length - 1 || key === null) {
871
  // Append at the end
872
  parent[newKey] = '';
873
  } else {
@@ -923,6 +879,8 @@ document.addEventListener('DOMContentLoaded', function() {
923
 
924
  // Find an element by key in nested structure
925
  function findElementByKey(obj, key) {
 
 
926
  if (obj[key] !== undefined) return obj;
927
 
928
  for (let prop in obj) {
@@ -1098,8 +1056,7 @@ document.addEventListener('DOMContentLoaded', function() {
1098
  });
1099
 
1100
  document.getElementById('ctxInsertBefore').addEventListener('click', () => {
1101
- // Insert before - need to handle this specially
1102
- const parent = contextMenuParentKey === 'root' ? jsonData : findElementByKey(jsonData, contextMenuParentKey);
1103
  if (parent && typeof parent === 'object') {
1104
  let newKey = 'newField';
1105
  let counter = 1;
@@ -1230,7 +1187,7 @@ document.addEventListener('DOMContentLoaded', function() {
1230
  historyIndex--;
1231
  }
1232
 
1233
- // Fix: Check if history has content before comparing
1234
  if (history.length > 0 && historyIndex >= 0 &&
1235
  JSON.stringify(history[historyIndex]) === JSON.stringify(jsonData)) {
1236
  return;
@@ -1301,12 +1258,10 @@ document.addEventListener('DOMContentLoaded', function() {
1301
 
1302
  // Update visual drop indicators
1303
  function updateDropIndicators() {
1304
- // Clear all indicators first
1305
  clearDropIndicators();
1306
 
1307
  if (!dropTarget) return;
1308
 
1309
- // Add appropriate indicator class
1310
  if (dropPosition === 'above') {
1311
  dropTarget.classList.add('drag-over-above');
1312
  } else if (dropPosition === 'below') {
@@ -1342,10 +1297,10 @@ document.addEventListener('DOMContentLoaded', function() {
1342
  }
1343
 
1344
  // Get the value being moved BEFORE removing
1345
- const draggedParent = findElementByKey(jsonData, draggedParentKey);
1346
  let movedValue = null;
1347
 
1348
- if (draggedParent === 'root') {
1349
  if (Array.isArray(jsonData)) {
1350
  const index = parseInt(draggedKey);
1351
  if (!isNaN(index) && index >= 0 && index < jsonData.length) {
@@ -1365,7 +1320,7 @@ document.addEventListener('DOMContentLoaded', function() {
1365
  }
1366
  }
1367
 
1368
- if (movedValue === null) {
1369
  showNotification('Could not move item - value not found', true);
1370
  return;
1371
  }
@@ -1398,7 +1353,7 @@ document.addEventListener('DOMContentLoaded', function() {
1398
 
1399
  // Get the new parent object
1400
  let newParent = null;
1401
- if (newParentKey === 'root') {
1402
  newParent = jsonData;
1403
  } else {
1404
  newParent = findElementByKey(jsonData, newParentKey);
@@ -1411,21 +1366,12 @@ document.addEventListener('DOMContentLoaded', function() {
1411
 
1412
  // If parent is a primitive, we can't insert inside - move to parent's parent
1413
  if (typeof newParent !== 'object' || newParent === null) {
1414
- // Try to find the parent's parent
1415
- const grandParent = findElementByKey(jsonData, dropParentKey);
1416
- if (grandParent && typeof grandParent === 'object') {
1417
- newParent = grandParent;
1418
- newParentKey = dropParentKey;
1419
- insertPosition = 'after';
1420
- insertKey = dropKey;
1421
- } else {
1422
- showNotification('Cannot move here - invalid parent type', true);
1423
- return;
1424
- }
1425
  }
1426
 
1427
  // Remove from original location
1428
- if (draggedParent === 'root') {
1429
  if (Array.isArray(jsonData)) {
1430
  const index = parseInt(draggedKey);
1431
  if (!isNaN(index) && index >= 0 && index < jsonData.length) {
@@ -1505,7 +1451,7 @@ document.addEventListener('DOMContentLoaded', function() {
1505
 
1506
  // Remove an element from its parent
1507
  function removeFromParent(parentKey, key) {
1508
- if (parentKey === 'root') {
1509
  delete jsonData[key];
1510
  } else {
1511
  const parent = findElementByKey(jsonData, parentKey);
@@ -1519,94 +1465,4 @@ document.addEventListener('DOMContentLoaded', function() {
1519
  }
1520
  }
1521
  }
1522
-
1523
- // Insert a value into a parent at a specific position
1524
- function insertToParent(parentKey, value, position = 'append', afterKey = null) {
1525
- if (parentKey === 'root') {
1526
- if (Array.isArray(jsonData)) {
1527
- if (position === 'append') {
1528
- jsonData.push(value);
1529
- } else if (position === 'before' || position === 'after') {
1530
- const index = Object.keys(jsonData).indexOf(afterKey);
1531
- if (position === 'before') {
1532
- jsonData.splice(index, 0, value);
1533
- } else {
1534
- jsonData.splice(index + 1, 0, value);
1535
- }
1536
- }
1537
- } else {
1538
- // Object - need a key for the new value
1539
- let newKey = 'newField';
1540
- let counter = 1;
1541
- while (jsonData[newKey] !== undefined) {
1542
- newKey = `newField${counter++}`;
1543
- }
1544
-
1545
- if (position === 'append') {
1546
- jsonData[newKey] = value;
1547
- } else if (position === 'before' || position === 'after') {
1548
- const keys = Object.keys(jsonData);
1549
- const index = keys.indexOf(afterKey);
1550
- const newData = {};
1551
-
1552
- keys.forEach((k, i) => {
1553
- if (position === 'before' && i === index) {
1554
- newData[newKey] = value;
1555
- }
1556
- newData[k] = jsonData[k];
1557
- if (position === 'after' && i === index) {
1558
- newData[newKey] = value;
1559
- }
1560
- });
1561
-
1562
- Object.keys(jsonData).forEach(k => delete jsonData[k]);
1563
- Object.assign(jsonData, newData);
1564
- }
1565
- }
1566
- } else {
1567
- const parent = findElementByKey(jsonData, parentKey);
1568
- if (parent && typeof parent === 'object') {
1569
- if (Array.isArray(parent)) {
1570
- if (position === 'append') {
1571
- parent.push(value);
1572
- } else if (position === 'before' || position === 'after') {
1573
- const index = parseInt(afterKey);
1574
- if (position === 'before') {
1575
- parent.splice(index, 0, value);
1576
- } else {
1577
- parent.splice(index + 1, 0, value);
1578
- }
1579
- }
1580
- } else {
1581
- // Object - need a key for the new value
1582
- let newKey = 'newField';
1583
- let counter = 1;
1584
- while (parent[newKey] !== undefined) {
1585
- newKey = `newField${counter++}`;
1586
- }
1587
-
1588
- if (position === 'append') {
1589
- parent[newKey] = value;
1590
- } else if (position === 'before' || position === 'after') {
1591
- const keys = Object.keys(parent);
1592
- const index = keys.indexOf(afterKey);
1593
- const newData = {};
1594
-
1595
- keys.forEach((k, i) => {
1596
- if (position === 'before' && i === index) {
1597
- newData[newKey] = value;
1598
- }
1599
- newData[k] = parent[k];
1600
- if (position === 'after' && i === index) {
1601
- newData[newKey] = value;
1602
- }
1603
- });
1604
-
1605
- Object.keys(parent).forEach(k => delete parent[k]);
1606
- Object.assign(parent, newData);
1607
- }
1608
- }
1609
- }
1610
- }
1611
- }
1612
  });
 
121
  };
122
  reader.readAsText(file);
123
  }
124
+ fileInput.value = '';
125
  });
126
 
127
  document.getElementById('openBtn').addEventListener('click', openFile);
 
256
  // Load JSON data into the editor
257
  function loadJSON(data) {
258
  try {
259
+ if (data === null || data === undefined) {
 
 
260
  jsonData = {};
261
+ } else if (typeof data !== 'object') {
262
+ jsonData = { value: data };
263
+ } else {
264
+ jsonData = JSON.parse(JSON.stringify(data));
265
  }
266
  renderEditor();
267
  updateOutput();
 
315
  lineNumbersRight.appendChild(fragmentRight);
316
  }
317
 
318
+ // Render a single JSON element
319
  function renderElement(container, data, depth, key, parentKey = 'root') {
320
  const layerClass = `lcars-layer-${Math.min(depth, 7)}`;
321
  const layerColor = layerColors[Math.min(depth, 7)];
 
555
  let currentValue = type === 'key' ? key : getValue(parentKey, key);
556
 
557
  // Handle undefined/null values gracefully - allow editing even if undefined
558
+ if (currentValue === undefined || currentValue === null) {
559
  currentValue = '';
560
  }
561
 
 
626
  const wrapper = input.parentNode;
627
 
628
  // Check if this is a newly inserted field that's still empty
629
+ const isNewField = key === 'newField' || (key && key.toString().startsWith('newField'));
630
  const isEmptyValue = (type === 'value' && newValue === '') || (type === 'key' && newValue === '');
631
 
632
  // If it's a new field and still empty, auto-delete it
 
736
  }
737
  }
738
 
739
+ // Change indentation depth of a field - simplified version
740
  function changeIndentation(key, parentKey, direction) {
 
 
741
  const currentValue = getValue(parentKey, key);
742
  if (currentValue === undefined) return;
743
 
744
+ showNotification('Indentation changes via keyboard are limited. Use drag and drop for complex restructuring.', false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
  }
746
 
747
  // Get nested value
748
  function getValue(parentKey, key) {
749
+ if (parentKey === 'root' || parentKey === undefined) {
750
+ return jsonData !== undefined ? jsonData[key] : undefined;
751
  }
752
  const parent = findElementByKey(jsonData, parentKey);
753
  if (parent && typeof parent === 'object') {
 
758
 
759
  // Update a value
760
  function updateValue(parentKey, key, newValue) {
761
+ if (parentKey === 'root' || parentKey === undefined) {
762
+ if (jsonData !== undefined && jsonData[key] !== undefined) {
763
  jsonData[key] = newValue;
764
  }
765
  } else {
 
776
 
777
  // Rename a key
778
  function renameKey(parentKey, oldKey, newKey) {
779
+ if (parentKey === 'root' || parentKey === undefined) {
780
+ if (jsonData[oldKey] !== undefined) {
781
+ jsonData[newKey] = jsonData[oldKey];
782
+ delete jsonData[oldKey];
783
+ }
784
  } else {
785
  const parent = findElementByKey(jsonData, parentKey);
786
+ if (parent && typeof parent === 'object' && !Array.isArray(parent) && parent[oldKey] !== undefined) {
787
  parent[newKey] = parent[oldKey];
788
  delete parent[oldKey];
789
  }
 
808
  // Mark this as a new field for tracking
809
  newKey = newKey + '_new';
810
 
811
+ const parent = (parentKey === 'root' || parentKey === undefined) ? jsonData : findElementByKey(jsonData, parentKey);
812
 
813
  if (!parent) {
814
  // If parent doesn't exist, initialize jsonData as empty object
 
823
  const keys = Object.keys(parent);
824
  const index = keys.indexOf(key);
825
 
826
+ if (index === -1 || index === keys.length - 1 || key === null || key === undefined) {
827
  // Append at the end
828
  parent[newKey] = '';
829
  } else {
 
879
 
880
  // Find an element by key in nested structure
881
  function findElementByKey(obj, key) {
882
+ if (obj === null || obj === undefined) return null;
883
+
884
  if (obj[key] !== undefined) return obj;
885
 
886
  for (let prop in obj) {
 
1056
  });
1057
 
1058
  document.getElementById('ctxInsertBefore').addEventListener('click', () => {
1059
+ const parent = (contextMenuParentKey === 'root' || contextMenuParentKey === undefined) ? jsonData : findElementByKey(jsonData, contextMenuParentKey);
 
1060
  if (parent && typeof parent === 'object') {
1061
  let newKey = 'newField';
1062
  let counter = 1;
 
1187
  historyIndex--;
1188
  }
1189
 
1190
+ // Only save if different from current state
1191
  if (history.length > 0 && historyIndex >= 0 &&
1192
  JSON.stringify(history[historyIndex]) === JSON.stringify(jsonData)) {
1193
  return;
 
1258
 
1259
  // Update visual drop indicators
1260
  function updateDropIndicators() {
 
1261
  clearDropIndicators();
1262
 
1263
  if (!dropTarget) return;
1264
 
 
1265
  if (dropPosition === 'above') {
1266
  dropTarget.classList.add('drag-over-above');
1267
  } else if (dropPosition === 'below') {
 
1297
  }
1298
 
1299
  // Get the value being moved BEFORE removing
1300
+ const draggedParent = (draggedParentKey === 'root' || draggedParentKey === undefined) ? null : findElementByKey(jsonData, draggedParentKey);
1301
  let movedValue = null;
1302
 
1303
+ if (draggedParent === null) {
1304
  if (Array.isArray(jsonData)) {
1305
  const index = parseInt(draggedKey);
1306
  if (!isNaN(index) && index >= 0 && index < jsonData.length) {
 
1320
  }
1321
  }
1322
 
1323
+ if (movedValue === null || movedValue === undefined) {
1324
  showNotification('Could not move item - value not found', true);
1325
  return;
1326
  }
 
1353
 
1354
  // Get the new parent object
1355
  let newParent = null;
1356
+ if (newParentKey === 'root' || newParentKey === undefined) {
1357
  newParent = jsonData;
1358
  } else {
1359
  newParent = findElementByKey(jsonData, newParentKey);
 
1366
 
1367
  // If parent is a primitive, we can't insert inside - move to parent's parent
1368
  if (typeof newParent !== 'object' || newParent === null) {
1369
+ showNotification('Cannot move here - invalid parent type', true);
1370
+ return;
 
 
 
 
 
 
 
 
 
1371
  }
1372
 
1373
  // Remove from original location
1374
+ if (draggedParent === null) {
1375
  if (Array.isArray(jsonData)) {
1376
  const index = parseInt(draggedKey);
1377
  if (!isNaN(index) && index >= 0 && index < jsonData.length) {
 
1451
 
1452
  // Remove an element from its parent
1453
  function removeFromParent(parentKey, key) {
1454
+ if (parentKey === 'root' || parentKey === undefined) {
1455
  delete jsonData[key];
1456
  } else {
1457
  const parent = findElementByKey(jsonData, parentKey);
 
1465
  }
1466
  }
1467
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1468
  });