function xOpatParseConfiguration(postData, i18n, supportsPost) {
function ensureDefined(object, property, defaultValue) {
if (!object.hasOwnProperty(property)) {
object[property] = defaultValue;
return false;
}
return true;
}
function _parse(configuration) {
function isBoolFlagInObject(object, key) {
const ref = object ? object[key] : undefined;
if (ref === undefined || ref === null) return false;
if (typeof ref === "string") return ref !== "" && ref !== "false";
return !!ref;
}
function getError(title, description, details) {
return {error: title, description: description, details: details};
}
if (!configuration) {
return null;
}
if (typeof configuration === "string") {
try {
configuration = JSON.parse(configuration);
} catch (e) {
return getError( "messages.urlInvalid", "messages.postDataSyntaxErr",
` "JSON Error: ${e}<br>`
+ JSON.stringify(configuration.data));
}
}
ensureDefined(configuration, "params", {});
ensureDefined(configuration, "data", []);
let definedRendering = ensureDefined(configuration, "background", []);
ensureDefined(configuration, "plugins", {});
const isDebug = isBoolFlagInObject(configuration.params, "debugMode");
const bypassCookies = isBoolFlagInObject(configuration.params, "bypassCookies");
function isValidDataReference(ref, dataLen) {
if (Number.isInteger(ref)) return ref >= 0 && ref < dataLen;
if (typeof ref === "string" && ref) return true;
if (ref && typeof ref === "object") {
if (ref.dataID !== undefined) return true;
return Object.keys(ref).length > 0;
}
return false;
}
for (let bg of configuration.background) {
if (!bg || !isValidDataReference(bg.dataReference, configuration.data.length)) {
return getError("messages.urlInvalid", "messages.bgReferenceMissing",
`Invalid data reference '${JSON.stringify(bg?.dataReference)}'. Available data: `
+ JSON.stringify(configuration.data));
}
}
const singleBgImage = configuration.background.length === 1;
const firstTimeVisited = false;
if (configuration.visualizations) {
definedRendering = true;
}
if (!definedRendering) {
return getError("error.nothingToRender",
"error.nothingToRenderDescription",
"Empty background and visualization configuration.");
}
return configuration;
}
let session;
try {
const url = new URL(window.location.href);
let data = postData["visualization"] || postData["visualisation"];
session = _parse(data);
if (!session || session.error) {
const fromHash = !!url.hash;
const urlData = fromHash
? decodeURIComponent(url.hash.substring(1))
: url.searchParams.get("visualization");
if (urlData) {
data = urlData;
if (supportsPost && !fromHash) {
const form = document.createElement("form");
form.method = "POST";
const node = document.createElement("input");
node.name = "visualization";
node.value = data;
form.appendChild(node);
form.style.visibility = 'hidden';
document.body.appendChild(form);
url.hash = "";
form.action = String(url);
form.submit();
} else {
session = _parse(data);
}
}
if (session && session.error && typeof data === "string" && /%[0-9A-Fa-f]{2}/.test(data)) {
try {
const retried = _parse(decodeURIComponent(data));
if (retried && !retried.error) session = retried;
} catch { }
}
}
if (!session) {
const handMadeConfiguration = {
data: []
};
const slide = url.searchParams.get("slides");
let processed = false;
if (slide) {
const slideList = slide.split(",");
handMadeConfiguration.data = slideList;
handMadeConfiguration.background = slideList.map((slide, index) => {
return {
dataReference: index,
}
});
processed = true;
}
let masks = url.searchParams.get("masks");
if (masks) {
masks = masks.split(',');
const visConfig = {
name: "Masks",
shaders: {}
};
handMadeConfiguration.visualizations = [visConfig];
let index = 1;
for (let mask of masks) {
handMadeConfiguration.data.push(mask);
visConfig.shaders[mask] = {
type: "heatmap",
fixed: false,
visible: 1,
dataReferences: [index++],
params: { }
}
}
processed = true;
}
if (processed) {
session = _parse(handMadeConfiguration);
}
}
if (!session) {
let strData = window.localStorage.getItem("xoSessionCache");
if (strData && strData !== "undefined") {
const data = JSON.parse(strData);
const viz = data.visualization;
if (viz && viz.__age && Date.now() - viz.__age < 1800e3) {
postData = data;
delete viz.__age;
session = _parse(viz);
session.__fromLocalStorage = true;
}
} else {
strData = window.sessionStorage.getItem("xoSessionCache");
const data = strData && strData !== "undefined" && JSON.parse(strData);
if (data) {
postData = data;
session = data.visualization && _parse(data.visualization);
session.__fromLocalStorage = true;
}
}
} else if (!session.error) {
const data = postData || {};
session.__age = Date.now();
data.visualization = session;
const sessionData = JSON.stringify(data);
window.localStorage.setItem("xoSessionCache", sessionData);
window.sessionStorage.setItem("xoSessionCache", sessionData);
}
if (!session) {
session = {};
}
if (session.error) {
session.error = i18n.t(session.error);
if (session.description) session.description = i18n.t(session.description);
}
} catch (e) {
postData = postData || {};
session = {error: e};
}
ensureDefined(session, "params", {});
ensureDefined(session, "data", []);
ensureDefined(session, "background", []);
ensureDefined(session, "plugins", {});
postData.visualization = session;
return postData;
}