Benutzer:Schnark/js/veCode.js
aus Wikipedia, der freien Enzyklopädie
< Benutzer:Schnark | js
Dies ist die aktuelle Version dieser Seite, zuletzt bearbeitet am 17. Dezember 2019 um 10:08 Uhr durch imported>Schnark(522406) (alten Code entfernt).
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
- Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Strg+F5
//Dokumentation unter [[Benutzer:Schnark/js/veCode]] <nowiki>
/*global mediaWiki, OO, ve*/
(function ($, mw) {
"use strict";
var l10n = {
en: {
'schnark-vecode-label': 'Edit code separately',
'schnark-vecode-title': 'Edit code',
'schnark-vecode-owe': 'Code (traditional)'
},
de: {
'schnark-vecode-label': 'Code separat bearbeiten',
'schnark-vecode-title': 'Code bearbeiten',
'schnark-vecode-owe': 'Quelltext (traditionell)'
}
}, availableModels = {
javascript: {mime: 'text/javascript', module: 'javascript', ace: 'javascript', geshi: 'javascript'},
css: {mime: 'text/css', module: 'css', ace: 'css', geshi: 'css'},
'sanitized-css': {mime: 'text/css', module: 'css', ace: 'css', geshi: 'css'}
//Scribunto: {mime: 'text/plain', module: ???, ace: 'lua', geshi: 'lua'}
};
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 define (model) {
/*jshint evil:true*/
//Change CodeMirrorAction and ArticleTarget to depend on current mime type
ve.ui.CodeMirrorAction.prototype.toggle = eval('(' +
ve.ui.CodeMirrorAction.prototype.toggle.toString().replace(
/(['"]?)mode\1\s*:\s*(['"])text\/mediawiki\2/,
'mode:"' + availableModels[model].mime + '"'
) +
')');
ve.init.mw.ArticleTarget.prototype.submit = eval('(' +
ve.init.mw.ArticleTarget.prototype.submit.toString().replace(
/(['"]?)format\1\s*:\s*(['"])text\/x-wiki\2/,
'format:"' + availableModels[model].mime + '"'
).replace(
/(['"]?)model\1\s*:\s*(['"])wikitext\2/,
'model:"' + model + '"'
) +
')');
//Target for editing code
function CodeTarget (config) {
config.modes = ['source']; //VE thinks no mode is available
CodeTarget.parent.call(this, config);
}
OO.inheritClass(CodeTarget, ve.init.mw.DesktopArticleTarget);
CodeTarget.static.name = 'code';
//Remove useless stuff, add our own dialog
CodeTarget.static.toolbarGroups = [
{name: 'history', include: ['undo', 'redo']},
{name: 'aceDialog', include: ['aceDialog']},
{name: 'specialCharacter', include: ['specialCharacter']}
];
//We ca'n't just inherit and add the tool to switch to OWE in CodeTarget,
//because several tools (including CodeMirror) extend DesktopArticleTarget.
//Depending on execution order, these would be missing.
//Since DesktopArticleTarget isn't used directly in our case, it doesn't matter
//that the tool is there (and even if it was, it would be acceptable).
ve.init.mw.DesktopArticleTarget.static.actionGroups[2].include.push('editModeOwe');
CodeTarget.prototype.getDocToSave = function () {
var doc = CodeTarget.parent.prototype.getDocToSave.apply(this, arguments);
if (this.addSyntaxhighlightTags) {
doc =
'<syntaxhighlight lang="' + availableModels[model].geshi + '">' +
doc +
'</syntaxhighlight>';
}
return doc;
};
CodeTarget.prototype.onSaveDialogPreview = function () {
var code = this.getDocToSave();
switch (model) {
case 'javascript':
$.globalEval(code);
break;
case 'css':
if (this.previousStyleTag) {
$(this.previousStyleTag).remove();
}
this.previousStyleTag = mw.util.addCSS(code).ownerNode;
}
this.addSyntaxhighlightTags = true;
CodeTarget.parent.prototype.onSaveDialogPreview.apply(this, arguments);
this.addSyntaxhighlightTags = false;
};
CodeTarget.prototype.saveComplete = function (html, categoriesHtml, newid, isRedirect) {
var newUrlParams;
//skip one level
ve.init.mw.DesktopArticleTarget.parent.prototype.saveComplete.apply(this, arguments);
//always reload
this.teardown().then(function () {
newUrlParams = newid === undefined ? {} :
{venotify: this.restoring ? 'restored' : (this.pageExists ? 'saved' : 'created')};
if (isRedirect) {
newUrlParams.redirect = 'no';
}
location.href = this.viewUri.extend(newUrlParams);
}.bind(this));
};
ve.init.mw.targetFactory.register(CodeTarget);
//Varinat of SaveDialog to exclude VisualDiff
function CodeSaveDialog () {
CodeSaveDialog.parent.apply(this, arguments);
}
OO.inheritClass(CodeSaveDialog, ve.ui.windowFactory.lookup('mwSave'));
CodeSaveDialog.prototype.initialize = function () {
if (ve.userConfig('visualeditor-diffmode-source') === 'visual') {
ve.userConfig('visualeditor-diffmode-source', 'source');
}
CodeSaveDialog.parent.prototype.initialize.apply(this, arguments);
this.reviewModeButtonSelect.findItemFromData('visual').setDisabled(true);
};
ve.ui.windowFactory.register(CodeSaveDialog);
//Add utility method to MWAceEditorWidget
ve.ui.MWAceEditorWidget.prototype.withAceEditor = function (callback) {
this.loadingPromise.then(function () {
callback(this.editor);
}.bind(this));
return this;
};
//Dialog, command, and tool to edit with Ace
function AceDialog () {
AceDialog.parent.apply(this, arguments);
}
OO.inheritClass(AceDialog, OO.ui.ProcessDialog);
AceDialog.static.name = 'aceDialog';
AceDialog.static.title = mw.msg('schnark-vecode-title');
AceDialog.static.size = 'full';
AceDialog.static.actions = [
{
label: OO.ui.deferMsg('visualeditor-dialog-action-cancel'),
flags: ['safe', 'close'],
modes: ['readonly', 'edit']
},
{
action: 'done',
label: OO.ui.deferMsg('visualeditor-dialog-action-done'),
flags: ['progressive', 'primary'],
modes: ['edit']
}
];
AceDialog.prototype.initialize = function () {
AceDialog.parent.prototype.initialize.apply(this, arguments);
this.panel = new OO.ui.PanelLayout({
padded: true
});
this.input = new ve.ui.MWAceEditorWidget({
limit: 1,
minRows: 5,
maxRows: Math.floor((window.innerHeight - 100) / 21), //FIXME
autosize: true,
autocomplete: 'live'
});
this.input.$element.css('max-width', 'none');
//this.input.connect(this, {resize: 'updateSize'});
this.panel.$element.append(this.input.$element);
this.$body.append(this.panel.$element);
};
AceDialog.prototype.getSetupProcess = function () {
return AceDialog.parent.prototype.getSetupProcess.apply(this, arguments).first(function () {
this.input.setup();
this.input
.setLanguage(availableModels[model].ace)
.withAceEditor(function (editor) {
var session = editor.getSession();
editor.setOptions({
enableSnippets: true
});
session.setUseSoftTabs(false);
mw.hook('codeEditor.configure').fire(session);
//TODO Toolbar, statusbar
//see Extension CodeEditor > jquery.codeEditor.js > updateStatusBar
//etc., e.g. editor.setShowInvisibles(true);
});
}, this).next(function () {
var readOnly = this.manager.surface.isReadOnly();
if (readOnly) {
this.input.setReadOnly(true);
}
this.actions.setMode(readOnly ? 'readonly' : 'edit');
this.actions.setAbilities({done: false});
}, this);
};
AceDialog.prototype.onFirstChange = function () {
this.actions.setAbilities({done: true});
this.input.disconnect(this, {change: 'onFirstChange'});
};
AceDialog.prototype.getTeardownProcess = function () {
return AceDialog.parent.prototype.getTeardownProcess.apply(this, arguments).first(function () {
this.input.teardown();
}, this);
};
AceDialog.prototype.getReadyProcess = function () {
return AceDialog.parent.prototype.getReadyProcess.apply(this, arguments)
.next(function () {
this.input.setValue(this.manager.surface.getDom());
this.input.clearUndoStack();
this.input.focus();
this.input.connect(this, {change: 'onFirstChange'});
}, this);
};
AceDialog.prototype.getActionProcess = function (action) {
return AceDialog.parent.prototype.getActionProcess.apply(this, arguments).next(function () {
var surfaceModel;
if (action === 'done') {
surfaceModel = this.manager.surface.getModel();
surfaceModel.setLinearSelection(
new ve.Range(0, surfaceModel.getDocument().data.getLength())
);
surfaceModel.getFragment().insertContent(this.input.getValue()).collapseToStart().select();
this.close({action: 'done'});
}
}, this);
};
ve.ui.windowFactory.register(AceDialog);
ve.ui.commandRegistry.register(
new ve.ui.Command('aceDialog', 'window', 'open', {args: ['aceDialog']})
);
function AceTool () {
AceTool.parent.apply(this, arguments);
}
OO.inheritClass(AceTool, ve.ui.WindowTool);
AceTool.static.name = 'aceDialog';
AceTool.static.group = 'dialog';
AceTool.static.icon = 'markup';
AceTool.static.title = mw.msg('schnark-vecode-label');
AceTool.static.displayBothIconAndLabel = true;
AceTool.static.autoAddToCatchall = false;
AceTool.static.autoAddToGroup = false;
AceTool.static.commandName = 'aceDialog';
ve.ui.toolFactory.register(AceTool);
//Tool to switch to OWE
function EditModeOweTool () {
EditModeOweTool.parent.apply(this, arguments);
}
OO.inheritClass(EditModeOweTool, mw.libs.ve.MWEditModeTool);
EditModeOweTool.static.editMode = 'owe';
EditModeOweTool.static.name = 'editModeOwe';
EditModeOweTool.static.icon = 'markup';
EditModeOweTool.static.title = mw.msg('schnark-vecode-owe');
EditModeOweTool.prototype.switch = function () {
//Actually nobody really cares whether the content is modified or not,
//so just claim it is withouth checking
this.toolbar.getTarget().switchToWikitextEditor(false, true, true);
};
ve.ui.toolFactory.register(EditModeOweTool);
}
function editVe (model) {
mw.loader.using([
'mediawiki.language',
'mediawiki.util',
'ext.visualEditor.desktopArticleTarget',
'ext.visualEditor.articleTarget',
'ext.CodeMirror.visualEditor',
'ext.CodeMirror.lib.mode.' + availableModels[model].module
]).then(function () {
initL10N(l10n);
define(model);
mw.config.get('wgVisualEditorConfig').contentModels[model] = 'code';
mw.libs.ve.activateVe('source');
});
}
function enableVe () {
$('html').removeClass('ve-not-available').addClass('ve-available');
$('#ca-edit, #ca-viewsource').on('click', function (e) {
if (!(e && e.which && e.which === 1 && !(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey))) {
return;
}
e.preventDefault();
editVe(mw.config.get('wgPageContentModel'));
});
}
if (availableModels[mw.config.get('wgPageContentModel')]) {
enableVe();
}
})(jQuery, mediaWiki);
//</nowiki>