Sindbad~EG File Manager
var H5P = H5P || {};
/**
* H5P audio module
*
* @external {jQuery} $ H5P.jQuery
*/
H5P.Audio = (function ($) {
/**
* @param {Object} params Options for this library.
* @param {Number} id Content identifier.
* @param {Object} extras Extras.
* @returns {undefined}
*/
function C(params, id, extras) {
H5P.EventDispatcher.call(this);
this.contentId = id;
this.params = params;
this.extras = extras;
this.toggleButtonEnabled = true;
// Retrieve previous state
if (extras && extras.previousState !== undefined) {
this.oldTime = extras.previousState.currentTime;
}
this.params = $.extend({}, {
playerMode: 'minimalistic',
fitToWrapper: false,
controls: true,
autoplay: false,
audioNotSupported: "Your browser does not support this audio",
playAudio: "Play audio",
pauseAudio: "Pause audio",
propagateButtonClickEvents: true
}, params);
// Required if e.g. used in CoursePresentation as area to click on
if (this.params.playerMode === 'transparent') {
this.params.fitToWrapper = true;
}
this.on('resize', this.resize, this);
}
C.prototype = Object.create(H5P.EventDispatcher.prototype);
C.prototype.constructor = C;
/**
* Adds a minimalistic audio player with only "play" and "pause" functionality.
*
* @param {jQuery} $container Container for the player.
* @param {boolean} transparentMode true: the player is only visible when hovering over it; false: player's UI always visible
*/
C.prototype.addMinimalAudioPlayer = function ($container, transparentMode) {
var INNER_CONTAINER = 'h5p-audio-inner';
var AUDIO_BUTTON = 'h5p-audio-minimal-button';
var PLAY_BUTTON = 'h5p-audio-minimal-play';
var PLAY_BUTTON_PAUSED = 'h5p-audio-minimal-play-paused';
var PAUSE_BUTTON = 'h5p-audio-minimal-pause';
var self = this;
this.$container = $container;
self.$inner = $('<div/>', {
'class': INNER_CONTAINER + (transparentMode ? ' h5p-audio-transparent' : '')
}).appendTo($container);
var audioButton = $('<button/>', {
'class': AUDIO_BUTTON + " " + PLAY_BUTTON,
'aria-label': this.params.playAudio
}).appendTo(self.$inner)
.click( function (event) {
if (!self.params.propagateButtonClickEvents){
event.stopPropagation();
}
if (!self.isEnabledToggleButton()) {
return;
}
// Prevent ARIA from playing over audio on click
this.setAttribute('aria-hidden', 'true');
if (self.audio.paused) {
self.play();
}
else {
self.pause();
}
})
.on('focusout', function () {
// Restore ARIA, required when playing longer audio and tabbing out and back in
this.setAttribute('aria-hidden', 'false');
});
// Fit to wrapper
if (this.params.fitToWrapper) {
audioButton.css({
'width': '100%',
'height': '100%'
});
}
//Event listeners that change the look of the player depending on events.
self.audio.addEventListener('ended', function () {
audioButton
.attr('aria-hidden', false)
.attr('aria-label', self.params.playAudio)
.removeClass(PAUSE_BUTTON)
.removeClass(PLAY_BUTTON_PAUSED)
.addClass(PLAY_BUTTON);
});
self.audio.addEventListener('play', function () {
audioButton
.attr('aria-label', self.params.pauseAudio)
.removeClass(PLAY_BUTTON)
.removeClass(PLAY_BUTTON_PAUSED)
.addClass(PAUSE_BUTTON);
});
self.audio.addEventListener('pause', function () {
// Don't override if initial look is set
if (!audioButton.hasClass(PLAY_BUTTON)) {
audioButton
.attr('aria-hidden', false)
.attr('aria-label', self.params.playAudio)
.removeClass(PAUSE_BUTTON)
.addClass(PLAY_BUTTON_PAUSED);
}
});
H5P.Audio.MINIMAL_BUTTON = AUDIO_BUTTON + " " + PLAY_BUTTON;
H5P.Audio.MINIMAL_BUTTON_PAUSED = AUDIO_BUTTON + " " + PLAY_BUTTON_PAUSED;
this.$audioButton = audioButton;
// Scale icon to container
self.resize();
};
/**
* Resizes the audio player icon when the wrapper is resized.
*/
C.prototype.resize = function () {
// Find the smallest value of height and width, and use it to choose the font size.
if (this.params.fitToWrapper && this.$container && this.$container.width()) {
var w = this.$container.width();
var h = this.$container.height();
if (w < h) {
this.$audioButton.css({'font-size': w / 2 + 'px'});
}
else {
this.$audioButton.css({'font-size': h / 2 + 'px'});
}
}
};
return C;
})(H5P.jQuery);
/**
* Wipe out the content of the wrapper and put our HTML in it.
*
* @param {jQuery} $wrapper Our poor container.
*/
H5P.Audio.prototype.attach = function ($wrapper) {
const self = this;
$wrapper.addClass('h5p-audio-wrapper');
// Check if browser supports audio.
var audio = document.createElement('audio');
if (audio.canPlayType === undefined) {
this.attachNotSupportedMessage($wrapper);
return;
}
// Add supported source files.
if (this.params.files !== undefined && this.params.files instanceof Object) {
for (var i = 0; i < this.params.files.length; i++) {
var file = this.params.files[i];
if (audio.canPlayType(file.mime)) {
var source = document.createElement('source');
source.src = H5P.getPath(file.path, this.contentId);
source.type = file.mime;
audio.appendChild(source);
}
}
}
if (!audio.children.length) {
this.attachNotSupportedMessage($wrapper);
return;
}
if (this.endedCallback !== undefined) {
audio.addEventListener('ended', this.endedCallback, false);
}
audio.className = 'h5p-audio';
audio.controls = this.params.controls === undefined ? true : this.params.controls;
// Menu removed, because it's cut off if audio is used as H5P.Question intro
const controlsList = 'nodownload noplaybackrate';
audio.setAttribute('controlsList', controlsList);
audio.preload = 'auto';
audio.style.display = 'block';
if (this.params.fitToWrapper === undefined || this.params.fitToWrapper) {
audio.style.width = '100%';
if (!this.isRoot()) {
// Only set height if this isn't a root
audio.style.height = '100%';
}
}
this.audio = audio;
if (this.params.playerMode === 'minimalistic') {
audio.controls = false;
this.addMinimalAudioPlayer($wrapper, false);
}
else if (this.params.playerMode === 'transparent') {
audio.controls = false;
this.addMinimalAudioPlayer($wrapper, true);
}
else {
$wrapper.html(audio);
}
if (audio.controls) {
$wrapper.addClass('h5p-audio-controls');
}
// Set time to saved time from previous run
if (this.oldTime) {
if (this.$audioButton) {
this.$audioButton.attr('class', H5P.Audio.MINIMAL_BUTTON_PAUSED);
}
this.seekTo(this.oldTime);
}
// Avoid autoplaying in authoring tool
if (window.H5PEditor === undefined) {
// Keep record of autopauses.
// I.e: we don't wanna autoplay if the user has excplicitly paused.
self.autoPaused = true;
// Set up intersection observer
new IntersectionObserver(function (entries) {
const entry = entries[0];
if (entry.intersectionRatio == 0) {
if (!self.audio.paused) {
// Audio element is hidden, pause it
self.autoPaused = true;
self.audio.pause();
}
}
else if (self.params.autoplay && self.autoPaused) {
// Audio element is visible. Autoplay if autoplay is enabled and it was
// not explicitly paused by a user
self.autoPaused = false;
self.play();
}
}, {
root: document.documentElement,
threshold: [0, 1] // Get events when it is shown and hidden
}).observe($wrapper.get(0));
}
};
/**
* Attaches not supported message.
*
* @param {jQuery} $wrapper Our dear container.
*/
H5P.Audio.prototype.attachNotSupportedMessage = function ($wrapper) {
$wrapper.addClass('h5p-audio-not-supported');
$wrapper.html(
'<div class="h5p-audio-inner">' +
'<div class="h5p-audio-not-supported-icon"><span/></div>' +
'<span>' + this.params.audioNotSupported + '</span>' +
'</div>'
);
if (this.endedCallback !== undefined) {
this.endedCallback();
}
}
/**
* Stop & reset playback.
*
* @returns {undefined}
*/
H5P.Audio.prototype.resetTask = function () {
this.stop();
this.seekTo(0);
if (this.$audioButton) {
this.$audioButton.attr('class', H5P.Audio.MINIMAL_BUTTON);
}
};
/**
* Stop the audio. TODO: Rename to pause?
*
* @returns {undefined}
*/
H5P.Audio.prototype.stop = function () {
if (this.audio !== undefined) {
this.audio.pause();
}
};
/**
* Play
*/
H5P.Audio.prototype.play = function () {
if (this.audio !== undefined) {
// play() returns a Promise that can fail, e.g. while autoplaying
this.audio.play().catch((error) => {
console.warn(error);
});
}
};
/**
* @public
* Pauses the audio.
*/
H5P.Audio.prototype.pause = function () {
if (this.audio !== undefined) {
this.audio.pause();
}
};
/**
* @public
* Seek to audio position.
*
* @param {number} seekTo Time to seek to in seconds.
*/
H5P.Audio.prototype.seekTo = function (seekTo) {
if (this.audio !== undefined) {
this.audio.currentTime = seekTo;
}
};
/**
* @public
* Get current state for resetting it later.
*
* @returns {object} Current state.
*/
H5P.Audio.prototype.getCurrentState = function () {
if (this.audio !== undefined && this.audio.currentTime > 0) {
const currentTime = this.audio.ended ? 0 : this.audio.currentTime;
return {
currentTime: currentTime
};
}
};
/**
* @public
* Disable button.
* Not using disabled attribute to block button activation, because it will
* implicitly set tabindex = -1 and confuse ChromeVox navigation. Clicks handled
* using "pointer-events: none" in CSS.
*/
H5P.Audio.prototype.disableToggleButton = function () {
this.toggleButtonEnabled = false;
if (this.$audioButton) {
this.$audioButton.addClass(H5P.Audio.BUTTON_DISABLED);
}
};
/**
* @public
* Enable button.
*/
H5P.Audio.prototype.enableToggleButton = function () {
this.toggleButtonEnabled = true;
if (this.$audioButton) {
this.$audioButton.removeClass(H5P.Audio.BUTTON_DISABLED);
}
};
/**
* @public
* Check if button is enabled.
* @return {boolean} True, if button is enabled. Else false.
*/
H5P.Audio.prototype.isEnabledToggleButton = function () {
return this.toggleButtonEnabled;
};
/** @constant {string} */
H5P.Audio.BUTTON_DISABLED = 'h5p-audio-disabled';
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists