From 0c2496530532e1f463a0efaa5c4be01ed9765b7a Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Wed, 11 Nov 2015 14:13:05 +0100 Subject: [PATCH 1/8] Keep track of the latest H5P release --- h5p.classes.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/h5p.classes.php b/h5p.classes.php index 8ff35f8..9624cd6 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -2391,6 +2391,10 @@ class H5PCore { if($platformInfo['uuid'] === '' && isset($json->uuid)) { $this->h5pF->setOption('site_uuid', $json->uuid); } + if (isset($json->latest) && !empty($json->latest)) { + $this->h5pF->setOption('update_available', $json->latest->releasedAt); + $this->h5pF->setOption('update_available_path', $json->latest->path); + } } } From 6773f7aad8f95d21c847e12e6ad781e1f8ff26b9 Mon Sep 17 00:00:00 2001 From: Juho Jaakkola Date: Fri, 27 Nov 2015 12:16:57 +0200 Subject: [PATCH 2/8] Adds minimal composer.json --- composer.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5f423f9 --- /dev/null +++ b/composer.json @@ -0,0 +1,10 @@ +{ + "name": "h5p/h5p-php-library", + "license": "GPL-3.0", + "autoload": { + "files": [ + "h5p-development.class.php", + "h5p.classes.php" + ] + } +} \ No newline at end of file From 2bc4dee85a367bcb3559d6d8303f78c66f640de7 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Thu, 10 Dec 2015 14:49:30 +0100 Subject: [PATCH 3/8] Prevent crashing editor for old libraries --- js/h5p-x-api.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/h5p-x-api.js b/js/h5p-x-api.js index 9fc6758..6becdad 100644 --- a/js/h5p-x-api.js +++ b/js/h5p-x-api.js @@ -95,7 +95,8 @@ H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, ver H5P.EventDispatcher.prototype.setActivityStarted = function() { if (this.activityStartTime === undefined) { // Don't trigger xAPI events in the editor - if (H5PIntegration.contents['cid-' + this.contentId] !== undefined) { + if (H5PIntegration.contents !== undefined && + H5PIntegration.contents['cid-' + this.contentId] !== undefined) { this.triggerXAPI('attempted'); } this.activityStartTime = Date.now(); @@ -114,4 +115,4 @@ H5P.xAPICompletedListener = function (event) { var contentId = event.getVerifiedStatementValue(['object', 'definition', 'extensions', 'http://h5p.org/x-api/h5p-local-content-id']); H5P.setFinished(contentId, score, maxScore); } -}; \ No newline at end of file +}; From 2d0e409ac4f48b73ae5555977f6cc21e91948df7 Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Wed, 16 Dec 2015 09:50:58 +0100 Subject: [PATCH 4/8] Made content state beeing saved on safari@iPad when closing tab and leaving tab --- js/h5p.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/h5p.js b/js/h5p.js index 24d9846..cd31b84 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -1948,7 +1948,7 @@ H5P.createTitle = function (rawTitle, maxLength) { if (H5PIntegration.saveFreq !== false) { // Store the current state of the H5P when leaving the page. - H5P.$window.on('beforeunload', function () { + var storeCurrentState = function () { for (var i = 0; i < H5P.instances.length; i++) { var instance = H5P.instances[i]; if (instance.getCurrentState instanceof Function || @@ -1960,7 +1960,9 @@ H5P.createTitle = function (rawTitle, maxLength) { } } } - }); + }; + H5P.$window.one('beforeunload unload', storeCurrentState); + H5P.$window.on('pagehide', storeCurrentState); } /** From e6ec257c6da2a05530ddad4185fac5d92e3b2770 Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Wed, 16 Dec 2015 15:42:26 +0100 Subject: [PATCH 5/8] Made setActivityStarted a little more robust [HFJ-1474] --- js/h5p-x-api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/h5p-x-api.js b/js/h5p-x-api.js index 9fc6758..272c058 100644 --- a/js/h5p-x-api.js +++ b/js/h5p-x-api.js @@ -95,7 +95,7 @@ H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, ver H5P.EventDispatcher.prototype.setActivityStarted = function() { if (this.activityStartTime === undefined) { // Don't trigger xAPI events in the editor - if (H5PIntegration.contents['cid-' + this.contentId] !== undefined) { + if (this.contentId !== undefined && H5PIntegration.contents !== undefined && H5PIntegration.contents['cid-' + this.contentId] !== undefined) { this.triggerXAPI('attempted'); } this.activityStartTime = Date.now(); @@ -114,4 +114,4 @@ H5P.xAPICompletedListener = function (event) { var contentId = event.getVerifiedStatementValue(['object', 'definition', 'extensions', 'http://h5p.org/x-api/h5p-local-content-id']); H5P.setFinished(contentId, score, maxScore); } -}; \ No newline at end of file +}; From e83b213183ee06f196ead588fedfc8bc5239cbd3 Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Fri, 18 Dec 2015 10:06:33 +0100 Subject: [PATCH 6/8] Made content state saving more robust [HFJ-1450] --- js/h5p.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/js/h5p.js b/js/h5p.js index cd31b84..4cb4250 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -1947,21 +1947,34 @@ H5P.createTitle = function (rawTitle, maxLength) { } if (H5PIntegration.saveFreq !== false) { + // When was the last state stored + var lastStoredOn = 0; // Store the current state of the H5P when leaving the page. var storeCurrentState = function () { - for (var i = 0; i < H5P.instances.length; i++) { - var instance = H5P.instances[i]; - if (instance.getCurrentState instanceof Function || - typeof instance.getCurrentState === 'function') { - var state = instance.getCurrentState(); - if (state !== undefined) { - // Async is not used to prevent the request from being cancelled. - H5P.setUserData(instance.contentId, 'state', state, {deleteOnChange: true, async: false}); + // Make sure at least 250 ms has passed since last save + var currentTime = new Date().getTime(); + if (currentTime - lastStoredOn > 250) { + lastStoredOn = currentTime; + for (var i = 0; i < H5P.instances.length; i++) { + var instance = H5P.instances[i]; + if (instance.getCurrentState instanceof Function || + typeof instance.getCurrentState === 'function') { + var state = instance.getCurrentState(); + if (state !== undefined) { + // Async is not used to prevent the request from being cancelled. + H5P.setUserData(instance.contentId, 'state', state, {deleteOnChange: true, async: false}); + } } } } }; - H5P.$window.one('beforeunload unload', storeCurrentState); + // iPad does not support beforeunload, therefore using unload + H5P.$window.one('beforeunload unload', function () { + // Only want to do this once + H5P.$window.off('pagehide beforeunload unload'); + storeCurrentState(); + }); + // pagehide is used on iPad when tabs are switched H5P.$window.on('pagehide', storeCurrentState); } From 919ac77f358b680cbc7585271af01d396b5d0228 Mon Sep 17 00:00:00 2001 From: Paal Joergensen Date: Fri, 18 Dec 2015 10:26:59 +0100 Subject: [PATCH 7/8] Readded check for undefined contentid in setActivityStarted() --- js/h5p-x-api.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/h5p-x-api.js b/js/h5p-x-api.js index 6becdad..1cf8b74 100644 --- a/js/h5p-x-api.js +++ b/js/h5p-x-api.js @@ -95,7 +95,8 @@ H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, ver H5P.EventDispatcher.prototype.setActivityStarted = function() { if (this.activityStartTime === undefined) { // Don't trigger xAPI events in the editor - if (H5PIntegration.contents !== undefined && + if (this.contentId !== undefined && + H5PIntegration.contents !== undefined && H5PIntegration.contents['cid-' + this.contentId] !== undefined) { this.triggerXAPI('attempted'); } From 59901fd1c9a828cc19bba058e80855fd6205efce Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Tue, 5 Jan 2016 13:57:16 +0100 Subject: [PATCH 8/8] Fixed resizing script trying to access iframe content HFJ-1512 --- js/h5p-resizer.js | 20 +++++++++----------- js/h5p.js | 10 ++++++++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/js/h5p-resizer.js b/js/h5p-resizer.js index 228cc72..772cafd 100644 --- a/js/h5p-resizer.js +++ b/js/h5p-resizer.js @@ -19,7 +19,6 @@ actionHandlers.hello = function (iframe, data, respond) { // Make iframe responsive iframe.style.width = '100%'; - iframe.contentDocument.body.style.height = 'auto'; // Tell iframe that it needs to resize when our window resizes var resize = function (event) { @@ -47,7 +46,14 @@ * @param {Function} respond Send a response to the iframe */ actionHandlers.prepareResize = function (iframe, data, respond) { - respond('resizePrepared'); + // Do not resize unless page and scrolling differs + if (iframe.clientHeight !== data.scrollHeight || + data.scrollHeight !== data.clientHeight) { + + // Reset iframe height, in case content has shrinked. + iframe.style.height = data.clientHeight + 'px'; + respond('resizePrepared'); + } }; /** @@ -59,16 +65,8 @@ * @param {Function} respond Send a response to the iframe */ actionHandlers.resize = function (iframe, data, respond) { - if (iframe.clientHeight === iframe.contentDocument.body.scrollHeight && - iframe.contentDocument.body.scrollHeight === iframe.contentWindow.document.body.clientHeight) { - return; // Do not resize unless page and scrolling differs - } - - // Reset iframe height, in case content has shrinked. - iframe.style.height = iframe.contentWindow.document.body.clientHeight + 'px'; - // Resize iframe so all content is visible. Use scrollHeight to make sure we get everything - iframe.style.height = iframe.contentDocument.body.scrollHeight + 'px'; + iframe.style.height = data.scrollHeight + 'px'; }; /** diff --git a/js/h5p.js b/js/h5p.js index cd31b84..4a36aad 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -279,6 +279,9 @@ H5P.init = function (target) { // Initial setup/handshake is done parentIsFriendly = true; + // Make iframe responsive + document.body.style.height = 'auto'; + // Hide scrollbars for correct size document.body.style.overflow = 'hidden'; @@ -289,7 +292,7 @@ H5P.init = function (target) { // When resize has been prepared tell parent window to resize H5P.communicator.on('resizePrepared', function (data) { H5P.communicator.send('resize', { - height: document.body.scrollHeight + scrollHeight: document.body.scrollHeight }); }); @@ -307,7 +310,10 @@ H5P.init = function (target) { resizeDelay = setTimeout(function () { // Only resize if the iframe can be resized if (parentIsFriendly) { - H5P.communicator.send('prepareResize'); + H5P.communicator.send('prepareResize', { + scrollHeight: document.body.scrollHeight, + clientHeight: document.body.clientHeight + }); } else { H5P.communicator.send('hello');