Spaces:
Running
Running
File size: 4,709 Bytes
b82d373 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import { applyLocale } from './i18n.js';
/**
* @type {Map<string, function>}
* @description Cache for Handlebars templates.
*/
const TEMPLATE_CACHE = new Map();
/**
* Loads a URL content using XMLHttpRequest synchronously.
* @param {string} url URL to load synchronously
* @returns {string} Response text
*/
function getUrlSync(url) {
console.debug('Loading URL synchronously', url);
const request = new XMLHttpRequest();
request.open('GET', url, false); // `false` makes the request synchronous
request.send();
if (request.status >= 200 && request.status < 300) {
return request.responseText;
}
throw new Error(`Error loading ${url}: ${request.status} ${request.statusText}`);
}
/**
* Loads a URL content using XMLHttpRequest asynchronously.
* @param {string} url URL to load asynchronously
* @returns {Promise<string>} Response text
*/
function getUrlAsync(url) {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.onload = () => {
if (request.status >= 200 && request.status < 300) {
resolve(request.responseText);
} else {
reject(new Error(`Error loading ${url}: ${request.status} ${request.statusText}`));
}
};
request.onerror = () => {
reject(new Error(`Error loading ${url}: ${request.status} ${request.statusText}`));
};
request.send();
});
}
/**
* Renders a Handlebars template asynchronously.
* @param {string} templateId ID of the template to render
* @param {Record<string, any>} templateData The data to pass to the template
* @param {boolean} sanitize Should the template be sanitized with DOMPurify
* @param {boolean} localize Should the template be localized
* @param {boolean} fullPath Should the template ID be treated as a full path or a relative path
* @returns {Promise<string>} Rendered template
*/
export async function renderTemplateAsync(templateId, templateData = {}, sanitize = true, localize = true, fullPath = false) {
async function fetchTemplateAsync(pathToTemplate) {
let template = TEMPLATE_CACHE.get(pathToTemplate);
if (!template) {
const templateContent = await getUrlAsync(pathToTemplate);
template = Handlebars.compile(templateContent);
TEMPLATE_CACHE.set(pathToTemplate, template);
}
return template;
}
try {
const pathToTemplate = fullPath ? templateId : `/scripts/templates/${templateId}.html`;
const template = await fetchTemplateAsync(pathToTemplate);
let result = template(templateData);
if (sanitize) {
result = DOMPurify.sanitize(result);
}
if (localize) {
result = applyLocale(result);
}
return result;
} catch (err) {
console.error('Error rendering template', templateId, templateData, err);
toastr.error('Check the DevTools console for more information.', 'Error rendering template');
}
}
/**
* Renders a Handlebars template synchronously.
* @param {string} templateId ID of the template to render
* @param {Record<string, any>} templateData The data to pass to the template
* @param {boolean} sanitize Should the template be sanitized with DOMPurify
* @param {boolean} localize Should the template be localized
* @param {boolean} fullPath Should the template ID be treated as a full path or a relative path
* @returns {string} Rendered template
*
* @deprecated Use renderTemplateAsync instead.
*/
export function renderTemplate(templateId, templateData = {}, sanitize = true, localize = true, fullPath = false) {
function fetchTemplateSync(pathToTemplate) {
let template = TEMPLATE_CACHE.get(pathToTemplate);
if (!template) {
const templateContent = getUrlSync(pathToTemplate);
template = Handlebars.compile(templateContent);
TEMPLATE_CACHE.set(pathToTemplate, template);
}
return template;
}
try {
const pathToTemplate = fullPath ? templateId : `/scripts/templates/${templateId}.html`;
const template = fetchTemplateSync(pathToTemplate);
let result = template(templateData);
if (sanitize) {
result = DOMPurify.sanitize(result);
}
if (localize) {
result = applyLocale(result);
}
return result;
} catch (err) {
console.error('Error rendering template', templateId, templateData, err);
toastr.error('Check the DevTools console for more information.', 'Error rendering template');
}
}
|