1/** 2 * DokuWiki Plugin Mizar Verifiable Docs (Source View Script) 3 * 4 * @author Yamada, M. <yamadam@mizar.work> 5 */ 6"use strict"; 7document.addEventListener('DOMContentLoaded', function() { 8 const editButtons = document.querySelector('.editButtons'); 9 if (editButtons && !document.getElementById('edbtn__miz2prel')) { 10 const isFullEdit = document.location.search.includes('&do=edit'); 11 12 if (isFullEdit) { 13 const miz2prelButton = document.createElement('button'); 14 miz2prelButton.textContent = 'miz2prel'; 15 miz2prelButton.id = 'edbtn__miz2prel'; 16 miz2prelButton.type = 'button'; 17 miz2prelButton.classList.add('miz2prel-button'); 18 19 const clearButton = document.createElement('button'); 20 clearButton.textContent = 'Clear'; 21 clearButton.id = 'edbtn__clear'; 22 clearButton.type = 'button'; 23 clearButton.classList.add('clear-button'); 24 25 clearButton.addEventListener('click', async function() { 26 const outputDiv = document.getElementById('compileResult'); 27 if (outputDiv) { 28 outputDiv.innerHTML = ''; 29 outputDiv.style.backgroundColor = ''; 30 } 31 32 try { 33 const response = await fetch(DOKU_BASE + "lib/exe/ajax.php?call=clear_temp_files", { 34 method: "POST", 35 headers: { 36 "Content-Type": "application/x-www-form-urlencoded" 37 } 38 }); 39 40 const data = await response.json(); 41 if (data.success) { 42 console.log(data.message); 43 } else { 44 console.error("Failed to clear temporary files:", data.message); 45 } 46 } catch (error) { 47 console.error("Error clearing temporary files:", error); 48 } 49 50 clearButton.style.display = 'none'; 51 miz2prelButton.style.display = 'inline-block'; 52 }); 53 54 miz2prelButton.addEventListener('click', async function() { 55 const editor = document.getElementById('wiki__text'); 56 if (!editor) { 57 alert('Editor not found'); 58 return; 59 } 60 61 const pageContent = editor.value; 62 const editBar = document.getElementById('wiki__editbar'); 63 let outputDiv = document.getElementById('compileResult'); 64 if (!outputDiv) { 65 outputDiv = document.createElement('div'); 66 outputDiv.id = 'compileResult'; 67 } 68 69 if (editBar) { 70 editBar.parentNode.insertBefore(outputDiv, editBar.nextSibling); 71 } 72 73 // ▼ Spinnerを追加 74 const spinner = document.createElement('div'); 75 spinner.className = 'loading-spinner'; 76 spinner.innerHTML = 'Loading...'; 77 miz2prelButton.parentNode.insertBefore(spinner, miz2prelButton.nextSibling); 78 79 try { 80 const response = await fetch(DOKU_BASE + 'lib/exe/ajax.php?call=source_compile', { 81 method: 'POST', 82 headers: { 83 'Content-Type': 'application/x-www-form-urlencoded' 84 }, 85 body: 'content=' + encodeURIComponent(pageContent) 86 }); 87 88 const data = await response.json(); 89 90 if (data.success) { 91 const eventSource = new EventSource(DOKU_BASE + 'lib/exe/ajax.php?call=source_sse'); 92 93 eventSource.onmessage = function(event) { 94 outputDiv.innerHTML += event.data + '<br>'; 95 }; 96 97 eventSource.addEventListener('compileErrors', function(event) { 98 try { 99 const errors = JSON.parse(event.data); 100 let errorContent = ''; 101 errors.forEach(function(error) { 102 const { line, column, message } = error; 103 errorContent += `❌ ${message} (Ln: ${line}, Col: ${column})<br>`; 104 }); 105 outputDiv.innerHTML += errorContent; 106 outputDiv.style.backgroundColor = '#fcc'; 107 } catch (e) { 108 console.error('Failed to parse error data:', e); 109 } 110 }); 111 112 eventSource.addEventListener('end', function(event) { 113 outputDiv.innerHTML += "Compilation complete<br>"; 114 if (!outputDiv.innerHTML.includes('❌')) { 115 outputDiv.style.backgroundColor = '#ccffcc'; 116 } 117 eventSource.close(); 118 119 // ▼ Spinnerを削除(コンパイル完了後) 120 spinner.remove(); 121 }); 122 123 eventSource.onerror = function(event) { 124 console.error('EventSource failed:', event); 125 eventSource.close(); 126 127 // ▼ Spinnerを削除(エラー発生時) 128 spinner.remove(); 129 }; 130 131 miz2prelButton.style.display = 'none'; 132 clearButton.style.display = 'inline-block'; 133 } else { 134 outputDiv.innerHTML = 'Error: ' + data.message; 135 outputDiv.style.backgroundColor = '#fcc'; 136 137 // ▼ Spinnerを削除(サーバーレスポンスエラー時) 138 spinner.remove(); 139 } 140 } catch (error) { 141 console.error('Error:', error); 142 outputDiv.innerHTML = 'Error: ' + error; 143 outputDiv.style.backgroundColor = '#fcc'; 144 145 // ▼ Spinnerを削除(キャッチ時) 146 spinner.remove(); 147 } 148 }); 149 150 editButtons.appendChild(miz2prelButton); 151 editButtons.appendChild(clearButton); 152 } 153 } 154});