Uživatel:KubiV/TestQuiz.js

Z WikiSkript

Poznámka: Po zveřejnění musíte vyprázdnit cache vašeho prohlížeče, jinak změny neuvidíte.

  • Firefox / Safari: Při kliknutí na Aktualizovat držte Shift nebo stiskněte Ctrl-F5 nebo Ctrl-R (na Macu ⌘-R)
  • Google Chrome: Stiskněte Ctrl-Shift-R (na Macu ⌘-Shift-R)
  • Internet Explorer / Edge: Při kliknutí na Aktualizovat držte Ctrl nebo stiskněte Ctrl-F5
  • Opera: Stiskněte Ctrl-F5.
$(document).ready(function() {
    console.debug("Document ready"); // added debug

    function extractQuestions(wikitext) {
        const lines = wikitext.split('\n');
        const questions = [];
        let i = 0;
        while (i < lines.length) {
            let line = lines[i].trim();
            if (!line) {
                i++;
                continue;
            }
            // Zpracujeme blok otázky začínající '{'
            if (line.startsWith('{')) {
                let questionLines = [];
                while (i < lines.length) {
                    const currentLine = lines[i].trim();
                    questionLines.push(currentLine);
                    if (currentLine.endsWith('}')) break;
                    i++;
                }
                let questionBlock = questionLines.join(' ');
                // Odebereme vnější složené závorky
                questionBlock = questionBlock.replace(/^\{/, '').replace(/\}$/, '').trim();
                // Zjistíme a odstraníme specifikaci typu
                let type = 'checkbox';
                const typeMatch = questionBlock.match(/\|type=[„"]([\[\]\(\)]+)[“"]/);
                if (typeMatch) {
                    type = typeMatch[1] === '[]' ? 'checkbox' : 'radio';
                    questionBlock = questionBlock.replace(/\|type=[„"]([\[\]\(\)]+)[“"]/, '').trim();
                }
                // Nově odstraníme ' |type=„[]“' nebo ' |type=„()“' pokud je v textu otázky
                questionBlock = questionBlock.replace(/\s*\|type=[„"]([\[\]\(\)]+)[“"]/, '').trim();
                // Přidá podmínku, aby text otázky začínal ihned za znakem '{', ale znak '{' se nepřepíše do textu otázky
                if (questionBlock.startsWith('{')) {
                    questionBlock = questionBlock.substring(1).trim();
                }
                const currentQuestion = { text: questionBlock, options: [], type: type };
                i++;
                // Zpracování následujících řádků jako odpovědí
                while (i < lines.length) {
                    const answerLine = lines[i].trim();
                    if (!answerLine) {
                        i++;
                        continue;
                    }
                    if (answerLine.startsWith('{')) break;
                    if (answerLine.startsWith('+') || answerLine.startsWith('-')) {
                        const isCorrect = answerLine.startsWith('+');
                        const optionText = answerLine.substring(1).trim();
                        currentQuestion.options.push({ text: optionText, correct: isCorrect });
                    } else if (answerLine.startsWith('||')) {
                        if (currentQuestion.options.length > 0) {
                            currentQuestion.options[currentQuestion.options.length - 1].text += " " + answerLine.substring(2).trim();
                        }
                    } else {
                        break;
                    }
                    i++;
                }
                if (currentQuestion.options.length > 0) {
                    questions.push(currentQuestion);
                }
            } else {
                i++;
            }
        }
        return questions;
    }

    function checkPageForQuiz(pageName) {
        return new mw.Api().get({
            action: 'parse',
            page: pageName,
            prop: 'text',
            format: 'json'
        }).then(function(result) {
            if (!result.parse || !result.parse.text) {
                return false;
            }
            const content = result.parse.text['*'];
            return content.includes('<quiz>') || content.includes('class="quiz"');
        });
    }

    async function loadRandomQuiz() {
        console.debug("loadRandomQuiz called"); // added debug
        const data = await $.get('/api.php', {
            action: 'query',
            list: 'allpages',
            apnamespace: 108,
            aplimit: 500,
            format: 'json'
        });

        if (!data.query || !data.query.allpages.length) {
            throw new Error('Nenalezeny žádné stránky');
        }

        const pages = data.query.allpages.sort(() => Math.random() - 0.5);
        for (const page of pages) {
            const hasQuiz = await checkPageForQuiz(page.title);
            if (hasQuiz) {
                return page.title;
            }
        }

        throw new Error('Nenalezena žádná stránka s kvízem');
    }

    function loadPageContent(pageName) {
        return new mw.Api().get({
            action: 'parse',
            page: pageName,
            prop: 'wikitext',
            format: 'json'
        }).then(function(result) {
            return { pageName, wikitext: result.parse.wikitext['*'] };
        });
    }

    function parseWikitext(wikitext) {
        console.debug("parseWikitext called", wikitext); // added debug
        return new mw.Api().post({
            action: 'parse',
            text: wikitext,
            contentmodel: 'wikitext',
            prop: 'text',
            format: 'json'
        }).then(function(result) {
            // Trim any surrounding <p> tags
           return result.parse.text['*']//.replace(/^<p>|<\/p>$/g, '').trim();
        });
    }

    function displayQuiz() {
        console.debug("displayQuiz called"); // added debug
        var quizContainer = $('#randomQuizContainer');
        quizContainer.html('<p>Načítání kvízu...</p>');

        mw.loader.using(['mediawiki.api', 'ext.quiz']).then(loadRandomQuiz)
        .then(loadPageContent)
        .then(function({ pageName, wikitext }) {
            var questions = extractQuestions(wikitext);
            if (questions.length === 0) {
                throw new Error('Nenalezeny žádné otázky na stránce');
            }

            var randomQuestion = questions[Math.floor(Math.random() * questions.length)];
            const inputType = randomQuestion.type === 'checkbox' ? 'checkbox' : 'radio';

            return Promise.all([
                parseWikitext(randomQuestion.text),
                Promise.all(randomQuestion.options.map(opt => parseWikitext(opt.text)))
            ]).then(function([parsedQuestionText, parsedOptions]) {
                // Nová proměnná pro text otázky
                let questionDisplayText = parsedQuestionText;
                console.log("Otázka:",parsedQuestionText)

                // Updated options display: vytvoříme tabulku s inputem vedle textu.
                var optionsHtml = `<table style="width: 100%; border-collapse: collapse;">` +
                    randomQuestion.options.map((opt, index) => {
                        return `<tr>
                                    <td style="vertical-align: middle; padding: 1px;">
                                        <input type="${inputType}" name="quizOption" value="${opt.text}" style="margin: 0 10px 0 0; vertical-align: middle;">
                                    </td>
                                    <td style="vertical-align: middle; padding: 1px;">${parsedOptions[index]}</td>
                                </tr>`;
                    }).join('') + `</table>`;

                var quizHtml = `
                    <p><a href="/w/${pageName}">${pageName}</a></p>
                    <form class="quizForm">
                        <div class="quizQuestion">
                            <p class="questionTitle">${questionDisplayText}</p>
                        </div>
                        <div class="quizOptions">
                            ${optionsHtml}
                        </div>
                        <div class="button-container">
                            <button type="button" class="quiz-button submitQuiz" style="padding: 10px 20px;">Vyhodnotit</button>
                            <button type="button" id="nextQuestion" class="quiz-button" style="padding: 10px 20px;">Další otázka</button>
                        </div>
                    </form>
                `;

                quizContainer.html(quizHtml);
                $('#nextQuestion').on('click', displayQuiz);
                $('.submitQuiz').on('click', function() {
                    evaluateQuiz(randomQuestion);
                });
                mw.hook('wikipage.content').fire(quizContainer);
            });
        }).catch(function(error) {
            console.error('Chyba při načítání kvízu:', error);
            quizContainer.html('<p class="error">Nepodařilo se načíst kvíz: ' + error.message + '</p>');
        });
    }

    function evaluateQuiz(question) {
        console.debug("evaluateQuiz called", question); // added debug
        $('.quizForm input').each(function() {
            const $input = $(this);
            const optionText = $input.val().trim();
            const corresponding = question.options.find(o => o.text === optionText);

            if (corresponding && corresponding.correct) {
                $input.closest('tr').css('background-color', 'lightgreen'); // changed from .closest('.proposal')
            }

            if ($input.is(':checked') && (!corresponding || !corresponding.correct)) {
                $input.closest('tr').css('background-color', 'lightcoral'); // changed from .closest('.proposal')
            }
        });
    }

    displayQuiz();
});