MediaWiki:Gadget-metadata.js
/** _____________________________________________________________________________
* | | * | === WARNING: GLOBAL GADGET FILE === | * | Changes to this page affect many users. | * | Please discuss changes on the talk page or on WT:Gadget before editing. | * |_____________________________________________________________________________| * * Imported from revision 185704269 as of January 20, 2008 18:40 from * User:Pyrospirit/metadata.js, itself a modified version of * User:Outriggr/metadata.js. * Metadata assessment script * Finds the WP 1.0/WikiProject assessment of every article you go to, then * displays that information in the article header. See (new script homepage * pending). * @author Outriggr - created the script and used to maintain it * @author Pyrospirit - used to maintain and update the script * @author Nihiltres - Overhauled the script, current maintainer */
window.assessment = (function () {
var assessmentObj = { props: {}, methods: {} }, //internal shortcuts ap = assessmentObj.props, am = assessmentObj.methods;
/** * The main function of the script. If the checkArticle() function can find * the assessment, it parses and displays that assessment for the page. * Otherwise, it tries to retrieve an assessment via AJAX. */ assessmentObj.init = function () { if (!$("#siteSub").length || //incompatible skin mw.config.get("wgNamespaceNumber") !== 0 || //non-mainspace page (mw.config.get("wgAction") !== "view" && mw.config.get("wgAction") !== "purge") || //non-read action mw.util.getParamValue("printable") || //printable page mw.config.get("wgArticleId") === 0 || //nonexistent page mw.config.get("wgIsMainPage") === true //Main Page ) { return; //Don't run the script under any of these conditions. } ap.foundAssessment = am.checkArticle(); //checks for types visible from article page if (!ap.foundAssessment.exists) { // no type visible on article, proceed to check the talk page $.ajax({ url: mw.config.get("wgScript") + "?title=Talk:" + mw.util.wikiUrlencode(mw.config.get("wgPageName")) + "&action=raw§ion=0", async: true, dataType: "text", success: function (responseText) { ap.text = responseText; ap.foundAssessment = am.getAssessment(ap.text); ap.updata = am.renderAssessment(ap.foundAssessment); am.update(); } }); } else { ap.updata = am.renderAssessment(ap.foundAssessment); am.update(); } };
/** * Checks for various objects on the article page that indicate a certain * assessment, such as a disambiguation page notice. If this function can * find the assessment, AJAX is not needed for this page. * @returns {Object} checkResult - the assessment found */ am.checkArticle = function () { var checkResult = { extra: [], exists: false }, checksList = [ [$("#disambig, #disambig_disambigbox, #disambigbox").length, "dab"], [$("#setindexbox").length, "setindex"], [$("#contentSub").text() === "Redirect page", "redir"], /* [$("table.stub").length, "stub"], */ [$("#ca-talk").hasClass("new"), "none"] //no talk page ]; $.each(checksList, function (i, e) { if (e[0]) { checkResult.rating = e[1]; checkResult.exists = true; return false; } }); return checkResult; };
/** * Searches the provided wikicode for the rating part of an assessment and * returns it as a string. * Note that higher assessments take priority, and less-used assessments * such as "list", "current", or "future" are used only if nothing else can * be found. * @param {String} text - some wikitext to be searched for assessment info */ am.getRating = function (text) { var rating = "none", standardChecks = [ [/\|\s*(class|currentstatus)\s*=\s*fa\b/i, "fa"], [/\|\s*(class|currentstatus)\s*=\s*fl\b/i, "fl"], [/\|\s*class\s*=\s*a\b/i, "a"], [/\|\s*class\s*=\s*b\b/i, "b"], [/\|\s*class\s*=\s*bplus\b/i, "bplus"], //used by WP Math [/\|\s*class\s*=\s*c\b/i, "c"], [/\|\s*class\s*=\s*start/i, "start"], [/\|\s*class\s*=\s*stub/i, "stub"], [/\|\s*class\s*=\s*al\b/i, "al"], // used by WP Military history & WP Highways [/\|\s*class\s*=\s*bl\b/i, "bl"], // used by WP Military history [/\|\s*class\s*=\s*cl\b/i, "cl"], // used by WP Military history [/\|\s*class\s*=\s*list/i, "list"], [/\|\s*class\s*=\s*sl\b/i, "sl"], // used by WP Plants [/\|\s*class\s*=\s*(dab|disambig)/i, "dab"], [/\|\s*class\s*=\s*cur(rent)?/i, "cur"], [/\|\s*class\s*=\s*future/i, "future"] ]; //evaluate the standard checks $.each(standardChecks, function (i, e) { if (text.match(e[0])) { rating = e[1]; return false; } }); //and then the nonstandard ones. These override earlier ratings if applicable. if (rating === "a" && text.match(/\|\s*class\s*=\s*ga\b|\|\s*currentstatus\s*=\s*(ffa\/)?ga\b/i)) { rating = "a/ga"; // A-class articles that are also GA's } else if (text.match(/\|\s*class\s*=\s*ga\b|\|\s*currentstatus\s*=\s*(ffa\/)?ga\b|\{\{\s*ga\s*\|/i) && !text.match(/\|\s*currentstatus\s*=\s*dga\b/i)) { rating = "ga"; } return rating; };
/** * Searches the provided wikicode for data on the article's current and past * featured or good status and returns an object that contains this data * along with some miscellaneous other bits of information. * @param {String} text - some wikitext to be searched for assessment info * @return {Object} gottenAssessment - the assessment data for the page */ am.getAssessment = function (text) { var gottenAssessment = { rating: am.getRating(text), pageLink: [null, null], extra: [], activeReview: null, exists: true }, actionNumber = 0, pageLinkFlag = false, peerReview, linkPattern, linkMatch, currentList, formerList;
currentList = [ // Current nominations (FAC, FLC, or GAN) { reg: /\{\{\s*featured[ _]article[ _]candidates\s*(?:[\|\}]\s*([^\|\}]*))?[^\}]*?\}\}/i, extraName: "fac", addArticleNameTo: "Wikipedia:Featured_article_candidates\/" }, { reg: /\{\{\s*featured[ _]list[ _]candidates\s*(?:[\|\}]\s*([^\|\}]*))?[^\}]*?\}\}/i, extraName: "flc", addArticleNameTo: "Wikipedia:Featured_list_candidates\/" }, { reg: /\{\{\s*ga ?nominee\s*[\|\}][^\}]*\}\}/i, extraName: "gan", addMatchReg: /\|\s*page\s*=\s*(\d+).*\|\s*status\s*=\s*\w+\b/i, addMatchTo: "Talk:" + mw.config.get("wgPageName") + "\/GA" }, // Current reviews of a status (FAR, FLRC, or GAR) { reg: /\{\{\s*featured[ _]article[ _]review\s*(?:[\|\}]\s*([^\|\}]*))?[^\}]*?\}\}/i, extraName: "far", addArticleNameTo: "Wikipedia:Featured_article_review\/" }, { reg: /\{\{\s*featured[ _]list[ _]removal[ _]candidates\s*(?:[\|\}]\s*([^\|\}]*))?[^\}]*?\}\}/i, extraName: "flrc", addArticleNameTo: "Wikipedia:Featured_list_removal_candidates\/" }, { reg: /\{\{\s*gar\/link\s*[\|\}][^\}]*\}\}/i, extraName: "gar", addMatchReg: /\|\s*GARpage\s*=\s*(\d+).*\|/i, addMatchTo: mw.config.get("wgPageName") } ]; $.each(currentList, function (i, e) { var reg = text.match(e.reg), articleName, tempMatch; if (reg) { gottenAssessment.extra.push(e.extraName); if (e.hasOwnProperty("addArticleNameTo") && reg[1]) { articleName = am.decodeEntities($.trim(reg[1])); if (articleName) { gottenAssessment.pageLink[0] = e.addArticleNameTo + articleName; } } if (e.hasOwnProperty("addMatchReg")) { tempMatch = reg[0].match(e.addMatchReg); if (tempMatch) { gottenAssessment.pageLink[0] = (e.addMatchTo || "") + (tempMatch[1] || ""); } if (e.extraName === "gar") { //Can't get around this special case easily gottenAssessment.pageLink[0] = am.getGARLink(e.addMatchTo, tempMatch[1]); } } return false; } });
formerList = [ // Former statuses (FFA, FFL, or DGA) { name: "ffa", reg: /\|\s*currentstatus\s*=\s*ffa\b/i, getActionNumber: true, getActionNumberReg: /\|\s*action(\d+)\s*=\s*far\b/gi }, { name: "ffa", reg: /\|\s*action(\d+)\s*=\s*far\b/gi, extraCondition: function (ec_reg) { //Checks if the last FAR entry in ArticleHistory resulted in removal. var match, ratingSearch; if (!ec_reg) { return false; } match = text.match(new RegExp( "\\|\\s*action" + ec_reg[ec_reg.length - 1].match(/\d+/) + "result\\s*=\\s*removed\\b", "i" )); ratingSearch = (gottenAssessment.rating.search(/f[al]/i) === -1); return (match && ratingSearch); }, getActionNumber: true }, { name: "ffa", reg: /\{\{\s*formerfa2?\b/i }, { name: "ffl", reg: /\|\s*currentstatus\s*=\s*ffl\b/i }, { name: "ffl", reg: /\{\{\s*ffl\s*[\|\}]/i }, { name: "dga", reg: /\|\s*currentstatus\s*=\s*dga\b/i, getActionNumber: true, getActionNumberReg: /\|\s*action(\d+)\s*=\s*gar\b/gi }, { name: "dga", reg: /\{\{\s*d(elisted)?ga\s*[\|\}]/i }, // Former nominations (former FAC, FLC, or GAN) { name: "ffac", reg: /\|\s*action(\d+)\s*=\s*fac\b/gi, extraCondition: function () { return (gottenAssessment.rating.search(/f[al]/i) === -1); }, getActionNumber: true }, { name: "ffac", reg: /\|\s*currentstatus\s*=\s*ffac\b/i }, { name: "ffac", reg: /\{\{\s*fac?(failed|(\-|[ _]\()?contested\)?)\s*[\|\}]/i }, { name: "fflc", reg: /\|\s*action(\d+)\s*=\s*flc\b/gi, extraCondition: function () { return (gottenAssessment.rating.search(/f[al]/i) === -1); }, getActionNumber: true }, { name: "fflc", reg: /\|\s*currentstatus\s*=\s*fflc\b/i }, { name: "fgan", reg: /\|\s*action(\d+)\s*=\s*gan\b/gi, extraCondition: function () { return (gottenAssessment.rating.search(/f[al]|(a\/)?ga/i) === -1); }, getActionNumber: true }, { name: "fgan", reg: /\|\s*currentstatus\s*=\s*fgan\b/i }, { name: "fgan", reg: /\{\{\s*f(ailed ?)?ga\s*[\|\}]/i } ]; $.each(formerList, function (i, e) { var reg = text.match(e.reg), extraCondition = !e.hasOwnProperty("extraCondition") || typeof e.extraCondition !== "function" || e.extraCondition(reg), //either true (ignored) or result of function tempMatch; if (reg && extraCondition) { gottenAssessment.extra.push(e.name); if (e.getActionNumber) { tempMatch = (e.getActionNumberReg ? text.match(e.getActionNumberReg) : reg); actionNumber = tempMatch[tempMatch.length - 1].match(/\d+/); pageLinkFlag = true; } return false; } });
// Looks for currently active peer reviews ap.showOldPeerReviews = false; //see TODO below peerReview = text.match(/\{\{\s*peer[_ ]?review\s*\|\s*archive\s*=\s*(\d+)\b/i); if (peerReview) { gottenAssessment.review = "Wikipedia:Peer_review/" + mw.config.get("wgPageName") + "/archive" + peerReview[1]; gottenAssessment.activeReview = true; } else if (ap.showOldPeerReviews) { $.noop(); // TODO: Add code for old peer reviews } else { gottenAssessment.review = null; }
// Scans for the link associated with an action in ArticleHistory if (pageLinkFlag) { linkPattern = new RegExp("\\|\\s*action" + actionNumber + "link\\s*=\\s*([^\\n\\|]+)\\s*\\|"); linkMatch = text.match(linkPattern); gottenAssessment.pageLink[1] = linkMatch ? am.decodeEntities(linkMatch[1]) : null; }
return gottenAssessment; };
/** * Parses an assessment object into the HTML and CSS code needed to update * the article header. If it doesn't recognize a part of the information * given, it will simply ignore it and mark as unassessed. * @param {Object} assess - assessment information for this article * @return {String} newClass - the CSS class corresponding to its assessment * @return {String} slogan - HTML giving (with a link) the main assessment * @return {String} info - HTML giving (with a link) additional information */ am.renderAssessment = function (assess) { var assessLink = mw.util.getUrl("Wikipedia:Content_assessment"), peerReviewText = am.addPeerReview(assess.review, assess.activeReview), pageLink = assess.pageLink || [null, null], info = am.getExtraInfo((assess.extra || []), pageLink), newClass, slogan, ratingList;
if (peerReviewText) {
info.push(peerReviewText);
}
ratingList = [
{
name: "a",
className: "assess-a-text",
text: "An <a>A-class<\/a> article"
},
{
name: "a/ga",
className: "assess-a-text",
text: "An <a>A-class<\/a> article",
info: "Also a <a href=\"" + mw.util.getUrl("Wikipedia:Good_articles") + "\">good article<\/a>."
},
{
name: "ga",
className: "assess-ga-text",
text: "A <a>good article<\/a>",
url: mw.util.getUrl("Wikipedia:Good_articles")
},
{
name: "b",
className: "assess-b-text",
text: "A <a>B-class<\/a> article"
},
{
name: "bplus",
className: "assess-bplus-text",
text: "A <a>B-plus-class<\/a> article",
url: mw.util.getUrl("Wikipedia:WikiProject_Mathematics/Wikipedia_1.0/Grading_scheme")
},
{
name: "c",
className: "assess-c-text",
text: "A <a>C-class<\/a> article"
},
{
name: "start",
className: "assess-start-text",
text: "A <a>start-class<\/a> article"
},
{
name: "stub",
className: "assess-stub-text",
text: "A <a>stub-class<\/a> article"
},
{
name: "al",
className: "assess-al-text",
text: "An <a>A-class<\/a> list",
url: mw.util.getUrl("Wikipedia:WikiProject_Military_history/Assessment") + "#SCALE" //Could use a more general link if one is available
},
{
name: "bl",
className: "assess-bl-text",
text: "A <a>B-class<\/a> list",
url: mw.util.getUrl("Wikipedia:WikiProject_Military_history/Assessment") + "#SCALE"
},
{
name: "cl",
className: "assess-cl-text",
text: "A <a>C-class<\/a> list",
url: mw.util.getUrl("Wikipedia:WikiProject_Military_history/Assessment") + "#SCALE"
},
{
name: "sl",
className: "assess-sl-text",
text: "A <a>stub-class<\/a> list"
},
{
name: "list",
className: "assess-list-text",
text: "A <a>list-class<\/a> article",
url: mw.util.getUrl("Wikipedia:Stand-alone lists")
},
{
name: "dab",
className: "assess-dab-text",
text: "A <a>disambiguation page<\/a>",
url: mw.util.getUrl("Wikipedia:Disambiguation")
},
{
name: "setindex",
className: "assess-setindex-text",
text: "A <a>set index article<\/a>",
url: mw.util.getUrl("Wikipedia:Set_index_articles")
},
{
name: "redir",
className: "assess-redir-text",
text: "A <a>redirect page<\/a>",
url: mw.util.getUrl("Help:Redirect")
},
{
name: "fl",
className: "assess-fl-text",
text: "A <a>featured list<\/a>",
url: mw.util.getUrl("Wikipedia:Featured_lists")
},
{
name: "fa",
className: "assess-fa-text",
text: "A <a>featured article<\/a>",
url: mw.util.getUrl("Wikipedia:Featured_articles")
},
{
name: "cur",
className: "assess-cur-text",
text: "A <a>current-class<\/a> article",
url: mw.util.getUrl("Portal:Current_events")
},
{
name: "future",
className: "assess-future-text",
text: "A <a>future-class<\/a> article",
url: mw.util.getUrl("Category:Future-Class_articles")
}
];
$.each(ratingList, function (i, e) {
if (assess.rating === e.name) {
newClass = e.className;
slogan = $("").doc(e.text).children().attr({href: (e.url || assessLink)}).parent().doc();
if (e.info) {
info.push(e.info);
}
return false;
}
});
if (!newClass) {
newClass = "assess-unassessed-text";
slogan = "An <a href=\"" + assessLink + "\">unassessed<\/a> article";
}
return {newClass: newClass, slogan: slogan, info: info}; };
/** * Creates an info string based on the assessment info and a page link. */ am.getExtraInfo = function (extra, pageLink) { var info = [], page = mw.config.get("wgPageName"), typeList;
typeList = [
// Current nominations and reviews
{
name: "fac",
doc: "Currently a <a>featured article candidate<\/a>.",
url: pageLink[0] || ("Wikipedia:Featured_article_candidates/" + page)
},
{
name: "flc",
doc: "Currently a <a>featured list candidate<\/a>.",
url: pageLink[0] || ("Wikipedia:Featured_list_candidates/" + page)
},
{
name: "gan",
doc: "Currently a <a>good article nominee<\/a>.",
url: pageLink[0] || "Wikipedia:Good_article_nominations"
},
{
name: "far",
doc: "Currently undergoing <a>review<\/a> of its featured status.",
url: pageLink[0] || ("Wikipedia:Featured_article_review/" + page)
},
{
name: "flrc",
doc: "Currently a <a>candidate<\/a> for removal as a featured list.",
url: pageLink[0] || ("Wikipedia:Featured_list_removal_candidates/" + page)
},
{
name: "gar",
doc: "Currently undergoing a <a>good article reassessment<\/a>.",
url: pageLink[0] || "Wikipedia:Good_article_reassessment",
wrapper: "<\/span>"
},
// Past statuses and nominations
{
name: "ffa",
doc: "A <a>former<\/a> featured article.",
url: pageLink[1] || ("Wikipedia:Featured_article_review/" + page)
},
{
name: "ffl",
doc: "A <a>former<\/a> featured list.",
url: pageLink[1] || ("Wikipedia:Featured_list_removal_candidates/" + page)
},
{
name: "dga",
doc: "A <a>delisted<\/a> good article.",
url: pageLink[1] || "Wikipedia:Good_article_reassessment"
},
{
name: "ffac",
doc: "A former <a>featured article candidate<\/a>.",
url: pageLink[1] || ("Wikipedia:Featured_article_candidates/" + page)
},
{
name: "fflc",
doc: "A former <a>featured list candidate<\/a>.",
url: pageLink[1] || ("Wikipedia:Featured_list_candidates/" + page)
},
{
name: "fgan",
doc: "A former <a>good article nominee<\/a>.",
url: pageLink[1] || "Wikipedia:Good_article_nominations"
}
];
$.each(typeList, function (i, e) {
if (extra.indexOf(e.name) !== -1) {
info.push($("").doc(e.doc).children().attr({href: mw.util.getUrl(e.url)})
.parent().wrapInner(e.wrapper || null).doc());
}
});
return info; };
/** * Get the correct link for Good Article reassessments. These things require an * additional AJAX request to determine whether it's a community or individual * reassessment. The trick is to assume it's a community reassessment, then * switch the link once the request returns if it's actually not. * @param {String} articleName - the name of the article to use * @param {String} reviewNumber - the number of the GAR to look for */ am.getGARLink = function (articleName, reviewNumber) { var communityTitle = "Wikipedia:Good_article_reassessment\/" + articleName + "\/" + reviewNumber, individualTitle = "Talk:" + articleName + "\/GA" + reviewNumber, titlesList = [communityTitle, individualTitle], api = new mw.Api();
api.get({ action: "query", titles: titlesList.join("|"), prop: "info", format: "json" }).done(function (data) { var i, j, noCommunityAssessment, query = data.query, communityTitleNorm = titlesList[0], individualTitleNorm = titlesList[1], len = query.normalized.length, garLink = $("#assess-gar-link a:first");
for (j = 0; j < len; j++) { switch (query.normalized[j].from) { case titlesList[0]: communityTitleNorm = query.normalized[j].to; break; case titlesList[1]: individualTitleNorm = query.normalized[j].to; break; } } noCommunityAssessment = false; for (i = -1; i >= -2; i--) { if (query.pages[i] && typeof query.pages[i].missing === "string") { if (query.pages[i].title === individualTitleNorm) { // No individual assessment, no need to change anything. return; } if (query.pages[i].title === communityTitleNorm) { // There's no community assessment, so flag it. noCommunityAssessment = true; } } } if (noCommunityAssessment && garLink.length) { // There's an individual assessment but no community assessment. Switch the link. garLink.attr("href", mw.util.getUrl(titlesList[1])); } }); return communityTitle; };
/** * Creates the peer review text from an info string, if a peer review was detected earlier. */ am.addPeerReview = function (peerReview, activeReview) { var reviewText = null; if (peerReview) {
reviewText = $("
" +
(activeReview ? "Currently being" : "Previously") + " <a>peer reviewed<\/a>.<\/span><\/div>"); reviewText.find("a").attr({href: mw.util.getUrl(peerReview)}); reviewText = reviewText.doc(); //Note div wrapper above. } return reviewText; };
/**
* Updates article header with new assessment information by giving it a new
* class (for style information such as color) and altering the tagline below
* it to state the assessment found.
*/
am.update = function () {
var info = ap.updata.info,
infoSpan = $("<\/span>"),
siteSub = $("