@zjy4fun/json-open 0.3.4 → 0.3.6
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/index.html +264 -128
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -5,111 +5,152 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>JSON Formatter</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
8
11
|
<style>
|
|
9
|
-
/* ===== Theme Variables ===== */
|
|
12
|
+
/* ===== Theme Variables (OKLCH) ===== */
|
|
10
13
|
:root {
|
|
11
14
|
color-scheme: dark;
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
--bg-
|
|
17
|
-
--bg-
|
|
18
|
-
--bg-
|
|
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
|
-
--
|
|
15
|
+
--font-ui: 'Figtree', system-ui, sans-serif;
|
|
16
|
+
--font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
17
|
+
|
|
18
|
+
/* Surfaces — teal-tinted neutrals, hue 195 */
|
|
19
|
+
--bg-body: oklch(0.16 0.012 195);
|
|
20
|
+
--bg-header: oklch(0.21 0.012 195);
|
|
21
|
+
--bg-input: oklch(0.16 0.012 195);
|
|
22
|
+
--bg-button: oklch(0.24 0.012 195);
|
|
23
|
+
--bg-button-hover: oklch(0.30 0.012 195);
|
|
24
|
+
--bg-primary: oklch(0.55 0.14 195);
|
|
25
|
+
--bg-primary-hover: oklch(0.60 0.14 195);
|
|
26
|
+
|
|
27
|
+
/* Borders */
|
|
28
|
+
--border: oklch(0.30 0.010 195);
|
|
29
|
+
--border-button: oklch(0.38 0.010 195);
|
|
30
|
+
--border-search-focus: oklch(0.65 0.14 195);
|
|
31
|
+
|
|
32
|
+
/* Text */
|
|
33
|
+
--text: oklch(0.92 0.008 195);
|
|
34
|
+
--text-secondary: oklch(0.70 0.010 195);
|
|
35
|
+
--text-muted: oklch(0.55 0.010 195);
|
|
36
|
+
--text-label: oklch(0.82 0.008 195);
|
|
37
|
+
--text-placeholder: oklch(0.40 0.010 195);
|
|
38
|
+
|
|
39
|
+
/* Resizer */
|
|
40
|
+
--resizer: oklch(0.30 0.010 195);
|
|
41
|
+
--resizer-active: oklch(0.65 0.14 195);
|
|
42
|
+
|
|
43
|
+
/* Tree */
|
|
44
|
+
--tree-line: oklch(0.30 0.010 195);
|
|
45
|
+
--arrow: oklch(0.60 0.010 195);
|
|
46
|
+
|
|
47
|
+
/* Syntax — cohesive, slightly desaturated */
|
|
48
|
+
--key: oklch(0.78 0.09 195);
|
|
49
|
+
--colon: oklch(0.60 0.010 195);
|
|
50
|
+
--string: oklch(0.76 0.11 155);
|
|
51
|
+
--number: oklch(0.78 0.10 80);
|
|
52
|
+
--boolean: oklch(0.74 0.09 340);
|
|
53
|
+
--null: oklch(0.62 0.02 195);
|
|
54
|
+
--symbol: oklch(0.74 0.09 285);
|
|
55
|
+
--meta: oklch(0.55 0.010 195);
|
|
56
|
+
|
|
57
|
+
/* Search highlights */
|
|
58
|
+
--highlight-bg: oklch(0.75 0.14 70);
|
|
59
|
+
--highlight-text: oklch(0.18 0.01 195);
|
|
60
|
+
--highlight-current-bg: oklch(0.60 0.14 195);
|
|
61
|
+
--highlight-current-text: oklch(0.98 0.005 195);
|
|
62
|
+
|
|
63
|
+
/* Errors */
|
|
64
|
+
--error-text: oklch(0.70 0.16 25);
|
|
65
|
+
--error-bg: oklch(0.22 0.03 25);
|
|
66
|
+
--error-border: oklch(0.30 0.05 25);
|
|
67
|
+
|
|
68
|
+
/* Toggle */
|
|
69
|
+
--toggle-bg: oklch(0.30 0.012 195);
|
|
70
|
+
--toggle-active: oklch(0.60 0.14 195);
|
|
71
|
+
--toggle-knob: oklch(0.92 0.008 195);
|
|
72
|
+
|
|
73
|
+
/* Links / icon buttons */
|
|
74
|
+
--github-link: oklch(0.60 0.010 195);
|
|
75
|
+
--github-link-hover: oklch(0.92 0.008 195);
|
|
76
|
+
--theme-btn-color: oklch(0.60 0.010 195);
|
|
77
|
+
--theme-btn-hover: oklch(0.92 0.008 195);
|
|
78
|
+
|
|
79
|
+
/* Parsed JSON indicator — background tint only, no border-left */
|
|
80
|
+
--parsed-bg: oklch(0.22 0.03 80);
|
|
81
|
+
--parsed-badge: oklch(0.75 0.10 80);
|
|
82
|
+
--parsed-badge-bg: oklch(0.26 0.04 80);
|
|
57
83
|
}
|
|
84
|
+
|
|
58
85
|
:root.light {
|
|
59
86
|
color-scheme: light;
|
|
60
|
-
--bg-body:
|
|
61
|
-
--bg-header:
|
|
62
|
-
--bg-input:
|
|
63
|
-
--bg-button:
|
|
64
|
-
--bg-button-hover:
|
|
65
|
-
--bg-primary:
|
|
66
|
-
--bg-primary-hover:
|
|
67
|
-
|
|
68
|
-
--border
|
|
69
|
-
--border-
|
|
70
|
-
--
|
|
71
|
-
|
|
72
|
-
--text
|
|
73
|
-
--text-
|
|
74
|
-
--text-
|
|
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
|
-
|
|
87
|
+
--bg-body: oklch(0.97 0.005 195);
|
|
88
|
+
--bg-header: oklch(0.93 0.008 195);
|
|
89
|
+
--bg-input: oklch(0.99 0.003 195);
|
|
90
|
+
--bg-button: oklch(0.93 0.008 195);
|
|
91
|
+
--bg-button-hover: oklch(0.88 0.010 195);
|
|
92
|
+
--bg-primary: oklch(0.50 0.14 195);
|
|
93
|
+
--bg-primary-hover: oklch(0.45 0.14 195);
|
|
94
|
+
|
|
95
|
+
--border: oklch(0.85 0.008 195);
|
|
96
|
+
--border-button: oklch(0.72 0.008 195);
|
|
97
|
+
--border-search-focus: oklch(0.50 0.14 195);
|
|
98
|
+
|
|
99
|
+
--text: oklch(0.22 0.012 195);
|
|
100
|
+
--text-secondary: oklch(0.42 0.010 195);
|
|
101
|
+
--text-muted: oklch(0.55 0.008 195);
|
|
102
|
+
--text-label: oklch(0.30 0.010 195);
|
|
103
|
+
--text-placeholder: oklch(0.65 0.008 195);
|
|
104
|
+
|
|
105
|
+
--resizer: oklch(0.85 0.008 195);
|
|
106
|
+
--resizer-active: oklch(0.50 0.14 195);
|
|
107
|
+
|
|
108
|
+
--tree-line: oklch(0.82 0.008 195);
|
|
109
|
+
--arrow: oklch(0.50 0.010 195);
|
|
110
|
+
|
|
111
|
+
--key: oklch(0.42 0.12 195);
|
|
112
|
+
--colon: oklch(0.50 0.008 195);
|
|
113
|
+
--string: oklch(0.42 0.12 155);
|
|
114
|
+
--number: oklch(0.48 0.10 80);
|
|
115
|
+
--boolean: oklch(0.45 0.10 340);
|
|
116
|
+
--null: oklch(0.55 0.02 195);
|
|
117
|
+
--symbol: oklch(0.45 0.10 285);
|
|
118
|
+
--meta: oklch(0.62 0.008 195);
|
|
119
|
+
|
|
120
|
+
--highlight-bg: oklch(0.85 0.12 80);
|
|
121
|
+
--highlight-text: oklch(0.20 0.01 195);
|
|
122
|
+
--highlight-current-bg: oklch(0.50 0.14 195);
|
|
123
|
+
--highlight-current-text: oklch(0.98 0.005 195);
|
|
124
|
+
|
|
125
|
+
--error-text: oklch(0.48 0.16 25);
|
|
126
|
+
--error-bg: oklch(0.95 0.03 25);
|
|
127
|
+
--error-border: oklch(0.85 0.05 25);
|
|
128
|
+
|
|
129
|
+
--toggle-bg: oklch(0.85 0.008 195);
|
|
130
|
+
--toggle-active: oklch(0.50 0.14 195);
|
|
131
|
+
--toggle-knob: oklch(0.99 0.003 195);
|
|
132
|
+
|
|
133
|
+
--github-link: oklch(0.50 0.010 195);
|
|
134
|
+
--github-link-hover: oklch(0.22 0.012 195);
|
|
135
|
+
--theme-btn-color: oklch(0.50 0.010 195);
|
|
136
|
+
--theme-btn-hover: oklch(0.22 0.012 195);
|
|
137
|
+
|
|
138
|
+
--parsed-bg: oklch(0.95 0.03 80);
|
|
139
|
+
--parsed-badge: oklch(0.45 0.10 80);
|
|
140
|
+
--parsed-badge-bg: oklch(0.90 0.04 80);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ===== Base ===== */
|
|
106
144
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
145
|
+
|
|
107
146
|
body {
|
|
108
|
-
font-family:
|
|
147
|
+
font-family: var(--font-mono);
|
|
109
148
|
background: var(--bg-body);
|
|
110
149
|
color: var(--text);
|
|
111
150
|
height: 100vh;
|
|
112
151
|
overflow: hidden;
|
|
152
|
+
-webkit-font-smoothing: antialiased;
|
|
153
|
+
-moz-osx-font-smoothing: grayscale;
|
|
113
154
|
}
|
|
114
155
|
|
|
115
156
|
/* ===== Header ===== */
|
|
@@ -124,14 +165,45 @@
|
|
|
124
165
|
flex-shrink: 0;
|
|
125
166
|
}
|
|
126
167
|
.header h1 {
|
|
168
|
+
font-family: var(--font-ui);
|
|
127
169
|
font-size: 15px;
|
|
128
170
|
font-weight: 600;
|
|
129
171
|
color: var(--text);
|
|
130
172
|
white-space: nowrap;
|
|
173
|
+
letter-spacing: -0.01em;
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: 6px;
|
|
177
|
+
}
|
|
178
|
+
.header h1 span {
|
|
179
|
+
color: var(--text-muted);
|
|
180
|
+
font-weight: 400;
|
|
181
|
+
}
|
|
182
|
+
.home-btn {
|
|
183
|
+
appearance: none;
|
|
184
|
+
background: none;
|
|
185
|
+
border: none;
|
|
186
|
+
color: inherit;
|
|
187
|
+
font: inherit;
|
|
188
|
+
cursor: pointer;
|
|
189
|
+
padding: 2px 4px;
|
|
190
|
+
border-radius: 6px;
|
|
191
|
+
display: inline-flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
gap: 6px;
|
|
194
|
+
transition: background 0.15s ease-out, color 0.15s ease-out;
|
|
195
|
+
line-height: 1;
|
|
196
|
+
}
|
|
197
|
+
.home-btn:hover {
|
|
198
|
+
background: var(--bg-button-hover);
|
|
199
|
+
}
|
|
200
|
+
.home-btn:focus-visible {
|
|
201
|
+
outline: 2px solid var(--border-search-focus);
|
|
202
|
+
outline-offset: 1px;
|
|
131
203
|
}
|
|
132
204
|
.header .actions {
|
|
133
205
|
display: flex;
|
|
134
|
-
gap:
|
|
206
|
+
gap: 8px;
|
|
135
207
|
margin-left: auto;
|
|
136
208
|
align-items: center;
|
|
137
209
|
}
|
|
@@ -142,18 +214,20 @@
|
|
|
142
214
|
cursor: pointer;
|
|
143
215
|
display: flex;
|
|
144
216
|
align-items: center;
|
|
145
|
-
padding:
|
|
217
|
+
padding: 6px;
|
|
146
218
|
border-radius: 6px;
|
|
147
|
-
transition: color 0.
|
|
219
|
+
transition: color 0.15s ease-out;
|
|
148
220
|
}
|
|
149
221
|
.theme-toggle:hover {
|
|
150
222
|
color: var(--theme-btn-hover);
|
|
151
223
|
}
|
|
152
224
|
.github-link {
|
|
153
225
|
color: var(--github-link);
|
|
154
|
-
transition: color 0.
|
|
226
|
+
transition: color 0.15s ease-out;
|
|
155
227
|
display: flex;
|
|
156
228
|
align-items: center;
|
|
229
|
+
padding: 4px;
|
|
230
|
+
border-radius: 6px;
|
|
157
231
|
}
|
|
158
232
|
.github-link:hover {
|
|
159
233
|
color: var(--github-link-hover);
|
|
@@ -180,23 +254,27 @@
|
|
|
180
254
|
display: flex;
|
|
181
255
|
align-items: center;
|
|
182
256
|
padding: 0 16px;
|
|
183
|
-
gap:
|
|
257
|
+
gap: 8px;
|
|
184
258
|
flex-shrink: 0;
|
|
259
|
+
font-family: var(--font-ui);
|
|
185
260
|
font-size: 13px;
|
|
186
261
|
color: var(--text-secondary);
|
|
187
262
|
}
|
|
188
263
|
.panel-header .label {
|
|
189
264
|
font-weight: 600;
|
|
190
265
|
color: var(--text-label);
|
|
266
|
+
font-size: 12px;
|
|
267
|
+
text-transform: uppercase;
|
|
268
|
+
letter-spacing: 0.04em;
|
|
191
269
|
}
|
|
192
270
|
|
|
193
271
|
/* ===== Resizer ===== */
|
|
194
272
|
.resizer {
|
|
195
|
-
width:
|
|
273
|
+
width: 4px;
|
|
196
274
|
background: var(--resizer);
|
|
197
275
|
cursor: col-resize;
|
|
198
276
|
flex-shrink: 0;
|
|
199
|
-
transition: background 0.15s;
|
|
277
|
+
transition: background 0.15s ease-out;
|
|
200
278
|
}
|
|
201
279
|
.resizer:hover, .resizer.active {
|
|
202
280
|
background: var(--resizer-active);
|
|
@@ -209,9 +287,9 @@
|
|
|
209
287
|
border: none;
|
|
210
288
|
background: var(--bg-input);
|
|
211
289
|
color: var(--text);
|
|
212
|
-
font-family:
|
|
290
|
+
font-family: var(--font-mono);
|
|
213
291
|
font-size: 13px;
|
|
214
|
-
line-height: 1.
|
|
292
|
+
line-height: 1.65;
|
|
215
293
|
padding: 16px;
|
|
216
294
|
outline: none;
|
|
217
295
|
tab-size: 2;
|
|
@@ -232,6 +310,7 @@
|
|
|
232
310
|
flex-shrink: 0;
|
|
233
311
|
}
|
|
234
312
|
button {
|
|
313
|
+
font-family: var(--font-ui);
|
|
235
314
|
border: 1px solid var(--border-button);
|
|
236
315
|
background: var(--bg-button);
|
|
237
316
|
color: var(--text);
|
|
@@ -239,16 +318,20 @@
|
|
|
239
318
|
padding: 5px 10px;
|
|
240
319
|
cursor: pointer;
|
|
241
320
|
font-size: 12px;
|
|
242
|
-
font-
|
|
321
|
+
font-weight: 500;
|
|
243
322
|
white-space: nowrap;
|
|
323
|
+
transition: background 0.12s ease-out, border-color 0.12s ease-out;
|
|
244
324
|
}
|
|
245
325
|
button:hover {
|
|
246
326
|
background: var(--bg-button-hover);
|
|
247
327
|
}
|
|
328
|
+
button:active {
|
|
329
|
+
transform: scale(0.98);
|
|
330
|
+
}
|
|
248
331
|
button.primary {
|
|
249
332
|
background: var(--bg-primary);
|
|
250
|
-
border-color: var(--bg-primary
|
|
251
|
-
color:
|
|
333
|
+
border-color: var(--bg-primary);
|
|
334
|
+
color: oklch(0.98 0.005 195);
|
|
252
335
|
}
|
|
253
336
|
button.primary:hover {
|
|
254
337
|
background: var(--bg-primary-hover);
|
|
@@ -262,24 +345,26 @@
|
|
|
262
345
|
margin-left: auto;
|
|
263
346
|
}
|
|
264
347
|
.search-wrap input {
|
|
348
|
+
font-family: var(--font-mono);
|
|
265
349
|
border: 1px solid var(--border-button);
|
|
266
350
|
background: var(--bg-input);
|
|
267
351
|
color: var(--text);
|
|
268
352
|
border-radius: 6px;
|
|
269
353
|
padding: 5px 10px;
|
|
270
354
|
font-size: 12px;
|
|
271
|
-
font-family: inherit;
|
|
272
355
|
width: 180px;
|
|
273
356
|
outline: none;
|
|
274
|
-
transition: border-color 0.
|
|
357
|
+
transition: border-color 0.15s ease-out, box-shadow 0.15s ease-out;
|
|
275
358
|
}
|
|
276
359
|
.search-wrap input:focus {
|
|
277
360
|
border-color: var(--border-search-focus);
|
|
361
|
+
box-shadow: 0 0 0 2px oklch(0.60 0.14 195 / 0.15);
|
|
278
362
|
}
|
|
279
363
|
.search-wrap input::placeholder {
|
|
280
364
|
color: var(--text-muted);
|
|
281
365
|
}
|
|
282
366
|
.search-count {
|
|
367
|
+
font-family: var(--font-ui);
|
|
283
368
|
font-size: 11px;
|
|
284
369
|
color: var(--text-muted);
|
|
285
370
|
min-width: 50px;
|
|
@@ -294,6 +379,7 @@
|
|
|
294
379
|
display: flex;
|
|
295
380
|
align-items: center;
|
|
296
381
|
gap: 6px;
|
|
382
|
+
font-family: var(--font-ui);
|
|
297
383
|
font-size: 12px;
|
|
298
384
|
color: var(--text-secondary);
|
|
299
385
|
}
|
|
@@ -314,7 +400,7 @@
|
|
|
314
400
|
inset: 0;
|
|
315
401
|
background: var(--toggle-bg);
|
|
316
402
|
border-radius: 20px;
|
|
317
|
-
transition: background 0.
|
|
403
|
+
transition: background 0.15s ease-out;
|
|
318
404
|
}
|
|
319
405
|
.toggle .slider::before {
|
|
320
406
|
content: '';
|
|
@@ -325,7 +411,7 @@
|
|
|
325
411
|
bottom: 3px;
|
|
326
412
|
background: var(--toggle-knob);
|
|
327
413
|
border-radius: 50%;
|
|
328
|
-
transition: transform 0.2s;
|
|
414
|
+
transition: transform 0.2s cubic-bezier(0.33, 1, 0.68, 1);
|
|
329
415
|
}
|
|
330
416
|
.toggle input:checked + .slider {
|
|
331
417
|
background: var(--toggle-active);
|
|
@@ -339,7 +425,7 @@
|
|
|
339
425
|
flex: 1;
|
|
340
426
|
overflow: auto;
|
|
341
427
|
padding: 16px;
|
|
342
|
-
line-height: 1.
|
|
428
|
+
line-height: 1.55;
|
|
343
429
|
font-size: 13px;
|
|
344
430
|
}
|
|
345
431
|
.viewer .empty-state {
|
|
@@ -349,12 +435,19 @@
|
|
|
349
435
|
justify-content: center;
|
|
350
436
|
height: 100%;
|
|
351
437
|
color: var(--text-placeholder);
|
|
438
|
+
font-family: var(--font-ui);
|
|
352
439
|
font-size: 14px;
|
|
353
|
-
gap:
|
|
440
|
+
gap: 6px;
|
|
354
441
|
}
|
|
355
442
|
.viewer .empty-state .icon {
|
|
356
|
-
font-
|
|
357
|
-
|
|
443
|
+
font-family: var(--font-mono);
|
|
444
|
+
font-size: 32px;
|
|
445
|
+
opacity: 0.4;
|
|
446
|
+
font-weight: 500;
|
|
447
|
+
}
|
|
448
|
+
.viewer .empty-state .hint {
|
|
449
|
+
font-size: 12px;
|
|
450
|
+
color: var(--text-muted);
|
|
358
451
|
}
|
|
359
452
|
.viewer .error-msg {
|
|
360
453
|
color: var(--error-text);
|
|
@@ -378,6 +471,8 @@
|
|
|
378
471
|
content: '\25B8';
|
|
379
472
|
margin-right: 6px;
|
|
380
473
|
color: var(--arrow);
|
|
474
|
+
display: inline-block;
|
|
475
|
+
transition: transform 0.12s ease-out;
|
|
381
476
|
}
|
|
382
477
|
details[open] > summary::before {
|
|
383
478
|
content: '\25BE';
|
|
@@ -397,17 +492,18 @@
|
|
|
397
492
|
.symbol { color: var(--symbol); }
|
|
398
493
|
.meta { color: var(--meta); }
|
|
399
494
|
|
|
400
|
-
/* ===== Parsed JSON string highlight ===== */
|
|
495
|
+
/* ===== Parsed JSON string highlight — background tint, no border-left ===== */
|
|
401
496
|
.parsed-json {
|
|
402
497
|
background: var(--parsed-bg);
|
|
403
|
-
border-left: 2px solid var(--parsed-border);
|
|
404
498
|
border-radius: 4px;
|
|
405
|
-
padding: 2px
|
|
499
|
+
padding: 2px 6px 2px 8px;
|
|
406
500
|
margin: 2px 0;
|
|
407
501
|
}
|
|
408
502
|
.parsed-json > summary::after {
|
|
409
503
|
content: 'parsed';
|
|
504
|
+
font-family: var(--font-ui);
|
|
410
505
|
font-size: 10px;
|
|
506
|
+
font-weight: 500;
|
|
411
507
|
color: var(--parsed-badge);
|
|
412
508
|
background: var(--parsed-badge-bg);
|
|
413
509
|
border-radius: 3px;
|
|
@@ -426,33 +522,67 @@
|
|
|
426
522
|
mark.highlight.current {
|
|
427
523
|
background: var(--highlight-current-bg);
|
|
428
524
|
color: var(--highlight-current-text);
|
|
429
|
-
box-shadow: 0 0 0 2px
|
|
525
|
+
box-shadow: 0 0 0 2px oklch(0.60 0.14 195 / 0.35);
|
|
430
526
|
}
|
|
431
527
|
|
|
432
528
|
/* ===== Status Bar ===== */
|
|
433
529
|
.status-bar {
|
|
434
|
-
height:
|
|
530
|
+
height: 26px;
|
|
435
531
|
background: var(--bg-header);
|
|
436
532
|
border-top: 1px solid var(--border);
|
|
437
533
|
display: flex;
|
|
438
534
|
align-items: center;
|
|
439
535
|
padding: 0 16px;
|
|
536
|
+
font-family: var(--font-ui);
|
|
440
537
|
font-size: 11px;
|
|
441
538
|
color: var(--text-muted);
|
|
442
539
|
gap: 16px;
|
|
443
540
|
flex-shrink: 0;
|
|
444
541
|
}
|
|
542
|
+
|
|
543
|
+
/* ===== Scrollbar ===== */
|
|
544
|
+
.viewer::-webkit-scrollbar,
|
|
545
|
+
.input-area::-webkit-scrollbar {
|
|
546
|
+
width: 8px;
|
|
547
|
+
height: 8px;
|
|
548
|
+
}
|
|
549
|
+
.viewer::-webkit-scrollbar-track,
|
|
550
|
+
.input-area::-webkit-scrollbar-track {
|
|
551
|
+
background: transparent;
|
|
552
|
+
}
|
|
553
|
+
.viewer::-webkit-scrollbar-thumb,
|
|
554
|
+
.input-area::-webkit-scrollbar-thumb {
|
|
555
|
+
background: var(--border);
|
|
556
|
+
border-radius: 4px;
|
|
557
|
+
}
|
|
558
|
+
.viewer::-webkit-scrollbar-thumb:hover,
|
|
559
|
+
.input-area::-webkit-scrollbar-thumb:hover {
|
|
560
|
+
background: var(--border-button);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* ===== Reduced Motion ===== */
|
|
564
|
+
@media (prefers-reduced-motion: reduce) {
|
|
565
|
+
*, *::before, *::after {
|
|
566
|
+
transition-duration: 0.01ms !important;
|
|
567
|
+
animation-duration: 0.01ms !important;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
445
570
|
</style>
|
|
446
571
|
</head>
|
|
447
572
|
<body>
|
|
448
573
|
<div class="header">
|
|
449
|
-
<h1>
|
|
574
|
+
<h1>
|
|
575
|
+
<button type="button" class="home-btn" id="home-btn" aria-label="Back to home and clear shared JSON">
|
|
576
|
+
<span>{ }</span>
|
|
577
|
+
JSON Formatter
|
|
578
|
+
</button>
|
|
579
|
+
</h1>
|
|
450
580
|
<div class="actions">
|
|
451
581
|
<button class="theme-toggle" id="theme-toggle" title="Toggle light/dark mode">
|
|
452
|
-
<svg id="icon-moon" height="
|
|
582
|
+
<svg id="icon-moon" height="18" width="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
453
583
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
|
454
584
|
</svg>
|
|
455
|
-
<svg id="icon-sun" height="
|
|
585
|
+
<svg id="icon-sun" height="18" width="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none">
|
|
456
586
|
<circle cx="12" cy="12" r="5"/>
|
|
457
587
|
<line x1="12" y1="1" x2="12" y2="3"/>
|
|
458
588
|
<line x1="12" y1="21" x2="12" y2="23"/>
|
|
@@ -465,7 +595,7 @@
|
|
|
465
595
|
</svg>
|
|
466
596
|
</button>
|
|
467
597
|
<a href="https://github.com/zjy4fun/json-open" target="_blank" rel="noopener noreferrer" class="github-link" title="View on GitHub">
|
|
468
|
-
<svg height="
|
|
598
|
+
<svg height="22" width="22" viewBox="0 0 16 16" fill="currentColor">
|
|
469
599
|
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
|
470
600
|
</svg>
|
|
471
601
|
</a>
|
|
@@ -477,8 +607,8 @@
|
|
|
477
607
|
<div class="panel panel-left" id="panel-left">
|
|
478
608
|
<div class="panel-header">
|
|
479
609
|
<span class="label">Input</span>
|
|
480
|
-
<button id="btn-copy"
|
|
481
|
-
<button id="btn-share"
|
|
610
|
+
<button id="btn-copy">Copy</button>
|
|
611
|
+
<button id="btn-share">Share</button>
|
|
482
612
|
</div>
|
|
483
613
|
<textarea class="input-area" id="json-input" placeholder="Paste or type JSON here..." spellcheck="false"></textarea>
|
|
484
614
|
</div>
|
|
@@ -511,7 +641,7 @@
|
|
|
511
641
|
<div class="empty-state">
|
|
512
642
|
<div class="icon">{ }</div>
|
|
513
643
|
<div>Paste or type JSON on the left</div>
|
|
514
|
-
<div
|
|
644
|
+
<div class="hint">It will format automatically</div>
|
|
515
645
|
</div>
|
|
516
646
|
</div>
|
|
517
647
|
</div>
|
|
@@ -673,6 +803,7 @@
|
|
|
673
803
|
var statusSize = document.getElementById('status-size')
|
|
674
804
|
var panelLeft = document.getElementById('panel-left')
|
|
675
805
|
var resizer = document.getElementById('resizer')
|
|
806
|
+
var homeBtn = document.getElementById('home-btn')
|
|
676
807
|
|
|
677
808
|
var currentParsed = null
|
|
678
809
|
var currentDeepParsed = null
|
|
@@ -681,7 +812,7 @@
|
|
|
681
812
|
function doFormat() {
|
|
682
813
|
var input = jsonInput.value.trim()
|
|
683
814
|
if (!input) {
|
|
684
|
-
viewer.innerHTML = '<div class="empty-state"><div class="icon">{ }</div><div>Paste or type JSON on the left</div><div
|
|
815
|
+
viewer.innerHTML = '<div class="empty-state"><div class="icon">{ }</div><div>Paste or type JSON on the left</div><div class="hint">It will format automatically</div></div>'
|
|
685
816
|
statusInfo.textContent = 'Ready'
|
|
686
817
|
statusSize.textContent = ''
|
|
687
818
|
toggleWrap.classList.add('hidden')
|
|
@@ -732,7 +863,7 @@
|
|
|
732
863
|
if (!text) return
|
|
733
864
|
navigator.clipboard.writeText(text).then(function () {
|
|
734
865
|
var orig = btnCopy.textContent
|
|
735
|
-
btnCopy.textContent = '
|
|
866
|
+
btnCopy.textContent = 'Copied!'
|
|
736
867
|
setTimeout(function () { btnCopy.textContent = orig }, 1500)
|
|
737
868
|
})
|
|
738
869
|
})
|
|
@@ -758,12 +889,17 @@
|
|
|
758
889
|
var url = location.origin + location.pathname + '#json=' + encoded
|
|
759
890
|
navigator.clipboard.writeText(url).then(function () {
|
|
760
891
|
var orig = btnShare.textContent
|
|
761
|
-
btnShare.textContent = '
|
|
892
|
+
btnShare.textContent = 'Link copied!'
|
|
762
893
|
statusInfo.textContent = 'Share link copied (' + formatBytes(url.length) + ')'
|
|
763
894
|
setTimeout(function () { btnShare.textContent = orig }, 2000)
|
|
764
895
|
})
|
|
765
896
|
})
|
|
766
897
|
|
|
898
|
+
// ===== Home =====
|
|
899
|
+
homeBtn.addEventListener('click', function () {
|
|
900
|
+
window.location.assign(location.origin + location.pathname + location.search)
|
|
901
|
+
})
|
|
902
|
+
|
|
767
903
|
// Input behavior
|
|
768
904
|
jsonInput.addEventListener('keydown', function (e) {
|
|
769
905
|
// Tab support
|