MediaWiki:Gadget-autodel.js
外观
提示:保存后,修改可能不会立即生效,点击此处以了解如何绕过浏览器的缓存。
- Mozilla/Firefox/Safari:按住Shift键的同时点击“Reload”,或按下Ctrl-Shift-R(苹果 Mac 上为Cmd-Shift-R);
- Internet Explorer:按住Ctrl键的同时点击“Refresh”,或按下Ctrl-F5;
- Konqueror:直接点击“Reload”按钮,或按下F5;
- Opera用户可能需要在工具 → 首选项中彻底清除缓存。
/**
* Replacement for the old [[MediaWiki:Gadget-autodel.js]] that is now on [[User:Mike.lifeguard/Gadget-autodel.js]]
* Eases deletion of pages
* Documentation at [[Help:Gadget-autodel.js]]
*
* @rev 1 (2012-07-02)
* @author Rillke, 2012
*/
// List the global variables for jsHint-Validation. Please make sure that it passes https://jshint.node.org.cn/
// Scheme: globalVariable:allowOverwriting[, globalVariable:allowOverwriting][, globalVariable:allowOverwriting]
/*global jQuery:false, mediaWiki:false*/
// Set jsHint-options. You should not set forin or undef to false if your script does not validate.
/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, curly:false, browser:true*/
( function ( $, mw ) {
"use strict";
var autoDel = null,
server = mw.config.get('wgServer'),
articlePath = mw.config.get('wgArticlePath');
if ( (-1 === $.inArray(mw.config.get('wgCanonicalSpecialPageName'), ['Contributions', 'Whatlinkshere', 'Log', 'Prefixindex', 'Newpages'])) &&
(!mw.config.get('wgArticleId') || -1 === $.inArray(mw.config.get('wgAction'), ['submit', 'view', 'edit', 'delete'])) ) return;
mw.util.addCSS('.autodel-dellink { background-color:#CEEDB4; font-size:.8em; position:relative; top:-0.5em; }');
autoDel = {
aDelInstall: function() {
var p = mw.util.addPortletLink('p-cactions', '#', 'Add DeleteLinks', 'ca-dellink', 'generate deletion links');
if (p) {
p = $(p);
} else {
return;
}
p.click(function(e) {
e.preventDefault();
autoDel.tasks = ['aDelQueryDefaultReason', 'aDelAddDelLinks'];
autoDel.nextTask();
});
if ('delete' === mw.config.get('wgAction') && mw.util.getParamValue('submitdelete')) {
$('#mw-content-text').prepend($('<p>').addClass('error').text(
"Either you are using an old version of autoDel or you opened a link in a new tab. " +
"Deletion via URL is evil and therefore not done. " +
"If you are using the latest version of autoDel, simply click the delete link. " +
"An in-page-dialog will be opened. You can submit deletion immediately pressing the enter-key. " +
"While it makes your account vulnerable, you can skip this dialog adding "
), $('<code>', { text: 'window.skipAutodelConfirm = true;' }),
$('<a>', { text: " to your common.js", href: 'Special:MyPage/common.js' }),
$('<p>').addClass('error').text(
"If you decided to add it to your js, be careful where you are clicking and double-check the tool tips."
));
}
// Providing functionality for {{Instant-nuke}}
// Additional safeguard: only run on the delinker-command-page or those the user wants it
window.autodelPages = $.extend({'User:CommonsDelinker/commands': true}, window.autodelPages);
if (!window.autodelPages[mw.config.get('wgPageName')]) return;
var $ins = $('.instant-nuke').css('display', 'inline-block').attr('title', 'Invoke immediate deletion');
$ins.each(function(i, el) {
try {
var $el = $(el),
h = $el.find('a:first').attr('href'),
pg_ = mw.util.getParamValue('title', h),
pg = pg_.replace(/_/g, ' '),
r = mw.util.getParamValue('wpReason', h),
bt = $el.find('.selToBlock').text(),
$b = $el.parents(bt),
// WikiUrlencode does too much, same for encodeURIComponent
$ol = $b.find('a[href$="' + encodeURI(pg_).replace(/\'/g, '%27').replace(/\"/g, '%22') + '"]');
$el.data('autoDel', { page: pg, $parent: $b, $oLink: $ol, reason: r });
if (!autoDel.aDelPages[pg]) autoDel.aDelPages[pg] = [];
autoDel.aDelPages[pg].push($el);
$(el).find('a').attr('title', 'Delete ' + pg);
$el.click(autoDel.__aDelConfirmDelete);
} catch (ex) {}
});
},
aDelQueryDefaultReason: function() {
var c = mw.cookie.get('com-autodel-reason');
this.reason = c || 'per [[COM:SPEEDY]]';
this.prompt([{
message: 'default reason',
prefill: this.reason,
returnvalue: 'reason',
cleanUp: true,
noEmpty: true,
byteLimit: 250,
parseReason: true
}], "Adding links: Set the default reason.");
},
aDelAddDelLinks: function() {
if (this.delLinksAdded) return;
var tryDecode = function(title) {
try {
// MediaWiki also encodes "=" even if not required (not a query string)
if (title) title = decodeURIComponent(title);
return title;
} catch(ex2) {
try {
if (title) title = decodeURI(title);
} catch (ex) {}
return title;
}
};
var tryDecodeComponent = function(title) {
try {
if (title) title = decodeURIComponent(title);
} catch (ex) {}
return title;
};
var addLink = function(pg, $el) {
if (!pg) return;
if (0 === pg.indexOf(mw.config.get('wgFormattedNamespaces')[-1])) return;
pg = pg.replace(/_/g, ' ');
var $dLink = $('<a>', { 'class': 'autodel-dellink', href: '#', text: 'Delete!', title: 'Delete ' + pg });
$el.wrap('<span>').after($dLink);
$dLink.data('autoDel', { page: pg, $parent: $el.parent(), $oLink: $el });
$dLink.click(autoDel.__aDelConfirmDelete);
if (!autoDel.aDelPages[pg]) autoDel.aDelPages[pg] = [];
autoDel.aDelPages[pg].push($dLink);
return true;
};
$('#mw-content-text').find('a').each(function(i, el) {
var $el = $(el),
h = $el.attr('href'),
pg, REArticle, m;
if ($el.hasClass('new')) return;
pg = mw.util.getParamValue('title', h);
if (addLink(tryDecodeComponent(pg), $el)) return;
REArticle = new RegExp('^' + mw.RegExp.escape(articlePath.replace('$1', '')) + '(.+?)(?:#.*)?$');
m = h.match(REArticle);
if (m) if (addLink(tryDecode(m[1]), $el)) return;
REArticle = new RegExp(mw.RegExp.escape(server + articlePath.replace('$1', '')) + '(.+?)(?:#.*)?$');
m = h.match(REArticle);
if (m) if (addLink(tryDecode(m[1]), $el)) return;
});
this.delLinksAdded = true;
// Finally save the reason into a cookie
mw.cookie.set('com-autodel-reason', this.reason, {
expires: 14, // expires in 14 days
path: '/' // domain-wide, entire wiki
});
},
__aDelConfirmDelete: function(e) {
e.preventDefault();
e.stopPropagation();
var $dLink = $(this),
d = $dLink.data('autoDel'),
$toRemove = $dLink,
$toBlock = d.$parent,
$toSetNew = d.$oLink;
// Add all links with the same target page
$.each(autoDel.aDelPages[d.page], function(i, el) {
var $el = $(el),
di = $el.data('autoDel');
if (!di) return;
$toRemove = $toRemove.add($el);
$toBlock = $toBlock.add(di.$parent);
$toSetNew = $toSetNew.add(di.$oLink);
});
var wasValidLink = !!$dLink.inView().length && (/[Dd]elete/.test($dLink.text()) || /\/16px-Gr%C3%BCnerm%C3%BClleimer\.svg\.png$/.test($dLink.find('img').attr('src')) && $dLink.find('img').inView().length );
// The last param is the check whether the delete-link was probably faked
autoDel.secureCall('aDelConfirmDelete', d.page, $toRemove, $toBlock, $toSetNew, d.reason, wasValidLink);
},
aDelFillInfoNode: function(page, $node) {
var query, isFile = (0 === page.indexOf(mw.config.get('wgFormattedNamespaces')[6]));
if (isFile) {
query = {
action: 'query',
prop: 'imageinfo|info',
intoken: 'delete',
iiprop: 'user|timestamp|url',
iiurlwidth: 250,
iiurlheight: 250,
iilimit: 1,
titles: page
};
} else {
query = {
action: 'query',
prop: 'info|revisions',
rvprop: 'user|timestamp',
rvlimit: 1,
rvdir: 'newer',
intoken: 'delete',
titles: page
};
}
this.queryAPI(query, function(r) {
var pgs = r.query.pages,
rv,
type = "page",
pg;
$.each(pgs, function(i, pgObj) {
pg = pgObj;
});
autoDel.deletetoken = pg.deletetoken;
$node.append($('<div>').append(
$('<span>').text("You are going to delete "),
$('<a>', { href: mw.util.getUrl(pg.title), text: pg.title }),
$('<span>').text(" (" + pg.length + " Bytes, PageID: " + pg.pageid + ", Changed: " + pg.touched + ").")
));
if ('undefined' !== typeof pg.missing) return $('.ui-dialog').find('.ui-button-green').button('option', 'disabled', true);
if (isFile) {
if (!pg.imageinfo) return;
rv = pg.imageinfo[0];
type = "file";
$node.append($('<img>', { src: rv.thumburl, height: rv.height, width: rv.width }));
} else {
if (!pg.revisions) return;
rv = pg.revisions[0];
}
$node.append($('<div>').text("This " + type + " was created by " + rv.user + " on " + rv.timestamp ));
});
},
aDelConfirmDelete: function(page, $dLink, $toBlock, $toSetNew, reason, wasValidLink) {
var $infoNode = $('<div>', { css: { 'min-height': '300px' } });
this.tasks = ['aDelExecDelete'];
this.pageToDelete = page;
this.$toRemove = $dLink;
this.$toBlock = $toBlock;
this.$toSetNew = $toSetNew;
// WARNING: SETTING THIS IN YOUR common.js WILL IMMEDIATELY DELETE ON CLICK
// Always watch the tooltip to prevent accidental wrong deletions
// You are responsible if you delete the world!
if (window.skipAutodelConfirm && wasValidLink) {
if (reason) this.reason = reason;
return this.nextTask();
}
this.secureCall('aDelFillInfoNode', page, $infoNode);
this.prompt([{
message: 'Delete reason (used in the deletion log)',
prefill: reason || this.reason,
returnvalue: 'reason',
cleanUp: true,
appendNode: $infoNode,
noEmpty: true,
byteLimit: 250,
parseReason: true
}], "WARNING: You are going to DELETE " + page);
},
aDelExecDelete: function() {
var $toRemove = this.$toRemove,
$toBlock = this.$toBlock,
$toSetNew = this.$toSetNew,
pg = autoDel.pageToDelete;
$toBlock.block({ message: 'Deleting', css: { color: '#A0C828', fontWeight: 'bold', background:'none', border:'none', width: '8em' } });
if (autoDel.deletetoken) mw.user.tokens.set('deleteToken', autoDel.deletetoken);
mw.loader.using(['ext.gadget.libAPI'], function() {
mw.libs.commons.api.deletePage({
cb: function() {
autoDel.secureCall('aDelExecDeleteCB', $toBlock, $toSetNew, $toRemove, pg);
},
// r-result, query, text
errCb: function(t, r, q) {
if (r && r.error && r.error.code === 'missingtitle') {
$toBlock.block({ message: 'Not found!', css: { color: '#C8A028', fontWeight: 'bold', background:'none', border:'none', width: '10em' } });
$toBlock.unblock( { fadeOut: 5000 } );
} else {
$toBlock.unblock();
autoDel.fail(t);
}
},
title: pg,
reason: autoDel.reason
});
//console.log(pg); autoDel.aDelExecDeleteCB()
});
},
aDelExecDeleteCB: function($toBlock, $toSetNew, $toRemove, pg) {
$toBlock.unblock();
$toSetNew.addClass('new');
if ($toSetNew.hasClass('image')) $toSetNew.find('img').fadeTo(500, 0.5);
$toRemove.remove();
delete this.aDelPages[pg];
},
aDelPages: {}
};
mw.loader.using([
'ext.gadget.jquery.blockUI',
'ext.gadget.AjaxQuickDelete',
'ext.gadget.jquery.in-view',
'mediawiki.util',
'mediawiki.user',
'mediawiki.cookie',
'user'
], function() {
// Merge into AjaxQuickDelete
autoDel = $.extend(window.AjaxQuickDelete, autoDel);
// Fire off the rest as soon as the dom is ready
$( document ).ready( function() { autoDel.secureCall('aDelInstall'); } );
});
}( jQuery, mediaWiki ));