UdGMoodle Printable Quiz

Cleans/simplifies a Moodle Quiz to be printable

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        UdGMoodle Printable Quiz
// @version     0.4.1
// @author      Antonio Bueno <[email protected]>
// @description Cleans/simplifies a Moodle Quiz to be printable
// @namespace   bueno.bcds.udg.edu
// @match       https://moodle.udg.edu/mod/quiz/attempt.php*
// @match       https://moodle2.udg.edu/mod/quiz/attempt.php*
// @icon        https://raw.githubusercontent.com/buenoudg/Ajudant-UdGMoodle/master/udgmoodle_44x44.png
// @require     https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
// @require     https://cdn.jsdelivr.net/npm/toastify-js@1/src/toastify.min.js
// @resource    toastifyCSS https://cdn.jsdelivr.net/npm/toastify-js@1/src/toastify.css
// @grant       GM.getResourceUrl
// ==/UserScript==

/*
 * Versions:
 *  - 0.4.0 (2023-09-16) Compatible amb el nou UdGMoodle
 *  - 0.4.1 (2023-10-19) Retocs estétics
 */

// jshint esversion: 8
(function () {
    "use strict";

    /*
     * DOM manipulations courtesy of jQuery
     */

    // Modificacions are applied once the DOM has been build (images may be still loading)
    $(document).ready(function () {

        // Makes clear that the script is running and its version
        notification(`${GM.info.script.name} ${GM.info.script.version}`, "hello", 3);

        // Technical info to console
        console.log(GM.info);

        // Trigger button
        $("#mod_quiz_navblock").prepend('<button id="printable">Fes-ho imprimible');
        // Button behavior
        $("#printable").on("click", function () {
            // Move quiz container to the top
            $("body").prepend($("#region-main"));
            // Add editable block with the quiz title at the beginning of the container
            $("#responseform").prepend('<div class="que"><div class="formulation"><div contenteditable="true"><h3>' +
                                       document.title +
                                       "</h3><i><b>Bloc editable</b> (també es pot enganxar des de Word i similars)</div>");
            // Modify webpage appearance
            let stylesheet = document.createElement("style");
            stylesheet.textContent = `
                /* Hide elements */
                nav, #nav-drawer, #nav-drawer-footer, .activity-navigation, .tertiary-navigation,
                #page-wrapper, #top-footer, .que .info, .submitbtns, .multichoice .prompt,
                .content input[type="submit"], .filemanager, .editor_atto_toolbar { display: none !important }

                /* Adjust spacing */
                body, .que .content, .que .ablock .answer>div:last-child { margin: 0 }
                #region-main>.card { border: none }
                .card-body { padding: 0 !important }
                .que { margin: 1em auto }
                .que .qtext { margin: 0 0 0.5em 1.7em }
                .que .ablock { margin: 0 0 0 0.5em }
                .que .qtext table td { padding: 0 0.25em }

                /* Question numbering */
                body { counter-reset: question }
                .que .qtext::before { counter-increment: question; content: counter(question) ". "; font-weight: bold; margin-left: -1.7em; float: left }

                /* Cosmetic details */
                .que .formulation { background-color: transparent }
                .editor_atto_content.form-control { border: 1px solid #ced4da }

                /* Usability */
                .editor_atto_content.form-control { min-height: 48px !important }
            `;
            document.documentElement.appendChild(stylesheet);
        });

    });

    // External CSS files
    (async function () {
        // Toastify CSS
        let externalFileURL = await GM.getResourceUrl("toastifyCSS");
        stylesheet = document.createElement("link");
        stylesheet.setAttribute("rel", "stylesheet");
        stylesheet.setAttribute("href", externalFileURL);
        document.documentElement.appendChild(stylesheet);
    })();

    // Inline CSS
    let stylesheet = document.createElement("style");
    stylesheet.textContent = `
        div.toastify { margin: inherit; padding-bottom: 20px; width: inherit; font-family:
            -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; }
        /* Trigger button appearance */
        #printable::before { content: "🖨 "; font-size: 200%; position: relative; top: 0.1em }
        #printable { border-color: lightgrey darkgrey darkgrey lightgrey; padding: 0em 1em 0.5em }
    `;
    document.documentElement.appendChild(stylesheet);

    /*
     * Notifications courtesy of Toastify JS (see https://apvarun.github.io/toastify-js/)
     */

    function notification(message, type = "info", timeout = 5) {
        // The "type" parameter accepts four values: "info", "warning", "error" and "hello"
        // The "timeout" parameter is expressed in seconds although Toastify uses milliseconds
        let color, icon;
        switch (type) {
            case "warning":
                color = "rgba(201, 201, 0, 0.8)";
                icon = "⚠️";
                break;
            case "error":
                color = "rgba(201, 51, 51, 0.8)";
                icon = "🛑";
                break;
            case "hello":
                color = "rgba(51, 153, 51, 0.8)";
                icon = "👋🏼";
                break;
            default:
                color = "rgba(51, 51, 153, 0.8)";
                icon = "ℹ️";
        }
        Toastify({
            text: icon + " " + message,
            duration: timeout * 1000,
            gravity: "bottom",
            style: {
                background: color,
            }
        }).showToast();
    }

})();