1const CHECK_INTERVAL_MS = 5500; 2const queue = []; 3let processing = false; 4 5export function queueUwscSyntaxCheck(pre) { 6 if (!pre || pre.dataset.uwscCheckQueued === "1") return; 7 8 const root = pre.closest('.highlightjs'); 9 const statusEl = root && root.querySelector('.syntax-check-status'); 10 if (!statusEl) return; 11 12 // â ãµã¼ãã¼å´ã§æ¢ã«ãã£ãã·ã¥æ¸ã¿ãªãAJAXããå³åæ 13 const cached = statusEl.dataset.checkResult; 14 if (cached) { 15 try { 16 applyStatus(statusEl, JSON.parse(cached)); 17 return; 18 } catch (e) { 19 // ãã¼ã¹å¤±ææã¯ãã©ã¼ã«ããã¯ãã¦AJAX㸠20 } 21 } 22 23 pre.dataset.uwscCheckQueued = "1"; 24 queue.push({ pre, statusEl }); 25 processQueue(); 26} 27 28async function processQueue() { 29 if (processing) return; 30 processing = true; 31 32 while (queue.length > 0) { 33 const { pre, statusEl } = queue.shift(); 34 await runCheck(pre, statusEl); 35 if (queue.length > 0) { 36 await sleep(CHECK_INTERVAL_MS); 37 } 38 } 39 40 processing = false; 41} 42 43function sleep(ms) { 44 return new Promise(resolve => setTimeout(resolve, ms)); 45} 46 47async function runCheck(pre, statusEl) { 48 const root = pre.closest('.highlightjs'); 49 if (!root) return; 50 51 const textarea = root.querySelector('textarea'); 52 const code = textarea ? textarea.value : pre.textContent; 53 if (!code || !code.trim()) return; 54 55 const ajaxUrl = window.SyntaxAnalyzerData && window.SyntaxAnalyzerData.ajaxUrl; 56 if (!ajaxUrl) { 57 console.warn('SyntaxAnalyzerData.ajaxUrl ãè¦ã¤ããã¾ãã'); 58 return; 59 } 60 61 try { 62 const body = new URLSearchParams(); 63 body.set('action', 'syntax_analyze'); 64 body.set('code', code); 65 66 const res = await fetch(ajaxUrl, { 67 method: 'POST', 68 credentials: 'same-origin', 69 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 70 body: body.toString() 71 }); 72 73 const data = await res.json(); 74 75 // ã¬ã¼ãå¶éã¡ãã»ã¼ã¸ï¼æååã®ã¿ã®errorï¼ã¯éãã«ã¹ããã 76 if (data && data.error && typeof data.error === 'string') { 77 console.warn('UWSCæ§æãã§ãã¯: ', data.error); 78 statusEl.classList.remove('is-pending'); 79 return; 80 } 81 82 applyStatus(statusEl, data); 83 84 } catch (e) { 85 console.error('UWSCæ§æãã§ãã¯å¤±æ:', e); 86 statusEl.classList.remove('is-pending'); 87 } 88} 89 90function applyStatus(statusEl, data) { 91 const hasError = !!(data && data.error); 92 const hasWarnings = !!(data && Array.isArray(data.warnings) && data.warnings.length > 0); 93 const status = hasError ? 'error' : (hasWarnings ? 'warning' : 'ok'); 94 95 const spinner = statusEl.querySelector('.syntax-check-spinner'); 96 const icon = statusEl.querySelector('.syntax-check-icon'); 97 98 statusEl.classList.remove('is-pending', 'is-error', 'is-warning', 'is-ok'); 99 statusEl.classList.add('is-' + status); 100 101 if (spinner) spinner.style.display = 'none'; 102 if (icon) icon.style.display = (status === 'error' || status === 'warning') ? 'inline-block' : 'none'; 103 104 if (status === 'ok') return; 105 106 statusEl.style.cursor = 'pointer'; 107 statusEl.addEventListener('click', () => { 108 const root = statusEl.closest('.highlightjs'); 109 const existing = root.querySelector('.syntax-check-detail'); 110 if (existing) { existing.remove(); return; } 111 showSyntaxDetail(root, data); 112 }); 113} 114 115function showSyntaxDetail(root, data) { 116 const panel = document.createElement('div'); 117 panel.className = 'syntax-check-detail'; 118 119 const lines = []; 120 if (data.error) { 121 const loc = (data.error.line != null) 122 ? `ï¼${data.error.line}è¡ç®${data.error.col != null ? ' ' + data.error.col + 'åç®' : ''}ï¼` 123 : ''; 124 lines.push(`<div class="syntax-check-error">ã¨ã©ã¼${loc}: ${escapeHtml(data.error.message || '')}</div>`); 125 } 126 if (Array.isArray(data.warnings)) {
127 data.warnings.forEach(w => { 128 const msg = typeof w === 'string' ? w : (w.message || JSON.stringify(w)); 129 const loc = (w && w.line != null) ? `ï¼${w.line}è¡ç®ï¼` : ''; 130 lines.push(`<div class="syntax-check-warning">è¦å${loc}: ${escapeHtml(msg)}</div>`); 131 }); 132 } 133 134 panel.innerHTML = lines.join(''); 135 root.appendChild(panel); 136} 137 138function escapeHtml(str) { 139 const div = document.createElement('div'); 140 div.textContent = str; 141 return div.innerHTML; 142}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.