MediaWiki:Gadget-twinkleprotect.js: Difference between revisions

Jump to navigation Jump to search
m (1 revision imported)
 
m (1 revision imported)
 
(One intermediate revision by the same user not shown)
Line 26: Line 26:


Twinkle.protect.callback = function twinkleprotectCallback() {
Twinkle.protect.callback = function twinkleprotectCallback() {
Twinkle.protect.protectionLevel = null;
var Window = new Morebits.simpleWindow( 620, 530 );
var Window = new Morebits.simpleWindow( 620, 530 );
Window.setTitle( Morebits.userIsInGroup( 'sysop' ) ? "Apply, request or tag page protection" : "Request or tag page protection" );
Window.setTitle( Morebits.userIsInGroup( 'sysop' ) ? "Apply, request or tag page protection" : "Request or tag page protection" );
Line 89: Line 87:
evt.initEvent( 'change', true, true );
evt.initEvent( 'change', true, true );
result.actiontype[0].dispatchEvent( evt );
result.actiontype[0].dispatchEvent( evt );
Morebits.wiki.actionCompleted.postfix = false;  // avoid Action: completed notice


// get current protection level asynchronously
// get current protection level asynchronously
if (Morebits.userIsInGroup('sysop')) {
Morebits.wiki.actionCompleted.postfix = false;  // avoid Action: completed notice
Morebits.status.init($('div[name="currentprot"] span').last()[0]);
}
Twinkle.protect.fetchProtectionLevel();
Twinkle.protect.fetchProtectionLevel();
};
};


// Current protection level in a human-readable format
// (a string, or null if no protection; only filled for sysops)
Twinkle.protect.protectionLevel = null;
// Contains the current protection level in an object
// Contains the current protection level in an object
// Once filled, it will look something like:
// Once filled, it will look something like:
Line 109: Line 102:


var api = new mw.Api();
var api = new mw.Api();
api.get({
var protectDeferred = api.get({
format: 'json',
format: 'json',
indexpageids: true,
indexpageids: true,
action: 'query',
action: 'query',
list: 'logevents',
letype: 'protect',
letitle: mw.config.get('wgPageName'),
prop: 'info|flagged',
prop: 'info|flagged',
inprop: 'protection',
inprop: 'protection',
titles: mw.config.get('wgPageName')
titles: mw.config.get('wgPageName')
})
});
.done(function(data){
var stableDeferred = api.get({
var pageid = data.query.pageids[0];
format: 'json',
var page = data.query.pages[pageid];
action: 'query',
var result = [];
list: 'logevents',
letype: 'stable',
letitle: mw.config.get('wgPageName')
});
 
$.when.apply($, [protectDeferred, stableDeferred]).done(function(protectData, stableData){
var pageid = protectData[0].query.pageids[0];
var page = protectData[0].query.pages[pageid];
var current = {};
var current = {};
var updateResult = function(label, level, expiry, cascade) {
// for sysops, stringify, so they can base their decision on existing protection
if (Morebits.userIsInGroup('sysop')) {
var boldnode = document.createElement('b');
boldnode.textContent = label + ": " + level;
result.push(boldnode);
if (expiry === 'infinity') {
result.push(" (indefinite) ");
} else {
result.push(" (expires " + new Date(expiry).toUTCString() + ") ");
}
if (cascade) {
result.push("(cascading) ");
}
}
};


$.each(page.protection, function( index, protection ) {
$.each(page.protection, function( index, protection ) {
Line 147: Line 133:
cascade: protection.cascade === ''
cascade: protection.cascade === ''
};
};
updateResult( Morebits.string.toUpperCaseFirstChar(protection.type), protection.level, protection.expiry, protection.cascade );
}
}
});
});
Line 156: Line 141:
expiry: page.flagged.protection_expiry
expiry: page.flagged.protection_expiry
};
};
// FlaggedRevision gives bad date
updateResult( 'Pending Changes', page.flagged.protection_level, page.flagged.protection_expiry, false );
}
}


// show the protection level to sysops
// show the protection level and log info
if (Morebits.userIsInGroup('sysop')) {
Twinkle.protect.hasProtectLog = !!protectData[0].query.logevents.length;
if (!result.length) {
Twinkle.protect.hasStableLog = !!stableData[0].query.logevents.length;
var boldnode = document.createElement('b');
Twinkle.protect.currentProtectionLevels = current;
boldnode.textContent = "no protection";
Twinkle.protect.callback.showLogAndCurrentProtectInfo();
result.push(boldnode);
});
};
 
Twinkle.protect.callback.showLogAndCurrentProtectInfo = function twinkleprotectCallbackShowLogAndCurrentProtectInfo() {
var currentlyProtected = !$.isEmptyObject(Twinkle.protect.currentProtectionLevels);
 
if (Twinkle.protect.hasProtectLog || Twinkle.protect.hasStableLog) {
var $linkMarkup = $("<span>");
 
if (Twinkle.protect.hasProtectLog)
$linkMarkup.append(
$( '<a target="_blank" href="' + mw.util.getUrl('Special:Log', {action: 'view', page: mw.config.get('wgPageName'), type: 'protect'}) + '">protection log</a>' ),
Twinkle.protect.hasStableLog ? $("<span> &bull; </span>") : null
);
if (Twinkle.protect.hasStableLog)
$linkMarkup.append($( '<a target="_blank" href="' + mw.util.getUrl('Special:Log', {action: 'view', page: mw.config.get('wgPageName'), type: 'stable'}) + '">pending changes log</a>)' ));
 
Morebits.status.init($('div[name="hasprotectlog"] span')[0]);
Morebits.status.warn(
currentlyProtected ? 'Previous protections' : 'This page has been protected in the past',
$linkMarkup[0]
);
}
 
Morebits.status.init($('div[name="currentprot"] span')[0]);
var protectionNode = [], statusLevel = 'info';
 
if (currentlyProtected) {
$.each(Twinkle.protect.currentProtectionLevels, function(type, settings) {
var label = type === 'stabilize' ? 'Pending Changes' : Morebits.string.toUpperCaseFirstChar(type);
protectionNode.push($("<b>" + label + ": " + settings.level + "</b>")[0]);
if (settings.expiry === 'infinity') {
protectionNode.push(" (indefinite) ");
} else {
protectionNode.push(" (expires " + new Date(settings.expiry).toUTCString() + ") ");
}
if (settings.cascade) {
protectionNode.push("(cascading) ");
}
}
Twinkle.protect.protectionLevel = result;
});
Morebits.status.init($('div[name="currentprot"] span').last()[0]);
statusLevel = 'warn';
Morebits.status.info("Current protection level", Twinkle.protect.protectionLevel);
} else {
}
protectionNode.push($("<b>no protection</b>")[0]);
}


Twinkle.protect.currentProtectionLevels = current;
Morebits.status[statusLevel]("Current protection level", protectionNode);
});
};
};


Line 199: Line 219:
field2 = new Morebits.quickForm.element({ type: 'field', label: 'Protection options', name: 'field2' });
field2 = new Morebits.quickForm.element({ type: 'field', label: 'Protection options', name: 'field2' });
field2.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
field2.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
field2.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
// for existing pages
// for existing pages
if (mw.config.get('wgArticleId')) {
if (mw.config.get('wgArticleId')) {
Line 229: Line 250:
label: 'Autoconfirmed',
label: 'Autoconfirmed',
value: 'autoconfirmed'
value: 'autoconfirmed'
});
editlevel.append({
type: 'option',
label: 'Extended confirmed',
value: 'extendedconfirmed'
});
});
if (isTemplate) {
if (isTemplate) {
Line 252: Line 278:
}
}
},
},
// default expiry selection is conditionally set in Twinkle.protect.callback.changePreset
list: [
list: [
{ label: '1 hour', value: '1 hour' },
{ label: '1 hour', value: '1 hour' },
Line 259: Line 286:
{ label: '12 hours', value: '12 hours' },
{ label: '12 hours', value: '12 hours' },
{ label: '1 day', value: '1 day' },
{ label: '1 day', value: '1 day' },
{ label: '2 days', selected: true, value: '2 days' },
{ label: '2 days', value: '2 days' },
{ label: '3 days', value: '3 days' },
{ label: '3 days', value: '3 days' },
{ label: '4 days', value: '4 days' },
{ label: '4 days', value: '4 days' },
Line 300: Line 327:
label: 'Autoconfirmed',
label: 'Autoconfirmed',
value: 'autoconfirmed'
value: 'autoconfirmed'
});
movelevel.append({
type: 'option',
label: 'Extended confirmed',
value: 'extendedconfirmed'
});
});
if (isTemplate) {
if (isTemplate) {
Line 323: Line 355:
}
}
},
},
// default expiry selection is conditionally set in Twinkle.protect.callback.changePreset
list: [
list: [
{ label: '1 hour', value: '1 hour' },
{ label: '1 hour', value: '1 hour' },
Line 339: Line 372:
{ label: '3 months', value: '3 months' },
{ label: '3 months', value: '3 months' },
{ label: '1 year', value: '1 year' },
{ label: '1 year', value: '1 year' },
{ label: 'indefinite', selected: true, value:'indefinite' },
{ label: 'indefinite', value: 'indefinite' },
{ label: 'Custom...', value: 'custom' }
{ label: 'Custom...', value: 'custom' }
]
]
Line 369: Line 402:
pclevel.append({
pclevel.append({
type: 'option',
type: 'option',
label: 'Level 1',
label: 'Pending changes',
value: 'autoconfirmed',
value: 'autoconfirmed',
selected: true
selected: true
});
pclevel.append({
type: 'option',
label: 'Level 2 (do not use)',
value: 'review'
});
});
field2.append({
field2.append({
Line 431: Line 459:
});
});
}
}
createlevel.append({
type: 'option',
label: 'Extended confirmed',
value: 'extendedconfirmed',
selected: true
});
createlevel.append({
createlevel.append({
type: 'option',
type: 'option',
label: 'Sysop',
label: 'Sysop',
value: 'sysop',
value: 'sysop'
selected: true
});
});
field2.append({
field2.append({
Line 478: Line 511:
case 'tag':
case 'tag':
field1 = new Morebits.quickForm.element({ type: 'field', label: 'Tagging options', name: 'field1' });
field1 = new Morebits.quickForm.element({ type: 'field', label: 'Tagging options', name: 'field1' });
field1.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
field1.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
field1.append( {
field1.append( {
type: 'select',
type: 'select',
Line 515: Line 550:


field1 = new Morebits.quickForm.element({ type: 'field', label: 'Options', name: 'field1' });
field1 = new Morebits.quickForm.element({ type: 'field', label: 'Options', name: 'field1' });
field1.append({ type: 'div', name: 'currentprot', label: ' ' });  // holds the current protection level, as filled out by the async callback
field1.append({ type: 'div', name: 'hasprotectlog', label: ' ' });
field1.append( {
field1.append( {
type: 'select',
type: 'select',
Line 537: Line 574:


var oldfield;
var oldfield;
if (field_preset) {
if (field_preset) {
oldfield = $(e.target.form).find('fieldset[name="field_preset"]')[0];
oldfield = $(e.target.form).find('fieldset[name="field_preset"]')[0];
Line 561: Line 599:
evt.initEvent( 'change', true, true );
evt.initEvent( 'change', true, true );
e.target.form.category.dispatchEvent( evt );
e.target.form.category.dispatchEvent( evt );
// re-add protection level text, if it's available
if (Twinkle.protect.protectionLevel) {
Morebits.status.init($('div[name="currentprot"] span').last()[0]);
Morebits.status.info("Current protection level", Twinkle.protect.protectionLevel);
}


// reduce vertical height of dialog
// reduce vertical height of dialog
$(e.target.form).find('fieldset[name="field2"] select').parent().css({ display: 'inline-block', marginRight: '0.5em' });
$(e.target.form).find('fieldset[name="field2"] select').parent().css({ display: 'inline-block', marginRight: '0.5em' });
}
}
// re-add protection level and log info, if it's available
Twinkle.protect.callback.showLogAndCurrentProtectInfo();
};
};


Line 583: Line 618:
},
},
movemodify: function twinkleprotectFormMovemodifyEvent(e) {
movemodify: function twinkleprotectFormMovemodifyEvent(e) {
// sync move settings with edit settings if applicable
if (e.target.form.movelevel.disabled && !e.target.form.editlevel.disabled) {
e.target.form.movelevel.value = e.target.form.editlevel.value;
e.target.form.moveexpiry.value = e.target.form.editexpiry.value;
} else if (e.target.form.editlevel.disabled) {
e.target.form.movelevel.value = 'sysop';
e.target.form.moveexpiry.value = 'indefinite';
}
e.target.form.movelevel.disabled = !e.target.checked;
e.target.form.movelevel.disabled = !e.target.checked;
e.target.form.moveexpiry.disabled = !e.target.checked || (e.target.form.movelevel.value === 'all');
e.target.form.moveexpiry.disabled = !e.target.checked || (e.target.form.movelevel.value === 'all');
Line 634: Line 677:
list: [
list: [
{ label: 'Highly visible template (TE)', value: 'pp-template' }
{ label: 'Highly visible template (TE)', value: 'pp-template' }
]
},
{
label: 'Extended confirmed protection',
list: [
{ label: 'Arbitration enforcement (ECP)', selected: true, value: 'pp-30-500-arb' },
{ label: 'Persistent vandalism (ECP)', value: 'pp-30-500-vandalism' },
{ label: 'Disruptive editing (ECP)', value: 'pp-30-500-disruptive' },
{ label: 'BLP policy violations (ECP)', value: 'pp-30-500-blp' },
{ label: 'Sockpuppetry (ECP)', value: 'pp-30-500-sock' }
]
]
},
},
Line 653: Line 706:
{ label: 'Generic (PC)', value: 'pp-pc-protected' },
{ label: 'Generic (PC)', value: 'pp-pc-protected' },
{ label: 'Persistent vandalism (PC)', value: 'pp-pc-vandalism' },
{ label: 'Persistent vandalism (PC)', value: 'pp-pc-vandalism' },
{ label: 'Disruptive editing (PC)', value: 'pp-pc-disruptive' },
{ label: 'Adding unsourced content (PC)', value: 'pp-pc-unsourced' },
{ label: 'BLP policy violations (PC)', value: 'pp-pc-blp' }
{ label: 'BLP policy violations (PC)', value: 'pp-pc-blp' }
]
]
Line 681: Line 736:


// A page with both regular and PC protection will be assigned its regular
// A page with both regular and PC protection will be assigned its regular
// protection weight plus 2 (for PC1) or 7 (for PC2)
// protection weight plus 2
Twinkle.protect.protectionWeight = {
Twinkle.protect.protectionWeight = {
sysop: 30,
sysop: 40,
templateeditor: 20,
templateeditor: 30,
flaggedrevs_review: 15, // Pending Changes level 2 protection alone
extendedconfirmed: 20,
autoconfirmed: 10,
autoconfirmed: 10,
flaggedrevs_autoconfirmed: 5,  // Pending Changes level 1 protection alone
flaggedrevs_autoconfirmed: 5,  // Pending Changes protection alone
all: 0,
all: 0,
flaggedrevs_none: 0  // just in case
flaggedrevs_none: 0  // just in case
Line 719: Line 774:
move: 'templateeditor',
move: 'templateeditor',
reason: '[[WP:High-risk templates|Highly visible template]]'
reason: '[[WP:High-risk templates|Highly visible template]]'
},
'pp-30-500-arb': {
edit: 'extendedconfirmed',
move: 'extendedconfirmed',
reason: '[[WP:30/500|Arbitration enforcement]]',
template: 'pp-30-500'
},
'pp-30-500-vandalism': {
edit: 'extendedconfirmed',
move: 'extendedconfirmed',
reason: 'Persistent [[WP:Vandalism|vandalism]] from (auto)confirmed accounts',
template: 'pp-30-500'
},
'pp-30-500-disruptive': {
edit: 'extendedconfirmed',
move: 'extendedconfirmed',
reason: 'Persistent [[WP:Disruptive editing|disruptive editing]] from (auto)confirmed accounts',
template: 'pp-30-500'
},
'pp-30-500-blp': {
edit: 'extendedconfirmed',
move: 'extendedconfirmed',
reason: 'Persistent violations of the [[WP:BLP|biographies of living persons policy]] from (auto)confirmed accounts',
template: 'pp-30-500'
},
'pp-30-500-sock': {
edit: 'extendedconfirmed',
move: 'extendedconfirmed',
reason: 'Persistent [[WP:Sock puppetry|sock puppetry]]',
template: 'pp-30-500'
},
},
'pp-semi-vandalism': {
'pp-semi-vandalism': {
Line 742: Line 827:
'pp-semi-usertalk': {
'pp-semi-usertalk': {
edit: 'autoconfirmed',
edit: 'autoconfirmed',
move: 'sysop',
move: 'autoconfirmed',
reason: '[[WP:PP#Talk-page protection|Inappropriate use of user talk page while blocked]]',
reason: '[[WP:PP#Talk-page protection|Inappropriate use of user talk page while blocked]]',
template: 'pp-usertalk'
template: 'pp-usertalk'
Line 748: Line 833:
'pp-semi-template': {  // removed for now
'pp-semi-template': {  // removed for now
edit: 'autoconfirmed',
edit: 'autoconfirmed',
move: 'sysop',
move: 'autoconfirmed',
reason: '[[WP:High-risk templates|Highly visible template]]',
reason: '[[WP:High-risk templates|Highly visible template]]',
template: 'pp-template'
template: 'pp-template'
Line 765: Line 850:
stabilize: 'autoconfirmed',  // stabilize = Pending Changes
stabilize: 'autoconfirmed',  // stabilize = Pending Changes
reason: 'Persistent [[WP:Vandalism|vandalism]]',
reason: 'Persistent [[WP:Vandalism|vandalism]]',
template: 'pp-pc1'
template: 'pp-pc'
},
'pp-pc-disruptive': {
stabilize: 'autoconfirmed',
reason: 'Persistent [[WP:Disruptive editing|disruptive editing]]',
template: 'pp-pc'
},
'pp-pc-unsourced': {
stabilize: 'autoconfirmed',
reason: 'Persistent addition of [[WP:INTREF|unsourced or poorly sourced content]]',
template: 'pp-pc'
},
},
'pp-pc-blp': {
'pp-pc-blp': {
stabilize: 'autoconfirmed',
stabilize: 'autoconfirmed',
reason: 'Violations of the [[WP:BLP|biographies of living persons policy]]',
reason: 'Violations of the [[WP:BLP|biographies of living persons policy]]',
template: 'pp-pc1'
template: 'pp-pc'
},
},
'pp-pc-protected': {
'pp-pc-protected': {
stabilize: 'autoconfirmed',
stabilize: 'autoconfirmed',
reason: null,
reason: null,
template: 'pp-pc1'
template: 'pp-pc'
},
},
'pp-move': {
'pp-move': {
Line 806: Line 901:
},
},
'pp-create-salt': {
'pp-create-salt': {
create: 'sysop',
create: 'extendedconfirmed',
reason: '[[WP:SALT|Repeatedly recreated]]'
reason: '[[WP:SALT|Repeatedly recreated]]'
},
},
'pp-create-blp': {
'pp-create-blp': {
create: 'sysop',
create: 'extendedconfirmed',
reason: '[[WP:BLPDEL|Recently deleted BLP]]'
reason: '[[WP:BLPDEL|Recently deleted BLP]]'
},
},
'pp-create': {
'pp-create': {
create: 'sysop',
create: 'extendedconfirmed',
reason: '{{pp-create}}'
reason: '{{pp-create}}'
}
}
Line 838: Line 933:
{ label: '{{pp-usertalk}}: blocked user talk', value: 'pp-usertalk' },
{ label: '{{pp-usertalk}}: blocked user talk', value: 'pp-usertalk' },
{ label: '{{pp-protected}}: general protection', value: 'pp-protected' },
{ label: '{{pp-protected}}: general protection', value: 'pp-protected' },
{ label: '{{pp-semi-indef}}: general long-term semi-protection', value: 'pp-semi-indef' }
{ label: '{{pp-semi-indef}}: general long-term semi-protection', value: 'pp-semi-indef' },
{ label: '{{pp-30-500}}: extended confirmed protection', value: 'pp-30-500' }
]
]
},
},
Line 844: Line 940:
label: 'Pending changes templates',
label: 'Pending changes templates',
list: [
list: [
{ label: '{{pp-pc1}}: pending changes level 1', value: 'pp-pc1' }
{ label: '{{pp-pc}}: pending changes', value: 'pp-pc' }
]
]
},
},
Line 874: Line 970:
if (actiontype === 'protect') {  // actually protecting the page
if (actiontype === 'protect') {  // actually protecting the page
var item = Twinkle.protect.protectionPresetsInfo[form.category.value];
var item = Twinkle.protect.protectionPresetsInfo[form.category.value];
if (mw.config.get('wgArticleId')) {
if (mw.config.get('wgArticleId')) {
if (item.edit) {
if (item.edit) {
Line 880: Line 977:
form.editlevel.value = item.edit;
form.editlevel.value = item.edit;
Twinkle.protect.formevents.editlevel({ target: form.editlevel });
Twinkle.protect.formevents.editlevel({ target: form.editlevel });
form.editexpiry.value = '2 days';
} else {
} else {
form.editmodify.checked = false;
form.editmodify.checked = false;
Line 890: Line 988:
form.movelevel.value = item.move;
form.movelevel.value = item.move;
Twinkle.protect.formevents.movelevel({ target: form.movelevel });
Twinkle.protect.formevents.movelevel({ target: form.movelevel });
form.moveexpiry.value = '2 days';
} else {
} else {
form.movemodify.checked = false;
form.movemodify.checked = false;
Line 930: Line 1,029:
form.noinclude.checked = true;
form.noinclude.checked = true;
form.editexpiry.value = form.moveexpiry.value = form.pcexpiry.value = "indefinite";
form.editexpiry.value = form.moveexpiry.value = form.pcexpiry.value = "indefinite";
} else {
} else if( mw.config.get('wgNamespaceNumber') !== 10 ) {
form.noinclude.checked = false;
form.noinclude.checked = false;
}
}
Line 940: Line 1,039:
form.expiry.disabled = true;
form.expiry.disabled = true;
} else {
} else {
form.expiry.value = '';
form.expiry.disabled = false;
form.expiry.disabled = false;
}
}
Line 964: Line 1,064:
tag: form.tagtype.value,
tag: form.tagtype.value,
reason: ((form.tagtype.value === 'pp-protected' || form.tagtype.value === 'pp-semi-protected' || form.tagtype.value === 'pp-move') && form.protectReason) ? form.protectReason.value : null,
reason: ((form.tagtype.value === 'pp-protected' || form.tagtype.value === 'pp-semi-protected' || form.tagtype.value === 'pp-move') && form.protectReason) ? form.protectReason.value : null,
expiry: (actiontype === 'protect') ?
(form.editmodify.checked ? form.editexpiry.value :
(form.movemodify.checked ? form.moveexpiry.value :
(form.pcmodify.checked ? form.pcexpiry.value : null)
)
) : null,
small: form.small.checked,
small: form.small.checked,
noinclude: form.noinclude.checked
noinclude: form.noinclude.checked
Line 978: Line 1,072:
case 'protect':
case 'protect':
// protect the page
// protect the page
Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
Morebits.wiki.actionCompleted.redirect = mw.config.get('wgPageName');
Morebits.wiki.actionCompleted.notice = "Protection complete";
Morebits.wiki.actionCompleted.notice = "Protection complete";
Line 994: Line 1,087:
};
};


var stabilizeValues = {
var stabilizeValues = {};
pclevel: form.pclevel.value,
if (form.pclevel) {
pcexpiry: form.pcexpiry.value,
stabilizeValues = {
protectReason: form.protectReason.value
pclevel: form.pclevel.value,
};
pcexpiry: form.pcexpiry.value,
protectReason: form.protectReason.value
};
}


var protectIt = function twinkleprotectCallbackProtectIt(next) {
var protectIt = function twinkleprotectCallbackProtectIt(next) {
Line 1,083: Line 1,179:


case 'request':
case 'request':
// file request at RPP
// file request at RFPP
var typename, typereason;
var typename, typereason;
switch( form.category.value ) {
switch( form.category.value ) {
Line 1,094: Line 1,190:
case 'pp-template':
case 'pp-template':
typename = 'template protection';
typename = 'template protection';
break;
case 'pp-30-500-arb':
case 'pp-30-500-vandalism':
case 'pp-30-500-disruptive':
case 'pp-30-500-blp':
case 'pp-30-500-sock':
typename = 'extended confirmed';
break;
break;
case 'pp-semi-vandalism':
case 'pp-semi-vandalism':
Line 1,107: Line 1,210:
case 'pp-pc-blp':
case 'pp-pc-blp':
case 'pp-pc-protected':
case 'pp-pc-protected':
case 'pp-pc-unsourced':
case 'pp-pc-disruptive':
typename = 'pending changes';
typename = 'pending changes';
break;
break;
Line 1,134: Line 1,239:
case 'pp-semi-vandalism':
case 'pp-semi-vandalism':
case 'pp-pc-vandalism':
case 'pp-pc-vandalism':
typereason = 'Persistent vandalism';
case 'pp-30-500-vandalism':
typereason = 'Persistent [[WP:VAND|vandalism]]';
break;
break;
case 'pp-semi-disruptive':
case 'pp-semi-disruptive':
case 'pp-pc-disruptive':
case 'pp-30-500-disruptive':
typereason = 'Persistent [[Wikipedia:Disruptive editing|disruptive editing]]';
typereason = 'Persistent [[Wikipedia:Disruptive editing|disruptive editing]]';
break;
break;
case 'pp-semi-unsourced':
case 'pp-semi-unsourced':
case 'pp-pc-unsourced':
typereason = 'Persistent addition of [[WP:INTREF|unsourced or poorly sourced content]]';
typereason = 'Persistent addition of [[WP:INTREF|unsourced or poorly sourced content]]';
break;
break;
case 'pp-template':
case 'pp-template':
typereason = 'Highly visible template';
typereason = '[[WP:HIGHRISK|High-risk template]]';
break;
case 'pp-30-500-arb':
typereason = '[[WP:30/500|Arbitration enforcement]]';
break;
break;
case 'pp-usertalk':
case 'pp-usertalk':
Line 1,150: Line 1,262:
break;
break;
case 'pp-semi-sock':
case 'pp-semi-sock':
typereason = 'Persistent sockpuppetry';
case 'pp-30-500-sock':
typereason = 'Persistent [[WP:SOCK|sockpuppetry]]';
break;
break;
case 'pp-semi-blp':
case 'pp-semi-blp':
case 'pp-pc-blp':
case 'pp-pc-blp':
case 'pp-30-500-blp':
typereason = '[[WP:BLP|BLP]] policy violations';
typereason = '[[WP:BLP|BLP]] policy violations';
break;
break;
Line 1,245: Line 1,359:
if( params.reason ) {
if( params.reason ) {
tag += '|reason=' + params.reason;
tag += '|reason=' + params.reason;
}
if( ['indefinite', 'infinite', 'never', null].indexOf(params.expiry) === -1 ) {
tag += '|expiry={{subst:#time:j F Y|' + (/^\s*\d+\s*$/.exec(params.expiry) ? params.expiry : '+' + params.expiry) + '}}';
}
}
if( params.small ) {
if( params.small ) {
Line 1,257: Line 1,368:
summary = 'Removing protection template' + Twinkle.getPref('summaryAd');
summary = 'Removing protection template' + Twinkle.getPref('summaryAd');
} else {
} else {
if( params.noinclude ) {
if( Morebits.wiki.isPageRedirect() ) {
//Only tag if no {{rcat shell}} is found
if (!text.match(/{{(?:redr|this is a redirect|r(?:edirect)?(?:.?cat.*)?[ _]?sh)/i)) {
text = text.replace(/#REDIRECT ?(\[\[.*?\]\])(.*)/i, "#REDIRECT $1$2\n\n{{" + tag + "}}");
} else {
Morebits.status.info("Redirect category shell present", "nothing to do");
return;
}
} else if( params.noinclude ) {
text = "<noinclude>{{" + tag + "}}</noinclude>" + text;
text = "<noinclude>{{" + tag + "}}</noinclude>" + text;
} else if( Morebits.wiki.isPageRedirect() ) {
text = text + "\n{{" + tag + "}}";
} else {
} else {
text = "{{" + tag + "}}\n" + text;
text = "{{" + tag + "}}\n" + text;
Line 1,280: Line 1,397:
var statusElement = rppPage.getStatusElement();
var statusElement = rppPage.getStatusElement();


// TODO Remove me once RPP moves to its new format
var rppRe = new RegExp( '===\\s*(\\[\\[)?\\s*:?\\s*' + RegExp.escape( Morebits.pageNameNorm, true ) + '\\s*(\\]\\])?\\s*===', 'm' );
var ns2tag = {
'0': 'la',
'1': 'lat',
'2': 'lu',
'3': 'lut',
'4': 'lw',
'5': 'lwt',
'6': 'lf',
'7': 'lft',
'8': 'lm',
'9': 'lmt',
'10': 'lt',
'11': 'ltt',
'12': 'lh',
'13': 'lht',
'14': 'lc',
'15': 'lct',
'100': 'lp',
'101': 'lpt',
'108': 'lb',
'109': 'lbt',
'118': 'ld',
'119': 'ldt',
'710': 'lttxt',
'711': 'lttxtt',
'828': 'lmd',
'829': 'lmdt'
};
 
// TODO Remove me once RPP moves to its new format
var linkTemplate = ns2tag[ mw.config.get('wgNamespaceNumber') ];
// support other namespaces like TimedText
// (this could support talk spaces better, but doesn't seem worth it)
if (!linkTemplate) {
linkTemplate = 'ln|' + Morebits.pageNameNorm.substring(0, Morebits.pageNameNorm.indexOf(':'));
}
 
// TODO Remove both "=?" and the linkTemplate bit when RPP moves to its new format
var rppRe = new RegExp( '====?\\s*((\\[\\[)?\s*:?\s*' + RegExp.escape( Morebits.pageNameNorm, true ) + '\s*(\\]\\])?|\\{\\{\\s*' +
linkTemplate + '\\s*\\|\\s*' + RegExp.escape( mw.config.get('wgTitle'), true ) + '\\s*\\}\\})\\s*====?', 'm' );
var tag = rppRe.exec( text );
var tag = rppRe.exec( text );


Line 1,337: Line 1,414:
return;
return;
}
}
newtag += '* {{pagelinks|' + Morebits.pageNameNorm + '}}\n\n';
newtag += '* {{pagelinks|1=' + Morebits.pageNameNorm + '}}\n\n';


var words;
var words;
Line 1,369: Line 1,446:
if (stabilizeLevel.level === "autoconfirmed") {
if (stabilizeLevel.level === "autoconfirmed") {
result += 2;
result += 2;
} else if (stabilizeLevel.level === "review") {
result += 7;
}
}
} else {
} else {
Line 1,394: Line 1,469:
var reg;
var reg;
if ( increase ) {
if ( increase ) {
reg = /(\n==\s*Current requests for increase in protection level\s*==\s*\n\s*\{\{[^\}\}]+\}\}\s*\n)([\s\S]*?)\s*(\n==[^=])/;
reg = /(\n==\s*Current requests for reduction in protection level\s*==)/;
} else {
} else {
reg = /(\n==\s*Current requests for reduction in protection level\s*==\s*\n\s*\{\{[^\}\}]+\}\}\s*\n)([\s\S]*?)\s*(\n==[^=])/;
reg = /(\n==\s*Current requests for edits to a protected page\s*==)/;
}
}
var originalTextLength = text.length;
var originalTextLength = text.length;
text = text.replace( reg, "$1$2\n\n" + newtag + "\n$3");
text = text.replace( reg, "\n" + newtag + "\n$1");
if (text.length === originalTextLength)
if (text.length === originalTextLength)
{
{
Line 1,409: Line 1,485:
}
}
statusElement.status( 'Adding new request...' );
statusElement.status( 'Adding new request...' );
rppPage.setEditSummary( "Requesting " + params.typename + (params.typename === "pending changes" ? ' on [[' : ' of [[') +
rppPage.setEditSummary( "Requesting " + params.typename + (params.typename === "pending changes" ? ' on [[:' : ' of [[:') +
Morebits.pageNameNorm + ']].' + Twinkle.getPref('summaryAd') );
Morebits.pageNameNorm + ']].' + Twinkle.getPref('summaryAd') );
rppPage.setPageText( text );
rppPage.setPageText( text );