MediaWiki:Gadget-find-archived-section.js: Difference between revisions

Content deleted Content added
try to find section even if anchor is dot-encoded, load dependencies only when needed
+case "Wikipedia:Teahouse":
 
(16 intermediate revisions by 5 users not shown)
Line 1:
/** _____________________________________________________________________________
(function() {
* | |
* | === 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. <b><a href="$2">Click to see archived discussion</a></b> <small>(<a href="$3">or search in archives</a>)</small>',
"fas-inexact-match": 'Looks like the discussion "$1" has been archived. <a href="$2">Click to search in archives</a>.',
"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');
Line 6 ⟶ 66:
 
// 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;
Line 12 ⟶ 72:
 
var sectionName = decodeURIComponent(
window.___location.hash.slice(1) // .slice(1) to remove the leading #
.replace(/_/g, ' ')
);
 
// Try to undo theFor anchor encoding-encoded (UTF-8 percent encoding but with % replaced by a period (.) ), try to undo the encoding.
// For some strange reason, theMediaWiki doesn't encode . itself, isn'tbecause encoded,of this means 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(
$('<div>')
.text(mw.msg('Looks like the discussion "fas-finding' +, sectionName + '" has been archived. Finding archived discussion...'))
.addClass('archived-section-prompt')
.css({
Line 39 ⟶ 106:
var prefix = mw.config.get('wgPageName').replace(/_/g, ' ');
 
// Apply normalisation for for admin noticeboards
// For admin noticeboards, archive pages titles are unusual
if (typeof config.prefixNormaliser === 'function') {
if (prefix === "Wikipedia:Administrators' noticeboard/Incidents") {
prefix = config.prefixNormaliser(prefix);
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";
}
 
var searchQuery = sectionNameDotDecoded === sectionName ?
mw.loader.using(['mediawiki.util', 'mediawiki.api'], function() {
'"' + escapeQuotes(sectionName) + '" prefix:"' + prefix + '"' :
'"' + escapeQuotes(sectionName) + '" OR "' + escapeQuotes(sectionNameDotDecoded) + '" prefix:"' + prefix + '"';
 
mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() {
var searchQuery = sectionNameDotDecoded === sectionName ?
'"' + sectionName + '" prefix:"' + prefix + '"' :
'"' + sectionName + '" OR "' + sectionNameDotDecoded + '" prefix:"' + prefix + '"';
 
return new mw.Api({
ajax: { headers: { 'Api-User-Agent': 'w:en:UserMediaWiki:SD0001/Gadget-find-archived-section.js' } }
}).get({
action: 'query',
Line 63 ⟶ 126:
srsort: 'create_timestamp_desc', // list more recent archives first
srlimit: '20'
});
}).then(function(json) {
if (!json || !json.query || !json.query.search) {
return;
}
 
}).then(function(json) {
var divHtml;
varif results(!json =|| !json.query || !json.query.search;) {
return;
if (results.length === 0) {
}
divHtml = 'No search results found for archived discussion "' + mw.html.escape(sectionName) + '"';
 
var results = json.query.search;
} else {
if (results.length === 0) {
var pageTitle,
$('.archived-section-prompt').html(mw.msg('fas-no-results', mw.html.escape(sectionName)));
sectionNameFound; // will either be sectionName or sectionNameDotDecoded
 
} else {
// obtain the the first exact section title match (which would be from the most recent archive)
var pageTitle,
// this loop iterates over just one item in the vast majority of cases
varsectionNameFound; sectionName_// =will either be sectionName.replace(/ /g,or '_');sectionNameDotDecoded
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_) {
 
// obtain the the first exact section title match (which would be from the most recent archive)
pageTitle = result.title;
// this loop iterates over just one item in the vast majority of cases
sectionNameFound = result.sectiontitle.replace(/_/g, ' ');
for (var i in results) {
break;
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'
});
 
divHtmlvar escapedSectionName = 'Looks like the discussion "' + mw.html.escape(sectionNameFound) +|| '" has been archived. '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));
divHtml += '<b><a href="' + discussionLink + '">Click to see archived discussion</a></b> ';
} else {
divHtml += '<small><a href="' + searchLink + '">(or search in archives)</a></small>. ';
$('.archived-section-prompt').html(mw.msg('fas-inexact-match', escapedSectionName, searchLink));
 
} else {
divHtml += '<a href="' + searchLink + '">Click to search in archives</a>. ';
}
}
}
 
}).catch(function(err) {
$('.archived-section-prompt').html(divHtml);
console.error('[find-archived-section]: ', JSON.stringify(err));
 
}).fail(function(err) {
console.error('[find-archived-section]: ', JSON.stringify(err));
});
 
});
 
})();