xref: /plugin/mizarverifiabledocs/script.js (revision 1a91113b0094ce6ce10091527b530187a60781d5) !
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