ميډياويکي:Gadget-DeveloperEditorTweaks.js

د ويکيسيند لخوا

يادښت: د غوره توبونو د خوندي کولو وروسته، خپل د کتنمل (بروزر) ساتل شوې حافظه تازه کړی.

  • فايرفاکس/ سفري: په دې کتنمل کې د Reload د ټکوهلو په وخت د Shift تڼۍ نيولې وساتی، او يا هم Ctrl-F5 يا Ctrl-Rتڼۍ کېښکاږۍ (په Apple Mac کمپيوټر باندې ⌘-R کېښکاږۍ)
  • گووگل کروم: په دې کتنمل کې د Ctrl-Shift-R تڼۍ کېښکاږۍ (د مک لپاره ⌘-Shift-R)
  • انټرنټ اېکسپلورر: په دې کتنمل کې د Refresh د ټکوهلو په وخت کې د Ctrl تڼۍ کېښکاږلې ونيسۍ، او يا هم د Ctrl-F5 تڼۍ کېښکاږۍ
  • اوپرا: په دې کتنمل کې د خپل براوزر ساتل شوې حافظه پدې توگه سپينولی شی Tools→Preferences
'use strict'; /*jshint undef:true */
/*global mw, jQuery */
if ((mw.config.get('wgAction') === 'edit') || (mw.config.get('wgAction') === 'submit'))
jQuery(function () {

var isCoding = { 'javascript': true, 'css': true, 'Scribunto': true };
var wgPageContentModel = mw.config.get('wgPageContentModel');

var wpTextbox1 = jQuery('#wpTextbox1');
if (!wpTextbox1.length) {
	console.error("det: failed to find WikiEditor entry point");
	return;
}
if (!wpTextbox1.wikiEditor) {
	console.error("det: WikiEditor not loaded?");
	return;
}

if (wgPageContentModel !== 'wikitext') {
	// remove irrelevant buttons
	// XXX: this should be reported to Bugzilla, really
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'main',
		'group': 'insert'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'main',
		'group': 'format'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'help'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'advanced',
		'group': 'heading'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'advanced',
		'group': 'format'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'advanced',
		'group': 'size'
	});
	wpTextbox1.wikiEditor('removeFromToolbar', {
		'section': 'advanced',
		'group': 'insert'
	});
}

// workaround [[gerrit:118993]]
mw.util.addCSS(
	".group-codeeditor-tools," +
	".codeEditor-ui-toolbar .group-insert," +
	".codeEditor-ui-toolbar .group-format," +
	".codeEditor-ui-toolbar .tabs span.tab-advanced," +
	".codeEditor-ui-toolbar .tabs span.tab-characters," +
	".codeEditor-ui-toolbar .tabs span.tab-help," +
	".codeEditor-ui-toolbar .sections {" +
	"	display: block !important;" +
	"}");

if (isCoding[wgPageContentModel]) {
	wpTextbox1.wikiEditor('addToToolbar', {
		'section': 'advanced',
		'groups': {
			'codefmt': {
				'tools': {
					'normws': {
						'type': 'button',
						'label': 'Normalise whitespace',
						'icon': '//upload.wikimedia.org/wikipedia/commons/thumb/0/00/VisualEditor_-_Icon_-_Indent-list-ltr.svg/24px-VisualEditor_-_Icon_-_Indent-list-ltr.svg.png', // XXX
						'action': {
							'type': 'callback',
							'execute': function (context) {
								function normws(text, lineStart, lineEnd) {
									text = text.replace(lineEnd ? /[ \t]+(\n|$)/g : /[ \t]+(\n)/g, '$1');
									var step = 4; // XXX: guess it by inspecting the source?
									text = text.replace(lineStart ? /(^|\n)([\t ]+)/g : /(\n)([\t ]+)/g, function (_, nl, indent) {
										indent = indent.replace(/    /g, '\t').replace(/ +\t/g, '\t').replace(/\t/g, '    ');
										var steps = Math.floor(indent.length / step); indent = '';
										for (var i = 0; i < steps; ++i)
											indent += '\t';
										return nl + indent;
									});
									return text;
								}

								if (!context.$textarea.textSelection('getSelection')) {
									if (context.codeEditor)
										context.codeEditor.selectAll();
									else
										context.$textarea[0].select();
								}

								context.$textarea.textSelection('encapsulateSelection', {
									replace: true, selectPeri: true,
									peri: normws(context.$textarea[0].value, true, true)
								});
							}
						}
					}
				}
			}
		}
	});
}

if ((wgPageContentModel === 'javascript') || (mw.config.get('wgPageName') === 'MediaWiki:Gadgets-definition')) {
	var moduleDescriptions = {
		'mediawiki.Title': "<code>mw.Title</code> object",
		'mediawiki.Uri'  : "<code>mw.Uri</code> object",
		'mediawiki.util' : "<code>mw.util</code>",
		'mediawiki.user' : "<code>mw.user</code>",
		'moment'         : "Moment.js",
		'site'           : "Site-specific scripts: [[MediaWiki:Common.js]] and per-skin JS",

		'':""
	};

	wpTextbox1.wikiEditor('addToToolbar', {
		'sections': {
			'js': {
				'type': 'booklet',
				'label': "JavaScript reference",
				'pages': {
					'modules': {
						'layout': 'table',
						'label': "ResourceLoader modules",
						'headings': [
							{ 'text': "Identifier" },
							{ 'text': "Description" }
						],
						'rows': mw.loader.getModuleNames().sort().filter(function (modname) {
							// they are quite dull modules, but they are there
							if (/^ext\.geshi\.language\./.test(modname))
								return false;
							if (/^ext\.math\.mathjax\.jax\.output\./.test(modname))
								return false;
							return true;
						}).map(function (modname) {
							return {
								'id': {
									'html': '<code>' + modname + '</code>',
								},
								'desc': {
									'html': moduleDescriptions[modname] || '<small style="color:gray;">(no description)</small>'
								}
							};
						})
					}
				}
			}
		}
	});
}

if (wgPageContentModel === 'javascript') {
	var jshintDescriptions = {
		'bitwise'                   : "Prohibit bitwise operators",
		'camelcase'                 : "Mandate <code>javaCamelCase</code>",
		'curly'                     : "Mandate curly brackets in control structures",
		'eqeqeq'                    : "Prohibit <code>==</code> and <code>!=</code>",
		'es3'                       : "Mandate ECMAScript 3 compatibility",
		'forin'                     : "Mandate <code>hasOwnProperty</code> in <code>for..in</code> loops",
		'freeze'                    : "Prohibit changing prototypes of built-in objects",
		'immed'                     : "Mandate parentheses around immediately-executed function expressions",
		'indent:<var>n</var>'       : "Set tab width",
		'latedef'                   : "Prohibit using variables before their declaration",
		'newcap'                    : "Mandate capitalisation of constructors",
		'noarg'                     : "Prohibit use of <code>arguments.caller</code> and <code>arguments.callee</code>",
		'noempty'                   : "Warn about empty blocks",
		'nonbsp'                    : "Warn about non-breaking space",
		'nonew'                     : "Prohibit constructor usage for side effects",
		'plusplus'                  : "Prohibit unary increment and decrement operators",
		'quotmark:true'             : "Mandate consistency of quotation marks",
		'quotmark:single'           : "Mandate single quotation marks only",
		'quotmark:double'           : "Mandata double quotation marks only",
		'undef'                     : "Prohibit use of variables not explicitly declared",
		'unused'                    : "Warn about unused variables",
		'strict'                    : "Mandate strict mode compatibility",
		'maxparams:<var>n</var>'    : "Enforce maximum number of formal parameters",
		'maxdepth:<var>n</var>'     : "Enforce maximum depth of nested blocks",
		'maxstatements'             : "Enforce maximum number of statements per function",
		'maxcomplexity:<var>n</var>': "Enforce maximum cyclomatic complexity",
		'maxlen'                    : "Enforce maximum length of a line",
		'asi'                       : "Allow semicolon insertion",
		'boss'                      : "Allow assignment-expressions",
		'debug'                     : "Allow <code>debugger</code> statements",
		'eqnull'                    : "Allow <code>== null</code> comparisons",
		'esnext'                    : "Allow ES.next syntax",
		'evil'                      : "Allow <code>eval</code>",
		'expr'                      : "Allow expressions where statements are expected",
		'funcscope'                 : "Allow using variables outside the block where they are declared",
		'globalstrict'              : "Allow global strict mode",
		'iterator'                  : "Allow using <code>__iterator__</code>",
		'lastsemic'                 : "Allow omitting semicolons last statement",
		'laxbreak'                  : "Allow lax line breaks",
		'laxcomma'                  : "Allow comma-first coding style",
		'loopfunc'                  : "Allow making functions within a loop",
		'maxerr:<var>n</var>'       : "Set maximum number of warnings",
		'moz'                       : "Allow Mozilla extensions",
		'multistr'                  : "Allow multi-line string literals",
		'notypeof'                  : "Allow lax usage of <code>typeof</code>",
		'proto'                     : "Allow using <code>__proto__</code>",
		'scripturl'                 : "Allow <code>javascript:</code> URLs",
		'shadow'                    : "Allow variable shadowing",
		'sub'                       : "Allow bracket notation for object member access",
		'supernew'                  : "Allow atypical constructor usage",
		'validthis'                 : "<code>this</code> is valid in this function",
		'noyield'                   : "Allow generators without <code>yield</code>",

		'browser'                   : "Assume a browser environment",
		'devel'                     : "Assume <code>console</code> is available",
		'jquery'                    : "Assume jQuery is available",
		'nonstandard'               : "Assume non-standard global functions are available",
		'worker'                    : "Assume Web Worker globals are available",

		/* probably not useful: assume a framework is available
		'couch'                 : "",
		'dojo'                  : "",
		'mootools'              : "",
		'node'                  : "",
		'phantom'               : "",
		'prototypejs'           : "",
		'rhino'                 : "",
		'wsh'                   : "",
		'yui'                   : "",
		*/
	};

	wpTextbox1.wikiEditor('addToToolbar', {
		'section': 'js',
		'pages': {
			'jshint': {
				'layout': 'table',
				'label': "JSHint options",
				'headings': [
					{ 'text': "Option" },
					{ 'text': "Description" }
				],
				'rows': Object.keys(jshintDescriptions).sort().map(function (option) {
					return {
						'option': {
							'html': '<code>' + option + '</code>'
						},
						'description': {
							'html': jshintDescriptions[option]
						}
					};
				})
			}
		}
	});
}

if (wgPageContentModel === 'Scribunto') {
	// XXX: move console upwards
}

});