@microsoft/omnichannel-chat-widget 1.8.4-main.cc9ad86 → 1.8.4-main.d4c4cb2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (15) hide show
  1. package/lib/cjs/components/livechatwidget/common/endChat.js +2 -0
  2. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +48 -1
  3. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  4. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +24 -7
  5. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  6. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  7. package/lib/esm/components/livechatwidget/common/endChat.js +2 -0
  8. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +48 -1
  9. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  10. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +21 -5
  11. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  12. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  13. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -0
  14. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.d.ts +3 -0
  15. package/package.json +2 -2
@@ -11,6 +11,7 @@ var _renderSurveyHelpers = require("./renderSurveyHelpers");
11
11
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
12
12
  var _ConversationState = require("../../../contexts/common/ConversationState");
13
13
  var _LazyLoadActivity = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity");
14
+ var _activityMiddleware = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware");
14
15
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
15
16
  var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler");
16
17
  var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
@@ -249,6 +250,7 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
249
250
 
250
251
  // Call direct reset to ensure LazyLoadHandler gets reset regardless of broadcast timing
251
252
  _LazyLoadActivity.LazyLoadHandler.directReset();
253
+ (0, _activityMiddleware.resetActivityMiddlewareCache)();
252
254
  _omnichannelChatComponents.BroadcastService.postMessage({
253
255
  eventName: _TelemetryConstants.BroadcastEvent.PersistentConversationReset
254
256
  });
@@ -1075,10 +1075,31 @@ const LiveChatWidgetStateful = props => {
1075
1075
  .webchat__basic-transcript__activity-markdown-body > :last-child {
1076
1076
  margin-bottom: 0px;
1077
1077
  }
1078
-
1078
+
1079
1079
  .webchat__basic-transcript__activity-markdown-body > :first-child {
1080
1080
  margin-top: 0px;
1081
1081
  }
1082
+
1083
+ /* Remove browser-default <p> margins inside system messages.
1084
+ Without this, each markdown paragraph adds ~1em top+bottom gap
1085
+ which causes the oversized line spacing visible on iOS Safari.
1086
+ Also disable iOS Safari's auto font-size scaling (-webkit-text-size-adjust)
1087
+ which inflates font sizes and causes line-height to grow over time
1088
+ when the layout is viewed in a narrow viewport. */
1089
+ .webchat__basic-transcript__activity-markdown-body {
1090
+ -webkit-text-size-adjust: 100%;
1091
+ text-size-adjust: 100%;
1092
+ }
1093
+
1094
+ .webchat__basic-transcript__activity-markdown-body p {
1095
+ margin-top: 0;
1096
+ margin-bottom: 4px;
1097
+ line-height: 1.4;
1098
+ }
1099
+
1100
+ .webchat__basic-transcript__activity-markdown-body p:last-child {
1101
+ margin-bottom: 0;
1102
+ }
1082
1103
 
1083
1104
  .webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
1084
1105
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
@@ -1086,6 +1107,32 @@ const LiveChatWidgetStateful = props => {
1086
1107
  margin-left: .25em;
1087
1108
  }
1088
1109
 
1110
+ /* ── iOS Safari: underline + number alignment fixes ────────────────
1111
+ 1. Position underlines below all glyphs (not at alphabetic baseline)
1112
+ so they never intersect numbers in links or auto-detected tel: hrefs.
1113
+ 2. Use a solid underline (skip-ink: none) so numbers aren't split by
1114
+ gaps the browser renders around descenders.
1115
+ 3. Prevent ::marker pseudo-element from inheriting text-decoration,
1116
+ which Safari applies to ol/ul counters causing them to appear
1117
+ underlined and misaligned.
1118
+ 4. Normalise ordered-list indentation across Safari/WebKit. */
1119
+ .webchat__basic-transcript__activity-markdown-body a {
1120
+ -webkit-text-underline-position: under;
1121
+ text-underline-position: under;
1122
+ text-decoration-skip-ink: none;
1123
+ -webkit-text-decoration-skip: none;
1124
+ }
1125
+
1126
+ .webchat__basic-transcript__activity-markdown-body ol li::marker,
1127
+ .webchat__basic-transcript__activity-markdown-body ul li::marker {
1128
+ text-decoration: none;
1129
+ }
1130
+
1131
+ .webchat__basic-transcript__activity-markdown-body ol {
1132
+ -webkit-padding-start: 1.5em;
1133
+ padding-inline-start: 1.5em;
1134
+ }
1135
+
1089
1136
  .webchat__link-definitions__header-text {
1090
1137
  color: ${bubbleBackground}
1091
1138
  }
@@ -23,7 +23,7 @@ const defaultWebChatStyles = {
23
23
  bubbleTextColor: "White",
24
24
  hideSendBox: false,
25
25
  hideUploadButton: true,
26
- primaryFont: "Segoe UI, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Noto Color Emoji\"",
26
+ primaryFont: "Segoe UI, Arial, sans-serif",
27
27
  rootHeight: "100%",
28
28
  rootWidth: "100%",
29
29
  sendBoxTextWrap: true,
@@ -34,7 +34,7 @@ const defaultWebChatStyles = {
34
34
  suggestedActionsStackedHeight: 125,
35
35
  suggestedActionsStackedOverflow: "scroll",
36
36
  // eslint-disable-line @typescript-eslint/no-explicit-any
37
- typingAnimationDuration: 3500,
37
+ typingAnimationDuration: 4500,
38
38
  emojiSet: {
39
39
  ":)": "😊",
40
40
  ":-)": "😊",
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createActivityMiddleware = void 0;
6
+ exports.resetActivityMiddlewareCache = exports.createActivityMiddleware = void 0;
7
7
  var _LazyLoadActivity = _interopRequireWildcard(require("./activities/LazyLoadActivity"));
8
8
  var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
9
9
  var _Constants = require("../../../../../common/Constants");
@@ -32,9 +32,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
32
32
 
33
33
  const loggedSystemMessages = new Array();
34
34
  let lastRenderedAt = 0; // Track last rendered receivedAt timestamp for deduplication
35
+ // Cache original (pre-render) text per activity ID to prevent exponential <br> growth.
36
+ // BotFramework WebChat can mutate card.activity.text between renders (e.g. on minimize/open),
37
+ // so we always render from the original markdown source, not the possibly-HTML-mutated text.
38
+ const originalSystemMessageTexts = new Map();
35
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
40
  const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyleProps) => {
37
- var _card$activity, _card$activity$channe, _card$activity$channe2, _card$activity2, _card$activity2$chann, _card$activity3, _card$activity3$chann, _card$activity3$chann2, _card$activity4, _card$activity4$chann, _card$activity5, _card$activity5$chann, _card$nextVisibleActi, _card$nextVisibleActi2, _card$activity6, _card$activity6$chann, _card$activity7, _card$nextVisibleActi3, _card$activity8;
41
+ var _card$activity, _card$activity$channe, _card$activity$channe2, _card$activity2, _card$activity2$chann, _card$activity3, _card$activity3$chann, _card$activity3$chann2, _card$activity4, _card$activity4$chann, _card$activity5, _card$activity5$chann, _card$nextVisibleActi, _card$nextVisibleActi2, _card$activity6, _card$activity6$chann, _card$activity7, _card$nextVisibleActi3, _card$activity8, _card$activity9, _card$activity9$chann;
38
42
  const systemMessageStyles = {
39
43
  ..._defaultSystemMessageStyles.defaultSystemMessageStyles,
40
44
  ...systemMessageStyleProps
@@ -56,7 +60,12 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
56
60
  if ((_card$activity5 = card.activity) !== null && _card$activity5 !== void 0 && (_card$activity5$chann = _card$activity5.channelData) !== null && _card$activity5$chann !== void 0 && _card$activity5$chann.clientmessageid && ((_card$nextVisibleActi = card.nextVisibleActivity) === null || _card$nextVisibleActi === void 0 ? void 0 : (_card$nextVisibleActi2 = _card$nextVisibleActi.channelData) === null || _card$nextVisibleActi2 === void 0 ? void 0 : _card$nextVisibleActi2.clientmessageid) === ((_card$activity6 = card.activity) === null || _card$activity6 === void 0 ? void 0 : (_card$activity6$chann = _card$activity6.channelData) === null || _card$activity6$chann === void 0 ? void 0 : _card$activity6$chann.clientmessageid) || (_card$activity7 = card.activity) !== null && _card$activity7 !== void 0 && _card$activity7.messageid && ((_card$nextVisibleActi3 = card.nextVisibleActivity) === null || _card$nextVisibleActi3 === void 0 ? void 0 : _card$nextVisibleActi3.messageid) === ((_card$activity8 = card.activity) === null || _card$activity8 === void 0 ? void 0 : _card$activity8.messageid)) {
57
61
  return () => false;
58
62
  }
59
- card.activity.text = renderMarkdown(card.activity.text);
63
+ const activityKey = card.activity.id || ((_card$activity9 = card.activity) === null || _card$activity9 === void 0 ? void 0 : (_card$activity9$chann = _card$activity9.channelData) === null || _card$activity9$chann === void 0 ? void 0 : _card$activity9$chann.clientmessageid);
64
+ if (activityKey && !originalSystemMessageTexts.has(activityKey)) {
65
+ originalSystemMessageTexts.set(activityKey, card.activity.text);
66
+ }
67
+ const sourceText = (activityKey && originalSystemMessageTexts.get(activityKey)) ?? card.activity.text;
68
+ const renderedHtml = renderMarkdown(sourceText);
60
69
  // eslint-disable-next-line react/display-name
61
70
  return () => /*#__PURE__*/_react.default.createElement("div", {
62
71
  key: card.activity.id,
@@ -64,7 +73,7 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
64
73
  "aria-hidden": "false",
65
74
  className: _Constants.Constants.markDownSystemMessageClass,
66
75
  dangerouslySetInnerHTML: {
67
- __html: card.activity.text
76
+ __html: renderedHtml
68
77
  }
69
78
  });
70
79
  };
@@ -97,12 +106,12 @@ const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps, userM
97
106
  return handleSystemMessage(next, args, card, renderMarkdown, systemMessageStyleProps);
98
107
  }
99
108
  if (isTagIncluded(card, _Constants.Constants.persistentChatHistoryMessagePullTriggerTag)) {
100
- var _card$activity9, _card$activity9$chann, _card$activity9$chann2;
109
+ var _card$activity10, _card$activity10$chan, _card$activity10$chan2;
101
110
  // Safety check: if this is a new chat session and flag is false, auto-correct it
102
111
  if (!_LazyLoadActivity.LazyLoadHandler.hasMoreHistoryAvailable) {
103
112
  _LazyLoadActivity.LazyLoadHandler.setHasMoreHistoryAvailable(true);
104
113
  }
105
- const receivedAt = card === null || card === void 0 ? void 0 : (_card$activity9 = card.activity) === null || _card$activity9 === void 0 ? void 0 : (_card$activity9$chann = _card$activity9.channelData) === null || _card$activity9$chann === void 0 ? void 0 : (_card$activity9$chann2 = _card$activity9$chann.webChat) === null || _card$activity9$chann2 === void 0 ? void 0 : _card$activity9$chann2.receivedAt;
114
+ const receivedAt = card === null || card === void 0 ? void 0 : (_card$activity10 = card.activity) === null || _card$activity10 === void 0 ? void 0 : (_card$activity10$chan = _card$activity10.channelData) === null || _card$activity10$chan === void 0 ? void 0 : (_card$activity10$chan2 = _card$activity10$chan.webChat) === null || _card$activity10$chan2 === void 0 ? void 0 : _card$activity10$chan2.receivedAt;
106
115
  if (receivedAt < lastRenderedAt) {
107
116
  card.activity = null;
108
117
  return () => false;
@@ -157,4 +166,12 @@ const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps, userM
157
166
  }
158
167
  return next(...args);
159
168
  };
160
- exports.createActivityMiddleware = createActivityMiddleware;
169
+
170
+ /** Clear module-level caches. Call on conversation end / chat close. */
171
+ exports.createActivityMiddleware = createActivityMiddleware;
172
+ const resetActivityMiddlewareCache = () => {
173
+ loggedSystemMessages.length = 0;
174
+ lastRenderedAt = 0;
175
+ originalSystemMessageTexts.clear();
176
+ };
177
+ exports.resetActivityMiddlewareCache = resetActivityMiddlewareCache;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.defaultAvatarTextStyles = void 0;
7
7
  const defaultAvatarTextStyles = {
8
8
  margin: "0",
9
- fontFamily: "'Segoe UI', 'Apple Color Emoji', 'Noto Color Emoji', 'Segoe UI Emoji', Arial, sans-serif",
9
+ fontFamily: "'Segoe UI', Arial, sans-serif",
10
10
  fontWeight: 600,
11
11
  fontSize: "13px",
12
12
  lineHeight: "18px",
@@ -11,8 +11,13 @@ const defaultSystemMessageStyles = {
11
11
  fontSize: "12px",
12
12
  borderRadius: 0,
13
13
  minHeight: "auto",
14
- fontFamily: "'Segoe UI', 'Apple Color Emoji', 'Noto Color Emoji', 'Segoe UI Emoji', Arial, sans-serif",
15
- lineHeight: "16px",
16
- padding: "0px 10px 0 10px"
14
+ fontFamily: "'Segoe UI', Arial, sans-serif",
15
+ lineHeight: "1.4",
16
+ padding: "0px 10px 0 10px",
17
+ // iOS Safari: position underlines below all glyphs so they do not
18
+ // intersect numbers. Also enforce lining figures for consistent baselines.
19
+ WebkitTextUnderlinePosition: "under",
20
+ textUnderlinePosition: "under",
21
+ fontVariantNumeric: "lining-nums"
17
22
  };
18
23
  exports.defaultSystemMessageStyles = defaultSystemMessageStyles;
@@ -5,6 +5,7 @@ import { getPostChatContext, initiatePostChat } from "./renderSurveyHelpers";
5
5
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
6
6
  import { ConversationState } from "../../../contexts/common/ConversationState";
7
7
  import { LazyLoadHandler } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity";
8
+ import { resetActivityMiddlewareCache } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware";
8
9
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
9
10
  import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
10
11
  import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
@@ -243,6 +244,7 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
243
244
 
244
245
  // Call direct reset to ensure LazyLoadHandler gets reset regardless of broadcast timing
245
246
  LazyLoadHandler.directReset();
247
+ resetActivityMiddlewareCache();
246
248
  BroadcastService.postMessage({
247
249
  eventName: BroadcastEvent.PersistentConversationReset
248
250
  });
@@ -1067,10 +1067,31 @@ export const LiveChatWidgetStateful = props => {
1067
1067
  .webchat__basic-transcript__activity-markdown-body > :last-child {
1068
1068
  margin-bottom: 0px;
1069
1069
  }
1070
-
1070
+
1071
1071
  .webchat__basic-transcript__activity-markdown-body > :first-child {
1072
1072
  margin-top: 0px;
1073
1073
  }
1074
+
1075
+ /* Remove browser-default <p> margins inside system messages.
1076
+ Without this, each markdown paragraph adds ~1em top+bottom gap
1077
+ which causes the oversized line spacing visible on iOS Safari.
1078
+ Also disable iOS Safari's auto font-size scaling (-webkit-text-size-adjust)
1079
+ which inflates font sizes and causes line-height to grow over time
1080
+ when the layout is viewed in a narrow viewport. */
1081
+ .webchat__basic-transcript__activity-markdown-body {
1082
+ -webkit-text-size-adjust: 100%;
1083
+ text-size-adjust: 100%;
1084
+ }
1085
+
1086
+ .webchat__basic-transcript__activity-markdown-body p {
1087
+ margin-top: 0;
1088
+ margin-bottom: 4px;
1089
+ line-height: 1.4;
1090
+ }
1091
+
1092
+ .webchat__basic-transcript__activity-markdown-body p:last-child {
1093
+ margin-bottom: 0;
1094
+ }
1074
1095
 
1075
1096
  .webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
1076
1097
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
@@ -1078,6 +1099,32 @@ export const LiveChatWidgetStateful = props => {
1078
1099
  margin-left: .25em;
1079
1100
  }
1080
1101
 
1102
+ /* ── iOS Safari: underline + number alignment fixes ────────────────
1103
+ 1. Position underlines below all glyphs (not at alphabetic baseline)
1104
+ so they never intersect numbers in links or auto-detected tel: hrefs.
1105
+ 2. Use a solid underline (skip-ink: none) so numbers aren't split by
1106
+ gaps the browser renders around descenders.
1107
+ 3. Prevent ::marker pseudo-element from inheriting text-decoration,
1108
+ which Safari applies to ol/ul counters causing them to appear
1109
+ underlined and misaligned.
1110
+ 4. Normalise ordered-list indentation across Safari/WebKit. */
1111
+ .webchat__basic-transcript__activity-markdown-body a {
1112
+ -webkit-text-underline-position: under;
1113
+ text-underline-position: under;
1114
+ text-decoration-skip-ink: none;
1115
+ -webkit-text-decoration-skip: none;
1116
+ }
1117
+
1118
+ .webchat__basic-transcript__activity-markdown-body ol li::marker,
1119
+ .webchat__basic-transcript__activity-markdown-body ul li::marker {
1120
+ text-decoration: none;
1121
+ }
1122
+
1123
+ .webchat__basic-transcript__activity-markdown-body ol {
1124
+ -webkit-padding-start: 1.5em;
1125
+ padding-inline-start: 1.5em;
1126
+ }
1127
+
1081
1128
  .webchat__link-definitions__header-text {
1082
1129
  color: ${bubbleBackground}
1083
1130
  }
@@ -17,7 +17,7 @@ export const defaultWebChatStyles = {
17
17
  bubbleTextColor: "White",
18
18
  hideSendBox: false,
19
19
  hideUploadButton: true,
20
- primaryFont: "Segoe UI, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Noto Color Emoji\"",
20
+ primaryFont: "Segoe UI, Arial, sans-serif",
21
21
  rootHeight: "100%",
22
22
  rootWidth: "100%",
23
23
  sendBoxTextWrap: true,
@@ -28,7 +28,7 @@ export const defaultWebChatStyles = {
28
28
  suggestedActionsStackedHeight: 125,
29
29
  suggestedActionsStackedOverflow: "scroll",
30
30
  // eslint-disable-line @typescript-eslint/no-explicit-any
31
- typingAnimationDuration: 3500,
31
+ typingAnimationDuration: 4500,
32
32
  emojiSet: {
33
33
  ":)": "😊",
34
34
  ":-)": "😊",
@@ -23,9 +23,13 @@ import { defaultUserMessageStyles } from "./defaultStyles/defaultUserMessageStyl
23
23
  import { escapeHtml } from "../../../../../common/utils";
24
24
  const loggedSystemMessages = new Array();
25
25
  let lastRenderedAt = 0; // Track last rendered receivedAt timestamp for deduplication
26
+ // Cache original (pre-render) text per activity ID to prevent exponential <br> growth.
27
+ // BotFramework WebChat can mutate card.activity.text between renders (e.g. on minimize/open),
28
+ // so we always render from the original markdown source, not the possibly-HTML-mutated text.
29
+ const originalSystemMessageTexts = new Map();
26
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
31
  const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyleProps) => {
28
- var _card$activity, _card$activity$channe, _card$activity$channe2, _card$activity2, _card$activity2$chann, _card$activity3, _card$activity3$chann, _card$activity3$chann2, _card$activity4, _card$activity4$chann, _card$activity5, _card$activity5$chann, _card$nextVisibleActi, _card$nextVisibleActi2, _card$activity6, _card$activity6$chann, _card$activity7, _card$nextVisibleActi3, _card$activity8;
32
+ var _card$activity, _card$activity$channe, _card$activity$channe2, _card$activity2, _card$activity2$chann, _card$activity3, _card$activity3$chann, _card$activity3$chann2, _card$activity4, _card$activity4$chann, _card$activity5, _card$activity5$chann, _card$nextVisibleActi, _card$nextVisibleActi2, _card$activity6, _card$activity6$chann, _card$activity7, _card$nextVisibleActi3, _card$activity8, _card$activity9, _card$activity9$chann;
29
33
  const systemMessageStyles = {
30
34
  ...defaultSystemMessageStyles,
31
35
  ...systemMessageStyleProps
@@ -47,7 +51,12 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
47
51
  if ((_card$activity5 = card.activity) !== null && _card$activity5 !== void 0 && (_card$activity5$chann = _card$activity5.channelData) !== null && _card$activity5$chann !== void 0 && _card$activity5$chann.clientmessageid && ((_card$nextVisibleActi = card.nextVisibleActivity) === null || _card$nextVisibleActi === void 0 ? void 0 : (_card$nextVisibleActi2 = _card$nextVisibleActi.channelData) === null || _card$nextVisibleActi2 === void 0 ? void 0 : _card$nextVisibleActi2.clientmessageid) === ((_card$activity6 = card.activity) === null || _card$activity6 === void 0 ? void 0 : (_card$activity6$chann = _card$activity6.channelData) === null || _card$activity6$chann === void 0 ? void 0 : _card$activity6$chann.clientmessageid) || (_card$activity7 = card.activity) !== null && _card$activity7 !== void 0 && _card$activity7.messageid && ((_card$nextVisibleActi3 = card.nextVisibleActivity) === null || _card$nextVisibleActi3 === void 0 ? void 0 : _card$nextVisibleActi3.messageid) === ((_card$activity8 = card.activity) === null || _card$activity8 === void 0 ? void 0 : _card$activity8.messageid)) {
48
52
  return () => false;
49
53
  }
50
- card.activity.text = renderMarkdown(card.activity.text);
54
+ const activityKey = card.activity.id || ((_card$activity9 = card.activity) === null || _card$activity9 === void 0 ? void 0 : (_card$activity9$chann = _card$activity9.channelData) === null || _card$activity9$chann === void 0 ? void 0 : _card$activity9$chann.clientmessageid);
55
+ if (activityKey && !originalSystemMessageTexts.has(activityKey)) {
56
+ originalSystemMessageTexts.set(activityKey, card.activity.text);
57
+ }
58
+ const sourceText = (activityKey && originalSystemMessageTexts.get(activityKey)) ?? card.activity.text;
59
+ const renderedHtml = renderMarkdown(sourceText);
51
60
  // eslint-disable-next-line react/display-name
52
61
  return () => /*#__PURE__*/React.createElement("div", {
53
62
  key: card.activity.id,
@@ -55,7 +64,7 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
55
64
  "aria-hidden": "false",
56
65
  className: Constants.markDownSystemMessageClass,
57
66
  dangerouslySetInnerHTML: {
58
- __html: card.activity.text
67
+ __html: renderedHtml
59
68
  }
60
69
  });
61
70
  };
@@ -88,12 +97,12 @@ export const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps
88
97
  return handleSystemMessage(next, args, card, renderMarkdown, systemMessageStyleProps);
89
98
  }
90
99
  if (isTagIncluded(card, Constants.persistentChatHistoryMessagePullTriggerTag)) {
91
- var _card$activity9, _card$activity9$chann, _card$activity9$chann2;
100
+ var _card$activity10, _card$activity10$chan, _card$activity10$chan2;
92
101
  // Safety check: if this is a new chat session and flag is false, auto-correct it
93
102
  if (!LazyLoadHandler.hasMoreHistoryAvailable) {
94
103
  LazyLoadHandler.setHasMoreHistoryAvailable(true);
95
104
  }
96
- const receivedAt = card === null || card === void 0 ? void 0 : (_card$activity9 = card.activity) === null || _card$activity9 === void 0 ? void 0 : (_card$activity9$chann = _card$activity9.channelData) === null || _card$activity9$chann === void 0 ? void 0 : (_card$activity9$chann2 = _card$activity9$chann.webChat) === null || _card$activity9$chann2 === void 0 ? void 0 : _card$activity9$chann2.receivedAt;
105
+ const receivedAt = card === null || card === void 0 ? void 0 : (_card$activity10 = card.activity) === null || _card$activity10 === void 0 ? void 0 : (_card$activity10$chan = _card$activity10.channelData) === null || _card$activity10$chan === void 0 ? void 0 : (_card$activity10$chan2 = _card$activity10$chan.webChat) === null || _card$activity10$chan2 === void 0 ? void 0 : _card$activity10$chan2.receivedAt;
97
106
  if (receivedAt < lastRenderedAt) {
98
107
  card.activity = null;
99
108
  return () => false;
@@ -147,4 +156,11 @@ export const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps
147
156
  }
148
157
  }
149
158
  return next(...args);
159
+ };
160
+
161
+ /** Clear module-level caches. Call on conversation end / chat close. */
162
+ export const resetActivityMiddlewareCache = () => {
163
+ loggedSystemMessages.length = 0;
164
+ lastRenderedAt = 0;
165
+ originalSystemMessageTexts.clear();
150
166
  };
@@ -1,6 +1,6 @@
1
1
  export const defaultAvatarTextStyles = {
2
2
  margin: "0",
3
- fontFamily: "'Segoe UI', 'Apple Color Emoji', 'Noto Color Emoji', 'Segoe UI Emoji', Arial, sans-serif",
3
+ fontFamily: "'Segoe UI', Arial, sans-serif",
4
4
  fontWeight: 600,
5
5
  fontSize: "13px",
6
6
  lineHeight: "18px",
@@ -5,7 +5,12 @@ export const defaultSystemMessageStyles = {
5
5
  fontSize: "12px",
6
6
  borderRadius: 0,
7
7
  minHeight: "auto",
8
- fontFamily: "'Segoe UI', 'Apple Color Emoji', 'Noto Color Emoji', 'Segoe UI Emoji', Arial, sans-serif",
9
- lineHeight: "16px",
10
- padding: "0px 10px 0 10px"
8
+ fontFamily: "'Segoe UI', Arial, sans-serif",
9
+ lineHeight: "1.4",
10
+ padding: "0px 10px 0 10px",
11
+ // iOS Safari: position underlines below all glyphs so they do not
12
+ // intersect numbers. Also enforce lining figures for consistent baselines.
13
+ WebkitTextUnderlinePosition: "under",
14
+ textUnderlinePosition: "under",
15
+ fontVariantNumeric: "lining-nums"
11
16
  };
@@ -9,3 +9,5 @@
9
9
  import { ILiveChatWidgetLocalizedTexts } from "../../../../../contexts/common/ILiveChatWidgetLocalizedTexts";
10
10
  import React from "react";
11
11
  export declare const createActivityMiddleware: (renderMarkdown: (text: string) => string, systemMessageStyleProps?: React.CSSProperties, userMessageStyleProps?: React.CSSProperties, localizedTexts?: ILiveChatWidgetLocalizedTexts) => () => (next: any) => (...args: any) => any;
12
+ /** Clear module-level caches. Call on conversation end / chat close. */
13
+ export declare const resetActivityMiddlewareCache: () => void;
@@ -8,4 +8,7 @@ export declare const defaultSystemMessageStyles: {
8
8
  fontFamily: string;
9
9
  lineHeight: string;
10
10
  padding: string;
11
+ WebkitTextUnderlinePosition: "under";
12
+ textUnderlinePosition: "under";
13
+ fontVariantNumeric: "lining-nums";
11
14
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.8.4-main.cc9ad86",
3
+ "version": "1.8.4-main.d4c4cb2",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -91,7 +91,7 @@
91
91
  "@azure/core-tracing": "^1.2.0",
92
92
  "@microsoft/applicationinsights-web": "^3.3.6",
93
93
  "@microsoft/omnichannel-chat-components": "1.1.17-main.940d996",
94
- "@microsoft/omnichannel-chat-sdk": "1.11.9-main.941a049",
94
+ "@microsoft/omnichannel-chat-sdk": "1.11.9-main.da8219b",
95
95
  "@opentelemetry/api": "^1.9.0",
96
96
  "abort-controller": "^3",
97
97
  "abort-controller-es5": "^2.0.1",