diff --git a/htdocs/js/Feedback/feedback.js b/htdocs/js/Feedback/feedback.js index b7271cee39..83e2c40025 100644 --- a/htdocs/js/Feedback/feedback.js +++ b/htdocs/js/Feedback/feedback.js @@ -21,10 +21,27 @@ Array.from(origScript.attributes).forEach((attr) => newScript.setAttribute(attr.name, attr.value)); newScript.appendChild(document.createTextNode(origScript.innerHTML)); origScript.parentNode.replaceChild(newScript, origScript); + setTimeout(() => bsPopover.update()); }); // Make a click on the popover header close the popover. bsPopover.tip?.querySelector('.popover-header')?.addEventListener('click', () => bsPopover?.hide()); + + const revealCorrectBtn = bsPopover.tip?.querySelector('.reveal-correct-btn'); + revealCorrectBtn?.addEventListener('click', () => { + revealCorrectBtn.classList.add('fade-out'); + revealCorrectBtn.parentElement.classList.add('resize-transition'); + revealCorrectBtn.parentElement.style.maxWidth = `${revealCorrectBtn.parentElement.offsetWidth}px`; + revealCorrectBtn.parentElement.style.maxHeight = `${revealCorrectBtn.parentElement.offsetHeight}px`; + revealCorrectBtn.addEventListener('animationend', () => { + revealCorrectBtn.nextElementSibling?.classList.remove('d-none'); + revealCorrectBtn.nextElementSibling?.classList.add('fade-in'); + revealCorrectBtn.parentElement.style.maxWidth = '1000px'; + revealCorrectBtn.parentElement.style.maxHeight = '1000px'; + revealCorrectBtn.remove(); + bsPopover.update(); + }); + }); }); }; diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss index f86fc9f59b..71c59d9c74 100644 --- a/htdocs/js/Problem/problem.scss +++ b/htdocs/js/Problem/problem.scss @@ -287,6 +287,39 @@ border-bottom-right-radius: var(--bs-card-inner-border-radius); } } + + &.resize-transition { + overflow: clip; + transition: max-height 1s ease-in, max-width 1s ease-in; + } + + .fade-out { + animation: fade-out 0.25s ease-in; + + @keyframes fade-out { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } + } + } + + .fade-in { + animation: fade-in 0.5s ease-in; + + @keyframes fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } + } + } } } } diff --git a/lib/WeBWorK/PG.pm b/lib/WeBWorK/PG.pm index c34153e1a2..fb6c6d1a34 100644 --- a/lib/WeBWorK/PG.pm +++ b/lib/WeBWorK/PG.pm @@ -513,9 +513,12 @@ The summary will also be generated if this is true. Determines if any messages generated in answer evaluation will be shown. -=item showCorrectAnswers (boolean, default: 0) +=item showCorrectAnswers (numeric, default: 0) -Determines if correct answers will be shown. +Determines if correct answers will be shown. If 0, then correct answers are not +shown. If set to 1, then correct answers are shown but hidden, and a "Reveal" +button is shown at first. If that button is clicked, then the answer is shown. +If set to 2, then correct answers are shown immediately. =item answerPrefix (string, default: '') diff --git a/macros/PG.pl b/macros/PG.pl index 35be2bf389..97a96f08ec 100644 --- a/macros/PG.pl +++ b/macros/PG.pl @@ -902,8 +902,10 @@ =head2 ENDDOCUMENT =item * C: This is a boolean value that is 1 by default. If this is true -and the translator option C is also true, then a preview of -the correct answer is shown in the feedback popover. +and the translator option C is nonzero, then a preview of +the correct answer is shown in the feedback popover. In other words, this option +prevents showing correct answers even if the frontend requests that correct +answers be shown. =item * @@ -1230,14 +1232,29 @@ sub ENDDOCUMENT { ) . ( $rh_envir->{showCorrectAnswers} && $options{showCorrect} - ? feedbackLine( - maketext('Correct Answer'), - previewAnswer( + ? do { + my $correctAnswer = previewAnswer( $ansHash->{correct_ans_latex_string}, $options{wrapPreviewInTex}, $ansHash->{correct_ans} - ) - ) + ); + feedbackLine( + maketext('Correct Answer'), + $rh_envir->{showCorrectAnswers} > 1 + ? $correctAnswer + : Mojo::DOM->new_tag( + 'button', + type => 'button', + class => 'reveal-correct-btn btn btn-secondary btn-sm', + maketext('Reveal') + ) + . Mojo::DOM->new_tag( + 'div', + class => 'd-none', + sub {$correctAnswer} + ) + ); + } : '' ); }