Remove thin-profile Still needed checklist
Fill Teammates lists from live Category:Team membership
Line 8: Line 8:
  * Reorder Special:Search hits so title matches and site pages rank above research-notes noise.
  * Reorder Special:Search hits so title matches and site pages rank above research-notes noise.
  * Hide retired “(merged duplicate)” roster pages from find/search suggestions and results.
  * Hide retired “(merged duplicate)” roster pages from find/search suggestions and results.
* Fill soldier Teammates rails from live Category:Team … membership (no roster-module rebuild).
  */
  */
function rbIsMergedDuplicateTitle(title) {
function rbIsMergedDuplicateTitle(title) {
Line 2,996: Line 2,997:
});
});
});
});
(function rbLiveTeammates() {
var $rails = $('.mw-parser-output .soldier-related[data-current-title]');
if (!$rails.length || !mw.Api) {
return;
}
function titleToCaption(title) {
var m = String(title || '').match(/^([^,]+),\s*(.+?)\s*\(/);
if (m) {
return $.trim(m[2] + ' ' + m[1]);
}
return String(title || '');
}
function wikiLink(title, caption) {
return $('<a></a>')
.attr('href', mw.util.getUrl(title))
.attr('title', title)
.text(caption || titleToCaption(title));
}
function fetchCategoryMembers(catTitle) {
var titles = [];
function next(cont) {
var params = {
action: 'query',
list: 'categorymembers',
cmtitle: catTitle,
cmlimit: 'max',
cmnamespace: 0,
cmtype: 'page'
};
if (cont) {
params.cmcontinue = cont;
}
return new mw.Api().get(params).then(function (data) {
var members = (data.query && data.query.categorymembers) || [];
members.forEach(function (m) {
if (m.title && !rbIsMergedDuplicateTitle(m.title)) {
titles.push(m.title);
}
});
var more = data.continue && data.continue.cmcontinue;
if (more) {
return next(more);
}
return titles;
});
}
return next(null);
}
$rails.each(function () {
var $rail = $(this);
if ($rail.data('rbLiveTeammates')) {
return;
}
$rail.data('rbLiveTeammates', 1);
var current = String($rail.attr('data-current-title') || mw.config.get('wgPageName') || '')
.replace(/_/g, ' ');
$rail.find('.soldier-related-block[data-team-cat]').each(function () {
var $block = $(this);
var cat = String($block.attr('data-team-cat') || '');
if (!/^Category:Team /.test(cat)) {
return;
}
var $links = $block.find('.soldier-related-links-live').first();
if (!$links.length) {
return;
}
$links.text('Loading teammates…');
fetchCategoryMembers(cat).done(function (titles) {
var others = titles.filter(function (t) {
return t.replace(/_/g, ' ') !== current;
});
others.sort(function (a, b) {
return titleToCaption(a).localeCompare(titleToCaption(b));
});
$links.empty();
if (!others.length) {
$links.append(document.createTextNode('No other teammates listed yet · '));
$links.append(wikiLink(cat, 'full roster'));
return;
}
var max = 24;
others.slice(0, max).forEach(function (title, i) {
if (i > 0) {
$links.append(document.createTextNode(' · '));
}
$links.append(wikiLink(title, titleToCaption(title)));
});
$links.append(document.createTextNode(' · '));
$links.append(wikiLink(cat, others.length > max ? 'full roster (' + others.length + ')' : 'full roster'));
}).fail(function () {
$links.empty().append(wikiLink(cat, 'Browse team roster'));
});
});
});
}());


(function rbBooksFilters() {
(function rbBooksFilters() {