Introduce a lang string `questioniconfollowlangdirection` that will
allow the current behaviour of displaying the question mark icon
in RTL languages in the same manner as the current language.
This fixes the changes made in MDL-75047:
* Change `thisicondirection` langconfig string to a more specific one
like `questionicondirection`.
* Use existing direction string value `ltr` for the value of
`questionicondirection`. Also add a comment to at least provide some
form of documentation for it.
* Improve the logic for applying the horizontal flipping class for the
question icon:
- Check first if the icon is a question icon
- Flip the icon if `questionicondirection` is set to `rtl`.
Patch makes user dashboard respect permission overrides
that have been set on individual blocks on the system
dashboard (indexsys.php). When a user dashboard is created
either when the user visits their dashboard for the first
time or after an admin reset. When blcoks are copied to
the new dashbaord overriden permissions are also copied.
This is in keeping with other Editors such as Atto and resolves an issue
where DOM Purification incorrectly identifies HTML-like string content
as an HTML tag with a JS variable.
Moodle already performs XSS sanitisation using HTML Purifier in PHP.
This bumps direct dependencies to current ones:
- phpunit: 9.5.x No updates here, there is the 9.6.x series
available but a lot of deprecation warnings have been
introduced there without any alternative to use. See:
- https://github.com/sebastianbergmann/phpunit/issues/5160
- https://github.com/sebastianbergmann/phpunit/issues/5062
- ...
While that will be handy to prepare ourselves to PHPUnit 10
in some months... we cannot force everybody to jump to 9.6.x
because that will make a lot of tests to start emitting
warnings.
So we stay with PHPUnit 9.5.x for the life of this branch.
- mink-phpwebdriver: 1.2.1 No updates here, just changed the
constraint because we cannot advance to 1.3.x yet, there is
a change there causing some app tests to fail. See:
- https://github.com/oleg-andreyev/MinkPhpWebDriver/pull/81
So we stay with 1.2.x until that issue is fixed/clarified,
only then we'll review the status.
- behat: 3.12.x => 3.13.x
And also, automatically, a bunch of 2nd and deepest dependencies.
Generated with php74 that is the lowest php version supported
by this branch and, also, by some of the dependencies, as per
documented @ https://moodledev.io/general/development/tools/composer
Worth mentioning behat/mink-goutte-driver, that we should move
to mink-browserkit-driver, but that's out from this issue scope.
The boost theme makes the TinyMCE editor rendered in a scrollable container,
scrolling the editor’s container will cause TinyMCE UI elements to be detached from the anchor.
Therefore, to keep the tinyMCE menu in the correct position,
adjustments must be made on the page drawers style.
When using TinyMCE editor in Safari browsers, a problem may occur where the dialogue
windows (such as modal dialogs) overlap with page drawers due to a specific behavior
in Safari's rendering. This function addresses the issue by adjusting the CSS overflow
property of the page drawers, ensuring they do not obscure the dialogue windows.
* Using the generator to create the forum discussions, the timecreated
of a discussion can be set before the user's last course access which
will prevent forum_print_recent_activity() from including this generated
discussion in the recent activity results. To work around this, generate
the forum discussion 1 second after the current time to make sure that
the user's last course access will always be before the discussion's
creation time.
* This patch also includes some optimisations by:
- Removing the unnecessary @javascript tag for the
`Time limit expires` scenario
- Bringing the discussion generation to each scenario to allow each
scenario to customise the data passed to the generator like for the
`Time limit expires` scenario.
- Navigating directly to the forum instance.
This commit does few things:
* Replace manual forum posts and replies to use data generator.
* It also changes the code to handle social forums.
* Other behat clean-ups and optimization.
Co-authored-by: Simey Lameze <simey@moodle.com>
The current I am on course homepage with editing mode loads twice the
course page. This patch prevents this from happening by going directly
to editmode.php.
Aurora MySQL does not support row format COMPRESSED and falls back
to COMPACT if you try to use it, cuasing column size too large
errors if you try to use it with utf8mb4 collation.
Where only the case of the idnumber field was being updated, we
triggered an exception because checking for an exising idnumber
was not excluding the current category (i.e. the one being updated).
Otherwise the enrolment index page tries to load the course index
drawer, which doesn't exist at this point and triggers exceptions in
the editor module.
Co-authored-by: Tim Volckmann <tim.volckmann@mastersolution.com>
The completion_rule_enabled() method was not checking all the fields
and, in some cases, it was returning false (because it was not checking
that "Count of entries" field was enabled).
Change the param type of the category name when editing to allow
for entry of multilang tags, the formatting of which is already
supported when returning category name.
Co-authored-by: Hiroto Kagotani <hiroto.kagotani@gmail.com>
Ensures cross-DB compatibility for all types of both custom and user
profile fields, specifically when they're filtered and/or aggregated.
Implement stress testing of both via appropriate report sources.
The selected value of the dropdown was being cleared when the dropdown
was opened, this was causing an error when submitting the form if the
field was required. The main cause was that we were emptying the
select before loading new values, this solution was created because
of an issue where we could not deselect values if the list was
reloaded. To fix this problem, I added an empty option as the first
element of the select only when deselecting a certain item.
If we cannot resize the given file (files such as ICO can't be, for
SVG it makes no sense), then we should just return the original file
as is rather than an error.
From my experimentation I have discovered that Safari does not properly
respect the standard MediaRecorder mimetype. Instead of using `codecs=`
it uses `codecs:`.
This change copies the codec array to have the list of possible codecs
include both codecs= and codecs: whilst remaining in order.
Add a new method for activity_header that determines the heading level
depending on whether the theme displays a heading for the activity
header (usually a h2 heading with the activity name).
E.g. in Boost, the activity name is already being displayed in a
heading. So page headings can be rendered as h2. However, on Classic,
the activity name is being displayed as a h2 heading. So headings need
to be adjusted for the activity pages.
- Improve the grammatical structure of the lang string.
- Remove the mention of "link", for sighted users, it should already
be obvious that it's a link. For screen reader users, screen readers
already announce links. So it would be confusing for them to hear
something like "Click 'Moodle.org, link' link to open resource"
Add a help text explaining that the URL resource's name field will be
used for the link text. Also add basic guidelines about naming links for
the benefit of screen reader users.
LTI 1.1 uses OAuth 1.0, which requires 'hostname', among other things,
as part of signature verification. When Moodle is run behind a reverse
proxy, $_SERVER['SERVER_NAME'] is an unreliable way to fetch hostname.
It isn't always equal to the external hostname but instead can contain
the local host, meaning the signature verification will fail. This
change replaces the use of $_SERVER vars with $FULLME - which already
takes this into account - to fix the signature verification.
Co-authored-by: Berengar W. Lehr <Berengar.Lehr@uni-jena.de>
It turns out that there are plugins which don't (currently)
clean up their question attempts when a context is deleted.
Therefore, we need to make Moodle core robust to that.
This covers the case where a course is published and the launch data
doesn't include the 'lineitem' property of the ags claim, meaning the
tool can manage its own line items.
With courselistshortnames enabled Moodle 3.11 and earlier showed
"Category | Short name" on the first line of course cards (for example
in block_myoverview). From Moodle 4.0 the category is moved to the last
line making the first line "Short name |". This change removes that
stray "|".
* Process markdown and other allowed formats (see FORMAT_XXX) in get_label_name
so it does not display it as a litteral string in the course index menu.
This handles things like site policies, which store the current URL,
redirect to the policy agreement, then redirect back the current URL
afterwards. In such cases, we want to redirect back with 'launchid' set
so that we can fetch the id_token from the session cache. This is the
same thing we already do during account binding, so the patch only
makes sure the PAGE->url is properly set before calling require_login.
This is a backport from MDL-77842.
In MDL-77086 some extra information was added when a badge can't be
sent to a backpack. However, as the Badgr is not following the
specification, it's still hard to debug it when it fails (as
raised in MDL-75552, Badgr is not working because, in some cases,
it's returning the "Method Not Allowed / Request method 'POST'
not supported" error.
Ensure we don't create nested <script> tags when rendering templates,
which triggers console errors since 1ef815cd.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
Changes done to fix the warnings thrown in the history view when the
last version of a question is deleted and improved UI to display the
message and a Continue button, to navigate back to the Question bank.
Import now checks whether assignment is an group submission and
matches group ids instead of user ids in that case.
Additionally check for original unchanged files to not import in
group files instead of user files.
Replace steps that manually add page instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
Co-authored-by: Simey Lameze <simey@moodle.com>
The property was added to the config options in c3f4123b, however no
default value was provided, meaning if it was ever unset then a PHP
type error would be triggered on the null return.
If an activity, like workshop or forum, has multiple grade items,
declarative binding of the grade item (line item) isn't supported.
Instead of throwing an exception, handle the case more elegantly
and just omit the 'add to gradebook' option for these activities.
Converting these tests to use an onlinetext submission and drop the JS
requirement means that they are much less susceptible to runtime issues,
and not susceptible to those caused by JS at all.
This random failure was happening because of the time required to render
and interact with the file picker which sometimes exceeded 2 seconds,
depending on the speed of the machine running the tests.
Converting these tests to use an onlinetext submission and drop the JS
requirement means that they are much less susceptible to runtime issues,
and not susceptible to those caused by JS at all.
If a statically accelerated cache returns an empty array then the value
was still fetched from the non-static cache store.
The check of the `$result` should be strictly checked against `false`,
which is the value used if no value was found.
When creating a course, a manual enrolment instance is added by default. The instance settings should inherit the values of those
for the manual enrolment plugin and properly calculate its extra settings. The 'expirynotify' setting wasn't inherited correctly
in case it had 'Enroller + Enrolled' value.
A functional test was added to test the behaviour of settings inheritance.
For backpack connection using OBv2.0, email and password can't be
blank.
This patch adds some extra checks to validate this and displays an
error to the users before trying to connect to the backpack.
Besides, the error displayed when any error is returned by the
backpack (like invalid credentials), has also been improved, to
make it clearer for the users.
The missing version bump caused cache configuration to not be updated,
and the static acceleration cache size was therefore not updated. The
result here was that the static acceleration cache was constantly
emptied leading to an increased page load time.
During request lifecycle ensure that column, filter and condition
persistents are only loaded a single time to prevent additional
database reads.
Provide invalidation method, used by the report helpers, to ensure
that the persistents are re-loaded appropriately.
This is a backport of MDL-76901.
Co-authored-by: Marina Glancy <marina@moodle.com>
Only call user_update_user when the relevant user data has changed,
preventing unnecessary user_updated events. This also removes the
line setting timemodified on the user since user_update_user already
handles this.
When receiving data from the LTI launch, or service call, only update
the user record when we know something has changed. This prevents the
creation of many \core\event\user_updated events.
This isn't required and generates excess events. The only thing update
does, other than update the user fields, is to update the picture, but
in this case, that's unset in membership-based auths anyway, so it's
entirely safe to remove this.
This is as regression of MDL-72413, when description was moved to a
standard module API.
In some cases, when description has only images, it's was not
displayed.
This is a regression when the activity pages were redessigned in Moodle
4.0. The default introduction should be displayed when the activity
description is empty.
This commit does few things:
* Unify data generators usage to role short name.
* Replace remaining manual steps to use the new data generator.
* Also replaced other manual steps to set config to use data generators.
* Tidy up of some tests, aligning pipes and splitting one line steps into multiple lines.
* Fixes tests to have one Given/When/Then per scenario.
If a plugin attempts to do something that would lock coursemodinfo cache
during install (such as creating a course module), this currently fails
as check_lock_state is not implemented in cache_disabled. Adding the
cache_loader_with_locking interface ensures that all lock methods are
implemented.
If the content in Atto is wrapped by an element with only a background color, without text color,
the accessibility checker will use the parent text-color as the foreground color, which is owned by form-control,
it becomes a problem if the wrapped element background using #34274f and the parent text-color is #495057 then
the low contrast as a result.
To avoid such a situation, the patch will only calculate color contrast if only the element has text,
so it will give results per element if the accessibility checker is unsatisfied.
If the content in Tiny is wrapped by an element with only a background color, without text color,
the accessibility checker will use the parent text-color as the foreground color, which is owned by form-control,
it becomes a problem if the wrapped element background using #34274f and the parent text-color is #495057 then
the low contrast as a result.
To avoid such a situation, the patch will only calculate color contrast if only the element has text,
so it will give results per element if the accessibility checker is unsatisfied.
The patch also changes the selected element from 'body > *' to 'body *',
so it will return all elements (parents and children) in the content instead of parents only.
And minor modifications on the warning_content.mustache to fix the numbering format.
This commit makes the following improvements to mod_imscp tests:
* Removes unnecessary @javascript and @_file_upload tags from non-JS tests.
* Removes user/enrol data generation from tests that can be performed as admin.
* Removes "I log out" and other unnecessary steps.
In this commit, the following improvements were made to the mod_lti Behat tests:
* Replaced manual steps with data generators to set completion.
* Eliminated unnecessary user and course enrolments data generation as some tests can be performed as an admin.
* Removed the @javascript tag from non-JS tests.
* Updated the LTI data generator to generate an internal Moodle URL in the toolurl field, enabling the use of XML files.
This feature had lots of small issues and it made sense to fix it whilst
investigating a query:
* most of the steps do not require JavaScript
* it uses the UI to set an admin setting, for every scenario:
** only 3-4 of the scenarios actually test that setting
** it is very slow to do it his way when we have a generator step we can use
* we create two assignments in the Background, but each test only uses one of them
* we create the assignments in the Background with a generator, but
update them to modify various settings in each Scenario using the UI
when we should just create one assignment for each test and set it up
correctly for that Scenario
The feature added in 4.1 to lock the modinfo cache does not work when
using Redis, because:
* The API to acquire a cache lock is confusing, and the code did not
check that it successfully acquired a lock before going on to build
the cache anyway.
* Unlike the other types of cache lock, the Redis store did not retry
the lock for a timeout period before giving up and failing.
This change fixes both points.
It is perfectly legitimate to create and/or use a method named `define`
in JS outside of RequireJS.
Unfortunately our requirejs.php wrapper is dumb and does not understand
this.
In the long term we need to stop doing this at all. We really should be
able to already, but every time I try to something prevents it.
In the interim, this change adds a secondary check to see if there is an
existing define which _does_ have the right name in it already.
Restoring multiple quizzes from a pre-4.0 backup was broken when
the quizzes shared a random question. This is because after the
first quiz created a set reference in place of the random question,
it deleted the question record so it was not there for the second
quiz to use. This change tracks the IDs of random questions so
they can be deleted at the end.
Several version checks were incorrectly using
restore_controller::info::moodle_release instead of moodle_version as a
version number. This replaces all of those checks with a common pair of
methods to make the checks clearer and more maintainable.
The previous method of hardcoded filepaths, specifically for events
belonging to core, meant that any events belongs to core subsystems
were omitted (core_customfield, core_h5p, core_payment, etc).
Previously, a set of calculated quiz statistics would only 'last' for
15 minutes. Then they would be considered invalid and not used.
Now, computed statistics are kept indefinitely. Instead, when a new
batch of values are computed for a particular set of settings, older numbers
for the same settings are deleted first. Therefore,
question_stats_cleanup_task is no more.
Previously, when users viewed the question bank, if the quiz statistics
had not already been calculated, we would try to compute them there an then.
This could be very, very slow, leading to session lock problems.
Now, we never try to compute the statistics on the fly. Instead, we rely
on the existing \quiz_statistics\task\recalculate scheduled task to do it.
There is a new method on the column class, for the column to declare any
statistics it requires. The question then efficiently loads all those
statistics in one go, and makes them available as the columns are
rendererd, or do any subsequent processing.
According to Boostrap Popovers documentation for popovers triggered
on focus:
"For proper cross-browser and cross-platform behavior, you must use the
<a> tag, not the <button> tag, and you also must include a tabindex
attribute."
The behat step "I draw on the pdf" creates the exact same line every
time it is called. This can cause issues in a situation like the following:
- Student uploads PDF
- Teacher annotates page 1
- Student edits submission, adding another PDF
- Teacher annotates page 1 again
- When the student looks at their annotated PDF it appears the same as
before they added the second PDF (i.e., they don't see extra pages for
the second PDF)
Exactly why this happens isn't clear, and in practice this probably never
happens because the chances of drawing the exact same line twice are almost
0. However, when testing the functionality added in MDL-45580 it was causing
issues.
When requesting the readonly version of pages (which contain
teacher annotations), they should always be available - the
PHP side even throws an exception when they're not. This
means we don't need to worry about polling document converters
from the JS side and can just return the pages immediately.
MDL-45580 introduced the readonlypages filearea, and when loading
page images for an attempt, the code would check if the pages existed
, creating them if not. The code inside this block also contained
a guard clause for the case where no readonly pages existed - which
is a situation that should not happen. Whenever readonly pages are
requested, they should exist.
MDL-66626 introduced a situation where page counts not matching would
also retrigger page generation. However this led to a situation where
the guard clause could be entered when requesting readonly pages.
This patch refactors the guard clause, and improves the logic to
regenerate pages.
This test apparently fails sporadically on Oracle, without obvious
causes. The failure however was hard to interpret, and the test
itself made a lot of assumptions about the system re. naming of
categories/courses. This could be prone to errors, so improve that.
Recent additions to timezones from the IANA TZDB are not necessarily
reflected in those used by the intl extension and/or ICU zones:
* America/Ciudad_Juarez
* America/Nuuk
* Europe/Kyiv
* Pacific/Kanton
Create mapping to allow these zones to be used without errors.
The apiBase in .well-known/badgeconnect.json was ignored and it was
causing some failures when connecting or sending badges to an
external backpack.
For OBv2.1, it has been changed to always use the apiBase defined
in the badgeconnect.json backpack provider.
Backport of MDL-76722.
Co-authored by: Andrew Lyons <andrew@nicols.co.uk>
The 'enable' field doesn't exist, and this is causing some failures
with MariaDB (and probably with MySQL too).
If the enrolment instance (the 'published resource') has been upgraded
from LTI 1.1/2.0 to LTI 1.3 (i.e. a new instance was not created),
prevent legacy launches which may occur from old resource links. Only
LTI Advantage launches should be permitted through the method.
If the enrolment method is updated from an LTI 1.1/2.0 tool to an LTI
1.3 tool, it may have associated enrol_lti_users records not having
ltideploymentid values. These are legacy users and must not be returned
by the repository, which deals only with LTI 1.3 LTI users.
Fixes an error in the parsing of response headers containing multiple
HTTP responses in the raw response. Curl already handles this, so let
it do the work.
Random failures after manually adding block instances (specifically
on slow/Oracle systems) can be entirely avoided by using the block
test generator for scenarios that are not specifically concerned with
manually adding blocks.
Although the screenshots in the failures for some of the scenarios in
filter/displayh5p/tests/behat/h5p_filter.feature, like "Render a local
H5P file as teacher" were displaying the expected result, there were
some javascript errors (probably due to behat is quicker and the
iframes were not always ready).
I've added one extra step before accessing the iframe to give more
time to the H5P player to load and confirm the page is displayed
properly.
* The object returned by update_question is alwasy a new clone
and the $question passed in will not be modified.
* The returned object has the fields like questionbankentryid and
the ones related to versionning, so it is more like the data
returned by question_bank::load_question_data.
The used the exist in Moodle up to 3.11, but then was removed with
insufficient thought in 4.0 (because we had grander long-term plans
which still have not happened). Until those plans happen, this
commit adds the simple link back on the preview screen.
When the two restore forms for searching courses and categories were
converted to core templates in eb9935c9 they lost the named submit
button, which broke searching.
When an editor is renderer initially invisible to the browser, e.g.
the forum "Add discussion" form, it has a `clientHeight` value of
zero. We can approximate an alternative value based on the number
of rows in the textarea.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
It's possible to have some Moodle components soft linked instead
of being real directories within codebase (within dirroot).
For example, Composer's "vendor" directory can be soft linked
(from elsewhere), or also plugins can be installed using soft
links.
In those cases, Moodle calculates the $SCRIPT global as null. And,
then, string operations on it are emitting a PHP deprecation message
with PHP 8.1 and up.
This fix just ensures that the behaviour is the same than before
PHP 8.1, aka: ltrim(null) = '' (empty string), without any PHP warning.
The icon's iconclass context data adds additional CSS class(es) to
calendar event icons to better control how the event icon is displayed.
e.g. without filtering for activity events that don't hae monologo
versions of their icons.
Ensure the same heading tags are available as those defined in the
editor block formats configuration (c51b7e2c).
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
From Selenium 4.8.0, support for non-w3c browser control has ended.
We only use W3C browser control these days, and this was missed as part
of the move to W3C. All browser options must be vendor-prefixed.
In some cases, $CFG->lang might not be set, and this is causing a
Notice to be displayed when, for instance, database connection fails.
This patch should fix this case.
- Only resize if the H5P EmbedCommunicator is defined (otherwise, it was causing a
JS error)
- An unnecessary image has been removed from the greeting-card.h5p fixture package.
That way, the text will always be displayed (even if the iframe is still not
resized). Instead of replacing the original greeting-card-887.h5p file, I've
renamed it to greeting-card.h5p, to remove these ugly and unnecessary numbers
at the end of the file name).
We should be proactive in ensuring that the environment is clean when
running a task. We already ensure that we have a clean renderer and
other parts of the output chain, but we were not setting a clean user.
This change adds a call to setup the cron user before each task is
actually executed.
When questions are filtered by tags in the question bank, the qtagids
params are passed in the array format. Though moodle_url handles this,
single_button::export_for_template cannot. Hence changes done in
weblib.php to provide params for export_for_template in the
suitable format.
Thanks Huong. I have added the Behat test you provided in the patch.
The main goal of this issue is to avoid scanners (Dependabot
and friends), reporting about security issues with the current
xmldom 0.6.0 package.
Note that this doesn't affect prod at all, because it's a dev
dependency, hardly exploitable. So it's not a security fix, just
a security_benefit, if something.
So here, we are updating from xmldom 0.6.0 to @xmldom/xmldom 0.8.7
(note that the package was renamed in 0.7.0, so it's the very same)
Also, when proceeding with the changes, it was detected that we
are incorrectly declaring @babel/eslint-parser as a normal dependency
instead of a development one, so we are also fixing that little detail.
The commands executed to get the changes above applied have been:
- nvm use
- npm install @xmldom/xmldom@^0.8.7 --save-dev
- npm uninstall xmldom
- npm install @babel/eslint-parser@^7.17.0 --save-dev
(we haven't run a complete re-install because we only want to modify
the minimum possible at this stage).
I cherry-picked this branch from master (because the current 401
had some conflicts). In master, quiz has been moved to quiz_settings,
so that's why the behat test start failing. Using the proper name
fixes it.
The YUI Overlay widget encloses the subquestion feedback in a div
which causes a div element to be enclosed in the subquestion span. This
leads to an accessibility issue in terms of HTML parsing as inline
elements (span) should not contain block elements (div)
The YUI Overlay widget is also not accessible as it does not really hide
the overlay contents via aria-hidden when the overlay is not being
shown. It's better if we stop using this and use Bootstrap's
popover component which is more accessible by default.
This patch also removes module.js for the qtype_multianswer plugin as
it only contains codes related to rendering the feedback contents in the
YUI overlay widget which is no longer necessary.
This adds "core_question > updated question" as an entity for `the
following "X" exist` and calls the existing update_question() generator
which will create a new question version with the supplied data.
Use native ANSI SQL syntax for numeric comparisons where possible,
define filter API for the case where filters must re-use the given
field SQL while ensuring uniqueness of any field parameters.
Currently only necessary in the category filter type.
The `filename` field was only used by each to determine whether the
file was itself a directory, and it's presence meant that aggregation
of each column wasn't working properly.
AMOS BEGIN
CPY [type_contentbank,core_plugin],[type_contenttype,core_plugin]
CPY [type_contentbank_plural,core_plugin],[type_contenttype_plural,core_plugin]
AMOS END
MDL-76499 revealed a few problems with resource generators:
1. We were not covering with unit tests the upload of files from disk
(and here it's where the problem was).
2. There was a little of confusion between disk paths (only needed
to upload files) and file_area paths (the generator only creates
or uploads files to the root directory of the file area.
3. It was possible to request the upload of a file to the generator
without that file effectively existing.
This commit fixes those points and covers 99% of the generator code.
After the user creation, the system must call an update function to update profile_fields_*.
We also provided two functions into user/profile/lib.php to get available from other areas.
We added PHP unit testing for new public functions and
the Behat tests for custom profile fields with locked and unlocked statuses.
Co-authored-by: Matt Porritt <matt.porritt@moodle.com>
Update oauth2 to allow mapping of provider attributes against
user profile fields. Fields can also be locked to prevent
user changes.
Co-Authored-By: Michael Milette <michael.milette@tngconsulting.ca>
When rendering content items, check whether the plugin has monologo
icons. If so, add a 'nofilter' class so the plugin icon can be
rendered as is and without the CSS filter.
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the timeline block.
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the recently accessed items block.
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the context header on the activity page.
Add the `.nofilter` class for activity icons when the icon URL's
`filtericon` parameter is not set, so they get rendered as they are on
the course homepage.
* Apply the filter CSS property only to activity icons
that don't have the ".nofilter" class. This will allow
activities with non-SVG icons to be rendered as they are.
* If a plugin defines a `filtericon` custom data or uses its monologo
version of the icon, a `filtericon` parameter is being added to the
icon's URL. This information can help plugins determine whether to
render the activity icon as is or with CSS filtering.
This is a workaround for an upstream bug which I have not been able to
reproduce outside of Moodle whereby the editor.contentWindow does not
math the editor.iframeElement.contentWindow when it should.
This issue only seems to affect Firefox, and it may even be a bug in
Firefox. It can only be reproduced when using a fresh browser which has
never had a TinyMCE window open.
The step i_enable_plugin cannot be used as bigbluebuttonbn_default_dpa_accepted
setting needs to be enable in order for the BigBlueButton plugin to be enabled.
Ensure that when the user entity is added multiple times to a report,
when there are custom profile fields, each of those gets a unique table
alias per-entity.
Evaluated usage of "Install selected language pack(s)" in Behat and
replaced the steps to use generator to install language packs as part
of test setup.
extrainfo is an extra information for the DB driver, e.g. SQL Server,
has additional configuration according to its environment,
which the administrator can specify to alter and override any connection options.
Co-authored-by: LukeCarrier <luke@carrier.im>
This is a backport of MDL-64153.
- Filter searchable courses if set.
- Sites with large groups should now experience better performance.
- Applies and optimises query against a proper date range.
Co-authored-by: Mark Sharp <mark.sharp@solent.ac.uk>
Co-authored-by: Peter Sistrom <petersistrom@catalyst-au.net>
Co-authored-by: Kevin Pham <keevan.pham@gmail.com>
* The file file_remove_editor_orphaned_files should take into account URL that
have been embedded in a tag content instead of an attribute (like src attribute)
* This will fix issue with inserting H5P content in calendar events.
When a test runs just after midnight, and the user time zone is not the
same as the server timezone, and the course is created using a generator
(which runs in server time zone) but the UI presented in the user
timezone, the course start time is still in the future.
We need to create the course a day earlier to ensure that the "This
week" indicator is in the correct day.
- Use span instead of dummy input elements because form elements need a
label
- Sufficient size for target is at least 24px by 24px (Success Criteria
2.5.8)
- set the role of table to none
- moved aria-label from <table> element (that doesn't has role="none")
to the element that has the radiogroup role
- if it's not radiogroup/radio, it is list/listitem
- removed aria-label from the rubric table and used caption instead
* Have the following classes extend qtype_essay_format_renderer_base
as they have been meant to:
- qtype_essay_format_editor_renderer
- qtype_essay_format_noinline_renderer
- qtype_essay_format_plain_renderer
* Add a question_display_options instance variable for
qtype_essay_format_renderer_base so its subclasses can use it to
generate the label for their respective answer fields.
* Add the question number to the answer fields if it's available.
* Improve multiple choice question accessibility:
- Label the multiple choice question groups appropriately by
enclosing them in fieldset tags and applying sr-only legend tags to
label them.
- Apply Bootstrap form-check classes to the radio buttons, so they
are rendered better and become responsive as well. This also helps
avoid the use of the table element for layout purposes when
rendering horizontal multiple choice sub-questions.
* Add an instance variable to question_display_options to store the
identifier associated with the question being rendered.
* This information can be used by question type plugins to improve the
accessibility of the answer fields being rendered by adding the
question identifier to the answer fields' labels.
* Adding the question identifier to the label can be achieved by using
question_display_options::add_question_identifier_to_label().
Co-authored-by: Tim Hunt <t.j.hunt@open.ac.uk>
This is very similar to MDL-77090, but at the time, I missed that this
also needed to be handled. (Question metadata is, I think, only used
by the quiz 'Try another question like this one' feature.)
Although the error in the "I check that I can import recordings into
the Recording activity and then if I delete them" scenario is unrelated
to this patch, this commit needs to be applied too, in order to avoid
behat failures (because the "Import recording links" button is in the
edge of the window).
This is a backport of MDL-74272.
In 4.0, the plugin name was added above their name. Based on the community
feedback and the research done by the UX team, this needs to be removed.
This commit removes the activity name when edit mode is disabled.
This is a backport of MDL-74272.
When clicked, disable the "Edit mode" button just before doing a
redirection. It's been reported that after clicling several times the
button, an inconsistent state between the button and the editing mode is
achieved. The patch mitigates the issue.
* When the server is not reachable (or recordings are not reacheable)
the recording is set to RECORDING_STATUS_DISMISSED and is then
not visible in the list.
* Add a CLI script to solve potential issue with DISMISSED recordings
When we unlock completion criteria and save changes 'viewed' criteria
still should be completed if user has viewed activity before. Seems
that that was broken by recent changes. Fixing here.
For hidden grade items we used to mark students as completed if
they have any grade. But this was not working correctly when we
also set pass grade for activity and completion criteria based
on pass grade. So we will have these completion states
Competion criteria 'Receive grade':
No grade - COMPLETION_INCOMPLETE
Grade visible, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade visible, failed passing grade - COMPLETION_COMPLETE_FAIL
Grade hidden - COMPLETION_COMPLETE
Completion criteris 'Receive passing grade'
No grade - COMPLETION_INCOMPLETE
Grade visible, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade visible, failed passing grade - COMPLETION_COMPLETE_FAIL
Grade hidden, achieved passing grade - COMPLETION_COMPLETE_PASS
Grade hidden, failed passing grade - COMPLETION_COMPLETE_FAIL_HIDDEN
This commit merges the fix and test for the incorrect counting of
words in essay type questions. The issue is due <span> tags not being
counted as inline tags.
Due to missing `AND k.script = 'rss'` condition, the query did not make
use of the existing script-value compound index defined for the table.
So it had to perform the full sequential scan for all rows when
searching for the token. This had serious performance issues on sites
with many users, especially in case on non-existing token / key.
Whenever some plugin is missing from disk but installed, the plugins
page (and the upgrade) shows them as "missing from disk". Still, the
code tries to do things with their directory that, now, is null.
That was silently defaulting to '' in previous php versions, but
php81 emits a deprecated warning. So we have to check for them.
This commit switches to a new custom version of Shifter which sees it
put on a massive diet.
Many of the standard Shifter features are totally unused by Moodle, but
they add dependency spaghetti. Some of those dependencies will start to
cause us issues as they have not been updated for a very long time, are
no longer maintained, and are no longer compatible with anything
resembling a recent version of NodeJS.
This resolves an issue identified in 77083 which identified that GitHub
hashes shouldn't be treated as repeatable.
Whilst GitHub have reverted this change, it's still worth making this
change.
Allow the repository call to the web service method to complete before
re-directing, otherwise the call may not complete and/or races against
the page reload causing random Behat errors.
Since 0188af39 we've cached loaded reports, however there was an
edge case in those report sources that relied on the current user
as part of their own initialization (e.g. checking capabilities).
Co-authored-by: Marina Glancy <marina@moodle.com>
Right now, any E_DEPRECATED, E_USER_DEPRECATED error type leads
to exception in behat runs, because the behat error handled is
not aware of them. See MDL-38041 for the initial implementation.
We don't want that to happen and they must behave like other "low"
error types (notices, warnings...), that will be reported in logs
or output, but won't trigger any exception, so the test can continue.
This commit just adds those 2 "new" error types to the handler,
providing the very same behaviour for them than the rest.
Following MDL-61880 you could turn on "Authenticate token requests via
HTTP headers" but not turn this off again. This change fixes this and
adds a Behat scenario to test toggling this checkbox is saved
correctly.
Replaced 4 occurrences of get_debug_type() by gettype() to keep PHP 7.4 compatibility. Note this
has not been applied to 4.2dev and up because, there, it's safe to use get_debug_type().
When a single template is reset, the string displayed in the modal should
not reference to "all templates" to avoid confusion, as it was shown in the
original prototype for the 4.1 database project.
Previously, it was possible to create drag-drop markers and onto image
questions without any drag items or drop zones. This was non-sensical,
and broke statistics calculations.
So, missing validation added, and random guess score calculation made
robust.
If you delete a file with a hash and then create another file with
the same hash, sometimes on EFS filesystems while trying to create
the new file, it returns true to the file_exists check even though
the file doesn't exist, but then fails other calls.
This change makes Moodle tolerate that behaviour.
The reactive debug panel stops working when a new reactive instance is
created in the fly. This was not detected until the new dragf and drop
files into course uses a second reactive UI component in the same page.
The get_items() and get_page_items() external methods should return
items only when the user has access. Otherwise, empty array for items
will be returned, with the exact error in the warnings parameter.
Text elements must have sufficient colour contrast against the background,
restyling the link element when it is focused is to ensure colour contrast of at least 4.5:1
Changes done to fix access order of attempts that need manual grading.
Changed button text from 'Save and go to next page' to 'Save and show next' to improve UI.
Cache locking fails if the cache store supports multiple identifiers
(in core, the only two which do are cachestore_static and
cachestore_mongodb, so this is unlikely to cause severe problems).
Apply for some of the improvements made for 4.2:
- Use our own moodlehq/mysql-action
- Define the tmpfs size and ensure that binlogs are disabled.
- 401_STABLE doesn't require the php-xmlrpc extension.
The behaviour-specific data was getting corrupted when the regrade
recreated the first step, because $oldstep->get_behaviour_data() was
stripping off the leading '-' characters from the names, and they were
not being added back.
Replace steps that manually add resource instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
Co-authored-by: David Woloszyn <david.woloszyn@moodle.com>
Old-version backups (< 3.11.7, < 4.0.1) lose their course-level format
options when restoring into newer versions after the backup structure
was changed.
Also, course-level format options were not accurately restored against
the appropriate format type. And section-level format options were
redundantly stored at course-level and restored without mapping their
sectionids, thus creating lint.
Replace steps that manually add Book instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
Additionally, performed Behat cleanup and optimisation to affected
files.
Ensure column and filters provided by each source have sufficient
coverage. Re-factor individual entity/helper class tests to test
their own specific implementation only.
Remove now-defunct test fixtures.
The base time allows for the setting of the "current time" for the
purposes of the schedule test against recurrence configuration.
We should ensure the generator method allows this property so that
it can be used when calculating the initial "next send time" of the
schedule upon creation (and avoiding excessive recursion when the
actual current time is used for the calculation).
The Preview questions icon shouldn't be displayed unless the user can
edit the feedback or access to the reports; otherwise, it's causing
confusion (especially when the feedback is not opened).
The TinyMCE menu has a significant issue with the Overflow style,
and the Boost theme heavily uses Overflow for drawer navigation.
Nest the dropdown menu container into the parent editor container makes it work correctly.
Co-authored-by: davewoloszyn <david.woloszyn@moodle.com>
Co-authored-by: xr0master <xr0master@gmail.com>
Some calls to the external_multiple_structure's constructor incorrectly
pass parameters where the value for the $description parameter is not
being passed. This results to invalid values being passed for the
$required parameter.
Calls to `str_ends_with` are polyfilled currently, as the method is
not present in PHP7.4 or earlier. We should avoid uses of it so as
to not trip up compatibility standard checkers.
quiz_settings::create() requires at least 3 DB queries, so the point is
that we can avoid doing that until after we have worked out if we need
to calculate statistics for this quiz.
Also, we order the list of quizzes to consier, to process the ones with
more recent attempts first.
This is because on classic theme the navigation block pushes the content
to the right and once behat changes the grades the 'Save changes' button
is no longer visible.
It happens often that some timezone is renamed, split, added to the
IANAs list of timezones (that, for PHP is kept updated by the
php-timezonedb PECL extension).
When the information coming from the extension changes, all the
PHPUnit jobs in the world start failing (that's when CIs update
their PHP images, when devs update their packages, ...).
So, what we are doing here is to move that test that check for
every single string existing to be run only when PHPUNIT_LONGTEST
is enabled. That way only places running all tests will run that
one. And every other run just will skip it.
This corresponds to point 1 & 2 of the issue, lower impact in general
and, still be able to enable the tests to run.
Changes in fbc2732d made the JS template string helper method
too strict in regards to what it considers a valid JSON object.
Co-authored-by: Mike Churchward <mike@brickfieldlabs.ie>
In PHP 8.1, any implicit conversion of float to int, which leads to a loss in precision, is now deprecated.
To avoid the error warning, the code must explicitly convert a floating value to an integer.
This change makes the regrade progress bar send frequent updates to
the web browser, even when processing within the same grade item, to
avoid timeout problems when there are a large number of users.
Pass correct parameter/type in field constructor (`XMLDB_NOTNULL`)
for consistency. This corrects the definition and preserves the
truthyness of the value that was incorrectly passed previously.
Whenever the page_requirements_manager::js_fix_url()
is called with null url, it must throw an exception and emit 0 warnings.
It's covered by an explicit test:
test_js_fix_url_coding_exception with data set "Provide a null argument"
The json_decode function does not accept a null, which is the
traditional default for get_user_preferences. By passing a default of
am empty string we avoid issues in PHP 8.1.
Added a few functions to remove the toolbar button, menubar and sub-menu items.
One of the implementations is to remove the justify alignment in the toolbar and
the sub-menu items to aid the accessibility aspect of the TinyMCE editor.
With Moodle 4.1 and up, we have stopped to work with strftime(),
because it's deprecated for PHP 8.1 and up and, instead we are
using core_date::strftime() that performs the conversions using
the php-intl extension.
The original strftime() had a lot of OS-specific dependencies,
both about locale names and charsets used to provide the information.
Instead, the php-intl gets rid of all those OS-specific nightmares
and only uses ICU/Unicode locales and UTF-8.
Because of that, the old utf-8 => windows charset => utf-8
conversions aren't needed anymore. Hence, removing them.
By using that assertion the arrays will be sorted before comparison
preventing any Oracle sorting related failures.
Credits for the solution go to Tim Hunt!
We created a list of placeholder selectors in placeholderSelectors option.
The purpose of this list is to indicate the contents that are only shown
in the editor and not to the users, by that way, we can decide to apply or
not to apply rules, styles, etc... to these contents
PHP before version 8.1 automatically converted to int if the function
parameter (or array key) is expected to be int. PHP 8.1 shows notice in
this case
PHP before version 8.1 automatically converted stdClass or 'false' to arrays if
function parameter expects array (for example, "reset").
PHP 8.1 shows notices in these situations
Currently, the unordered list in the course content follows the original style and
is ordered from the top of the content section, which is not part of the description.
That's why the first occurrence of the list is the 2nd level which uses the circle as the marker/list type
instead of the disc. In contrast, the editor always uses the original style.
so we need to reset the CSS of the unordered list in the description to the original
which the disc as the first marker, a circle for the second marker,
and a square for the following levels.
Allow users to see their own private messages even if they don't have
mod/forum:readprivatereplies capability
Add behat test to avoid MDL-67109 issue.
Co-authored-by: Martin Putzlocher <mputzi@users.noreply.github.com>
At the moment, quiz_statistics\task\recalculate gives no useful
information about what it is doing, which makes it hard to investigate
if the task fails. This commit makes it more usefully verbose.
Also, following this change, one instance of this task will not
run for more than one hour at a time.
As part of this commit, I have added a new helper mtrace_exception.
to consistently log exceptions in scheduled tasks. It is sad to
add a new function to moodlelib.php, but that seemed the logical place.
Looking at other tasks, this method is badly needed. Many are just
logging the ->getMessage() which is normaly insufficient for proper
debugging. However, swiching all existing tasks to use the new function
will need to wait for a future MDL.
Since the <ul> and <li> elements for listing the quiz questions and
elements are mainly used for layout purposes, it is better to set the
role of these elements to presentation only.
The aria-label for the <li> element is inappropriate and can also cause
confusion to screen reader users. Better to remove this. Though this is
being used in the confirmation modal so better to just change it to a
data attribute.
Since the <ul> and <li> elements for listing the quiz questions and
elements are mainly used for layout purposes, it is better to set the
role of these elements to presentation only.
Add a default sr-only section heading in order to prevent having an
empty heading for the quiz section which is not good for accessibility.
Plus:
- There's also an existing issue where filters are never applied to
section headings on load. This has been fixed in this commit as well.
- Button role added for the edit section button which enables it to
take advantage of the theme highlighting when it receives focus.
As in MDL-74691, we need either or both of these fields, meaning either
one could be omitted. This just supports that as per the fix made in
MDL-74691.
This covers the following cases:
1. Where only the 'lineitem' service endpoint is provided
2. Where only the 'lineitems' service endpoint is provided.
Existing tests already cover the case where both are provided.
- Markdown is saved to the DB, no conversion to HTML to keep
ability to reedit the content without beaking it.
- Blockquote element is styled that it's distingishable from
normal text.
See also f4fb91ae. PHP8 now supports named arguments in calls to
the `call_user_func_array` method, which can result in differing
behaviour compared to PHP7, e.g. in this case it was throwing an
exception due to an unknown named parameter.
Displaying the course card menu only on hover is bad in terms of
accessibility as it prevents keyboard-only users from accessing the
menu. So it's better to always display them.
Including in this commit:
- Prevent the tour to be displayed if the CSS is disabled by the browser
- Removed redundant tabindex=0 attribute on the target
- Created extra code to re-calculate the suitable position of the tour
- Fixed tour issue in 200% and 400% zoom
- Fixed tour highlight is not correct in 200% and 400%
When the param string contains a left curly bracket as the first character,
the system will assume the string is a JSON string and will be parsed and returned as an object.
But in some cases, the string is not JSON and will return an error if the system parses it.
For example, a user might have used the course name with a left curly bracket as the first character.
Adding a double quote after the left curly bracket to differentiate between string and JSON string,
so it can be safe to parse the string.
The new library version should work without problems with older
php-mongodb extension versions:
- v1.15.0 (paired version, tested).
- v1.14.1 (tested)
So, here, in 401_STABLE, we aren't raising the requirements. We have
done that in master, in order to get php82 support, but not here. For
more details about compatibilities, see:
https://www.mongodb.com/docs/drivers/php/#compatibility
This updates the library from v1.13.1. Fixes some php81 warnings
leading to failed/risky tests.
The new library version should work without problems with older
php-mongodb extension versions:
- v1.15.0 (paired version, tested).
- v1.14.1 (tested)
Webservice doesn't need to set the page URL. Hence,
any function that requires a page URL will raise debugging output.
The patch fixes it by adding a fake URL for the webservice.
The patch also removed assertDebuggingCalled because it is no longer needed.
This will find all data generators that can be used in behat via the
'the following "something" exist:' step, and display them in a select
list on the step definitions page.
When a generator is selected, it will fetch the required fields for that
generator and display them on the page.
jQuery submit events do not trigger the native submit event, and
therefore the TinyMCE submit listener is not called. This means that the
tinymce.triggerSave() function is not called, and the editor content is
not saved.
To work around this, if there is a form for the Node that the editor is
attached to, the jQuery submit event is listened to and the save event
called.
Unfortunately it is not possible to use a global jQuery submit listener
added to the document to save all editors on the page.
In some cases, this is too late because the bubbling process means that
a child node consumer may attempt to consume the data before the
delegated handler is called for the document.
This change reduces the priority of the shipped phpcs configuration to
allow for local overrides.
This is beneficial in several situations:
- when users wish to apply stricter or additional standards
- when the integration team wishes to trial new rules
If the default dashboard contained a block that was missing from disk
then "Exception - Call to a member function instance_copy() on bool"
was shown to users. This change only shows an error with debugging
enabled which now includes the name of the missing block.
Use the full result from download_file_content within the component
installer to ensure that spurious debugging is not emitted during
operation. Handle validation of the returned data consistently.
Under some linux versions, and depending of the configured
locale categories, it's possible to get a current locally
which length > 255 when calling to setlocale(LC_ALL, 0).
Later, if that long locale is tried to be restored, there
is a "setlocale(): Specified locale name is too long" warning
error.
When that happens we need to split the long locale into
individual chunks and set all the (six) locale categories
supported one by one.
Covered with tests, note that, in practice, this only
happens with linux because it supports 12 locale categories
@ OS level. Both BSD (6) and Windows (5) hardly can reach the limit.
No matter of that, the tests have been designed to ensure that
they pass on all OSs, just the new code only will be executed
on linux.
This part of the code in 'question_category_object.php' 'update_category' method was used before Moodle 4.0 version for renaming
the random questions in an updated category. For Moodle 4.1, it is unnecessary as the details of random questions are no more
stored in 'question' table but in 'question_set_references' table. The method call move_question_set_references handles the same.
AMOS BEGIN
MOV [config_recordings_sortorder,mod_bigbluebuttonbn],[config_recordings_asc_sort,mod_bigbluebuttonbn]
MOV [config_recordings_sortorder_description,mod_bigbluebuttonbn],[config_recordings_asc_sort_description,mod_bigbluebuttonbn]
AMOS END
We will not calculate old maker position again and using old data.
This will make sure the position of makers is correct
when the background image is smaller than dropzone.
Remove negative margin from the "clear my choice" anchor.
With the negative margin, when the containing box height is calculated
the anchor's hidden style overflows beyond the boundary and triggers
the overflow:auto to add a scroll bar.
... or anything else with length = 0. This got broken in MDL-71696.
The only way to fix this kind-of involves and API change to
quiz_report_get_significant_questions. However, it is only changing
the external API of this function back to how it was before the 4.0 release,
and the chnages in 4.0 were never documented, nor, I would guess, intended,
since they just broke things.
When the site uses custom user text fields that would show up in a
user list, the filter for firstname or lastname didnt work anymore.
If a filter was used, no result would show up. Users where shown only
when the course reports where used without filters.
This commit adds an additional environment check for the unsupported
PHP 8.1 version to Moodle 3.9.x, 3.11.x and 4.0.x.
It also updates the lang string for unsupported PHP version.
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
It was detected that 'This month' option may cause failures in builds in between months
so using the 'Recent and next 60 days' still fixes the weekend scenario and also the
in between months issue.
In some cases, we get an error message such as:
Wrong parameter count for Redis::zRem()
Within the delete_many function. This function requires at least one
key to be supplied, but if delete_many is called with an empty array,
we will call it with no keys.
This changes a couple of cases, in postgres and oracle where we
were trying to calculate strlen() on null values (that causes a
PHP 8.1 warning).
Also, at the same time, fixing another case in xmldb_field, it
was detected that it had a bug around precision (being set to the
value of type), being used as object property, when it's not, so
it was also fixed by moving the code logic a little bit.
Note that the bug has been there since inception because there
isn't any code in Moodle using that ->precision property. It
was just detected thanks to PHP 8.2, but that's another story. :-)
Verified that with the patch:
- All DBs can be installed (phpunit install)
- Both DDL and DML pass without any ddl/dml warning (in all DBs).
Including in this commit:
- Convert existing Behat scenario to use Data generators
- Convert existing Behat scenario to use Provider
- Add new scenario for Include users setting in General restore page
When the keyword participant filter was used with multiple values
in conjunction with other participants filters, the boolean logic
was effectively:
X AND Y OR Z
When what we actually wanted was:
X AND (Y OR Z)
Set type of the report paging setting to integer, to ensure usage
of it is predictable. Unsupported operated type errors were thrown
on PHP8.0 when it's value contained a string or was empty.
Prior to this change, all the line endings in the imported HTMLPurifier
library were using CRLF (\r\n aka Windows style), but the HTMLPurifier
source and also the downloadable artefacts use LF (\n aka Linux style)
as line endings. This has been the case since
510d190382 when with the commit
"MDL-38672 import HTML Purifier 4.5.0" all line endings were changed
from LF to CRLF. There was no comment in the commit on why this change
was done.
As the original source uses LF, this commit partly reverts
510d190382 and goes back to LF as line
endings.
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
Fixed problems in lateral navigation and grading when
a SCORM has more than three levels
The SCORM module has problems with full screen display,
completion tracking and grading in SCORM.
Also resolves issues MDL-74992, MDL-73249, MDL-75407
This adds a new method to the assignfeedback edit pdf library
to specify user data file areas that will return just the meaningful
annotated feedback pdf.
get_file_areas has been updated for this plugin to return all
file areas related to assignfeedback_editpdf, and should stop
producing orphaned files and records when a course reset is done.
Thanks to @toniginard who provided a base solution for me to work
off.
The method already loaded the validated persistent model data on the
previous line, there's no need to do it again (while also trying to
load unvalidated properties).
The assumption that the settings checkbox always stores boolean values
(e.g. 0/1) isn't correct. The `perfdebug` configuration instead uses
the values 7/15.
Default value of the $flag argument changed in PHP 8.1 from ENT_COMPAT to ENT_QUOTES | ENT_SUBSTITUTE
To ensure consistent behavior across different PHP version the second parameter is now required for the functions:
htmlspecialchars(), htmlentities(), htmlspecialchars_decode(), html_entity_decode() and get_html_translation_table()
{"version":3,"file":"steps.min.js","sources":["../src/steps.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\nimport Ajax from 'core/ajax';\nimport Templates from 'core/templates';\nimport PendingJS from 'core/pending';\n\n/**\n * Enhancements for the step definitions page.\n *\n * @module tool_behat/steps\n * @copyright 2022 Catalyst IT EU\n * @author Mark Johnson <mark.johnson@catalyst-eu.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Call the get_entity_generator web service function\n *\n * Takes the name of an entity generator and returns an object containing a list of the required fields.\n *\n * @param {String} entityType\n * @returns {Promise}\n */\nconst getGeneratorEntities = (entityType) => Ajax.call([{\n methodname: 'tool_behat_get_entity_generator',\n args: {entitytype: entityType}\n}])[0];\n\n/**\n * Render HTML for required fields\n *\n * Takes the entity data returned from getGeneratorEntities and renders the HTML to display the required fields.\n *\n * @param {String} entityData\n * @return {Promise}\n */\nconst getRequiredFieldsContent = (entityData) => {\n if (!entityData.required?.length) {\n return Promise.resolve({\n html: '',\n js: ''\n });\n }\n return Templates.renderForPromise('tool_behat/steprequiredfields', {fields: entityData.required});\n};\n\nexport const init = () => {\n // When an entity is selected in the \"the following exist\" step, fetch and display the required fields.\n document.addEventListener('change', async(e) => {\n const entityElement = e.target.closest('.entities');\n const stepElement = e.target.closest('.stepcontent');\n if (!entityElement || !stepElement) {\n return;\n }\n\n const pendingPromise = new PendingJS('tool_behat/steps:change');\n\n const entityData = await getGeneratorEntities(e.target.value);\n const {html, js} = await getRequiredFieldsContent(entityData);\n\n const stepRequiredFields = stepElement.querySelector('.steprequiredfields');\n if (stepRequiredFields) {\n await Templates.replaceNode(stepRequiredFields, html, js);\n } else {\n await Templates.appendNodeContents(stepElement, html, js);\n }\n pendingPromise.resolve();\n });\n};\n"],"names":["document","addEventListener","async","entityElement","e","target","closest","stepElement","pendingPromise","PendingJS","entityData","entityType","value","Ajax","call","methodname","args","entitytype","html","js","required","_entityData$required","length","Templates","renderForPromise","fields","Promise","resolve","getRequiredFieldsContent","stepRequiredFields","querySelector","replaceNode","appendNodeContents"],"mappings":";;;;;;;;4NA2DoB,KAEhBA,SAASC,iBAAiB,UAAUC,MAAAA,UAC1BC,cAAgBC,EAAEC,OAAOC,QAAQ,aACjCC,YAAcH,EAAEC,OAAOC,QAAQ,oBAChCH,gBAAkBI,yBAIjBC,eAAiB,IAAIC,iBAAU,2BAE/BC,iBAlCgBC,WAkCwBP,EAAEC,OAAOO,MAlClBC,cAAKC,KAAK,CAAC,CACpDC,WAAY,kCACZC,KAAM,CAACC,WAAYN,eACnB,IAH0BA,IAAAA,iBAmChBO,KAACA,KAADC,GAAOA,SAtBaT,CAAAA,0EACzBA,WAAWU,0CAAXC,qBAAqBC,OAMnBC,mBAAUC,iBAAiB,gCAAiC,CAACC,OAAQf,WAAWU,WAL5EM,QAAQC,QAAQ,CACnBT,KAAM,GACNC,GAAI,MAkBiBS,CAAyBlB,YAE5CmB,mBAAqBtB,YAAYuB,cAAc,uBACjDD,yBACMN,mBAAUQ,YAAYF,mBAAoBX,KAAMC,UAEhDI,mBAAUS,mBAAmBzB,YAAaW,KAAMC,IAE1DX,eAAemB"}
@@ -30,7 +30,7 @@ $string['errordataroot'] = '$CFG->behat_dataroot is not set or is invalid.';
$string['errorsetconfig']='$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot need to be set in config.php.';
$string['erroruniqueconfig']='$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot values need to be different than $CFG->dataroot, $CFG->prefix, $CFG->wwwroot, $CFG->phpunit_dataroot and $CFG->phpunit_prefix values.<br/>Or, if $CFG->behat_prefix is the same, $CFG->behat_dbname or $CFG->behat_dbhost need to be different from $CFG->phpunit_dbname and $CFG->phpunit_dbhost and from $CFG->dbname and $CFG->dbhost.';
$string['fieldvalueargument']='Field value arguments';
$string['fieldvalueargument_help']='This argument should be completed by a field value. There are many field types, including simple ones like checkboxes, selects or textareas, or complex ones like date selectors. See the dev documentation <a href="https://docs.moodle.org/dev/Acceptance_testing" target="_blank">Acceptance_testing</a> for details of expected field values.';
$string['fieldvalueargument_help']='This argument should be completed by a field value. There are many field types, including simple ones like checkboxes, selects or textareas, or complex ones like date selectors. See the dev documentation <a href="https://moodledev.io/general/development/tools/behat" target="_blank">Acceptance_testing</a> for details of expected field values.';
$string['giveninfo']='Given. Processes to set up the environment';
$string['infoheading']='Info';
$string['installinfo']='Read {$a} for installation and tests execution info';
Since breadcrumbs provide a navigation, it's a good idea to add a meaningful label such as `aria-label="breadcrumb"` to describe the type of navigation provided in the `<nav>` element, as well as applying an `aria-current="page"` to the last item of the set to indicate that it represents the current page.
For more information, see the [WAI-ARIA Authoring Practices for the breadcrumb pattern](https://www.w3.org/TR/wai-aria-practices/#breadcrumb).
For more information, see the [ARIA Authoring Practices Guide breadcrumb pattern](https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/).
@@ -81,7 +81,7 @@ Create block level buttons—those that span the full width of a parent—by add
## Active state
Buttons will appear pressed (with a darker background, darker border, and inset shadow) when active. **There's no need to add a class to `<button>`s as they use a pseudo-class**. However, you can still force the same active appearance with `.active` (and include the <code>aria-pressed="true"</code> attribute) should you need to replicate the state programmatically.
Buttons will appear pressed when active with a darker background, darker border, and, when shadows are enabled, an inset shadow. **There's no need to add a class to `<button>`s as they use a pseudo-class**. However, you can still force the same active appearance with `.active` (and include the <code>aria-pressed="true"</code> attribute) should you need to replicate the state programmatically.
@@ -101,19 +101,23 @@ Disabled buttons using the `<a>` element behave a bit different:
-`<a>`s don't support the `disabled` attribute, so you must add the `.disabled` class to make it visually appear disabled.
- Some future-friendly styles are included to disable all `pointer-events` on anchor buttons. In browsers which support that property, you won't see the disabled cursor at all.
- Disabled buttons should include the `aria-disabled="true"` attribute to indicate the state of the element to assistive technologies.
- Disabled buttons using `<a>` should include the `aria-disabled="true"` attribute to indicate the state of the element to assistive technologies.
- Disabled buttons using `<a>`*should not* include the `href` attribute.
To cover cases where you have to keep the `href` attribute on a disabled link, the `.disabled` class uses `pointer-events: none` to try to disable the link functionality of `<a>`s. Note that this CSS property is not yet standardized for HTML, but all modern browsers support it. In addition, even in browsers that do support `pointer-events: none`, keyboard navigation remains unaffected, meaning that sighted keyboard users and users of assistive technologies will still be able to activate these links. So to be safe, in addition to `aria-disabled="true"`, also include a `tabindex="-1"` attribute on these links to prevent them from receiving keyboard focus, and use custom JavaScript to disable their functionality altogether.
The `.disabled` class uses `pointer-events: none` to try to disable the link functionality of `<a>`s, but that CSS property is not yet standardized. In addition, even in browsers that do support `pointer-events: none`, keyboard navigation remains unaffected, meaning that sighted keyboard users and users of assistive technologies will still be able to activate these links. So to be safe, add a `tabindex="-1"` attribute on these links (to prevent them from receiving keyboard focus) and use custom JavaScript to disable their functionality.
{{< /callout >}}
## Button plugin
Do more with buttons. Control button states or create groups of buttons for more components like toolbars.
@@ -24,7 +24,7 @@ Lastly, if you're building our JavaScript from source, it [requires `util.js`]({
Carousels don't automatically normalize slide dimensions. As such, you may need to use additional utilities or custom styles to appropriately size content. While carousels support previous/next controls and indicators, they're not explicitly required. Add and customize as you see fit.
**The `.active` class needs to be added to one of the slides** otherwise the carousel will not be visible. Also be sure to set a unique id on the `.carousel` for optional controls, especially if you're using multiple carousels on a single page. Control and indicator elements must have a `data-target` attribute (or `href` for links) that matches the id of the `.carousel` element.
**The `.active` class needs to be added to one of the slides** otherwise the carousel will not be visible. Also be sure to set a unique `id` on the `.carousel` for optional controls, especially if you're using multiple carousels on a single page. Control and indicator elements must have a `data-target` attribute (or `href` for links) that matches the `id` of the `.carousel` element.
### Slides only
@@ -48,7 +48,7 @@ Here's a carousel with slides only. Note the presence of the `.d-block` and `.w-
### With controls
Adding in the previous and next controls:
Adding in the previous and next controls. We recommend using `<button>` elements, but you can also use `<a>` elements with `role="button"`.
Add `.carousel-fade` to your carousel to animate slides with a fade transition instead of a slide.
Add `.carousel-fade` to your carousel to animate slides with a fade transition instead of a slide. Depending on your carousel content (e.g., text only slides), you may want to add `.bg-body` or some custom CSS to the `.carousel-item`s for proper crossfading.
@@ -40,6 +40,29 @@ Generally, we recommend using a button with the `data-target` attribute. While n
</div>
{{< /example >}}
## Horizontal
The collapse plugin also supports horizontal collapsing. Add the `.width` modifier class to transition the `width` instead of `height` and set a `width` on the immediate child element. Feel free to write your own custom Sass, use inline styles, or use our [width utilities]({{< docsref "/utilities/sizing" >}}).
{{< callout info >}}
Please note that while the example below has a `min-height` set to avoid excessive repaints in our docs, this is not explicitly required. **Only the `width` on the child element is required.**
This is some placeholder content for a horizontal collapse. It's hidden by default and shown when triggered.
</div>
</div>
</div>
{{< /example >}}
## Multiple targets
A `<button>` or `<a>` can show and hide multiple elements by referencing them with a JQuery selector in its `href` or `data-target` attribute.
@@ -127,7 +150,7 @@ Be sure to add `aria-expanded` to the control element. This attribute explicitly
If your control element is targeting a single collapsible element – i.e. the `data-target` attribute is pointing to an `id` selector – you should add the `aria-controls` attribute to the control element, containing the `id` of the collapsible element. Modern screen readers and similar assistive technologies make use of this attribute to provide users with additional shortcuts to navigate directly to the collapsible element itself.
Note that Bootstrap's current implementation does not cover the various keyboard interactions described in the [WAI-ARIA Authoring Practices 1.1 accordion pattern](https://www.w3.org/TR/wai-aria-practices-1.1/#accordion) - you will need to include these yourself with custom JavaScript.
Note that Bootstrap's current implementation does not cover the various keyboard interactions described in the [ARIA Authoring Practices Guide accordion pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) - you will need to include these yourself with custom JavaScript.
@@ -16,7 +16,7 @@ If you're building our JavaScript from source, it [requires `util.js`]({{< docsr
## Accessibility
The [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr>](https://www.w3.org/TR/wai-aria/) standard defines an actual [`role="menu"` widget](https://www.w3.org/WAI/PF/aria/roles#menu), but this is specific to application-like menus which trigger actions or functions. <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus.
The [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr>](https://www.w3.org/TR/wai-aria/) standard defines an actual [`role="menu"` widget](https://www.w3.org/TR/wai-aria/#menu), but this is specific to application-like menus which trigger actions or functions. <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus.
Bootstrap's dropdowns, on the other hand, are designed to be generic and applicable to a variety of situations and markup structures. For instance, it is possible to create dropdowns that contain additional inputs and form controls, such as search fields or login forms. For this reason, Bootstrap does not expect (nor automatically add) any of the `role` and `aria-` attributes required for true <abbr title="Accessible Rich Internet Applications">ARIA</abbr> menus. Authors will have to include these more specific attributes themselves.
@@ -32,10 +32,10 @@ Any single `.btn` can be turned into a dropdown toggle with some markup changes.
description: Documentation and examples for Bootstrap's powerful, responsive navigation header, the navbar. Includes support for branding, navigation, and more, including support for our collapse plugin.
description: Documentation and examples for Bootstrap's powerful, responsive navigation header, the navbar. Includes support for branding, navigation, collapse plugin, and more.
group: components
toc: true
---
@@ -50,10 +50,10 @@ Here's an example of all the sub-components included in a responsive light-theme
@@ -243,7 +243,7 @@ If you need responsive nav variations, consider using a series of [flexbox utili
If you're using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the `<ul>`, or wrap a `<nav>` element around the whole navigation. Do not add the role to the `<ul>` itself, as this would prevent it from being announced as an actual list by assistive technologies.
Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example.
Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example.
## Using dropdowns
@@ -257,7 +257,7 @@ Add dropdown menus with a little extra HTML and the [dropdowns JavaScript plugin
@@ -307,20 +307,22 @@ Use the tab JavaScript plugin—include it individually or through the compiled
If you're building our JavaScript from source, it [requires `util.js`]({{< docsref "/getting-started/javascript#util" >}}).
Dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers).
Dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers). As a best practice, we recommend using `<button>` elements for the tabs, as these are controls that trigger a dynamic change, rather than links that navigate to a new page or location.
Note that dynamic tabbed interfaces should <em>not</em> contain dropdown menus, as this causes both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies.
{{< callout danger >}}
Note that the tab JavaScript plugin **does not** support tabbed interfaces that contain dropdown menus, as these cause both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies.
@@ -526,7 +528,7 @@ You can activate a tab or pill navigation without writing any JavaScript by simp
Enable tabbable tabs via JavaScript (each tab needs to be activated individually):
```js
$('#myTab a').on('click',function(event){
$('#myTab button').on('click',function(event){
event.preventDefault()
$(this).tab('show')
})
@@ -535,10 +537,10 @@ $('#myTab a').on('click', function (event) {
You can activate individual tabs in several ways:
```js
$('#myTab a[href="#profile"]').tab('show')// Select tab by name
$('#myTab li:first-child a').tab('show')// Select first tab
$('#myTab li:last-child a').tab('show')// Select last tab
$('#myTab li:nth-child(3) a').tab('show')// Select third tab
$('#myTab button[data-target="#profile"]').tab('show')// Select tab by name
$('#myTab li:first-child button').tab('show')// Select first tab
$('#myTab li:last-child button').tab('show')// Select last tab
$('#myTab li:nth-child(3) button').tab('show')// Select third tab
```
### Fade effect
@@ -562,21 +564,21 @@ To make tabs fade in, add `.fade` to each `.tab-pane`. The first tab pane must a
#### $().tab
Activates a tab element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.
Activates a tab element and content container. Tab should have either a `data-target` or, if using a link, an `href` attribute targeting a container node in the DOM.
@@ -268,7 +272,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` opti
<td>sanitize</td>
<td>boolean</td>
<td>true</td>
<td>Enable or disable the sanitization. If activated <code>'template'</code>, <code>'content'</code> and <code>'title'</code> options will be sanitized.</td>
<td>Enable or disable the sanitization. If activated <code>'template'</code>, <code>'content'</code> and <code>'title'</code> options will be sanitized. See the <a href="{{< docsref "/getting-started/javascript#sanitizer" >}}">sanitizer section in our JavaScript documentation</a>.</td>
@@ -91,7 +91,7 @@ Click the button the below to show as toast (positioning with our utilities in t
### Translucent
Toasts are slightly translucent, too, so they blend over whatever they might appear over. For browsers that support the `backdrop-filter` CSS property, we'll also attempt to blur the elements under a toast.
Toasts are slightly translucent to blend in with what's below them.
@@ -229,13 +229,13 @@ You can also get fancy with flexbox utilities to align toasts horizontally and/o
## Accessibility
Toasts are intended to be small interruptions to your visitors or users, so to help those with screen readers and similar assistive technologies, you should wrap your toasts in an [`aria-live` region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Changes to live regions (such as injecting/updating a toast component) are automatically announced by screen readers without needing to move the user's focus or otherwise interrupt the user. Additionally, include `aria-atomic="true"` to ensure that the entire toast is always announced as a single (atomic) unit, rather than announcing what was changed (which could lead to problems if you only update part of the toast's content, or if displaying the same toast content at a later point in time). If the information needed is important for the process, e.g. for a list of errors in a form, then use the [alert component]({{< docsref "/components/alerts" >}}) instead of toast.
Toasts are intended to be small interruptions to your visitors or users, so to help those with screen readers and similar assistive technologies, you should wrap your toasts in an [`aria-live` region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Changes to live regions (such as injecting/updating a toast component) are automatically announced by screen readers without needing to move the user's focus or otherwise interrupt the user. Additionally, include `aria-atomic="true"` to ensure that the entire toast is always announced as a single (atomic) unit, rather than just announcing what was changed (which could lead to problems if you only update part of the toast's content, or if displaying the same toast content at a later point in time). If the information needed is important for the process, e.g. for a list of errors in a form, then use the [alert component]({{< docsref "/components/alerts" >}}) instead of toast.
Note that the live region needs to be present in the markup *before* the toast is generated or updated. If you dynamically generate both at the same time and inject them into the page, they will generally not be announced by assistive technologies.
You also need to adapt the `role` and `aria-live` level depending on the content. If it's an important message like an error, use `role="alert" aria-live="assertive"`, otherwise use `role="status" aria-live="polite"` attributes.
As the content you're displaying changes, be sure to update the [`delay` timeout](#options) to ensure people have enough time to read the toast.
As the content you're displaying changes, be sure to update the [`delay` timeout](#options) so that users have enough time to read the toast.
@@ -261,6 +261,8 @@ When using `autohide: false`, you must add a close button to allow users to dism
</div>
{{< /example >}}
While technically it's possible to add focusable/actionable controls (such as additional buttons or links) in your toast, you should avoid doing this for autohiding toasts. Even if you give the toast a long [`delay` timeout](#options), keyboard and assistive technology users may find it difficult to reach the toast in time to take action (since toasts don't receive focus when they are displayed). If you absolutely must have further controls, we recommend using a toast with `autohide: false`.
@@ -269,7 +273,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn` and `whiteList` opti
<td>sanitize</td>
<td>boolean</td>
<td>true</td>
<td>Enable or disable the sanitization. If activated <code>'template'</code> and <code>'title'</code> options will be sanitized.</td>
<td>Enable or disable the sanitization. If activated <code>'template'</code> and <code>'title'</code> options will be sanitized. See the <a href="{{< docsref "/getting-started/javascript#sanitizer" >}}">sanitizer section in our JavaScript documentation</a>.</td>
@@ -53,7 +53,7 @@ Align images with the [helper float classes]({{< docsref "/utilities/float" >}})
If you are using the `<picture>` element to specify multiple `<source>` elements for a specific `<img>`, make sure to add the `.img-*` classes to the `<img>` and not to the `<picture>` tag.
"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"!default;
```
Note that because the font stack includes emoji fonts, many common symbol/dingbat unicode characters will be rendered as multi-colored pictographs. Their appearance will vary, depending on the style used in the browser/platform's native emoji font, and they won't be affected by any CSS `color` styles.
Note that because the font stack includes emoji fonts, many common symbol/dingbat Unicode characters will be rendered as multi-colored pictographs. Their appearance will vary, depending on the style used in the browser/platform's native emoji font, and they won't be affected by any CSS `color` styles.
This `font-family` is applied to the `<body>` and automatically inherited globally throughout Bootstrap. To switch the global `font-family`, update `$font-family-base` and recompile Bootstrap.
@@ -201,7 +201,7 @@ Use text utilities as needed to change the alignment of your blockquote.
{{< example >}}
<blockquote class="blockquote text-center">
<p class="mb-0">>A well-known quote, contained in a blockquote element.</p>
<p class="mb-0">A well-known quote, contained in a blockquote element.</p>
<footer class="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
</blockquote>
{{< /example >}}
@@ -283,4 +283,4 @@ Align terms and descriptions horizontally by using our grid system's predefined
As of v4.3.0, Bootstrap ships with the option to enable responsive font sizes, allowing text to scale more naturally across device and viewport sizes. <abbr title="Responsive font sizes">RFS</abbr> can be enabled by changing the `$enable-responsive-font-sizes` Sass variable to `true` and recompiling Bootstrap.
To support <abbr title="Responsive font sizes">RFS</abbr>, we use a Sass mixin to replace our normal `font-size` properties. Responsive font sizes will be compiled into `calc()` functions with a mix of `rem` and viewport units to enable the responsive scaling behavior. More about <abbr title="Responsive font sizes">RFS</abbr> and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs/tree/v8.0.4).
To support <abbr title="Responsive font sizes">RFS</abbr>, we use a Sass mixin to replace our normal `font-size` properties. Responsive font sizes will be compiled into `calc()` functions with a mix of `rem` and viewport units to enable the responsive scaling behavior. More about <abbr title="Responsive font sizes">RFS</abbr> and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs/tree/v8.1.0).
Some activities allow icons to be customised. This can be done by implementing callback XXX_get_coursemodule_info() returning instance of object e.g. mod/lti/lib.php
{{< php >}}
$info = new cached_cm_info();
$info->iconurl = new moodle_url('https://moodle.org/theme/moodleorg/pix/moodle_logo_small.svg');
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.