MediaWiki:Gadget-find-archived-section.js

/** _____________________________________________________________________________

* | |

* | === WARNING: GLOBAL GADGET FILE === |

* | Changes to this page affect many users. |

* | Please discuss changes on the talk page or on WT:Gadget before editing. |

* |_____________________________________________________________________________|

*

* Gadget to navigate to an archived section after following its broken link.

*

* Author: SD0001

* Documentation: User:SD0001/find-archived-section

*

*/

// START EDITING HERE FOR LOCALISATION

// Messages: translate these strings if porting to a non-English language wiki

mw.messages.set({

"fas-finding": 'Looks like the discussion "$1" has been archived. Finding archived discussion...',

"fas-exact-match": 'Looks like the discussion "$1" has been archived. Click to see archived discussion (or search in archives)',

"fas-inexact-match": 'Looks like the discussion "$1" has been archived. Click to search in archives.',

"fas-no-results": 'No search results found for section "$1" in archives. It may have been removed or renamed, or you may have followed a malformed link.',

});

var config = {

// Function to introduce arbitrary changes to prefix.

// Used here as archive page names used for admin noticeboards on enwiki are unusual

prefixNormaliser: function(prefix) {

switch (prefix) {

case "Wikipedia:Administrators' noticeboard/Incidents":

return "Wikipedia:Administrators' noticeboard/IncidentArchive";

case "Wikipedia:Administrators' noticeboard/Edit warring":

return "Wikipedia:Administrators' noticeboard/3RRArchive";

case "Wikipedia:Administrators' noticeboard":

return "Wikipedia:Administrators' noticeboard/Archive";

case "Wikipedia:Reference desk/Science":

return "Wikipedia:Reference desk/Archives/Science";

case "Wikipedia:Reference desk/Miscellaneous":

return "Wikipedia:Reference desk/Archives/Miscellaneous";

case "Wikipedia:Reference desk/Mathematics":

return "Wikipedia:Reference desk/Archives/Mathematics";

case "Wikipedia:Reference desk/Language":

return "Wikipedia:Reference desk/Archives/Language";

case "Wikipedia:Reference desk/Humanities":

return "Wikipedia:Reference desk/Archives/Humanities";

case "Wikipedia:Reference desk/Entertainment":

return "Wikipedia:Reference desk/Archives/Entertainment";

case "Wikipedia:Reference desk/Computing":

return "Wikipedia:Reference desk/Archives/Computing";

case "Wikipedia:Reference desk":

return "Wikipedia:Reference desk/Archives";

case "Wikipedia:Teahouse":

return "Wikipedia:Teahouse/Questions";

default:

return prefix;

}

}

};

// STOP EDITING HERE FOR LOCALISATION

$(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 the add section button) show on all talk & project space pages

if (!addsection && (!correctNs || !minerva)) {

return;

}

var sectionName = decodeURIComponent(

window.location.hash.slice(1) // to remove the leading #

.replace(/_/g, ' ')

);

// For anchor-encoded (UTF-8 percent encoding but with % replaced by a period (.) ), try to undo the encoding.

// For some strange reason, MediaWiki doesn't encode . itself, because of this the encoding process isn't

// exactly reversible. But this should work for the vast majority of cases.

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

/^c-/.test(sectionName) || //URLs used by DiscussionTools

/^\d{12} /.test(sectionName) || // URLs used by convenientDiscussions

/^noticeApplied-/.test(sectionName) || // URLs used by RedWarn

document.getElementById(sectionName.replace(/ /g, '_')) !== null) { // section exists on page

return;

}

var escapeQuotes = function(str) {

return str.replace(/"/g, '\\"');

};

$('#mw-content-text').before(

$('

')

.text(mw.msg('fas-finding', sectionName))

.addClass('archived-section-prompt')

.css({

'font-size': '90%',

'padding': '0 0 10px 20px'

})

);

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

// Apply normalisation for for admin noticeboards

if (typeof config.prefixNormaliser === 'function') {

prefix = config.prefixNormaliser(prefix);

}

var searchQuery = sectionNameDotDecoded === sectionName ?

'"' + escapeQuotes(sectionName) + '" prefix:"' + prefix + '"' :

'"' + escapeQuotes(sectionName) + '" OR "' + escapeQuotes(sectionNameDotDecoded) + '" prefix:"' + prefix + '"';

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

return new mw.Api({

ajax: { headers: { 'Api-User-Agent': 'w:en:MediaWiki:Gadget-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 results = json.query.search;

if (results.length === 0) {

$('.archived-section-prompt').html(mw.msg('fas-no-results', 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

for (var i in results) {

var result = results[i];

if (

result.sectiontitle &&

(result.sectiontitle === sectionName || result.sectiontitle === sectionNameDotDecoded)

) {

pageTitle = result.title;

sectionNameFound = result.sectiontitle;

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'

});

var escapedSectionName = mw.html.escape(sectionNameFound || sectionName);

if (pageTitle) { // if a section with the same name was found

var discussionLink = mw.util.getUrl(pageTitle) + '#' + mw.util.wikiUrlencode(sectionNameFound);

$('.archived-section-prompt').html(mw.msg('fas-exact-match', escapedSectionName, discussionLink, searchLink));

} else {

$('.archived-section-prompt').html(mw.msg('fas-inexact-match', escapedSectionName, searchLink));

}

}

}).catch(function(err) {

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

});

});