/**
* Formatting and string utility helpers for TinAI.
*/
/**
* Generates a standard RFC4122 version 4 UUID.
* Uses crypto.randomUUID when available, with a fallback for older environments.
* @returns {string} UUID string.
*/
export function generateUUID() {
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
let ts = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
ts += performance.now();
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (ts + Math.random() * 16) % 16 | 0;
ts = Math.floor(ts / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
/**
* Safely escapes HTML special characters in a string.
* @param {string|null|undefined} text - Raw string.
* @returns {string} Escaped HTML string.
*/
export function escapeHtml(text) {
if (text === null || text === undefined) return '';
return String(text)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
/**
* Formats a query chip HTML span.
* @param {string} text - Chip text content.
* @param {string} [className='span-query-chip span-clickable-query'] - CSS class names.
* @param {string} [extraAttrs=''] - Additional HTML attributes.
* @returns {string} HTML string.
*/
export function formatQueryChip(text, className = 'span-query-chip span-clickable-query', extraAttrs = '') {
return `<span class="${className}"${extraAttrs ? ' ' + extraAttrs : ''}>${text}</span>`;
}
/**
* Formats related topics array into linked chips separated by non-breaking spaces.
* @param {string[]} relatedTopics - List of related query topics.
* @returns {string} HTML string.
*/
export function formatRelatedChipsHtml(relatedTopics) {
if (!Array.isArray(relatedTopics) || relatedTopics.length === 0) return '';
return relatedTopics
.map(topic => formatQueryChip(topic, 'span-query-chip span-related-query span-clickable-query'))
.join(' ');
}
/**
* Formats suggested queries array into linked chips separated by non-breaking spaces.
* @param {string[]} suggestions - List of suggestion strings.
* @returns {string} HTML string.
*/
export function formatSuggestedChipsHtml(suggestions) {
if (!Array.isArray(suggestions) || suggestions.length === 0) return '';
return suggestions
.map(suggestion => formatQueryChip(suggestion, 'span-query-chip span-suggested-query span-clickable-query'))
.join(' ');
}
/**
* Returns a standard horizontal divider HTML string for chat and turn separation.
* @param {string|number|null} [id=null] - Optional ID or index for the divider.
* @returns {string} HTML string.
*/
export function formatDividerHtml(id = null) {
const idAttr = (id !== null && id !== undefined) ? ` id="chat-item-${id}"` : '';
return `<hr class="hr-chat-response-divider"${idAttr}/>`;
}
format-utils.js
×
Type: Web, text/plain
2.89 Kilobytes
Last Modified 2026-09-04 14:23:28
⬇ Download File
Type: Web, text/plain
2.89 Kilobytes
Last Modified 2026-09-04 14:23:28
⬇ Download File