User:Enterprisey/unreliable.js

// WARNING: DO NOT USE. TESTING ONLY

// Instructions available at User:Headbomb/unreliable // Feel free to request tweaks or additional sources to be covered on the talk page

// Adapted from https://en.wikipedia.org/w/index.php?title=Wikipedia:User_scripts/Requests&diff=939432100&oldid=939403363 by User:SD0001 // Updated from https://en.wikipedia.org/w/index.php?title=User:Jorm/unreliable.js&oldid=940556311 by User:Jorm // Updated from https://en.wikipedia.org/w/index.php?title=User:SD0001/unreliabe.js&oldid=941114456 by User:SD0001 // Updated from https://en.wikipedia.org/w/index.php?title=User:SD0001/unreliable.js&action=edit by User:SD0001 // Updated from https://en.wikipedia.org/w/index.php?title=User:Creffett/unreliable.js&oldid=957395306 by User:Creffett // Updated to use JSON by User:Enterprisey

// Unreliable websites based on WP:RSPSOURCES and WP:NPPSG (mostly) // Unreliable publishers/journals based on WP:CITEWATCH (mostly)

$.when(	$.ready,	mw.loader.using([ 'mediawiki.api' ]) ).then(function {

// Fetch main list of rules // TODO localStorage var mainRulesPromise = new mw.Api.get({		action: 'query',		prop: 'revisions',		titles: 'Wikipedia:TESTING-DONT-USE-unreliable.json',		rvslots: '*',		rvprop: 'content',		formatversion: '2',		uselang: 'content', // needed for caching		smaxage: '86400', // cache for 1 day		maxage: '86400' // cache for 1 day	}).then(function(data) {		return JSON.parse(data.query.pages[0].revisions[0].slots.main.content);	}); var customRulesPromise;

if (window.unreliableUseCustomRules) {

// Dynamically load a user's custom rules from User:USERNAME/unreliable-rules.js		customRulesPromise = mw.loader.getScript('/w/index.php?title=User:' + encodeURIComponent(mw.config.get('wgUserName')) + 			'/unreliable-rules.js&action=raw&ctype=text/javascript') .fail( function(e) {			// Something's gone very wrong			mw.log.error("Error retrieving your unreliable-rules.js");			// More detailed error in the console if someone feels nice enough to file a bug report			console.log("Error getting local unreliable-rules.js: " + e.message);		}) .then( function {			// Script succeeded. You can use X now.			if (Array.isArray(window.unreliableCustomRules)) {				window.unreliableCustomRules.forEach(function(customRule) { if (!(customRule.regex instanceof RegExp) || (typeof customRule.css !== 'object')) { mw.log.warn("Error parsing custom unreliable links rule: ", rule); return []; }				});				return window.unreliableCustomRules;			}		}); } else { customRulesPromise = $.when([]); }

mw.loader.using('mediawiki.util').then(function {		mw.util.addCSS('.unreliable-borderline { background-color: #fffdd0; }');		mw.util.addCSS('.unreliable-unreliable { background-color: #ffdddd; }');		mw.util.addCSS('.unreliable-predatory { background-color: #ffbbbb; text-decoration: underline; text-decoration-style: wavy; }');		mw.util.addCSS('.unreliable-blacklist  { background-color: #dddddd; text-decoration: underline; text-decoration-style: wavy; text-decoration-color: #cc0000; }');	});

function tryRules(rules, originalText) { originalText = originalText.toLowerCase.replace('%2F', '/').replace('https://', ).replace('http://', ); var text = originalText.substring(0, originalText.indexOf('/')); var numDots = text.split('.').length - 1; // For example, if originalText was a.b.c.d, subdomains would be ['c.d', 'b.c.d', 'a.b.c.d']. // This is so that we can look up each "subdomain" in the appropriate "set". var subdomains = [text]; for (var i = 0; i < numDots - 1; i++) { subdomains.splice(0, 0, subdomains[0].substring(subdomains[0].indexOf('.') + 1)); }		for (var i = 0; i < rules.length; i++) { var rule = rules[i]; if (typeof rule.namespaces !== 'undefined' && rule.namespaces.indexOf(mw.config.get('wgNamespaceNumber')) < 0) { return false; }			if (rule.regex && rule.regex.test(originalText)) { return rule; }			if (rule.sets) { for (var numDots in rule.sets) { if (rule.sets[numDots][subdomains[numDots - 1]]) { return rule; }				}			}		}	}

$.when(		mainRulesPromise,		customRulesPromise	).then(function(mainRules, customRules) {		//var start=+new Date;		//console.log(start)

// Preprocess the rules to make checking faster var rules = mainRules.concat(customRules).map(function(rule) {			if (rule.regex) {				rule.regex = new RegExp('\\b(?:' + rule.regex + ')\\b', 'i');			}			if (rule.list) {				// Divide the domains by the number of dots in them, so that all we need to do for link checks is to do a "in this set?" check instead of a substring				rule.sets = {};				rule.list.forEach(function(domain) { var numDots = domain.split('.').length - 1; if (!rule.sets[numDots]) rule.sets[numDots] = {}; rule.sets[numDots][domain] = true; });				//console.log(rule.sets);			}			return rule;		});

// Check each external link on the page against each regex $('.mw-parser-output a.external').each(function(_, link) {			var rule = tryRules(rules, link.href);			if (rule) {				$(link).addClass('unreliable-' + rule.kind);				$(link).attr('title', rule.comment || '');			}		});

// Check list items against each regex to catch further reading/bibliography items without links $('.mw-parser-output ul li, .mw-parser-output ol:not(.references) li, .reference-text:not(:has(a))') .each(function(_, li) {			var rule = tryRules(rules, li.textContent);			if (rule) {				$(li).addClass('unreliable-' + rule.kind);				$(li).attr('title', rule.comment || '');			}		}); //var end=+new Date; //console.log(end,end-start); }); });