var H5P = H5P || {}; /** * Constructor. * * @param {Object} params Options for this library. * @param {Number} id Content identifier * @returns {undefined} */ (function ($) { H5P.Image = function (params, id, extras) { H5P.EventDispatcher.call(this); this.extras = extras; if (params.file === undefined || !(params.file instanceof Object)) { this.placeholder = true; } else { this.source = H5P.getPath(params.file.path, id); this.width = params.file.width; this.height = params.file.height; } this.alt = (!params.decorative && params.alt !== undefined) ? this.stripHTML(this.htmlDecode(params.alt)) : ''; if (params.title !== undefined) { this.title = this.stripHTML(this.htmlDecode(params.title)); } }; H5P.Image.prototype = Object.create(H5P.EventDispatcher.prototype); H5P.Image.prototype.constructor = H5P.Image; /** * Wipe out the content of the wrapper and put our HTML in it. * * @param {jQuery} $wrapper * @returns {undefined} */ H5P.Image.prototype.attach = function ($wrapper) { var self = this; var source = this.source; if (self.$img === undefined) { if(self.placeholder) { self.$img = $('
', { width: '100%', height: '100%', class: 'h5p-placeholder', title: this.title === undefined ? '' : this.title, on: { load: function () { self.trigger('loaded'); } } }); } else { self.$img = $('', { width: '100%', height: '100%', src: source, alt: this.alt, title: this.title === undefined ? '' : this.title, on: { load: function () { self.trigger('loaded'); } } }); } } $wrapper.addClass('h5p-image').html(self.$img); }; /** * Retrieve decoded HTML encoded string. * * @param {string} input HTML encoded string. * @returns {string} Decoded string. */ H5P.Image.prototype.htmlDecode = function (input) { const dparser = new DOMParser().parseFromString(input, 'text/html'); return dparser.documentElement.textContent; }; /** * Retrieve string without HTML tags. * * @param {string} input Input string. * @returns {string} Output string. */ H5P.Image.prototype.stripHTML = function (html) { const div = document.createElement('div'); div.innerHTML = html; return div.textContent || div.innerText || ''; }; return H5P.Image; }(H5P.jQuery)); ; var H5P = H5P || {}; /** * H5P Link Library Module. */ H5P.Link = (function ($) { /** * Link constructor. * * @param {Object} parameters */ function Link(parameters) { // Add default parameters parameters = $.extend(true, { title: 'New link', linkWidget: { protocol: '', url: '' } }, parameters); var url = ''; if (parameters.linkWidget.protocol !== 'other') { url += parameters.linkWidget.protocol; } url += parameters.linkWidget.url; /** * Public. Attach. * * @param {jQuery} $container */ this.attach = function ($container) { var sanitizedUrl = sanitizeUrlProtocol(url); $container.addClass('h5p-link').html('' + parameters.title + '') .keypress(function (event) { if (event.which === 32) { this.click(); } }); }; /** * Return url * * @returns {string} */ this.getUrl = function () { return url; }; /** * Private. Remove illegal url protocols from uri */ var sanitizeUrlProtocol = function(uri) { var allowedProtocols = ['http', 'https', 'ftp', 'irc', 'mailto', 'news', 'nntp', 'rtsp', 'sftp', 'ssh', 'tel', 'telnet', 'webcal']; var first = true; var before = ''; while (first || uri != before) { first = false; before = uri; var colonPos = uri.indexOf(':'); if (colonPos > 0) { // We found a possible protocol var protocol = uri.substr(0, colonPos); // If the colon is preceeded by a hash, slash or question mark it isn't a protocol if (protocol.match(/[/?#]/g)) { break; } // Is this a forbidden protocol? if (allowedProtocols.indexOf(protocol.toLowerCase()) == -1) { // If illegal, remove the protocol... uri = uri.substr(colonPos + 1); } } } return uri; }; } return Link; })(H5P.jQuery); ; H5P.AdvancedText = (function ($, EventDispatcher) { /** * A simple library for displaying text with advanced styling. * * @class H5P.AdvancedText * @param {Object} parameters * @param {Object} [parameters.text='New text'] * @param {number} id */ function AdvancedText(parameters, id) { var self = this; EventDispatcher.call(this); var html = (parameters.text === undefined ? 'New text' : parameters.text); /** * Wipe container and add text html. * * @alias H5P.AdvancedText#attach * @param {H5P.jQuery} $container */ self.attach = function ($container) { $container.addClass('h5p-advanced-text').html(html); }; } AdvancedText.prototype = Object.create(EventDispatcher.prototype); AdvancedText.prototype.constructor = AdvancedText; return AdvancedText; })(H5P.jQuery, H5P.EventDispatcher); ; 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 = $('
', { 'class': INNER_CONTAINER + (transparentMode ? ' h5p-audio-transparent' : '') }).appendTo($container); var audioButton = $('