(value)
| 249 | |
| 250 | // 创建节点 |
| 251 | function createNode(value) { |
| 252 | let node = { |
| 253 | type: getType(value), |
| 254 | value: value, |
| 255 | children: [], |
| 256 | |
| 257 | getHTML: function() { |
| 258 | switch(this.type) { |
| 259 | case 'string': |
| 260 | // 判断原始字符串是否为URL |
| 261 | if (isUrl(this.value)) { |
| 262 | // 用JSON.stringify保证转义符显示,内容包裹在<a>里 |
| 263 | return '<div class="item item-line"><span class="string"><a href="' |
| 264 | + htmlspecialchars(this.value) + '" target="_blank" rel="noopener noreferrer" data-is-link="1" data-link-url="' + htmlspecialchars(this.value) + '">' |
| 265 | + htmlspecialchars(JSON.stringify(this.value)) + '</a></span></div>'; |
| 266 | } else { |
| 267 | // 检测字符串是否是有效的JSON(用于转义功能) |
| 268 | // 当转义功能开启时,如果字符串是有效的JSON,就格式化显示 |
| 269 | if (escapeJsonStringEnabled) { |
| 270 | const strValue = String(this.value); |
| 271 | // 检查字符串是否看起来像JSON(以[或{开头,以]或}结尾) |
| 272 | const trimmed = strValue.trim(); |
| 273 | if ((trimmed.startsWith('[') && trimmed.endsWith(']')) || |
| 274 | (trimmed.startsWith('{') && trimmed.endsWith('}'))) { |
| 275 | try { |
| 276 | // 尝试解析为JSON,使用全局的 JSON.parse(已被 json-bigint.js 覆盖) |
| 277 | const parsed = JSON.parse(strValue); |
| 278 | // 如果解析成功且是对象或数组,格式化显示 |
| 279 | if (typeof parsed === 'object' && parsed !== null) { |
| 280 | const nestedNode = createNode(parsed); |
| 281 | // 获取嵌套JSON的完整HTML(完全展开) |
| 282 | let nestedHTML = nestedNode.getHTML(); |
| 283 | // 移除外层的item容器div,只保留内部内容 |
| 284 | nestedHTML = nestedHTML.replace(/^<div class="item[^"]*">/, '').replace(/<\/div>$/, ''); |
| 285 | // 返回格式化的JSON结构,但保持在外层的字符串容器中 |
| 286 | // 使用block显示,确保完全展开 |
| 287 | return '<div class="item item-line"><span class="string">' + |
| 288 | '<span class="quote">"</span>' + |
| 289 | '<div class="string-json-nested" style="display:block;margin-left:0;padding-left:0;">' + |
| 290 | nestedHTML + |
| 291 | '</div>' + |
| 292 | '<span class="quote">"</span>' + |
| 293 | '</span></div>'; |
| 294 | } |
| 295 | } catch (e) { |
| 296 | // 解析失败,按普通字符串处理 |
| 297 | } |
| 298 | } |
| 299 | } |
| 300 | return '<div class="item item-line"><span class="string">' + formatStringValue(JSON.stringify(this.value)) + '</span></div>'; |
| 301 | } |
| 302 | case 'number': |
| 303 | // 确保大数字不使用科学计数法 |
| 304 | let numStr = typeof this.value === 'number' && this.value.toString().includes('e') |
| 305 | ? this.value.toLocaleString('fullwide', {useGrouping: false}) |
| 306 | : this.value; |
| 307 | return '<div class="item item-line"><span class="number">' + |
| 308 | numStr + |
no test coverage detected