MediaWiki:FulfillEditRequest.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at MediaWiki:FulfillEditRequest. |
/**
* Script for fulfilling edit requests
*
* @revision 10:43, 14 October 2019 (UTC)
* @rev 1 (2015-01-26); rev 2 (2017-10-29)
* @author Rillke 2015, Perhelion 2018
* TODO: better user select
*/
// <nowiki>
/* eslint indent:[error,tab,{outerIIFEBody:0}] */
/* eslint-disable vars-on-top, no-alert, max-statements-per-line*/
(function ($, mw) {
'use strict';
mw.libs.commons = mw.libs.commons || {};
var conf = mw.config.get(['wgAction', 'wgTitle', 'wgNamespaceNumber']),
FER = { erTemplates: ['Edit request'] };
mw.libs.commons.fulfillEditRequest = FER = {
$adminAreas: null,
subjectAbsent: false,
erTemplates: FER.erTemplates,
regExp: null,
templatedEditRequestBox: '<code>{{<a title="Template:' + FER.erTemplates[0] + '" \
href="/wiki/Template:Edit_request">' + FER.erTemplates[0] + '</a>}}</code>',
install: function ($content) {
if (conf.wgAction !== 'view' || conf.wgNamespaceNumber % 2 !== 1)
return;
FER.$adminAreas = $content.find('.com-edit-request-admin-area');
if (!FER.$adminAreas.length)
return;
mw.loader.using(['jquery.ui'], FER.createUI);
},
getRegExp: function () {
var escRE = [];
if (FER.regExp)
return FER.regExp;
FER.erTemplates.forEach(function (txt, i) {
escRE[i] = mw.util.escapeRegExp(txt);
});
// Needs very strict because the very short "Ep" could also be an alias.
return (FER.regExp = new RegExp('^(?:' + escRE.join('|') + ') *$', 'i'));
},
queryRedirects: function (cb) {
mw.libs.commons.api.query({
action: 'query',
generator: 'backlinks',
gblfilterredir: 'redirects',
prop: 'revisions',
gblnamespace: 10,
gbltitle: 'Template:' + FER.erTemplates[0]
}, { cb: function (r) {
if ((r = r.query) && (r = r.pages)) {
for (var id in r) {
var pg = r[id];
if (pg.title)
FER.erTemplates.push(pg.title.replace('Template:', ''));
}
}
if (typeof cb === 'function')
cb();
}
// errCb: function (t, r, q) {}
});
},
evt: {
markDone: function (e) {
e.preventDefault();
var $button = $(this),
$editRequestBox = $button
.closest('.com-edit-request-admin-area'),
index = FER.$adminAreas.index($editRequestBox),
section = FER.$adminAreas.prevObject.find('.mw-headline').
siblings('.mw-editsection').find('a').prop('href')
.match(/section=(\d+)/)[1];
if (!section)
alert('Section not found!');
mw.loader.using([
'mediawiki.util',
'ext.gadget.jquery.blockUI',
'ext.gadget.libAPI',
'ext.gadget.libWikiDOM'
], function () {
$button.parent().block();
FER.queryRedirects(
function () {
FER.markDone(
new mw.Title(conf.wgTitle, conf.wgNamespaceNumber)
.getPrefixedText(),
index,
function (success) {
$button.parent().unblock();
if (success) {
// There can be more edit requests so reload is needed,
// also other fails can't be recognized
document.location.reload();
/* $editRequestBox
.closest('.com-edit-request')
.hide()
.after(FER.templatedEditRequestBox);*/
}
},
section);
});
});
},
createWith: function (/* e*/) {
var $button = $(this),
$ta = $button.data('com-fer-create-text'),
$wrap = $button.parent(),
user = FER.revisionUser($wrap.closest('.com-edit-request-admin-area')),
newText = $ta.val();
mw.loader.using([
'ext.gadget.jquery.blockUI',
'ext.gadget.libAPI',
'mediawiki.Title'
], function () {
$wrap.block();
FER.createPage(
new mw.Title(conf.wgTitle, conf.wgNamespaceNumber - 1)
.getPrefixedText(),
newText,
'Fulfilling edit request originating talk page ' +
'whose last editor is [[User:' + user + '|' + user + ']]',
function (success) {
$wrap.unblock();
if (success) {
$wrap.delay(700).fadeOut();
FER.$subjectTab.removeClass('new');
}
});
});
},
createLink: function (e) {
e.preventDefault();
var $a = $(this),
$adminArea = $a.closest('.com-edit-request-admin-area'),
user = FER.revisionUser($adminArea),
// Unsure fallback only
lastUser = $adminArea.parent().find('.com-edit-request-revision-user').eq(0).text();
// Replace unsure default link
if (user && lastUser !== user) {
$a.attr('href', function (i, v) {
lastUser = encodeURIComponent(lastUser + '|' + lastUser);
user = encodeURIComponent(user);
return v.replace(lastUser, user);
});
}
}
},
/**
* @brief Get requesting user per DOM
* @details Searches the first line with a user link and take the last.
*
* @param {node} $box $adminArea
* @return {string} username
*/
revisionUser: function ($box) {
$box = $box.parent();
/* TODO: The search is only sure if the template is before a linked user sig,
* so check also backward to a headline!?
* Better replace with revisions finder like in AQD.findTemplateAdder FER.regExp
*/
var lines = $box.nextAll(),
reUser;
$.each(lines, function (i, v) {
v = $(v);
var links = v.find('a[href^="/wiki/User"]');
if (!links[0])
return;
v = v.contents().toArray();
for (var a = links.length - 1, m; a > 0; a--) {
var c = 0;
a = links.eq(a);
m = a.attr('href');
if (!m)
continue;
m = m.match(/^\/wiki\/User(?:[ _]talk)?:([^\n]+)/);
if (m && m[1]) {
for (var t = v.length - 1, n; t > 0; t--) {
n = v[t];
if (c > 5)
break;
c++;
// Take user link if with date
if (/\d{4} \(UTC\)[^\d]*?$/.test($(n).text())) {
reUser = m[1];
reUser = /\//.test(reUser) ? reUser.split('/')[0] : reUser;
break;
}
}
if (reUser)
return false;
}
}
});
reUser = reUser || $box.find('.com-edit-request-revision-user').eq(0).text(); // fallback revisions-user
return reUser.replace('_', ' ');
},
createPage: function (title, content, summary, cb) {
mw.libs.commons.api.editPage({
title: title,
text: content,
editType: 'text',
createonly: true,
summary: summary,
cb: function () {
cb(true);
},
errCb: function (e) {
mw.log.warn(e);
alert('Page could not be created; edit failed.');
cb();
}
});
},
markDone: function (title, index, cb, section) {
mw.libs.commons.api.$changeText(title, function (content) {
var parsed = mw.libs.wikiDOM.parser.text2Obj(content),
user = decodeURI(FER.revisionUser(FER.$adminAreas.eq(index))),
replaced,
nodes = parsed.nodesByType,
ssection = '',
regExp = FER.regExp || FER.getRegExp();
$.each(nodes.template || [], function (i, erNode) {
if (regExp.test(erNode.parts[0][0])) {
// if (index-- === 0) { // Why count and only first request?
erNode.prepend('tl');
FER.addThanks(parsed, erNode);
replaced = true;
return false;
// }
}
});
if (!replaced) {
alert('Could not find edit request template.\n' +
'Please report this incident on: ' +
'[[MediaWiki:FulfillEditRequest.js]]');
return cb();
}
if (nodes.h && nodes.h[0]) {
ssection = nodes.h[0].parts[0][0];
ssection = (ssection && /(=+)(\s?[^\n]+\s?)\1/.test(ssection)) ? '/*' + RegExp.$2 + '*/ ' : '';
}
return {
text: mw.libs.wikiDOM.parser.obj2Text(parsed),
summary: ssection + 'Marking edit request as done. @' +
'[[User:' + user + '|' + user + ']]'
};
}, section).done(function () {
cb(true);
}).fail(function (e) {
mw.log.warn(e);
alert('Could not mark edit request as done; edit failed.');
cb();
});
},
addThanks: function (rootNode, erNode) {
var text = window.prompt('Confirm the reply:', '{{done}} Awesome! Thank you! ~~~~'),
foundErNode,
addToThis,
addToThisIdx;
if (!text) {
if (text === '')
return;
throw new Error('Confirm canceled');
}
text = '\n:' + text + '\n';
$.each(rootNode.parts[0], function (i, node) {
if (node === erNode)
foundErNode = true;
if (node.type === 'h' && foundErNode)
return false;
addToThis = node;
addToThisIdx = i;
});
if (typeof addToThis.after === 'function')
addToThis.after(text);
else
rootNode.parts[0][addToThisIdx] += text;
},
$getUI: function () {
var $ui = $('<div>').addClass('com-fer-main'),
$createPageWrap,
$createPageText;
$('<button>')
.text('Mark request as done')
.attr({
type: 'button',
role: 'button'
})
.button({ icons: { primary: 'ui-icon-check' } })
.addClass('com-fer-mark-done')
.on('click', FER.evt.markDone)
.appendTo($ui);
if (FER.subjectAbsent) {
$createPageWrap = $('<div>').appendTo($ui);
$createPageText = $('<textarea>')
.css({
'width': '100%',
'height': '5em',
'box-sizing': 'border-box'
})
.attr({ placeholder: 'Create page with this content ...' })
.addClass('com-fer-create-text')
.appendTo($createPageWrap);
$('<button>')
.text('Create')
.attr({
type: 'button',
role: 'button'
})
.button({ icons: { primary: 'ui-icon-document' } })
.addClass('com-fer-create-button')
.data('com-fer-create-text', $createPageText)
.on('click', FER.evt.createWith)
.appendTo($createPageWrap);
}
return $ui;
},
createUI: function () {
FER.$subjectTab = $('#p-namespaces li[id^="ca-nstab"]');
FER.subjectAbsent = FER.$subjectTab.hasClass('new');
FER.$adminAreas.each(function (i, el) {
el = $(el);
if (el.data('com-fer-enhanced'))
return;
el.append(FER.$getUI()).data('com-fer-enhanced', 1);
el.find('a.external').one('mouseover', FER.evt.createLink);
});
}
};
mw.hook('wikipage.content').add(FER.install);
}(jQuery, mediaWiki));
// </nowiki>