{"version":3,"file":"819.js","mappings":"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","sources":["webpack://WebComponents/./runestone/shortanswer/js/shortanswer.js","webpack://WebComponents/./runestone/shortanswer/js/timed_shortanswer.js"],"sourcesContent":["/*==========================================\n=======    Master shortanswer.js    ========\n============================================\n===     This file contains the JS for    ===\n=== the Runestone shortanswer component. ===\n============================================\n===              Created by              ===\n===           Isaiah Mayerchak           ===\n===                7/2/15                ===\n===              Brad Miller             ===\n===                2019                  ===\n==========================================*/\n\nimport RunestoneBase from \"../../common/js/runestonebase.js\";\nimport \"./../css/shortanswer.css\";\n\nexport default class ShortAnswer extends RunestoneBase {\n    constructor(opts) {\n        super(opts);\n        if (opts) {\n            var orig = opts.orig; // entire <p> element that will be replaced by new HTML\n            this.useRunestoneServices =\n                opts.useRunestoneServices || eBookConfig.useRunestoneServices;\n            this.origElem = orig;\n            this.divid = orig.id;\n            this.question = this.origElem.innerHTML;\n            this.optional = false;\n            this.attachURL = opts.attachURL;\n            if ($(this.origElem).is(\"[data-optional]\")) {\n                this.optional = true;\n            }\n            if ($(this.origElem).is(\"[data-mathjax]\")) {\n                this.mathjax = true;\n            }\n            this.mathjax = true;\n            if ($(this.origElem).is(\"[data-attachment]\")) {\n                this.attachment = true;\n            }\n            this.placeholder =\n                $(this.origElem).data(\"placeholder\") ||\n                \"Write your answer here\";\n            this.renderHTML();\n            this.caption = \"shortanswer\";\n            this.addCaption(\"runestone\");\n            this.checkServer(\"shortanswer\", true);\n            if (typeof Prism !== \"undefined\") {\n                Prism.highlightAllUnder(this.containerDiv);\n            }\n        }\n    }\n\n    renderHTML() {\n        this.containerDiv = document.createElement(\"div\");\n        this.containerDiv.id = this.divid;\n        $(this.containerDiv).addClass(this.origElem.getAttribute(\"class\"));\n        this.newForm = document.createElement(\"form\");\n        this.newForm.id = this.divid + \"_journal\";\n        this.newForm.name = this.newForm.id;\n        this.newForm.action = \"\";\n        this.containerDiv.appendChild(this.newForm);\n        this.fieldSet = document.createElement(\"fieldset\");\n        this.newForm.appendChild(this.fieldSet);\n        this.firstLegendDiv = document.createElement(\"div\");\n        this.firstLegendDiv.innerHTML = this.question;\n        $(this.firstLegendDiv).addClass(\"journal-question\");\n        this.fieldSet.appendChild(this.firstLegendDiv);\n        this.jInputDiv = document.createElement(\"div\");\n        this.jInputDiv.id = this.divid + \"_journal_input\";\n        this.fieldSet.appendChild(this.jInputDiv);\n        this.jOptionsDiv = document.createElement(\"div\");\n        $(this.jOptionsDiv).addClass(\"journal-options\");\n        this.jInputDiv.appendChild(this.jOptionsDiv);\n        this.jTextArea = document.createElement(\"textarea\");\n        let self = this;\n        this.jTextArea.onchange = function () {\n            self.isAnswered = true;\n        };\n        this.jTextArea.id = this.divid + \"_solution\";\n        $(this.jTextArea).attr(\"aria-label\", \"textarea\");\n        this.jTextArea.placeholder = this.placeholder;\n        $(this.jTextArea).css(\"display:inline, width:530px\");\n        $(this.jTextArea).addClass(\"form-control\");\n        this.jTextArea.rows = 4;\n        this.jTextArea.cols = 50;\n        this.jOptionsDiv.appendChild(this.jTextArea);\n        this.jTextArea.onchange = function () {\n            this.isAnswered = true;\n            if (this.isTimed) {\n                this.feedbackDiv.innerHTML = \"Your answer is automatically saved.\";\n            } else {\n                this.feedbackDiv.innerHTML = \"Your answer has not been saved yet!\";\n            }\n            $(this.feedbackDiv).removeClass(\"alert-success\");\n            $(this.feedbackDiv).addClass(\"alert alert-danger\");\n        }.bind(this);\n        this.fieldSet.appendChild(document.createElement(\"br\"));\n        if (this.mathjax) {\n            this.renderedAnswer = document.createElement(\"div\");\n            $(this.renderedAnswer).addClass(\"latexoutput\");\n            this.fieldSet.appendChild(this.renderedAnswer);\n        }\n        this.buttonDiv = document.createElement(\"div\");\n        this.fieldSet.appendChild(this.buttonDiv);\n        this.submitButton = document.createElement(\"button\");\n        $(this.submitButton).addClass(\"btn btn-success\");\n        this.submitButton.type = \"button\";\n        this.submitButton.textContent = \"Save\";\n        this.submitButton.onclick = function () {\n            this.checkCurrentAnswer();\n            this.logCurrentAnswer();\n            this.renderFeedback();\n        }.bind(this);\n        this.buttonDiv.appendChild(this.submitButton);\n        this.randomSpan = document.createElement(\"span\");\n        this.randomSpan.innerHTML = \"Instructor's Feedback\";\n        this.fieldSet.appendChild(this.randomSpan);\n        this.otherOptionsDiv = document.createElement(\"div\");\n        $(this.otherOptionsDiv).css(\"padding-left:20px\");\n        $(this.otherOptionsDiv).addClass(\"journal-options\");\n        this.fieldSet.appendChild(this.otherOptionsDiv);\n        // add a feedback div to give user feedback\n        this.feedbackDiv = document.createElement(\"div\");\n        //$(this.feedbackDiv).addClass(\"bg-info form-control\");\n        //$(this.feedbackDiv).css(\"width:530px, background-color:#eee, font-style:italic\");\n        $(this.feedbackDiv).css(\"width:530px, font-style:italic\");\n        this.feedbackDiv.id = this.divid + \"_feedback\";\n        this.feedbackDiv.innerHTML = \"You have not answered this question yet.\";\n        $(this.feedbackDiv).addClass(\"alert alert-danger\");\n        //this.otherOptionsDiv.appendChild(this.feedbackDiv);\n        this.fieldSet.appendChild(this.feedbackDiv);\n        if (this.attachment) {\n            let attachDiv = document.createElement(\"div\")\n            if (this.graderactive) {\n                // If in grading mode make a button to create a popup with the image\n                let viewButton = document.createElement(\"button\")\n                viewButton.type = \"button\"\n                viewButton.innerHTML = \"View Attachment\"\n                viewButton.onclick = this.viewFile.bind(this);\n                attachDiv.appendChild(viewButton);\n            } else {\n                // Otherwise make a button for the student to select a file to upload.\n                this.fileUpload = document.createElement(\"input\")\n                this.fileUpload.type = \"file\";\n                this.fileUpload.id = `${this.divid}_fileme`;\n                attachDiv.appendChild(this.fileUpload);\n            }\n            this.containerDiv.appendChild(attachDiv);\n        }\n        //this.fieldSet.appendChild(document.createElement(\"br\"));\n        $(this.origElem).replaceWith(this.containerDiv);\n        // This is a stopgap measure for when MathJax is not loaded at all.  There is another\n        // more difficult case that when MathJax is loaded asynchronously we will get here\n        // before MathJax is loaded.  In that case we will need to implement something\n        // like `the solution described here <https://stackoverflow.com/questions/3014018/how-to-detect-when-mathjax-is-fully-loaded>`_\n        if (typeof MathJax !== \"undefined\") {\n            this.queueMathJax(this.containerDiv);\n        }\n    }\n\n    renderMath(value) {\n        if (this.mathjax) {\n            value = value.replace(/\\$\\$(.*?)\\$\\$/g, \"\\\\[ $1 \\\\]\");\n            value = value.replace(/\\$(.*?)\\$/g, \"\\\\( $1 \\\\)\");\n            value = value.replace(/\\n/g, \"<br/>\"); // add line breaks\n            $(this.renderedAnswer).html(value);\n            this.queueMathJax(this.renderedAnswer);\n        }\n    }\n\n    async checkCurrentAnswer() {\n        let value = $(document.getElementById(this.divid + \"_solution\")).val();\n        this.renderMath(value);\n        this.setLocalStorage({\n            answer: value,\n            timestamp: new Date(),\n        });\n    }\n\n    async logCurrentAnswer(sid) {\n        let value = $(document.getElementById(this.divid + \"_solution\")).val();\n        this.renderMath(value);\n        this.setLocalStorage({\n            answer: value,\n            timestamp: new Date(),\n        });\n        let data = {\n            event: \"shortanswer\",\n            act: value,\n            answer: value,\n            div_id: this.divid,\n        };\n        if (typeof sid !== \"undefined\") {\n            data.sid = sid;\n        }\n        await this.logBookEvent(data);\n        if (this.attachment) {\n            await this.uploadFile();\n        }\n    }\n\n    renderFeedback() {\n        this.feedbackDiv.innerHTML = \"Your answer has been saved.\";\n        $(this.feedbackDiv).removeClass(\"alert-danger\");\n        $(this.feedbackDiv).addClass(\"alert alert-success\");\n    }\n    setLocalStorage(data) {\n        if (!this.graderactive) {\n            let key = this.localStorageKey();\n            localStorage.setItem(key, JSON.stringify(data));\n        }\n    }\n    checkLocalStorage() {\n        // Repopulates the short answer text\n        // which was stored into local storage.\n        var answer = \"\";\n        if (this.graderactive) {\n            return;\n        }\n        var len = localStorage.length;\n        if (len > 0) {\n            var ex = localStorage.getItem(this.localStorageKey());\n            if (ex !== null) {\n                try {\n                    var storedData = JSON.parse(ex);\n                    answer = storedData.answer;\n                } catch (err) {\n                    // error while parsing; likely due to bad value stored in storage\n                    console.log(err.message);\n                    localStorage.removeItem(this.localStorageKey());\n                    return;\n                }\n                let solution = $(\"#\" + this.divid + \"_solution\");\n                solution.text(answer);\n                this.renderMath(answer);\n                this.feedbackDiv.innerHTML =\n                    \"Your current saved answer is shown above.\";\n                $(this.feedbackDiv).removeClass(\"alert-danger\");\n                $(this.feedbackDiv).addClass(\"alert alert-success\");\n            }\n        }\n    }\n    restoreAnswers(data) {\n        // Restore answers from storage retrieval done in RunestoneBase\n        // sometimes data.answer can be null\n        if (!data.answer) {\n            data.answer = \"\";\n        }\n        this.answer = data.answer;\n        this.jTextArea.value = this.answer;\n        this.renderMath(this.answer);\n\n        let p = document.createElement(\"p\");\n        this.jInputDiv.appendChild(p);\n        var tsString = \"\";\n        if (data.timestamp) {\n            tsString = new Date(data.timestamp).toLocaleString();\n        } else {\n            tsString = \"\";\n        }\n        $(p).text(tsString);\n        if (data.last_answer) {\n            this.current_answer = \"ontime\";\n            let toggle_answer_button = document.createElement(\"button\");\n            toggle_answer_button.type = \"button\";\n            $(toggle_answer_button).text(\"Show Late Answer\");\n            $(toggle_answer_button).addClass(\"btn btn-warning\");\n            $(toggle_answer_button).css(\"margin-left\", \"5px\");\n\n            $(toggle_answer_button).click(\n                function () {\n                    var display_timestamp, button_text;\n                    if (this.current_answer === \"ontime\") {\n                        this.jTextArea.value = data.last_answer;\n                        this.answer = data.last_answer;\n                        display_timestamp = new Date(\n                            data.last_timestamp\n                        ).toLocaleString();\n                        button_text = \"Show on-Time Answer\";\n                        this.current_answer = \"late\";\n                    } else {\n                        this.jTextArea.value = data.answer;\n                        this.answer = data.answer;\n                        display_timestamp = tsString;\n                        button_text = \"Show Late Answer\";\n                        this.current_answer = \"ontime\";\n                    }\n                    this.renderMath(this.answer);\n                    $(p).text(`Submitted: ${display_timestamp}`);\n                    $(toggle_answer_button).text(button_text);\n                }.bind(this)\n            );\n\n            this.buttonDiv.appendChild(toggle_answer_button);\n        }\n        let feedbackStr = \"Your current saved answer is shown above.\";\n        if (typeof data.score !== \"undefined\") {\n            feedbackStr = `Score: ${data.score}`;\n        }\n        if (data.comment) {\n            feedbackStr += ` -- ${data.comment}`;\n        }\n        this.feedbackDiv.innerHTML = feedbackStr;\n\n        $(this.feedbackDiv).removeClass(\"alert-danger\");\n        $(this.feedbackDiv).addClass(\"alert alert-success\");\n    }\n\n    disableInteraction() {\n        this.jTextArea.disabled = true;\n    }\n\n    async uploadFile() {\n        const files = this.fileUpload.files\n        const data = new FormData()\n        if (this.fileUpload.files.length > 0) {\n            data.append('file', files[0])\n            fetch(`/ns/logger/upload/${this.divid}`, {\n                method: 'POST',\n                body: data\n            })\n                .then(response => response.json())\n                .then(data => {\n                    console.log(data)\n                })\n                .catch(error => {\n                    console.error(error)\n                })\n        }\n    }\n\n    viewFile() {\n        // Get the URL from the S3 API -- saved when we display in grader mode\n        if (this.attachURL) {\n            //window.open(this.attachURL, \"_blank\");\n            const image_window = window.open(\"\", \"_blank\")\n            image_window.document.write(`\n                  <html>\n                    <head>\n                    </head>\n                    <body>\n                      <img src=\"${this.attachURL}\" alt=\"Attachment\" >\n                    </body>\n                  </html>\n            `);\n        } else {\n            alert(\"No attachment for this student.\")\n        }\n    }\n}\n\n/*=================================\n== Find the custom HTML tags and ==\n==   execute our code on them    ==\n=================================*/\n$(document).on(\"runestone:login-complete\", function () {\n    $(\"[data-component=shortanswer]\").each(function () {\n        if ($(this).closest(\"[data-component=timedAssessment]\").length == 0) {\n            // If this element exists within a timed component, don't render it here\n            try {\n                window.componentMap[this.id] = new ShortAnswer({\n                    orig: this,\n                    useRunestoneServices: eBookConfig.useRunestoneServices,\n                });\n            } catch (err) {\n                console.log(`Error rendering ShortAnswer Problem ${this.id}\n                Details: ${err}`);\n            }\n        }\n    });\n});\n","import ShortAnswer from \"./shortanswer.js\";\n\nexport default class TimedShortAnswer extends ShortAnswer {\n    constructor(opts) {\n        super(opts);\n        this.renderTimedIcon(this.containerDiv);\n        this.isTimed = true;\n        this.hideButtons();\n    }\n    hideButtons() {\n        $(this.submitButton).hide();\n    }\n    renderTimedIcon(component) {\n        // renders the clock icon on timed components.    The component parameter\n        // is the element that the icon should be appended to.\n        var timeIconDiv = document.createElement(\"div\");\n        var timeIcon = document.createElement(\"img\");\n        $(timeIcon).attr({\n            src: \"../_static/clock.png\",\n            style: \"width:15px;height:15px\",\n        });\n        timeIconDiv.className = \"timeTip\";\n        timeIconDiv.title = \"\";\n        timeIconDiv.appendChild(timeIcon);\n        $(component).prepend(timeIconDiv);\n    }\n    checkCorrectTimed() {\n        return \"I\"; // we ignore this in the grading\n    }\n    hideFeedback() {\n        $(this.feedbackDiv).hide();\n    }\n}\n\nif (typeof window.component_factory === \"undefined\") {\n    window.component_factory = {};\n}\n\nwindow.component_factory.shortanswer = function (opts) {\n    if (opts.timed) {\n        return new TimedShortAnswer(opts);\n    }\n    return new ShortAnswer(opts);\n};\n"],"names":["ShortAnswer","constructor","opts","super","orig","this","useRunestoneServices","eBookConfig","origElem","divid","id","question","innerHTML","optional","attachURL","$","is","mathjax","attachment","placeholder","data","renderHTML","caption","addCaption","checkServer","Prism","highlightAllUnder","containerDiv","document","createElement","addClass","getAttribute","newForm","name","action","appendChild","fieldSet","firstLegendDiv","jInputDiv","jOptionsDiv","jTextArea","self","onchange","isAnswered","attr","css","rows","cols","isTimed","feedbackDiv","removeClass","bind","renderedAnswer","buttonDiv","submitButton","type","textContent","onclick","checkCurrentAnswer","logCurrentAnswer","renderFeedback","randomSpan","otherOptionsDiv","attachDiv","graderactive","viewButton","viewFile","fileUpload","replaceWith","MathJax","queueMathJax","renderMath","value","replace","html","getElementById","val","setLocalStorage","answer","timestamp","Date","sid","event","act","div_id","logBookEvent","uploadFile","key","localStorageKey","localStorage","setItem","JSON","stringify","checkLocalStorage","length","ex","getItem","parse","err","console","log","message","removeItem","text","restoreAnswers","p","tsString","toLocaleString","last_answer","current_answer","toggle_answer_button","click","display_timestamp","button_text","last_timestamp","feedbackStr","score","comment","disableInteraction","disabled","files","FormData","append","fetch","method","body","then","response","json","catch","error","window","open","write","alert","on","each","closest","componentMap","TimedShortAnswer","renderTimedIcon","hideButtons","hide","component","timeIconDiv","timeIcon","src","style","className","title","prepend","checkCorrectTimed","hideFeedback","component_factory","shortanswer","timed"],"sourceRoot":""}