Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move Hint and Solution knowls to details/summary disclosure #941

Merged
merged 8 commits into from
Oct 30, 2023
Merged
39 changes: 39 additions & 0 deletions htdocs/js/Problem/details-accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
(() => {
const setupAccordion = (accordion) => {
const collapseEl = accordion.querySelector('.collapse');
const button = accordion.querySelector('summary.accordion-button');
const details = accordion.querySelector('details.accordion-item');
if (!collapseEl || !button || !details) return;

const collapse = new bootstrap.Collapse(collapseEl, { toggle: false });
button.addEventListener('click', () => collapse.toggle());

details.addEventListener('click', (e) => e.preventDefault());
collapseEl.addEventListener('show.bs.collapse', () => {
details.open = true;
button.classList.remove('collapsed');
});
collapseEl.addEventListener('hide.bs.collapse', () => button.classList.add('collapsed'));
collapseEl.addEventListener('hidden.bs.collapse', () => (details.open = false));
};

// Deal with solution/hint details that are already on the page.
document.querySelectorAll('.solution.accordion, .hint.accordion').forEach(setupAccordion);

// Deal with solution/hint details that are added to the page later.
const observer = new MutationObserver((mutationsList) => {
mutationsList.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node instanceof Element) {
if (
(node.classList.contains('solution') || node.classList.contains('hint')) &&
node.classList.contains('accordion')
)
setupAccordion(node);
else node.querySelectorAll('.solution.accordion, .hint.accordion').forEach(setupAccordion);
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
6 changes: 6 additions & 0 deletions htdocs/js/Problem/problem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@
border: 1px solid black;
}
}

/* Hints and Solutions */
.hint summary, .solution summary {
font-weight: bold;
color: var(--bs-primary);
Alex-Jordan marked this conversation as resolved.
Show resolved Hide resolved
}
}

/* rtl:raw:
Expand Down
11 changes: 6 additions & 5 deletions macros/PG.pl
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,12 @@ sub ADD_JS_FILE {
# Some problems use jquery-ui still, and so the requestor should also load the js for that if those problems are used,
# although those problems should also be rewritten to not use jquery-ui.
sub load_js() {
ADD_JS_FILE('js/InputColor/color.js', 0, { defer => undef });
ADD_JS_FILE('js/Base64/Base64.js', 0, { defer => undef });
ADD_JS_FILE('js/Knowls/knowl.js', 0, { defer => undef });
ADD_JS_FILE('js/ImageView/imageview.js', 0, { defer => undef });
ADD_JS_FILE('js/Essay/essay.js', 0, { defer => undef });
ADD_JS_FILE('js/InputColor/color.js', 0, { defer => undef });
ADD_JS_FILE('js/Base64/Base64.js', 0, { defer => undef });
ADD_JS_FILE('js/Knowls/knowl.js', 0, { defer => undef });
ADD_JS_FILE('js/Problem/details-accordion.js', 0, { defer => undef });
ADD_JS_FILE('js/ImageView/imageview.js', 0, { defer => undef });
ADD_JS_FILE('js/Essay/essay.js', 0, { defer => undef });

if ($envir{useMathQuill}) {
ADD_JS_FILE('node_modules/mathquill/dist/mathquill.js', 0, { defer => undef });
Expand Down
43 changes: 38 additions & 5 deletions macros/core/PGbasicmacros.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,24 @@ sub SOLUTION {
return "" if $solution_body eq "";

if ($displayMode =~ /HTML/) {
TEXT('<div class="knowl-container">',
knowlLink(SOLUTION_HEADING(), value => $solution_body, type => 'solution'), '</div>');
TEXT(tag(
'div',
class => 'solution accordion my-3',
tag(
'details',
class => 'accordion-item',
tag(
'summary',
class => 'accordion-button collapsed p-2',
Alex-Jordan marked this conversation as resolved.
Show resolved Hide resolved
tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING())
)
. tag(
'div',
class => 'accordion-collapse collapse',
tag('div', class => 'accordion-body', $solution_body)
)
)
));
} elsif ($displayMode =~ /TeX/) {
TEXT(
"\n%%% BEGIN SOLUTION\n"
Expand All @@ -1208,7 +1224,24 @@ sub HINT {
my $hint_body = hint(@_);
return unless $hint_body;
if ($displayMode =~ /HTML/) {
TEXT('<div class="knowl-container">', knowlLink(HINT_HEADING(), value => $hint_body, type => 'hint'), '</div>');
TEXT(tag(
'div',
class => 'hint accordion my-3',
tag(
'details',
class => 'accordion-item',
tag(
'summary',
class => 'accordion-button collapsed p-2',
tag('div', class => 'accordion-header user-select-none', HINT_HEADING())
)
. tag(
'div',
class => 'accordion-collapse collapse',
tag('div', class => 'accordion-body', $hint_body)
)
)
));
} elsif ($displayMode =~ /TeX/) {
TEXT(
"\n%%% BEGIN HINT\n"
Expand Down Expand Up @@ -1506,15 +1539,15 @@ sub END_ONE_COLUMN { # deprecated
sub SOLUTION_HEADING {
MODES(
TeX => '{\\bf ' . maketext('Solution:') . ' }',
HTML => '<B>' . maketext('Solution:') . '</B> ',
HTML => maketext('Solution'),
PTX => ''
);
}

sub HINT_HEADING {
MODES(
TeX => '{\\bf ' . maketext('Hint:') . ' }',
HTML => '<B>' . maketext('Hint:') . '</B> ',
HTML => maketext('Hint'),
PTX => ''
);
}
Expand Down
1 change: 1 addition & 0 deletions t/pg_problems/problem_file.t
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ is(
{ file => 'js/InputColor/color.js', external => 0, attributes => { defer => undef } },
{ file => 'js/Base64/Base64.js', external => 0, attributes => { defer => undef } },
{ file => 'js/Knowls/knowl.js', external => 0, attributes => { defer => undef } },
{ file => 'js/Problem/details-accordion.js', external => 0, attributes => { defer => undef } },
{ file => 'js/ImageView/imageview.js', external => 0, attributes => { defer => undef } },
{ file => 'js/Essay/essay.js', external => 0, attributes => { defer => undef } },
{ file => 'node_modules/mathquill/dist/mathquill.js', external => 0, attributes => { defer => undef } },
Expand Down