// copy of [[User:Trappist the monk/HarvErrors.js]] rev. 1171512037 of 15:14, 21 August 2023; look for '+MOD+' flags.
mw.hook( 'wikipage.content' ).add( function( $content )
{
mw.loader.addStyleTag ('.ttm_harv_err_dflt {color:DarkOrange}'); // +MOD+ no target error message default color
mw.loader.addStyleTag ('.ttm_harv_err_dup {color:#C3F}'); // duplicate target error message default color (sfn or harv template – source)
mw.loader.addStyleTag ('.ttm_err_harv_dup {color:#C3F}'); // duplicate target error message default color (citation template – target)
mw.loader.addStyleTag ('.ttm_harv_warn {color:#ac6600}'); // warning message default color
// load User:Username/HarvErrors.css here if it exists
var cites = $content.find('.citation'); // get all cites on the page
var citeref_tgt_counts = {}; // associative array of citerefs as key, their number as value
var citeref_source_ids = {}; // associative array of citerefs from sfn, harv templates
var idi; // citeref id in and iterated loop
for (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 array
citeref_tgt_counts[idi]++; // yep, bump the count
else
citeref_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 links
links.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 escaped
if ( $content.find( '#' + $.escapeSelector(href) ).length < 1)
$(elem.parentNode).append(" ", $("<span class=\"ttm_harv_err ttm_harv_err_dflt\">Harv error: link from " + href + " doesn't point to any citation.</span>")); // +MOD+ dflt and override classes
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').find('.citation').get(); // get all cites inside a Further reading section
var external_links = $content.find('#External_links').parent().nextUntil('h2').find('.citation').get(); // get all cites inside a External links section
var sections = [further_reading, external_links]; // make an array of links in these sections
var filtered_cites = cites.get().filter(function(x) { return further_reading.indexOf(x) === -1; }); // all cites not in 'Further reading' section
filtered_cites = filtered_cites.filter(function(x) { return external_links.indexOf(x) === -1; }); // all cites not in 'External links' section
var 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 id
if(!id || id.indexOf('CITEREF') !== 0)
continue;
// don't do cites that are inside a ref
var parentid = filtered_cites[i].parentNode.parentNode.getAttribute('id');
if(parentid && parentid.indexOf('cite_note') === 0)
continue;
// check for links to this citation
query = '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 templates
continue;
if(!idi || idi.indexOf('CITEREF') !== 0) // only check citations with an id that is a CITEREF id
continue;
if (1 < citeref_tgt_counts[idi])
$(cites[i]).append(" ", $("<span class=\"ttm_err_harv_dup\">Harv error: duplicate target for " + idi + ".</span>"));
}
}
});