/*** SVG Editor ***/
// Adds a button to SVG file pages to view and edit their source code
// Documentation at [[en:w:User:BrandonXLF/SVGEditor]]
// By [[en:w:User:BrandonXLF]]
mw.loader.using(['oojs-ui', 'jquery.textSelection']).then(function() {
function showEditor(text) {
var isCommons = !!$('#ca-view-foreign').length,
lineWrap = new OO.ui.ButtonInputWidget({
label: 'Toggle line wrap',
icon: 'newline',
id: 'svgeditor-linewrap-btn',
framed: false
}),
code = new OO.ui.MultilineTextInputWidget({
rows: 25,
name: 'wpTextbox1',
id: 'svgeditor'
}),
comment = new OO.ui.TextInputWidget({
id: 'svgeditor-comment',
label: 'Comment',
labelPosition: 'before'
}),
save = new OO.ui.ButtonInputWidget({
label: 'Save',
flags: ['primary', 'progressive'],
icon: isCommons ? 'logoWikimediaCommons' : void 0,
title: isCommons ? 'Save To Wikimedia Commons' : void 0
}),
preview = new OO.ui.ButtonInputWidget({
label: 'Preview',
flags: ['progressive']
}),
cancel = new OO.ui.ButtonInputWidget({
label: 'Cancel',
flags: ['destructive']
}),
buttons = new OO.ui.HorizontalLayout({
items: [save, preview, cancel]
}),
img,
container = $('<div>');
mw.loader.load('oojs-ui.styles.icons-editing-advanced');
lineWrap.on('click', function() {
code.$input.toggleClass('line-wrap');
});
mw.config.set('wgCodeEditorCurrentLanguage', 'svg');
code.$input.attr('id', 'wpTextbox1');
code.$input.textSelection('setContents', text);
if (isCommons) mw.loader.load('oojs-ui.styles.icons-wikimedia');
save.on('click', function() {
var api = isCommons ? new mw.ForeignApi('https://commons.wikimedia.org/w/api.php') : new mw.Api(),
req = api.upload(new Blob([code.$input.textSelection('getContents')], {type: 'image/svg+xml'}), {
filename: mw.config.get('wgTitle'),
comment: comment.getValue(),
ignorewarnings: 1
});
req.always(function(errOrRes, resWhenErr) {
var res = resWhenErr || errOrRes;
if (res.error) {
mw.notify(api.getErrorMessage(res), {type: 'error'});
return;
}
mw.notify('File saved! Loading updated page...', {type: 'success'});
$.get().then(function(html) {
var doc = new DOMParser().parseFromString(html, 'text/html');
$('#content').replaceWith($('#content', doc).prepend(container));
});
});
});
preview.on('click', function() {
if (!img) {
img = $('<img>');
img.css('max-height', '15em');
container.append(img);
}
img.attr('src', 'data:image/svg+xml,' + encodeURIComponent(code.$input.textSelection('getContents')));
});
cancel.on('click', function() {
$('#svgeditor-container').remove();
});
container.attr('id', 'svgeditor-container').addClass('content').append(
lineWrap.$element,
code.$element,
comment.$element,
buttons.$element
);
mw.util.$content.prepend(container);
mw.loader.using(['ext.wikiEditor'], function() {
mw.addWikiEditor(code.$input);
if (mw.loader.getState('ext.codeEditor') === 'ready') {
mw.loader.state({'ext.codeEditor': 'loaded'});
}
mw.loader.load(['ext.codeEditor']);
$.wikiEditor.modules.editSVGTools = {
req: ['editSVGTools']
};
$.wikiEditor.extensions.editSVGTools = function(ctx) {
lineWrap.$element.remove();
ctx.api.addToToolbar(ctx, {
section: 'main',
groups: {
'svgeditor-tools': {
tools: {
lineWrap: {
label: 'Toggle line wrap',
type: 'toggle',
oouiIcon: 'newline',
action: {
type: 'callback',
execute: function() {
code.$input.toggleClass('line-wrap');
}
}
}
}
},
}
});
};
code.$input.wikiEditor('addModule', 'editSVGTools');
});
}
$(function() {
if (mw.config.get('wgNamespaceNumber') !== 6) return;
var url = $('#file > a').attr('href');
if (!/.+svg$/.test(url)) return;
var link;
if (mw.config.get('skin') === 'minerva') {
mw.loader.load('oojs-ui.styles.icons-editing-advanced');
link = $(mw.util.addPortletLink('page-actions', '#', 'Edit SVG', 'page-actions-svgeditor', '', '', '#page-actions-edit'));
var iconUrl ='/w/load.php?modules=oojs-ui.styles.icons-editing-advanced&image=markup&format=rasterized';
mw.loader.addStyleTag('#page-actions-svgeditor .mw-ui-icon:before { background: url(' + iconUrl + '); }');
} else {
link = $(mw.util.addPortletLink('p-views', '#', 'Edit SVG', 'ca-svgeditor', '', '', '#ca-edit'));
}
link.on('click', function(e) {
e.preventDefault();
$('#svgeditor-container').remove();
$.get(url, null, null, 'text').then(showEditor);
});
mw.loader.addStyleTag(
'#svgeditor, #svgeditor-comment { width: unset !important; max-width: unset !important; marin: none !important; }' +
'#svgeditor textarea { font-family: monospace; resize: vertical; white-space: nowrap; }' +
'#svgeditor textarea.line-wrap { white-space: normal; }' +
'#svgeditor .wikiEditor-ui textarea { border: none !important; }' +
'#svgeditor-container > * { margin: 1em 0; }' +
'.skin-minerva #svgeditor-container { padding: 1em; }' +
'.skin-minerva #svgeditor-linewrap-btn { margin-bottom: -0.5em; }' +
'#svgeditor .group-insert, #svgeditor .group-format, #svgeditor .sections { display: none; }' +
'#svgeditor .tabs span.tab-advanced, #svgeditor .tabs span.tab-characters, #svgeditor .tabs span.tab-help { display: none; }' +
'.codeEditor-ui-toolbar .group-svgeditor-tools { display: none; }'
);
});
});