Changeset 3724923 for mxchat-basic/trunk/js/chat-script.js
- Timestamp:
- 10/02/2026 01:56:12 PM (4 weeks ago)
- File:
-
- 1 edited
-
mxchat-basic/trunk/js/chat-script.js (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mxchat-basic/trunk/js/chat-script.js
r3718803 r3724923 1308 1308 // Server-pushed html to append as its OWN bot bubble once the stream 1309 1309 // finishes (e.g. the consent-safe YouTube embed, plan 03ba33). Rendering is 1310 // deferred to [DONE] so the embed always lands BELOW the streamed text. 1310 // deferred to the end of the stream so the embed always lands BELOW the 1311 // streamed text. 1311 1312 let pendingAppendHtml = ''; 1313 1314 // Render the stashed appendix as its own bot bubble below the streamed 1315 // text — mirrors how it is saved in the transcript, so history replays 1316 // identically. Called from BOTH ends of a stream: the [DONE] line and 1317 // the stream simply closing (the OpenAI Responses path and Gemini end 1318 // without a [DONE] line). The stash is cleared, so a stream that sends 1319 // [DONE] and then closes renders it once. Any future appendix-type 1320 // event belongs in here, not in one of the two branches. 1321 function flushAppendHtml() { 1322 if (pendingAppendHtml) { 1323 appendMessage("bot", "", pendingAppendHtml, [], false, botId); 1324 pendingAppendHtml = ''; 1325 } 1326 } 1312 1327 1313 1328 // Abortable stream: a fresh controller per turn, keyed by bot instance. … … 1393 1408 enableChatInput(botId); 1394 1409 1410 flushAppendHtml(); 1411 1395 1412 // Scroll the user's last message to the top now that the 1396 1413 // bot's full reply has rendered (gives max reading room). … … 1425 1442 enableChatInput(botId); 1426 1443 1427 // Render any server-pushed appendix html (e.g. the 1428 // YouTube embed) as its own bot bubble below the 1429 // streamed text — mirrors how it is saved in the 1430 // transcript, so history replays identically. 1431 if (pendingAppendHtml) { 1432 appendMessage("bot", "", pendingAppendHtml, [], false, botId); 1433 pendingAppendHtml = ''; 1434 } 1444 flushAppendHtml(); 1435 1445 1436 1446 // Scroll the user's last message to the top now … … 2253 2263 } 2254 2264 2265 // Link clicks in bot and agent messages: the click is recorded, the browser 2266 // follows the anchor itself. Navigation must not wait for the tracking 2267 // request: a window.open() made from that request's callback is outside the 2268 // visitor's tap, and Safari's pop-up blocker drops it without a message. 2269 2270 // Give a tracked anchor the target it should open in, and noopener on a new tab. 2271 function prepareTrackedLink($link) { 2272 if (linkTarget === '_blank' && $link.attr('target') !== '_blank') { 2273 $link.attr('target', '_blank'); 2274 } 2275 if ($link.attr('target') === '_blank') { 2276 var rel = $link.attr('rel') || ''; 2277 if (!/(^|\s)noopener(\s|$)/.test(rel)) { 2278 $link.attr('rel', $.trim(rel + ' noopener')); 2279 } 2280 } 2281 } 2282 2283 // Record one click, fire-and-forget. sendBeacon survives the page unloading 2284 // when the link opens in the same tab. 2285 function trackLinkClick(href, messageContext, botId) { 2286 var fields = { 2287 action: 'mxchat_track_url_click', 2288 session_id: getChatSession(botId), 2289 url: href, 2290 message_context: messageContext, 2291 nonce: mxchatChat.nonce 2292 }; 2293 try { 2294 if (navigator.sendBeacon && typeof FormData !== 'undefined') { 2295 var body = new FormData(); 2296 $.each(fields, function(name, value) { 2297 body.append(name, value == null ? '' : value); 2298 }); 2299 if (navigator.sendBeacon(mxchatChat.ajax_url, body)) { 2300 return; 2301 } 2302 } 2303 } catch (error) { 2304 // Fall through to the plain request 2305 } 2306 $.ajax({ 2307 url: mxchatChat.ajax_url, 2308 type: 'POST', 2309 data: fields 2310 }); 2311 } 2312 2255 2313 // Helper function to attach link tracking with proper event handling 2256 2314 function attachLinkTracking(messageDiv, messageText, botId) { … … 2272 2330 $link.off('click.tracking'); 2273 2331 2332 // The anchor carries its own target: the browser follows it 2333 prepareTrackedLink($link); 2334 2274 2335 // Add new click handler with namespace 2275 2336 $link.on('click.tracking', function(e) { 2276 e.preventDefault();2277 2337 e.stopPropagation(); 2278 2338 … … 2281 2341 : ''; 2282 2342 2283 // Track the click 2284 $.ajax({ 2285 url: mxchatChat.ajax_url, 2286 type: 'POST', 2287 data: { 2288 action: 'mxchat_track_url_click', 2289 session_id: getChatSession(botId), 2290 url: originalHref, 2291 message_context: messageContext, 2292 nonce: mxchatChat.nonce 2293 }, 2294 complete: function() { 2295 // Always redirect, even if tracking fails 2296 if ($link.attr('target') === '_blank' || linkTarget === '_blank') { 2297 window.open(originalHref, '_blank'); 2298 } else { 2299 window.location.href = originalHref; 2300 } 2301 } 2302 }); 2303 2304 return false; // Extra insurance to prevent default 2343 prepareTrackedLink($link); 2344 trackLinkClick(originalHref, messageContext, botId); 2305 2345 }); 2306 2346 } … … 4552 4592 4553 4593 if (originalHref && (originalHref.startsWith('http://') || originalHref.startsWith('https://'))) { 4554 e.preventDefault();4555 e.stopPropagation();4556 4557 // Mark as tracked4558 $link.attr('data-tracked', 'true');4559 4560 4594 // Get bot ID from the chat box context 4561 4595 var botId = getBotIdFromElement(this); … … 4564 4598 const messageText = messageDiv.text().substring(0, 200); 4565 4599 4566 $.ajax({ 4567 url: mxchatChat.ajax_url, 4568 type: 'POST', 4569 data: { 4570 action: 'mxchat_track_url_click', 4571 session_id: getChatSession(botId), 4572 url: originalHref, 4573 message_context: messageText, 4574 nonce: mxchatChat.nonce 4575 }, 4576 complete: function() { 4577 if ($link.attr('target') === '_blank' || linkTarget === '_blank') { 4578 window.open(originalHref, '_blank'); 4579 } else { 4580 window.location.href = originalHref; 4581 } 4582 } 4583 }); 4584 4585 return false; 4600 // Same path as attachLinkTracking(): set the target, record the 4601 // click, and let the browser follow the anchor. 4602 prepareTrackedLink($link); 4603 trackLinkClick(originalHref, messageText, botId); 4586 4604 } 4587 4605 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)