153 lines
6.5 KiB
JavaScript
153 lines
6.5 KiB
JavaScript
// API region helpers for resolving source data and nested values.
|
|
|
|
var registry = window.pulsePlayerRegionTypes;
|
|
var placeholderUtils = window.placeholderUtils || {};
|
|
|
|
function getApiSourceById(sourceId) {
|
|
var sources = Array.isArray(initialData && initialData.apiSources) ? initialData.apiSources : [];
|
|
var normalizedId = Number(sourceId || 0);
|
|
return sources.find(function (source) {
|
|
return Number(source.id) === normalizedId;
|
|
}) || null;
|
|
}
|
|
|
|
function getApiSourceItemsPath(source, overridePath) {
|
|
if (overridePath === undefined || overridePath === null) {
|
|
return String(source && (source.items_path || source.itemsPath) || '').trim();
|
|
}
|
|
|
|
return String(overridePath || '').trim();
|
|
}
|
|
|
|
function getApiSourceItems(sourceId, itemsPathOverride) {
|
|
var source = getApiSourceById(sourceId);
|
|
var responseJson = source && source.responseJson && typeof source.responseJson === 'object' ? source.responseJson : null;
|
|
var itemsPath = getApiSourceItemsPath(source, itemsPathOverride);
|
|
if (itemsPath !== undefined && itemsPath !== null && itemsPath !== '') {
|
|
var current = responseJson;
|
|
String(itemsPath).split('.').forEach(function (segment) {
|
|
if (current === undefined || current === null) {
|
|
current = '';
|
|
return;
|
|
}
|
|
current = current[segment];
|
|
});
|
|
return Array.isArray(current) ? current : [];
|
|
}
|
|
if (Array.isArray(responseJson)) {
|
|
return responseJson;
|
|
}
|
|
if (responseJson && Array.isArray(responseJson.items)) {
|
|
return responseJson.items;
|
|
}
|
|
if (responseJson && Array.isArray(responseJson.results)) {
|
|
return responseJson.results;
|
|
}
|
|
if (responseJson && Array.isArray(responseJson.data)) {
|
|
return responseJson.data;
|
|
}
|
|
return responseJson ? [responseJson] : [];
|
|
}
|
|
|
|
function getApiItem(sourceId, itemNumber, itemsPathOverride) {
|
|
var items = getApiSourceItems(sourceId, itemsPathOverride);
|
|
var parsedItemNumber = Math.max(1, Number(itemNumber || 1));
|
|
var index = Number.isFinite(parsedItemNumber) && parsedItemNumber > 0 ? parsedItemNumber - 1 : 0;
|
|
return items[index] || null;
|
|
}
|
|
|
|
function substituteApiVariables(html, item, sourceId) {
|
|
var source = String(html || '');
|
|
return source.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, function (_match, expression) {
|
|
if (!item || typeof item !== 'object') {
|
|
return '';
|
|
}
|
|
|
|
if (typeof placeholderUtils.resolvePlaceholderExpression !== 'function' || typeof placeholderUtils.formatPlaceholderValue !== 'function') {
|
|
return '';
|
|
}
|
|
|
|
var resolved = placeholderUtils.resolvePlaceholderExpression(item, expression);
|
|
if (typeof placeholderUtils.isImagePlaceholderExpression === 'function' && placeholderUtils.isImagePlaceholderExpression(expression)) {
|
|
var imageSource = placeholderUtils.formatPlaceholderValue(resolved);
|
|
var source = getApiSourceById(sourceId);
|
|
imageSource = source && source.imageCache && source.imageCache[imageSource] ? source.imageCache[imageSource] : imageSource;
|
|
if (!/^(?:https?:\/\/|\/media\/|\/assets\/|\/[^/])/i.test(imageSource)) {
|
|
return '';
|
|
}
|
|
var imageConfig = typeof placeholderUtils.getImagePlaceholderConfig === 'function' ? placeholderUtils.getImagePlaceholderConfig(expression) : {};
|
|
var hasImageBounds = imageConfig.width && imageConfig.height;
|
|
var imageStyle = hasImageBounds
|
|
? 'display:block;width:100%;height:100%;object-fit:contain;'
|
|
: 'display:block;width:auto;height:auto;' + (imageConfig.width ? 'max-width:' + imageConfig.width + 'px;' : '') + (imageConfig.height ? 'max-height:' + imageConfig.height + 'px;' : '');
|
|
var image = '<img src="' + escapeHtml(imageSource) + '" alt="" style="' + imageStyle + '" />';
|
|
return hasImageBounds
|
|
? '<span style="display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:' + imageConfig.width + 'px;height:' + imageConfig.height + 'px;">' + image + '</span>'
|
|
: image;
|
|
}
|
|
return escapeHtml(placeholderUtils.formatPlaceholderValue(resolved));
|
|
});
|
|
}
|
|
|
|
function getApiPreviewFallback(item) {
|
|
if (!item || typeof item !== 'object') {
|
|
return '';
|
|
}
|
|
|
|
var title = String(item.title || item.name || '').trim();
|
|
var description = String(item.description || item.summary || item.text || '').trim();
|
|
var summary = [];
|
|
if (title) {
|
|
summary.push('<h3>' + escapeHtml(title) + '</h3>');
|
|
}
|
|
if (description) {
|
|
summary.push('<div>' + sanitizeRichText(description) + '</div>');
|
|
}
|
|
if (!summary.length) {
|
|
return '';
|
|
}
|
|
return summary.join('');
|
|
}
|
|
|
|
function normalizeRenderableValue(value) {
|
|
if (value && typeof value === 'object') {
|
|
if (value.value !== undefined) {
|
|
return value.value;
|
|
}
|
|
if (value.text !== undefined) {
|
|
return value.text;
|
|
}
|
|
if (value.html !== undefined) {
|
|
return value.html;
|
|
}
|
|
try {
|
|
return JSON.stringify(value);
|
|
} catch (_error) {
|
|
return '';
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function renderApiRegion(region, regionContent) {
|
|
var content = normalizeRenderableValue(regionContent && regionContent.value !== undefined ? regionContent.value : '');
|
|
var sourceId = regionContent && regionContent.source_id !== undefined ? regionContent.source_id : null;
|
|
var itemNumber = regionContent && regionContent.item_number !== undefined ? regionContent.item_number : 1;
|
|
var itemsPath = regionContent && regionContent.items_path !== undefined ? regionContent.items_path : '';
|
|
var fontFamily = sanitizeFontFamily(regionContent.font_family || region.fontFamily);
|
|
var fontSize = sanitizeFontSize(regionContent.font_size || region.fontSize);
|
|
var fontColor = sanitizeTextColor(regionContent.font_color || region.fontColor);
|
|
var item = getApiItem(sourceId, itemNumber, itemsPath);
|
|
var hasSource = String(sourceId === undefined || sourceId === null ? '' : sourceId).trim() !== '';
|
|
var body = hasSource ? (item ? substituteApiVariables(content, item, sourceId) : '') : content;
|
|
var contentStyle = 'width:' + region.pixelWidth + 'px;height:' + region.pixelHeight + 'px;transform:scale(' + region.canvasScale + ');transform-origin:top left;' + (fontFamily ? 'font-family:' + escapeHtml(fontFamily) + ';' : '') + 'font-size:' + fontSize + 'px;color:' + escapeHtml(fontColor) + ';';
|
|
if (!body) {
|
|
return '';
|
|
}
|
|
var renderedBody = renderEditorJsContent(body);
|
|
return renderedBody ? '<div class="template-region api" style="' + region.baseStyle + '"><div class="template-region-text-scale" style="' + contentStyle + '">' + renderedBody + '</div></div>' : '';
|
|
}
|
|
|
|
registry.register('api', {
|
|
renderRegion: renderApiRegion
|
|
}); |