User:Isaac (WMF)/article quality.js

const COEF_LEN = 0.395; const COEF_MED = 0.114; const COEF_HEA = 0.123; const COEF_REF = 0.181; const COEF_LIN = 0.115; const COEF_CAT = 0.070;

const MAX_LEN = 165.7; // sqrt(bytes) const MAX_MED = 3; // # images const MAX_HEA = 0.115; // # headings / bytes const MAX_REF = 0.294; // # refs / bytes const MAX_LIN = 0.116; // # links / bytes const MAX_CAT = 14; // # categories

function scoreToClass(score) { if (score <= 0.42) { return 'Stub'; } else if (score <= 0.56) { return 'Start'; } else if (score <= 0.73) { return 'C-class'; } else if (score <= 0.85) { return 'B-class'; } else if (score <= 0.93) { return 'GA'; } else if (score <= 1) { return 'FA'; } else { return 'N/A' } }

function workNeeded(length, references, media, categories, pagelinks, headings) { let lowest_feature = Math.min(length, references, media, categories, pagelinks, headings); if (lowest_feature <= 0.833) { if (length == lowest_feature) { return 'more content?'; } else if (references == lowest_feature) { return 'more references?'; } else if (pagelinks == lowest_feature) { return 'wikify (more links)?'; } else if (media == lowest_feature) { return 'add an image?'; } else if (categories == lowest_feature) { return 'more categories?'; } else if (headings == lowest_feature) { return 'more structure (break up sections)?'; } else { return 'not sure what work needed'; }	} else { return 'looking good!'; } }

function getFeatures { // all non-hidden categories let catLinks = document.querySelector("#mw-normal-catlinks").querySelectorAll("a[href^=\"/wiki/Category:\"]").length; // all images that are at least 100 pixels tall or wide (excludes most icons) let media = 0; for (let med of document.querySelector("#bodyContent").querySelectorAll("img")) { if (med.height >= 100 || med.width >= 100) { media += 1; }	}	// all pagelinks in the article text (loses tables / infoboxes but those are often template-added links not in wikitext) let pageLinks = document.querySelector("#bodyContent").querySelectorAll("p > a:not(.image, .internal)[href*=\"/wiki/\"]").length; // no way to get wikitext length without calling an API but this is a rough approximation // length of all article HTML (includes a lot of syntax but so does wikitext) + infobox/table text (too much syntax on those to keep) let pageLength = 0; for (let para of document.querySelector("#bodyContent").querySelectorAll("p")) { // article text pageLength += para.innerHTML.length; }	for (let tablerow of document.querySelector("#bodyContent").querySelectorAll("table")) { // infoboxes + tables pageLength += tablerow.innerText.length; }	pageLength = Math.sqrt(pageLength); // take square root to normalize // all Level 2/3 headings let headings = 0; headings += document.querySelector("#bodyContent").querySelectorAll("h2:not(#mw-toc-heading)").length; // L2 headings but exclude TOC headings += document.querySelector("#bodyContent").querySelectorAll("h3").length; // L3 headings // all references -- based on the superscripts in text so not unique references but that's how wikitext works too let references = document.querySelectorAll(".reference").length; let len_x = Math.min(pageLength / MAX_LEN, 1); let med_x = Math.min(media / MAX_MED, 1); let cat_x = Math.min(catLinks / MAX_CAT, 1); let ref_x = Math.min(references / pageLength / MAX_REF, 1); let lin_x = Math.min(pageLinks / pageLength / MAX_LIN, 1); let hea_x = Math.min(headings / pageLength / MAX_HEA, 1); let quality = (COEF_LEN * len_x) + (COEF_MED * med_x) + (COEF_HEA * hea_x) + (COEF_REF * ref_x) + (COEF_LIN * lin_x) + (COEF_CAT * cat_x); let quality_class = scoreToClass(quality); let work_needed = workNeeded(len_x, ref_x, med_x, cat_x, lin_x, hea_x); const result = { 'overall_quality':quality, 'quality_class':quality_class, 'work_needed':work_needed, 'content_score':len_x, 'media_score':med_x, 'reference_score':ref_x, 'link_score':lin_x, 'structure_score':hea_x, 'annotation_score':cat_x };	return result; }

$(document).ready(function {	// article on enwiki but not Main Page   if (mw.config.get("wgDBname") == "enwiki" && mw.config.get('wgNamespaceNumber') == 0 && mw.config.get('wgWikibaseItemId') != 'Q5296') {	    let data = getFeatures;        //console.log(data);        $("#firstHeading").append(' (' + data['quality_class'] + " -- " + data['work_needed'] + ") ");  // add to header    } });