MediaWiki:Gadget-DeveloperEditorTweaks.js
Jump to navigation
Jump to search
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- The following documentation is located at MediaWiki:Gadget-DeveloperEditorTweaks.js/documentation. [edit]
- This script is a part of the
DeveloperEditorTweaks
gadget (edit definitions)- Description (edit): Editor enhancements for script developers
- Useful links: subpage list • links • redirects
See also: Special:Gadgets.
'use strict'; /*jshint undef:true */
// {{documentation}}
/*global mw, jQuery */
if ((mw.config.get('wgAction') === 'edit') || (mw.config.get('wgAction') === 'submit'))
jQuery(document).ready(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': 'main',
'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",
'es5-shim' : "ECMAScript 5 shim for older browsers",
'':""
};
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> (deprecated)",
'curly' : "Mandate curly brackets in control structures",
'eqeqeq' : "Prohibit <code>==</code> and <code>!=</code>",
'es3' : "Mandate ECMAScript 3 compatibility (deprecated; use <code>esversion:3</code>)",
'es5' : "Mandate ECMAScript 5 compatibility (deprecated; use <code>esversion:5</code>)",
'esversion:<var>n</var>' : 'Mandate compatibility with an ECMAScript version (3, 5<span class="serial-comma">,</span> or 6)',
'forin' : "Mandate <code>hasOwnProperty</code> in <code>for..in</code> loops",
'freeze' : "Prohibit changing prototypes of built-in objects",
'futurehostile' : "Warn about identifiers defined in future versions of JavaScript",
'globals' : "Disable warnings for these globals",
'immed' : "Mandate parentheses around immediately-executed function expressions (deprecated)",
'indent:<var>n</var>' : "Set tab width (deprecated)",
'latedef' : "Prohibit using variables before their declaration",
'newcap' : "Mandate capitalisation of constructors (deprecated)",
'noarg' : "Prohibit use of <code>arguments.caller</code> and <code>arguments.callee</code>",
'noempty' : "Warn about empty blocks (deprecated)",
'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 (deprecated)",
'quotmark:single' : "Mandate single quotation marks only (deprecated)",
'quotmark:double' : "Mandata double quotation marks only (deprecated)",
'undef' : "Prohibit use of variables not explicitly declared",
'unused' : "Warn about unused variables",
'varstmt' : "Prohibit <code>var</code> (use <code>let</code> or <code>const</code>)",
'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 (deprecated)",
'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 (deprecated; use <code>esversion:6</code>)",
'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 (deprecated)",
'iterator' : "Allow using <code>__iterator__</code>",
'lastsemic' : "Allow omitting semicolons last statement",
'laxbreak' : "Allow lax line breaks (deprecated)",
'laxcomma' : "Allow comma-first coding style (deprecated)",
'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 (deprecated)",
'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 (deprecated)",
'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.replace(
/^[^:]+/,
'<a href="https://jshint.com/docs/options/#$&" target="_blank">$&</a>')
+ '</code>'
},
'description': {
'html': jshintDescriptions[option]
}
};
})
}
}
});
}
if (wgPageContentModel === 'Scribunto') {
// XXX: move console upwards
}
});