MDL-75486 filter_mathmaxloader: Upgraded MathJax cdn to version 3.2.2

This commit is contained in:
Stevani Andolo 2025-03-03 13:45:54 +08:00
parent 5670447ece
commit 70b5993e2a
12 changed files with 56 additions and 101 deletions

View File

@ -1,11 +1,3 @@
define("filter_mathjaxloader/loader",["exports","core_filters/events"],(function(_exports,_events){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.typeset=_exports.contentUpdated=_exports.configure=void 0;
/**
* Mathjax JS Loader.
*
* @module filter_mathjaxloader/loader
* @copyright 2014 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
let lang="",configured=!1;_exports.configure=params=>{const script=document.createElement("script");script.type="text/x-mathjax-config",script[window.opera?"innerHTML":"text"]=params.mathjaxconfig,document.getElementsByTagName("head")[0].appendChild(script),lang=params.lang,document.addEventListener(_events.eventTypes.filterContentUpdated,contentUpdated)};const setLocale=()=>{configured||void 0!==window.MathJax&&(window.MathJax.Hub.Queue((function(){window.MathJax.Localization.setLocale(lang)})),window.MathJax.Hub.Configured(),configured=!0)},typesetNode=node=>{node instanceof HTMLElement&&(window.MathJax.Hub.Queue(["Typeset",window.MathJax.Hub,node]),window.MathJax.Hub.Queue([node=>{(0,_events.notifyFilterContentRenderingComplete)([node])},node]))};_exports.typeset=()=>{if(!configured){setLocale();const elements=document.getElementsByClassName("filter_mathjaxloader_equation");for(const element of elements)void 0!==window.MathJax&&typesetNode(element)}};const contentUpdated=event=>{if(void 0===window.MathJax)return;let listOfElementContainMathJax=[],hasMathJax=!1;if(event.detail.nodes.forEach((node=>{if(!(node instanceof HTMLElement))return;const mathjaxElements=node.querySelectorAll(".filter_mathjaxloader_equation");mathjaxElements.length>0&&(hasMathJax=!0),listOfElementContainMathJax.push(mathjaxElements)})),!hasMathJax)return;const processDelay=window.MathJax.Hub.processSectionDelay;window.MathJax.Hub.processSectionDelay=0,window.MathJax.Hub.Config({positionToHash:!1}),setLocale(),listOfElementContainMathJax.forEach((mathjaxElements=>{mathjaxElements.forEach((node=>typesetNode(node)))})),window.MathJax.Hub.processSectionDelay=processDelay};_exports.contentUpdated=contentUpdated}));
define("filter_mathjaxloader/loader",["exports","core_filters/events"],(function(_exports,_events){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.typeset=_exports.contentUpdated=_exports.configure=void 0;_exports.configure=params=>{window.MathJax&&(window.MathJax.config.locale=params.lang),document.addEventListener(_events.eventTypes.filterContentUpdated,contentUpdated)};const typesetNode=node=>{node instanceof HTMLElement&&window.MathJax&&window.MathJax.typesetPromise([node]).then((()=>{(0,_events.notifyFilterContentRenderingComplete)([node])})).catch((e=>{window.console.log(e)}))};_exports.typeset=()=>{const elements=document.getElementsByClassName("filter_mathjaxloader_equation");for(const element of elements)void 0!==window.MathJax&&typesetNode(element)};const contentUpdated=event=>{if(void 0===window.MathJax)return;let listOfElementContainMathJax=[],hasMathJax=!1;event.detail.nodes.forEach((node=>{if(!(node instanceof HTMLElement))return;const mathjaxElements=node.querySelectorAll(".filter_mathjaxloader_equation");mathjaxElements.length>0&&(hasMathJax=!0),listOfElementContainMathJax.push(mathjaxElements)})),hasMathJax&&listOfElementContainMathJax.forEach((mathjaxElements=>{mathjaxElements.forEach((node=>typesetNode(node)))}))};_exports.contentUpdated=contentUpdated}));
//# sourceMappingURL=loader.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -24,22 +24,6 @@ import {
notifyFilterContentRenderingComplete,
} from 'core_filters/events';
/**
* The users current language - this can't be set until MathJax is loaded - so we need to store it.
* @property {string} lang
* @default ''
* @private
*/
let lang = '';
/**
* Used to prevent configuring MathJax twice.
* @property {boolean} configured
* @default false
* @private
*/
let configured = false;
/**
* Called by the filter when it is active on any page.
* This does not load MathJAX yet - it addes the configuration to the head incase it gets loaded later.
@ -48,38 +32,17 @@ let configured = false;
* @param {Object} params List of configuration params containing mathjaxconfig (text) and lang
*/
export const configure = (params) => {
// Add a js configuration object to the head.
// See "https://docs.mathjax.org/en/v2.7-latest/advanced/dynamic.html"
const script = document.createElement("script");
script.type = "text/x-mathjax-config";
script[(window.opera ? "innerHTML" : "text")] = params.mathjaxconfig;
document.getElementsByTagName("head")[0].appendChild(script);
// Save the lang config until MathJax is actually loaded.
lang = params.lang;
if (window.MathJax) {
// Let's still set the locale even if the localization is not yet ported to version 3.2.2
// https://docs.mathjax.org/en/v3.2-latest/upgrading/v2.html#not-yet-ported-to-version-3.
window.MathJax.config.locale = params.lang;
}
// Listen for events triggered when new text is added to a page that needs
// processing by a filter.
document.addEventListener(eventTypes.filterContentUpdated, contentUpdated);
};
/**
* Set the correct language for the MathJax menus. Only do this once.
*
* @private
*/
const setLocale = () => {
if (!configured) {
if (typeof window.MathJax !== "undefined") {
window.MathJax.Hub.Queue(function() {
window.MathJax.Localization.setLocale(lang);
});
window.MathJax.Hub.Configured();
configured = true;
}
}
};
/**
* Add the node to the typeset queue.
*
@ -93,32 +56,25 @@ const typesetNode = (node) => {
return;
}
// MathJax 2.X does not notify when complete. The best we can do, according to their docs, is to queue a callback.
// See https://docs.mathjax.org/en/v2.7-latest/advanced/typeset.html
// Note that the MathJax.Hub.Queue() method will return immediately, regardless of whether the typesetting has taken place
// or not, so you can not assume that the mathematics is visible after you make this call.
// That means that things like the size of the container for the mathematics may not yet reflect the size of the
// typeset mathematics. If you need to perform actions that depend on the mathematics being typeset, you should push those
// actions onto the MathJax.Hub.queue as well.
window.MathJax.Hub.Queue(["Typeset", window.MathJax.Hub, node]);
window.MathJax.Hub.Queue([(node) => {
// The notifyFilterContentRenderingComplete event takes an Array of NodeElements or a NodeList.
// We cannot create a NodeList so we use an HTMLElement[].
notifyFilterContentRenderingComplete([node]);
}, node]);
if (window.MathJax) {
window.MathJax.typesetPromise([node]).then(() => {
notifyFilterContentRenderingComplete([node]);
return;
})
.catch(e => {
window.console.log(e);
});
}
};
/**
* Called by the filter when an equation is found while rendering the page.
*/
export const typeset = () => {
if (!configured) {
setLocale();
const elements = document.getElementsByClassName('filter_mathjaxloader_equation');
for (const element of elements) {
if (typeof window.MathJax !== "undefined") {
typesetNode(element);
}
const elements = document.getElementsByClassName('filter_mathjaxloader_equation');
for (const element of elements) {
if (typeof window.MathJax !== "undefined") {
typesetNode(element);
}
}
};
@ -147,17 +103,12 @@ export const contentUpdated = (event) => {
}
listOfElementContainMathJax.push(mathjaxElements);
});
if (!hasMathJax) {
return;
}
const processDelay = window.MathJax.Hub.processSectionDelay;
// Set the process section delay to 0 when updating the formula.
window.MathJax.Hub.processSectionDelay = 0;
// When content is updated never position to hash, it may cause unexpected document scrolling.
window.MathJax.Hub.Config({positionToHash: false});
setLocale();
listOfElementContainMathJax.forEach((mathjaxElements) => {
mathjaxElements.forEach((node) => typesetNode(node));
});
window.MathJax.Hub.processSectionDelay = processDelay;
};

View File

@ -74,19 +74,21 @@ class text_filter extends \core_filters\text_filter {
if (!$page->requires->should_create_one_time_item_now('filter_mathjaxloader-scripts')) {
return;
}
$url = get_config('filter_mathjaxloader', 'httpsurl');
$lang = $this->map_language_code(current_language());
$url = new url($url, ['delayStartupUntil' => 'configured']);
$url = new url($url);
$page->requires->js($url);
// Let's still get this config even if the value is null due to the setting being set as default.
// For the config we can set based on the needs when we need from:
// https://docs.mathjax.org/en/v3.2-latest/web/configuration.html#web-configuration.
$config = get_config('filter_mathjaxloader', 'mathjaxconfig');
$wwwroot = new url('/');
$config = str_replace('{wwwroot}', $wwwroot->out(true), $config);
$params = ['mathjaxconfig' => $config, 'lang' => $lang];
// Let's still send the config and lang to the loader.
$page->requires->js_call_amd('filter_mathjaxloader/loader', 'configure', [$params]);
}

View File

@ -39,5 +39,17 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
// Automatically generated Moodle v4.5.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2025022700) {
// Set value of "httpsurl" to the latest MathJax cdn version 3.2.2.
set_config('httpsurl', 'https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-mml-chtml.js', 'filter_mathjaxloader');
// Set the "mathjaxconfig" value to empty due to default config has been set by default.
// We can always set new configs from the setting page in site admin.
set_config('mathjaxconfig', '', 'filter_mathjaxloader');
// Main savepoint reached.
upgrade_plugin_savepoint(true, 2025022700, 'filter', 'mathjaxloader');
}
return true;
}

View File

@ -1,7 +1,7 @@
Description of MathJAX library integration in Moodle
====================================================
* Default MathJax version: 2.7.9
* Default MathJax version: 3.2.2
* License: Apache 2.0
* Source: https://www.mathjax.org/
@ -17,10 +17,15 @@ Upgrading the default MathJax version
previous default.
3. Check and eventually update the list of language mappings in filter.php.
Also see the unit test for the language mappings.
4. Add any required configurations from (https://docs.mathjax.org/en/v3.2-latest/web/configuration.html#web-configuration)
to "filter_mathjaxloader/mathjaxconfig" because it has been removed as the required ones have been loaded by default.
For more details about the documentation please check MDL-75486.
Changes
-------
* Updated to the 3.2.2 version. See MDL-75486 for details
* Updated to the 2.7.9 version. See MDL-70317 for details.
* The MathJax 2.7.2 seems to have a possible security issue, the CDN default value have been

View File

@ -33,7 +33,7 @@ if ($ADMIN->fulltree) {
$item = new admin_setting_configtext('filter_mathjaxloader/httpsurl',
new lang_string('httpsurl', 'filter_mathjaxloader'),
new lang_string('httpsurl_help', 'filter_mathjaxloader'),
'https://cdn.jsdelivr.net/npm/mathjax@2.7.9/MathJax.js',
'https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-mml-chtml.js',
PARAM_RAW);
$settings->add($item);
@ -43,19 +43,10 @@ if ($ADMIN->fulltree) {
0);
$settings->add($item);
$default = '
MathJax.Hub.Config({
config: ["Accessible.js", "Safe.js"],
errorSettings: { message: ["!"] },
skipStartupTypeset: true,
messageStyle: "none"
});
';
$item = new admin_setting_configtextarea('filter_mathjaxloader/mathjaxconfig',
new lang_string('mathjaxsettings','filter_mathjaxloader'),
new lang_string('mathjaxsettings_desc', 'filter_mathjaxloader'),
$default);
'');
$settings->add($item);

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025022700;
$plugin->requires = 2024100100; // Requires this Moodle version.
$plugin->component= 'filter_mathjaxloader';

View File

@ -18,7 +18,9 @@ Feature: Equation editor
And I click on "Save equation" "button"
And I click on "Update profile" "button"
And I follow "Profile" in the user menu
Then "\infty" "text" should exist
# MathJax 3.2.2 renders matemathical equation using css classes, so it will not work against the pre-rendered code like "\infty".
# That said, we can instead check the rendered text using the rendered equation or symbol "∞".
Then "" "text" should exist
@javascript
Scenario: Edit an equation using TinyMCE

View File

@ -90,7 +90,7 @@ form.mform fieldset#id_previewareaheader .droppreview {
* So we remove the default margin of Mathjax.
*/
.que.ddimageortext .MathJax_Display,
.que.ddimageortext .MathJax_SVG_Display {
.que.ddimageortext .MathJax_SVG {
margin: 0;
}

View File

@ -64,9 +64,9 @@ Feature: Preview a drag-drop marker question
And the "mathjaxloader" filter applies to "content and headings"
And I am on the "Drag to mathjax equation" "core_question > preview" page logged in as teacher
When I press "Submit and finish"
Then ".markertexts .markertext .MathJax_Display" "css_element" should exist in the ".droparea" "css_element"
Then ".markertexts .markertext .MathJax" "css_element" should exist in the ".droparea" "css_element"
And I press "Start again"
And I press "Fill in correct responses"
And I press "Submit and finish"
And ".filter_mathjaxloader_equation" "css_element" should exist in the ".droparea" "css_element"
And ".markertexts .markertext .MathJax_Display" "css_element" should not exist in the ".droparea" "css_element"
And ".markertexts .markertext .MathJax" "css_element" should not exist in the ".droparea" "css_element"

View File

@ -127,6 +127,6 @@
bottom: -0.2em;
}
.que.ddwtos .MathJax_Display {
.que.ddwtos .MathJax {
margin: 0;
}