xref: /plugin/mizarverifiabledocs/script.js (revision 3f7dd076be52992d1f40215ecd797f9d17132992)
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});