RobinsAIWorld commited on
Commit
f80e511
·
verified ·
1 Parent(s): e912915

I tried to paste in clipboard contents of mcp_config.json but it again opened the deepsite editor pane - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +345 -100
index.html CHANGED
@@ -25,35 +25,73 @@
25
  min-height: 500px;
26
  max-height: 70vh;
27
  overflow-y: auto;
 
 
 
 
 
28
  }
29
  .json-item {
30
  transition: all 0.2s ease;
 
 
 
 
 
 
 
 
 
 
 
 
31
  border-left: 3px solid transparent;
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  .json-item:hover {
34
- background-color: #f1f5f9;
35
- border-left: 3px solid #3b82f6;
36
  }
37
  .json-item.selected {
38
- background-color: #dbeafe;
39
- border-left: 3px solid #3b82f6;
 
 
 
 
 
 
40
  }
41
  .json-item.dragging {
42
  opacity: 0.5;
43
- background-color: #dbeafe;
44
  }
45
  .json-item.drag-over {
46
- border-top: 2px dashed #3b82f6;
47
  }
48
  .json-key {
49
  font-weight: 600;
50
- color: #4338ca;
 
51
  }
52
  .json-value {
53
- color: #0f766e;
54
  }
55
  .json-bracket {
56
- color: #64748b;
57
  }
58
  .btn {
59
  transition: all 0.2s ease;
@@ -67,27 +105,30 @@
67
  top: 0;
68
  bottom: 0;
69
  width: 1px;
70
- background-color: #cbd5e1;
71
  }
72
  .cursor-pointer {
73
  cursor: pointer;
74
  }
75
  .editable:focus {
76
- outline: 2px solid #3b82f6;
77
  border-radius: 4px;
78
  }
79
  .editable {
80
  min-width: 20px;
81
  display: inline-block;
 
 
 
82
  }
83
  .toolbar-btn {
84
  transition: all 0.2s;
85
  }
86
  .toolbar-btn:hover {
87
- background-color: #e2e8f0;
88
  }
89
  .toolbar-btn.active {
90
- background-color: #3b82f6;
91
  color: white;
92
  }
93
  .notification {
@@ -101,40 +142,169 @@
101
  background-color: #fee2e2;
102
  border-left: 3px solid #ef4444;
103
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  </style>
105
  </head>
106
- <body class="bg-gray-100 min-h-screen p-4 md:p-8">
107
  <div class="max-w-6xl mx-auto">
108
  <header class="mb-8 text-center">
109
- <h1 class="text-3xl md:text-4xl font-bold text-gray-800 mb-2">Visual JSON Editor</h1>
110
- <p class="text-gray-600">Edit JSON with drag-and-drop and intuitive keyboard navigation</p>
111
  </header>
112
 
113
- <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-8">
114
- <div class="p-4 bg-gray-50 border-b flex flex-wrap items-center justify-between gap-2">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  <div class="flex flex-wrap gap-2">
116
- <button id="newBtn" class="btn bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg flex items-center gap-2">
117
  <i class="fas fa-plus"></i> New
118
  </button>
119
- <button id="loadBtn" class="btn bg-gray-200 hover:bg-gray-300 px-4 py-2 rounded-lg flex items-center gap-2">
120
- <i class="fas fa-folder-open"></i> Load
121
  </button>
122
- <button id="saveBtn" class="btn bg-gray-200 hover:bg-gray-300 px-4 py-2 rounded-lg flex items-center gap-2">
123
  <i class="fas fa-save"></i> Save
124
  </button>
125
  </div>
126
 
127
  <div class="flex flex-wrap gap-2">
128
- <button id="undoBtn" class="btn bg-gray-200 hover:bg-gray-300 px-3 py-2 rounded-lg">
129
  <i class="fas fa-undo"></i>
130
  </button>
131
- <button id="redoBtn" class="btn bg-gray-200 hover:bg-gray-300 px-3 py-2 rounded-lg">
132
  <i class="fas fa-redo"></i>
133
  </button>
134
- <button id="formatBtn" class="btn bg-gray-200 hover:bg-gray-300 px-3 py-2 rounded-lg">
135
  <i class="fas fa-indent"></i>
136
  </button>
137
- <button id="validateBtn" class="btn bg-gray-200 hover:bg-gray-300 px-3 py-2 rounded-lg">
138
  <i class="fas fa-check-circle"></i>
139
  </button>
140
  </div>
@@ -159,10 +329,10 @@
159
  </div>
160
 
161
  <div class="p-4 flex flex-col md:flex-row gap-4">
162
- <div class="w-full md:w-1/2">
163
- <div class="bg-gray-50 rounded-lg p-4 mb-4">
164
- <h2 class="text-lg font-semibold text-gray-700 mb-2">JSON Editor</h2>
165
- <div id="jsonEditor" class="json-editor bg-white border rounded-lg p-4 font-mono min-h-[400px] relative">
166
  <!-- JSON content will be rendered here -->
167
  </div>
168
  </div>
@@ -183,66 +353,9 @@
183
 
184
  <div class="w-full md:w-1/2">
185
  <div class="bg-gray-50 rounded-lg p-4 h-full">
186
- <h2 class="text-lg font-semibold text-gray-700 mb-2">Instructions</h2>
187
  <div class="bg-white border rounded-lg p-4 h-[400px] overflow-y-auto">
188
- <ul class="space-y-3 text-gray-700">
189
- <li class="flex items-start">
190
- <i class="fas fa-mouse-pointer text-primary mt-1 mr-2"></i>
191
- <div>
192
- <span class="font-medium">Double-click</span> to edit any element
193
- </div>
194
- </li>
195
- <li class="flex items-start">
196
- <i class="fas fa-arrows-alt text-primary mt-1 mr-2"></i>
197
- <div>
198
- <span class="font-medium">Drag and drop</span> elements to reorganize
199
- </div>
200
- </li>
201
- <li class="flex items-start">
202
- <i class="fas fa-keyboard text-primary mt-1 mr-2"></i>
203
- <div>
204
- <span class="font-medium">Keyboard navigation:</span>
205
- <ul class="ml-5 mt-1 space-y-1">
206
- <li>• <span class="font-mono">Tab</span> / <span class="font-mono">Shift+Tab</span> to change indent level</li>
207
- <li>• <span class="font-mono">Enter</span> to create new element at same level</li>
208
- <li>• <span class="font-mono">Shift+Enter</span> to create child element</li>
209
- <li>• <span class="font-mono">Arrow keys</span> to navigate between elements</li>
210
- <li>• <span class="font-mono">Delete</span> to remove selected element</li>
211
- </ul>
212
- </div>
213
- </li>
214
- <li class="flex items-start">
215
- <i class="fas fa-paste text-primary mt-1 mr-2"></i>
216
- <div>
217
- <span class="font-medium">Paste JSON</span> to automatically parse and render
218
- </div>
219
- </li>
220
- <li class="flex items-start">
221
- <i class="fas fa-wrench text-primary mt-1 mr-2"></i>
222
- <div>
223
- <span class="font-medium">Auto-repair</span> fixes common JSON syntax errors
224
- </div>
225
- </li>
226
- </ul>
227
-
228
- <div class="mt-6 p-4 bg-blue-50 rounded-lg border border-blue-200">
229
- <h3 class="font-semibold text-blue-800 mb-2">Try this sample JSON:</h3>
230
- <pre class="text-sm bg-white p-3 rounded overflow-x-auto">{
231
- "name": "John Doe",
232
- "age": 30,
233
- "address": {
234
- "street": "123 Main St",
235
- "city": "Anytown"
236
- },
237
- "hobbies": [
238
- "reading",
239
- "swimming"
240
- ]
241
- }</pre>
242
- <button id="loadSampleBtn" class="mt-3 btn bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg">
243
- Load Sample
244
- </button>
245
- </div>
246
  </div>
247
  </div>
248
  </div>
@@ -313,7 +426,8 @@
313
  // DOM elements
314
  const jsonEditor = document.getElementById('jsonEditor');
315
  const jsonOutput = document.getElementById('jsonOutput');
316
- const loadSampleBtn = document.getElementById('loadSampleBtn');
 
317
  const notification = document.getElementById('notification');
318
  const copyBtn = document.getElementById('copyBtn');
319
  const downloadBtn = document.getElementById('downloadBtn');
@@ -328,11 +442,38 @@
328
  loadJSON(sampleJSON);
329
 
330
  // Event listeners
331
- loadSampleBtn.addEventListener('click', () => {
332
- loadJSON(sampleJSON);
333
- showNotification('Sample JSON loaded successfully!');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  });
335
 
 
 
 
336
  copyBtn.addEventListener('click', () => {
337
  jsonOutput.select();
338
  document.execCommand('copy');
@@ -369,8 +510,7 @@
369
  // Render a single JSON element
370
  function renderElement(container, data, depth, key = null, parentKey = null) {
371
  const wrapper = document.createElement('div');
372
- wrapper.className = 'json-item relative pl-6';
373
- wrapper.style.paddingLeft = `${depth * 20 + 8}px`;
374
  wrapper.dataset.key = key;
375
  wrapper.dataset.parent = parentKey;
376
  wrapper.dataset.depth = depth;
@@ -385,7 +525,8 @@
385
 
386
  // Create element content
387
  const content = document.createElement('div');
388
- content.className = 'flex items-start py-1';
 
389
 
390
  // Key
391
  if (key !== null && key !== 'root') {
@@ -414,12 +555,15 @@
414
 
415
  // Closing bracket
416
  const closingWrapper = document.createElement('div');
417
- closingWrapper.className = 'json-item relative pl-6';
418
- closingWrapper.style.paddingLeft = `${depth * 20 + 8}px`;
419
  closingWrapper.dataset.key = 'closing';
420
  closingWrapper.dataset.parent = key;
421
  closingWrapper.dataset.depth = depth;
422
 
 
 
 
 
423
  if (depth > 0) {
424
  const indentLine = document.createElement('div');
425
  indentLine.className = 'indent-line';
@@ -452,12 +596,15 @@
452
 
453
  // Closing bracket
454
  const closingWrapper = document.createElement('div');
455
- closingWrapper.className = 'json-item relative pl-6';
456
- closingWrapper.style.paddingLeft = `${depth * 20 + 8}px`;
457
  closingWrapper.dataset.key = 'closing';
458
  closingWrapper.dataset.parent = key;
459
  closingWrapper.dataset.depth = depth;
460
 
 
 
 
 
461
  if (depth > 0) {
462
  const indentLine = document.createElement('div');
463
  indentLine.className = 'indent-line';
@@ -708,6 +855,104 @@
708
  document.getElementById('undoBtn').addEventListener('click', undo);
709
  document.getElementById('redoBtn').addEventListener('click', redo);
710
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
  // Format JSON
712
  document.getElementById('formatBtn').addEventListener('click', () => {
713
  updateOutput();
 
25
  min-height: 500px;
26
  max-height: 70vh;
27
  overflow-y: auto;
28
+ background-color: #1e293b;
29
+ background-image: radial-gradient(#334155 1px, transparent 1px);
30
+ background-size: 20px 20px;
31
+ padding: 20px;
32
+ border-radius: 8px;
33
  }
34
  .json-item {
35
  transition: all 0.2s ease;
36
+ margin: 5px 0;
37
+ border-radius: 6px;
38
+ background-color: #334155;
39
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
40
+ position: relative;
41
+ display: block;
42
+ }
43
+ .json-item-content {
44
+ padding: 8px 12px;
45
+ margin-left: 0;
46
+ display: inline-block;
47
+ min-width: 200px;
48
  border-left: 3px solid transparent;
49
  }
50
+ .json-item:hover .json-item-content {
51
+ background-color: #475569;
52
+ border-left: 3px solid #60a5fa;
53
+ }
54
+ .json-item.selected .json-item-content {
55
+ background-color: #475569;
56
+ border-left: 3px solid #60a5fa;
57
+ box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.3);
58
+ }
59
+ .json-item.editing .json-item-content {
60
+ background-color: #64748b;
61
+ border-left: 3px solid #fbbf24;
62
+ box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.5);
63
+ }
64
  .json-item:hover {
65
+ background-color: #475569;
66
+ border-left: 3px solid #60a5fa;
67
  }
68
  .json-item.selected {
69
+ background-color: #475569;
70
+ border-left: 3px solid #60a5fa;
71
+ box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.3);
72
+ }
73
+ .json-item.editing {
74
+ background-color: #64748b;
75
+ border-left: 3px solid #fbbf24;
76
+ box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.5);
77
  }
78
  .json-item.dragging {
79
  opacity: 0.5;
80
+ background-color: #475569;
81
  }
82
  .json-item.drag-over {
83
+ border-top: 2px dashed #60a5fa;
84
  }
85
  .json-key {
86
  font-weight: 600;
87
+ color: #93c5fd;
88
+ margin-right: 8px;
89
  }
90
  .json-value {
91
+ color: #6ee7b7;
92
  }
93
  .json-bracket {
94
+ color: #94a3b8;
95
  }
96
  .btn {
97
  transition: all 0.2s ease;
 
105
  top: 0;
106
  bottom: 0;
107
  width: 1px;
108
+ background-color: #475569;
109
  }
110
  .cursor-pointer {
111
  cursor: pointer;
112
  }
113
  .editable:focus {
114
+ outline: 2px solid #60a5fa;
115
  border-radius: 4px;
116
  }
117
  .editable {
118
  min-width: 20px;
119
  display: inline-block;
120
+ background-color: rgba(96, 165, 250, 0.1);
121
+ padding: 2px 4px;
122
+ border-radius: 4px;
123
  }
124
  .toolbar-btn {
125
  transition: all 0.2s;
126
  }
127
  .toolbar-btn:hover {
128
+ background-color: #475569;
129
  }
130
  .toolbar-btn.active {
131
+ background-color: #60a5fa;
132
  color: white;
133
  }
134
  .notification {
 
142
  background-color: #fee2e2;
143
  border-left: 3px solid #ef4444;
144
  }
145
+ .menu-bar {
146
+ background-color: #334155;
147
+ padding: 8px 16px;
148
+ border-radius: 8px;
149
+ margin-bottom: 16px;
150
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
151
+ }
152
+ .menu-item {
153
+ color: #cbd5e1;
154
+ padding: 8px 12px;
155
+ border-radius: 4px;
156
+ cursor: pointer;
157
+ transition: all 0.2s;
158
+ margin-right: 4px;
159
+ }
160
+ .menu-item:hover {
161
+ background-color: #475569;
162
+ }
163
+ .menu-item.active {
164
+ background-color: #60a5fa;
165
+ color: white;
166
+ }
167
+ .dropdown {
168
+ position: relative;
169
+ display: inline-block;
170
+ }
171
+ .dropdown-content {
172
+ display: none;
173
+ position: absolute;
174
+ background-color: #334155;
175
+ min-width: 160px;
176
+ box-shadow: 0px 8px 16px rgba(0,0,0,0.2);
177
+ z-index: 1;
178
+ border-radius: 4px;
179
+ overflow: hidden;
180
+ }
181
+ .dropdown-content a {
182
+ color: #cbd5e1;
183
+ padding: 12px 16px;
184
+ text-decoration: none;
185
+ display: block;
186
+ }
187
+ .dropdown-content a:hover {
188
+ background-color: #475569;
189
+ }
190
+ .dropdown:hover .dropdown-content {
191
+ display: block;
192
+ }
193
+ .modal {
194
+ display: none;
195
+ position: fixed;
196
+ z-index: 1000;
197
+ left: 0;
198
+ top: 0;
199
+ width: 100%;
200
+ height: 100%;
201
+ background-color: rgba(0,0,0,0.5);
202
+ }
203
+ .modal-content {
204
+ background-color: #334155;
205
+ margin: 10% auto;
206
+ padding: 20px;
207
+ border-radius: 8px;
208
+ width: 80%;
209
+ max-width: 600px;
210
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
211
+ color: #f1f5f9;
212
+ }
213
+ .close {
214
+ color: #94a3b8;
215
+ float: right;
216
+ font-size: 28px;
217
+ font-weight: bold;
218
+ cursor: pointer;
219
+ }
220
+ .close:hover {
221
+ color: #f1f5f9;
222
+ }
223
+ .boolean-select {
224
+ background-color: #475569;
225
+ color: #f1f5f9;
226
+ border: 1px solid #64748b;
227
+ border-radius: 4px;
228
+ padding: 2px 4px;
229
+ }
230
  </style>
231
  </head>
232
+ <body class="bg-slate-900 min-h-screen p-4 md:p-8">
233
  <div class="max-w-6xl mx-auto">
234
  <header class="mb-8 text-center">
235
+ <h1 class="text-3xl md:text-4xl font-bold text-slate-100 mb-2">Visual JSON Editor</h1>
236
+ <p class="text-slate-300">Edit JSON with drag-and-drop and intuitive keyboard navigation</p>
237
  </header>
238
 
239
+ <!-- Menu Bar -->
240
+ <div class="menu-bar flex flex-wrap">
241
+ <div class="dropdown">
242
+ <div class="menu-item">File</div>
243
+ <div class="dropdown-content">
244
+ <a href="#" id="newBtn"><i class="fas fa-plus mr-2"></i>New</a>
245
+ <a href="#" id="openBtn"><i class="fas fa-folder-open mr-2"></i>Open</a>
246
+ <a href="#" id="saveBtn"><i class="fas fa-save mr-2"></i>Save</a>
247
+ </div>
248
+ </div>
249
+ <div class="dropdown">
250
+ <div class="menu-item">Edit</div>
251
+ <div class="dropdown-content">
252
+ <a href="#" id="undoBtn"><i class="fas fa-undo mr-2"></i>Undo</a>
253
+ <a href="#" id="redoBtn"><i class="fas fa-redo mr-2"></i>Redo</a>
254
+ <a href="#" id="copyBtnMenu"><i class="fas fa-copy mr-2"></i>Copy</a>
255
+ <a href="#" id="cutBtnMenu"><i class="fas fa-cut mr-2"></i>Cut</a>
256
+ <a href="#" id="pasteBtnMenu"><i class="fas fa-paste mr-2"></i>Paste</a>
257
+ <a href="#" id="preferencesBtn"><i class="fas fa-cog mr-2"></i>Preferences</a>
258
+ </div>
259
+ </div>
260
+ <div class="dropdown">
261
+ <div class="menu-item">Tools</div>
262
+ <div class="dropdown-content">
263
+ <a href="#" id="formatBtn"><i class="fas fa-indent mr-2"></i>Format</a>
264
+ <a href="#" id="validateBtn"><i class="fas fa-check-circle mr-2"></i>Validate</a>
265
+ </div>
266
+ </div>
267
+ <div class="dropdown">
268
+ <div class="menu-item">View</div>
269
+ <div class="dropdown-content">
270
+ <a href="#" id="viewModeBtn"><i class="fas fa-eye mr-2"></i>View Mode</a>
271
+ <a href="#" id="editModeBtn"><i class="fas fa-edit mr-2"></i>Edit Mode</a>
272
+ </div>
273
+ </div>
274
+ <div class="dropdown">
275
+ <div class="menu-item">Help</div>
276
+ <div class="dropdown-content">
277
+ <a href="#" id="instructionsBtn"><i class="fas fa-info-circle mr-2"></i>Instructions</a>
278
+ <a href="#" id="sampleBtn"><i class="fas fa-code mr-2"></i>Sample JSON</a>
279
+ </div>
280
+ </div>
281
+ </div>
282
+
283
+ <div class="bg-slate-800 rounded-xl shadow-lg overflow-hidden mb-8">
284
+ <div class="p-4 bg-slate-700 border-b flex flex-wrap items-center justify-between gap-2">
285
  <div class="flex flex-wrap gap-2">
286
+ <button id="newBtn2" class="btn bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg flex items-center gap-2">
287
  <i class="fas fa-plus"></i> New
288
  </button>
289
+ <button id="openBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-4 py-2 rounded-lg flex items-center gap-2">
290
+ <i class="fas fa-folder-open"></i> Open
291
  </button>
292
+ <button id="saveBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-4 py-2 rounded-lg flex items-center gap-2">
293
  <i class="fas fa-save"></i> Save
294
  </button>
295
  </div>
296
 
297
  <div class="flex flex-wrap gap-2">
298
+ <button id="undoBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-2 rounded-lg">
299
  <i class="fas fa-undo"></i>
300
  </button>
301
+ <button id="redoBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-2 rounded-lg">
302
  <i class="fas fa-redo"></i>
303
  </button>
304
+ <button id="formatBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-2 rounded-lg">
305
  <i class="fas fa-indent"></i>
306
  </button>
307
+ <button id="validateBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-2 rounded-lg">
308
  <i class="fas fa-check-circle"></i>
309
  </button>
310
  </div>
 
329
  </div>
330
 
331
  <div class="p-4 flex flex-col md:flex-row gap-4">
332
+ <div class="w-full">
333
+ <div class="bg-slate-700 rounded-lg p-4 mb-4">
334
+ <h2 class="text-lg font-semibold text-slate-200 mb-2">JSON Editor</h2>
335
+ <div id="jsonEditor" class="json-editor border rounded-lg p-4 font-mono min-h-[400px] relative">
336
  <!-- JSON content will be rendered here -->
337
  </div>
338
  </div>
 
353
 
354
  <div class="w-full md:w-1/2">
355
  <div class="bg-gray-50 rounded-lg p-4 h-full">
356
+ <h2 class="text-lg font-semibold text-gray-700 mb-2">Preview</h2>
357
  <div class="bg-white border rounded-lg p-4 h-[400px] overflow-y-auto">
358
+ <p class="text-gray-600">JSON structure will be displayed here in view mode.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  </div>
360
  </div>
361
  </div>
 
426
  // DOM elements
427
  const jsonEditor = document.getElementById('jsonEditor');
428
  const jsonOutput = document.getElementById('jsonOutput');
429
+ const openBtn = document.getElementById('openBtn');
430
+ const openBtn2 = document.getElementById('openBtn2');
431
  const notification = document.getElementById('notification');
432
  const copyBtn = document.getElementById('copyBtn');
433
  const downloadBtn = document.getElementById('downloadBtn');
 
442
  loadJSON(sampleJSON);
443
 
444
  // Event listeners
445
+ // Create hidden file input for opening files
446
+ const fileInput = document.createElement('input');
447
+ fileInput.type = 'file';
448
+ fileInput.accept = 'application/json,.json';
449
+ fileInput.style.display = 'none';
450
+ document.body.appendChild(fileInput);
451
+
452
+ // Open file functionality
453
+ function openFile() {
454
+ fileInput.click();
455
+ }
456
+
457
+ fileInput.addEventListener('change', (event) => {
458
+ const file = event.target.files[0];
459
+ if (file) {
460
+ const reader = new FileReader();
461
+ reader.onload = (e) => {
462
+ try {
463
+ const data = JSON.parse(e.target.result);
464
+ loadJSON(data);
465
+ showNotification('File loaded successfully!');
466
+ } catch (error) {
467
+ showNotification('Error loading file: Invalid JSON');
468
+ }
469
+ };
470
+ reader.readAsText(file);
471
+ }
472
  });
473
 
474
+ openBtn.addEventListener('click', openFile);
475
+ openBtn2.addEventListener('click', openFile);
476
+
477
  copyBtn.addEventListener('click', () => {
478
  jsonOutput.select();
479
  document.execCommand('copy');
 
510
  // Render a single JSON element
511
  function renderElement(container, data, depth, key = null, parentKey = null) {
512
  const wrapper = document.createElement('div');
513
+ wrapper.className = 'json-item relative';
 
514
  wrapper.dataset.key = key;
515
  wrapper.dataset.parent = parentKey;
516
  wrapper.dataset.depth = depth;
 
525
 
526
  // Create element content
527
  const content = document.createElement('div');
528
+ content.className = 'json-item-content flex items-start py-1';
529
+ content.style.marginLeft = `${depth * 20 + 8}px`;
530
 
531
  // Key
532
  if (key !== null && key !== 'root') {
 
555
 
556
  // Closing bracket
557
  const closingWrapper = document.createElement('div');
558
+ closingWrapper.className = 'json-item relative';
 
559
  closingWrapper.dataset.key = 'closing';
560
  closingWrapper.dataset.parent = key;
561
  closingWrapper.dataset.depth = depth;
562
 
563
+ const closingContent = document.createElement('div');
564
+ closingContent.className = 'json-item-content flex items-start py-1';
565
+ closingContent.style.marginLeft = `${depth * 20 + 8}px`;
566
+
567
  if (depth > 0) {
568
  const indentLine = document.createElement('div');
569
  indentLine.className = 'indent-line';
 
596
 
597
  // Closing bracket
598
  const closingWrapper = document.createElement('div');
599
+ closingWrapper.className = 'json-item relative';
 
600
  closingWrapper.dataset.key = 'closing';
601
  closingWrapper.dataset.parent = key;
602
  closingWrapper.dataset.depth = depth;
603
 
604
+ const closingContent = document.createElement('div');
605
+ closingContent.className = 'json-item-content flex items-start py-1';
606
+ closingContent.style.marginLeft = `${depth * 20 + 8}px`;
607
+
608
  if (depth > 0) {
609
  const indentLine = document.createElement('div');
610
  indentLine.className = 'indent-line';
 
855
  document.getElementById('undoBtn').addEventListener('click', undo);
856
  document.getElementById('redoBtn').addEventListener('click', redo);
857
 
858
+ // Event listeners for copy, cut, paste
859
+ document.getElementById('copyBtnMenu').addEventListener('click', () => {
860
+ if (selectedElement) {
861
+ const range = document.createRange();
862
+ range.selectNode(selectedElement);
863
+ window.getSelection().removeAllRanges();
864
+ window.getSelection().addRange(range);
865
+ document.execCommand('copy');
866
+ window.getSelection().removeAllRanges();
867
+ showNotification('Copied to clipboard');
868
+ }
869
+ });
870
+
871
+ document.getElementById('cutBtnMenu').addEventListener('click', () => {
872
+ if (selectedElement) {
873
+ const range = document.createRange();
874
+ range.selectNode(selectedElement);
875
+ window.getSelection().removeAllRanges();
876
+ window.getSelection().addRange(range);
877
+ document.execCommand('cut');
878
+ window.getSelection().removeAllRanges();
879
+ showNotification('Cut to clipboard');
880
+ }
881
+ });
882
+
883
+ document.getElementById('pasteBtnMenu').addEventListener('click', () => {
884
+ navigator.clipboard.readText().then(text => {
885
+ // Try to parse as JSON and load if valid
886
+ try {
887
+ const data = JSON.parse(text);
888
+ loadJSON(data);
889
+ showNotification('JSON pasted successfully');
890
+ } catch (e) {
891
+ // If not valid JSON, just show notification
892
+ showNotification('Clipboard content is not valid JSON');
893
+ }
894
+ }).catch(err => {
895
+ showNotification('Failed to read clipboard contents');
896
+ });
897
+ });
898
+
899
+ // Enable pasting in JSON output pane
900
+ jsonOutput.addEventListener('paste', (e) => {
901
+ e.preventDefault();
902
+ navigator.clipboard.readText().then(text => {
903
+ try {
904
+ const data = JSON.parse(text);
905
+ loadJSON(data);
906
+ showNotification('JSON pasted successfully');
907
+ } catch (parseError) {
908
+ // If not valid JSON, paste as plain text
909
+ const start = jsonOutput.selectionStart;
910
+ const end = jsonOutput.selectionEnd;
911
+ const currentValue = jsonOutput.value;
912
+ jsonOutput.value = currentValue.substring(0, start) + text + currentValue.substring(end);
913
+ showNotification('Pasted as plain text');
914
+ }
915
+ }).catch(err => {
916
+ // Fallback to clipboardData for older browsers
917
+ const text = (e.originalEvent || e).clipboardData.getData('text/plain');
918
+ try {
919
+ const data = JSON.parse(text);
920
+ loadJSON(data);
921
+ showNotification('JSON pasted successfully');
922
+ } catch (parseError) {
923
+ const start = jsonOutput.selectionStart;
924
+ const end = jsonOutput.selectionEnd;
925
+ const currentValue = jsonOutput.value;
926
+ jsonOutput.value = currentValue.substring(0, start) + text + currentValue.substring(end);
927
+ showNotification('Pasted as plain text');
928
+ }
929
+ });
930
+ });
931
+
932
+ // Enable pasting in JSON editor pane
933
+ jsonEditor.addEventListener('paste', (e) => {
934
+ e.preventDefault();
935
+ navigator.clipboard.readText().then(text => {
936
+ try {
937
+ const data = JSON.parse(text);
938
+ loadJSON(data);
939
+ showNotification('JSON pasted successfully');
940
+ } catch (parseError) {
941
+ showNotification('Clipboard content is not valid JSON');
942
+ }
943
+ }).catch(err => {
944
+ // Fallback to clipboardData for older browsers
945
+ const text = (e.originalEvent || e).clipboardData.getData('text/plain');
946
+ try {
947
+ const data = JSON.parse(text);
948
+ loadJSON(data);
949
+ showNotification('JSON pasted successfully');
950
+ } catch (parseError) {
951
+ showNotification('Clipboard content is not valid JSON');
952
+ }
953
+ });
954
+ });
955
+
956
  // Format JSON
957
  document.getElementById('formatBtn').addEventListener('click', () => {
958
  updateOutput();