Snippets/Load JS and CSS by URL

How to use Snippets
List of Snippets
Load JS and CSS by URL
Language(s): JavaScript
Compatible with: MediaWiki 1.35+ 

Description

edit

Adds support for loading a script or stylesheet from a wiki page in the MediaWiki namespace, based on a URL parameter. This makes showing demonstrations easier as users don't have to enable a gadget or put something in their user common.js.

  Warning: If you add this snippet to a wiki, you should take special care that there are no scripts in the MediaWiki namespace susceptible to XSS attacks.

Code

edit

This version adds two new url parameters withJS and withCSS. You can append them on to the end of the url: ?withCSS=MediaWiki:Foo.css&withJS=MediaWiki:Foo.js

/**
 * @source https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
 * @revision 2020-04-04
 */
mw.loader.using( ['mediawiki.util'], function () {
	var extraCSS = mw.util.getParamValue( 'withCSS' ),
		extraJS = mw.util.getParamValue( 'withJS' );

	if ( extraCSS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.css$/.test( extraCSS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraCSS ) + '&action=raw&ctype=text/css', 'text/css' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );
		}
	}

	if ( extraJS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.js$/.test( extraJS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraJS ) + '&action=raw&ctype=text/javascript' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );
		}
	}
});


With module

edit
/**
 * @source https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
 * @revision 2020-04-04
 */
mw.loader.using( ['mediawiki.util'], function () {
	var extraCSS = mw.util.getParamValue( 'withCSS' ),
		extraJS = mw.util.getParamValue( 'withJS' ),
		extraModule = mw.util.getParamValue( 'withModule' );

	if ( extraCSS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.css$/.test( extraCSS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraCSS ) + '&action=raw&ctype=text/css', 'text/css' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );
		}
	}

	if ( extraJS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.js$/.test( extraJS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraJS ) + '&action=raw&ctype=text/javascript' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );
		}
	}

	if ( extraModule ) {
		if ( /^ext\.gadget\.[^,\|]+$/.test( extraModule ) ) {
			mw.loader.load( extraModule );
		} else {
			mw.notify( 'Only gadget modules are allowed.', { title: 'Invalid withModule value' } );
		}
	}
});

Load multiple files

edit
  Warning: The version of this snippet prior to May 8, 2017 had a security vulnerability in it. If you used an older version of this snippet, please update to the version shown below

This version adds a single url parameter, use but allows multiple files to be separated by a pipe (|). You can then append on to the end of a url: ?use=MediaWiki:Foo.js|MediaWiki:Foo.css|MediaWiki:Bar.js

/**
 * Load CSS and JS files temporarily through URL.
 * &use=File1.css|File2.css|File3.js
 *
 * Required modules: mediawiki.util
 * @source https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL#Load_multiple_files
 * @revision 2023-09-24
 */
mw.loader.using( 'mediawiki.util', function () {
	var files = mw.util.getParamValue( 'use' ), user, FileRE, ExtRE, path;

	if ( !files ) {
		return;
	}

	user = mw.util.escapeRegExp( mw.config.get( 'wgUserName', '' ) );
	FileRE = new RegExp( '^(?:MediaWiki:' + ( user ? '|User:' + user + '/' : '' ) + ')[^&<>=%#]*\\.(js|css)$' );
	ExtRE = new RegExp( '^ext\\.[^,]+$' );
	path = mw.config.get('wgServer')
		+ mw.config.get('wgScript')
		+ '?action=raw&ctype=text/';

	$.each( files.split( '|' ), function(k, v) {
		var f = $.trim( v ), what = FileRE.exec( f ) || ['', ''];
		switch ( what[1] ) {
			case  'js':
				mw.loader.load( path + 'javascript&title=' + encodeURIComponent( f ) );
				break;
			case 'css':
				mw.loader.load( path + 'css&title=' + encodeURIComponent( f ) );
				break;
			default:
				if ( ExtRE.exec( f ) ) {
					mw.loader.load(f);
				}
		}
	});
});