预览修改
This commit is contained in:
1 parent
ef23e33ad0
commit
90e5a2b81e
4 files changed
+268
-6
No files matched your search
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 269 KiB |
@@ -14,6 +14,13 @@
|
|||||||
--accent: #4fc1ff;
|
--accent: #4fc1ff;
|
||||||
--border: #3c3c3c;
|
--border: #3c3c3c;
|
||||||
--error: #f14c4c;
|
--error: #f14c4c;
|
||||||
|
/* 悬浮层填充与滚动条配色。Eagle 内置 Electron 22 / Chromium 108 不支持 color-mix(),
|
||||||
|
这些必须写成 rgba(),否则整条颜色声明会被丢弃。 */
|
||||||
|
--hover-fill: rgba(255, 255, 255, .07);
|
||||||
|
--scroll-thumb: rgba(255, 255, 255, .34);
|
||||||
|
--scroll-thumb-hover: rgba(255, 255, 255, .55);
|
||||||
|
--scroll-thumb-active: rgba(255, 255, 255, .72);
|
||||||
|
--scroll-track: rgba(255, 255, 255, .07);
|
||||||
}
|
}
|
||||||
[data-theme="light"] {
|
[data-theme="light"] {
|
||||||
--bg: #f3f4f6;
|
--bg: #f3f4f6;
|
||||||
@@ -24,6 +31,11 @@
|
|||||||
--accent: #0078d4;
|
--accent: #0078d4;
|
||||||
--border: #ddd;
|
--border: #ddd;
|
||||||
--error: #d13438;
|
--error: #d13438;
|
||||||
|
--hover-fill: rgba(0, 0, 0, .06);
|
||||||
|
--scroll-thumb: rgba(0, 0, 0, .30);
|
||||||
|
--scroll-thumb-hover: rgba(0, 0, 0, .46);
|
||||||
|
--scroll-thumb-active: rgba(0, 0, 0, .62);
|
||||||
|
--scroll-track: rgba(0, 0, 0, .06);
|
||||||
}
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -182,6 +194,50 @@
|
|||||||
font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
||||||
color: var(--text-dim); white-space: pre; word-break: normal;
|
color: var(--text-dim); white-space: pre; word-break: normal;
|
||||||
}
|
}
|
||||||
|
/* 纯文本 / 普通 JSON 预览允许拖动选择与 Ctrl+C 复制;画布与查看器控件仍保持不可选中 */
|
||||||
|
#overlay.text-preview .title,
|
||||||
|
#overlay.text-preview .msg {
|
||||||
|
-webkit-user-select: text; user-select: text;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .msg { cursor: text; }
|
||||||
|
/* 预览区滚动条:不使用原生样式。宽度 14px、滑块可见 8px,保证看得清。
|
||||||
|
颜色走 --scroll-* 变量(rgba 写死),不能用 color-mix():Eagle 内置 Chromium 108
|
||||||
|
不支持该函数,声明会整条失效,滑块就变成看不见。也不要写 scrollbar-width /
|
||||||
|
scrollbar-color,那两个标准属性在 108 上无效且易与 ::-webkit-scrollbar 混淆。 */
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar { width: 14px; height: 14px; }
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-track { background: var(--scroll-track); }
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb {
|
||||||
|
min-height: 36px;
|
||||||
|
border: 3px solid transparent; border-radius: 999px;
|
||||||
|
background: var(--scroll-thumb);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--scroll-thumb-hover);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb:active {
|
||||||
|
background: var(--scroll-thumb-active);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-corner { background: transparent; }
|
||||||
|
/* JSON 字段树:折叠标记与计数只用符号 / 数字,无需新增界面文案 */
|
||||||
|
#overlay.json-preview .msg { white-space: normal; }
|
||||||
|
.jt-node > summary {
|
||||||
|
list-style: none; cursor: pointer; border-radius: 4px;
|
||||||
|
}
|
||||||
|
.jt-node > summary::-webkit-details-marker { display: none; }
|
||||||
|
.jt-node > summary:hover { background: var(--hover-fill); }
|
||||||
|
.jt-node > summary::before {
|
||||||
|
content: '▾'; display: inline-block; width: 14px; color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.jt-node:not([open]) > summary::before { content: '▸'; }
|
||||||
|
.jt-children { margin-left: 7px; padding-left: 11px; border-left: 1px solid var(--border); }
|
||||||
|
.jt-leaf { padding-left: 14px; }
|
||||||
|
.jt-key { color: var(--accent); }
|
||||||
|
.jt-str { color: var(--text); }
|
||||||
|
.jt-brace, .jt-count { color: var(--text-dim); }
|
||||||
|
.jt-count { margin: 0 3px; font-size: 11px; }
|
||||||
#overlay.hidden { display: none; }
|
#overlay.hidden { display: none; }
|
||||||
#loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); }
|
#loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); }
|
||||||
#loading.hidden { display: none; }
|
#loading.hidden { display: none; }
|
||||||
@@ -421,6 +477,8 @@
|
|||||||
|
|
||||||
function showError(title, msg) {
|
function showError(title, msg) {
|
||||||
loadingEl.classList.add('hidden');
|
loadingEl.classList.add('hidden');
|
||||||
|
overlay.classList.remove('text-preview');
|
||||||
|
overlay.classList.remove('json-preview');
|
||||||
overlay.classList.remove('hidden');
|
overlay.classList.remove('hidden');
|
||||||
document.getElementById('errorTitle').textContent = title;
|
document.getElementById('errorTitle').textContent = title;
|
||||||
document.getElementById('errorMsg').textContent = msg;
|
document.getElementById('errorMsg').textContent = msg;
|
||||||
@@ -432,8 +490,78 @@
|
|||||||
timelineBarEl.style.display = 'none';
|
timelineBarEl.style.display = 'none';
|
||||||
animationPanel.style.display = 'none';
|
animationPanel.style.display = 'none';
|
||||||
statusEl.style.display = 'none';
|
statusEl.style.display = 'none';
|
||||||
overlay.classList.add('text-preview');
|
|
||||||
showError(title, text);
|
showError(title, text);
|
||||||
|
overlay.classList.add('text-preview');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 普通 JSON:轻量字段树(点击折叠 / 展开) ----------
|
||||||
|
const JSON_TREE_MAX_NODES = 20000; // 超过此规模退回纯文本,避免构建 DOM 卡顿
|
||||||
|
const JSON_TREE_OPEN_DEPTH = 1; // 默认展开的层级,更深的折叠
|
||||||
|
|
||||||
|
function jsonNodeCount(value, budget) {
|
||||||
|
let n = 0;
|
||||||
|
const walk = (node) => {
|
||||||
|
if (!node || typeof node !== 'object' || n > budget) return;
|
||||||
|
for (const key of Object.keys(node)) { n++; walk(node[key]); if (n > budget) return; }
|
||||||
|
};
|
||||||
|
walk(value);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonKeySpan(key) {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.className = 'jt-key';
|
||||||
|
span.textContent = (typeof key === 'number' ? '[' + key + ']: ' : JSON.stringify(key) + ': ');
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildJsonTree(key, value, depth) {
|
||||||
|
if (value === null || typeof value !== 'object') {
|
||||||
|
const leaf = document.createElement('div');
|
||||||
|
leaf.className = 'jt-leaf';
|
||||||
|
if (key !== null) leaf.appendChild(jsonKeySpan(key));
|
||||||
|
const val = document.createElement('span');
|
||||||
|
val.textContent = typeof value === 'string' ? JSON.stringify(value) : String(value);
|
||||||
|
if (typeof value === 'string') val.className = 'jt-str';
|
||||||
|
leaf.appendChild(val);
|
||||||
|
return leaf;
|
||||||
|
}
|
||||||
|
const isArray = Array.isArray(value);
|
||||||
|
const keys = isArray ? value.map((_, i) => i) : Object.keys(value);
|
||||||
|
const node = document.createElement('details');
|
||||||
|
node.className = 'jt-node';
|
||||||
|
if (depth <= JSON_TREE_OPEN_DEPTH) node.open = true;
|
||||||
|
const summary = document.createElement('summary');
|
||||||
|
if (key !== null) summary.appendChild(jsonKeySpan(key));
|
||||||
|
const open = document.createElement('span');
|
||||||
|
open.className = 'jt-brace';
|
||||||
|
open.textContent = isArray ? '[' : '{';
|
||||||
|
const count = document.createElement('span');
|
||||||
|
count.className = 'jt-count';
|
||||||
|
count.textContent = String(keys.length);
|
||||||
|
const close = document.createElement('span');
|
||||||
|
close.className = 'jt-brace';
|
||||||
|
close.textContent = isArray ? ']' : '}';
|
||||||
|
summary.append(open, count, close);
|
||||||
|
node.appendChild(summary);
|
||||||
|
const children = document.createElement('div');
|
||||||
|
children.className = 'jt-children';
|
||||||
|
for (const k of keys) children.appendChild(buildJsonTree(k, value[k], depth + 1));
|
||||||
|
node.appendChild(children);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showJsonPreview(title, value) {
|
||||||
|
const box = document.getElementById('errorMsg');
|
||||||
|
showTextPreview(title, '');
|
||||||
|
if (jsonNodeCount(value, JSON_TREE_MAX_NODES) > JSON_TREE_MAX_NODES) {
|
||||||
|
// 超大对象仍以纯文本呈现,保证打开速度与可选择性
|
||||||
|
box.textContent = JSON.stringify(value, null, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
overlay.classList.add('json-preview');
|
||||||
|
box.textContent = '';
|
||||||
|
box.appendChild(buildJsonTree(null, value, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus(msg, holdMs = 0) {
|
function setStatus(msg, holdMs = 0) {
|
||||||
@@ -1063,10 +1191,13 @@
|
|||||||
let count = 0;
|
let count = 0;
|
||||||
try { count = fs.readSync(fd, buffer, 0, buffer.length, 0); } finally { fs.closeSync(fd); }
|
try { count = fs.readSync(fd, buffer, 0, buffer.length, 0); } finally { fs.closeSync(fd); }
|
||||||
let text = buffer.subarray(0, count).toString('utf8');
|
let text = buffer.subarray(0, count).toString('utf8');
|
||||||
|
const name = path.basename(filePath);
|
||||||
|
let parsed;
|
||||||
if (stat.size <= maxPreviewBytes) {
|
if (stat.size <= maxPreviewBytes) {
|
||||||
try { text = JSON.stringify(JSON.parse(text), null, 2); } catch (e) { /* 保留 JSONC/原始文本 */ }
|
try { parsed = JSON.parse(text); } catch (e) { /* 保留 JSONC/原始文本 */ }
|
||||||
} else text += t('viewer.truncated1m');
|
} else text += t('viewer.truncated1m');
|
||||||
showTextPreview(path.basename(filePath), text);
|
if (parsed !== null && typeof parsed === 'object') showJsonPreview(name, parsed);
|
||||||
|
else showTextPreview(name, parsed === undefined ? text : JSON.stringify(parsed, null, 2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const assets = utils.discoverAssets(filePath);
|
const assets = utils.discoverAssets(filePath);
|
||||||
|
|||||||
+134
-3
@@ -14,6 +14,13 @@
|
|||||||
--accent: #4fc1ff;
|
--accent: #4fc1ff;
|
||||||
--border: #3c3c3c;
|
--border: #3c3c3c;
|
||||||
--error: #f14c4c;
|
--error: #f14c4c;
|
||||||
|
/* 悬浮层填充与滚动条配色。Eagle 内置 Electron 22 / Chromium 108 不支持 color-mix(),
|
||||||
|
这些必须写成 rgba(),否则整条颜色声明会被丢弃。 */
|
||||||
|
--hover-fill: rgba(255, 255, 255, .07);
|
||||||
|
--scroll-thumb: rgba(255, 255, 255, .34);
|
||||||
|
--scroll-thumb-hover: rgba(255, 255, 255, .55);
|
||||||
|
--scroll-thumb-active: rgba(255, 255, 255, .72);
|
||||||
|
--scroll-track: rgba(255, 255, 255, .07);
|
||||||
}
|
}
|
||||||
[data-theme="light"] {
|
[data-theme="light"] {
|
||||||
--bg: #f3f4f6;
|
--bg: #f3f4f6;
|
||||||
@@ -24,6 +31,11 @@
|
|||||||
--accent: #0078d4;
|
--accent: #0078d4;
|
||||||
--border: #ddd;
|
--border: #ddd;
|
||||||
--error: #d13438;
|
--error: #d13438;
|
||||||
|
--hover-fill: rgba(0, 0, 0, .06);
|
||||||
|
--scroll-thumb: rgba(0, 0, 0, .30);
|
||||||
|
--scroll-thumb-hover: rgba(0, 0, 0, .46);
|
||||||
|
--scroll-thumb-active: rgba(0, 0, 0, .62);
|
||||||
|
--scroll-track: rgba(0, 0, 0, .06);
|
||||||
}
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -182,6 +194,50 @@
|
|||||||
font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
||||||
color: var(--text-dim); white-space: pre; word-break: normal;
|
color: var(--text-dim); white-space: pre; word-break: normal;
|
||||||
}
|
}
|
||||||
|
/* 纯文本 / 普通 JSON 预览允许拖动选择与 Ctrl+C 复制;画布与查看器控件仍保持不可选中 */
|
||||||
|
#overlay.text-preview .title,
|
||||||
|
#overlay.text-preview .msg {
|
||||||
|
-webkit-user-select: text; user-select: text;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .msg { cursor: text; }
|
||||||
|
/* 预览区滚动条:不使用原生样式。宽度 14px、滑块可见 8px,保证看得清。
|
||||||
|
颜色走 --scroll-* 变量(rgba 写死),不能用 color-mix():Eagle 内置 Chromium 108
|
||||||
|
不支持该函数,声明会整条失效,滑块就变成看不见。也不要写 scrollbar-width /
|
||||||
|
scrollbar-color,那两个标准属性在 108 上无效且易与 ::-webkit-scrollbar 混淆。 */
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar { width: 14px; height: 14px; }
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-track { background: var(--scroll-track); }
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb {
|
||||||
|
min-height: 36px;
|
||||||
|
border: 3px solid transparent; border-radius: 999px;
|
||||||
|
background: var(--scroll-thumb);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--scroll-thumb-hover);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-thumb:active {
|
||||||
|
background: var(--scroll-thumb-active);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
#overlay.text-preview .box::-webkit-scrollbar-corner { background: transparent; }
|
||||||
|
/* JSON 字段树:折叠标记与计数只用符号 / 数字,无需新增界面文案 */
|
||||||
|
#overlay.json-preview .msg { white-space: normal; }
|
||||||
|
.jt-node > summary {
|
||||||
|
list-style: none; cursor: pointer; border-radius: 4px;
|
||||||
|
}
|
||||||
|
.jt-node > summary::-webkit-details-marker { display: none; }
|
||||||
|
.jt-node > summary:hover { background: var(--hover-fill); }
|
||||||
|
.jt-node > summary::before {
|
||||||
|
content: '▾'; display: inline-block; width: 14px; color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.jt-node:not([open]) > summary::before { content: '▸'; }
|
||||||
|
.jt-children { margin-left: 7px; padding-left: 11px; border-left: 1px solid var(--border); }
|
||||||
|
.jt-leaf { padding-left: 14px; }
|
||||||
|
.jt-key { color: var(--accent); }
|
||||||
|
.jt-str { color: var(--text); }
|
||||||
|
.jt-brace, .jt-count { color: var(--text-dim); }
|
||||||
|
.jt-count { margin: 0 3px; font-size: 11px; }
|
||||||
#overlay.hidden { display: none; }
|
#overlay.hidden { display: none; }
|
||||||
#loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); }
|
#loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); }
|
||||||
#loading.hidden { display: none; }
|
#loading.hidden { display: none; }
|
||||||
@@ -421,6 +477,8 @@
|
|||||||
|
|
||||||
function showError(title, msg) {
|
function showError(title, msg) {
|
||||||
loadingEl.classList.add('hidden');
|
loadingEl.classList.add('hidden');
|
||||||
|
overlay.classList.remove('text-preview');
|
||||||
|
overlay.classList.remove('json-preview');
|
||||||
overlay.classList.remove('hidden');
|
overlay.classList.remove('hidden');
|
||||||
document.getElementById('errorTitle').textContent = title;
|
document.getElementById('errorTitle').textContent = title;
|
||||||
document.getElementById('errorMsg').textContent = msg;
|
document.getElementById('errorMsg').textContent = msg;
|
||||||
@@ -432,8 +490,78 @@
|
|||||||
timelineBarEl.style.display = 'none';
|
timelineBarEl.style.display = 'none';
|
||||||
animationPanel.style.display = 'none';
|
animationPanel.style.display = 'none';
|
||||||
statusEl.style.display = 'none';
|
statusEl.style.display = 'none';
|
||||||
overlay.classList.add('text-preview');
|
|
||||||
showError(title, text);
|
showError(title, text);
|
||||||
|
overlay.classList.add('text-preview');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 普通 JSON:轻量字段树(点击折叠 / 展开) ----------
|
||||||
|
const JSON_TREE_MAX_NODES = 20000; // 超过此规模退回纯文本,避免构建 DOM 卡顿
|
||||||
|
const JSON_TREE_OPEN_DEPTH = 1; // 默认展开的层级,更深的折叠
|
||||||
|
|
||||||
|
function jsonNodeCount(value, budget) {
|
||||||
|
let n = 0;
|
||||||
|
const walk = (node) => {
|
||||||
|
if (!node || typeof node !== 'object' || n > budget) return;
|
||||||
|
for (const key of Object.keys(node)) { n++; walk(node[key]); if (n > budget) return; }
|
||||||
|
};
|
||||||
|
walk(value);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonKeySpan(key) {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.className = 'jt-key';
|
||||||
|
span.textContent = (typeof key === 'number' ? '[' + key + ']: ' : JSON.stringify(key) + ': ');
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildJsonTree(key, value, depth) {
|
||||||
|
if (value === null || typeof value !== 'object') {
|
||||||
|
const leaf = document.createElement('div');
|
||||||
|
leaf.className = 'jt-leaf';
|
||||||
|
if (key !== null) leaf.appendChild(jsonKeySpan(key));
|
||||||
|
const val = document.createElement('span');
|
||||||
|
val.textContent = typeof value === 'string' ? JSON.stringify(value) : String(value);
|
||||||
|
if (typeof value === 'string') val.className = 'jt-str';
|
||||||
|
leaf.appendChild(val);
|
||||||
|
return leaf;
|
||||||
|
}
|
||||||
|
const isArray = Array.isArray(value);
|
||||||
|
const keys = isArray ? value.map((_, i) => i) : Object.keys(value);
|
||||||
|
const node = document.createElement('details');
|
||||||
|
node.className = 'jt-node';
|
||||||
|
if (depth <= JSON_TREE_OPEN_DEPTH) node.open = true;
|
||||||
|
const summary = document.createElement('summary');
|
||||||
|
if (key !== null) summary.appendChild(jsonKeySpan(key));
|
||||||
|
const open = document.createElement('span');
|
||||||
|
open.className = 'jt-brace';
|
||||||
|
open.textContent = isArray ? '[' : '{';
|
||||||
|
const count = document.createElement('span');
|
||||||
|
count.className = 'jt-count';
|
||||||
|
count.textContent = String(keys.length);
|
||||||
|
const close = document.createElement('span');
|
||||||
|
close.className = 'jt-brace';
|
||||||
|
close.textContent = isArray ? ']' : '}';
|
||||||
|
summary.append(open, count, close);
|
||||||
|
node.appendChild(summary);
|
||||||
|
const children = document.createElement('div');
|
||||||
|
children.className = 'jt-children';
|
||||||
|
for (const k of keys) children.appendChild(buildJsonTree(k, value[k], depth + 1));
|
||||||
|
node.appendChild(children);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showJsonPreview(title, value) {
|
||||||
|
const box = document.getElementById('errorMsg');
|
||||||
|
showTextPreview(title, '');
|
||||||
|
if (jsonNodeCount(value, JSON_TREE_MAX_NODES) > JSON_TREE_MAX_NODES) {
|
||||||
|
// 超大对象仍以纯文本呈现,保证打开速度与可选择性
|
||||||
|
box.textContent = JSON.stringify(value, null, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
overlay.classList.add('json-preview');
|
||||||
|
box.textContent = '';
|
||||||
|
box.appendChild(buildJsonTree(null, value, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus(msg, holdMs = 0) {
|
function setStatus(msg, holdMs = 0) {
|
||||||
@@ -1063,10 +1191,13 @@
|
|||||||
let count = 0;
|
let count = 0;
|
||||||
try { count = fs.readSync(fd, buffer, 0, buffer.length, 0); } finally { fs.closeSync(fd); }
|
try { count = fs.readSync(fd, buffer, 0, buffer.length, 0); } finally { fs.closeSync(fd); }
|
||||||
let text = buffer.subarray(0, count).toString('utf8');
|
let text = buffer.subarray(0, count).toString('utf8');
|
||||||
|
const name = path.basename(filePath);
|
||||||
|
let parsed;
|
||||||
if (stat.size <= maxPreviewBytes) {
|
if (stat.size <= maxPreviewBytes) {
|
||||||
try { text = JSON.stringify(JSON.parse(text), null, 2); } catch (e) { /* 保留 JSONC/原始文本 */ }
|
try { parsed = JSON.parse(text); } catch (e) { /* 保留 JSONC/原始文本 */ }
|
||||||
} else text += t('viewer.truncated1m');
|
} else text += t('viewer.truncated1m');
|
||||||
showTextPreview(path.basename(filePath), text);
|
if (parsed !== null && typeof parsed === 'object') showJsonPreview(name, parsed);
|
||||||
|
else showTextPreview(name, parsed === undefined ? text : JSON.stringify(parsed, null, 2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const assets = utils.discoverAssets(filePath);
|
const assets = utils.discoverAssets(filePath);
|
||||||
|
|||||||
Reference in new issue
Block a user