diff --git a/js/h5p-event-dispatcher.js b/js/h5p-event-dispatcher.js index 1d52ef7..b6f59a6 100644 --- a/js/h5p-event-dispatcher.js +++ b/js/h5p-event-dispatcher.js @@ -1,21 +1,26 @@ -/** @namespace H5P */ var H5P = H5P || {}; /** - * The Event class for the EventDispatcher + * The Event class for the EventDispatcher. + * * @class + * @param {string} type + * @param {*} data + * @param {Object} [extras] + * @param {boolean} [extras.bubbles] + * @param {boolean} [extras.external] */ H5P.Event = function(type, data, extras) { this.type = type; this.data = data; var bubbles = false; - + // Is this an external event? var external = false; - + // Is this event scheduled to be sent externally? var scheduledForExternal = false; - + if (extras === undefined) { extras = {}; } @@ -25,31 +30,29 @@ H5P.Event = function(type, data, extras) { if (extras.external === true) { external = true; } - + /** * Prevent this event from bubbling up to parent - * - * @returns {undefined} */ this.preventBubbling = function() { bubbles = false; }; - + /** * Get bubbling status - * - * @returns {Boolean} - true if bubbling false otherwise + * + * @returns {boolean} + * true if bubbling false otherwise */ this.getBubbles = function() { return bubbles; }; - + /** * Try to schedule an event for externalDispatcher - * - * @returns {Boolean} - * - true if external and not already scheduled - * - false otherwise + * + * @returns {boolean} + * true if external and not already scheduled, otherwise false */ this.scheduleForExternal = function() { if (external && !scheduledForExternal) { @@ -60,18 +63,28 @@ H5P.Event = function(type, data, extras) { }; }; +/** + * Callback type for event listeners. + * + * @callback H5P.EventCallback + * @param {H5P.Event} event + */ + H5P.EventDispatcher = (function () { /** * The base of the event system. * Inherit this class if you want your H5P to dispatch events. + * * @class + * @memberof H5P */ function EventDispatcher() { var self = this; /** * Keep track of listeners for each event. + * * @private * @type {Object} */ @@ -80,11 +93,14 @@ H5P.EventDispatcher = (function () { /** * Add new event listener. * - * @public - * @throws {TypeError} listener - Must be a function - * @param {String} type - Event type - * @param {Function} listener - Event listener - * @param {Function} thisArg - Optionally specify the this value when calling listener. + * @throws {TypeError} + * listener must be a function + * @param {string} type + * Event type + * @param {H5P.EventCallback} listener + * Event listener + * @param {function} thisArg + * Optionally specify the this value when calling listener. */ this.on = function (type, listener, thisArg) { if (thisArg === undefined) { @@ -110,11 +126,14 @@ H5P.EventDispatcher = (function () { /** * Add new event listener that will be fired only once. * - * @public - * @throws {TypeError} listener - must be a function - * @param {String} type - Event type - * @param {Function} listener - Event listener - * @param {Function} thisArg - Optionally specify the this value when calling listener. + * @throws {TypeError} + * listener must be a function + * @param {string} type + * Event type + * @param {H5P.EventCallback} listener + * Event listener + * @param {function} thisArg + * Optionally specify the this value when calling listener. */ this.once = function (type, listener, thisArg) { if (thisArg === undefined) { @@ -136,10 +155,12 @@ H5P.EventDispatcher = (function () { * Remove event listener. * If no listener is specified, all listeners will be removed. * - * @public - * @throws {TypeError} listener - must be a function - * @param {String} type - Event type - * @param {Function} listener - Event listener + * @throws {TypeError} + * listener must be a function + * @param {string} type + * Event type + * @param {H5P.EventCallback} listener + * Event listener */ this.off = function (type, listener) { if (listener !== undefined && !(listener instanceof Function)) { @@ -175,45 +196,48 @@ H5P.EventDispatcher = (function () { /** * Dispatch event. * - * @public - * @param {String|Function} event - Event object or event type as string - * @param {mixed} eventData - * Custom event data(used when event type as string is used as first - * argument + * @param {string|H5P.Event} event + * Event object or event type as string + * @param {*} [eventData] + * Custom event data(used when event type as string is used as first + * argument). + * @param {Object} [extras] + * @param {boolean} [extras.bubbles] + * @param {boolean} [extras.external] */ this.trigger = function (event, eventData, extras) { if (event === undefined) { return; } - if (typeof event === 'string') { + if (typeof event === 'string') { // TODO: Check instanceof String as well? event = new H5P.Event(event, eventData, extras); } else if (eventData !== undefined) { event.data = eventData; } - + // Check to see if this event should go externally after all triggering and bubbling is done var scheduledForExternal = event.scheduleForExternal(); - + if (triggers[event.type] !== undefined) { // Call all listeners for (var i = 0; i < triggers[event.type].length; i++) { triggers[event.type][i].listener.call(triggers[event.type][i].thisArg, event); } } - + if (triggers['*'] !== undefined) { // Call all * listeners - for (var i = 0; i < triggers['*'].length; i++) { - triggers['*'][i].listener.call(triggers['*'][i].thisArg, event); + for (var j = 0; j < triggers['*'].length; j++) { + triggers['*'][j].listener.call(triggers['*'][j].thisArg, event); } } - + // Bubble - if (event.getBubbles() && self.parent instanceof H5P.EventDispatcher && typeof self.parent.trigger === 'function') { + if (event.getBubbles() && self.parent instanceof H5P.EventDispatcher && typeof self.parent.trigger === 'function') { // TODO: Check instanceof Function as well? self.parent.trigger(event); } - + if (scheduledForExternal) { H5P.externalDispatcher.trigger(event); } diff --git a/js/h5p-x-api-event.js b/js/h5p-x-api-event.js index d26a3b7..c28b4d3 100644 --- a/js/h5p-x-api-event.js +++ b/js/h5p-x-api-event.js @@ -1,11 +1,12 @@ var H5P = H5P || {}; /** - * Constructor for xAPI events + * Used for xAPI events. * * @class + * @extends H5P.Event */ -H5P.XAPIEvent = function() { +H5P.XAPIEvent = function () { H5P.Event.call(this, 'xAPI', {'statement': {}}, {bubbles: true, external: true}); }; @@ -13,12 +14,12 @@ H5P.XAPIEvent.prototype = Object.create(H5P.Event.prototype); H5P.XAPIEvent.prototype.constructor = H5P.XAPIEvent; /** - * Helperfunction to set scored result statements + * Set scored result statements. * - * @param {int} score - * @param {int} maxScore + * @param {number} score + * @param {number} maxScore */ -H5P.XAPIEvent.prototype.setScoredResult = function(score, maxScore) { +H5P.XAPIEvent.prototype.setScoredResult = function (score, maxScore) { this.data.statement.result = { 'score': { 'min': 0, @@ -29,13 +30,14 @@ H5P.XAPIEvent.prototype.setScoredResult = function(score, maxScore) { }; /** - * Helperfunction to set a verb. + * Set a verb. * * @param {string} verb - * Verb in short form, one of the verbs defined at - * http://adlnet.gov/expapi/verbs/ + * Verb in short form, one of the verbs defined at + * {@link http://adlnet.gov/expapi/verbs/|ADL xAPI Vocabulary} + * */ -H5P.XAPIEvent.prototype.setVerb = function(verb) { +H5P.XAPIEvent.prototype.setVerb = function (verb) { if (H5P.jQuery.inArray(verb, H5P.XAPIEvent.allowedXAPIVerbs) !== -1) { this.data.statement.verb = { 'id': 'http://adlnet.gov/expapi/verbs/' + verb, @@ -50,13 +52,15 @@ H5P.XAPIEvent.prototype.setVerb = function(verb) { }; /** - * Helperfunction to get the statements verb id + * Get the statements verb id. * * @param {boolean} full - * if true the full verb id prefixed by http://adlnet.gov/expapi/verbs/ will be returned - * @returns {string} - Verb or null if no verb with an id has been defined + * if true the full verb id prefixed by http://adlnet.gov/expapi/verbs/ + * will be returned + * @returns {string} + * Verb or null if no verb with an id has been defined */ -H5P.XAPIEvent.prototype.getVerb = function(full) { +H5P.XAPIEvent.prototype.getVerb = function (full) { var statement = this.data.statement; if ('verb' in statement) { if (full === true) { @@ -70,13 +74,14 @@ H5P.XAPIEvent.prototype.getVerb = function(full) { }; /** - * Helperfunction to set the object part of the statement. + * Set the object part of the statement. * * The id is found automatically (the url to the content) * - * @param {object} instance - the H5P instance + * @param {Object} instance + * The H5P instance */ -H5P.XAPIEvent.prototype.setObject = function(instance) { +H5P.XAPIEvent.prototype.setObject = function (instance) { if (instance.contentId) { this.data.statement.object = { 'id': this.getContentXAPIId(instance), @@ -107,11 +112,12 @@ H5P.XAPIEvent.prototype.setObject = function(instance) { }; /** - * Helperfunction to set the context part of the statement. + * Set the context part of the statement. * - * @param {object} instance - the H5P instance + * @param {Object} instance + * The H5P instance */ -H5P.XAPIEvent.prototype.setContext = function(instance) { +H5P.XAPIEvent.prototype.setContext = function (instance) { if (instance.parent && (instance.parent.contentId || instance.parent.subContentId)) { var parentId = instance.parent.subContentId === undefined ? instance.parent.contentId : instance.parent.subContentId; this.data.statement.context = { @@ -128,9 +134,9 @@ H5P.XAPIEvent.prototype.setContext = function(instance) { }; /** - * Helper function to set the actor, email and name will be added automatically + * Set the actor. Email and name will be added automatically. */ -H5P.XAPIEvent.prototype.setActor = function() { +H5P.XAPIEvent.prototype.setActor = function () { if (H5PIntegration.user !== undefined) { this.data.statement.actor = { 'name': H5PIntegration.user.name, @@ -160,7 +166,8 @@ H5P.XAPIEvent.prototype.setActor = function() { /** * Get the max value of the result - score part of the statement * - * @returns {int} the max score, or null if not defined + * @returns {number} + * The max score, or null if not defined */ H5P.XAPIEvent.prototype.getMaxScore = function() { return this.getVerifiedStatementValue(['result', 'score', 'max']); @@ -169,12 +176,19 @@ H5P.XAPIEvent.prototype.getMaxScore = function() { /** * Get the raw value of the result - score part of the statement * - * @returns {int} the max score, or null if not defined + * @returns {number} + * The score, or null if not defined */ H5P.XAPIEvent.prototype.getScore = function() { return this.getVerifiedStatementValue(['result', 'score', 'raw']); }; +/** + * Get content xAPI ID. + * + * @param {Object} instance + * The H5P instance + */ H5P.XAPIEvent.prototype.getContentXAPIId = function (instance) { var xAPIId; if (instance.contentId && H5PIntegration && H5PIntegration.contents) { @@ -184,15 +198,16 @@ H5P.XAPIEvent.prototype.getContentXAPIId = function (instance) { } } return xAPIId; -} +}; /** * Figure out if a property exists in the statement and return it * - * @param {array} keys - * List describing the property we're looking for. For instance - * ['result', 'score', 'raw'] for result.score.raw - * @returns the value of the property if it is set, null otherwise + * @param {string[]} keys + * List describing the property we're looking for. For instance + * ['result', 'score', 'raw'] for result.score.raw + * @returns {*} + * The value of the property if it is set, null otherwise. */ H5P.XAPIEvent.prototype.getVerifiedStatementValue = function(keys) { var val = this.data.statement; @@ -206,7 +221,7 @@ H5P.XAPIEvent.prototype.getVerifiedStatementValue = function(keys) { }; /** - * List of verbs defined at http://adlnet.gov/expapi/verbs/ + * List of verbs defined at {@link http://adlnet.gov/expapi/verbs/|ADL xAPI Vocabulary} * * @type Array */ diff --git a/js/h5p-x-api.js b/js/h5p-x-api.js index 87a6267..ea5ba79 100644 --- a/js/h5p-x-api.js +++ b/js/h5p-x-api.js @@ -1,31 +1,41 @@ var H5P = H5P || {}; -// Create object where external code may register and listen for H5P Events +/** + * The external event dispatcher. Others, outside of H5P may register and + * listen for H5P Events here. + * + * @type {H5P.EventDispatcher} + */ H5P.externalDispatcher = new H5P.EventDispatcher(); // EventDispatcher extensions /** - * Helper function for triggering xAPI added to the EventDispatcher + * Helper function for triggering xAPI added to the EventDispatcher. * - * @param {string} verb - the short id of the verb we want to trigger - * @param {oject} extra - extra properties for the xAPI statement + * @param {string} verb + * The short id of the verb we want to trigger + * @param {Oject} [extra] + * Extra properties for the xAPI statement */ -H5P.EventDispatcher.prototype.triggerXAPI = function(verb, extra) { +H5P.EventDispatcher.prototype.triggerXAPI = function (verb, extra) { this.trigger(this.createXAPIEventTemplate(verb, extra)); }; /** - * Helper function to create event templates added to the EventDispatcher + * Helper function to create event templates added to the EventDispatcher. * * Will in the future be used to add representations of the questions to the * statements. * - * @param {string} verb - verb id in short form - * @param {object} extra - Extra values to be added to the statement - * @returns {Function} - XAPIEvent object + * @param {string} verb + * Verb id in short form + * @param {Object} [extra] + * Extra values to be added to the statement + * @returns {H5P.XAPIEvent} + * Instance */ -H5P.EventDispatcher.prototype.createXAPIEventTemplate = function(verb, extra) { +H5P.EventDispatcher.prototype.createXAPIEventTemplate = function (verb, extra) { var event = new H5P.XAPIEvent(); event.setActor(); @@ -49,22 +59,28 @@ H5P.EventDispatcher.prototype.createXAPIEventTemplate = function(verb, extra) { * * DEPRECATED - USE triggerXAPIScored instead * - * @param {int} score - will be set as the 'raw' value of the score object - * @param {int} maxScore - will be set as the "max" value of the score object + * @deprecated + * since 1.5, use triggerXAPIScored instead. + * @param {number} score + * Will be set as the 'raw' value of the score object + * @param {number} maxScore + * will be set as the "max" value of the score object */ -H5P.EventDispatcher.prototype.triggerXAPICompleted = function(score, maxScore) { +H5P.EventDispatcher.prototype.triggerXAPICompleted = function (score, maxScore) { this.triggerXAPIScored(score, maxScore, 'completed'); }; /** * Helper function to create scored xAPI events * - * - * @param {int} score - will be set as the 'raw' value of the score object - * @param {int} maxScore - will be set as the "max" value of the score object - * @param {string} verb - short form of adl verb + * @param {number} score + * Will be set as the 'raw' value of the score object + * @param {number} maxScore + * Will be set as the "max" value of the score object + * @param {string} verb + * Short form of adl verb */ -H5P.EventDispatcher.prototype.triggerXAPIScored = function(score, maxScore, verb) { +H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, verb) { var event = this.createXAPIEventTemplate(verb); event.setScoredResult(score, maxScore); this.trigger(event); @@ -73,9 +89,9 @@ H5P.EventDispatcher.prototype.triggerXAPIScored = function(score, maxScore, verb /** * Internal H5P function listening for xAPI completed events and stores scores * - * @param {function} event - xAPI event + * @param {H5P.XAPIEvent} event */ -H5P.xAPICompletedListener = function(event) { +H5P.xAPICompletedListener = function (event) { if (event.getVerb() === 'completed' && !event.getVerifiedStatementValue(['context', 'contextActivities', 'parent'])) { var score = event.getScore(); var maxScore = event.getMaxScore(); diff --git a/js/h5p.js b/js/h5p.js index b8a09e0..9a9554a 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -1,17 +1,34 @@ /*jshint multistr: true */ // TODO: Should we split up the generic parts needed by the editor(and others), and the parts needed to "run" H5Ps? + +/** @namespace */ var H5P = H5P || {}; -// Determine if we're inside an iframe. +/** + * Tells us if we're inside of an iframe. + * @member {boolean} + */ H5P.isFramed = (window.self !== window.top); -// Useful jQuery object. +/** + * jQuery instance of current window. + * @member {H5P.jQuery} + */ H5P.$window = H5P.jQuery(window); +/** + * List over H5P instances on the current page. + * @member {Array} + */ H5P.instances = []; // Detect if we support fullscreen, and what prefix to use. if (document.documentElement.requestFullScreen) { + /** + * Browser prefix to use when entering fullscreen mode. + * undefined means no fullscreen support. + * @member {string} + */ H5P.fullScreenBrowserPrefix = ''; } else if (document.documentElement.webkitRequestFullScreen) { @@ -30,34 +47,36 @@ else if (document.documentElement.msRequestFullscreen) { H5P.fullScreenBrowserPrefix = 'ms'; } -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_NONE = 0; -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_FRAME = 1; -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_DOWNLOAD = 2; -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_EMBED = 4; -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_COPYRIGHT = 8; -/** @const {Number} */ +/** @const {number} */ H5P.DISABLE_ABOUT = 16; /** * Keep track of when the H5Ps where started. * - * @type {Array} + * @type {Object[]} */ H5P.opened = {}; /** * Initialize H5P content. * Scans for ".h5p-content" in the document and initializes H5P instances where found. + * + * @param {Object} target DOM Element */ H5P.init = function (target) { // Useful jQuery object. @@ -67,8 +86,12 @@ H5P.init = function (target) { // Determine if we can use full screen if (H5P.canHasFullScreen === undefined) { - // Restricts fullscreen when embedded. - // (embedded doesn't support semi-fullscreen solution) + /** + * Use this variable to check if fullscreen is supported. Fullscreen can be + * restricted when embedding since not all browsers support the native + * fullscreen, and the semi-fullscreen solution doesn't work when embedded. + * @type {boolean} + */ H5P.canHasFullScreen = (H5P.isFramed && H5P.externalEmbed !== false) ? ((document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled) ? true : false) : true; // We should consider document.msFullscreenEnabled when they get their // element sizing corrected. Ref. https://connect.microsoft.com/IE/feedback/details/838286/ie-11-incorrectly-reports-dom-element-sizes-in-fullscreen-mode-when-fullscreened-element-is-within-an-iframe @@ -348,9 +371,15 @@ H5P.getHeadTags = function (contentId) { ''; }; +/** + * When embedded the communicator helps talk to the parent page. + * + * @type {Communicator} + */ H5P.communicator = (function () { /** * @class + * @private */ function Communicator() { var self = this; @@ -373,9 +402,8 @@ H5P.communicator = (function () { /** * Register action listener. * - * @public - * @param {String} action What you are waiting for - * @param {Function} handler What you want done + * @param {string} action What you are waiting for + * @param {function} handler What you want done */ self.on = function (action, handler) { actionHandlers[action] = handler; @@ -384,8 +412,7 @@ H5P.communicator = (function () { /** * Send a message to the all mighty father. * - * @public - * @param {String} action + * @param {string} action * @param {Object} [data] payload */ self.send = function (action, data) { @@ -404,13 +431,12 @@ H5P.communicator = (function () { })(); /** - * Enable full screen for the given h5p. + * Enter fullscreen for the given H5P instance. * - * @param {jQuery} $element Content container. - * @param {object} instance + * @param {H5P.jQuery} $element Content container. + * @param {Object} instance * @param {function} exitCallback Callback function called when user exits fullscreen. - * @param {jQuery} $body For internal use. Gives the body of the iframe. - * @returns {undefined} + * @param {H5P.jQuery} $body For internal use. Gives the body of the iframe. */ H5P.fullScreen = function ($element, instance, exitCallback, body) { if (H5P.exitFullScreen !== undefined) { @@ -450,7 +476,8 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) { /** * Prepare for resize by setting the correct styles. * - * @param {String} classes CSS + * @private + * @param {string} classes CSS */ var before = function (classes) { $classes.addClass(classes); @@ -464,6 +491,8 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) { /** * Gets called when fullscreen mode has been entered. * Resizes and sets focus on content. + * + * @private */ var entered = function () { // Do not rely on window resize events. @@ -476,7 +505,8 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) { * Gets called when fullscreen mode has been exited. * Resizes and sets focus on content. * - * @param {String} classes CSS + * @private + * @param {string} classes CSS */ var done = function (classes) { H5P.isFullscreen = false; @@ -561,14 +591,15 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) { }; /** - * Find the path to the content files based on the id of the content + * Find the path to the content files based on the id of the content. + * Also identifies and returns absolute paths. * - * Also identifies and returns absolute paths - * - * @param string path - * Absolute path to a file, or relative path to a file in the content folder - * @param contentId - * Id of the content requesting a path + * @param {string} path + * Relative to content folder or absolute. + * @param {number} contentId + * ID of the content requesting the path. + * @returns {string} + * Complete URL to path. */ H5P.getPath = function (path, contentId) { var hasProtocol = function (path) { @@ -601,10 +632,14 @@ H5P.getPath = function (path, contentId) { * THIS FUNCTION IS DEPRECATED, USE getPath INSTEAD * Will be remove march 2016. * - * Find the path to the content files folder based on the id of the content + * Find the path to the content files folder based on the id of the content * - * @param contentId - * Id of the content requesting a path + * @deprecated + * Will be removed march 2016. + * @param contentId + * Id of the content requesting the path + * @returns {string} + * URL */ H5P.getContentPath = function (contentId) { return H5PIntegration.url + '/content/' + contentId; @@ -613,32 +648,38 @@ H5P.getContentPath = function (contentId) { /** * Get library class constructor from H5P by classname. * Note that this class will only work for resolve "H5P.NameWithoutDot". - * Also check out: H5P.newRunnable + * Also check out {@link H5P.newRunnable} * * Used from libraries to construct instances of other libraries' objects by name. * * @param {string} name Name of library - * @returns Class constructor + * @returns {Object} Class constructor */ H5P.classFromName = function (name) { var arr = name.split("."); - return this[arr[arr.length-1]]; + return this[arr[arr.length - 1]]; }; /** * A safe way of creating a new instance of a runnable H5P. * - * TODO: Should we check if version matches the library? - * TODO: Dynamically try to load libraries currently not loaded? That will require a callback. - * - * @param {Object} library Library/action object form params. - * @param {Number} contentId - * @param {jQuery} $attachTo An optional element to attach the instance to. - * @param {Boolean} skipResize Optionally skip triggering of the resize event after attaching. - * @param {Object} extras - extra params for the H5P content constructor - * @return {Object} Instance. + * @param {Object} library + * Library/action object form params. + * @param {number} contentId + * Identifies the content. + * @param {H5P.jQuery} [$attachTo] + * Element to attach the instance to. + * @param {boolean} [skipResize] + * Skip triggering of the resize event after attaching. + * @param {Object} [extras] + * Extra parameters for the H5P content constructor + * @returns {Object} + * Instance. */ H5P.newRunnable = function (library, contentId, $attachTo, skipResize, extras) { + // TODO: Should we check if version matches the library? + // TODO: Dynamically try to load libraries currently not loaded? That will require a callback. + var nameSplit, versionSplit, machineName; try { nameSplit = library.library.split(' ', 2); @@ -723,10 +764,9 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize, extras) { }; /** - * Used to print useful error messages. + * Used to print useful error messages. (to JavaScript error console) * - * @param {mixed} err Error to print. - * @returns {undefined} + * @param {*} err Error to print. */ H5P.error = function (err) { if (window.console !== undefined && console.error !== undefined) { @@ -737,10 +777,14 @@ H5P.error = function (err) { /** * Translate text strings. * - * @param {String} key Translation identifier, may only contain a-zA-Z0-9. No spaces or special chars. - * @param {Object} vars Data for placeholders. - * @param {String} ns Translation namespace. Defaults to H5P. - * @returns {String} Text + * @param {string} key + * Translation identifier, may only contain a-zA-Z0-9. No spaces or special chars. + * @param {Object} vars + * Data for placeholders. + * @param {string} ns + * Translation namespace. Defaults to H5P. + * @returns {string} + * Translated text */ H5P.t = function (key, vars, ns) { if (ns === undefined) { @@ -767,6 +811,19 @@ H5P.t = function (key, vars, ns) { return translation; }; +/** + * Creates a new popup dialog over the H5P content. + * + * @class + * @param {string} name + * Used for html class. + * @param {string} title + * Used for header. + * @param {string} content + * Displayed inside the dialog. + * @param {H5P.jQuery} $element + * Which DOM element the dialog should be inserted after. + */ H5P.Dialog = function (name, title, content, $element) { var self = this; var $dialog = H5P.jQuery('