From bc5159e272b0e42857ca3cf220d8f226a0c41655 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 10 Nov 2014 11:31:23 +0100 Subject: [PATCH 1/5] Added event dispatcher. --- h5p.classes.php | 1 + js/h5p-event-dispatcher.js | 135 +++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 js/h5p-event-dispatcher.js diff --git a/h5p.classes.php b/h5p.classes.php index 827903a..d0fd2c8 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1534,6 +1534,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..147024d --- /dev/null +++ b/js/h5p-event-dispatcher.js @@ -0,0 +1,135 @@ +/** @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]; + } + }; + + /** + * Dispatch event. + * + * @public + * @param {String} type Event type + * @param {...*} args + */ + self.trigger = function (type, args) { + if (events[type] === undefined) { + return; + } + + // Copy all arguments except the first + args = []; + var i; + for (i = 1; i < arguments.length; i++) { + args.push(arguments[i]); + } + + // Call all listeners + for (i = 0; i < events[type].length; i++) { + events[type][i].apply(self, args); + } + }; + } + + return EventDispatcher; +})(); From 2bba9a183b02f55af1569ed69e5c579fac312fab Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 10 Nov 2014 11:35:15 +0100 Subject: [PATCH 2/5] Bumped api version. --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index d0fd2c8..0830735 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1526,7 +1526,7 @@ class H5PCore { public static $coreApi = array( 'majorVersion' => 1, - 'minorVersion' => 3 + 'minorVersion' => 4 ); public static $styles = array( 'styles/h5p.css', From acb36845c06bd5d1c6f90854e3f66418ee5a051c Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 15 Dec 2014 11:50:48 +0100 Subject: [PATCH 3/5] Fixed wrong args. --- js/h5p-event-dispatcher.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/h5p-event-dispatcher.js b/js/h5p-event-dispatcher.js index 147024d..b5907b2 100644 --- a/js/h5p-event-dispatcher.js +++ b/js/h5p-event-dispatcher.js @@ -112,14 +112,13 @@ H5P.EventDispatcher = (function () { * @param {String} type Event type * @param {...*} args */ - self.trigger = function (type, args) { + self.trigger = function (type) { if (events[type] === undefined) { return; } // Copy all arguments except the first - args = []; - var i; + var i, args = []; for (i = 1; i < arguments.length; i++) { args.push(arguments[i]); } From 1aef9e376d09f8e4d2e108dca79efcc7061bb3bd Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 15 Dec 2014 16:04:01 +0100 Subject: [PATCH 4/5] Removed ulgy border from full screen. --- styles/h5p.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/styles/h5p.css b/styles/h5p.css index 3ceb8e8..fff975b 100644 --- a/styles/h5p.css +++ b/styles/h5p.css @@ -4,9 +4,9 @@ @font-face { font-family: 'H5P'; src: url('../fonts/h5p.eot?ver=1.2.1'); - src: url('../fonts/h5p.eot?#iefix&ver=1.2.1') format('embedded-opentype'), + src: url('../fonts/h5p.eot?#iefix&ver=1.2.1') format('embedded-opentype'), url('data:application/font-woff;base64,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') format('woff'), - url('../fonts/h5p.ttf?ver=1.2.1') format('truetype'), + url('../fonts/h5p.ttf?ver=1.2.1') format('truetype'), url('../fonts/h5p.svg?ver=1.2.1#h5pregular') format('svg'); font-weight: normal; font-style: normal; @@ -36,6 +36,9 @@ html.h5p-iframe .h5p-content { width: 100%; height: 100%; } +.h5p-fullscreen .h5p-content, .h5p-semi-fullscreen .h5p-content { + border: 0; +} .h5p-container { position: relative; z-index: 1; @@ -264,7 +267,7 @@ div.h5p-fullscreen { } .h5p-popup-dialog .h5p-scroll-content::-webkit-scrollbar-track { background: #e0e0e0; -} +} .h5p-popup-dialog .h5p-scroll-content::-webkit-scrollbar-thumb { box-shadow: 0 0 10px #000 inset; border-radius: 4px; From 74fc8403661d5248b28642fa2be0e63b90edcfc9 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Wed, 17 Dec 2014 16:57:46 +0100 Subject: [PATCH 5/5] Added support for debugging events. --- js/h5p-event-dispatcher.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/js/h5p-event-dispatcher.js b/js/h5p-event-dispatcher.js index b5907b2..fb7f5ef 100644 --- a/js/h5p-event-dispatcher.js +++ b/js/h5p-event-dispatcher.js @@ -105,6 +105,22 @@ H5P.EventDispatcher = (function () { } }; + /** + * 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. * @@ -113,18 +129,20 @@ H5P.EventDispatcher = (function () { * @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 i, args = []; - for (i = 1; i < arguments.length; i++) { - args.push(arguments[i]); - } + var args = getArgs(arguments, 1); // Call all listeners - for (i = 0; i < events[type].length; i++) { + for (var i = 0; i < events[type].length; i++) { events[type][i].apply(self, args); } };