Benutzer:Schnark/js/veCustomize.js
< Benutzer:Schnark | js
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Dokumentation unter [[Benutzer:Schnark/js/veCustomize]] <nowiki>
/*global mediaWiki, ve, OO*/
(function ($, mw) {
"use strict";
var l10n = {
en: {
'schnark-vecustomize-small-title': 'Small font',
'schnark-vecustomize-small-help': '',
'schnark-vecustomize-small-sample': 'small font',
'schnark-vecustomize-br-title': 'Line break',
'schnark-vecustomize-br-help': '',
'schnark-vecustomize-poem-title': 'Poem',
'schnark-vecustomize-poem-help': 'Poem',
'schnark-vecustomize-poem-sample': 'Poem',
'schnark-vecustomize-la-title': 'Löschantrag',
'schnark-vecustomize-la-help': 'LA-Vorlage',
'schnark-vecustomize-nbsp-help': 'Non-breaking space'
},
de: {
'schnark-vecustomize-small-title': 'Kleine Schriftgröße',
'schnark-vecustomize-small-help': '',
'schnark-vecustomize-small-sample': 'kleine Schriftgröße',
'schnark-vecustomize-br-title': 'Zeilenumbruch',
'schnark-vecustomize-br-help': '',
'schnark-vecustomize-poem-title': 'Gedicht',
'schnark-vecustomize-poem-help': 'Gedicht',
'schnark-vecustomize-poem-sample': 'Gedicht',
'schnark-vecustomize-nbsp-help': 'Geschütztes Leerzeichen'
}
}, toolCount = 0;
function initL10N (l10n) {
var i, chain = mw.language.getFallbackLanguageChain();
for (i = chain.length - 1; i >= 0; i--) {
if (chain[i] in l10n) {
mw.messages.set(l10n[chain[i]]);
}
}
}
function makeName () {
return 'schnark-ve-tool-' + (toolCount++);
}
function makeTrigger (trigger) {
function convertToTrigger (input) {
return Array.isArray(input) ?
input.map(function (str) {
return new ve.ui.Trigger(str);
}) :
new ve.ui.Trigger(input);
}
if (typeof trigger === 'string') {
trigger = {mac: trigger.replace('ctrl', 'cmd'), pc: trigger};
}
return {mac: convertToTrigger(trigger.mac), pc: convertToTrigger(trigger.pc)};
}
function makeTemplate (name, params, block, subst) {
var formattedParams = {}, param;
for (param in params) {
if (Object.prototype.hasOwnProperty.call(params, param)) {
formattedParams[param] = {wt: params[param]};
}
}
return [{
type: block ? 'mwTransclusionBlock' : 'mwTransclusionInline',
attributes: {
mw: {
parts: [{
template: {
target: {
href: mw.config.get('wgFormattedNamespaces')[10] + ':' + name,
wt: (subst ? 'subst:' : '') + name
},
params: formattedParams
}
}]
}
}
}, {
type: block ? '/mwTransclusionBlock' : '/mwTransclusionInline'
}];
}
function replaceLinebreaks (s) {
var data = [];
if (s.indexOf('\n') === -1) {
return s;
}
s.split('').forEach(function (c) {
if (c === '\n') {
data.push({type: '/paragraph'}, {type: 'paragraph'});
} else {
data.push(c);
}
});
return data;
}
function enableSignEverywhere (all) {
var ns, module;
if (!all) {
all = [];
for (ns in mw.config.get('wgFormattedNamespaces')) {
if (!isNaN(ns) && ns >= 0) {
all.push(Number(ns));
}
}
}
mw.config.set('wgExtraSignatureNamespaces', all);
//HACK
try {
module = mw.loader.moduleRegistry['ext.visualEditor.mwsignature'];
if (module && module.state === 'ready') {
module.script($, $, mw);
}
} catch (e) {
mw.log.warn(e);
}
}
function makeCustomTool (config) {
var name = makeName();
config = $.extend({
parent: config.insert ? ve.ui.MWTransclusionDialogTool : ve.ui.AnnotationTool,
group: config.insert ? 'object' : 'textStyle',
icon: 'template',
title: '',
insert: false,
dialog: false,
annotation: false,
collapseToEnd: true,
selections: config.insert ? ['linear'] : ['linear', 'table']
}, config);
if (config.icon.slice(0, 8) === 'https://') {
mw.util.addCSS('.oo-ui-icon-' + name + '{background-image: url(' + config.icon + ');}');
config.icon = name;
} else if (config.iconModule) {
mw.loader.load(config.iconModule);
}
function InsertAndOpenCommand (name, type, options) {
InsertAndOpenCommand.parent.call(this, name, null, null, options);
this.windowType = type;
}
OO.inheritClass(InsertAndOpenCommand, ve.ui.Command);
InsertAndOpenCommand.prototype.execute = function (surface, args) {
args = args || this.args;
surface.getModel().getFragment().collapseToEnd().insertContent(args[0], args[1]).select();
surface.execute('window', 'open', this.windowType);
return true;
};
function CustomTool () {
CustomTool.parent.apply(this, arguments);
}
OO.inheritClass(CustomTool, config.parent);
CustomTool.static.name = name;
CustomTool.static.group = config.group;
CustomTool.static.icon = config.icon;
CustomTool.static.title = config.title;
if (!config.insert) {
CustomTool.static.annotation = {name: config.annotation};
}
CustomTool.static.commandName = name;
if (config.icon) {
ve.ui.toolFactory.register(CustomTool);
}
if (config.insert) {
if (config.dialog) {
ve.ui.commandRegistry.register(
new InsertAndOpenCommand(name, config.dialog, {
args: [config.insert, config.annotation],
supportedSelections: config.selections
})
);
} else {
ve.ui.commandRegistry.register(
new ve.ui.Command(name, 'content', 'insert', {
args: [config.insert, config.annotation, config.collapseToEnd],
supportedSelections: config.selections
})
);
}
} else {
ve.ui.commandRegistry.register(
new ve.ui.Command(name, 'annotation', 'toggle', {
args: [config.annotation],
supportedSelections: config.selections
})
);
}
if (config.wikitext && ve.ui.wikitextCommandRegistry) {
if (Array.isArray(config.wikitext)) {
ve.ui.wikitextCommandRegistry.register(
new ve.ui.Command(name, 'mwWikitext', config.annotation ? 'toggleWrapSelection' : 'wrapSelection', {
//NOTE: I prefer this order
args: [
replaceLinebreaks(config.wikitext[0]),
replaceLinebreaks(config.wikitext[2]),
replaceLinebreaks(config.wikitext[1])
],
supportedSelections: ['linear']
})
);
} else {
ve.ui.wikitextCommandRegistry.register(
new ve.ui.Command(name, 'content', 'insert', {
args: [config.wikitext, false, config.collapseToEnd],
supportedSelections: ['linear']
})
);
}
}
if (config.sequence) {
ve.ui.sequenceRegistry.register(
new ve.ui.Sequence(name, name, config.sequence, config.sequence.length)
);
}
if (config.trigger) {
ve.ui.triggerRegistry.register(
name, makeTrigger(config.trigger)
);
}
if (config.help) {
ve.ui.commandHelpRegistry.register(config.insert ? 'insert' : 'textStyle', name, {
sequences: config.sequence ? [name] : [],
trigger: config.trigger ? name : undefined,
label: config.help
});
}
}
function makeToolFromCode (code) {
var data;
switch (code) {
case 'small': //no longer necessary
data = {
annotation: 'textStyle/small',
wikitext: ['<small>', mw.msg('schnark-vecustomize-small-sample'), '</small>'],
icon: 'smaller',
iconModule: 'oojs-ui.styles.icons-editing-styling'
};
break;
case 'br':
data = {
insert: [{type: 'break'}, {type: '/break'}],
wikitext: '<br>',
icon: 'newline',
iconModule: 'oojs-ui.styles.icons-editing-advanced'
};
break;
case 'poem':
data = [{
type: 'mwAlienBlockExtension',
attributes: {
mw: {
name: 'poem',
body: {
extsrc: ''
}
}
}
}, {
type: '/mwAlienBlockExtension'
}];
data = {
insert: data,
collapseToEnd: false,
dialog: 'alienExtension',
wikitext: ['\n<poem>\n', mw.msg('schnark-vecustomize-poem-sample'), '\n</poem>\n'],
icon: 'textFlow',
iconModule: 'oojs-ui.styles.icons-layout',
sequence: '<poem'
};
break;
case 'la': //actually more proof of concept than anything else
data = {
insert: makeTemplate('Löschantrag', {1: '\'\'Grund\'\' --~~~~'}, true, true),
dialog: 'transclusion',
wikitext: ['\n{{subst:Löschantrag|1=\'\'', 'Grund', '\'\' --~~~~}}\n'],
sequence: '{LA}',
icon: 'tag',
iconModule: 'oojs-ui.styles.icons-content',
trigger: 'ctrl+shift+l'
};
break;
case 'nbsp':
data = {
insert: [
{type: 'mwEntity', attributes: {character: '\u00a0'}},
{type: '/mwEntity'}
],
wikitext: ' ',
annotation: true,
icon: '', //no visible tool
trigger: {mac: 'alt+space', pc: ['ctrl+space', 'ctrl+shift+space']},
sequence: ' '
};
break;
case 'sig':
return;
default:
mw.log.warn('Code "' + code + '" not defined!');
return;
}
data.title = mw.msg('schnark-vecustomize-' + code + '-title');
data.help = mw.msg('schnark-vecustomize-' + code + '-help');
makeCustomTool(data);
}
function init () {
var codes = mw.user.options.get('userjs-schnark-vecustomize-tools', 'sig, br').split(/\W+/),
deps = ['mediawiki.language', 'ext.visualEditor.core', 'ext.visualEditor.mwtransclusion'];
if (codes.indexOf('sig') > -1) {
enableSignEverywhere();
}
if (mw.libs.ve.isWikitextAvailable) {
deps.push('ext.visualEditor.mwwikitext');
}
mw.loader.using(deps).then(function () {
var i;
initL10N(l10n);
for (i = 0; i < codes.length; i++) {
makeToolFromCode(codes[i]);
}
mw.hook('userjs.script-ready.veCustomize').fire();
});
}
mw.loader.using('user.options').then(init);
})(jQuery, mediaWiki);
//</nowiki>