Anonymous user
MediaWiki:Gadget-morebits.js: Difference between revisions
v2.0-737-g19690a8: batchdel: Single-request actions; morebits: wgRestrictionEdit applies to current page, single-request delete/append/prepend; speedy, image, xfd, tag: Prevent warning oneself; batchdel, batchundel: Tweak; speedy: Tweak reason, tweak
imported>Amalthea (v2.0-728-g051bc0c: unlink: checkboxes have shift-click support; morebits: function to give a set of checkboxes shift-click support) |
(v2.0-737-g19690a8: batchdel: Single-request actions; morebits: wgRestrictionEdit applies to current page, single-request delete/append/prepend; speedy, image, xfd, tag: Prevent warning oneself; batchdel, batchundel: Tweak; speedy: Tweak reason, tweak) |
||
Line 341:
// styles go on the label, doesn't make sense to style a checkbox/radio
if( current.style ) {
}
Line 1,973:
ctx.onSaveFailure = onFailure || emptyFunction;
// are we getting our edit token from mw.user.tokens?
var canUseMwUserToken = fnCanUseMwUserToken('edit');
if (!ctx.pageLoaded && !canUseMwUserToken) {
ctx.statusElement.error("Internal error: attempt to save a page that has not been loaded!");
ctx.onSaveFailure(this);
Line 1,984 ⟶ 1,987:
}
// shouldn't happen if canUseMwUserToken === true
if (ctx.fullyProtected && !ctx.suppressProtectWarning &&
!confirm('You are about to make an edit to the fully protected page "' + ctx.pageName +
Line 1,999 ⟶ 2,003:
title: ctx.pageName,
summary: ctx.editSummary,
token: canUseMwUserToken ? mw.user.tokens.get('editToken') : ctx.editToken,
watchlist: ctx.watchlistOption
};
Line 2,045 ⟶ 2,049:
if (['recreate', 'createonly', 'nocreate'].indexOf(ctx.createOption) !== -1) {
query[ctx.createOption] = '';
}
if (canUseMwUserToken && ctx.followRedirect) {
query.redirect = true;
}
Line 2,054 ⟶ 2,062:
this.append = function(onSuccess, onFailure) {
ctx.editMode = 'append';
if (fnCanUseMwUserToken('edit')) {
this.
} else {
ctx.onSaveSuccess = onSuccess;
ctx.onSaveFailure = onFailure || emptyFunction;
this.load(fnAutoSave, ctx.onSaveFailure);
}
};
this.prepend = function(onSuccess, onFailure) {
ctx.editMode = 'prepend';
if (fnCanUseMwUserToken('edit')) {
this.
} else {
ctx.onSaveSuccess = onSuccess;
ctx.onSaveFailure = onFailure || emptyFunction;
this.load(fnAutoSave, ctx.onSaveFailure);
}
};
Line 2,180 ⟶ 2,198:
}
if (fnCanUseMwUserToken('delete')) {
fnProcessDelete();
} else {
var query = {
inprop: 'protection',
intoken: 'delete',
titles: ctx.pageName
};
if (ctx.followRedirect) {
query.redirects = ''; // follow all redirects
}
ctx.deleteApi = new Morebits.wiki.api("retrieving delete token...", query, fnProcessDelete, ctx.statusElement, ctx.onDeleteFailure);
ctx.deleteApi.setParent(this);
ctx.deleteApi.post();
}
};
Line 2,217 ⟶ 2,239:
}
// because of the way MW API interprets protection levels (absolute, not
// differential), we need to request protection levels from the server
var query = {
action: 'query',
Line 2,273 ⟶ 2,297:
};
/* Private member functions
*
* These are not exposed outside
*/
/**
* Determines whether we can save an API call by using the edit token sent with the page
* HTML, or whether we need to ask the server for more info (e.g. protection expiry).
*
* Currently only used for append, prepend, and deletePage.
*
* @param {string} action The action being undertaken, e.g. "edit", "delete".
*/
var fnCanUseMwUserToken = function(action) {
// API-based redirect resolution only works for action=query and
// action=edit in append/prepend modes (and section=new, but we don't
// really support that)
if (ctx.followRedirect && (action !== 'edit' ||
(ctx.editMode !== 'append' && ctx.editMode !== 'prepend'))) {
return false;
}
// do we need to fetch the edit protection expiry?
if (Morebits.userIsInGroup('sysop') && !ctx.suppressProtectWarning) {
// poor man's normalisation
if (Morebits.string.toUpperCaseFirstChar(mw.config.get('wgPageName')).replace(/ /g, '_').trim() !==
Morebits.string.toUpperCaseFirstChar(ctx.pageName).replace(/ /g, '_').trim()) {
return false;
}
var editRestriction = mw.config.get('wgRestrictionEdit');
if (!editRestriction || editRestriction.indexOf('sysop') !== -1) {
return false;
}
}
return !!mw.user.tokens.get('editToken');
};
// callback from loadSuccess() for append() and prepend() threads
Line 2,459 ⟶ 2,516:
ctx.statusElement.info("Edit conflict detected, reapplying edit");
if (fnCanUseMwUserToken('edit')) {
ctx.saveApi.post(); // necessarily append or prepend, so this should work as desired
} else {
ctx.loadApi.post(); // reload the page and reapply the edit
}
// check for loss of edit token
Line 2,467 ⟶ 2,528:
ctx.statusElement.info("Edit token is invalid, retrying");
--Morebits.wiki.numberOfActionsLeft; // allow for normal completion if retry succeeds
if (fnCanUseMwUserToken('edit')) {
this.load(fnAutoSave, ctx.onSaveFailure); // try the append or prepend again
} else {
ctx.loadApi.post(); // reload the page and reapply the edit
}
// check for network or server error
Line 2,563 ⟶ 2,628:
var fnProcessDelete = function() {
var pageTitle, token;
if (
token = mw.user.tokens.get('editToken');
pageTitle = ctx.pageName;
} else {
var xml = ctx.deleteApi.getXML();
if ($(xml).find('page').attr('missing') === "") {
ctx.statusElement.error("Cannot delete the page, because it no longer exists");
ctx.onDeleteFailure(this);
return;
}
// extract protection info
var editprot = $(xml).find('pr[type="edit"]');
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') + ')')) +
'. \n\nClick OK to proceed with the deletion, or Cancel to skip this deletion.')) {
ctx.statusElement.error("Deletion of fully protected page was aborted.");
ctx.onDeleteFailure(this);
return;
}
token = $(xml).find('page').attr('deletetoken');
if (!token) {
ctx.statusElement.error("Failed to retrieve delete token.");
ctx.onDeleteFailure(this);
return;
}
pageTitle = $(xml).find('page').attr('title');
}
var query = {
'action': 'delete',
'title':
'token':
'reason': ctx.editSummary
};
Line 2,616 ⟶ 2,690:
ctx.deleteProcessApi.post(); // give it another go!
} else if ( errorCode === "missingtitle" ) {
ctx.statusElement.error("Cannot delete the page, because it no longer exists");
if (ctx.onDeleteFailure) {
ctx.onDeleteFailure.call(this, ctx.deleteProcessApi); // invoke callback
}
// hard error, give up
} else {
|