diff --git a/h5p.classes.php b/h5p.classes.php index a6add6b..ae7d2f5 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1539,7 +1539,7 @@ class H5PCore { public static $coreApi = array( 'majorVersion' => 1, - 'minorVersion' => 3 + 'minorVersion' => 4 ); public static $styles = array( 'styles/h5p.css', @@ -1547,6 +1547,7 @@ class H5PCore { public static $scripts = array( 'js/jquery.js', 'js/h5p.js', + 'js/h5p-event-dispatcher.js', ); public static $adminScripts = array( 'js/jquery.js', diff --git a/js/h5p-event-dispatcher.js b/js/h5p-event-dispatcher.js new file mode 100644 index 0000000..fb7f5ef --- /dev/null +++ b/js/h5p-event-dispatcher.js @@ -0,0 +1,152 @@ +/** @namespace H5P */ +var H5P = H5P || {}; + +H5P.EventDispatcher = (function () { + + /** + * The base of the event system. + * Inherit this class if you want your H5P to dispatch events. + * @class + */ + function EventDispatcher() { + var self = this; + + /** + * Keep track of events and listeners for each event. + * @private + * @type {Object} + */ + var events = {}; + + /** + * Add new event listener. + * + * @public + * @throws {TypeError} listener must be a function + * @param {String} type Event type + * @param {Function} listener Event listener + */ + self.on = function (type, listener) { + if (!(listener instanceof Function)) { + throw TypeError('listener must be a function'); + } + + // Trigger event before adding to avoid recursion + self.trigger('newListener', type, listener); + + if (!events[type]) { + // First + events[type] = [listener]; + } + else { + // Append + events[type].push(listener); + } + }; + + /** + * 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 + */ + self.once = function (type, listener) { + if (!(listener instanceof Function)) { + throw TypeError('listener must be a function'); + } + + var once = function () { + self.off(type, once); + listener.apply(self, arguments); + }; + + self.on(type, once); + }; + + /** + * 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 + */ + self.off = function (type, listener) { + if (listener !== undefined && !(listener instanceof Function)) { + throw TypeError('listener must be a function'); + } + + if (events[type] === undefined) { + return; + } + + if (listener === undefined) { + // Remove all listeners + delete events[type]; + self.trigger('removeListener', type); + return; + } + + // Find specific listener + for (var i = 0; i < events[type].length; i++) { + if (events[type][i] === listener) { + events[type].unshift(i, 1); + self.trigger('removeListener', type, listener); + break; + } + } + + // Clean up empty arrays + if (!events[type].length) { + delete events[type]; + } + }; + + /** + * Creates a copy of the arguments list. Skips the given number of arguments. + * + * @private + * @param {Array} args List of arguments + * @param {Number} skip Number of arguments to skip + * @param {Array} Copy og arguments list + */ + var getArgs = function (args, skip) { + var left = []; + for (var i = skip; i < args.length; i++) { + left.push(args[i]); + } + return left; + }; + + /** + * Dispatch event. + * + * @public + * @param {String} type Event type + * @param {...*} args + */ + self.trigger = function (type) { + if (self.debug !== undefined) { + // Class has debug enabled. Log events. + console.log(self.debug + ' - Firing event "' + type + '", ' + (events[type] === undefined ? 0 : events[type].length) + ' listeners.', getArgs(arguments, 1)); + } + + if (events[type] === undefined) { + return; + } + + // Copy all arguments except the first + var args = getArgs(arguments, 1); + + // Call all listeners + for (var i = 0; i < events[type].length; i++) { + events[type][i].apply(self, args); + } + }; + } + + return EventDispatcher; +})(); diff --git a/styles/h5p.css b/styles/h5p.css index 1e94238..072ce4d 100644 --- a/styles/h5p.css +++ b/styles/h5p.css @@ -36,7 +36,9 @@ html.h5p-iframe .h5p-content { width: 100%; height: 100%; } -.h5p-content.h5p-no-frame { +.h5p-content.h5p-no-frame, +.h5p-fullscreen .h5p-content, +.h5p-semi-fullscreen .h5p-content { border: 0; } .h5p-container {