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