/*** FFU Helper ***/
// User script to close and respond to FFU request
// Documentation at ]
// By ]
// <syntaxhighlight lang=javascript>
mw.hook('wikipage.content').add(function(content) {
if (mw.config.get('wgPageName') !== 'Wikipedia:Files_for_upload') return;
var currentInterface,
// Template data (TEMPLATE, DESCRIPTION, USER TALK MESSAGE TYPE, PARAMETER 1, PARAMETER 2)
templates = {
accept: [
],
decline: [
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
],
comment: [
,
,
,
,
,
,
,
,
,
],
};
function createParameter(key, desc) {
return $('<span>')
.attr('id', 'ffu-parameter-' + key)
.css({
marginLeft: '1em',
display: 'block'
})
.append(key + ': ')
.append($('<input>')
.attr('placeholder', desc)
.css({
border: 'none',
borderBottom: '1px solid #555',
padding: '2px'
})
);
}
function createOption(data, select) {
var label = $('<label>'),
code = data.replace(/\|+=\$\d/g, '').replace(/ \$\d/g, '');
function selectClicked() {
$('#ffu-parameter-1, #ffu-parameter-2').remove();
$('#ffu-selected')
.removeAttr('id')
.find('input')
.prop('checked', false);
label.attr('id', 'ffu-selected');
if (data)
label.after(createParameter('2', data));
if (data)
label.after(createParameter('1', data));
}
setTimeout(function() {
if (select)
selectClicked();
});
label
.data('ffu', data)
.css('display', 'block')
.append($('<input>')
.css({
verticalAlign: 'middle',
marginRight: '4px'
})
.attr('type', 'radio')
.prop('checked', select)
.click(selectClicked)
)
.append($('<span>')
.css('vertical-align', 'middle')
.text(code + ' - ')
.append($('<i>').text(data))
);
return label;
}
function getUser(sectionElement) {
var user = '',
element = sectionElement.next();
while (user === '' && element) {
if (!element.is(currentInterface)) {
user = element.find('.userlink').attr('href') || '';
}
element = element.next();
}
user = decodeURIComponent(user).match(/.*(?:ser:|\/)(+)/);
user = user ? user : '';
return user;
}
function openInterface(type, section, sectionElement) {
var idElement = sectionElement.find('.mw-headline');
if (!idElement.length) {
idElement = sectionElement.find(':header');
}
var sectionName = idElement.attr('id').replace(/_/g, ' '),
user = getUser(sectionElement),
addHoldInput = $('<input>'),
notifyUserInput = $('<input>'),
userInput = $('<input>'),
options = ;
for (var i = 0; i < templates.length; i++) {
options.push(createOption(templates, i === 0));
}
var actionButtons;
function onSave() {
actionButtons.prop('disabled', true);
var selectedOption = $('#ffu-selected'),
shouldNotifyUser = notifyUserInput.prop('checked');
if (!selectedOption.length) {
actionButtons.prop('disabled', false);
return;
}
if (shouldNotifyUser && !userInput.val()) {
mw.notify('No username given to notify.', {
type: 'error'
});
actionButtons.prop('disabled', false);
return;
}
var data = selectedOption.data('ffu'),
api = new mw.Api();
mw.notify('Fetching page text...');
$.get(mw.config.get('wgScript'), {
title: mw.config.get('wgPageName'),
action: 'raw',
section: section
}).then(function(text) {
mw.notify('Updating FFU request...');
// Substitute parameters
var code = data
.replace(/\$1/, $('#ffu-parameter-1 input').val() || '')
.replace(/\$2/, $('#ffu-parameter-2 input').val() || '');
text += '\n:' + code + ' ~~' + '~~';
// Add hold notice for comments
if (type === 'comment' && addHoldInput.prop('checked')) {
text = text.replace(/{{(?:Template:|)fu h\|.*?}}/g, '');
text = text.replace(/-->\n/, '-->');
text = text.replace(/-->\n+/, '-->');
text = text.replace(/\n+<!--/, '<!--');
text = text.replace(/(==.*==)\n*/, '$1\n{{su' + 'bst:ffu h}}\n');
}
// Add top and bottom for accept/decline
if (type !== 'comment') {
text = text.replace(/(==.*==)\n*/, '$1\n{{su' + 'bst:ffu ' + type + '}}\n');
text = text.replace(/(<!-- \\].**)/, '');
text += '\n{{su' + 'bst:ffu b}}';
}
var editSummary = {
'accept': 'Accepted',
'decline': 'Declined',
'comment': 'Commented on'
} + ' request using ]';
return api.postWithEditToken({
action: 'edit',
section: section,
text: text,
title: mw.config.get('wgPageName'),
summary: editSummary
}).then(function() {
mw.notify('Finished editing FFU request.');
});
}).then(function() {
if (!shouldNotifyUser) return;
mw.notify('Posting on user talk page...');
return api.postWithEditToken({
action: 'edit',
appendtext: '\n\n{{su' + 'bst:ffu talk|' + data + '|section=' + sectionName + '}} ~~' + '~~',
title: 'User talk:' + userInput.val(),
summary: 'Notifying about ] request using ]'
}).then(function() {
mw.notify('Posted notice on user talk page.');
});
}).then(function() {
mw.notify('Reloading page...');
$.get(mw.config.get('wgScriptPath') + '/api.php', {
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'text|categorieshtml',
format: 'json'
}).done(function(res) {
var contentText = $('#mw-content-text'),
catLinks = $('#catlinks');
contentText.find('.mw-parser-output').replaceWith(res.parse.text);
mw.hook('wikipage.content').fire(contentText);
catLinks.replaceWith(res.parse.categorieshtml);
mw.hook('wikipage.categories').fire(catLinks);
mw.notify('Page reloaded.');
});
}).fail(function(_, data) {
mw.notify(new mw.Api().getErrorMessage(data), {type: 'error'});
actionButtons.prop('disabled', false);
});
}
if (currentInterface)
currentInterface.remove();
actionButtons = $()
.add($('<button>')
.css('margin', '4px')
.text('Save')
.click(onSave)
)
.add($('<button>')
.css('margin', '4px')
.text('Cancel')
.click(function() {
currentInterface.remove();
})
);
currentInterface = $('<p>')
.css({
border: '1px solid ' + {
comment: 'grey',
decline: 'red',
accept: 'green'
},
borderRadius: '4px',
padding: '4px 0.5em'
})
.append($('<span>')
.css({
fontStyle: '125%',
fontWeight: 'bold',
marginBottom: '1em'
})
.text('FFU Helper - ' + type.charAt(0).toUpperCase() + type.slice(1))
)
.append($('<div>')
.css('margin-left', '5px')
.append(options)
)
.append($('<div>')
.css({
margin: '0.5em 0',
borderBottom: '1px solid #555'
})
)
.append(type !== 'comment' ? '' : $('<div>')
.css('margin-left', '5px')
.append($('<label>')
.append(addHoldInput
.css({
verticalAlign: 'middle',
marginRight: '4px'
})
.attr('type', 'checkbox')
.prop('checked', true)
)
.append($('<span>')
.css('vertical-align', 'middle')
.text('Add 7 day hold notice')
)
)
)
.append($('<div>')
.css('margin-left', '5px')
.append($('<label>')
.append(notifyUserInput
.css({
verticalAlign: 'middle',
marginRight: '4px'
})
.attr('type', 'checkbox')
.prop('checked', true)
)
.append($('<span>')
.css('vertical-align', 'middle')
.text('Notify user:')
)
)
.append(userInput
.css({
border: 'none',
borderBottom: '1px solid #555',
padding: '2px'
})
.attr('placeholder', 'User')
.val(user)
)
)
.append($('<div>')
.css('margin', '4px 0 0 -4px')
.append(actionButtons)
)
.append(
'<div style="margin-top:4px;">[' +
'<a href="https://en.wikipedia.orghttps://wikifreehand.com/en/Wikipedia:Files_for_upload/Reviewer_instructions">Reviewer instructions</a>' +
' • <a href="https://commons.wikimedia.orghttps://wikifreehand.com/en/Special:UploadWizard">Commons</a>' +
' (<a href="https://commons.wikimedia.orghttps://wikifreehand.com/en/Special:Upload">plain</a>)' +
' • <a href="' + mw.config.get('wgScript') + '?title=Wikipedia:File_Upload_Wizard&withJS=MediaWiki:FileUploadWizard.js">Local</a>' +
' (<a href="' + mw.config.get('wgScript') + '?title=Special:Upload">plain</a>)' +
' • <a href="https://en.wikipedia.orghttps://wikifreehand.com/en/User:BrandonXLF/FFUHelper">FFU Helper</a>' +
']</span>'
);
sectionElement.after(currentInterface);
}
// Add links to sections
content.find('.mw-parser-output h2').each(function() {
var heading = $(this);
if (heading.closest('.mw-heading').length)
heading = heading.closest('.mw-heading');
var editLink = heading.find('.mw-editsection a').first();
if (!editLink.length) return;
var section = /v?e?section=(T?-?\d*)/.exec(editLink.attr('href'));
if (heading.next().hasClass('mw-collapsible')) {
editLink.siblings().last().after('<span class="mw-editsection" style="background:#dfdfdf;"></span>');
return;
}
$.each({
accept: '#a0ffa0',
decline: '#ffcece',
comment: '#ededed'
}, function(type, color) {
editLink.siblings().last().after($('<span>')
.css('background', color)
.addClass('mw-editsection')
.append('[')
.append($('<a>')
.text(type)
.attr('href', '#')
.click(function(e) {
e.preventDefault();
openInterface(type, section, heading);
})
)
.append(']')
);
});
});
});
// </syntaxhighlight>