Math/modules/ext.math.mathjax.enabler.js

242 lines
7.1 KiB
JavaScript

/**
* From https://en.wikipedia.org/wiki/User:Nageh/mathJax.js
*/
/*global mathJax:true, MathJax:true */
( function ( mw, $ ) {
'use strict';
if( ! mw.user.options.get( 'mathJax' ) ) {
return true;
}
if ( typeof mathJax === 'undefined' ) {
window.mathJax = {};
}
mathJax.version = '0.2';
mathJax.loaded = false;
mathJax.locale = mw.config.get( 'wgUserLanguage' );
// See http://docs.mathjax.org/en/latest/options/index.html
mathJax.config = $.extend( true, {
root: mw.config.get( 'wgExtensionAssetsPath' ) + '/Math/modules/MathJax/unpacked',
'v1.0-compatible': false,
menuSettings: {
zoom: 'Click'
},
'HTML-CSS': {
imageFont: null,
mtextFontInherit: true
},
MathMenu: {
showLocale: false
},
jax: ['input/TeX','input/MathML','output/NativeMML','output/HTML-CSS']
}, mathJax.config );
/**
* @param {string} relative path to a MathJax file
* @return {string} MediaWiki module containing the file
*/
mathJax.getModuleNameFromFile = function ( file ) {
var regexp, module;
// These modules are loaded at startup and thus don't need to be specified:
// - ext.math.mathjax.mathjax in mathJax.Load
// - ext.math.mathjax.localization in mathJax.Init
// - ext.math.mathjax.jax.config in MathJax.Hub.Startup.Jax
// - ext.math.mathjax.extensions in MathJax.Hub.Startup.Extensions
//
module = 'ext.math.mathjax.';
regexp = file.match( /(.*)\/jax\.js/ );
if ( regexp ) {
// These are jax.js files of input, element or output modules:
// - ext.math.mathjax.jax.input.MathML
// - ext.math.mathjax.jax.input.TeX
// - ext.math.mathjax.jax.output.HTML-CSS
// - ext.math.mathjax.jax.output.NativeMML
// - ext.math.mathjax.jax.output.HTML-CSS
// - ext.math.mathjax.jax.output.SVG
return module + regexp[1].replace( /\//g, '.' );
}
if ( file.match( /jax\/element\/mml\/optable/ ) ) {
return module + 'jax.element.mml.optable';
}
regexp = file.match( /jax\/output\/(HTML-CSS|SVG)/ );
if ( regexp ) {
module += 'jax.output.' + regexp[1] + '.';
if ( file.match( /autoload/ ) ) {
return module + 'autoload';
}
if ( file.match( /fonts\/TeX\/fontdata/ ) ) {
return module + 'fonts.TeX.fontdata';
}
if ( file.match( /fonts\/TeX\/.*\/.*\/Main\.js/ ) ) {
return module + 'fonts.TeX.MainJS';
}
if ( file.match( /fonts\/TeX\/Main/ ) ) {
return module + 'fonts.TeX.Main';
}
if ( file.match( /fonts\/TeX\/AMS/ ) ) {
return module + 'fonts.TeX.AMS';
}
if ( file.match( /fonts\/TeX/ ) ) {
return module + 'fonts.TeX.Extra';
}
}
mw.log( 'MathJax resource not handled by MediaWiki: ' + file );
return null;
};
/**
* Configure MathJax, preload some files and replace MathJax's resource loader
* by our own resource loader.
*/
mathJax.Init = function () {
// Configure MathJax
MathJax.Hub.Config( mathJax.config );
MathJax.OutputJax.fontDir = mw.config.get( 'wgExtensionAssetsPath' ) + '/Math/modules/MathJax/fonts';
// Redefine MathJax.Hub.Startup.Jax
MathJax.Hub.Startup.Jax = function () {
var config, jax, i, k, name, queue, callback;
// Save the order of the output jax since they are loading asynchronously
config = MathJax.Hub.config;
jax = MathJax.Hub.outputJax;
for ( i = 0, k = 0; i < config.jax.length; i++ ) {
name = config.jax[i].substr( 7 );
if ( config.jax[i].substr( 0,7 ) === 'output/' && jax.order[name] === null ) {
jax.order[name] = k;
k++;
}
}
queue = MathJax.Callback.Queue();
callback = MathJax.Callback( {} );
return queue.Push(
['Post', MathJax.Hub.Startup.signal, 'Begin Jax'],
['using', mw.loader, 'ext.math.mathjax.jax.config', callback],
callback,
['Post', MathJax.Hub.Startup.signal, 'End Jax']
);
};
// Redefine MathJax.Hub.Startup.Extensions
MathJax.Hub.Startup.Extensions = function () {
var queue, callback;
queue = MathJax.Callback.Queue();
callback = MathJax.Callback( {} );
return queue.Push(
['Post', MathJax.Hub.Startup.signal, 'Begin Extensions'],
['using', mw.loader, 'ext.math.mathjax.extensions', callback],
callback,
['Post', MathJax.Hub.Startup.signal, 'End Extensions']
);
};
// Redefine MathJax.Ajax.Load
MathJax.Ajax.MathJaxLoad = MathJax.Ajax.Load;
MathJax.Ajax.Load = function ( file, callback ) {
var type, i, module;
callback = MathJax.Callback( callback );
if ( file instanceof Object ) {
for ( i in file ) {
if ( file.hasOwnProperty( i ) ) {
type = i.toUpperCase();
file = file[i];
}
}
} else {
type = file.split( /\./ ).pop().toUpperCase();
}
file = MathJax.Ajax.fileURL( file );
if ( MathJax.Ajax.loading[file] ) {
MathJax.Ajax.addHook( file, callback );
} else {
if ( MathJax.Ajax.loader[type] ) {
module = mathJax.getModuleNameFromFile( file.substring( MathJax.Hub.config.root.length + 1 ) );
if ( module ) {
// Use MediaWiki's resource loader.
MathJax.Ajax.loading[file] = {
callback: callback,
timeout: -1,
status: this.STATUS.OK,
script: null
};
// Add this to the structure above after it is created to prevent
// recursion when loading the initial localization file (before
// loading message is available)
MathJax.Ajax.loading[file].message = MathJax.Message.File( file );
mw.loader.load( module );
} else {
// Fallback to MathJax's own loader.
callback = MathJax.Ajax.MathJaxLoad( file, callback );
}
} else {
throw new Error( 'Can\'t load files of type ' + type );
}
}
return callback;
};
// Register the final action after MathJax processing: hide
// SVG/PNG preview if thas was not done before and show MathJax's output.
MathJax.Hub.Startup.signal.MessageHook( 'End', function () {
mw.loader.load( 'ext.math.mathml' );
} );
// Set MathJax's locale and load the localization data.
MathJax.Localization.resetLocale( mathJax.locale );
mathJax.locale = MathJax.Localization.locale;
MathJax.Hub.config.menuSettings.locale = mathJax.locale;
mw.loader.using( 'ext.math.mathjax.localization', function () {
MathJax.Hub.Configured();
} );
};
/**
* Renders all Math TeX inside the given elements.
* @param {function} callback to be executed after text elements have rendered [optional]
*/
$.fn.renderTex = function () {
mathJax.LoadAndRender( this );
return this;
};
mw.log.deprecate( $.fn, 'renderTex', $.fn.renderTex,
'Use the mw.hook wikipage.content instead' );
mathJax.LoadAndRender = function ( $content ) {
// create the global MathJax variable to hook into MathJax startup
if( typeof MathJax === 'undefined' ) {
window.MathJax = {
delayStartupUntil: 'configured',
skipStartupTypeset: true,
AuthorInit: mathJax.Init
};
}
function render() {
var elem = $content.toArray();
MathJax.Hub.Queue( ['Typeset', MathJax.Hub, elem] );
}
if ( MathJax.isReady ) {
render();
} else {
mw.loader.using( 'ext.math.mathjax.mathjax', function () {
MathJax.Hub.Startup.signal.MessageHook( 'End', render );
} );
}
};
mw.hook( 'wikipage.content' ).add( mathJax.LoadAndRender );
}( mediaWiki, jQuery ) );