User:Lagewi/bibliography.js

From Wikidata
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
(function () {
	if (!mw.config.exists('wbEntityId')	|| mw.config.get('wgCanonicalNamespace') !== '') {
		return;
	}

	const $header = $(document.createElement('h2'));
	$header.text('Bibliography');
	$header.attr('id', 'bibliography');
	$header.addClass('wb-section-heading section-heading');
	const $container = $(document.createElement('div'));
	$container.css({
		float: 'left',
    	'margin-bottom': '1em'
	});
	$container.text('Loading...');
	$('.wikibase-entityview-main').append($header, $container);
	
	const elements = {};
	const bibliography = [];
	const items = [];
	$('.wikibase-referenceview').each(function (i, reference) {
		const $statements = $(reference).find('.wikibase-snakview');
		const $statedAs = $statements.has('.wikibase-snakview-property [title="Property:P248"]');
		const $referenceUrl = $statements.has('.wikibase-snakview-property [title="Property:P854"]');
		if ($statedAs.length) {
			const id = $statedAs.find('.wikibase-snakview-value a[title]').attr('title');
			if (elements[id]) {
				elements[id].push(reference);
			} else {
				elements[id] = [reference];
				bibliography.push(id);
				items.push(id);
			}
		} else if ($referenceUrl.length) {
			const url = $referenceUrl.find('.wikibase-snakview-value a').attr('href');
			if (elements[url]) {
				elements[url].push(reference);
			} else {
				elements[url] = [reference];
				bibliography.push(url);
			}
		}
	});
	
	if (bibliography.length === 0) {
		$container.text('No references');
	} else if (items.length === 0) {
		displayReferences(bibliography, []);
	} else {
		fetch('https://citation-js.toolforge.org/api/v1/export/' + items.join() + '/bibliography?format=html&asEntryArray=true')
			.then(function (response) { return response.json() })
			.then(function (response) { displayReferences(bibliography, response) });
	}
	
	function displayReferences (bibliography, response) {
		const items = {};
		for (let i = 0; i < response.length; i++) {
			items[response[i][0]] = response[i][1];
		}
		
		$container.empty();
		const $list = $(document.createElement('ol'));
		for (let i = 0; i < bibliography.length; i++) {
			const noteNumber = i + 1;
			
			// Note
			{
				const $sup = $(document.createElement('sup'));
				const $a = $(document.createElement('a'));
				$a.attr('href', '#bibliography-' + noteNumber);
				$a.text('[' + noteNumber + ']');
				$sup.append($a);
				
				const $heading = $(elements[bibliography[i]]).find('.wikibase-referenceview-heading');
				$heading.show();
				$heading.prepend($sup);
			}
			
			// Reference
			const $reference = $(document.createElement('li'));
			$reference.attr('id', 'bibliography-' + noteNumber);
			
			// Reference content
			if (items[bibliography[i]]) {
				$reference.html(items[bibliography[i]]);
			} else {
				const $div = $(document.createElement('div'));
				const $a = $(document.createElement('a'));
				$a.attr('href', bibliography[i]);
				$a.text(bibliography[i]);
				$div.append($a);
				$reference.append($div);
			}
			
			// Backlinks
			for (const element of elements[bibliography[i]]) {
				const id = $(element).parents('.wikibase-statementview').attr('id');
				const property = $(element).parents('.wikibase-statementgroupview')
					.find('.wikibase-statementgroupview-property-label a')
					.attr('title').slice('Property:'.length);
				const $sup = $(document.createElement('sup'));
				const $a = $(document.createElement('a'));
				$a.attr('href', '#' + id);
				$a.text('[' + property + ']');
				$sup.append($a);
				$reference.append($sup, ' ');
			}
			
			$list.append($reference);
		}
		$container.append($list);
	}
})();