Merge branch 'master' into copy-and-paste

pull/6/head
Frode Petterson 2015-11-04 11:38:52 +01:00
commit 4bca7055ab
6 changed files with 100 additions and 42 deletions

View File

@ -1578,7 +1578,9 @@ Class H5PExport {
*/ */
private static function populateFileList($dir, &$files, $relative = '') { private static function populateFileList($dir, &$files, $relative = '') {
$strip = strlen($dir) + 1; $strip = strlen($dir) + 1;
foreach (glob($dir . DIRECTORY_SEPARATOR . '*') as $file) { $contents = glob($dir . DIRECTORY_SEPARATOR . '*');
if (!empty($contents)) {
foreach ($contents as $file) {
$rel = $relative . substr($file, $strip); $rel = $relative . substr($file, $strip);
if (is_dir($file)) { if (is_dir($file)) {
self::populateFileList($file, $files, $rel . '/'); self::populateFileList($file, $files, $rel . '/');
@ -1591,6 +1593,7 @@ Class H5PExport {
} }
} }
} }
}
/** /**
* Delete .h5p file * Delete .h5p file

View File

@ -19,6 +19,7 @@
actionHandlers.hello = function (iframe, data, respond) { actionHandlers.hello = function (iframe, data, respond) {
// Make iframe responsive // Make iframe responsive
iframe.style.width = '100%'; iframe.style.width = '100%';
iframe.contentDocument.body.style.height = 'auto';
// Tell iframe that it needs to resize when our window resizes // Tell iframe that it needs to resize when our window resizes
var resize = function (event) { var resize = function (event) {
@ -46,16 +47,6 @@
* @param {Function} respond Send a response to the iframe * @param {Function} respond Send a response to the iframe
*/ */
actionHandlers.prepareResize = function (iframe, data, respond) { actionHandlers.prepareResize = function (iframe, data, respond) {
responseData = {};
// Create spaceholder and insert after iframe.
var spaceholder = document.createElement('div');
spaceholder.style.height = (iframe.clientHeight - 1) + 'px';
iframe.parentNode.insertBefore(spaceholder, iframe.nextSibling);
// Reset iframe height, in case content has shrinked.
iframe.style.height = '1px';
respond('resizePrepared'); respond('resizePrepared');
}; };
@ -68,9 +59,16 @@
* @param {Function} respond Send a response to the iframe * @param {Function} respond Send a response to the iframe
*/ */
actionHandlers.resize = function (iframe, data, respond) { actionHandlers.resize = function (iframe, data, respond) {
// Resize iframe so all content is visible. if (iframe.clientHeight === iframe.contentDocument.body.scrollHeight &&
iframe.style.height = data.height + 'px'; iframe.contentDocument.body.scrollHeight === iframe.contentWindow.document.body.clientHeight) {
iframe.parentNode.removeChild(iframe.nextSibling); 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';
}; };
/** /**

View File

@ -18,18 +18,40 @@ H5P.XAPIEvent.prototype.constructor = H5P.XAPIEvent;
* *
* @param {number} score * @param {number} score
* @param {number} maxScore * @param {number} maxScore
* @param {object} instance
* @param {boolean} completion
* @param {boolean} success
*/ */
H5P.XAPIEvent.prototype.setScoredResult = function (score, maxScore, instance) { H5P.XAPIEvent.prototype.setScoredResult = function (score, maxScore, instance, completion, success) {
this.data.statement.result = { this.data.statement.result = {};
'score': {
if (typeof score !== 'undefined') {
if (typeof maxScore === 'undefined') {
this.data.statement.result.score = {'raw': score};
}
else {
this.data.statement.result.score = {
'min': 0, 'min': 0,
'max': maxScore, 'max': maxScore,
'raw': score 'raw': score
}
}; };
if (maxScore > 0) { if (maxScore > 0) {
this.data.statement.result.score.scaled = Math.round(score / maxScore * 10000) / 10000; this.data.statement.result.score.scaled = Math.round(score / maxScore * 10000) / 10000;
} }
}
}
if (typeof completion === 'undefined') {
this.data.statement.result.completion = (this.getVerb() === 'completed' || this.getVerb() === 'answered');
}
else {
this.data.statement.result.completion = completion;
}
if (typeof success !== 'undefined') {
this.data.statement.result.success = success;
}
if (instance && instance.activityStartTime) { if (instance && instance.activityStartTime) {
var duration = Math.round((Date.now() - instance.activityStartTime ) / 10) / 100; var duration = Math.round((Date.now() - instance.activityStartTime ) / 10) / 100;
// xAPI spec allows a precision of 0.01 seconds // xAPI spec allows a precision of 0.01 seconds

View File

@ -65,9 +65,11 @@ H5P.EventDispatcher.prototype.createXAPIEventTemplate = function (verb, extra) {
* Will be set as the 'raw' value of the score object * Will be set as the 'raw' value of the score object
* @param {number} maxScore * @param {number} maxScore
* will be set as the "max" value of the score object * will be set as the "max" value of the score object
* @param {boolean} success
* will be set as the "success" value of the result object
*/ */
H5P.EventDispatcher.prototype.triggerXAPICompleted = function (score, maxScore) { H5P.EventDispatcher.prototype.triggerXAPICompleted = function (score, maxScore, success) {
this.triggerXAPIScored(score, maxScore, 'completed'); this.triggerXAPIScored(score, maxScore, 'completed', true, success);
}; };
/** /**
@ -79,10 +81,14 @@ H5P.EventDispatcher.prototype.triggerXAPICompleted = function (score, maxScore)
* Will be set as the "max" value of the score object * Will be set as the "max" value of the score object
* @param {string} verb * @param {string} verb
* Short form of adl verb * Short form of adl verb
* @param {boolean} completion
* Is this a statement from a completed activity?
* @param {boolean} success
* Is this a statement from an activity that was done successfully?
*/ */
H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, verb) { H5P.EventDispatcher.prototype.triggerXAPIScored = function (score, maxScore, verb, completion, success) {
var event = this.createXAPIEventTemplate(verb); var event = this.createXAPIEventTemplate(verb);
event.setScoredResult(score, maxScore, this); event.setScoredResult(score, maxScore, this, completion, success);
this.trigger(event); this.trigger(event);
}; };
@ -96,7 +102,7 @@ H5P.EventDispatcher.prototype.setActivityStarted = function() {
* @param {H5P.XAPIEvent} event * @param {H5P.XAPIEvent} event
*/ */
H5P.xAPICompletedListener = function (event) { H5P.xAPICompletedListener = function (event) {
if (event.getVerb() === 'completed' && !event.getVerifiedStatementValue(['context', 'contextActivities', 'parent'])) { if ((event.getVerb() === 'completed' || event.getVerb() === 'answered') && !event.getVerifiedStatementValue(['context', 'contextActivities', 'parent'])) {
var score = event.getScore(); var score = event.getScore();
var maxScore = event.getMaxScore(); var maxScore = event.getMaxScore();
var contentId = event.getVerifiedStatementValue(['object', 'definition', 'extensions', 'http://h5p.org/x-api/h5p-local-content-id']); var contentId = event.getVerifiedStatementValue(['object', 'definition', 'extensions', 'http://h5p.org/x-api/h5p-local-content-id']);

View File

@ -539,7 +539,13 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) {
before('h5p-semi-fullscreen'); before('h5p-semi-fullscreen');
var $disable = H5P.jQuery('<div role="button" tabindex="1" class="h5p-disable-fullscreen" title="' + H5P.t('disableFullscreen') + '"></div>').appendTo($container.find('.h5p-content-controls')); var $disable = H5P.jQuery('<div role="button" tabindex="1" class="h5p-disable-fullscreen" title="' + H5P.t('disableFullscreen') + '"></div>').appendTo($container.find('.h5p-content-controls'));
var keyup, disableSemiFullscreen = function () { var keyup, disableSemiFullscreen = H5P.exitFullScreen = function () {
if (lastViewport) {
metaTags[i].content = lastViewport;
}
else {
head.removeChild(metaTag);
}
$disable.remove(); $disable.remove();
$body.unbind('keyup', keyup); $body.unbind('keyup', keyup);
done('h5p-semi-fullscreen'); done('h5p-semi-fullscreen');
@ -551,6 +557,27 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) {
}; };
$disable.click(disableSemiFullscreen); $disable.click(disableSemiFullscreen);
$body.keyup(keyup); $body.keyup(keyup);
// Disable zoom
var lastViewport;
var metaTags = document.getElementsByTagName('meta');
for (var i = 0; i < metaTags.length; i++) {
if (metaTags[i].name === 'viewport') {
lastViewport = metaTags[i].content;
break;
}
}
if (!lastViewport) {
// Create tag
metaTags[i] = document.createElement('meta');
metaTags[i].name = 'viewport';
}
metaTags[i].content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0';
if (!lastViewport) {
var head = document.getElementsByTagName('head')[0];
head.appendChild(metaTag);
}
entered(); entered();
} }
else { else {

View File

@ -130,13 +130,15 @@ div.h5p-fullscreen {
} }
.h5p-iframe-wrapper.h5p-semi-fullscreen { .h5p-iframe-wrapper.h5p-semi-fullscreen {
width: 100%; width: auto;
height: 100%; height: auto;
background: black; background: black;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1000; right: 0;
bottom: 0;
z-index: 100001;
} }
.h5p-iframe-wrapper.h5p-semi-fullscreen .buttons { .h5p-iframe-wrapper.h5p-semi-fullscreen .buttons {
position: absolute; position: absolute;