File size: 10,981 Bytes
e912915
 
 
 
 
 
 
 
b9fe4f1
e912915
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3024053
 
 
58d7ea5
 
e912915
 
f80e511
3024053
f80e511
58d7ea5
f80e511
 
 
 
 
 
 
58d7ea5
f80e511
 
 
 
 
 
 
 
 
 
58d7ea5
f80e511
 
 
 
 
 
58d7ea5
f80e511
 
 
 
 
 
 
3024053
58d7ea5
 
 
 
e912915
58d7ea5
 
e912915
58d7ea5
 
e912915
 
 
58d7ea5
 
 
e912915
58d7ea5
 
e912915
58d7ea5
 
e912915
58d7ea5
 
e912915
 
 
 
58d7ea5
949d7d1
 
3024053
58d7ea5
 
3024053
e912915
3024053
4e37599
58d7ea5
4e37599
58d7ea5
4e37599
58d7ea5
4e37599
 
e912915
 
 
 
949d7d1
 
3024053
58d7ea5
 
 
6c6c4eb
58d7ea5
949d7d1
 
 
 
3024053
58d7ea5
 
 
949d7d1
 
58d7ea5
949d7d1
 
 
58d7ea5
949d7d1
58d7ea5
949d7d1
e912915
 
 
 
 
 
3024053
e912915
 
 
 
 
 
 
 
4e37599
 
58d7ea5
 
4e37599
527614f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14e9683
d1b354f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Visual JSON Editor</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="style.css">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3b82f6',
                        secondary: '#1e40af',
                        dark: '#0f172a',
                        light: '#f8fafc'
                    }
                }
            }
        }
    </script>
</head>
<body class="bg-slate-900 h-screen overflow-hidden p-0">
    <div class="w-full h-screen flex flex-col">
        <header class="flex-shrink-0 mb-1 text-center py-1">
            <h1 class="text-2xl font-bold text-slate-100">Visual JSON Editor</h1>
            <p class="text-slate-400 text-sm">The way JSON should <i class="italic font-semibold">ALWAYS</i> been editored!</p>
        </header>

        <!-- Menu Bar -->
        <div class="menu-bar flex flex-wrap py-1 px-2 flex-shrink-0">
            <div class="dropdown">
                <div class="menu-item px-2 py-1">File</div>
                <div class="dropdown-content">
                    <a href="#" id="newBtn"><i class="fas fa-plus mr-2"></i>New</a>
                    <a href="#" id="openBtn"><i class="fas fa-folder-open mr-2"></i>Open</a>
                    <a href="#" id="saveBtn"><i class="fas fa-save mr-2"></i>Save</a>
                </div>
            </div>
            <div class="dropdown">
                <div class="menu-item px-2 py-1">Edit</div>
                <div class="dropdown-content">
                    <a href="#" id="undoBtn"><i class="fas fa-undo mr-2"></i>Undo</a>
                    <a href="#" id="redoBtn"><i class="fas fa-redo mr-2"></i>Redo</a>
                    <a href="#" id="copyBtnMenu"><i class="fas fa-copy mr-2"></i>Copy</a>
                    <a href="#" id="cutBtnMenu"><i class="fas fa-cut mr-2"></i>Cut</a>
                    <a href="#" id="pasteBtnMenu"><i class="fas fa-paste mr-2"></i>Paste</a>
                    <a href="#" id="preferencesBtn"><i class="fas fa-cog mr-2"></i>Preferences</a>
                </div>
            </div>
            <div class="dropdown">
                <div class="menu-item px-2 py-1">Tools</div>
                <div class="dropdown-content">
                    <a href="#" id="formatBtn"><i class="fas fa-indent mr-2"></i>Format</a>
                    <a href="#" id="validateBtn"><i class="fas fa-check-circle mr-2"></i>Validate</a>
                </div>
            </div>
            <div class="dropdown">
                <div class="menu-item px-2 py-1">Help</div>
                <div class="dropdown-content">
                    <a href="#" id="instructionsBtn"><i class="fas fa-info-circle mr-2"></i>Instructions</a>
                    <a href="#" id="sampleBtn"><i class="fas fa-code mr-2"></i>Sample JSON</a>
                </div>
            </div>
        </div>

        <div class="bg-slate-800 rounded-lg overflow-hidden mb-1 border border-slate-700 flex-1 flex flex-col overflow-hidden">
            <div class="p-2 bg-slate-700 border-b border-slate-600 flex flex-wrap items-center justify-between gap-2">
                <div class="flex flex-wrap gap-1">
                    <button id="newBtn2" class="btn bg-primary hover:bg-secondary text-white px-3 py-1.5 rounded flex items-center gap-1 text-sm">
                        <i class="fas fa-plus text-xs"></i> New
                    </button>
                    <button id="openBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-1.5 rounded flex items-center gap-1 text-sm">
                        <i class="fas fa-folder-open text-xs"></i> Open
                    </button>
                    <button id="saveBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-3 py-1.5 rounded flex items-center gap-1 text-sm">
                        <i class="fas fa-save text-xs"></i> Save
                    </button>
                </div>
                
                <div class="flex flex-wrap gap-1">
                    <button id="undoBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-2 py-1.5 rounded text-sm">
                        <i class="fas fa-undo text-xs"></i>
                    </button>
                    <button id="redoBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-2 py-1.5 rounded text-sm">
                        <i class="fas fa-redo text-xs"></i>
                    </button>
                    <button id="formatBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-2 py-1.5 rounded text-sm">
                        <i class="fas fa-indent text-xs"></i>
                    </button>
                    <button id="validateBtn2" class="btn bg-slate-600 hover:bg-slate-500 px-2 py-1.5 rounded text-sm">
                        <i class="fas fa-check-circle text-xs"></i>
                    </button>
                </div>
            </div>
            
            <div class="flex flex-col lg:flex-row gap-0.5">
                <!-- Left Panel - Visual JSON Editor -->
                <div class="w-full lg:w-1/2">
                    <div class="bg-slate-700 h-full flex flex-col" style="height: calc(100vh - 120px);">
                        <div class="flex justify-between items-center px-2 py-1 border-b border-slate-600">
                            <h2 class="text-sm font-semibold text-slate-200">Visual Editor</h2>
                            <span class="text-xs text-slate-400">Click to edit • Tab nav • Ctrl+Tab indent</span>
                        </div>
                        <div class="relative json-editor border-none overflow-auto flex-1" style="min-height: 100%;">
                            <!-- Left line numbers -->
                            <div id="lineNumbersLeft" class="absolute left-0 top-0 bottom-0 w-8 bg-slate-800 text-slate-500 text-xs font-mono text-right pr-2 select-none overflow-hidden z-10 pt-1 border-r border-slate-700"></div>
                            <!-- Right line numbers -->
                            <div id="lineNumbersRight" class="absolute right-0 top-0 bottom-0 w-8 bg-slate-800 text-slate-500 text-xs font-mono text-left pl-2 select-none overflow-hidden z-10 pt-1 border-l border-slate-700"></div>
                            <!-- JSON content -->
                            <div id="jsonEditor" class="pl-9 pr-9 py-1 font-mono text-sm">
                                <!-- JSON content will be rendered here -->
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- Right Panel - JSON Code Editor -->
                <div class="w-full lg:w-1/2">
                    <div class="bg-gray-50 h-full flex flex-col" style="height: calc(100vh - 120px);">
                        <div class="flex justify-between items-center px-2 py-1 border-b border-gray-300 bg-gray-100">
                            <h2 class="text-sm font-semibold text-gray-700">Code Editor</h2>
                            <div class="flex gap-1 items-center">
                                <span id="autoSaveStatus" class="text-xs text-green-600 hidden"><i class="fas fa-check-circle mr-1"></i>Auto-saved</span>
                                <button id="applyCodeBtn" class="btn bg-green-500 hover:bg-green-600 text-white px-2 py-1 rounded text-xs">
                                    <i class="fas fa-check mr-1"></i> Apply
                                </button>
                            </div>
                        </div>
                        <textarea id="jsonOutput" class="w-full flex-1 font-mono text-sm p-1 border-none bg-white focus:outline-none resize-none" style="min-height: 100%;"></textarea>
                        <div class="px-2 py-1 border-t border-gray-300 flex flex-wrap gap-1 justify-between items-center bg-gray-100">
                            <div class="flex gap-1">
                                <button id="copyBtn" class="btn bg-gray-200 hover:bg-gray-300 px-2 py-1 rounded text-xs">
                                    <i class="fas fa-copy mr-1"></i> Copy
                                </button>
                                <button id="downloadBtn" class="btn bg-primary hover:bg-secondary text-white px-2 py-1 rounded text-xs">
                                    <i class="fas fa-download mr-1"></i> Download
                                </button>
                            </div>
                            <div id="validationStatus" class="flex items-center gap-1 text-xs">
                                <i class="fas fa-check-circle text-green-500"></i>
                                <span class="text-green-600">Valid</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div id="notification" class="notification fixed bottom-4 right-4 bg-white shadow-lg rounded-lg p-4 border-l-4 border-green-500 max-w-md z-50">
            <div class="flex items-start">
                <i class="fas fa-check-circle text-green-500 text-xl mt-0.5 mr-3"></i>
                <div>
                    <h4 class="font-bold text-gray-800">Success!</h4>
                    <p class="text-gray-600 mt-1">Your JSON has been updated successfully.</p>
                </div>
            </div>
        </div>
        
        <!-- Coordinates display - fixed position -->
        <div id="coordinates" class="fixed top-16 right-2 bg-slate-800 text-slate-300 px-2 py-1 rounded text-xs font-mono shadow-lg z-50 opacity-80 hover:opacity-100 transition-opacity border border-slate-600">
            <span id="coordLine">L:0</span> <span id="coordChar">C:0</span> <span id="coordDepth">D:0</span>
        </div>
        
        <!-- Context menu -->
        <div id="contextMenu" class="context-menu">
            <div class="context-menu-item" id="ctxInsertAfter">
                <i class="fas fa-plus"></i> Insert Line After
            </div>
            <div class="context-menu-item" id="ctxInsertBefore">
                <i class="fas fa-arrow-up"></i> Insert Line Before
            </div>
            <div class="context-menu-divider"></div>
            <div class="context-menu-item" id="ctxCopyKey">
                <i class="fas fa-copy"></i> Copy Key
            </div>
            <div class="context-menu-item" id="ctxCopyValue">
                <i class="fas fa-copy"></i> Copy Value
            </div>
            <div class="context-menu-item" id="ctxDelete">
                <i class="fas fa-trash"></i> Delete
            </div>
        </div>
    </div>
    <script src="script.js"></script>
</body>