Merge branch 'aggregated-xapi' of ssh://stash.joubel.com:7999/h5p/php-core into aggregated-xapi
Conflicts: js/h5p.jssemantics-font
commit
7a3e6ee847
|
@ -86,7 +86,7 @@ class H5PDevelopment {
|
||||||
$library['libraryId'] = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']);
|
$library['libraryId'] = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']);
|
||||||
$this->h5pF->saveLibraryData($library, $library['libraryId'] === FALSE);
|
$this->h5pF->saveLibraryData($library, $library['libraryId'] === FALSE);
|
||||||
|
|
||||||
$library['path'] = $libraryPath;
|
$library['path'] = $path . '/' . $contents[$i];
|
||||||
$this->libraries[H5PDevelopment::libraryToString($library['machineName'], $library['majorVersion'], $library['minorVersion'])] = $library;
|
$this->libraries[H5PDevelopment::libraryToString($library['machineName'], $library['majorVersion'], $library['minorVersion'])] = $library;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,6 @@ class H5PDevelopment {
|
||||||
*/
|
*/
|
||||||
public function getSemantics($name, $majorVersion, $minorVersion) {
|
public function getSemantics($name, $majorVersion, $minorVersion) {
|
||||||
$library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion);
|
$library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
if (isset($this->libraries[$library]) === FALSE) {
|
if (isset($this->libraries[$library]) === FALSE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1785,10 +1785,9 @@ class H5PCore {
|
||||||
if ($type === 'preloadedCss' && (isset($dependency['dropCss']) && $dependency['dropCss'] === '1')) {
|
if ($type === 'preloadedCss' && (isset($dependency['dropCss']) && $dependency['dropCss'] === '1')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($dependency[$type] as $file) {
|
foreach ($dependency[$type] as $file) {
|
||||||
$assets[] = (object) array(
|
$assets[] = (object) array(
|
||||||
'path' => $prefix . $dependency['path'] . '/' . trim(is_array($file) ? $file['path'] : $file),
|
'path' => /*$prefix .*/ $dependency['path'] . '/' . trim(is_array($file) ? $file['path'] : $file),
|
||||||
'version' => $dependency['version']
|
'version' => $dependency['version']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1840,7 +1839,6 @@ class H5PCore {
|
||||||
$dependency['preloadedJs'] = explode(',', $dependency['preloadedJs']);
|
$dependency['preloadedJs'] = explode(',', $dependency['preloadedJs']);
|
||||||
$dependency['preloadedCss'] = explode(',', $dependency['preloadedCss']);
|
$dependency['preloadedCss'] = explode(',', $dependency['preloadedCss']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dependency['version'] = "?ver={$dependency['majorVersion']}.{$dependency['minorVersion']}.{$dependency['patchVersion']}";
|
$dependency['version'] = "?ver={$dependency['majorVersion']}.{$dependency['minorVersion']}.{$dependency['patchVersion']}";
|
||||||
$this->getDependencyAssets($dependency, 'preloadedJs', $files['scripts'], $prefix);
|
$this->getDependencyAssets($dependency, 'preloadedJs', $files['scripts'], $prefix);
|
||||||
$this->getDependencyAssets($dependency, 'preloadedCss', $files['styles'], $prefix);
|
$this->getDependencyAssets($dependency, 'preloadedCss', $files['styles'], $prefix);
|
||||||
|
@ -2741,11 +2739,14 @@ class H5PContentValidator {
|
||||||
'type' => 'group',
|
'type' => 'group',
|
||||||
'fields' => $library['semantics'],
|
'fields' => $library['semantics'],
|
||||||
), FALSE);
|
), FALSE);
|
||||||
$validkeys = array('library', 'params');
|
$validkeys = array('library', 'params', 'uuid');
|
||||||
if (isset($semantics->extraAttributes)) {
|
if (isset($semantics->extraAttributes)) {
|
||||||
$validkeys = array_merge($validkeys, $semantics->extraAttributes);
|
$validkeys = array_merge($validkeys, $semantics->extraAttributes);
|
||||||
}
|
}
|
||||||
$this->filterParams($value, $validkeys);
|
$this->filterParams($value, $validkeys);
|
||||||
|
if (isset($value->uuid) && ! preg_match('/^\{?[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\}?$/', $value->uuid)) {
|
||||||
|
unset($value->uuid);
|
||||||
|
}
|
||||||
|
|
||||||
// Find all dependencies for this library
|
// Find all dependencies for this library
|
||||||
$depkey = 'preloaded-' . $library['machineName'];
|
$depkey = 'preloaded-' . $library['machineName'];
|
||||||
|
|
|
@ -5,9 +5,22 @@ var H5P = H5P || {};
|
||||||
* The Event class for the EventDispatcher
|
* The Event class for the EventDispatcher
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
H5P.Event = function(type, data) {
|
H5P.Event = function(type, data, extras) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
var bubbles = false;
|
||||||
|
if (extras === undefined) {
|
||||||
|
extras = {};
|
||||||
|
}
|
||||||
|
if (extras.bubbles === true) {
|
||||||
|
bubbles = true;
|
||||||
|
}
|
||||||
|
this.preventBubbling = function() {
|
||||||
|
bubbles = false;
|
||||||
|
};
|
||||||
|
this.getBubbles = function() {
|
||||||
|
return bubbles;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
H5P.EventDispatcher = (function () {
|
H5P.EventDispatcher = (function () {
|
||||||
|
@ -148,6 +161,10 @@ H5P.EventDispatcher = (function () {
|
||||||
for (var i = 0; i < triggers[event.type].length; i++) {
|
for (var i = 0; i < triggers[event.type].length; i++) {
|
||||||
triggers[event.type][i].listener.call(triggers[event.type][i].thisArg, event);
|
triggers[event.type][i].listener.call(triggers[event.type][i].thisArg, event);
|
||||||
}
|
}
|
||||||
|
// Bubble
|
||||||
|
if (event.getBubbles() && self.parent instanceof H5P.EventDispatcher && typeof self.parent.trigger === 'function') {
|
||||||
|
self.parent.trigger(event);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ var H5P = H5P || {};
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
H5P.XAPIEvent = function() {
|
H5P.XAPIEvent = function() {
|
||||||
H5P.Event.call(this, 'xAPI', {'statement': {}});
|
H5P.Event.call(this, 'xAPI', {'statement': {}}, {bubbles: true});
|
||||||
};
|
};
|
||||||
|
|
||||||
H5P.XAPIEvent.prototype = Object.create(H5P.Event.prototype);
|
H5P.XAPIEvent.prototype = Object.create(H5P.Event.prototype);
|
||||||
|
@ -44,8 +44,8 @@ H5P.XAPIEvent.prototype.setVerb = function(verb) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else if (verb.id !== undefined) {
|
||||||
H5P.error('illegal verb');
|
this.data.statement.verb = verb;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,17 +79,50 @@ H5P.XAPIEvent.prototype.getVerb = function(full) {
|
||||||
H5P.XAPIEvent.prototype.setObject = function(instance) {
|
H5P.XAPIEvent.prototype.setObject = function(instance) {
|
||||||
if (instance.contentId) {
|
if (instance.contentId) {
|
||||||
this.data.statement.object = {
|
this.data.statement.object = {
|
||||||
'id': H5PIntegration.contents['cid-' + instance.contentId].url,
|
'id': this.getContentXAPIId(instance),
|
||||||
'objectType': 'Activity',
|
'objectType': 'Activity',
|
||||||
'extensions': {
|
'definition': {
|
||||||
'http://h5p.org/x-api/h5p-local-content-id': instance.contentId
|
'extensions': {
|
||||||
|
'http://h5p.org/x-api/h5p-local-content-id': instance.contentId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (instance.uuid) {
|
||||||
|
this.data.statement.object.definition.extensions['http://h5p.org/x-api/h5p-uuid'] = instance.uuid;
|
||||||
|
// Don't set titles on main content, title should come from publishing platform
|
||||||
|
if (typeof instance.getH5PTitle === 'function') {
|
||||||
|
this.data.statement.object.definition.name = {
|
||||||
|
"en-US": instance.getH5PTitle()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (H5PIntegration && H5PIntegration.contents && H5PIntegration.contents['cid-' + instance.contentId].title) {
|
||||||
|
this.data.statement.object.definition.name = {
|
||||||
|
"en-US": H5P.createH5PTitle(H5PIntegration.contents['cid-' + instance.contentId].title)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
};
|
||||||
// Not triggered by an H5P content type...
|
|
||||||
this.data.statement.object = {
|
/**
|
||||||
'objectType': 'Activity'
|
* Helperfunction to set the context part of the statement.
|
||||||
|
*
|
||||||
|
* @param {object} instance - the H5P instance
|
||||||
|
*/
|
||||||
|
H5P.XAPIEvent.prototype.setContext = function(instance) {
|
||||||
|
if (instance.parent && (instance.parent.contentId || instance.parent.uuid)) {
|
||||||
|
var parentId = instance.parent.uuid === undefined ? instance.parent.contentId : instance.parent.uuid;
|
||||||
|
this.data.statement.context = {
|
||||||
|
"contextActivities": {
|
||||||
|
"parent": [
|
||||||
|
{
|
||||||
|
"id": this.getContentXAPIId(instance.parent),
|
||||||
|
"objectType": "Activity"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -111,10 +144,7 @@ H5P.XAPIEvent.prototype.setActor = function() {
|
||||||
uuid = localStorage.H5PUserUUID;
|
uuid = localStorage.H5PUserUUID;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(char) {
|
uuid = H5P.createUUID();
|
||||||
var random = Math.random()*16|0, newChar = char === 'x' ? random : (random&0x3|0x8);
|
|
||||||
return newChar.toString(16);
|
|
||||||
});
|
|
||||||
localStorage.H5PUserUUID = uuid;
|
localStorage.H5PUserUUID = uuid;
|
||||||
}
|
}
|
||||||
this.data.statement.actor = {
|
this.data.statement.actor = {
|
||||||
|
@ -145,6 +175,17 @@ H5P.XAPIEvent.prototype.getScore = function() {
|
||||||
return this.getVerifiedStatementValue(['result', 'score', 'raw']);
|
return this.getVerifiedStatementValue(['result', 'score', 'raw']);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
H5P.XAPIEvent.prototype.getContentXAPIId = function (instance) {
|
||||||
|
var xAPIId;
|
||||||
|
if (instance.contentId && H5PIntegration && H5PIntegration.contents) {
|
||||||
|
xAPIId = H5PIntegration.contents['cid-' + instance.contentId].url;
|
||||||
|
if (instance.uuid) {
|
||||||
|
xAPIId += '?uuid=' + instance.uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xAPIId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Figure out if a property exists in the statement and return it
|
* Figure out if a property exists in the statement and return it
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,7 +3,7 @@ var H5P = H5P || {};
|
||||||
// Create object where external code may register and listen for H5P Events
|
// Create object where external code may register and listen for H5P Events
|
||||||
H5P.externalDispatcher = new H5P.EventDispatcher();
|
H5P.externalDispatcher = new H5P.EventDispatcher();
|
||||||
|
|
||||||
if (H5P.isFramed && H5P.externalEmbed === false) {
|
if (H5P.isFramed && H5P.externalEmbed !== true) {
|
||||||
H5P.externalDispatcher.on('xAPI', window.top.H5P.externalDispatcher.trigger);
|
H5P.externalDispatcher.on('xAPI', window.top.H5P.externalDispatcher.trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +39,12 @@ H5P.EventDispatcher.prototype.createXAPIEventTemplate = function(verb, extra) {
|
||||||
event.data.statement[i] = extra[i];
|
event.data.statement[i] = extra[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!('object' in event)) {
|
if (!('object' in event.data.statement)) {
|
||||||
event.setObject(this);
|
event.setObject(this);
|
||||||
}
|
}
|
||||||
|
if (!('context' in event.data.statement)) {
|
||||||
|
event.setContext(this);
|
||||||
|
}
|
||||||
return event;
|
return event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,13 +66,10 @@ H5P.EventDispatcher.prototype.triggerXAPICompleted = function(score, maxScore) {
|
||||||
* @param {function} event - xAPI event
|
* @param {function} event - xAPI event
|
||||||
*/
|
*/
|
||||||
H5P.xAPICompletedListener = function(event) {
|
H5P.xAPICompletedListener = function(event) {
|
||||||
var statement = event.data.statement;
|
if (event.getVerb() === 'completed' && !event.getVerifiedStatementValue(['context', 'contextActivities', 'parent'])) {
|
||||||
if ('verb' in statement) {
|
var score = event.getScore();
|
||||||
if (statement.verb.id === 'http://adlnet.gov/expapi/verbs/completed') {
|
var maxScore = event.getMaxScore();
|
||||||
var score = statement.result.score.raw;
|
var contentId = event.getVerifiedStatementValue(['object', 'definition', 'extensions', 'http://h5p.org/x-api/h5p-local-content-id']);
|
||||||
var maxScore = statement.result.score.max;
|
H5P.setFinished(contentId, score, maxScore);
|
||||||
var contentId = statement.object.extensions['http://h5p.org/x-api/h5p-local-content-id'];
|
|
||||||
H5P.setFinished(contentId, score, maxScore);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
246
js/h5p.js
246
js/h5p.js
|
@ -57,33 +57,9 @@ H5P.init = function (target) {
|
||||||
if (contentData === undefined) {
|
if (contentData === undefined) {
|
||||||
return H5P.error('No data for content id ' + contentId + '. Perhaps the library is gone?');
|
return H5P.error('No data for content id ' + contentId + '. Perhaps the library is gone?');
|
||||||
}
|
}
|
||||||
if (contentData.contentUserDatas && contentData.contentUserDatas.state) {
|
|
||||||
if (contentData.contentUserDatas.state === 'RESET') {
|
|
||||||
// Content has been reset. Display dialog.
|
|
||||||
delete contentData.contentUserDatas;
|
|
||||||
var dialog = new H5P.Dialog('content-user-data-reset', 'Data Reset', '<p>' + H5P.t('contentChanged') + '</p><p>' + H5P.t('startingOver') + '</p><div class="h5p-dialog-ok-button" tabIndex="0" role="button">OK</div>', $container);
|
|
||||||
H5P.jQuery(dialog).on('dialog-opened', function (event, $dialog) {
|
|
||||||
$dialog.find('.h5p-dialog-ok-button').click(function () {
|
|
||||||
dialog.close();
|
|
||||||
}).keypress(function (event) {
|
|
||||||
if (event.which === 32) {
|
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
dialog.open();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
contentData.contentUserDatas.state = JSON.parse(contentData.contentUserDatas.state);
|
|
||||||
}
|
|
||||||
catch (err) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var library = {
|
var library = {
|
||||||
library: contentData.library,
|
library: contentData.library,
|
||||||
params: JSON.parse(contentData.jsonContent),
|
params: JSON.parse(contentData.jsonContent)
|
||||||
userDatas: contentData.contentUserDatas
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create new instance.
|
// Create new instance.
|
||||||
|
@ -137,37 +113,6 @@ H5P.init = function (target) {
|
||||||
H5P.on(instance, 'xAPI', H5P.xAPICompletedListener);
|
H5P.on(instance, 'xAPI', H5P.xAPICompletedListener);
|
||||||
H5P.on(instance, 'xAPI', H5P.externalDispatcher.trigger);
|
H5P.on(instance, 'xAPI', H5P.externalDispatcher.trigger);
|
||||||
|
|
||||||
// Auto save current state if supported
|
|
||||||
if (H5PIntegration.saveFreq !== false && (
|
|
||||||
instance.getCurrentState instanceof Function ||
|
|
||||||
typeof instance.getCurrentState === 'function')) {
|
|
||||||
|
|
||||||
var saveTimer, save = function () {
|
|
||||||
var state = instance.getCurrentState();
|
|
||||||
if (state !== undefined) {
|
|
||||||
H5P.setUserData(contentId, 'state', state, true, true);
|
|
||||||
}
|
|
||||||
saveTimer = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (H5PIntegration.saveFreq) {
|
|
||||||
// Only run the loop when there's stuff happening (reduces load)
|
|
||||||
H5P.$body.on('mousedown keydown touchstart', function () {
|
|
||||||
if (!saveTimer) {
|
|
||||||
saveTimer = setTimeout(save, H5PIntegration.saveFreq * 1000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// xAPI events will schedule a save in three seconds.
|
|
||||||
H5P.on(instance, 'xAPI', function () {
|
|
||||||
if (saveTimer) {
|
|
||||||
clearTimeout(saveTimer);
|
|
||||||
}
|
|
||||||
saveTimer = setTimeout(save, 3000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (H5P.isFramed) {
|
if (H5P.isFramed) {
|
||||||
var resizeDelay;
|
var resizeDelay;
|
||||||
if (H5P.externalEmbed === false) {
|
if (H5P.externalEmbed === false) {
|
||||||
|
@ -599,10 +544,10 @@ H5P.classFromName = function (name) {
|
||||||
* @param {Number} contentId
|
* @param {Number} contentId
|
||||||
* @param {jQuery} $attachTo An optional element to attach the instance to.
|
* @param {jQuery} $attachTo An optional element to attach the instance to.
|
||||||
* @param {Boolean} skipResize Optionally skip triggering of the resize event after attaching.
|
* @param {Boolean} skipResize Optionally skip triggering of the resize event after attaching.
|
||||||
* @param {Object} The parent of this H5P
|
* @param {Object} extras - extra params for the H5P content constructor
|
||||||
* @return {Object} Instance.
|
* @return {Object} Instance.
|
||||||
*/
|
*/
|
||||||
H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
|
H5P.newRunnable = function (library, contentId, $attachTo, skipResize, extras) {
|
||||||
var nameSplit, versionSplit;
|
var nameSplit, versionSplit;
|
||||||
try {
|
try {
|
||||||
nameSplit = library.library.split(' ', 2);
|
nameSplit = library.library.split(' ', 2);
|
||||||
|
@ -633,14 +578,20 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
|
||||||
return H5P.error('Unable to find constructor for: ' + library.library);
|
return H5P.error('Unable to find constructor for: ' + library.library);
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentExtrasWrapper;
|
if (extras === undefined) {
|
||||||
if (library.userDatas && library.userDatas.state) {
|
extras = {};
|
||||||
contentExtrasWrapper = {
|
}
|
||||||
previousState: library.userDatas.state
|
if (library.uuid) {
|
||||||
};
|
extras.uuid = library.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some old library versions have their own custom third parameter. Make sure we don't send them the extras. They'll interpret it as something else
|
||||||
|
if (H5P.jQuery.inArray(library.library, ['H5P.CoursePresentation 1.0', 'H5P.CoursePresentation 1.1', 'H5P.CoursePresentation 1.2', 'H5P.CoursePresentation 1.3']) > -1) {
|
||||||
|
var instance = new constructor(library.params, contentId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var instance = new constructor(library.params, contentId, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
var instance = new constructor(library.params, contentId, contentExtrasWrapper);
|
|
||||||
|
|
||||||
if (instance.$ === undefined) {
|
if (instance.$ === undefined) {
|
||||||
instance.$ = H5P.jQuery(instance);
|
instance.$ = H5P.jQuery(instance);
|
||||||
|
@ -649,6 +600,12 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
|
||||||
if (instance.contentId === undefined) {
|
if (instance.contentId === undefined) {
|
||||||
instance.contentId = contentId;
|
instance.contentId = contentId;
|
||||||
}
|
}
|
||||||
|
if (instance.uuid === undefined && library.uuid) {
|
||||||
|
instance.uuid = library.uuid;
|
||||||
|
}
|
||||||
|
if (instance.parent === undefined && extras && extras.parent) {
|
||||||
|
instance.parent = extras.parent;
|
||||||
|
}
|
||||||
|
|
||||||
if ($attachTo !== undefined) {
|
if ($attachTo !== undefined) {
|
||||||
instance.attach($attachTo);
|
instance.attach($attachTo);
|
||||||
|
@ -1456,132 +1413,37 @@ H5P.on = function(instance, eventType, handler) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wrap in privates
|
/**
|
||||||
(function ($) {
|
* Create UUID
|
||||||
|
*
|
||||||
/**
|
* @returns {String} UUID
|
||||||
* Creates ajax requests for inserting, updateing and deleteing
|
*/
|
||||||
* content user data.
|
H5P.createUUID = function() {
|
||||||
*
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(char) {
|
||||||
* @private
|
var random = Math.random()*16|0, newChar = char === 'x' ? random : (random&0x3|0x8);
|
||||||
* @param {number} contentId What content to store the data for.
|
return newChar.toString(16);
|
||||||
* @param {string} dataType Identifies the set of data for this content.
|
|
||||||
* @param {function} [done] Callback when ajax is done.
|
|
||||||
* @param {object} [data] To be stored for future use.
|
|
||||||
* @param {boolean} [preload=false] Data is loaded when content is loaded.
|
|
||||||
* @param {boolean} [invalidate=false] Data is invalidated when content changes.
|
|
||||||
* @param {boolean} [async=true]
|
|
||||||
*/
|
|
||||||
function contentUserDataAjax(contentId, dataType, done, data, preload, invalidate, async) {
|
|
||||||
var options = {
|
|
||||||
url: H5PIntegration.ajaxPath + 'content-user-data/' + contentId + '/' + dataType,
|
|
||||||
dataType: 'json',
|
|
||||||
async: async === undefined ? true : async
|
|
||||||
};
|
|
||||||
if (data !== undefined) {
|
|
||||||
options.type = 'POST';
|
|
||||||
options.data = {
|
|
||||||
data: (data === null ? 0 : JSON.stringify(data)),
|
|
||||||
preload: (preload ? 1 : 0),
|
|
||||||
invalidate: (invalidate ? 1 : 0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
options.type = 'GET';
|
|
||||||
}
|
|
||||||
if (done !== undefined) {
|
|
||||||
options.error = function (xhr, error) {
|
|
||||||
done(error);
|
|
||||||
};
|
|
||||||
options.success = function (response) {
|
|
||||||
if (!response.success) {
|
|
||||||
done(response.error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.data === false || response.data === undefined) {
|
|
||||||
done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
done(undefined, JSON.parse(response.data));
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
done('Unable to decode data.');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get user data for given content.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
* @param {number} contentId What content to get data for.
|
|
||||||
* @param {string} dataId Identifies the set of data for this content.
|
|
||||||
* @param {function} [done] Callback with error and data parameters.
|
|
||||||
*/
|
|
||||||
H5P.getUserData = function (contentId, dataId, done) {
|
|
||||||
contentUserDataAjax(contentId, dataId, done);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set user data for given content.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
* @param {number} contentId What content to get data for.
|
|
||||||
* @param {string} dataId Identifies the set of data for this content.
|
|
||||||
* @param {object} data The data that is to be stored.
|
|
||||||
* @param {boolean} [preloaded=false] If the data should be loaded when content is loaded.
|
|
||||||
* @param {boolean} [deleteOnChange=false] If the data should be invalidated when the content changes.
|
|
||||||
* @param {function} [errorCallback] Callback with error as parameters.
|
|
||||||
*/
|
|
||||||
H5P.setUserData = function (contentId, dataId, data, preloaded, deleteOnChange, errorCallback) {
|
|
||||||
contentUserDataAjax(contentId, dataId, function (error, data) {
|
|
||||||
if (errorCallback && error) {
|
|
||||||
errorCallback(error);
|
|
||||||
}
|
|
||||||
}, data, preloaded, deleteOnChange);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete user data for given content.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
* @param {number} contentId What content to remove data for.
|
|
||||||
* @param {string} dataId Identifies the set of data for this content.
|
|
||||||
*/
|
|
||||||
H5P.deleteUserData = function (contentId, dataId) {
|
|
||||||
contentUserDataAjax(contentId, dataId, undefined, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Init H5P when page is fully loadded
|
|
||||||
$(document).ready(function () {
|
|
||||||
if (!H5P.preventInit) {
|
|
||||||
// Note that this start script has to be an external resource for it to
|
|
||||||
// load in correct order in IE9.
|
|
||||||
H5P.init(document.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (H5PIntegration.saveFreq !== false) {
|
|
||||||
// Store the current state of the H5P when leaving the page.
|
|
||||||
H5P.$window.on('unload', 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.
|
|
||||||
contentUserDataAjax(instance.contentId, 'state', undefined, state, true, true, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
})(H5P.jQuery);
|
H5P.createH5PTitle = function(rawTitle, maxLength) {
|
||||||
|
if (maxLength === undefined) {
|
||||||
|
maxLength = 60;
|
||||||
|
}
|
||||||
|
var title = H5P.jQuery('<div></div>')
|
||||||
|
.text(
|
||||||
|
// Strip tags
|
||||||
|
rawTitle.replace(/(<([^>]+)>)/ig,"")
|
||||||
|
// Escape
|
||||||
|
).text();
|
||||||
|
if (title.length > maxLength) {
|
||||||
|
title = title.substr(0, maxLength - 3) + '...';
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
};
|
||||||
|
|
||||||
|
H5P.jQuery(document).ready(function () {
|
||||||
|
if (!H5P.preventInit) {
|
||||||
|
// Start script need to be an external resource to load in correct order for IE9.
|
||||||
|
H5P.init(document.body);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue