diff --git a/static/i18n.js b/static/i18n.js index 708616ee..6c1c186e 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -31,6 +31,7 @@ const LOCALES = { diff_too_large: 'Patch file too large to display inline', tree_view: '트리', raw_view: '원본', + parse_failed_note: 'parse failed', you: 'You', thinking: 'Thinking', expand_all: 'Expand all', @@ -730,6 +731,7 @@ const LOCALES = { diff_too_large: 'Файл патча слишком большой для отображения', tree_view: '樹狀', raw_view: '原始', + parse_failed_note: 'parse failed', you: 'Вы', thinking: 'Думаю', expand_all: 'Развернуть всё', @@ -1378,6 +1380,7 @@ const LOCALES = { diff_too_large: 'Archivo de parche demasiado grande para mostrar', tree_view: '树形', raw_view: '原始', + parse_failed_note: 'parse failed', you: 'Tú', thinking: 'Pensando', expand_all: 'Expandir todo', @@ -2018,6 +2021,7 @@ const LOCALES = { diff_too_large: 'Patch-Datei zu groß für Inline-Anzeige', tree_view: 'Baum', raw_view: 'Rohdaten', + parse_failed_note: 'parse failed', you: 'Du', thinking: 'Nachdenken', expand_all: 'Alle ausklappen', @@ -2433,6 +2437,7 @@ const LOCALES = { diff_too_large: 'Patch 文件过大,无法内联显示', tree_view: 'Árbol', raw_view: 'Original', + parse_failed_note: '\u89e3\u6790\u5931\u8d25', you: '\u4f60', thinking: '\u601d\u8003\u8fc7\u7a0b', expand_all: '\u5168\u90e8\u5c55\u5f00', @@ -3071,6 +3076,7 @@ const LOCALES = { diff_too_large: 'Patch 檔案過大,無法內聯顯示', tree_view: 'Дерево', raw_view: 'Исходный', + parse_failed_note: '\u89e3\u6790\u5931\u8d25', you: '\u4f60', thinking: '\u601d\u8003\u904e\u7a0b', expand_all: '\u5168\u90e8\u5c55\u958b', @@ -3758,6 +3764,7 @@ const LOCALES = { diff_too_large: '패치 파일이 너무 커서 인라인으로 표시할 수 없습니다', tree_view: 'Tree', raw_view: 'Raw', + parse_failed_note: 'parse failed', you: '나', thinking: '생각 중', expand_all: '모두 펼치기', diff --git a/static/ui.js b/static/ui.js index 1b4494b0..0e154fe1 100644 --- a/static/ui.js +++ b/static/ui.js @@ -3129,19 +3129,49 @@ function highlightCode(container) { Prism.highlightAllUnder(el); } +// Lazy load js-yaml for YAML tree view support +let _jsyamlLoading=false; +function _loadJsyamlThen(cb){ + if(typeof jsyaml!=='undefined'){ cb(); return; } + if(_jsyamlLoading){ setTimeout(()=>_loadJsyamlThen(cb),100); return; } + _jsyamlLoading=true; + const s=document.createElement('script'); + s.src='https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js'; + s.integrity='sha384-8pLvVQkv7pCQqFk7AChLpdEe7gXz9h8GAb7cS0zVeJuKhxR5PU5aEET5pRpHZvxUorzdM'; + s.crossOrigin='anonymous'; + s.onload=()=>{ _jsyamlLoading=false; cb(); }; + s.onerror=()=>{ _jsyamlLoading=false; }; // CDN blocked, fall back to raw + document.head.appendChild(s); +} + function initTreeViews(){ document.querySelectorAll('.code-tree-wrap:not([data-tree-init])').forEach(wrap=>{ wrap.setAttribute('data-tree-init','1'); const rawText=wrap.dataset.raw; const lang=wrap.dataset.lang; let parsed=null; + let parseFailed=false; // Try JSON parse - try{ parsed=JSON.parse(rawText); }catch(e){} - // YAML: try parsing if js-yaml is available - if(!parsed && lang==='yaml' && typeof jsyaml!=='undefined'){ - try{ parsed=jsyaml.load(rawText); }catch(e){} + try{ parsed=JSON.parse(rawText); }catch(e){ parseFailed=(lang==='json'); } + // YAML: lazy-load js-yaml if needed + if(!parsed && lang==='yaml'){ + if(typeof jsyaml!=='undefined'){ + try{ parsed=jsyaml.load(rawText); }catch(e){ parseFailed=true; } + }else{ + // Trigger async load, leave as raw for now + parseFailed=true; + } } if(!parsed || typeof parsed!=='object'){ + if(parseFailed){ + const hint=wrap.querySelector('.tree-raw-view'); + if(hint&&!hint.querySelector('.tree-parse-note')){ + const note=document.createElement('div'); + note.className='tree-parse-note'; + note.textContent=t('parse_failed_note')||'parse failed'; + hint.parentNode.insertBefore(note,hint.nextSibling); + } + } return; // leave as raw view } const lineCount=rawText.split('\n').length;