« MediaWiki:Gadget-easyPeerReview.js » : différence entre les versions
Contenu supprimé Contenu ajouté
make {{breaking review}} goto {{breaking}} |
m fix for IE |
||
Ligne 101 : | Ligne 101 : | ||
} |
} |
||
catch(err) { |
catch(err) { |
||
alert('Easy review script has uncaught exception [tell Bawolff]: ' + err); |
alert('Easy review script has uncaught exception [tell Bawolff]: ' + err.name + ': ' + err.message); |
||
} |
} |
||
return false; |
return false; |
Version du 6 décembre 2009 à 18:36
/*global skin, addPortletLink, importScript, wgTitle, wgPageName, jsMsg, wgAction, wgNamespaceNumber, wgUserGroups, addOnloadHook, Bawolff, wgCurRevisionId, wgUserName, wgCanonicalNamespace, escapeQuotesHTML, wgArticleId */
/*members AsyncQueue, EasyReview_comment, EasyReview_copyright,
EasyReview_copyright_comment, EasyReview_news, EasyReview_news_comment,
EasyReview_npov, EasyReview_npov_comment, EasyReview_revid,
EasyReview_sg, EasyReview_sg_comment, EasyReview_sources,
EasyReview_sources_comment, Request, action, add, comment, confirm,
content, createElement, delaySend, edit, exec, failReview, getAttribute,
getElementById, getElementsByName, getElementsByTagName, getPage,
indexOf, innerHTML, lastIndex, length, level, mwapi, next, page,
postReview, previousSibling, prop, redraw, replace, revid, review,
rvprop, section, selectChange, sight, src, start, style, submit,
substring, summary, titles, toString, value, visibility
*/
//So that this doesn't interfere with var names of anything else
if (typeof Bawolff === "undefined") Bawolff = {};
Bawolff.review = function() {
//this is initilization function. called onload
//pre-req: already checked in main namespace, user is in group editor, and action is view
//check if {{tl|review}} is on page
if (document.getElementById('review')) {
addPortletLink("p-cactions", "javascript:Bawolff.review.start();void%200;", "Review", "ca-peerReview", "Do a peer review on this page");
}
}
Bawolff.review.doWeirdGoogleHack = true; // FIXME: this is crap.
Bawolff.review.start = function () {
importScript('User:Bawolff/mwapilib.js'); //needed when pressing submit
//This draws the dialog. called on click
var container = document.createElement("div");
container.innerHTML ='<form id="easyReviewForm" action="javascript:void 0" onsubmit="Bawolff.review.submit(); return false;"><table class="metadata plainlinks ambox ambox-notice EasyReview" id="EasyReview-mainAmbox" style="line-height: 1.2"><tr><td class="ambox-image"><a href="/wiki/File:Pictogram_voting_question-blue.svg" class="image" title="Pictogram_voting_question-blue.svg"><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Pictogram_voting_question-blue.svg/60px-Pictogram_voting_question-blue.svg.png" width="60" height="62" border="0" /></a></td><td>Reviewing revision ' + wgCurRevisionId + '<ul style="line-height:1.6;"><li><b><a href="/wiki/Wikinews:Copyright" title="Wikinews:Copyright">Copyright</a>:</b> <img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-copyright-image" width="10" height="10" border="0" /><select name="EasyReview-copyright" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-copyright-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-copyright-comment" name="EasyReview-copyright-comment" type="text" length="30" style="visibility: hidden"/></li><li><b><a href="/wiki/Wikinews:Content_guide" title="Wikinews:Content guide">Newsworthiness</a>:</b> <img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-news-image" width="10" height="10" border="0" /><select name="EasyReview-news" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-news-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-news-comment" name="EasyReview-news-comment" type="text" length="30" style="visibility: hidden"/></li><li><b><a href="/wiki/Wikinews:Cite_sources" title="Wikinews:Cite sources">Verifiability</a>:</b> <img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-sources-image" width="10" height="10" border="0" /><select name="EasyReview-sources" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-sources-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-sources-comment" name="EasyReview-sources-comment" type="text" length="30" style="visibility: hidden"/></li><li><b><a href="/wiki/Wikinews:Neutral_point_of_view" title="Wikinews:Neutral point of view">NPOV</a>:</b> <img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-npov-image" width="10" height="10" border="0" /><select name="EasyReview-npov" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-npov-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-npov-comment" name="EasyReview-npov-comment" type="text" length="30" style="visibility: hidden"/></li><li><b><a href="/wiki/Wikinews:Style_guide" title="Wikinews:Style guide">Style</a>:</b> <img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-sg-image" width="10" height="10" border="0" /><select name="EasyReview-sg" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-sg-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-sg-comment" name="EasyReview-sg-comment" type="text" length="30" style="visibility: hidden"/></li></ul><p><b><label for="EasyReview-commentBox">Comments by reviewer: </label></b> <textarea row="3" id="EasyReview-commentBox" name="EasyReview-commentBox"></textarea></p><input type="submit" value="Submit Review"/> <input type="submit" value="Cancel" onclick="jsMsg(\'\');return false"/></td></tr></table></form>';
/*<img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png" id="EasyReview-sg-image" width="10" height="10" border="0" /><select name="EasyReview-sg" onchange="Bawolff.review.selectChange()"><option value="pass">Pass</option><option value="fail" selected="selected">Fail</option></select> <label for="EasyReview-sg-comment" style="visibility:hidden">Comment: </label><input id="EasyReview-sg-comment" name="EasyReview-sg-comment" type="text" length="30" style="visibility: hidden"/>
*/
/*http://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Art%C3%ADculo_bueno.svg/10px-Art%C3%ADculo_bueno.svg.png
http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png
*/
jsMsg(container);
Bawolff.review.selectChange();
}
Bawolff.review.selectChange = function () {
//basically a redraw operation. something change, so redraw box
Bawolff.review.redraw("sg", document.getElementsByName("EasyReview-sg")[0].value === "pass");
Bawolff.review.redraw("npov", document.getElementsByName("EasyReview-npov")[0].value === "pass");
Bawolff.review.redraw("sources", document.getElementsByName("EasyReview-sources")[0].value === "pass");
Bawolff.review.redraw("news", document.getElementsByName("EasyReview-news")[0].value === "pass");
Bawolff.review.redraw("copyright", document.getElementsByName("EasyReview-copyright")[0].value === "pass");
}
Bawolff.review.redraw = function (prefix, state) {
var base = "EasyReview-" + prefix;
if (state) {
document.getElementById(base + "-image").src = "http://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Art%C3%ADculo_bueno.svg/10px-Art%C3%ADculo_bueno.svg.png";
document.getElementById(base + "-comment").previousSibling.style.visibility = "hidden";
document.getElementById(base + "-comment").style.visibility = "hidden";
} else {
document.getElementById(base + "-image").src = "http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/10px-Red_x.svg.png";
document.getElementById(base + "-comment").previousSibling.style.visibility = "visible";
document.getElementById(base + "-comment").style.visibility = "visible";
}
}
Bawolff.review.submit = function () {
try {
//form submit handler
var text;
var review = {
"EasyReview_revid": wgCurRevisionId,
"EasyReview_sg" : document.getElementsByName("EasyReview-sg")[0].value === 'pass',
"EasyReview_sg_comment" : document.getElementById("EasyReview-sg-comment").value,
"EasyReview_npov" : document.getElementsByName("EasyReview-npov")[0].value === 'pass',
"EasyReview_npov_comment" : document.getElementById("EasyReview-npov-comment").value,
"EasyReview_sources" : document.getElementsByName("EasyReview-sources")[0].value === 'pass',
"EasyReview_sources_comment" : document.getElementById("EasyReview-sources-comment").value,
"EasyReview_news" : document.getElementsByName("EasyReview-news")[0].value === 'pass',
"EasyReview_news_comment" : document.getElementById("EasyReview-news-comment").value,
"EasyReview_copyright" : document.getElementsByName("EasyReview-copyright")[0].value === 'pass',
"EasyReview_copyright_comment" : document.getElementById("EasyReview-copyright-comment").value,
"EasyReview_comment" : document.getElementById("EasyReview-commentBox").value
}
// True -> pass
review.EasyReview_sg_comment = (review.EasyReview_sg ? 'pass' : review.EasyReview_sg_comment );
review.EasyReview_npov_comment = (review.EasyReview_npov ? 'pass' : review.EasyReview_npov_comment );
review.EasyReview_sources_comment = (review.EasyReview_sources ? 'pass' : review.EasyReview_sources_comment );
review.EasyReview_news_comment = (review.EasyReview_news ? 'pass' : review.EasyReview_news_comment );
review.EasyReview_copyright_comment = (review.EasyReview_copyright ? 'pass' : review.EasyReview_copyright_comment );
//pass review if all subsections are passed
var passed = review.EasyReview_sg && review.EasyReview_npov && review.EasyReview_sources && review.EasyReview_news && review.EasyReview_copyright;
//func for publishing article
if (passed) {
Bawolff.review.postReview(review);
} else {
Bawolff.review.failReview(review);
}
}
catch(err) {
alert('Easy review script has uncaught exception [tell Bawolff]: ' + err.name + ': ' + err.message);
}
return false;
}
Bawolff.review.failReview = function(r) {
/*var cont = confirm('review failed. continue posting review?'); //for debuging
*if (!cont) {throw new Error("User bailed [failed rev]");}*/
//post {{tl|tasks|copyvio|news|src|npov|mos|re-review}} on page, peer review on talk.
//First post peer review template on talk
//generate content to add to talk page
var reviewText = "<!--Submitted using easy peer review - MediaWiki:Gadget-easyPeerReview.js --> \{\{peer_reviewed|revid=" + r.EasyReview_revid + "|copyright=" + r.EasyReview_copyright_comment + "|newsworthy=" + r.EasyReview_news_comment + "|verifiable=" + r.EasyReview_sources_comment + "|npov=" + r.EasyReview_npov_comment + "|style=" + r.EasyReview_sg_comment + "|reviewer=" + wgUserName + "|comments=" + r.EasyReview_comment + "|time=~~" + "~~" + "~}}";
var reviewHeader = "Review of revision " + r.EasyReview_revid + " [Failed]";
//callback to ajax that inserts review template on talk
var talk_rev_cb = function (success) {
if (success) {
jsMsg('<p><a class="image" href="/wiki/File:X_mark.svg"><img height="17" width="15" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/15px-X_mark.svg.png" alt="X mark.svg"/></a> <b>Done</b> ' + escapeQuotesHTML(wgTitle) + ' has been reviewed (With the article <b>failing</b> the review process)</p>');
}
else {
throw new Error("Something bad happened (recoverable edit error, like a captcha or something. However we couldn't figure out how to recover.)");
}
}
Bawolff.mwapi.edit({content: reviewText, page: "Talk:" + wgTitle, summary: reviewHeader, section: "new"}, talk_rev_cb);
/***END posting peer review template to talk page ****/
/***Start replace {{tl|review}} with {{tl|tasks}}****/
//generate tasks tag. ({{tl|tasks|copyvio|news|src|npov|mos|re-review}})
var tasks_template = "\{\{tasks";
//for each one, if failed (if false) add the tag
tasks_template += (r.EasyReview_copyright ? "" : "|copyvio");
tasks_template += (r.EasyReview_news ? "" : "|news");
tasks_template += (r.EasyReview_sources ? "" : "|src");
tasks_template += (r.EasyReview_npov ? "" : "|npov");
tasks_template += (r.EasyReview_sg ? "" : "|mos");
tasks_template += "|re-review}}";
//Get the page
var final_article_text = ""; //string that contains page that will be posted to server (Pay attention to variable scope)
var apiOps = new Bawolff.mwapi.AsyncQueue; //Container to chain api requests
var getPage_cb = function (res) {
//callback to do work on the current page (aka put article flag)
var page = res[wgTitle]; //wgPageName is url escaped
if (page === undefined) { //if not in main ns
page = res[wgCanonicalNamespace + ":" + wgTitle];
}
if (page === undefined) { //badness happened
throw new Error("Could not retrieve page source from server when trying to replace review with tasks in failed review");
}
page = page.replace(/\{\{(?:[rR]eview|[bB]reaking review|[rR]eady|[uU]nder review)(?:\|[^}]*)?\}\}/, tasks_template); //replace {{tl|review}} with tasks
page = page.replace(/\{\{(?:[rR]eview|[bB]reaking review|[rR]eady|[uU]nder review)(?:\|[^}]*)?\}\}(?:\n)?/g, ""); //if multiple review templates
if (page.indexOf(tasks_template) === -1) {
page = tasks_template + page; // if the above regexs fail for some reason, add tasks to top.
}
final_article_text = page;
}
//add Obtain and modify page to queue of api operations
Bawolff.mwapi.getPage(wgPageName, getPage_cb, apiOps);
/****end obtain and modify page***/
/***start save page to server****/
//this is really ugly.
//wrap in function so it uses the variable in the outer function's scope (final_article_text) at time of execution
var postChanges = function () {
var edit_cb = function(success, resp) {
if (!success) {
var APIerror = resp.getElementsByTagName("error");
var err = "Unknown Error"; //default
if (APIerror.length !== 0) {
err = APIerror[0].getAttribute("info");
}
alert("Could not add article flag to article due to error: '"+ err + "'. Peer review template will still be added to talk, but make your checks.");
}
apiOps.next(); //go to next action
}
Bawolff.mwapi.edit({content: final_article_text, page: wgPageName, summary: "Failed Review. Add article flag. (Using [[MediaWiki:Gadget-easyPeerReview.js|easy peer review]]"}, edit_cb);
}
apiOps.add(postChanges); //add to ops queue
/******End incredibly ugly add {{tl|tasks}} to page, code*******/
apiOps.start(); //start editing
}
Bawolff.review.postReview = function(r) {
//argument: review object
//called from form handler if review was SUCCESSFUL
/***** DO WEIRD GOOGLE NEWS HACK ********/
//FIXME: this is stupid
//create a redirect with a numb in it.
if (Bawolff.review.doWeirdGoogleHack) {
var googleOps = new Bawolff.mwapi.AsyncQueue;
var google_cb = function(success, resp) {
//alert("We reached the callback");
//this is a callback for after done editing.
if (!success) {
var APIerror = resp.getElementsByTagName("error");
if (APIerror.length !== 0) {
var err = APIerror[0].getAttribute("info");
}
alert("Could not make a redirect for google news. Contact Bawolff. Error: "+ err + ". Continuing with rest of review process");
}
var editTags = resp.getElementsByTagName('edit');
if (editTags && editTags[0] && editTags[0].getAttribute('newrevid') > 2) {
//so we sight the page.
var GoogleRedirId = editTags[0].getAttribute('newrevid');
Bawolff.mwapi.sight({revid: GoogleRedirId, level: '1', comment: "Making redirect for google with a really long number, as those google people like long numbers.(Using [[MediaWiki:Gadget-easyPeerReview.js]]) "});
} else {
alert('Warning (Please leave user:Bawolff a note): Could not figure out revision id of google news redirect to article. Falling back to dying in a hole. you may have to sight the google redirect manually.');
}
}
Bawolff.mwapi.edit({content: "#Redirect[[" + wgPageName + "]]\n\n{\{Google News}}", page: "Article/" + wgArticleId + "/" + wgPageName, summary: "Add a redirect for google (Using [[MediaWiki:Gadget-easyPeerReview.js]])", minor: "true"}, google_cb);
}
/**********END GOOGLE NEWS HACK *******/
/*var cont = confirm('review passed. continue posting review?'); //for debuging
if (!cont) {throw new Error("User bailed [passed rev]");}*/
// alert(reviewText); //make it do stuff later.
/**************
*Post changes to server.
*prereq: assume user has ability to edit page and to sight it
*first edit current page
**<nowiki>{{review}} -> {{publish}}</nowiki> (in correct position)
**sight that revision
**get rev number of published version, and update review template
**Post a new section named "Review" with the peer review template.
**************/
var apiOps = new Bawolff.mwapi.AsyncQueue; //list of apiops we have to do.
//Check if rev we are looking at is most current.
var actual_rev;
//Make a callback function that
//checks if theres been an edit
//and if so prompts the user as to wether to proceed.
var checkEditConfilict_cb = function (res) {
//Get the revid from the api query
actual_rev = res.getElementsByTagName('rev')[0].getAttribute('revid');
//if its different from what we're looking at, prompt if we want to continue.
if (actual_rev != r.EasyReview_revid) {
var keep_going = window.confirm("*********[edit conflict]********** \nSomeone has edited this page since you have reviewed it. Do you want to review this page (including the latest edits) anyways?");
if (!keep_going) {throw new Error("User prematurely canceled due to edit conflict");}
//fixme: should be some soft error thats less ugly
//perhaps subclass of error thats recognized by mwapilib
}
}
var checkEditConflict = new Bawolff.mwapi.Request({action:"query", prop: "revisions", titles: wgPageName, rvprop: "ids"});
checkEditConflict.delaySend(apiOps, checkEditConfilict_cb);
/***End checking for edit conflict ****/
/***Start editng of article (add pub tag, rm review)*****/
//Get the page
var final_article_text = ""; //string that contains page that will be posted to server
var getPage_cb = function (res) {
//callback to do work on the current page (aka publish it)
var page = res[wgTitle]; //wgPageName is url escaped
if (page === undefined) { //if not in main ns
page = res[wgCanonicalNamespace + ":" + wgTitle];
}
if (page === undefined) { //badness happened
throw new Error("Could not retrieve page source from server when trying to replace review with publish in successful review");
}
page = page.replace(/\{\{[dD]ate\|[^}]*\}\}/, "\{\{date|\{\{subst:#time:F j, Y}}}}");
page = page.replace(/\{\{[bB]reaking review(?:\|[^}]*)?\}\}/g, "\{\{breaking}}"); //rm {{tl|breaking review}} add breaking
page = page.replace(/\{\{(?:[rR]eview|[bB]reaking review|[rR]eady|[uU]nder review)(?:\|[^}]*)?\}\}(?:\n)?/g, ""); //rm {{tl|review}}
page = page.replace(/\{\{[dD]evelop(?:ing)?(?:\|[^}]*)?\}\}(?:\n)?/g, ""); //rm {{tl|develop}}
//Add {{tl|publish}} (code slightly inelegant)
var src = /\*\{\{(?:[sS]ource(-pr|-science)?|[aA]pasource|[pP]apersource|[oO]rsource|[sS]ourceReg)\|[^}]*\}\}/gm;
var endOfSrc = page.length;
while (src.exec(page) !== null) {endOfSrc = src.lastIndex;}
page = page.substring(0, endOfSrc) + "\n\n{\{Publish}}" + page.substring(endOfSrc, page.length);
//end insertion of publish template.
final_article_text = page; //push to outside scope.
if (final_article_text.length < 10) {
//if result less than length of pub tag, wine.
throw new Error("Error in adding \{\{publish}}. please report this to [[User:Bawolff]].");
}
}
//add Obtain and modify page to queue of api operations
Bawolff.mwapi.getPage(wgPageName, getPage_cb, apiOps);
/****end obtain and modify page***/
/***start save page to server****/
//this is really ugly.
//wrap in function so it uses the global variable at time of execution
var postChanges = function () {
var edit_cb = function(success, resp) {
if (!success) {
var APIerror = resp.getElementsByTagName("error");
if (APIerror.length !== 0) {
var err = APIerror[0].getAttribute("info");
}
alert("Could not add \{\{publish\}\} to article. Due to error: "+ err + ". Continuing with rest of review process");
}
var editTags = resp.getElementsByTagName('edit');
if (editTags && editTags[0] && editTags[0].getAttribute('newrevid') > 2) {
//so we sight the published revision
Bawolff.review.newid = editTags[0].getAttribute('newrevid');
} else {
alert('Warning (Please leave user:Bawolff a note): Could not figure out revision id of new published version of article. Falling back to using revision id of penultimate revision. you may have to sight the latest version of this article manually.');
}
apiOps.next(); //go to next action
}
Bawolff.mwapi.edit({content: final_article_text, page: wgPageName, summary: "Publish. (Using [[MediaWiki:Gadget-easyPeerReview.js|easy peer review]]"}, edit_cb);
}
apiOps.add(postChanges); //add to ops queue
/******End incredibly ugly publish page code*******/
//Sight the apropriate revision.
Bawolff.mwapi.sight({revid: new Bawolff.LazyVar('Bawolff.review.newid'), level: '1', comment: "Publishing article after successful peer review (Using [[MediaWiki:Gadget-easyPeerReview.js]]): " + r.EasyReview_comment }, undefined, undefined, apiOps);
/******Start put review template on talk page*****/
//generate template
var reviewText = "<!--Submited using easy peer review - MediaWiki:Gadget-easyPeerReview.js --> \{\{peer_reviewed|revid=" + r.EasyReview_revid + "|copyright=" + r.EasyReview_copyright_comment + "|newsworthy=" + r.EasyReview_news_comment + "|verifiable=" + r.EasyReview_sources_comment + "|npov=" + r.EasyReview_npov_comment + "|style=" + r.EasyReview_sg_comment + "|reviewer=" + wgUserName + "|comments=" + r.EasyReview_comment + "|time=~~" + "~~" + "~" + "}}";
var reviewHeader = "Review of revision " + r.EasyReview_revid + " [Passed]";
var talk_rev_cb = function (success) {
if (success) {
jsMsg('<p><a href="/wiki/File:Yes_check.svg" class="image" title="Yes check.svg"><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/16px-Yes_check.svg.png" width="16" height="16" /></a> <b>Done</b> <i>' + escapeQuotesHTML(wgTitle) + '</i> has been successfully reviewed. <form action="/wiki/Wikinews:Make_lead" method="GET"><button type="submit" value="' + escapeQuotesHTML(wgTitle) + '" name="use-page">Make this story a lead article</button></form></p>');
}
else {
throw new Error("Something bad happened (recoverable edit error, like a captcha or something. However we couldn't figure out how to recover.)");
}
}
Bawolff.mwapi.edit({content: reviewText, page: "Talk:" + wgTitle, summary: reviewHeader, section: "new"}, talk_rev_cb, undefined, apiOps);
/****End talk page editing ***/
/****Start making edits!*****/
apiOps.start();
}
if (wgAction === "view" && wgNamespaceNumber === 0 && wgUserGroups.toString().indexOf("editor") > -1 ) {
addOnloadHook(Bawolff.review);
}