From Wikipedia, the free encyclopedia
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 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 = citesi].getAttribute('id');										// get citeref anchor from cites[]

		if ((idi in citeref_tgt_counts))										// is target in the associative array

			citeref_tgt_countsidi++;											// yep, bump the count

		else

			citeref_tgt_countsidi = 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\">Harv error: link from " + href + " doesn't point to any citation.</span>"));

		else if (1 < citeref_tgt_countshref])

			{

			$(elem.parentNode).append(" ", $("<span class=\"ttm_harv_err_dup\">Harv error: " + href + " has multiple targets (" + citeref_tgt_countshref + "×).</span>"));

			citeref_source_idshref = 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 publications = $content.find('#Publications').parent().nextUntil('h2').find('.citation').get();			// get all cites inside a Publications section



		var sections = further_reading, external_links, publications];			// 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

		filtered_cites = filtered_cites.filter(function(x) { return publications.indexOf(x) === -1; });		// all cites not in 'Publications' section

		

		var id;

		var query;



		for(i=0; i < filtered_cites.length; i++)

			{

			id = filtered_citesi].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_citesi].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_citesi]).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 < sectionss].length; i++)								// look for linked cites in sections[s]

				{

				id = sectionss][i].getAttribute('id');

				query = 'a[href|="#' + $.escapeSelector(id) + '"]';

				if($content.find(query).length !== 0)

					$(sectionss][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 = citesi].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_countsidi])

				$(citesi]).append(" ", $("<span class=\"ttm_err_harv_dup\">Harv error: duplicate target for " + idi + ".</span>"));

			}

		}

	});