Разлика между версии на „МедияУики:Gadget-Quick patrol.js“
От БГ-Фантастика
(Enhance recent changes patrol.) |
(Няма разлика)
|
Текуща версия към 22:45, 15 септември 2009
/** Enhance recent changes patrol. Author: Borislav Manolov License: Public domain */ if ( window.importScript && ! window.jQuery ) { importScript("МедияУики:Gadget-jQuery.js"); } var WebRequest = { /** Get a parameter from the requested URL */ getParam: function(param) { var m = this.getRequestUrl().match( new RegExp("[?&]" + param + "=([^&#]*)") ); return null === m ? null : m[1]; }, requestUrl: null, getRequestUrl: function() { return this.requestUrl || location.href; }, setRequestUrl: function(url) { this.requestUrl = url; } }; gLang.addMessages({ "markaspatrolledtext1" : "Отбелязване на следната редакция като проверена", "markaspatrolledtext" : "Отбелязване на следните $1 редакции като проверени", "markedaspatrolledtext1": "Редакцията беше отбелязана като проверена.", "markedaspatrolledtext" : "Готово.", "showalldiffs" : "Показване на редакциите", "recentchangespage" : "Специални:Последни промени", "nchanges" : "\\d+ промени" }, "bg"); /** Ajaxify patrol links. @uses jQuery */ var QuickPattroler = { linkClassWorking: "working", enable: function() { $(".patrollink a").live("click", function(){ QuickPattroler.executePatrol(this); return false; }); }, executePatrol: function(link) { var $link = $(link).addClass( this.linkClassWorking ); $.post(link.href, function(data){ $link.replaceWith( gLang.msg("markedaspatrolledtext1") ); QuickPattroler.gotoRcIfWanted(); }); }, gotoRcIfWanted: function() { if ( window.wgxQuickPatrolLoadRc && wgxQuickPatrolLoadRc ) { location.href = Creator.createInternUrl( gLang.msg("recentchangespage") ); } } }; /** Enable bunch patrolling when multiple edits are reviewed at once thru the enhanced recent changes @uses jQuery */ var BunchPatroller = { apiPath: wgScriptPath + "/api.php", rcidsParam: "rcids", diffsParam: "diffs", paramDelim: ",", bunchDiffLinkClass: "bunch-duff-link", diffLinkClass: "duff-link", diffLinkClassDone: "done", diffLinkClassNotDone: "not-done", classLoading: "loading", /* track number of patrolled edits */ numEditsPatrolled: 0, /* error codes returned from API */ errors: [], /** Works on Special:Recentchanges */ makeBunchDiffsPatrollable: function() { $("div.mw-changeslist-hidden").each(function(){ BunchPatroller.makeBunchDiffPatrollable(this); }); }, makeBunchDiffPatrollable: function(changeslist) { var $rcidLinks = $("a[href*=rcid]", changeslist); var rcids = BunchPatroller.getJoinedValueFromHrefs($rcidLinks, /rcid=(\d+)/); if ( "" !== rcids ) { var diffs = BunchPatroller.getJoinedValueFromHrefs($rcidLinks, /diff=(\d+)/, /oldid=(\d+)/); this.enhanceBunchDiffLink($(changeslist).prev(), rcids, diffs); } }, getJoinedValueFromHrefs: function($links, regexp, regexpAlt) { return $links.map(function(){ var m = $(this).attr("href").match(regexp); if ( null === m && typeof regexpAlt == "object" ) { // test the fallback regexp m = $(this).attr("href").match(regexpAlt); } return null === m ? 0 : m[1]; }).get().join(this.paramDelim); }, /** Add extra parameters to the href attribute of the bunch diff link. If there is no diff link (by new pages) one is created. */ enhanceBunchDiffLink: function($holder, rcids, diffs) { var extraParams = "&" + BunchPatroller.rcidsParam + "=" + rcids + "&" + BunchPatroller.diffsParam + "=" + diffs; var $link = $("a[href*=diff]", $holder); if ( $link.length ) { $link.attr("href", function(){ return this.href + extraParams; }).addClass( BunchPatroller.bunchDiffLinkClass ); } else { this.addBunchDiffLinkTo( $("td:eq(1)", $holder), // second table cell diffs.split(this.paramDelim).shift(), // first id extraParams ); } }, addBunchDiffLinkTo: function($holder, diff, extraParams) { $holder.html( $holder.html().replace( new RegExp( gLang.msg("nchanges") ), '<a href="' + wgScript + "?diff=" + diff + "&oldid=" + diff + extraParams + '" class="' + BunchPatroller.bunchDiffLinkClass + '">$&</a>') ); }, /** Works on diff pages */ enable: function() { $bunchPatrolLinkHolder = $("#mw-diff-ntitle4"); if ( 0 == $bunchPatrolLinkHolder.length ) { return; // not a diff page, get out of here } var rcidsRaw = WebRequest.getParam(this.rcidsParam); if ( ! rcidsRaw ) { return; // no rcids to patrol } var rcids = rcidsRaw.split(this.paramDelim); this.addPatrolLinkTo($bunchPatrolLinkHolder, rcids); var diffs = WebRequest.getParam(this.diffsParam).split(this.paramDelim); this.addDiffLinksTo($bunchPatrolLinkHolder, rcids, diffs); this.addShowAllDiffsLinkTo($bunchPatrolLinkHolder); }, addPatrolLinkTo: function($holder, rcids) { if ( $holder.children().length ) { $holder.append("<br/>"); } $('<a href="#executePatrol"/>') .text( rcids.length == 1 ? gLang.msg("markaspatrolledtext1") : gLang.msg("markaspatrolledtext", rcids.length) ) .click(function(){ $(this).addClass( QuickPattroler.linkClassWorking ); BunchPatroller.executePatrol(rcids, this); return false; }) .appendTo($holder); }, addDiffLinksTo: function($holder, rcids, diffs) { var $list = $("<ul/>"); $.each(diffs, function(i, diff){ $list.append( BunchPatroller.getDiffLink(rcids[i], diff) ); }); $list.appendTo($holder); }, addShowAllDiffsLinkTo: function($holder) { $('<a href="#alldiffs"/>') .text( gLang.msg("showalldiffs") ) .click(function(){ $all = $('<div id="alldiffs"/>').insertAfter( $holder.parents(".diff") ); $("." + BunchPatroller.diffLinkClass, $holder).each(function(){ BunchPatroller.loadDiffContentFor(this, $all); }); $(this).remove(); }) .appendTo($holder); }, loadDiffContentFor: function(link, $holder) { var $out = $("<div/>").appendTo($holder).addClass(this.classLoading).before("<hr/>"); $.get(link.href + "&diffonly=1&action=render", function(data){ $out.html(data).removeClass( BunchPatroller.classLoading ); }); }, getDiffLink: function(rcid, diff) { return '<li><a' + ' id="' + this.getDiffLinkId(rcid) + '"' + ' class="' + this.diffLinkClass + '"' + ' href="' + wgScript + '?oldid=prev&diff=' + diff + '&rcid=' + rcid + '"' + '>' + diff +'</a></li>'; }, getDiffLinkId: function(rcid) { return "diff-link-" + rcid; }, executePatrol: function(rcids, motherLink) { var token = this.getToken(); $.each(rcids, function(i, rcid){ BunchPatroller.executePatrolOne(token, rcid); }); this.executeOnPatrolDone(function() { if ( BunchPatroller.checkForBadToken() ) { BunchPatroller.restartPatrol(rcids, motherLink); return; } $(motherLink).replaceWith( gLang.msg("markedaspatrolledtext") ); QuickPattroler.gotoRcIfWanted(); }, rcids); }, restartPatrol: function(rcids, motherLink) { this.errors = []; this.numEditsPatrolled = 0; $("." + this.diffLinkClass).removeClass(BunchPatroller.diffLinkClassNotDone); BunchPatroller.clearToken().executePatrol(rcids, motherLink); }, intervalId: 0, executeOnPatrolDone: function(callback, rcids) { this.intervalId = setInterval(function(){ if ( BunchPatroller.numEditsPatrolled >= rcids.length ) { clearInterval(BunchPatroller.intervalId); callback(); } }, 200); }, executePatrolOne: function(token, rcid) { var $diffLink = $("#" + BunchPatroller.getDiffLinkId(rcid)); $diffLink.addClass( QuickPattroler.linkClassWorking ); $.post(BunchPatroller.apiPath, { action : "patrol", token : token, rcid : rcid, format : "json" }, function(data){ $diffLink.removeClass( QuickPattroler.linkClassWorking ); if ( data.error ) { $diffLink.addClass(BunchPatroller.diffLinkClassNotDone); BunchPatroller.handleError(data.error, $diffLink); } else { $diffLink.addClass(BunchPatroller.diffLinkClassDone); } BunchPatroller.numEditsPatrolled++; }, "json"); }, handleError: function(error, $diffLink) { this.errors.push(error.code); $diffLink.attr("title", error.info); }, checkForBadToken: function() { return inArray("badtoken", this.errors); }, tokenCookie: "patrolToken", getToken: function() { var token = Cookie.read(this.tokenCookie); if ( ! token ) { token = this.getTokenFromApi(); Cookie.create(this.tokenCookie, token); } return token; }, getTokenFromApi: function() { var token = null; $.ajax({ type: "GET", url: this.apiPath + "?action=query&list=recentchanges" + "&rctoken=patrol&rclimit=1&format=json", async: false, dataType: "json", success: function(data){ token = data.query.recentchanges[0].patroltoken; } }); return token; }, clearToken: function() { Cookie.erase(this.tokenCookie); return this; } }; // prepare for fight addOnloadHook(function(){ if ( /^(Recentchanges|Watchlist)/.test(wgCanonicalSpecialPageName) ) { BunchPatroller.makeBunchDiffsPatrollable(); } else if ( "view" == wgAction ) { QuickPattroler.enable(); BunchPatroller.enable(); } });