Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* global $, mw, pathoschild */

/*******************
** Scripts on all wikis
*******************/
/**
 * Forces left-to-right layout and editing on RTL wikis.
 * @see https://meta.wikimedia.org/wiki/Force_ltr
 * @update-token [[File:Pathoschild/forceltr.js]]
 */
mw.loader.load('//tools-static.wmflabs.org/meta/scripts/pathoschild.forceltr.js');

/**
 * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.
 * @see https://meta.wikimedia.org/wiki/TemplateScript
 * @update-token [[File:Pathoschild/templatescript.js]]
 */
// <nowiki>
$.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function() {
	/* various specific uses */
	pathoschild.TemplateScript.add(
		[
			// signature on non-home wikis
			{
				name: '✎  talk signature',
				template: '<small>—~~~~</small>',
				position: 'cursor',
				enabled: mw.config.get('wgNamespaceNumber') % 2 == 1 || mw.config.get('wgCanonicalNamespace') == 'Project'
			},
			
			// on watchlist, mark all pages visited (even if the button is hidden)
			{
				name: 'mark all pages visited',
				script: function() {
					$('#mw-watchlist-resetbutton').submit();
				},
				forActions: 'view',
				enabled: mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist'
			}
		]
	);

	/* script maintenance (editing pages) */
	pathoschild.TemplateScript.add(
		[
			{
				name: '☢ update scripts',
				scriptUrl: 'https://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/heuristic-script-update.js&action=raw&ctype=text/javascript',
				script: function(editor) {
					pathoschild.migrateLegacyScripts().applyAll(editor);
				},
				enabled: mw.config.get('wgPageName').endsWith('.js'),
				accessKey: 'u'
			},
			{
				name: '☢ trim trailing space',
				script: function(editor) {
					editor.replace(/[ \t]+$/mg, '');
				},
				enabled: mw.config.get('wgPageName').match(/\.(?:css|js)$/)
			},
			{
				name: '⚙ TemplateScript',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.',
							' * @see https://meta.wikimedia.org/wiki/TemplateScript',
							' * @update-token [[File:Pathoschild/templatescript.js]]',
							' */',
							'mw.loader.load(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js\');'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '⚙ TemplateScript (c)',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.',
							' * @see https://meta.wikimedia.org/wiki/TemplateScript',
							' * @update-token [[File:Pathoschild/templatescript.js]]',
							' */',
							'// <' + 'nowiki>',
							'$.ajax(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js\', { dataType:\'script\', cache:true }).then(function() {',
							'	pathoschild.TemplateScript.add([',
							'		{',
							'			name: \'\',',
							'			script: function(editor) {',
							'				editor',
							'			}',
							'		}',
							'	]);',
							'});',
							'// </' + 'nowiki>'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '⚙ ajax sysop',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * Ajax sysop',
							' * @see https://meta.wikimedia.org/wiki/Ajax_sysop',
							' * @update-token [[File:Pathoschild/ajaxsysop.js]]',
							' */',
							'mw.loader.load(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.ajaxsysop.js\');'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '⚙ ajax transclusion',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * Ajax transclusion table adds dynamic content loading to tables with class="attable".',
							' * @see https://meta.wikimedia.org/wiki/Ajax_transclusion_table',
							' * @update-token [[File:Pathoschild/ajaxtransclusiontable.js]]',
							' */',
							'mw.loader.load(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.ajaxtransclusiontable.js\');'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '⚙ force LTR',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * Forces left-to-right layout and editing on RTL wikis.',
							' * @see https://meta.wikimedia.org/wiki/Force_ltr',
							' * @update-token [[File:Pathoschild/forceltr.js]]',
							' */',
							'mw.loader.load(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.forceltr.js\');'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '⚙ StewardScript',
				script: function(editor) {
					editor
						.replaceSelection([
							'/**',
							' * StewardScript extends the user interface for Wikimedia stewards\' convenience.',
							' * @see https://meta.wikimedia.org/wiki/StewardScript',
							' * @update-token [[File:Pathoschild/stewardscript.js]]',
							' */',
							'mw.loader.load(\'//tools-static.wmflabs.org/meta/scripts/pathoschild.stewardscript.js\');'
						].join('\n'))
						.appendEditSummary('updated scripts');
				}
			},
			{
				name: '✎ updated rmf ',
				script: function(editor) {
					editor
						.replaceSelection([
							'Hi {{subst:PAGENAME}}. I [[Special:Diff/' + prompt('diff rev id?') + '|edited your <tt>common.js</tt>]] to update you to the latest version of [[m:TemplateScript|TemplateScript]]. You were using a much older version called [[m:User:Pathoschild/Scripts/Regex menu framework|regex menu framework]], so you should notice a lot of improvements. A few of the big changes:',
							'{| class="wikitable"',
							'|-',
							'! &nbsp;',
							'! regex menu framework',
							'! TemplateScript',
							'|-',
							'| regex editor',
							'|style="background:#CFC;"| ✓',
							'|style="background:#CFC;"| ✓ an improved regex editor which can save your patterns for later use',
							'|-',
							'| compatibility',
							'|style="background:#FFC;"| unknown',
							'|style="background:#CFC;"| ✓ compatible with all skins and modern browsers',
							'|-',
							'| custom scripts',
							'|style="background:#FFC;"| limited',
							'|style="background:#CFC;"| ✓ much better framework for writing scripts',
							'|-',
							'| supported views',
							'|style="background:#FFC;"| edit',
							'|style="background:#CFC;"| ✓ add templates and scripts for any view (edit, block, protect, etc)',
							'|-',
							'| keyboard shortcuts',
							'|style="background:#FCC;"| ✘',
							'|style="background:#CFC;"| ✓ add keyboard shortcuts for your templates and scripts',
							'|-',
							'| translatable',
							'|style="background:#FCC;"| ✘',
							'|style="background:#CFC;"| ✓ {{subst:#switch:{{subst:CONTENTLANG}}|en|fr|pt=[[m:TemplateScript#Translation|translated into {{subst:#language:{{subst:CONTENTLANG}}|en}}]]!|#default=translatable (but there\'s no {{subst:#language:{{subst:CONTENTLANG}}|en}} translation yet; [[m:TemplateScript#Translation|translators are welcome!]])}}',
							'|}',
							'',
							'I also [[mw:ResourceLoader/Migration guide (users)|updated deprecated functions]] and made your scripts HTTPS-compatible. Let me know if anything breaks. :) <small>—~~~~<small>'
						].join('\n'))
						.appendEditSummary('Updated scripts');
				}
			},
			{
				name: '✎ updated scripts',
				script: function(editor) {
					editor
						.append('Hi {{subst:PAGENAME}}. I [[Special:Diff/' + prompt('diff rev id?') + '|edited your <tt>common.js</tt>]] to update you to the latest version of [[m:TemplateScript|TemplateScript]], [[mw:ResourceLoader/Migration guide (users)|update deprecated functions]] and make your scripts HTTPS-compatible. I also moved it to <tt>common.js</tt> so it works in all skins. Let me know if anything breaks. :) <small>—~~~~</small>')
						.appendEditSummary('Updated scripts');
				}
			}
		],
		{ category: 'script maintenance' }
	);

	/* script maintenance (moving pages) */
	pathoschild.TemplateScript.add({
		name: 'move to common.js',
		category: 'script maintenance',
		forActions: 'move',
		enabled: mw.config.get('wgTitle').match(/\.(?:css|js)$/),
		script: function(editor) {
			// parse details
			var extension = mw.config.get('wgTitle').match(/(?:css|js)$/).toString();

			// apply changes
			$('#wpNewTitleMain').val(function(i, val) { return val.replace(/[a-z]+\.(css|js)$/, 'common.$1'); });
			$('#wpReason').val('updated ' + (extension === 'css' ? 'styles' : 'scripts'));
			$('#wpLeaveRedirect').prop('checked', false);
		}
	});

	/* talk pages on Meta */
	pathoschild.TemplateScript.add(
		[
			{
				name: '✎ {{answered}}',
				script: function(editor) {
					var summary = prompt('Brief summary of the discussion result:');
					editor
						.replace(/^(=+)\s+(.+?)\s+(\1).+/, '$1$2$1') // fix header syntax
						.replace(/^(.+=)[\n\s]+([\s\S]+?)[\n\s]+$/, '$1\n{{answered|' + summary + '|text=\n$2\n}}') // place template
						.appendEditSummary('marked answered');
				}
			},
			{
				name:'✎ offer global CSS/JS migration',
				template: 'Hello {{subst:PAGENAME}}. You have global scripts and styles in <tt>[[User:{{subst:PAGENAME}}/global.js]]</tt> and <tt>[[{{subst:PAGENAME}}/global.css]]</tt>, which you import using [[toollabs:meta/userpages/{{subst:PAGENAME}}#css,js|your local CSS/JS pages]]. Since August 2014, your <tt>global.js</tt> and <tt>global.css</tt> pages are [[global user pages|loaded automatically on all wikis]]. Since you already import them yourself, you may experience script errors or tools being added twice. Do you want me to fix this by removing the imports from your local pages using [[Synchbot]] (without changing any other content)? ~~~',
				editSummary: 'Global CSS/JS migration',
				accessKey: 'm'
			},
			{
				name:'✎ synchbot done',
				template: '\n==Global user pages==\nHello {{subst:PAGENAME}}. [[Synchbot]] updated your user pages on all wikis as requested. You can see the full log on [[Synchbot/Archives/{{subst:PAGENAME}}|your archive page]]. :) ~~~',
				editSummary: '/* Global user pages */ new section',
				editSummaryPosition: 'replace'
			},
			{
				name:'✎ synchbot CSS/JS delete done',
				template: '\n==Global CSS/JS migration==\nHello {{subst:PAGENAME}}. [[Synchbot]] deleted your local CSS/JS pages on all wikis as requested. You can see the full log on [[Synchbot/Archives/{{subst:PAGENAME}}|your archive page]]. :) ~~~',
				editSummary: '/* Global CSS/JS migration */ new section',
				editSummaryPosition: 'replace'
			}
		],
		{ category: 'talk pages', forNamespaces: 'user talk', enabled: mw.config.get('wgDBname') === 'metawiki' }
	);
});
// </nowiki>

/**
 * GlobalView adds a [[Special:GlobalView]] page on the current
 * wiki to view your new messages and unread notifications on all wikis.
 * 
 * This is a quick and dirty script — it's not ready for reuse! Please contact
 * me if you're interested in using it.
*/
mw.loader.load('https://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/globalview.js&action=raw&ctype=text/javascript');

/**
 * When viewing a user's CSS/JS subpage, show a list of their other pages of the same type.
 */
mw.loader.using(['mediawiki.api'], function() {
	$(function() {
		var _cssjsTitlePattern = /\.(?:css|js)$/;

		// get page details
		var title = mw.config.get('wgTitle');
		if(mw.config.get('wgNamespaceNumber') !== 2 || !title.match(_cssjsTitlePattern))
			return;
		var username = mw.config.get('wgRelevantUserName');
		var contentModel = mw.config.get('wgPageContentModel');

		// add CSS
		mw.util.addCSS('.subpages a.is-standard { font-weight: bold; }');

		// fetch subpages
		var api = new mw.Api();
		api.get({ action: 'query', list: 'prefixsearch', pssearch: 'User:' + username + '/', pslimit: 100 }).then(function(data) {
			// get matching scripts
			var titles = [];
			$.each(data.query.prefixsearch, function(p, page) {
				if(page.title.match(_cssjsTitlePattern) && page.title.indexOf(title) === -1)
					titles.push(page.title.replace(/^[^:]+:[^\/]+\//, ''));
			});
			titles.sort();

			// get subpages box
			var container = $('.subpages:first');
			if(!container.length)
				container = $('<div>').addClass('subpages').prependTo('#contentSub'); // some wikis don't have subpages enabled in user namespace

			// add links
			if(titles.length) {
				var articlePath = mw.config.get('wgArticlePath');
				$.each(titles, function(t, title) {
					var link = $('<a>')
						.attr({ href: articlePath.replace('$1', 'User:' + username + '/' + title) })
						.text(title);
					if(title.match(/^(?:cologneblue|common|global|minerva|modern|monobook|vector)\.(?:css|js)$/))
						link.addClass('is-standard');
					container
						.append(' • ')
						.append(link);
				});
			}
			else {
				container
					.append(' • ')
					.append($('<em>').text('no other css/js pages'));
			}
		});
	});
});

/*******************
** Scripts on specific wikis
*******************/
switch(mw.config.get('wgDBname')) {
	case 'enwikisource':
		mw.loader.load('https://en.wikisource.org/w/index.php?title=MediaWiki:TemplateScript/proofreading.js&action=raw&ctype=text/javascript');
		break;

	case 'enwiki':
		/**
		 * Ajax sysop
		 * @see https://meta.wikimedia.org/wiki/Ajax_sysop
		 * @update-token [[File:Pathoschild/ajaxsysop.js]]
		 */
		mw.loader.load('//tools-static.wmflabs.org/meta/scripts/pathoschild.ajaxsysop.js');
		break;
}