MediaWiki:Gadget-morebits.js: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
m (1 revision)
imported>Mlpearc
m (Update)
Line 269: Line 269:
if( current.disabled ) {
if( current.disabled ) {
subnode.setAttribute( 'disabled', 'disabled' );
subnode.setAttribute( 'disabled', 'disabled' );
}
if( data.event ) {
subnode.addEventListener( 'change', data.event, false );
} else if ( current.event ) {
subnode.addEventListener( 'change', current.event, true );
}
}
label = cur_div.appendChild( document.createElement( 'label' ) );
label = cur_div.appendChild( document.createElement( 'label' ) );
Line 281: Line 276:
Morebits.quickForm.element.generateTooltip( label, current );
Morebits.quickForm.element.generateTooltip( label, current );
}
}

var event;
var event;
if( current.subgroup ) {
if( current.subgroup ) {
var tmpgroup = current.subgroup; // $.extend({}, current.subgroup); really needed?
var tmpgroup = current.subgroup;


if( ! $.isArray( tmpgroup ) ) {
if( ! $.isArray( tmpgroup ) ) {
Line 294: Line 290:
});
});
$.each( tmpgroup, function( idx, el ) {
$.each( tmpgroup, function( idx, el ) {
if( ! el.type ) {
var newEl = $.extend( {}, el );
el.type = data.type;
if( ! newEl.type ) {
newEl.type = data.type;
}
}
el.name = (current.name || data.name) + '.' + el.name;
newEl.name = (current.name || data.name) + '.' + newEl.name;
subgroupRaw.append( el );
subgroupRaw.append( newEl );
} );
} );


Line 335: Line 332:
};
};
subnode.addEventListener( 'change', event, true );
subnode.addEventListener( 'change', event, true );
}
// add users' event last, so it can interact with the subgroup
if( data.event ) {
subnode.addEventListener( 'change', data.event, false );
} else if ( current.event ) {
subnode.addEventListener( 'change', current.event, true );
}
}
}
}
Line 792: Line 795:


RegExp.escape = function( text, space_fix ) {
RegExp.escape = function( text, space_fix ) {

text = $.escapeRE(text);
text = $.escapeRE(text);


Line 1,201: Line 1,203:
'101': 'Portal talk',
'101': 'Portal talk',
'108': 'Book',
'108': 'Book',
'109': 'Book talk'
'109': 'Book talk',
'446': 'Education Program',
'447': 'Education Program talk',
'710': 'TimedText',
'711': 'TimedText talk',
'828': 'Module',
'829': 'Module talk'
};
};


Line 1,224: Line 1,232:
'101': 'Portal talk',
'101': 'Portal talk',
'108': 'Book',
'108': 'Book',
'109': 'Book talk'
'109': 'Book talk',
'446': 'Education Program',
'447': 'Education Program talk',
'710': 'TimedText',
'711': 'TimedText talk',
'828': 'Module',
'829': 'Module talk'
};
};


Line 1,236: Line 1,250:
Morebits.wiki = {};
Morebits.wiki = {};


// Analyzes the HTML of the current page (i.e. no AJAX requests) to determine if it
// Determines whether the current page is a redirect or soft redirect
// (fails to detect soft redirects on edit, history, etc. pages)
// is a redirect or soft redirect
Morebits.wiki.isPageRedirect = function wikipediaIsPageRedirect() {
Morebits.wiki.isPageRedirect = function wikipediaIsPageRedirect() {
return !!($("span.redirectText").length > 0 || document.getElementById("softredirect"));
return !!(mw.config.get("wgIsRedirect") || document.getElementById("softredirect"));
};
};


Line 1,574: Line 1,588:
*
*
* getCreator(): returns the user who created the page following lookupCreator()
* getCreator(): returns the user who created the page following lookupCreator()
*
* getCurrentID(): returns a string containing the current revision ID of the page
*
*
* patrol(): marks the page as patrolled, if possible
* patrol(): marks the page as patrolled, if possible
Line 1,666: Line 1,682:
revertUser: null,
revertUser: null,
fullyProtected: false,
fullyProtected: false,
suppressProtectWarning: false,
conflictRetries: 0,
conflictRetries: 0,
retries: 0,
retries: 0,
Line 1,767: Line 1,784:
this.setOldID = function(oldID) {
this.setOldID = function(oldID) {
ctx.revertOldID = oldID;
ctx.revertOldID = oldID;
};

this.getCurrentID = function() {
return ctx.revertCurID;
};
};


Line 1,835: Line 1,856:
ctx.watchlistOption = 'nochange';
ctx.watchlistOption = 'nochange';
}
}
};

this.suppressProtectWarning = function() {
ctx.suppressProtectWarning = true;
};
};


Line 1,899: Line 1,924:
}
}


if (ctx.fullyProtected && !confirm('You are about to make an edit to the fully protected page "' + ctx.pageName +
if (ctx.fullyProtected && !ctx.suppressProtectWarning &&
!confirm('You are about to make an edit to the fully protected page "' + ctx.pageName +
(ctx.fullyProtected === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + ctx.fullyProtected + ')')) +
(ctx.fullyProtected === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + ctx.fullyProtected + ')')) +
'. \n\nClick OK to proceed with the edit, or Cancel to skip this edit.')) {
'. \n\nClick OK to proceed with the edit, or Cancel to skip this edit.')) {
Line 2,223: Line 2,249:


ctx.editToken = $(xml).find('page').attr('edittoken');
ctx.editToken = $(xml).find('page').attr('edittoken');
if (!ctx.editToken)
if (!ctx.editToken) {
{
ctx.statusElement.error("Failed to retrieve edit token.");
ctx.statusElement.error("Failed to retrieve edit token.");
ctx.onLoadFailure(this);
ctx.onLoadFailure(this);
Line 2,230: Line 2,255:
}
}
ctx.loadTime = $(xml).find('page').attr('starttimestamp');
ctx.loadTime = $(xml).find('page').attr('starttimestamp');
if (!ctx.loadTime)
if (!ctx.loadTime) {
{
ctx.statusElement.error("Failed to retrieve start timestamp.");
ctx.statusElement.error("Failed to retrieve start timestamp.");
ctx.onLoadFailure(this);
ctx.onLoadFailure(this);
Line 2,237: Line 2,261:
}
}
ctx.lastEditTime = $(xml).find('page').attr('touched');
ctx.lastEditTime = $(xml).find('page').attr('touched');
ctx.revertCurID = $(xml).find('page').attr('lastrevid');


if (ctx.editMode === 'revert') {
if (ctx.editMode === 'revert') {
Line 2,321: Line 2,346:


// errors here are only generated by extensions which hook APIEditBeforeSave within MediaWiki
// errors here are only generated by extensions which hook APIEditBeforeSave within MediaWiki
// Wikimedia wikis should only return spam blacklist errors and captchas
// Wikimedia wikis should only return spam blacklist errors, captchas, and AbuseFilter messages
var blacklist = $(xml).find('edit').attr('spamblacklist');
var $editNode = $(xml).find('edit');
var blacklist = $editNode.attr('spamblacklist');


if (blacklist) {
if (blacklist) {
Line 2,329: Line 2,355:
code.appendChild(document.createTextNode(blacklist));
code.appendChild(document.createTextNode(blacklist));
ctx.statusElement.error(['Could not save the page because the URL ', code, ' is on the spam blacklist.']);
ctx.statusElement.error(['Could not save the page because the URL ', code, ' is on the spam blacklist.']);
} else if ( $(xml).find('captcha').length > 0 ) {
}
else if ( $(xml).find('captcha').length > 0 ) {
ctx.statusElement.error("Could not save the page because the wiki server wanted you to fill out a CAPTCHA.");
ctx.statusElement.error("Could not save the page because the wiki server wanted you to fill out a CAPTCHA.");
} else if ( $editNode.attr('code') === 'abusefilter-disallowed' ) {
}
ctx.statusElement.error('The edit was disallowed by the edit filter rule "' + $editNode.attr('info').substring(17) + '".');
else {
} else if ( $editNode.attr('info').indexOf('Hit AbuseFilter:') === 0 ) {
var div = document.createElement('div');
div.className = "toccolours";
div.style.fontWeight = "normal";
div.style.color = "black";
div.innerHTML = $editNode.attr('warning');
ctx.statusElement.error([ 'The following warning was returned by the edit filter: ', div, 'If you wish to proceed with the edit, please carry it out again. This warning wil not appear a second time.' ]);
// XXX provide the user with a way to automatically retry the action if they so choose -
// I can't see how to do this without creating a UI dependency on Morebits.wiki.page though -- TTO
} else {
ctx.statusElement.error("Unknown error received from API while saving page");
ctx.statusElement.error("Unknown error received from API while saving page");
}
}
Line 2,424: Line 2,459:
if (Morebits.userIsInGroup('sysop')) {
if (Morebits.userIsInGroup('sysop')) {
var editprot = $(xml).find('pr[type="edit"]');
var editprot = $(xml).find('pr[type="edit"]');
if (editprot.length > 0 && editprot.attr('level') === 'sysop' && !confirm('You are about to move the fully protected page "' + ctx.pageName +
if (editprot.length > 0 && editprot.attr('level') === 'sysop' && !ctx.suppressProtectWarning &&
!confirm('You are about to move the fully protected page "' + ctx.pageName +
(editprot.attr('expiry') === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + editprot.attr('expiry') + ')')) +
(editprot.attr('expiry') === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + editprot.attr('expiry') + ')')) +
'. \n\nClick OK to proceed with the move, or Cancel to skip this move.')) {
'. \n\nClick OK to proceed with the move, or Cancel to skip this move.')) {
Line 2,476: Line 2,512:
// extract protection info
// extract protection info
var editprot = $(xml).find('pr[type="edit"]');
var editprot = $(xml).find('pr[type="edit"]');
if (editprot.length > 0 && editprot.attr('level') === 'sysop' && !confirm('You are about to delete the fully protected page "' + ctx.pageName +
if (editprot.length > 0 && editprot.attr('level') === 'sysop' && !ctx.suppressProtectWarning &&
!confirm('You are about to delete the fully protected page "' + ctx.pageName +
(editprot.attr('expiry') === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + editprot.attr('expiry') + ')')) +
(editprot.attr('expiry') === 'infinity' ? '" (protected indefinitely)' : ('" (protection expiring ' + editprot.attr('expiry') + ')')) +
'. \n\nClick OK to proceed with the deletion, or Cancel to skip this deletion.')) {
'. \n\nClick OK to proceed with the deletion, or Cancel to skip this deletion.')) {
Line 2,792: Line 2,829:
removeLink: function( link_target ) {
removeLink: function( link_target ) {
var first_char = link_target.substr( 0, 1 );
var first_char = link_target.substr( 0, 1 );
var link_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( link_target.substr( 1 ), true );
var link_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( link_target.substr( 1 ), true );
var link_simple_re = new RegExp( "\\[\\[:?(" + link_re_string + ")\\]\\]", 'g' );
var link_simple_re = new RegExp( "\\[\\[:?(" + link_re_string + ")\\]\\]", 'g' );
var link_named_re = new RegExp( "\\[\\[:?" + link_re_string + "\\|(.+?)\\]\\]", 'g' );
var link_named_re = new RegExp( "\\[\\[:?" + link_re_string + "\\|(.+?)\\]\\]", 'g' );
Line 2,803: Line 2,840:
reason = reason ? (reason + ': ') : '';
reason = reason ? (reason + ': ') : '';
var first_char = image.substr( 0, 1 );
var first_char = image.substr( 0, 1 );
var image_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( image.substr( 1 ), true );
var image_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( image.substr( 1 ), true );


/*
/*
Line 2,862: Line 2,899:
removeTemplate: function( template ) {
removeTemplate: function( template ) {
var first_char = template.substr( 0, 1 );
var first_char = template.substr( 0, 1 );
var template_re_string = "(?:[Tt]emplate:)?\\s*[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( template.substr( 1 ), true );
var template_re_string = "(?:[Tt]emplate:)?\\s*[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( template.substr( 1 ), true );
var links_re = new RegExp( "\\{\\{" + template_re_string );
var links_re = new RegExp( "\\{\\{" + template_re_string );
var allTemplates = Morebits.array.uniq(Morebits.string.splitWeightedByKeys( this.text, '{{', '}}', [ '{{{', '}}}' ] ));
var allTemplates = Morebits.array.uniq(Morebits.string.splitWeightedByKeys( this.text, '{{', '}}', [ '{{{', '}}}' ] ));