Add functionality to store user state in localStorage
parent
743147698f
commit
a2849c8367
|
@ -1981,6 +1981,13 @@ abstract class H5PDisplayOptionBehaviour {
|
||||||
const CONTROLLED_BY_PERMISSIONS = 4;
|
const CONTROLLED_BY_PERMISSIONS = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class H5PSaveContentStorages {
|
||||||
|
const NONE = 0;
|
||||||
|
const DATABASE = 1;
|
||||||
|
const LOCALSTORAGE = 2;
|
||||||
|
const DATABASE_LOCALSTORAGE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
abstract class H5PHubEndpoints {
|
abstract class H5PHubEndpoints {
|
||||||
const CONTENT_TYPES = 'api.h5p.org/v1/content-types/';
|
const CONTENT_TYPES = 'api.h5p.org/v1/content-types/';
|
||||||
const SITES = 'api.h5p.org/v1/sites';
|
const SITES = 'api.h5p.org/v1/sites';
|
||||||
|
|
83
js/h5p.js
83
js/h5p.js
|
@ -80,6 +80,16 @@ H5P.init = function (target) {
|
||||||
// Update: Seems to be no need as they've moved on to Webkit
|
// Update: Seems to be no need as they've moved on to Webkit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if we can use local storage
|
||||||
|
if (H5P.localStorageSupported === undefined) {
|
||||||
|
try {
|
||||||
|
H5P.localStorageSupported = (window.localStorage) ? true : false;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
H5P.localStorageSupported = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated variable, kept to maintain backwards compatability
|
// Deprecated variable, kept to maintain backwards compatability
|
||||||
if (H5P.canHasFullScreen === undefined) {
|
if (H5P.canHasFullScreen === undefined) {
|
||||||
/**
|
/**
|
||||||
|
@ -2319,7 +2329,7 @@ H5P.createTitle = function (rawTitle, maxLength) {
|
||||||
function contentUserDataAjax(contentId, dataType, subContentId, done, data, preload, invalidate, async) {
|
function contentUserDataAjax(contentId, dataType, subContentId, done, data, preload, invalidate, async) {
|
||||||
if (H5PIntegration.user === undefined) {
|
if (H5PIntegration.user === undefined) {
|
||||||
// Not logged in, no use in saving.
|
// Not logged in, no use in saving.
|
||||||
done('Not signed in.');
|
done('Not signed in.'); // Return value used when storing state in localStorage
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2381,6 +2391,44 @@ H5P.createTitle = function (rawTitle, maxLength) {
|
||||||
H5PIntegration.contents = H5PIntegration.contents || {};
|
H5PIntegration.contents = H5PIntegration.contents || {};
|
||||||
var content = H5PIntegration.contents['cid-' + contentId] || {};
|
var content = H5PIntegration.contents['cid-' + contentId] || {};
|
||||||
var preloadedData = content.contentUserData;
|
var preloadedData = content.contentUserData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If previous state in DB is empty (user might not be logged in),
|
||||||
|
* alternatively try to preload state from localStorage
|
||||||
|
*/
|
||||||
|
if (preloadedData && preloadedData[subContentId] && preloadedData[subContentId][dataId] === '{}') {
|
||||||
|
if (H5PIntegration.saveContentStorages && H5PIntegration.saveContentStorages.localStorage && H5P.localStorageSupported) {
|
||||||
|
const localStorageData = window.localStorage.getItem('H5P-cid-' + contentId + '-sid-' + subContentId);
|
||||||
|
if (localStorageData) {
|
||||||
|
let data = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = JSON.parse(localStorageData);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('Unable to parse JSON from state in localStorage.', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.state && data.checksum) {
|
||||||
|
// Detect whether content parameters changed meanwhile
|
||||||
|
if (data.checksum === H5P.getNumericalHash(content.jsonContent)) {
|
||||||
|
try {
|
||||||
|
data = JSON.stringify(data.state);
|
||||||
|
preloadedData[subContentId][dataId] = data;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('Unable to stringify JSON for state in localStorage.', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Content has been changed
|
||||||
|
preloadedData[subContentId][dataId] = 'RESET';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (preloadedData && preloadedData[subContentId] && preloadedData[subContentId][dataId] !== undefined) {
|
if (preloadedData && preloadedData[subContentId] && preloadedData[subContentId][dataId] !== undefined) {
|
||||||
if (preloadedData[subContentId][dataId] === 'RESET') {
|
if (preloadedData[subContentId][dataId] === 'RESET') {
|
||||||
done(undefined, null);
|
done(undefined, null);
|
||||||
|
@ -2486,6 +2534,18 @@ H5P.createTitle = function (rawTitle, maxLength) {
|
||||||
if (options.errorCallback && error) {
|
if (options.errorCallback && error) {
|
||||||
options.errorCallback(error);
|
options.errorCallback(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additionally store state in localStorage if requested
|
||||||
|
if ((!error || error === 'Not signed in.') &&
|
||||||
|
H5PIntegration.saveContentStorages && H5PIntegration.saveContentStorages.localStorage && H5P.localStorageSupported
|
||||||
|
) {
|
||||||
|
// Add checksum of params to detect changes for resetting localStorage
|
||||||
|
window.localStorage.setItem(
|
||||||
|
'H5P-cid-' + contentId + '-sid-' + options.subContentId,
|
||||||
|
'{"checksum":' + H5P.getNumericalHash(content.jsonContent) + ',"state":' + data + '}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}, data, options.preloaded, options.deleteOnChange, options.async);
|
}, data, options.preloaded, options.deleteOnChange, options.async);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2510,7 +2570,12 @@ H5P.createTitle = function (rawTitle, maxLength) {
|
||||||
delete preloadedData[subContentId][dataId];
|
delete preloadedData[subContentId][dataId];
|
||||||
}
|
}
|
||||||
|
|
||||||
contentUserDataAjax(contentId, dataId, subContentId, undefined, null);
|
contentUserDataAjax(contentId, dataId, subContentId, function (error) {
|
||||||
|
// When done deleting user data in DB, delete in localStorage
|
||||||
|
if ((!error || error === 'Not signed in.') && H5P.localStorageSupported) {
|
||||||
|
window.localStorage.removeItem('H5P-cid-' + contentId + '-sid-' + subContentId);
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2616,6 +2681,20 @@ H5P.createTitle = function (rawTitle, maxLength) {
|
||||||
H5P.externalDispatcher.trigger('datainclipboard', {reset: false});
|
H5P.externalDispatcher.trigger('datainclipboard', {reset: false});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get numerical hash for a text.
|
||||||
|
*
|
||||||
|
* @param {string} text - Text to be hashed.
|
||||||
|
*/
|
||||||
|
H5P.getNumericalHash = function (text) {
|
||||||
|
text = text || '';
|
||||||
|
return text
|
||||||
|
.split('')
|
||||||
|
.reduce(function (result, current) {
|
||||||
|
return (((result << 5) - result) + current.charCodeAt(0)) | 0;
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get config for a library
|
* Get config for a library
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue