Jump to content

MediaWiki:Gadget-find-archived-section.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by SD0001 (talk | contribs) at 21:32, 13 November 2019 (try to find section even if anchor is dot-encoded, load dependencies only when needed). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
(function() {

	var addsection = document.getElementById('ca-addsection');
	var correctNs = mw.config.get('wgNamespaceNumber') % 2 === 1 || mw.config.get('wgNamespaceNumber') === 4;
	var minerva = mw.config.get('skin') === 'minerva';

	// Show only on discussion pages (pages with "add section" button)
	// On minerva skin (which doesn't use add section button) show on all talk & project space pages
	if (!addsection && (!correctNs || !minerva)) {
		return;
	}

	var sectionName = decodeURIComponent(
		window.location.hash.slice(1)  // .slice(1) to remove the leading #
		.replace(/_/g, ' ')
	);

	// Try to undo the anchor encoding (UTF-8 percent encoding but with % replaced by . )
	// For some strange reason, the . itself isn't encoded, this means the encoding process isn't
	// exactly reversible
	var sectionNameDotDecoded = decodeURIComponent(sectionName.replace(/\.([0-9A-F]{2})/g, '%$1'));

	if (!sectionName || // no section name in URL
		sectionName.indexOf('/media/') === 0 || // URLs used by MediaViewer
		document.getElementById(sectionName.replace(/ /g, '_')) !== null) { // section exists on page
			return;
	}

	$('#mw-content-text').before(
		$('<div>')
			.text('Looks like the discussion "' + sectionName + '" has been archived. Finding archived discussion...')
			.addClass('archived-section-prompt')
			.css({
				'font-size': '90%',
				'padding': '0 0 10px 20px'
			})
	);

	var prefix = mw.config.get('wgPageName').replace(/_/g, ' ');

	// For admin noticeboards, archive pages titles are unusual
	if (prefix === "Wikipedia:Administrators' noticeboard/Incidents") {
		prefix = "Wikipedia:Administrators' noticeboard/IncidentArchive";
	} else if (prefix === "Wikipedia:Administrators' noticeboard/Edit warring") {
		prefix = "Wikipedia:Administrators' noticeboard/3RRArchive";
	} else if (prefix === "Wikipedia:Administrators' noticeboard") {
		prefix = "Wikipedia:Administrators' noticeboard/Archive";
	}

	mw.loader.using(['mediawiki.util', 'mediawiki.api'], function() {

		var searchQuery = sectionNameDotDecoded === sectionName ?
		'"' + sectionName + '" prefix:"' + prefix + '"' :
		'"' + sectionName + '" OR "' + sectionNameDotDecoded + '" prefix:"' + prefix + '"';

		new mw.Api({
			ajax: { headers: { 'Api-User-Agent': 'w:en:User:SD0001/find-archived-section.js' } }
		}).get({
			action: 'query',
			list: 'search',
			srsearch: searchQuery,
			srprop: 'sectiontitle',
			srsort: 'create_timestamp_desc', // list more recent archives first
			srlimit: '20'
		}).then(function(json) {
			if (!json || !json.query || !json.query.search) {
				return;
			}

			var divHtml;
			var results = json.query.search;
			if (results.length === 0) {
				divHtml = 'No search results found for archived discussion "' + mw.html.escape(sectionName) + '"';

			} else {
				var pageTitle,
					sectionNameFound; // will either be sectionName or sectionNameDotDecoded

				// obtain the the first exact section title match (which would be from the most recent archive)
				// this loop iterates over just one item in the vast majority of cases
				var sectionName_ = sectionName.replace(/ /g, '_');
				var sectionNameDotDecoded_ = sectionNameDotDecoded.replace(/ /g, '_');
				for (var i in results) {
					var result = results[i];
					// sectiontitle in API output has spaces encoded as underscores
					if (result.sectiontitle) {
						if (result.sectiontitle === sectionName_ ||
							result.sectiontitle === sectionNameDotDecoded_) {

							pageTitle = result.title;
							sectionNameFound = result.sectiontitle.replace(/_/g, ' ');
							break;
						}
					}
				}

				var searchLink = mw.util.getUrl('Special:Search', {
					search: '~' + searchQuery, // ~ in the beginning forces a search even if a page of the same name exists, see [[H:FORCE]]
					prefix: prefix,
					sort: 'create_timestamp_desc'
				});

				divHtml = 'Looks like the discussion "' + mw.html.escape(sectionNameFound) + '" has been archived. ';

				if (pageTitle) { // if a section with the same name was found
					var discussionLink = mw.util.getUrl(pageTitle) + '#' + mw.util.wikiUrlencode(sectionNameFound);
					divHtml += '<b><a href="' + discussionLink + '">Click to see archived discussion</a></b> ';
					divHtml += '<small><a href="' + searchLink + '">(or search in archives)</a></small>. ';

				} else {
					divHtml += '<a href="' + searchLink + '">Click to search in archives</a>. ';
				}
			}

			$('.archived-section-prompt').html(divHtml);

		}).fail(function(err) {
			console.error('[find-archived-section]: ', JSON.stringify(err));
		});

	});

})();