Skip to content

WeBWorK 2.21 Release Candidate#2940

Open
drgrice1 wants to merge 526 commits into
mainfrom
WeBWorK-2.21
Open

WeBWorK 2.21 Release Candidate#2940
drgrice1 wants to merge 526 commits into
mainfrom
WeBWorK-2.21

Conversation

@drgrice1

Copy link
Copy Markdown
Member

This is the release candidate for WeBWorK 2.21. Please re-target any pull requests that you want to get into the release for this branch.

drgrice1 and others added 30 commits March 29, 2026 10:36
The `switchToBSStyle` method should be called on the `commonStyles` key
of the `CHTML` object rather than the object itself (which is actually a
function).
Fix an issue with MathJax CHTML mode.
Rework PG error/warning/debug message handling.
Add a point input field to set the problem score in the ProblemGrader.
This is the same as what is being used in the SingleProblemGrader,
and honors the same setting to show it or not. The input uses
JavaScript to update the actual score which is what is submitted
when the grader is saved. If the percent score is not shown, a hidden
field is used instead.

This also adds a step of 1 to the percent score and validation on
both the percent score and point score values.
Add point input to ProblemGrader.
First, remove the `div` with the `mb-3` class that I added to the `Email
Instructor` button in #2935.  I added it so that warnings or debug
messages are appropriately spaced after the button on the problem page.
However, the `feedback_macro_email.html.ep` template is used in other
places for which that margin causes issues (for example on the problem
set page).  Instead the `div` is added on the problem page, if the
button is to be shown.

Note that `problemFooter` div has been removed, since that isn't even
doing anything.

Also, the database access in the `output_past_answer_button` is skipped
if the button is not to be shown. I just saw this while working on the
area and realized that is bad.

Finally, the `h4` for the header of the achievement rewards dialog is
changed to an `h1`.  The css `h4` class is used to give the header the
same size and style.  Note that structurally a "modal dialog represents
its own separate document/context, so the .modal-title should ideally be
an `<h1>`." That is quoted from bootstraps [modal dialog
documentation](https://getbootstrap.com/docs/5.3/components/modal/).
show desired course ID in messages for when course does not exist
Fix some layout and validation issues.
With the current code if you are in a month that does not have a day
(such as April that does not have the 31st), one of those days is
selected in another month that does have that day, and you click the
"Today" button, then it doesn't go to today.  Instead it goes to the
date of today in the next month.  This is because the code sets the
year, month, and day for today on the selected date object and in that
order, and uses the modified selected date to set the flatpickr date.
So for example, if today is April 7, 2026, and the selected date is July
31, 2026, then the selected date's year is set to 2026, then the month
set to April.  So at that point the selected date is April 31, 2026,
which really becomes May 1, 2026.  Then the day is set, and so you get
May 7, 2026.

This fixes the issue by starting with todays date at 12:00 am, and then
setting the time of todays date to the time of the selected date, and
then using that to set the flatpickr date.
… page.

Currently that style is defined in the `system.scss` and is not scoped.
As a result it applies to most content generator pages of webwork2.  In
particular it applies to problem pages, and thus it affects draggable
proof problems which use the same sortablejs library with that same css
class.

Note that a related pull request to PG will change the styles for drag
and drop problems and this conflicts with that.  This is probably
already a problem because the opacity of 0.5 does make the drag and drop
elements in problems lack sufficient contrast. Although it only occurs
during a mouse drag and in that situation perhaps that contrast is not
necessary. Still I think there is a better way to do this for problems.

On a related note to the PG pull request, perhaps at some point keyboard
support should be added for reorganizing problems on the problem set
detail page.
When saving a problem in a new location in the PGProblemEditor,
add an option to copy auxiliary files or not. Since it is not
possible to determine what files are needed, all auxiliary files
were copied in all cases. This allows the user to uncheck the
"Copy auxiliary files" option to not copy any auxiliary files.

The default option is to copy auxiliary files which has not
changed. This only allows the user to disable that if they are
sure no auxiliary files are needed.

This also adds a check so the message about auxiliary files
being copied only shows if at least one file was copied.
Updated packages have been published, and this just updates the
package.json file to point to the latest version.

The dependencies of the `pg-codemirror-editor` and `codemirror-lang-pg`
packages were updated (largely to deal with security vulnerabilities in
the dependencies).

There is also a bug fixed with builtin operator names occuring as the
key of a hash. For example, the keys of the following hash are builtin
operators, but should not be interpreted as such in this context.

```perl
%hash = (
    step    => 1,
    defined => 1,
    split   => 1
);
```

Since they were the hask key value pair was not parsing, and so all
syntax highlighting after it is messed up.

The first key `step` is a PG operator, the second `defined` is a Perl
named unary operator, the third `split` is a Perl list operator.  Of
course any of the other PG operators, Perl named unary operators, or
Perl list operators had the same problem since they are all handled in
the code by the same external tokenizer.
This adds some spacing between the set link and the info icon to
make it accessible on small touch screens to give enough space to
touch the icon without hitting the link instead.
There is no longer a `pgwarning` key set on the controller object for
the `lib/WeBWorK/ContentGenerator/Problem.pm` module and never was a
`pgwarning` key for the returned pg object in the
`lib/ContentGenerator/GatewayQuiz.pm` module.  So use the correct key on
the returned pg object in both cases.  That is the `warning_messages`
key.

The warning messages were still being shown at the bottom, but not the
message at the top of the page notifying of the existence of those
warnings.  Since the warnings at the bottom might not be visible, the
warnings may be missed.
Co-authored-by: Glenn Rice <47527406+drgrice1@users.noreply.github.com>
Co-authored-by: Glenn Rice <47527406+drgrice1@users.noreply.github.com>
Co-authored-by: Glenn Rice <47527406+drgrice1@users.noreply.github.com>
I removed the `reference-link` class from these links in #2896.  That
was a mistake.  That class does do something.  It is what the javascript
uses to determine which links need the tooltips. So add those back.
Also, the `writeCourseConf` method doesn't need any arguments other than
the file handle anymore, so eliminate those.
Add horizontal padding to set info icon.
Fix Resurrect Achievement Items
PGProblemEditor: Add option to copy auxiliary files.
…tips

Fix the reference link tooltips on the PG Problem Editor page.
transifex-integration Bot and others added 30 commits July 16, 2026 09:34
10% of minimum 1% translated source file: 'webwork2.pot'
on 'ko'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…225881

Updates for file lib/WeBWorK/Localize/webwork2.pot in es [Manual Sync]
38% of minimum 1% translated source file: 'webwork2.pot'
on 'el'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…e80e68

Updates for file lib/WeBWorK/Localize/webwork2.pot in ko [Manual Sync]
6% of minimum 1% translated source file: 'webwork2.pot'
on 'zh_CN'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…41b207

Updates for file lib/WeBWorK/Localize/webwork2.pot in el [Manual Sync]
31% of minimum 1% translated source file: 'webwork2.pot'
on 'fr_CA'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…86f39c

Updates for file lib/WeBWorK/Localize/webwork2.pot in zh_CN [Manual Sync]
…ca662b

Updates for file lib/WeBWorK/Localize/webwork2.pot in fr_CA [Manual Sync]
5% of minimum 1% translated source file: 'webwork2.pot'
on 'cs_CZ'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
5% of minimum 1% translated source file: 'webwork2.pot'
on 'zh_HK'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…09b01c

Updates for file lib/WeBWorK/Localize/webwork2.pot in cs_CZ [Manual Sync]
11% of minimum 1% translated source file: 'webwork2.pot'
on 'hu'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…881df7

Updates for file lib/WeBWorK/Localize/webwork2.pot in hu [Manual Sync]
…9ae7d9

Updates for file lib/WeBWorK/Localize/webwork2.pot in zh_HK [Manual Sync]
21% of minimum 1% translated source file: 'webwork2.pot'
on 'de'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…a555ba

Updates for file lib/WeBWorK/Localize/webwork2.pot in de [Manual Sync]
47% of minimum 1% translated source file: 'webwork2.pot'
on 'he_IL'.

Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
…fe77ba

Updates for file lib/WeBWorK/Localize/webwork2.pot in he_IL [Manual Sync]
- `templates/ContentGenerator/Grades/problem_table.html.ep`: On line 40
  a `th` is closed with a `td`.
- `templates/HelpFiles/InstructorAchievementList.html.ep`: On line 76 a
  `dt` tag is closed with a `td`.
- `templates/ContentGenerator/Options.html.ep`: On line 170 a `legend`
  is closed with a `fieldset`.
- `templates/HelpFiles/InstructorScoring.html.ep`: Starting at line 18
  there is a `dl` nested inside a `p` which is invalid HTML. So end the
  `p` tag before the `dl` is started.
- `templates/ContentGenerator/Instructor/Scoring.html.ep`: The ending
  `dl` tag on line 96 should not be inside the for loop. This results in
   extraneous `dl` closings.
- `templates/ContentGenerator/Base/set_status.html.ep`: A `p` tag is
  incorrectly created using a string instead of a proper tag on line 11.
- `templates/ContentGenerator/ProblemSet.html.ep`: A `p` tag is created
  in a bad way on line 44.
- `templates/ContentGenerator/Instructor/ProblemSetList/set_list_row.html.ep`:
  A `tr` tag is started on line 16 that is never ended.  It should be
  ended at the end of the file.

The last two are not strictly HTML validation issues, and do work, but
they are not done in a good way.
Make the workflow work for Perl scripts without a Perl extension.
Make the color scheme chooser active theme check work.
First, the `lineitems` URL that is sent with any resource link (and even
for a deep linking request, i.e., a content selection request) is stored
in the course settings whenever one of those occur.  This `lineitems`
URL is unique for the external tool, and can be used to fetch a list of
all resource links that use the external tool. Then when any grade pass
back is performed this URL is used to get that list which includes the
`lineitem` URL for each specific resource link. That is the link that is
used for grade pass back for the set.  However, webwork needs to be able
to identify the set it belongs to.  Since it does not come from a
resource link launch the webwork2 set id is not available.  To fix this,
when deep linking is used to create a resource link, webwork now sets
the `resourceId` of the lineitem.  Note that this is a reserved value
for the tool provider, and the LMS (the tool consumer) is not supposed
to ever change it, and must send it when the `lineitems` URL is used.
Thus is deep linking is used to create a resource link to a set, then
grade pass back will be available immediately for that set without a
user ever using the link.

Second, implement LMS roster synchronization.  The requires that the
names and roles service be enabled for the external tool.  The
registration URL now includes the
`https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly`
scope which makes this so. Note that tools created manually without the
registration URL, this service can be enabled for the tool.  However, at
least for Canvas, if the tool was created using the registration URL
before this scope was added, the only way to add the scope is to have
the Canvas admin delete the tool and recreate it again using the
registration URL with what is in this pull request. Moodle still allows
editing of the tool created via the registration URL, so this can be
added later. In any case, if the names and roles service is enabled,
than any launch request (again including a deep linking request)
includes the `namesrolesservice` URL. That can be used to request the
list of users in the LMS course.  There is now a new tab that will
appear in the accounts manager if LTI 1.3 is enabled for a course, the
`preferred_source_of_username` is set, and this `namesrolesservice` URL
has been obtained (by some user using content selection or a resource
link).  When this tab is available and its action used, the list of
users in the LMS course will be obtained, and users will be created in
webwork that do not already exist, users will be updated that do exist
(if `LMSManageUserData` is true), and users not in the LMS course will
have their status changed to dropped.  Note that the data sent when
using the `namesrolesservice` URL is not the same as that sent in a
launch request.  So there are some new options that control what is used
for the username and student_id.  See the options and documentation in
`conf/authen_LTI_1_3.conf.dist`. Also note that this will never add,
update, or modify in any way any users that have a role that is above
the `LTIAccountCreationCutoff`.

Note that when users are created or updated via the tab in the accounts
manager and the `namesrolesservice` URL, the LMS `user_id` (or `sub`) is
included in the data received and saved to the `lis_source_did` column
for the user.  So this means that for links created via deep linking
with this pull request and users added or updated in this way, grade
pass back is available immediately, even if the user never logs in to
webwork via the LMS.

Also fix plurality of some texts for some other similar action results
in the accounts manager.

Unfortunately the message on the assignments page stating "You must
access this assignment from the LMS before you can start." is still
shown even if an instructor uses deep linking to create links in the
LMS.  The problem is that although grade passabck will work for those
sets, the lineitem URL is still not saved in the database for all of
those sets.  The lineitem is not obtained until grade pass back occurs
or as before, a user uses the link from the LMS. So those that create
all links via deep linking will most likely want to set
`$LTI{v1p3}{ignoreMissingSourcedID}` so that users are not shown that
message, and can access the sets. As such, I made that option one that
can be made available for instructors to set on the LTI tab in the
course configuration.

Third, implement set date synchronization with the LMS. Set dates can be
synchronized to or from the LMS. There is a new tab for this in the sets
manager that is shown if LTI 1.3 with homework grade pass back is
enabled and the general lineitems URL is available. Also there is a new
LTI 1.3 option `$LTI{v1p3}{autoSyncSetDatesToLMS}`. If this is true,
then anytime that dates are changed on the sets manager or problem set
detail pages, a job to synchronize dates to the LMS will automatically
be queued for the sets with dates changed.

Note that only the open and due (or close) dates have an equivalent in
the LTI specification, namely the start and end dates. So when
synchronizing from an LMS, the reduced scoring date and answer date are
adjusted if needed to make them fit into the dates received from the
LMS. Of course, when sending dates, only the open and due date are sent.

It is also important to note that date synchronization is not supported
by all LMSs.  Canvas does, but Moodle does not.  As usual, I don't know
what D2L or Blackboard support.

One related small change is that set dates are now also set when grade
pass back mode is homework and a link is created to a set via deep
linking.

Another small change to the deep linking response is that
`window => { targetName => '_blank' }` is set. This makes Canvas open
the links in a new window instead of being embedded in the page. This
does not work for Moodle, and as far as I can tell, there is no way to
make this happen from the deep linking response.  Fortunately for Moodle
users, the external tool can be set so that all links created that use
the external tool open in a new window.  Canvas on the other hand does
not have that.  So without this change, Canvas users that create links
have to go edit each link and change it to open in a new window.
…from the LMS optional.

According to the specification it is optional, and apparently D2L does
not send it.  Both Moodle and Canvas do.

Also make sure that the `placements` message parameter is only sent for
Canvas. Although Moodle ignores this parameter, D2L rejects the message
if the parameter is included.

Also add a `description` to the lti tool configuration, and a label to
the deep linking message.
If the new `$LTI{v1p3}{allowCourseSelection}` option is set to 1 and an
instructor attempts to sign in via LTI 1.3 authentication from an LMS
course that is not in the LTI course map for the site, then a list of
webwork courses will be compiled that have matching LTI 1.3 parameters,
that have a user that works for the LMS user with email_address set that
matches the email address sent from the LMS, and such that the user has
the access_instructor_tools and modify_problem_sets permissions. So it
is important that the email_address be set in the webwork courses for
the user. Also note that the LTI user id selection parameters
(`preferred_source_of_username`, `fallback_source_of_username`,
strip_domain_from_email`, and `lowercase_username`) have to be the same
for all matching courses (effectively the settings from the first course
found are used).

Then the user will be presented a list of courses to choose from (or if
only one matching course is found that course will be used). When the
user selects a course (or only on course matches), it will be
automatically added to the LTI course map, and then content selection
will continue as usual with that course.

For this to work, the user is authenticated into the first matching
course. Then if the user chooses a different course, that authentication
is transferred to the selected course. Authentication should work in any
of them since all of the matching courses have the same LTI 1.3
parameters and the user in each course has the same user id, email
address, and permissions.

If no matching courses are found or if the `$LTI{v1p3}{allowCourseSelection}`
option is set to 0, then the context id is shown as before.

Note that the `$LTI{v1p3}{allowCourseSelection}` is necessarily a site
wide option that cannot be configured per course.
This was requested by @dlglin, and restricts authentication into a
webwork course to only users in the LMS course that matches the context
id of the webwork course set in the LTI course map for the site.

If the new `$LTI{v1p3}{restrictAuthenticationByCourseMap}` option is set
to 1, then this restriction is in effect.
…hoice-plus-context-id-restrict

Restrict LTI authentication by LTI course map.
The only dependency that is updated that is not for the
`generate-assets.js` script is `@fortawesome/fontawesome-free` and there
do not seem to be any issues from that.  From their changelog the only
changes are new icons and some improvements to animations.

The `generate-assets.js` script still seems to be working fine, so the
development updates should be fine also.

The security vulnerabilities that just showed up were fixed with the
upgrade.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants