User:Mathglot/HarvErrors.js

// 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(" ", $("Harv error: link from " + href + " doesn't point to any citation. ")); // +MOD+ dflt and override classes		else if (1 < citeref_tgt_counts[href])			{			$(elem.parentNode).append(" ", $("Harv error: " + href + " has multiple targets (" + citeref_tgt_counts[href] + "×). "));			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(" ", $("Harv warning: There is no link pointing to this citation. The anchor is named " + id + ". ")); }

// 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(" ", $("Harv error: linked from " + id + ". ")); }			}

// 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(" ", $("Harv error: duplicate target for " + idi + ". ")); }		}	});