User:Trappist the monk/HarvErrors.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// tweaked copy of [[User:Ucucha/HarvErrors.js]]mw.loader.addStyleTag ('.ttm_harv_err {color:DarkOrange}' +// no target error message default color'.ttm_harv_err_dup {color:#C3F}' +// duplicate target error message default color (sfn or harv template – source)'.ttm_err_harv_dup {color:#C3F}' +// duplicate target error message default color (citation template – target)'.ttm_harv_warn {color:#ac6600}'// warning message default color);mw.hook( 'wikipage.content' ).add( function( $content ){var cites = $content.find('.citation');// get all cites on the pagevar citeref_tgt_counts = {};// associative array of citerefs as key, their number as valuevar citeref_source_ids = {};// associative array of citerefs from sfn, harv templatesvar idi;// citeref id in and iterated loopfor (var i=0; i < cites.length; i++)// fill the array; to be used when identifying multiple targets{idi = cites[i].getAttribute('id');// get citeref anchor from cites[]if ((idi in citeref_tgt_counts))// is target in the associative arrayciteref_tgt_counts[idi]++;// yep, bump the countelseciteref_tgt_counts[idi] = 1;// nope, add it with a count of one}var href, links = $content.find( 'a[href^="#CITEREF"]' );// make a list of harv and sfn linkslinks.each( function (i, elem)// first check: do links in Harvard citations point to a valid citation?{href = elem.getAttribute( 'href' ).substring(1); //skip the #// IDs can contain characters like . that have meaning in selectors// use $.escapeSelector to make sure they are escapedif ( $content.find( '#' + $.escapeSelector(href) ).length < 1)$(elem.parentNode).append(" ", $("<span class=\"ttm_harv_err\">Harv error: link from " + href + " doesn't point to any citation.</span>"));else if (1 < citeref_tgt_counts[href]){$(elem.parentNode).append(" ", $("<span class=\"ttm_harv_err_dup\">Harv error: " + href + " has multiple targets (" + citeref_tgt_counts[href] + "×).</span>"));citeref_source_ids[href] = 1;// add this citeref to the list; duplicates simply overwrite}});// second check: do CITEREF IDs have Harvard citations pointing to them?if (0 !== links.length)// non-zero when links were found{var further_reading = $content.find('#Further_reading').parent().nextUntil('h2, .mw-heading2').find('.citation').get();// get all cites inside a Further reading sectionvar external_links = $content.find('#External_links').parent().nextUntil('h2, .mw-heading2').find('.citation').get();// get all cites inside a External links sectionvar publications = $content.find('#Publications').parent().nextUntil('h2, .mw-heading2').find('.citation').get();// get all cites inside a Publications sectionvar sections = [further_reading, external_links, publications];// make an array of links in these sectionsvar filtered_cites = cites.get().filter(function(x) { return further_reading.indexOf(x) === -1; });// all cites not in 'Further reading' sectionfiltered_cites = filtered_cites.filter(function(x) { return external_links.indexOf(x) === -1; });// all cites not in 'External links' sectionfiltered_cites = filtered_cites.filter(function(x) { return publications.indexOf(x) === -1; });// all cites not in 'Publications' sectionvar id;var query;for(i=0; i < filtered_cites.length; i++){id = filtered_cites[i].getAttribute('id');// we only need to check citations with an id that is a CITEREF idif(!id || id.indexOf('CITEREF') !== 0)continue;// don't do cites that are inside a refvar parentid = filtered_cites[i].parentNode.parentNode.getAttribute('id');if(parentid && parentid.indexOf('cite_note') === 0)continue;// check for links to this citationquery = 'a[href|="#' + $.escapeSelector(id) + '"]';if($content.find(query).length === 0)$(filtered_cites[i]).append(" ", $("<span class=\"ttm_harv_warn\">Harv warning: There is no link pointing to this citation. The anchor is named " + id + ".</span>"));}// third check: are Harvard citations pointing to citerefs in inappropriate article sections?for (var s=0; s < sections.length; s++)// loop through the list of sections{for (i=0; i < sections[s].length; i++)// look for linked cites in sections[s]{id = sections[s][i].getAttribute('id');query = 'a[href|="#' + $.escapeSelector(id) + '"]';if($content.find(query).length !== 0)$(sections[s][i]).append(" ", $("<span class=\"ttm_harv_err\">Harv error: linked from " + id + ".</span>"));}}// fourth check: do Harvard citations have multiple targets?for (i=0; i < cites.length; i++){idi = cites[i].getAttribute('id');if (!(idi in citeref_source_ids))// only check citations that have matching sfn or ref templatescontinue;if(!idi || idi.indexOf('CITEREF') !== 0)// only check citations with an id that is a CITEREF idcontinue;if (1 < citeref_tgt_counts[idi])$(cites[i]).append(" ", $("<span class=\"ttm_err_harv_dup\">Harv error: duplicate target for " + idi + ".</span>"));}}});