pull/81/merge
Oliver Tacke 2021-12-22 00:58:25 +01:00 committed by GitHub
commit def8ddf8b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 2 deletions

View File

@ -2024,6 +2024,12 @@ abstract class H5PDisplayOptionBehaviour {
const CONTROLLED_BY_PERMISSIONS = 4;
}
abstract class H5PSaveContentStorages {
const NONE = 0;
const DATABASE = 1;
const LOCALSTORAGE = 2;
const DATABASE_LOCALSTORAGE = 3;
abstract class H5PContentHubSyncStatus {
const NOT_SYNCED = 0;
const SYNCED = 1;

View File

@ -80,6 +80,16 @@ H5P.init = function (target) {
// 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
if (H5P.canHasFullScreen === undefined) {
/**
@ -2338,7 +2348,7 @@ H5P.createTitle = function (rawTitle, maxLength) {
function contentUserDataAjax(contentId, dataType, subContentId, done, data, preload, invalidate, async) {
if (H5PIntegration.user === undefined) {
// Not logged in, no use in saving.
done('Not signed in.');
done('Not signed in.'); // Return value used when storing state in localStorage
return;
}
@ -2400,6 +2410,44 @@ H5P.createTitle = function (rawTitle, maxLength) {
H5PIntegration.contents = H5PIntegration.contents || {};
var content = H5PIntegration.contents['cid-' + contentId] || {};
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.getLocalStoragePrefix() + '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[subContentId][dataId] === 'RESET') {
done(undefined, null);
@ -2505,6 +2553,18 @@ H5P.createTitle = function (rawTitle, maxLength) {
if (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.getLocalStoragePrefix() + 'H5P-cid-' + contentId + '-sid-' + options.subContentId,
'{"checksum":' + H5P.getNumericalHash(content.jsonContent) + ',"state":' + data + '}'
);
}
}, data, options.preloaded, options.deleteOnChange, options.async);
};
@ -2529,7 +2589,12 @@ H5P.createTitle = function (rawTitle, maxLength) {
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.getLocalStoragePrefix() + 'H5P-cid-' + contentId + '-sid-' + subContentId);
}
}, null);
};
/**
@ -2635,6 +2700,33 @@ H5P.createTitle = function (rawTitle, maxLength) {
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 prefix for localStorage. Relevant for multiple instances on same domain.
*
* @return {string} Prefix for localStorage.
*/
H5P.getLocalStoragePrefix = function () {
if (!H5PIntegration.saveContentStorages || !H5PIntegration.saveContentStorages.localStorage || typeof(H5PIntegration.saveContentStorages.localStorage) !== 'string') {
return '';
}
return H5PIntegration.saveContentStorages.localStorage;
};
/**
* Get config for a library
*