User:MarioGom/Scripts/CiteHighlighter.js

// Highlight references based on their reliability. // // Based on https://en.wikipedia.org/wiki/User:Novem_Linguae/Scripts/CiteHighlighter.js // Based on https://en.wikipedia.org/w/index.php?title=User:Headbomb/unreliable.js&oldid=1086050209 by User:Headbomb // Previous credits: //  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

$(async function {   "use strict";

function json_path_to_url(path) { return '/w/index.php?title=' + encodeURIComponent(path) + '&action=raw&ctype=text/json'; }

function escape_regex(s) { return s.replace(".", "\\.").replace("/", "(?:%2F|/)"); }

function prepare_rule(rule) { if (!("regex" in rule)) { if ("sites" in rule) { rule["regex"] = "[^-]\\b(?:" + rule["sites"].map(escape_regex).join("|") + ")\\b"; }       }        if ("regex" in rule) { rule["regex"] = new RegExp(rule["regex"], "i"); }       if ("filter" in rule) { rule["filter"] = eval(rule["filter"]); } else { rule["filter"] = true; }       return rule; }

function matches_rule(rule, el, text) { if (!rule["filter"]) { return false; }       if ("regex" in rule) { if (rule["regex"].test(text)) { return true; }       }        return false; }

function apply_rule(rule, el, text) { if (!matches_rule(rule, el, text)) { return false; }       const title = rule.comment || ''; $(el).attr("title", title); // Walk up to the first citation, if any, to highlight the full reference. var $el = $(el).closest('li[id^="cite_note-"]'); if ($el.length === 0) { $el = $(el); }       if ("css" in rule) { $el.css(rule.css); }       if ("kind" in rule) { $el.addClass("chl-" + rule.kind); }       $el.attr("title", title); return true; }

function apply_rules(rules, el, text) { $.each(rules, function(_, rule) {           if (apply_rule(rule, el, text)) {                return false;            }        }); }

const defaultSourceRulesPath = "User:MarioGom/Scripts/source-rules.json"; const sourceRulesPaths = window.sourceRulesPaths || [defaultSourceRulesPath]; const sourceRulesUrls = window.sourceRulesUrls || sourceRulesPaths.map(json_path_to_url);

var rules = []; for (let url of sourceRulesUrls) { console.log("URL", url); let rawRuleData = await $.ajax({           method: "GET",            dataType: "json",            url: url        }); console.log(rawRuleData); rules = rules.concat(rawRuleData["rules"].map(prepare_rule)); }

mw.util.addCSS(`       .chl-very-good {            background-color: #50ee50 !important;        }        .chl-good {            background-color: #90ee90 !important;        }        .chl-warn {            background-color: khaki !important;        }        .chl-bad {            background-color: #ffbbbb !important;        }        .chl-very-bad {            background-color: #ff9999 !important;            text-decoration: underline !important;            text-decoration-style: wavy !important;        }        .chl-blacklisted {            background-color: #dddddd !important;            text-decoration: underline !important;            text-decoration-style: wavy !important;            text-decoration-color: #cc0000 !important;        }    `);

// Check each external link on the page against each regex $('.mw-parser-output a.external').each(function(_, link) {       apply_rules(rules, link, link.href);    });

// 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) {       apply_rules(rules, li, li.textContent);    }); });