MediaWiki:Common.js: Difference between revisions
Fix library Remove/Delete buttons for Media: /images/ links |
Add Internet Archive click-to-play embeds for interview watchlist |
||
| (8 intermediate revisions by the same user not shown) | |||
| Line 546: | Line 546: | ||
}); | }); | ||
var $cards = $('.mw-parser-output .yt-interview | function interviewCardRef($el) { | ||
var yt = String($el.attr('data-youtube-id') || ''); | |||
if (yt) { | |||
return { key: 'yt:' + yt, href: '#yt-' + yt }; | |||
} | |||
var sc = String($el.attr('data-soundcloud-track') || ''); | |||
if (sc) { | |||
return { key: 'sc:' + sc, href: '#sc-' + sc }; | |||
} | |||
return null; | |||
} | |||
var $cards = $('.mw-parser-output .yt-interview').filter(function () { | |||
return interviewCardRef($(this)) !== null; | |||
}); | |||
$cards.each(function (idx) { | $cards.each(function (idx) { | ||
var $card = $(this); | var $card = $(this); | ||
| Line 558: | Line 572: | ||
} | } | ||
var mine = splitSoldiers($card.attr('data-soldiers')); | var mine = splitSoldiers($card.attr('data-soldiers')); | ||
var selfRef = interviewCardRef($card); | |||
var picks = []; | var picks = []; | ||
var seen = {}; | var seen = {}; | ||
function addCard($other, why) { | function addCard($other, why) { | ||
var | var ref = interviewCardRef($other); | ||
if (! | if (!ref || !selfRef || seen[ref.key] || ref.key === selfRef.key) { | ||
return; | return; | ||
} | } | ||
seen[ | seen[ref.key] = 1; | ||
picks.push({ | picks.push({ | ||
href: ref.href, | |||
heading: String($other.attr('data-heading') || $other.find('h3, h2').first().text() || 'Interview'), | heading: String($other.attr('data-heading') || $other.find('h3, h2').first().text() || 'Interview'), | ||
short: String($other.attr('data-short') || ''), | short: String($other.attr('data-short') || ''), | ||
| Line 593: | Line 608: | ||
picks.slice(0, 3).forEach(function (item) { | picks.slice(0, 3).forEach(function (item) { | ||
var label = item.short ? (item.heading + ' — ' + item.short) : item.heading; | var label = item.short ? (item.heading + ' — ' + item.short) : item.heading; | ||
var $a = $('<a></a>').attr('href', | var $a = $('<a></a>').attr('href', item.href).text(label); | ||
var $li = $('<li></li>').append($a); | var $li = $('<li></li>').append($a); | ||
if (item.why === 'same soldier') { | if (item.why === 'same soldier') { | ||
| Line 603: | Line 618: | ||
.append($('<div class="yt-interview-next-label"></div>').text('Watch next')) | .append($('<div class="yt-interview-next-label"></div>').text('Watch next')) | ||
.append($list); | .append($list); | ||
}); | |||
}()); | |||
(function buildSoundCloudEmbeds() { | |||
var SC_TRACK = /^[0-9]{6,12}$/; | |||
function playSoundCloud($slot, trackId, title) { | |||
var src = 'https://w.soundcloud.com/player/?url=' + | |||
encodeURIComponent('https://api.soundcloud.com/tracks/' + trackId) + | |||
'&color=%23ff5500&auto_play=true&hide_related=true&show_comments=false' + | |||
'&show_user=true&show_reposts=false&show_teaser=false&visual=true'; | |||
var $iframe = $('<iframe class="sc-embed-frame" scrolling="no" frameborder="no" allow="autoplay"></iframe>') | |||
.attr({ | |||
src: src, | |||
title: title || 'SoundCloud audio', | |||
loading: 'lazy' | |||
}); | |||
$slot.empty().append($iframe).addClass('sc-embed-playing'); | |||
} | |||
$('.mw-parser-output .sc-embed[data-soundcloud-track]').each(function () { | |||
var $slot = $(this); | |||
if ($slot.data('rbScEmbed')) { | |||
return; | |||
} | |||
var trackId = String($slot.attr('data-soundcloud-track') || ''); | |||
if (!SC_TRACK.test(trackId)) { | |||
return; | |||
} | |||
$slot.data('rbScEmbed', 1); | |||
var title = String($slot.attr('data-title') || 'SoundCloud audio'); | |||
var $fallback = $slot.find('.sc-embed-fallback').first(); | |||
var $btn = $('<button type="button" class="sc-embed-play"></button>') | |||
.attr('aria-label', 'Play ' + title) | |||
.append($('<span class="sc-embed-play-icon" aria-hidden="true"></span>')) | |||
.append($('<span class="sc-embed-play-text"></span>').text('Play audio')); | |||
var $poster = $('<div class="sc-embed-poster"></div>').append($btn); | |||
if ($fallback.length) { | |||
$fallback.before($poster); | |||
$fallback.hide(); | |||
} else { | |||
$slot.prepend($poster); | |||
} | |||
$poster.on('click', function (ev) { | |||
ev.preventDefault(); | |||
playSoundCloud($slot, trackId, title); | |||
}); | |||
}); | |||
}()); | |||
(function buildAviaryEmbeds() { | |||
var AV_MEDIA = /^[0-9]{4,12}$/; | |||
function playAviary($slot, mediaId, title) { | |||
var src = 'https://milken.aviaryplatform.com/embed/media/' + | |||
encodeURIComponent(mediaId) + | |||
'?embed=true&media_player=true'; | |||
var $iframe = $('<iframe class="aviary-embed-frame" allowfullscreen allow="autoplay; encrypted-media; fullscreen; picture-in-picture"></iframe>') | |||
.attr({ | |||
src: src, | |||
title: title || 'Aviary media', | |||
loading: 'lazy' | |||
}); | |||
$slot.empty().append($iframe).addClass('aviary-embed-playing'); | |||
} | |||
$('.mw-parser-output .aviary-embed[data-aviary-media]').each(function () { | |||
var $slot = $(this); | |||
if ($slot.data('rbAviaryEmbed')) { | |||
return; | |||
} | |||
var mediaId = String($slot.attr('data-aviary-media') || ''); | |||
if (!AV_MEDIA.test(mediaId)) { | |||
return; | |||
} | |||
$slot.data('rbAviaryEmbed', 1); | |||
var title = String($slot.attr('data-title') || 'Aviary media'); | |||
var playLabel = String($slot.attr('data-play-label') || 'Play video'); | |||
var $fallback = $slot.find('.aviary-embed-fallback').first(); | |||
var $btn = $('<button type="button" class="aviary-embed-play"></button>') | |||
.attr('aria-label', playLabel + ' — ' + title) | |||
.append($('<span class="aviary-embed-play-icon" aria-hidden="true"></span>')) | |||
.append($('<span class="aviary-embed-play-text"></span>').text(playLabel)); | |||
var $poster = $('<div class="aviary-embed-poster"></div>').append($btn); | |||
if ($fallback.length) { | |||
$fallback.before($poster); | |||
$fallback.hide(); | |||
} else { | |||
$slot.prepend($poster); | |||
} | |||
$poster.on('click', function (ev) { | |||
ev.preventDefault(); | |||
playAviary($slot, mediaId, title); | |||
}); | |||
}); | |||
}()); | |||
(function buildInternetArchiveEmbeds() { | |||
// archive.org item identifiers (e.g. RobertA.Potash13january2012YiddishBookCenter) | |||
var IA_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{5,120}$/; | |||
function playInternetArchive($slot, itemId, title) { | |||
var src = 'https://archive.org/embed/' + encodeURIComponent(itemId); | |||
var $iframe = $('<iframe class="ia-embed-frame" allowfullscreen allow="autoplay; encrypted-media; fullscreen; picture-in-picture"></iframe>') | |||
.attr({ | |||
src: src, | |||
title: title || 'Internet Archive media', | |||
loading: 'lazy' | |||
}); | |||
$slot.empty().append($iframe).addClass('ia-embed-playing'); | |||
} | |||
$('.mw-parser-output .ia-embed[data-archive-id]').each(function () { | |||
var $slot = $(this); | |||
if ($slot.data('rbIaEmbed')) { | |||
return; | |||
} | |||
var itemId = String($slot.attr('data-archive-id') || ''); | |||
if (!IA_ID.test(itemId)) { | |||
return; | |||
} | |||
$slot.data('rbIaEmbed', 1); | |||
var title = String($slot.attr('data-title') || 'Internet Archive media'); | |||
var playLabel = String($slot.attr('data-play-label') || 'Play interview'); | |||
var $fallback = $slot.find('.ia-embed-fallback').first(); | |||
var $btn = $('<button type="button" class="ia-embed-play"></button>') | |||
.attr('aria-label', playLabel + ' — ' + title) | |||
.append($('<span class="ia-embed-play-icon" aria-hidden="true"></span>')) | |||
.append($('<span class="ia-embed-play-text"></span>').text(playLabel)); | |||
var $poster = $('<div class="ia-embed-poster"></div>').append($btn); | |||
if ($fallback.length) { | |||
$fallback.before($poster); | |||
$fallback.hide(); | |||
} else { | |||
$slot.prepend($poster); | |||
} | |||
$poster.on('click', function (ev) { | |||
ev.preventDefault(); | |||
playInternetArchive($slot, itemId, title); | |||
}); | |||
}); | }); | ||
}()); | }()); | ||
| Line 1,031: | Line 1,186: | ||
} | } | ||
var negative = /fail(?:ed|ure)?|flunk|wash(?:ed)?\s*out|kick(?:ed)?\s*out|dismiss|expel|unsatisfactor|poor\s+(?:performance|work|grades)|awol|court[-\s]?martial|disciplin|discharged\s+for\s+cause|drop(?:ped)?\s+(?:out|from)|relieved|eliminat|unfit|misconduct|desert|excess\s+absence|absence\s*\(|\billness\b|sick\s+call|medical\s+board|psychiatr|neurot|homosexual|suicid|alcohol(?:ism)?|drunk|intoxicat|venereal|\bVD\b|syphili|gonorrh|mental\s+(?:case|illness)|nervous\s+breakdown|not\s+graduat|did\s+not\s+graduate|physically\s+unfit|unfit\s+for|non[-\s]?graduate|certificate\s+listed\s+as\s+ng/i; | var negative = /fail(?:ed|ure)?|flunk|wash(?:ed)?\s*out|kick(?:ed)?\s*out|dismiss|expel|unsatisfactor|poor\s+(?:performance|work|grades)|awol|court[-\s]?martial|disciplin|discharged\s+for\s+cause|drop(?:ped)?\s+(?:out|from)|relieved|eliminat|unfit|misconduct|desert|excess\s+absence|absence\s*\(|\billness\b|sick\s+call|medical\s+board|psychiatr|neurot|homosexual|suicid|alcohol(?:ism)?|drunk|intoxicat|venereal|\bVD\b|syphili|gonorrh|mental\s+(?:case|illness)|nervous\s+breakdown|not\s+graduat|did\s+not\s+graduate|physically\s+unfit|unfit\s+for|non[-\s]?graduate|certificate\s+listed\s+as\s+ng|(?:^|\b)NG\b(?:\s+Class|\s+OB|\s*$|\s*[,;:/]|\s+\d)|\bnongrad/i; | ||
var $ul = $heading.nextAll('ul').first(); | var $ul = $heading.nextAll('ul').first(); | ||
if (!$ul.length) { | if (!$ul.length) { | ||
| Line 1,274: | Line 1,429: | ||
{ key: 'death_year', label: 'Death year', hint: 'Four digits, e.g. 2001' }, | { key: 'death_year', label: 'Death year', hint: 'Four digits, e.g. 2001' }, | ||
{ key: 'nativity', label: 'Nativity (birthplace)' }, | { key: 'nativity', label: 'Nativity (birthplace)' }, | ||
{ key: 'religion', label: 'Religion | { key: 'religion', label: 'Religion' } | ||
] | ] | ||
}, | }, | ||
| Line 1,300: | Line 1,451: | ||
collapsed: true, | collapsed: true, | ||
fields: [ | fields: [ | ||
{ key: 'other_class', label: 'Other class' }, | { | ||
key: 'other_class', | |||
label: 'Other class', | |||
hint: 'Roster code, e.g. SC8, DC36, MITU4 (shown expanded on the page)' | |||
}, | |||
{ key: 'division', label: 'Unit / division' }, | { key: 'division', label: 'Unit / division' }, | ||
{ key: 'loc', label: 'LOC | { key: 'loc', label: 'LOC' } | ||
] | ] | ||
} | } | ||
| Line 3,732: | Line 3,885: | ||
}()); | }()); | ||
/* Related-media wrap removed: story/interview cues already sit under the lead | |||
* with their own labels (Full story, etc.). Wrapping them added a stray | |||
* Related media heading near the top of the article. */ | |||