diff --git a/fonts/h5p-core-15.eot b/fonts/h5p-core-15.eot
deleted file mode 100644
index 5a51b72..0000000
Binary files a/fonts/h5p-core-15.eot and /dev/null differ
diff --git a/fonts/h5p-core-15.svg b/fonts/h5p-core-15.svg
deleted file mode 100644
index 3a440df..0000000
--- a/fonts/h5p-core-15.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/fonts/h5p-core-15.woff b/fonts/h5p-core-15.woff
deleted file mode 100644
index fa8d5b0..0000000
Binary files a/fonts/h5p-core-15.woff and /dev/null differ
diff --git a/fonts/h5p-core-16.eot b/fonts/h5p-core-16.eot
new file mode 100644
index 0000000..239079b
Binary files /dev/null and b/fonts/h5p-core-16.eot differ
diff --git a/fonts/h5p-core-16.svg b/fonts/h5p-core-16.svg
new file mode 100644
index 0000000..d0bdb88
--- /dev/null
+++ b/fonts/h5p-core-16.svg
@@ -0,0 +1,58 @@
+
+
+
diff --git a/fonts/h5p-core-15.ttf b/fonts/h5p-core-16.ttf
similarity index 50%
rename from fonts/h5p-core-15.ttf
rename to fonts/h5p-core-16.ttf
index d3a9a27..daf1571 100644
Binary files a/fonts/h5p-core-15.ttf and b/fonts/h5p-core-16.ttf differ
diff --git a/fonts/h5p-core-16.woff b/fonts/h5p-core-16.woff
new file mode 100644
index 0000000..d654df4
Binary files /dev/null and b/fonts/h5p-core-16.woff differ
diff --git a/h5p-default-storage.class.php b/h5p-default-storage.class.php
index 4d0385f..25ae287 100644
--- a/h5p-default-storage.class.php
+++ b/h5p-default-storage.class.php
@@ -282,6 +282,8 @@ class H5PDefaultStorage implements \H5PFileStorage {
throw new \Exception('unabletocopy');
}
+ $ignoredFiles = self::getIgnoredFiles("{$source}/.h5pignore");
+
$dir = opendir($source);
if ($dir === FALSE) {
trigger_error('Unable to open directory ' . $source, E_USER_WARNING);
@@ -289,7 +291,7 @@ class H5PDefaultStorage implements \H5PFileStorage {
}
while (false !== ($file = readdir($dir))) {
- if (($file != '.') && ($file != '..') && $file != '.git' && $file != '.gitignore') {
+ if (($file != '.') && ($file != '..') && $file != '.git' && $file != '.gitignore' && !in_array($file, $ignoredFiles)) {
if (is_dir("{$source}/{$file}")) {
self::copyFileTree("{$source}/{$file}", "{$destination}/{$file}");
}
@@ -301,6 +303,25 @@ class H5PDefaultStorage implements \H5PFileStorage {
closedir($dir);
}
+ /**
+ * Retrieve array of file names from file.
+ *
+ * @param string $file
+ * @return array Array with files that should be ignored
+ */
+ private static function getIgnoredFiles($file) {
+ if (file_exists($file) === FALSE) {
+ return array();
+ }
+
+ $contents = file_get_contents($file);
+ if ($contents === FALSE) {
+ return array();
+ }
+
+ return preg_split('/\s+/', $contents);
+ }
+
/**
* Recursive function that makes sure the specified directory exists and
* is writable.
diff --git a/h5p.classes.php b/h5p.classes.php
index 72d84b6..90026b4 100644
--- a/h5p.classes.php
+++ b/h5p.classes.php
@@ -1700,7 +1700,7 @@ class H5PCore {
public static $coreApi = array(
'majorVersion' => 1,
- 'minorVersion' => 10
+ 'minorVersion' => 12
);
public static $styles = array(
'styles/h5p.css',
@@ -2454,7 +2454,9 @@ class H5PCore {
// Handle libraries metadata
if (isset($json->libraries)) {
foreach ($json->libraries as $machineName => $libInfo) {
- $this->h5pF->setLibraryTutorialUrl($machineName, $libInfo->tutorialUrl);
+ if (isset($libInfo->tutorialUrl)) {
+ $this->h5pF->setLibraryTutorialUrl($machineName, $libInfo->tutorialUrl);
+ }
}
}
@@ -3185,7 +3187,9 @@ class H5PContentValidator {
$function = null;
$field = null;
- if (count($semantics->fields) == 1 && $flatten) {
+ $isSubContent = isset($semantics->isSubContent) && $semantics->isSubContent === TRUE;
+
+ if (count($semantics->fields) == 1 && $flatten && !$isSubContent) {
$field = $semantics->fields[0];
$function = $this->typeMap[$field->type];
$this->$function($group, $field);
@@ -3193,7 +3197,7 @@ class H5PContentValidator {
else {
foreach ($group as $key => &$value) {
// If subContentId is set, keep value
- if($key == 'subContentId' && $value == TRUE){
+ if($isSubContent && ($key == 'subContentId')){
continue;
}
diff --git a/js/h5p-content-upgrade-process.js b/js/h5p-content-upgrade-process.js
index 1d886cc..e54dbb7 100644
--- a/js/h5p-content-upgrade-process.js
+++ b/js/h5p-content-upgrade-process.js
@@ -182,7 +182,7 @@ H5P.ContentUpgradeProcess = (function (Version) {
break;
case 'group':
- if (field.fields.length === 1) {
+ if (field.fields.length === 1 && field.isSubContent !== true) {
// Single field to process, wrapper will be skipped
self.processField(field.fields[0], params, function (err, upgradedParams) {
if (upgradedParams) {
diff --git a/js/h5p.js b/js/h5p.js
index aa313b1..45068d8 100644
--- a/js/h5p.js
+++ b/js/h5p.js
@@ -32,7 +32,7 @@ if (document.documentElement.requestFullScreen) {
H5P.fullScreenBrowserPrefix = '';
}
else if (document.documentElement.webkitRequestFullScreen) {
- H5P.safariBrowser = navigator.userAgent.match(/Version\/(\d)/);
+ H5P.safariBrowser = navigator.userAgent.match(/version\/([.\d]+)/i);
H5P.safariBrowser = (H5P.safariBrowser === null ? 0 : parseInt(H5P.safariBrowser[1]));
// Do not allow fullscreen for safari < 7.
@@ -74,11 +74,20 @@ H5P.init = function (target) {
* fullscreen, and the semi-fullscreen solution doesn't work when embedded.
* @type {boolean}
*/
- H5P.fullscreenSupported = (H5P.isFramed && H5P.externalEmbed !== false) ? ((document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled) ? true : false) : true;
+ H5P.fullscreenSupported = !(H5P.isFramed && H5P.externalEmbed !== false) || !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled);
// 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
}
+ // Deprecated variable, kept to maintain backwards compatability
+ if (H5P.canHasFullScreen === undefined) {
+ /**
+ * @deprecated since version 1.11
+ * @type {boolean}
+ */
+ H5P.canHasFullScreen = H5P.fullscreenSupported;
+ }
+
// H5Ps added in normal DIV.
var $containers = H5P.jQuery('.h5p-content:not(.h5p-initialized)', target).each(function () {
var $element = H5P.jQuery(this).addClass('h5p-initialized');
@@ -423,6 +432,19 @@ H5P.communicator = (function () {
return (window.postMessage && window.addEventListener ? new Communicator() : undefined);
})();
+/**
+ * Enter semi fullscreen for the given H5P instance
+ *
+ * @method semiFullScreen
+ * @param {H5P.jQuery} $element Content container.
+ * @param {Object} instance
+ * @param {function} exitCallback Callback function called when user exits fullscreen.
+ * @param {H5P.jQuery} $body For internal use. Gives the body of the iframe.
+ */
+H5P.semiFullScreen = function ($element, instance, exitCallback, body) {
+ H5P.fullScreen($element, instance, exitCallback, body, true);
+};
+
/**
* Enter fullscreen for the given H5P instance.
*
@@ -430,15 +452,16 @@ H5P.communicator = (function () {
* @param {Object} instance
* @param {function} exitCallback Callback function called when user exits fullscreen.
* @param {H5P.jQuery} $body For internal use. Gives the body of the iframe.
+ * @param {Boolean} forceSemiFullScreen
*/
-H5P.fullScreen = function ($element, instance, exitCallback, body) {
+H5P.fullScreen = function ($element, instance, exitCallback, body, forceSemiFullScreen) {
if (H5P.exitFullScreen !== undefined) {
return; // Cannot enter new fullscreen until previous is over
}
if (H5P.isFramed && H5P.externalEmbed === false) {
// Trigger resize on wrapper in parent window.
- window.parent.H5P.fullScreen($element, instance, exitCallback, H5P.$body.get());
+ window.parent.H5P.fullScreen($element, instance, exitCallback, H5P.$body.get(), forceSemiFullScreen);
H5P.isFullscreen = true;
H5P.exitFullScreen = function () {
window.parent.H5P.exitFullScreen();
@@ -518,7 +541,7 @@ H5P.fullScreen = function ($element, instance, exitCallback, body) {
};
H5P.isFullscreen = true;
- if (H5P.fullScreenBrowserPrefix === undefined) {
+ if (H5P.fullScreenBrowserPrefix === undefined || forceSemiFullScreen === true) {
// Create semi fullscreen.
if (H5P.isFramed) {
@@ -1583,7 +1606,8 @@ H5P.shuffleArray = function (array) {
* Reported time consumption/usage
*/
H5P.setFinished = function (contentId, score, maxScore, time) {
- if (typeof score === 'number' && H5PIntegration.postUserStatistics === true) {
+ var validScore = typeof score === 'number' || score instanceof Number;
+ if (validScore && H5PIntegration.postUserStatistics === true) {
/**
* Return unix timestamp for the given JS Date.
*
diff --git a/styles/h5p-confirmation-dialog.css b/styles/h5p-confirmation-dialog.css
index 2923b17..7e5196f 100644
--- a/styles/h5p-confirmation-dialog.css
+++ b/styles/h5p-confirmation-dialog.css
@@ -5,7 +5,7 @@
left: 0;
top: 0;
- background: rgba(255, 255, 255, 0.85);
+ background: rgba(28, 34, 41, 0.9);
opacity: 1;
visibility: visible;
-webkit-transition: opacity 0.1s, linear 0s, visibility 0s linear 0s;
@@ -46,7 +46,7 @@
transform: translate(-50%, 0%);
color: #555;
- box-shadow: 0 0 6px 1px #ddd;
+ box-shadow: 0 0 6px 3px #424242;
-webkit-transition: transform 0.1s ease-in;
transition: transform 0.1s ease-in;
@@ -61,7 +61,7 @@
.h5p-confirmation-dialog-header {
padding: 1.5em;
background: #fff;
- color: #1a73d9;
+ color: #356593;
}
.h5p-confirmation-dialog-header-text {
@@ -69,8 +69,9 @@
}
.h5p-confirmation-dialog-body {
+ background: #fafbfc;
+ border-top: solid 1px #dde0e9;
padding: 1.25em 1.5em;
- background: #fafafa;
}
.h5p-confirmation-dialog-text {
@@ -90,14 +91,14 @@ button.h5p-confirmation-dialog-exit {
font-size: 2.5em;
top: -0.9em;
right: -1.15em;
- color: #777;
+ color: #fff;
cursor: pointer;
text-decoration: none;
}
button.h5p-confirmation-dialog-exit:focus,
button.h5p-confirmation-dialog-exit:hover {
- color: #555;
+ color: #E4ECF5;
}
.h5p-confirmation-dialog-exit:before {
diff --git a/styles/h5p-core-button.css b/styles/h5p-core-button.css
index 3ba392e..eb4e08d 100644
--- a/styles/h5p-core-button.css
+++ b/styles/h5p-core-button.css
@@ -1,13 +1,15 @@
button.h5p-core-button:visited,
button.h5p-core-button:link,
button.h5p-core-button {
+ font-family: "Open Sans", sans-serif;
+ font-weight: 600;
font-size: 1em;
line-height: 1.2;
padding: 0.5em 1.25em;
border-radius: 2em;
- background: #1a73d9;
- color: #ffffff;
+ background: #488ac9;
+ color: #fff;
cursor: pointer;
border: none;
@@ -22,7 +24,7 @@ button.h5p-core-button {
}
button.h5p-core-button:hover,
button.h5p-core-button:focus {
- background: #1356a3;
+ background: #3b71a5;
color: #fff;
text-decoration: none;
-webkit-transition: initial;
diff --git a/styles/h5p.css b/styles/h5p.css
index e5c5240..2e5842e 100644
--- a/styles/h5p.css
+++ b/styles/h5p.css
@@ -3,11 +3,11 @@
/* Custom H5P font to use for icons. */
@font-face {
font-family: 'h5p';
- src: url('../fonts/h5p-core-15.eot?1a4hhb');
- src: url('../fonts/h5p-core-15.eot?1a4hhb#iefix') format('embedded-opentype'),
- url('../fonts/h5p-core-15.ttf?1a4hhb') format('truetype'),
- url('../fonts/h5p-core-15.woff?1a4hhb') format('woff'),
- url('../fonts/h5p-core-15.svg?1a4hhb#h5p-core-15') format('svg');
+ src: url('../fonts/h5p-core-16.eot?80e76o');
+ src: url('../fonts/h5p-core-16.eot?80e76o#iefix') format('embedded-opentype'),
+ url('../fonts/h5p-core-16.ttf?80e76o') format('truetype'),
+ url('../fonts/h5p-core-16.woff?80e76o') format('woff'),
+ url('../fonts/h5p-core-16.svg?80e76o#h5p-core-15') format('svg');
font-weight: normal;
font-style: normal;
}
@@ -235,6 +235,7 @@ div.h5p-fullscreen {
}
.h5p-actions > li {
margin: 0;
+ list-style: none;
}
.h5p-popup-dialog {
position: absolute;