Użytkownik:Expert3222/quickPatrol.js: Różnice pomiędzy wersjami

Z Nondanych
(na razie kopia)
 
m
 
(Nie pokazano 97 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 2: Linia 2:
* gadżet do szybkiego oznaczania wersji jako sprawdzonych na OZ, nowych stronach i widoku diffów
* gadżet do szybkiego oznaczania wersji jako sprawdzonych na OZ, nowych stronach i widoku diffów
* autor: Expert3222
* autor: Expert3222
* drobne modyfikacje: Ostrzyciel
* drobne modyfikacje, backend: Ostrzyciel
*/
*/


mw.loader.load('/wiki/Użytkownik:Expert3222/patrolModule.js?action=raw&ctype=text/javascript');
// TODO: $(this) na $this (do zmiennej), lepsza wydajność będzie


var patrolSuccessCode = "<span style='color: green;' class='patrolButtonClicked'><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;zrobione</span>";
var QuickPatrolLastClick = 0; //https://stackoverflow.com/questions/28609994/javascript-prevent-function-from-executing-multiple-times
var patrolFailureCode = "<span style='color: red;' class='patrolButtonClicked'><img src='https://nonsa.pl/images/a/a8/Przeciw.svg.png' width='15px' height='15px' />&nbsp;błąd</span>";
var QuickPatrolDelay = 20; //syfiło w logach, rejestrując patrolowanie po kilka razy
var tryAgainText = "spróbuj ponownie";
var QuickPatrolToken = null;
var QuickPatrolDiffPageRevids = [];
var spinnerCode = "<div class='mw-spinner mw-spinner-small mw-spinner-inline' title='...'></div>";

//fix dla
//https://nonsa.pl/wiki/Plik:Patrolowe_czworaczki.jpg
var makePatrolLinksIsExecuting = false;
var makeDiffViewRevidsListIsExecuting = false;
var makeFilePatrolLinkCallCount = 0;


$(document).ready(function()
$(document).ready(function()
{
{
mw.loader.using(["jquery.spinner", "mediawiki.notification"], function()
if (mw.config.get("wgCanonicalSpecialPageName") === "Recentchanges")
{
{
if (mw.config.get("wgCanonicalSpecialPageName") === "Recentchanges")
makePatrolLinks();
if (!!$('.mw-rcfilters-enabled').length) //wzięte od Polskacafe z gadżetu RollWithReason
{
{
setInterval(makePatrolLinks, 2000);
makePatrolLinks();
if (!!$('.mw-rcfilters-enabled').length) //wzięte od Polskacafe z gadżetu RollWithReason
{
setInterval(makePatrolLinks, 2000);
}
}
}
else if (mw.config.get("wgCanonicalSpecialPageName") == "Newpages")
}
else if (mw.config.get("wgCanonicalSpecialPageName") == "Newpages")
{
makeNewpagesPatrolLinks();
}
else if (mw.util.getParamValue("diff") !== null)
{
var parse = function()
{
{
var $buttons = $(".patrollink-page a");
var oldid = mw.util.getParamValue("oldid", $("#mw-diff-otitle1 > strong > a").attr("href"));
$buttons.click(function()
//alert("oldid = " + oldid);
{
var curid = mw.util.getParamValue("oldid", $("#mw-diff-ntitle1 > strong > a").attr("href"));
processPagePatrol($(this).parent());
//alert("curid = " + curid);
});
}
else if (mw.util.getParamValue("diff") !== null)
{
makeDiffPagePatrolLinks();
setInterval(makeDiffPagePatrolLinks, 2000); //"przeglądaj historię interaktywnie" na górze
var title = mw.config.get("wgPageName").replace("_", " ");
}
else if ($(".patrollink").length > 0) //footer
{
$(".patrollink-page a").off("click").click(function(event) //remove default click handler and attach our own
{
event.preventDefault();
event.stopImmediatePropagation();
processPagePatrol($(this).parent());
});
}
else if (mw.config.get("wgCanonicalSpecialPageName") == "MobileDiff")
{
//TODO
/*var oldid = mw.util.getParamValue("oldid", $("#mw-mf-diff-info a").attr("href"));
//console.log(oldid, curid, title);
makeDiffViewRevidsList(oldid, curid, title);
alert("oldid = " + oldid);
var urlArray = window.location.href.split("/");
};
var curid = urlArray[urlArray.length - 1];
parse();
alert("curid = " + curid);
setInterval(parse, 2000); //"przeglądaj historię interaktywnie" na górze
var title = $("#mw-mf-diff-info a").text();
}
makeDiffViewRevidsList(oldid, curid, title);*/
else if (mw.config.get("wgCanonicalSpecialPageName") == "MobileDiff")
}
{
});
//TODO
/*var oldid = mw.util.getParamValue("oldid", $("#mw-mf-diff-info a").attr("href"));
alert("oldid = " + oldid);
var urlArray = window.location.href.split("/");
var curid = urlArray[urlArray.length - 1];
alert("curid = " + curid);
var title = $("#mw-mf-diff-info a").text();
makeDiffViewRevidsList(oldid, curid, title);*/
}
});
});


function makePatrolLinks()
function makePatrolLinks()
{
{
$(".patrollink-range a").each(function()
if (makePatrolLinksIsExecuting)
{
{
var $link = $(this);
return;
if (!isEventBound($link))
}
makePatrolLinksIsExecuting = true;
//podstawowa logika: mamy liczbę zaplanowanych wywołań AJAX i liczbę zakończonych. Chcemy zaznaczyć, że funkcja skończyła się wykonywać, gdy obie wartości będą równe.
//ale czysto teoretycznie może dojść do sytuacji, w której liczba zaplanowanych zapytań nie będzie tą finalną, a obie będą równe.
//dlatego sprawdzamy tylko wtedy, gdy kontrola doszła do końca funkcji (czyli wiemy finalnie, ile AJAX-ów będzie)
var AJAXCallsCompleted = 0;
var reachedEndOfFunction = false;
function handleEndOfAJAXCall()
{
++AJAXCallsCompleted;
if (AJAXCallsCompleted == makeFilePatrolLinkCallCount && reachedEndOfFunction)
{
makePatrolLinksIsExecuting = false;
makeFilePatrolLinkCallCount = 0;
}
}
//pojedyncze zmiany i pojedyncze przesłania pliku
$("table.mw-changeslist-reviewstatus-unpatrolled").each(function()
{
if ($(this).find(".patrolButton").length === 0 && $(this).find(".patrolButtonClicked").length === 0) //jeśli nie ma buttona i nie został wcześniej użyty
{
{
var $tbody = getParentTag($link, "tbody");
if (typeof $(this).attr("data-mw-logaction") == "undefined") //zmiana
$link.on("click", function()
{
{
processMultipleChangeRCPatrol($tbody);
$(this).find(".mw-changeslist-links:not(.mw-usertoollinks)").append("<span class='patrolButton' title='Oznacz tę zmianę jako sprawdzoną' data-diff='" + $(this).attr("data-mw-revid") + "'><a>patrol</a></span>");
}
});
else //przesłanie pliku
{
var extraAttributes =
{
"data-mw-logid": $(this).attr("data-mw-logid"),
"data-mw-ts": $(this).attr("data-mw-ts")
};
var overwritten = ($(this).attr("data-mw-logaction") == "upload/upload") ? false : true;
makeFilePatrolLink($(this), overwritten, extraAttributes).always(handleEndOfAJAXCall);
}
}
}
});
});


$(".patrollink-single a").each(function()
//wielokrotne zmiany, które można rozwijać i zwijać + przesłane pliki, też wielokrotne
$("tr.mw-enhanced-rc.mw-changeslist-reviewstatus-unpatrolled").each(function()
{
{
var $button = $(this);
if ($(this).find(".patrolButton").length === 0 && $(this).find(".patrolButtonClicked").length === 0)
if (!isEventBound($button))
{
{
$button.on("click", function()
var found = $(this).find(".mw-changeslist-diff");
if (found.length > 0) //jest link w "poprz", czyli strona nie została utworzona w tej edycji
{
$(found).after(" • <span class='patrolButton' title='Oznacz tę zmianę jako sprawdzoną' data-diff='" + $(this).attr("data-mw-revid") + "'><a>patrol</a></span>");
}
else if (typeof $(this).attr("data-mw-logaction") == "undefined") //strony stworzone w tej edycji
{
$(this).html($(this).html().replace("•&nbsp;poprz.", "•&nbsp;poprz. • <span class='patrolButton' title='Oznacz tę zmianę jako sprawdzoną' data-diff='" + $(this).attr("data-mw-revid") + "'><a>patrol</a></span>"));
}
else if ($(this).attr("data-mw-logaction") == "upload/upload") //przesłane pliki
{
var extraAttributes =
{
"data-mw-logid": $(this).attr("data-mw-logid"),
"data-mw-ts": $(this).attr("data-mw-ts")
};
makeFilePatrolLink($(this), false, extraAttributes).always(handleEndOfAJAXCall);
}
else if ($(this).attr("data-mw-logaction") == "upload/overwrite") //nadpisane pliki
{
var extraAttributes =
{
"data-mw-logid": $(this).attr("data-mw-logid"),
"data-mw-ts": $(this).attr("data-mw-ts")
};
makeFilePatrolLink($(this), true, extraAttributes).always(handleEndOfAJAXCall);
}
}
});
//link do patrolowania wszystkich zmian danej strony
$("table.mw-collapsible > tbody").each(function()
{
var lines = $(this).find("tr");
var firstLine = $(lines).first();
if (lines.length >= 2 && $(firstLine).hasClass("mw-changeslist-reviewstatus-unpatrolled") &&
$(firstLine).find(".multiplePatrolButton").length === 0 && $(firstLine).find(".multiplePatrolButtonClicked").length === 0)
{
$(firstLine).find("span.mw-changeslist-links > span:nth-child(2)").after("<span class='multiplePatrolButton' title='Oznacz zmiany tej strony jako sprawdzone'><a>patroluj tę stronę</a></span>");
$(firstLine).find(".multiplePatrolButton").on("click", function()
{
{
patrolMultipleChanges($(lines).parent());
processRCChangePatrol($(this).parent(), true);
});
});
}
}
});
});

$(".patrolButton").on("click", function()
{
patrolChange($(this).attr("data-diff"), false, false);
});
if (makeFilePatrolLinkCallCount === 0 || AJAXCallsCompleted == makeFilePatrolLinkCallCount)
{
makePatrolLinksIsExecuting = false;
makeFilePatrolLinkCallCount = 0;
}
reachedEndOfFunction = true;
}
}


//helper function to process multiple change RC patrol, including spinner etc.
function makeFilePatrolLink(elem, overwritten, extraAttributes)
function processMultipleChangeRCPatrol($tbody)
{
{
var $button = $tbody.find(".patrollink-range"),
//console.log(elem);
$patrolLink = $button.find("a"),
++makeFilePatrolLinkCallCount;
$singlePatrolLinks = $tbody.find(".patrollink-single a"),
/*console.log(makeFilePatrolLinkCallCount);
$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
console.dir(elem[0]);*/
$patrolAgainBrackets = $patrolLink.parent().find(".patrolAgainBracket");
$patrolLink.hide();
var api = new mw.Api(),
$patrolAgainBrackets.hide();
fileName = $(elem).find(".mw-changeslist-log-entry > a:not(.mw-userlink)").attr("title"),
$patrolLink.after($spinner);
deferred = $.Deferred();
$patrolLink.parent().find(".patrolButtonClicked").remove();
patrolModule.patrolRangeOfChanges($patrolLink.attr("data-revision-max")).done(function(data)
if (fileName.indexOf(" (strona nie istnieje)") == -1) //jeśli plik istnieje (w przeciwnym przypadku przycisk patrolowania jest zbędny)
{
{
removeSpinner($button);
if (!overwritten)
$patrolLink.after(patrolSuccessCode);
$patrolLink.remove();
$patrolAgainBrackets.remove();
var title = new mw.Title(data["fmod-patrol"].title);
mw.notify( mw.msg( 'markedaspatrollednotifymulti', title.toText() ) );
//replace single buttons with success text
$singlePatrolLinks.replaceWith(patrolSuccessCode);
//remove patrol exclamation marks
$tbody.find("abbr.unpatrolled").replaceWith("&nbsp;");
}).fail(function() {
removeSpinner($button);
if ($patrolAgainBrackets.length === 0)
{
{
$patrolLink.before(patrolFailureCode);
//bierzemy sobie numer pierwszej wersji pliku, który jest potrzebny do patrolowania
$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
api.post(
$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
{
action: 'query',
format: 'json',
formatversion: '2',
prop: 'revisions',
titles: fileName,
rvprop: 'ids',
rvlimit: '1',
rvdir: 'newer'
}).done(function(data)
{
var oldid = data.query.pages[0].revisions[0].revid;
$(elem).find(".mw-changeslist-log-entry > a:not(.mw-userlink)").after("&nbsp;(<span class='patrolButton' title='Oznacz tę zmianę jako sprawdzoną' data-diff='" + oldid + "'><a>patrol</a></span>)");
var $button = $(elem).find(".patrolButton");
$button.on("click", function()
{
patrolChange(oldid, false, false);
});
$.each(extraAttributes, function(name, value)
{
$button.attr(name, value);
});
deferred.resolve();
}).fail(function(error)
{
console.log(error);
deferred.reject();
});
}
}
else
else
{
{
$patrolAgainBrackets.first().before(patrolFailureCode);
//bierzemy numer konkretnej wersji pliku (takie obejście potrzebne, bo tylko w tym wypadku nie ma atrybutu data-mw-revid)
$patrolAgainBrackets.show();
var timestamp = $(elem).attr("data-mw-ts");
api.post(
{
action: 'query',
format: 'json',
formatversion: '2',
prop: 'revisions',
titles: fileName,
rvprop: 'ids',
rvlimit: '1',
rvstart: timestamp,
rvend: timestamp
}).done(function(data)
{
var oldid = data.query.pages[0].revisions[0].revid;
$(elem).find("td>a:nth-child(5)").after("&nbsp;(<span class='patrolButton' data-diff='" + oldid + "'><a>patrol</a></span>)");
$(elem).find(".patrolButton").on("click", function()
{
patrolChange(oldid, false, false);
});
deferred.resolve();
}).fail(function(error)
{
console.log(error);
deferred.reject();
});
}
}
$patrolLink.text(tryAgainText);
}
$patrolLink.show();
else
{
mw.notify( mw.msg( 'markedaspatrollederrornotify' ), { type: 'error' } );
deferred.resolve();
}
});
return deferred.promise();
}
}


//helper function to process one RC link including spinner etc.
function makeNewpagesPatrolLinks()
function processRCChangePatrol($button)
{
{
var $patrolLink = $button.find("a"),
$("li.not-patrolled").each(function()
revid = $patrolLink.attr("data-revision"),
$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
$patrolAgainBrackets = $button.find(".patrolAgainBracket");
$patrolLink.hide();
$patrolAgainBrackets.hide();
$patrolLink.after($spinner);
$patrolLink.parent().find(".patrolButtonClicked").remove();
patrolModule.resetLastClick();
patrolModule.patrolChange(revid).done(function(data)
{
{
removeSpinner($button);
if (typeof $(this).find(".mw-newpages-oldtitle") == "undefined")
$patrolLink.after(patrolSuccessCode);
$patrolLink.remove();
$patrolAgainBrackets.remove();
getParentTag($button, "tr").find("abbr.unpatrolled").replaceWith("&nbsp;");
var title = new mw.Title(data["fmod-patrol"].title);
mw.notify( mw.msg( 'markedaspatrollednotify', title.toText() ) );
}).fail(function()
{
removeSpinner($button);
if ($patrolAgainBrackets.length === 0)
{
{
$patrolLink.before(patrolFailureCode);
var oldid = $(this).attr("data-mw-revid");
$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
$(this).find("span.mw-newpages-history a").after(" • <span class='patrolButton' title='Oznacz tę stronę jako sprawdzoną' data-diff='" + oldid + "'><a>patrol</a></span>");
$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
}
}
else
else
{
{
$patrolAgainBrackets.first().before(patrolFailureCode);
var api = new mw.Api(),
$patrolAgainBrackets.show();
elem = $(this),
pageName = $(this).find(".mw-newpages-pagename").attr("title");
api.post(
{
action: 'query',
format: 'json',
formatversion: '2',
prop: 'revisions',
titles: pageName,
rvprop: 'ids',
rvlimit: '1',
rvdir: 'newer'
}).done(function(data)
{
var oldid = data.query.pages[0].revisions[0].revid;
$(elem).find("span.mw-newpages-history a").after(" • <span class='patrolButton' title='Oznacz tę stronę jako sprawdzoną' data-diff='" + oldid + "'><a>patrol</a></span>");
$(elem).find(".patrolButton").on("click", function()
{
patrolChange(oldid, false, false);
});
}).fail(function(error)
{
console.log(error);
});
}
}
$patrolLink.text(tryAgainText);
});
$patrolLink.show();
$(".patrolButton").on("click", function()
mw.notify( mw.msg( 'markedaspatrollederrornotifychange' ), { type: 'error' } );
{
patrolChange($(this).attr("data-diff"), false, false);
});
});
}
}


function processPagePatrol($button)
function patrolChange(diff, isDiffPagePatrol, tokenAlreadyReset)
{
{
//diff page, new pages and any new page on the bottom
if (QuickPatrolLastClick >= (Date.now() - QuickPatrolDelay))
var pageid = $button.find("a").attr("data-pageid"),
return;
$patrolLink = $button.find("a"),
QuickPatrolLastClick = Date.now();
$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
$patrolAgainBrackets = $button.find(".patrolAgainBracket");
$patrolLink.hide();
if (diff === null || diff === "" || typeof diff == "undefined")
$patrolAgainBrackets.hide();
$patrolLink.after($spinner);
$patrolLink.parent().find(".patrolButtonClicked").remove();
patrolModule.resetLastClick();
patrolModule.patrolPage(pageid).done(function(data)
{
{
removeSpinner($button);
return $.when(); //resolved promise
}
var api = new mw.Api(),
$button = undefined, //button to nasz przycisk do patrolowania
deferred = $.Deferred();
$patrolLink.after(patrolSuccessCode);
if (!isDiffPagePatrol)
$patrolLink.remove();
{
$patrolAgainBrackets.remove();
$button = $(".patrolButton[data-diff='" + diff + "']");
$button.off("click").find("a").replaceWith(spinnerCode);
// if we are on diff page remove range patrol button, because we just patrolled all page revisions
}
$(".patrollink-range a").replaceWith(patrolSuccessCode);
api.post(
//if we are on Special:Newpages change background to match patrolled
{
if (mw.config.get("wgCanonicalSpecialPageName") == "Newpages")
action: 'patrol',
format: 'json',
revid: diff,
token: mw.user.tokens.get("patrolToken")
}).done(function(data)
{
if (!isDiffPagePatrol)
{
{
getParentTag($button, "li").removeClass("not-patrolled");
if (typeof $button.attr("data-mw-ts") == "undefined") //patrol zwykłej strony
{
$("table[data-mw-revid='" + diff + "'] abbr.unpatrolled").replaceWith('&nbsp;');
$("tr[data-mw-revid='" + diff + "'] abbr.unpatrolled").replaceWith('&nbsp;');
}
else //patrol pliku
{
var timestamp = $button.attr("data-mw-ts"),
logid = $button.attr("data-mw-logid");
$("table[data-mw-ts=" + timestamp + "] tr[data-mw-logid=" + logid + "] abbr.unpatrolled").replaceWith('&nbsp;');
}
var $anchor = $button.parent(); //koniecznie, bo zaraz $button nie bedzie mialo wartosci
$button.replaceWith("<span><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;<span style='color: green;' class='patrolButtonClicked'>zrobione</span><span>");
processGroupMarksAndButtons($anchor);
}
}
var title = new mw.Title(data["fmod-patrol"].title);
deferred.resolve();
mw.notify( mw.msg( 'markedaspatrollednotifypage', title.toText() ) );
}).fail(function(error)
}).fail(function()
{
{
removeSpinner($button);
if (!tokenAlreadyReset)
if ($patrolAgainBrackets.length === 0)
{
{
$patrolLink.before(patrolFailureCode);
console.log("TOKEN PATROLOWANIA NIEPRAWIDŁOWY - DRUGA PRÓBA");
$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
api.post
$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
({
format: "json",
formatversion: "2",
action: "query",
meta: "tokens",
type: "patrol"
}).done(function(data)
{
mw.user.tokens.set("patrolToken", data.query.tokens.patroltoken);
patrolChange(diff, isDiffPagePatrol, true)
.done(function()
{
deferred.resolve();
console.log("NOWY TOKEN PRAWIDŁOWY");
}).fail(function()
{
deferred.reject();
console.log("NOWY TOKEN NIEPRAWIDŁOWY");
});
});
}
}
else
else // w przypadku pierwszego faila to zostanie wykonane przez funkcję wywołaną rekursywnie
{
{
$patrolAgainBrackets.first().before(patrolFailureCode);
if (!isDiffPagePatrol)
$patrolAgainBrackets.show();
{
$button.replaceWith("<img src='https://nonsa.pl/images/a/a8/Przeciw.svg.png' width='15px' height='15px' />&nbsp;<span style='color: red;' class='patrolButtonClicked'>błąd</span>");
}
console.log(error);
deferred.reject();
}
}
$patrolLink.text(tryAgainText);
$patrolLink.show();
mw.notify( mw.msg( 'markedaspatrollederrornotifypage' ), { type: 'error' } );
});
});
return deferred.promise();
}
}


function patrolMultipleChanges(tbody)
function makeDiffPagePatrolLinks()
{
{
var deferred = $.Deferred(),
var $button = $(".patrollink-range a");
if (!isEventBound($button))
failureCount = 0,
successCount = 0,
multiplePatrolButton = tbody.find(".multiplePatrolButton"),
buttons = $(tbody).find(".patrolButton"),
buttonsCount = buttons.length;
multiplePatrolButton.off("click").find("a").replaceWith(spinnerCode);
buttons.each(function()
{
{
$button.click(function()
QuickPatrolLastClick = 0;
patrolChange($(this).attr("data-diff"), false, false)
.done(function()
{
{
processDiffPageRangePatrol();
++successCount;
}).fail(function()
{
++failureCount;
}).always(function()
{
if (successCount == buttonsCount) //wszystkie wywołania AJAX do patrolowania zakończyły się pomyślnie
{
deferred.resolve(successCount, failureCount);
multiplePatrolButton.replaceWith("<span><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;<span style='color: green;' class='multiplePatrolButtonClicked'>zrobione</span></span>");
tbody.find("tr:first-child abbr.unpatrolled").replaceWith("&nbsp;");
}
else if (successCount + failureCount == buttonsCount) //wszystkie zakończyły się, niekoniecznie pomyślnie
{
deferred.reject(successCount, failureCount);
multiplePatrolButton.replaceWith("<img src='https://nonsa.pl/images/a/a8/Przeciw.svg.png' width='15px' height='15px' />&nbsp;<span style='color: red;' class='multiplePatrolButtonClicked'>błąd</span>");
}
});
});
});
}
$button = $(".patrollink-page a");
if (buttonsCount == 0)
if (!isEventBound($button))
{
{
$button.click(function()
multiplePatrolButton.replaceWith("<span><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;<span style='color: green;' class='multiplePatrolButtonClicked'>zrobione</span></span>");
{
tbody.find("tr:first-child abbr.unpatrolled").replaceWith("&nbsp;");
processPagePatrol($button.parent());
});
}
}
return deferred.promise();
}
}


//helper function to process diff page range patrol including spinner etc.
function makeDiffViewRevidsList(oldid, curid, pagetitle)
function processDiffPageRangePatrol()
{
{
var $button = $(".patrollink-range"),
if ($(".diffPagePatrolButton").length || $(".diffPagePatrolButtonClicked").length || makeDiffViewRevidsListIsExecuting)
$patrolLink = $button.find("a"),
{
$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
return;
$patrolAgainBrackets = $button.find(".patrolAgainBracket"),
}
to = $patrolLink.attr("data-revision-max"),
makeDiffViewRevidsListIsExecuting = true;
from = $patrolLink.attr("data-revision-min");
$patrolLink.hide();
var api = new mw.Api(),
$patrolAgainBrackets.hide();
timestampQueryData = function(id)
$patrolLink.after($spinner);
{
$patrolLink.parent().find(".patrolButtonClicked").remove();
var ret =
{
format: "json",
formatversion: 2,
action: "query",
prop: "revisions",
rvprop: "timestamp",
rvstartid: id,
rvendid: id,
titles: pagetitle
};
return ret;
};
var leftEditIsPageCreation = ($("#differences-prevlink").length == 0); // czy jest link "przejdź do poprzedniej edycji"
patrolModule.resetLastClick();
api.post
patrolModule.patrolRangeOfChanges(to, from).done(function(data)
(
timestampQueryData(oldid)
).done(function(data)
{
{
removeSpinner($button);
//debugger;
var firstTimestamp = data.query.pages[0].revisions[0].timestamp;
$patrolLink.after(patrolSuccessCode);
//debugger;
$patrolLink.remove();
//żeby nie oznaczało jako sprawdzonej pierwszej zmiany (po lewej)
$patrolAgainBrackets.remove();
if (!leftEditIsPageCreation) //ale tylko jeśli była edycja przedtem
{
var date = new Date(firstTimestamp);
date.setSeconds(date.getSeconds() + 1);
function pad2withzeros(number)
{
return String(number).padStart(2, "0");
}
firstTimestamp = date.getUTCFullYear() + "-" + pad2withzeros(date.getUTCMonth() + 1) + "-" + pad2withzeros(date.getUTCDate()) + "T" + pad2withzeros(date.getUTCHours()) + ":" + pad2withzeros(date.getUTCMinutes()) + ":" + pad2withzeros(date.getUTCSeconds()) + "Z";
}
var title = new mw.Title(data["fmod-patrol"].title);
api.post
mw.notify( mw.msg( 'markedaspatrollednotifymulti', title.toText() ) );
(
}).fail(function()
timestampQueryData(curid)
).done(function(data)
{
//debugger;
var secondTimestamp = data.query.pages[0].revisions[0].timestamp;
api.post(
{
format: "json",
formatversion: 2,
action: "query",
list: "recentchanges",
rcstart: firstTimestamp,
rcend: secondTimestamp,
rcdir: "newer",
rctitle: pagetitle,
rcshow: "!patrolled",
rcprop: "ids"
}).done(function(data)
{
//debugger;
var length = data.query.recentchanges.length;
for (var i = 0; i < length; ++i)
{
QuickPatrolDiffPageRevids.push(data.query.recentchanges[i].revid);
}
if (length > 0)
{
makeDiffPagePatrolButton();
}
makeDiffViewRevidsListIsExecuting = false;
}).fail(function(error)
{
makeDiffViewRevidsListIsExecuting = false;
});
}).fail(function(error)
{
makeDiffViewRevidsListIsExecuting = false;
});
}).fail(function(error)
{
{
removeSpinner($button);
makeDiffViewRevidsListIsExecuting = false;
});
if ($patrolAgainBrackets.length === 0)
}

function makeDiffPagePatrolButton()
{
var patrolButtonCode = "<span class='diffPagePatrolButton'>[<a title='oznacz wszystkie edycje widoczne w porównaniu jako sprawdzone'>oznacz wszystkie edycje jako sprawdzone</a>]</span>";
if (mw.config.get("skin") != "minerva" && mw.config.get("wgCanonicalSpecialPageName") != "MobileDiff")
{
var patrolLink = $("#mw-diff-ntitle4 .patrollink");
if (patrolLink.length > 0)
{
{
patrolLink.replaceWith(patrolButtonCode);
$patrolLink.before(patrolFailureCode);
$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
}
}
else
else
{
{
$patrolAgainBrackets.first().before(patrolFailureCode);
$("#mw-diff-ntitle4").append("&nbsp;" + patrolButtonCode);
$patrolAgainBrackets.show();
}
}
$patrolLink.text(tryAgainText);
}
$patrolLink.show();
else
{
mw.notify( mw.msg( 'markedaspatrollederrornotifypage' ), { type: 'error' } );
//debugger;
$(".patrollink").append(" • " + patrolButtonCode.replace(/(\[|\])/g, "")); //bez kwadratowych nawiasów
}
$(".diffPagePatrolButton a").click(function()
{
patrolMultipleChangesDiffPage();
});
});
}
}


function patrolMultipleChangesDiffPage()
function getParentTag($anchor, tag)
{
{
var deferred = $.Deferred(),
tag = tag.toUpperCase();
var $a = $anchor;
failureCount = 0,
while ($a.prop("tagName") != tag && $a.prop("tagName") != "BODY")
successCount = 0,
length = QuickPatrolDiffPageRevids.length,
button = $(".diffPagePatrolButton");
//debugger;
button.off("click").find("a").replaceWith(spinnerCode);
//debugger;
QuickPatrolDiffPageRevids.forEach(function(oldid)
{
{
$a = $a.parent();
QuickPatrolLastClick = 0;
}
patrolChange(oldid, true, false)
return $a;
.done(function()
{
++successCount;
}).fail(function()
{
++failureCount;
}).always(function()
{
if (successCount == length)
{
deferred.resolve(successCount, failureCount);
//debugger;
button.replaceWith("<img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;<span style='color: green;' class='diffPagePatrolButtonClicked'>zrobione</span>");
//debugger;
}
else if (successCount + failureCount == length)
{
deferred.reject(successCount, failureCount);
button.replaceWith("<img src='https://nonsa.pl/images/a/a8/Przeciw.svg.png' width='15px' height='15px' />&nbsp;<span style='color: red;' class='diffPagePatrolButtonClicked'>błąd</span>");
}
});
//debugger;
});
//debugger;
return deferred.promise();
}
}


function isEventBound($element)
function processGroupMarksAndButtons($anchor) //usuwa grupowy wykrzyknik i przycisk patrolowania, jak zajdzie potrzeba
{
{
if ($element == null || $element.length == 0)
var $parent = $anchor;
while ($parent.prop("tagName") != "TABLE" && $parent.prop("tagName") != "BODY")
{
{
return false;
$parent = $parent.parent();
}
//wszystkie rozwijalne zmiany/pliki spatrolowane, drugi warunek po to,
//zeby nie ignorowalo sytuacji, gdy zmiany nie udalo sie spatrolowac
if ($parent.find(".patrolButton").length == 0 && $parent.find("abbr.unpatrolled").length == 1)
{
$parent.find("abbr.unpatrolled").replaceWith("&nbsp;");
$parent.find(".multiplePatrolButton").replaceWith("<span><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;<span style='color: green;' class='multiplePatrolButtonClicked'>zrobione</span></span>");
}
}
var events = $._data($element.get(0), "events");
return events != null;
}

function removeSpinner($node)
{
$node.find("div.mw-spinner").remove();
}
}

Aktualna wersja na dzień 17:25, 28 maj 2020

/*
 * gadżet do szybkiego oznaczania wersji jako sprawdzonych na OZ, nowych stronach i widoku diffów
 * autor: Expert3222
 * drobne modyfikacje, backend: Ostrzyciel
 */

mw.loader.load('/wiki/Użytkownik:Expert3222/patrolModule.js?action=raw&ctype=text/javascript');

var patrolSuccessCode = "<span style='color: green;' class='patrolButtonClicked'><img src='https://nonsa.pl/images/2/26/Za.svg.png' width='15px' height='15px' />&nbsp;zrobione</span>";
var patrolFailureCode = "<span style='color: red;' class='patrolButtonClicked'><img src='https://nonsa.pl/images/a/a8/Przeciw.svg.png' width='15px' height='15px' />&nbsp;błąd</span>";
var tryAgainText = "spróbuj ponownie";

$(document).ready(function()
{
	mw.loader.using(["jquery.spinner", "mediawiki.notification"], function()
	{
		if (mw.config.get("wgCanonicalSpecialPageName") === "Recentchanges")
		{
			makePatrolLinks();
			if (!!$('.mw-rcfilters-enabled').length) //wzięte od Polskacafe z gadżetu RollWithReason
			{
				setInterval(makePatrolLinks, 2000);
			}
		}
		else if (mw.config.get("wgCanonicalSpecialPageName") == "Newpages")
		{
			var $buttons = $(".patrollink-page a");
			$buttons.click(function()
			{
				processPagePatrol($(this).parent());
			});
		}
		else if (mw.util.getParamValue("diff") !== null)
		{
			makeDiffPagePatrolLinks();
			
			setInterval(makeDiffPagePatrolLinks, 2000); //"przeglądaj historię interaktywnie" na górze
		}
		else if ($(".patrollink").length > 0) //footer
		{
			$(".patrollink-page a").off("click").click(function(event) //remove default click handler and attach our own
			{
				event.preventDefault();
				event.stopImmediatePropagation();
				processPagePatrol($(this).parent());
			});
		}
		else if (mw.config.get("wgCanonicalSpecialPageName") == "MobileDiff")
		{
			//TODO
			
			/*var oldid = mw.util.getParamValue("oldid", $("#mw-mf-diff-info a").attr("href"));
			alert("oldid = " + oldid);
			var urlArray = window.location.href.split("/");
			var curid = urlArray[urlArray.length - 1];
			alert("curid = " + curid);
			
			var title = $("#mw-mf-diff-info a").text();
			makeDiffViewRevidsList(oldid, curid, title);*/
		}
	});
});

function makePatrolLinks()
{
	$(".patrollink-range a").each(function()
	{
		var $link = $(this);
		if (!isEventBound($link))
		{
			var $tbody = getParentTag($link, "tbody");
			$link.on("click", function()
			{
				processMultipleChangeRCPatrol($tbody);
			});
		}
	});

	$(".patrollink-single a").each(function()
	{
		var $button = $(this);
		if (!isEventBound($button))
		{
			$button.on("click", function()
			{
				processRCChangePatrol($(this).parent(), true);
			});
		}
	});
}

//helper function to process multiple change RC patrol, including spinner etc.
function processMultipleChangeRCPatrol($tbody)
{
	var $button = $tbody.find(".patrollink-range"),
		$patrolLink = $button.find("a"),
		$singlePatrolLinks = $tbody.find(".patrollink-single a"),
		$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
		$patrolAgainBrackets = $patrolLink.parent().find(".patrolAgainBracket");
	
	$patrolLink.hide();
	$patrolAgainBrackets.hide();
	$patrolLink.after($spinner);
	$patrolLink.parent().find(".patrolButtonClicked").remove();
	
	patrolModule.patrolRangeOfChanges($patrolLink.attr("data-revision-max")).done(function(data)
	{
		removeSpinner($button);
		
		$patrolLink.after(patrolSuccessCode);
		$patrolLink.remove();
		$patrolAgainBrackets.remove();
		
		var title = new mw.Title(data["fmod-patrol"].title);
		mw.notify( mw.msg( 'markedaspatrollednotifymulti', title.toText() ) );
		
		//replace single buttons with success text
		$singlePatrolLinks.replaceWith(patrolSuccessCode);
		
		//remove patrol exclamation marks
		$tbody.find("abbr.unpatrolled").replaceWith("&nbsp;");
	}).fail(function() {
		removeSpinner($button);
		
		if ($patrolAgainBrackets.length === 0)
		{
			$patrolLink.before(patrolFailureCode);
			$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
			$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
		}
		else
		{
			$patrolAgainBrackets.first().before(patrolFailureCode);
			$patrolAgainBrackets.show();
		}
		$patrolLink.text(tryAgainText);
		$patrolLink.show();
		
		mw.notify( mw.msg( 'markedaspatrollederrornotify' ), { type: 'error' } );
	});
}

//helper function to process one RC link including spinner etc.
function processRCChangePatrol($button)
{
	var $patrolLink = $button.find("a"),
		revid = $patrolLink.attr("data-revision"),
		$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
		$patrolAgainBrackets = $button.find(".patrolAgainBracket");
		
	$patrolLink.hide();
	$patrolAgainBrackets.hide();
	$patrolLink.after($spinner);
	$patrolLink.parent().find(".patrolButtonClicked").remove();
	
	patrolModule.resetLastClick();
	patrolModule.patrolChange(revid).done(function(data)
	{
		removeSpinner($button);
		
		$patrolLink.after(patrolSuccessCode);
		$patrolLink.remove();
		$patrolAgainBrackets.remove();
		
		getParentTag($button, "tr").find("abbr.unpatrolled").replaceWith("&nbsp;");
		
		var title = new mw.Title(data["fmod-patrol"].title);
		mw.notify( mw.msg( 'markedaspatrollednotify', title.toText() ) );
	}).fail(function()
	{
		removeSpinner($button);
		
		if ($patrolAgainBrackets.length === 0)
		{
			$patrolLink.before(patrolFailureCode);
			$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
			$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
		}
		else
		{
			$patrolAgainBrackets.first().before(patrolFailureCode);
			$patrolAgainBrackets.show();
		}
		$patrolLink.text(tryAgainText);
		$patrolLink.show();
		
		mw.notify( mw.msg( 'markedaspatrollederrornotifychange' ), { type: 'error' } );
	});
}

function processPagePatrol($button)
{
	//diff page, new pages and any new page on the bottom
	var pageid = $button.find("a").attr("data-pageid"),
		$patrolLink = $button.find("a"),
		$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
		$patrolAgainBrackets = $button.find(".patrolAgainBracket");
	
	$patrolLink.hide();
	$patrolAgainBrackets.hide();
	$patrolLink.after($spinner);
	$patrolLink.parent().find(".patrolButtonClicked").remove();
	
	patrolModule.resetLastClick();
	patrolModule.patrolPage(pageid).done(function(data)
	{
		removeSpinner($button);
		
		$patrolLink.after(patrolSuccessCode);
		$patrolLink.remove();
		$patrolAgainBrackets.remove();
		
		// if we are on diff page remove range patrol button, because we just patrolled all page revisions
		$(".patrollink-range a").replaceWith(patrolSuccessCode);
		
		//if we are on Special:Newpages change background to match patrolled
		if (mw.config.get("wgCanonicalSpecialPageName") == "Newpages")
		{
			getParentTag($button, "li").removeClass("not-patrolled");
		}
		
		var title = new mw.Title(data["fmod-patrol"].title);
		mw.notify( mw.msg( 'markedaspatrollednotifypage', title.toText() ) );
	}).fail(function()
	{
		removeSpinner($button);
		
		if ($patrolAgainBrackets.length === 0)
		{
			$patrolLink.before(patrolFailureCode);
			$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
			$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
		}
		else
		{
			$patrolAgainBrackets.first().before(patrolFailureCode);
			$patrolAgainBrackets.show();
		}
		$patrolLink.text(tryAgainText);
		$patrolLink.show();
		
		mw.notify( mw.msg( 'markedaspatrollederrornotifypage' ), { type: 'error' } );
	});
}

function makeDiffPagePatrolLinks()
{	
	var $button = $(".patrollink-range a");
	if (!isEventBound($button))
	{
		$button.click(function()
		{
			processDiffPageRangePatrol();
		});
	}
	
	$button = $(".patrollink-page a");
	if (!isEventBound($button))
	{
		$button.click(function()
		{
			processPagePatrol($button.parent());
		});
	}
}

//helper function to process diff page range patrol including spinner etc.
function processDiffPageRangePatrol()
{
	var $button = $(".patrollink-range"),
		$patrolLink = $button.find("a"),
		$spinner = $.createSpinner({ size: 'small', type: 'inline' }),
		$patrolAgainBrackets = $button.find(".patrolAgainBracket"),
		to = $patrolLink.attr("data-revision-max"),
		from = $patrolLink.attr("data-revision-min");
	
	$patrolLink.hide();
	$patrolAgainBrackets.hide();
	$patrolLink.after($spinner);
	$patrolLink.parent().find(".patrolButtonClicked").remove();
	
	patrolModule.resetLastClick();
	patrolModule.patrolRangeOfChanges(to, from).done(function(data)
	{
		removeSpinner($button);
		
		$patrolLink.after(patrolSuccessCode);
		$patrolLink.remove();
		$patrolAgainBrackets.remove();
		
		var title = new mw.Title(data["fmod-patrol"].title);
		mw.notify( mw.msg( 'markedaspatrollednotifymulti', title.toText() ) );
	}).fail(function()
	{
		removeSpinner($button);
		
		if ($patrolAgainBrackets.length === 0)
		{
			$patrolLink.before(patrolFailureCode);
			$patrolLink.before("<span class='patrolAgainBracket'> (</span>");
			$patrolLink.after("<span class='patrolAgainBracket'>)</span>");
		}
		else
		{
			$patrolAgainBrackets.first().before(patrolFailureCode);
			$patrolAgainBrackets.show();
		}
		$patrolLink.text(tryAgainText);
		$patrolLink.show();
		
		mw.notify( mw.msg( 'markedaspatrollederrornotifypage' ), { type: 'error' } );
	});
}

function getParentTag($anchor, tag)
{
	tag = tag.toUpperCase();
	var $a = $anchor;
	while ($a.prop("tagName") != tag && $a.prop("tagName") != "BODY")
	{
		$a = $a.parent();
	}
	return $a;
}

function isEventBound($element)
{
	if ($element == null || $element.length == 0)
	{
		return false;
	}
	var events = $._data($element.get(0), "events");
	return events != null;
}

function removeSpinner($node)
{
	$node.find("div.mw-spinner").remove();
}