Difference between revisions of "MediaWiki:Common.js"

From Conceptual Reconstructionism Project
Line 48: Line 48:
     // Create one audio player per declared track
     // Create one audio player per declared track


     $('*[data-track]').each(function(trackNumber) {
     $('*[data-track]').each(function(trackNumber) {
         var audio = $('<audio></audio>')
         var audio = $('<audio></audio>')
Line 61: Line 62:


function onPlay(event) {
function onPlay(event) {
if (playbackData.playingAudioIndex !== null
if (playbackData.playingAudioIndex != null
&& playbackData.playingAudioIndex !== trackNumber) {
&& playbackData.playingAudioIndex !== trackNumber) {
playbackData.htmlAudios[playbackData.playingAudioIndex].pause();
playbackData.htmlAudios[playbackData.playingAudioIndex].pause();
Line 99: Line 100:
     // Create hyperlinks out of reconstruction markup
     // Create hyperlinks out of reconstruction markup


     $('*[data-def]').click(function() {
     $('*[data-def]').click(function() {
         var url = location.href;
         var url = location.href;
Line 108: Line 110:
     // Update timing data
     // Update timing data


     $('*[data-segment]').each(function() {
     $('*[data-segment]').each(function() {
 
         var m = /(?<track>\d+\/)?((?<minuteStart>\d+):)?(?<secondStart>\d+(.\d*)?)-((?<minuteEnd>\d+):)?(?<secondEnd>\d+(.\d*)?)/.exec($(this).attr('data-segment'));
         var m = /(?<track>\d+\/)?((?<minuteStart>\d+):)?(?<secondStart>\d+(.\d*)?)-((?<minuteEnd>\d+):)?(?<secondEnd>\d+(.\d*)?)/.exec($(this).attr('data-segment'));


if (m) {
if (m) {
playbackData.segments.push(new TimeSegment(
if (m.groups.track != null && playbackData.htmlAudios.length <= m.groups.track) {
m.groups.track? parseInt(m.groups.track) : 0,
$(this).append('Track number does not refer to existing track');
(m.groups.minuteStart? parseInt(m.groups.minuteStart) : 0) * 60 + parseFloat(m.groups.secondStart),
}
(m.groups.minuteEnd? parseInt(m.groups.minuteEnd) : 0) * 60 + parseFloat(m.groups.secondEnd),
else {
$(this).find('.meta-progress') ));
playbackData.segments.push(new TimeSegment(
m.groups.track? parseInt(m.groups.track) : 0,
(m.groups.minuteStart? parseInt(m.groups.minuteStart) : 0) * 60 + parseFloat(m.groups.secondStart),
(m.groups.minuteEnd? parseInt(m.groups.minuteEnd) : 0) * 60 + parseFloat(m.groups.secondEnd),
$(this).find('.meta-progress')
));
}
}
}
else {
else {
$(this).append('Wrong time segment');
$(this).append('Wrong syntax for segment time');
}
}
});
});
Line 126: Line 135:
playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; });
playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; });


// Add context menu for music references
$('*[data-segment]').each(function() {
$(this).append('<div class="meta-menu">\
<div><a>\u25B6 [-0 +0]</a></div>\
<div><a>\u25B6 [-2 +2]</a></div>\
<div><a>\u25B6 [-5 +5]</a></div>\
<div><a>\u25B6 [-10 +10]</a></div>\
</div>');
});
// Playing tick
// Playing tick
window.setInterval(function() {
window.setInterval(function() {
Line 157: Line 180:
}
}
if (playbackData.autostopTime !== null && currentTime >= playbackData.autostopTime) {
if (playbackData.autostopTime != null && currentTime >= playbackData.autostopTime) {
playingAudio.pause();
playingAudio.pause();
return;
return;
Line 164: Line 187:
}, 50);
}, 50);


// Implement the context menu for music references
$.getScript('/w/index.php?title=MediaWiki:Jquery_context_popup.js&action=raw&ctype=text/javascript', function() {
console.log('loaded plugin')
var myMenu =  '<div>\
  <div>great</div>\
  <div>bof</div>\
  <div>meh</div>\
</div>';
$('*[data-segment]').popup({
content: myMenu,
// Where the popup will show by default- top.
// Other options: right, bottom, or left
position: 'bottom', 
// Menu Element theme. Defaults to popupTheme, but custom class can be set instead
theme: "",
// Default no style, will revert to default colours.
// Other options: blue, red, green, custom
style: "", 
// Standard animation by default.
// Other options: flip, grow, bounce
animation: "standard", 
// Default set to "click".
// Can also be set to hover
event: 'click',
// When true, clicking off the menu closes it. When false, only clicking on the menu closes it.
hideOnClick: true, 
});
console.log('set menus')
});
});
});

Revision as of 09:51, 20 December 2021

/* Any JavaScript here will be loaded for all users on every page load. */


function TimeSegment(trackIndex, startTime, endTime, element) {
	this.trackIndex = trackIndex;
	this.startTime = startTime;
	this.endTime = endTime;
	this.element = element;
}


TimeSegment.prototype.isDisabled = function() {
	return !this.element.hasClass('active');
};


TimeSegment.prototype.disable = function() {
	this.element.removeClass('active');
};


TimeSegment.prototype.update = function(trackIndex, currentTime) {
	var percent = 100.0 * Math.max(currentTime - this.startTime, 0) / (this.endTime - this.startTime)
	if (trackIndex === this.trackIndex && percent > 0.0 && percent < 100.0) {
		this.element.get(0).style.setProperty('--gauge-fill',  percent + "%");
		this.element.addClass('active');
	} else {
		this.disable();
	}
};


function PlaybackData() {
	this.autostopTime = null;
	this.segments = [];
	this.htmlAudios = [];
	this.closestPlayableSegIndex = 0;
	this.playingAudioIndex = null;
};


var playbackData = new PlaybackData();


$(document).ready(function() {


    // Create one audio player per declared track

	
    $('*[data-track]').each(function(trackNumber) {
        var audio = $('<audio></audio>')
			.prop('controls', true)
			.attr('preload', 'auto')
			.attr('src', $(this).attr('data-track'));
        
		$('<figure></figure>')
			.append($('<figcaption></figcaption>')
				.text($(this).attr('data-track-title')))
			.appendTo($(this))
			.append(audio);

		function onPlay(event) {
			if (playbackData.playingAudioIndex != null
				&& playbackData.playingAudioIndex !== trackNumber) {
				playbackData.htmlAudios[playbackData.playingAudioIndex].pause();
			}
			playbackData.playingAudioIndex = trackNumber;
		}
		
		function onPause(event) {
			playbackData.autostopTime = null;
			playbackData.playingAudioIndex = null;
			playbackData.closestPlayableSegIndex = 0;
		}
		
		function onSeeked(event) {
			playbackData.closestPlayableSegIndex = 0;
			playbackData.segments.forEach(function(s) { s.disable(); });
		}
		
		function onEnded(event) {
			var nextPlayingAudioIndex = playbackData.playingAudioIndex + 1;
			onPause(event);
			onSeeked(event);
			if (nextPlayingAudioIndex < playbackData.htmlAudios.length) {
				playbackData.htmlAudios[nextPlayingAudioIndex].play();
			}
		}
		
        audio.on('play', onPlay);
        audio.on('pause', onPause);
		audio.on('ended', onEnded);
		audio.on('seeked', onSeeked);
		
        playbackData.htmlAudios.push(audio.get(0));
    });


    // Create hyperlinks out of reconstruction markup

	
    $('*[data-def]').click(function() {
        var url = location.href;
        location.href = "#" + $(this).attr('data-def');
        history.replaceState(null, null, url);
    });


    // Update timing data

	
    $('*[data-segment]').each(function() {
		
        var m = /(?<track>\d+\/)?((?<minuteStart>\d+):)?(?<secondStart>\d+(.\d*)?)-((?<minuteEnd>\d+):)?(?<secondEnd>\d+(.\d*)?)/.exec($(this).attr('data-segment'));

		if (m) {
			if (m.groups.track != null && playbackData.htmlAudios.length <= m.groups.track) {
				$(this).append('Track number does not refer to existing track');
			}
			else {
				playbackData.segments.push(new TimeSegment(
					m.groups.track? parseInt(m.groups.track) : 0,
					(m.groups.minuteStart? parseInt(m.groups.minuteStart) : 0) * 60 + parseFloat(m.groups.secondStart),
					(m.groups.minuteEnd? parseInt(m.groups.minuteEnd) : 0) * 60 + parseFloat(m.groups.secondEnd),
					$(this).find('.meta-progress')
				));
			}
		}
		else {
			$(this).append('Wrong syntax for segment time');
		}
	});

	playbackData.segments.sort(function(a, b) { return a.startTime - b.startTime; });

	
	// Add context menu for music references
	
	
	$('*[data-segment]').each(function() {
		$(this).append('<div class="meta-menu">\
			<div><a>\u25B6 [-0 +0]</a></div>\
			<div><a>\u25B6 [-2 +2]</a></div>\
			<div><a>\u25B6 [-5 +5]</a></div>\
			<div><a>\u25B6 [-10 +10]</a></div>\
		</div>');
	});
	
	
	// Playing tick
	
	
	window.setInterval(function() {
		if (playbackData.playingAudioIndex === null) {
			return;
		}
		var playingAudio = playbackData.htmlAudios[playbackData.playingAudioIndex];
		var currentTime = playingAudio.currentTime;
		
		var previouSegmentActive = false;
		
		for(var segIndex = playbackData.closestPlayableSegIndex;
			segIndex < playbackData.segments.length;
			segIndex++) {
			var segment = playbackData.segments[segIndex];
			segment.update(playbackData.playingAudioIndex, currentTime);
			
			if (segment.isDisabled()) {
				if (segment.startTime > currentTime) {
					break;
				}
				continue;
			}

			if (!previouSegmentActive) {
				playbackData.closestPlayableSegIndex = segIndex;
			}
			previouSegmentActive = true;
		}
		
		if (playbackData.autostopTime != null && currentTime >= playbackData.autostopTime) {
			playingAudio.pause();
			return;
		}

	}, 50);

});