PageSourceSearch

https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dess…/js/chatbot-message-format.js

js dessertlady.ca collected 2026-10-08 07:56:29 UTC 3,356 bytes, 117 lines download raw bytes

1(function (root) {
2    function escapeHtml(text) {
3        return String(text || '')
4            .replace(/&/g, '&')
5            .replace(/</g, '&lt;')
6            .replace(/>/g, '&gt;')
7            .replace(/"/g, '&quot;')
8            .replace(/'/g, '&#39;');
9    }
10
11    function isSafeHref(href, baseOrigin) {
12        var value = String(href || '').trim();
13        if (!value) {
14            return false;
15        }
16
17        if (/^[a-z][a-z0-9+.-]*:/i.test(value) && !/^https?:/i.test(value)) {
18            return false;
19        }
20
21        if (value.indexOf('//') === 0) {
22            return false;
23        }
24
25        if (value.charAt(0) === '/' && value.charAt(1) !== '/') {
26            return true;
27        }
28
29        try {
30            var parsed = new URL(value, baseOrigin || 'https://example.test');
31            return parsed.protocol === 'http:' || parsed.protocol === 'https:';
32        } catch (error) {
33            return false;
34        }
35    }
36
37    function linkAttributes(href) {
38        var value = String(href || '').trim();
39        if (value.charAt(0) === '/' && value.charAt(1) !== '/') {
40            return '';
41        }
42
43        return ' target="_blank" rel="noopener noreferrer"';
44    }
45
46    function formatAssistantMessage(text, baseOrigin) {
47        var safe = escapeHtml(text);
48
49        safe = safe.replace(/\[([^\]]+)\]\(([^)]+)\)/g, function (match, label, url) {
50            var href = String(url || '').trim();
51            if (!isSafeHref(href, baseOrigin)) {
52                return escapeHtml(match);
53            }
54
55            return (
56                '<a class="tm-chatbot__bubble-link" href="' +
57                escapeHtml(href) +
58                '"' +
59                linkAttributes(href) +
60                '>' +
61                label +
62                '</a>'
63            );
64        });
65
66        safe = safe.replace(/(^|[\s(])((https?:\/\/)[^\s<]+[^\s<.,);:!?])/gi, function (_, prefix, url) {
67            if (!isSafeHref(url, baseOrigin)) {
68                return prefix + url;
69            }
70
71            return (
72                prefix +
73                '<a class="tm-chatbot__bubble-link" href="' +
74                escapeHtml(url) +
75                '"' +
76                linkAttributes(url) +
77                '>' +
78                url +
79                '</a>'
80            );
81        });
82
83        safe = safe.replace(/(^|[\s>:])(\/[a-z0-9][a-z0-9/_-]{6,}[a-z0-9]\/?)/gi, function (_, prefix, path) {
84            if (!isSafeHref(path, baseOrigin)) {
85                return prefix + path;
86            }
87
88            return (
89                prefix +
90                '<a class="tm-chatbot__bubble-link" href="' +
91                escapeHtml(path) +
92                '"' +
93                linkAttributes(path) +
94                '>' +
95                path +
96                '</a>'
97            );
98        });
99
100        safe = safe.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>');
101        safe = safe.replace(/(^|[^\s*])\*([^*\n]+)\*(?!\*)/g, '$1<em>$2</em>');
102
103        return safe;
104    }
105
106    var api = {
107        escapeHtml: escapeHtml,
108        isSafeHref: isSafeHref,
109        formatAssistantMessage: formatAssistantMessage
110    };
111
112    root.TmChatbotMessageFormat = api;
113
114    if (typeof module !== 'undefined' && module.exports) {
115        module.exports = api;
116    }
117})(typeof window !== 'undefined' ? window : globalThis);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.