@microsoft/omnichannel-chat-widget 1.7.6 → 1.7.7-main.262d750

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 (42) hide show
  1. package/lib/cjs/common/Constants.js +3 -0
  2. package/lib/cjs/common/facades/FacadeChatSDK.js +62 -19
  3. package/lib/cjs/common/utils.js +14 -2
  4. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
  5. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +4 -3
  6. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +27 -22
  7. package/lib/cjs/components/livechatwidget/interfaces/ISendBox.js +1 -0
  8. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
  9. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
  10. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
  11. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
  12. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  13. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
  14. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
  15. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
  16. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
  17. package/lib/cjs/plugins/createChatTranscript.js +5 -1
  18. package/lib/esm/common/Constants.js +3 -0
  19. package/lib/esm/common/facades/FacadeChatSDK.js +62 -19
  20. package/lib/esm/common/utils.js +11 -1
  21. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
  22. package/lib/esm/components/livechatwidget/common/createMarkdown.js +4 -3
  23. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +28 -22
  24. package/lib/esm/components/livechatwidget/interfaces/ISendBox.js +1 -0
  25. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
  26. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
  27. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
  28. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
  29. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  30. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
  31. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
  32. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
  33. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
  34. package/lib/esm/plugins/createChatTranscript.js +5 -1
  35. package/lib/types/common/Constants.d.ts +3 -0
  36. package/lib/types/common/facades/FacadeChatSDK.d.ts +2 -0
  37. package/lib/types/common/utils.d.ts +1 -0
  38. package/lib/types/components/livechatwidget/common/createMarkdown.d.ts +1 -1
  39. package/lib/types/components/livechatwidget/interfaces/ISendBox.d.ts +12 -0
  40. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +5 -0
  41. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.d.ts +1 -1
  42. package/package.json +2 -2
@@ -22,8 +22,9 @@ const convertTextToHtmlNode = text => {
22
22
  if (!text) return "";
23
23
  const element = document.createElement(_Constants.HtmlAttributeNames.div);
24
24
  try {
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- text = _dompurify.default.sanitize(text);
25
+ text = _dompurify.default.sanitize(text, {
26
+ ADD_ATTR: ["target"]
27
+ });
27
28
  element.innerHTML = text;
28
29
  } catch (e) {
29
30
  const errorMessage = `Failed to purify and set innertHTML with text: ${text}`;
@@ -39,7 +40,7 @@ const convertTextToHtmlNode = text => {
39
40
  };
40
41
 
41
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
- const processHTMLText = (action, text) => {
43
+ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
43
44
  const htmlNode = convertTextToHtmlNode(text);
44
45
  const aNodes = htmlNode.getElementsByTagName(_Constants.HtmlAttributeNames.aTagName);
45
46
  if ((aNodes === null || aNodes === void 0 ? void 0 : aNodes.length) > 0) {
@@ -52,8 +53,8 @@ const processHTMLText = (action, text) => {
52
53
  continue;
53
54
  }
54
55
 
55
- // Add target to 'a' node if target is missing or does not equal to blank
56
- if (!aNode.target || aNode.target !== _Constants.Constants.blank) {
56
+ // Add target to 'a' node if target is missing or if honorsTargetInHTMLLinks is false
57
+ if (!aNode.target || !honorsTargetInHTMLLinks) {
57
58
  aNode.target = _Constants.Constants.blank;
58
59
  }
59
60
 
@@ -69,9 +70,6 @@ const processHTMLText = (action, text) => {
69
70
  }
70
71
  }
71
72
  }
72
-
73
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
- action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
75
73
  } catch (e) {
76
74
  let errorMessage = "Failed to apply action: ";
77
75
  try {
@@ -88,11 +86,12 @@ const processHTMLText = (action, text) => {
88
86
  });
89
87
  }
90
88
  }
89
+ action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
91
90
  return action;
92
91
  };
93
92
 
94
93
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
95
- const htmlTextMiddleware = _ref => {
94
+ const htmlTextMiddleware = honorsTargetInHTMLLinks => _ref => {
96
95
  let {
97
96
  dispatch
98
97
  } = _ref;
@@ -102,7 +101,7 @@ const htmlTextMiddleware = _ref => {
102
101
  var _action$payload, _action$payload$activ;
103
102
  const text = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : (_action$payload$activ = _action$payload.activity) === null || _action$payload$activ === void 0 ? void 0 : _action$payload$activ.text;
104
103
  if (text) {
105
- action = processHTMLText(action, text);
104
+ action = processHTMLText(action, text, honorsTargetInHTMLLinks ?? false);
106
105
  }
107
106
  } catch (e) {
108
107
  let errorMessage = "Failed to validate action.";
@@ -26,7 +26,9 @@ const sanitizationMiddleware = _ref => {
26
26
  var _action$payload;
27
27
  let text = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.text;
28
28
  if (text) {
29
- text = _dompurify.default.sanitize(text) ?? " ";
29
+ text = _dompurify.default.sanitize(text, {
30
+ ADD_ATTR: ["target"]
31
+ }) ?? " ";
30
32
  }
31
33
  } catch (e) {
32
34
  const copyDataForTelemetry = {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _utils = require("../common/utils");
8
8
  var _defaultLibraryScripts = _interopRequireDefault(require("../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts"));
9
+ var _dompurify = _interopRequireDefault(require("dompurify"));
9
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
12
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
@@ -674,7 +675,10 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
674
675
  reader.readAsDataURL(blob);
675
676
  });
676
677
  };
677
- let messages = transcriptMessages;
678
+ let messages = transcriptMessages.filter(message => {
679
+ message.content = _dompurify.default.sanitize(message.content);
680
+ return message.content.length > 0;
681
+ });
678
682
  if (renderAttachments) {
679
683
  messages = await Promise.all(transcriptMessages.map(async message => {
680
684
  // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -92,6 +92,8 @@ _defineProperty(Constants, "Zero", "zero");
92
92
  _defineProperty(Constants, "Title", "title");
93
93
  _defineProperty(Constants, "Target", "target");
94
94
  _defineProperty(Constants, "Blank", "_blank");
95
+ _defineProperty(Constants, "TargetSelf", "_self");
96
+ _defineProperty(Constants, "TargetTop", "_top");
95
97
  _defineProperty(Constants, "TargetRelationship", "rel");
96
98
  _defineProperty(Constants, "TargetRelationshipAttributes", "noopener noreferrer");
97
99
  // Markdown icons
@@ -120,6 +122,7 @@ _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
120
122
  export class HtmlClassNames {}
121
123
  _defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
122
124
  _defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
125
+ _defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
123
126
  export class HtmlElementSelectors {}
124
127
  _defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
125
128
  export class HtmlAttributeNames {}
@@ -58,32 +58,75 @@ export class FacadeChatSDK {
58
58
 
59
59
  // compare expiration time with current time
60
60
  if (now > this.expiration) {
61
- console.log("Token is expired", now, this.expiration, now > this.expiration);
61
+ console.error("Token is expired", now, this.expiration, now > this.expiration);
62
62
  return true;
63
63
  }
64
64
  return false;
65
65
  }
66
+ enforceBase64Encoding(payload) {
67
+ //base64url when present, switches the "-" and "_" characters with "+" and "/"
68
+ const base64Payload = payload.replace(/-/g, "+").replace(/_/g, "/");
69
+ // since base64 encoding requires padding, we need to add padding to the payload
70
+ return base64Payload.padEnd(base64Payload.length + (4 - base64Payload.length % 4) % 4, "=");
71
+ }
72
+ extractExpFromToken(token) {
73
+ const tokenParts = token.split(".");
74
+ const last3digits = token.slice(-3);
75
+
76
+ // token must have 3 parts as JWT format
77
+ if (tokenParts.length !== 3) {
78
+ TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
79
+ Event: TelemetryEvent.NewTokenFailed,
80
+ Description: "Invalid token format",
81
+ ExceptionDetails: {
82
+ message: "Invalid token format, must be in JWT format",
83
+ token: last3digits
84
+ }
85
+ });
86
+ throw new Error("Invalid token format, must be in JWT format");
87
+ }
88
+ try {
89
+ const payload = this.enforceBase64Encoding(tokenParts[1]);
90
+ // decode payload
91
+ const decodedPayload = atob(payload);
92
+ const jsonPayload = JSON.parse(decodedPayload);
93
+ // check if exp is present in payload
94
+ if (jsonPayload) {
95
+ if (jsonPayload.exp) {
96
+ return jsonPayload.exp;
97
+ }
98
+ return 0;
99
+ }
100
+ TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
101
+ Event: TelemetryEvent.NewTokenFailed,
102
+ Description: "Invalid token payload",
103
+ ExceptionDetails: {
104
+ message: "Token payload is not valid JSON",
105
+ token: last3digits
106
+ }
107
+ });
108
+ throw new Error("Invalid token payload, payload is not valid JSON");
109
+ } catch (e) {
110
+ console.error("Failed to decode token", e);
111
+ TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
112
+ Event: TelemetryEvent.NewTokenFailed,
113
+ Description: "Failed to decode token",
114
+ ExceptionDetails: {
115
+ message: "Failed to decode token",
116
+ token: last3digits
117
+ }
118
+ });
119
+ throw new Error("Failed to decode token");
120
+ }
121
+ }
66
122
  async setToken(token) {
67
123
  // token must be not null, and must be new
68
124
  if (!isNullOrEmptyString(token) && token !== this.token) {
69
- var _this$token;
125
+ const last3digits = token.slice(-3);
70
126
  const instant = Math.floor(Date.now() / 1000);
71
127
  this.token = token;
72
- // decompose token
73
- const tokenParts = (_this$token = this.token) === null || _this$token === void 0 ? void 0 : _this$token.split(".");
74
- if (!tokenParts || tokenParts.length <= 1) {
75
- TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
76
- Event: TelemetryEvent.NewTokenFailed,
77
- Description: "Invalid token format",
78
- ExceptionDetails: "Token must be in JWT format"
79
- });
80
- throw new Error("Invalid token format, must be in JWT format");
81
- }
82
- // decode token
83
- const tokenDecoded = JSON.parse(atob(tokenParts[1]));
84
128
  // calculate expiration time
85
- this.expiration = this.convertExpiration(tokenDecoded.exp);
86
-
129
+ this.expiration = this.convertExpiration(this.extractExpFromToken(token) || 0);
87
130
  // this is a control , in case the getAuthToken function returns same token
88
131
  if (this.expiration > 0 && this.expiration < instant) {
89
132
  TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
@@ -91,10 +134,11 @@ export class FacadeChatSDK {
91
134
  Description: "New token is already expired",
92
135
  ExceptionDetails: {
93
136
  "Instant": instant,
94
- "Expiration": this.expiration
137
+ "Expiration": this.expiration,
138
+ "Token": last3digits
95
139
  }
96
140
  });
97
- throw new Error("New token is already expired, with epoch time " + this.expiration);
141
+ throw new Error(`New token is already expired, with epoch time ${this.expiration} , last 3 digits of token: ${last3digits}`);
98
142
  }
99
143
  }
100
144
  }
@@ -158,7 +202,6 @@ export class FacadeChatSDK {
158
202
  };
159
203
  } else {
160
204
  var _ring$error, _ring$error2;
161
- console.error("Failed to get token", ring);
162
205
  TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
163
206
  Event: TelemetryEvent.NewTokenFailed,
164
207
  Description: (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
@@ -440,4 +440,14 @@ export const setOcUserAgent = chatSDK => {
440
440
  console.warn(error);
441
441
  }
442
442
  }
443
- };
443
+ };
444
+ export function getDeviceType() {
445
+ const userAgent = navigator.userAgent.toLowerCase();
446
+ if (/android/.test(userAgent)) {
447
+ return "android";
448
+ } else if (/iphone|ipad|ipod/.test(userAgent)) {
449
+ return "ios";
450
+ } else {
451
+ return "standard";
452
+ }
453
+ }
@@ -8,6 +8,8 @@ import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcon
8
8
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
9
9
  import createChatTranscript from "../../../plugins/createChatTranscript";
10
10
  import { executeReducer } from "../../../contexts/createReducer";
11
+ import { uuidv4 } from "@microsoft/omnichannel-chat-sdk";
12
+ import { ConversationState } from "../../../contexts/common/ConversationState";
11
13
  const processDisplayName = displayName => {
12
14
  // if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
13
15
  const displayNameRegex = ".+:.+";
@@ -161,11 +163,24 @@ export const downloadTranscript = async (facadeChatSDK, downloadTranscriptProps,
161
163
  // Need to keep existing live chat context for scenarios when transcript is downloaded after endchat
162
164
  let liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.liveChatContext;
163
165
  if (!liveChatContext) {
166
+ var _inMemoryState$appSta;
164
167
  const inMemoryState = executeReducer(state, {
165
168
  type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
166
169
  payload: null
167
170
  });
168
171
  liveChatContext = inMemoryState.domainStates.liveChatContext;
172
+ if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.conversationState) !== ConversationState.Active && !liveChatContext) {
173
+ var _state$domainStates2;
174
+ const chatToken = (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.chatToken) || inMemoryState.domainStates.chatToken;
175
+ if (chatToken && Object.keys(chatToken).length > 0) {
176
+ liveChatContext = {
177
+ chatToken: chatToken,
178
+ requestId: chatToken.requestId || uuidv4()
179
+ };
180
+ } else {
181
+ liveChatContext = await (facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.getCurrentLiveChatContext());
182
+ }
183
+ }
169
184
  }
170
185
  let data = await (facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.getLiveChatTranscript({
171
186
  liveChatContext
@@ -5,7 +5,7 @@ import { defaultMarkdownLocalizedTexts } from "../../webchatcontainerstateful/co
5
5
  import { addSlackMarkdownIt } from "./helpers/markdownHelper";
6
6
 
7
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
8
+ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab) => {
9
9
  let markdown;
10
10
  if (!disableMarkdownMessageFormatting) {
11
11
  markdown = new MarkdownIt(Constants.Default, {
@@ -39,10 +39,11 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
39
39
  const targetAttrIndex = tokens[idx].attrIndex(Constants.Target);
40
40
  // Put a transparent pixel instead of the "open in new window" icon, so developers can easily modify the icon in CSS.
41
41
  const TRANSPARENT_GIF = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
42
+ const targetValue = opensMarkdownLinksInSameTab ? Constants.TargetTop : Constants.Blank;
42
43
  if (~targetAttrIndex) {
43
- tokens[idx].attrs[targetAttrIndex][1] = Constants.Blank;
44
+ tokens[idx].attrs[targetAttrIndex][1] = targetValue;
44
45
  } else {
45
- tokens[idx].attrPush([Constants.Target, Constants.Blank]);
46
+ tokens[idx].attrPush([Constants.Target, targetValue]);
46
47
  }
47
48
  const relAttrIndex = tokens[idx].attrIndex(Constants.TargetRelationship);
48
49
  if (~relAttrIndex) {
@@ -31,10 +31,11 @@ import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroll
31
31
  import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
32
32
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
33
33
  import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
34
+ import { Constants } from "../../../common/Constants";
34
35
 
35
36
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
37
  export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
37
- var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain13, _props$webChatContain14, _defaultWebChatContai, _props$webChatContain15, _props$webChatContain16, _props$webChatContain17, _props$webChatContain18, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai2, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai3, _props$webChatContain23, _props$webChatContain24;
38
+ var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _props$webChatContain19, _props$webChatContain20, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai2, _props$webChatContain23, _props$webChatContain24, _defaultWebChatContai3, _props$webChatContain25, _props$webChatContain26;
38
39
  // Add a hook to make all links open a new window
39
40
  postDomPurifyActivities();
40
41
  const localizedTexts = {
@@ -44,12 +45,14 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
44
45
  const hyperlinkTextOverride = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hyperlinkTextOverride) ?? defaultWebChatContainerStatefulProps.hyperlinkTextOverride;
45
46
  const disableNewLineMarkdownSupport = ((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.disableNewLineMarkdownSupport) ?? defaultWebChatContainerStatefulProps.disableNewLineMarkdownSupport;
46
47
  const disableMarkdownMessageFormatting = ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.disableMarkdownMessageFormatting) ?? defaultWebChatContainerStatefulProps.disableMarkdownMessageFormatting;
48
+ const opensMarkdownLinksInSameTab = (_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.opensMarkdownLinksInSameTab;
49
+ const honorsTargetInHTMLLinks = (_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.honorsTargetInHTMLLinks;
47
50
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
48
- const markdown = createMarkdown(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
51
+ const markdown = createMarkdown(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab);
49
52
  // Initialize Web Chat's redux store
50
53
  let webChatStore = WebChatStoreLoader.store;
51
54
  if (!webChatStore) {
52
- var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain5;
55
+ var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
53
56
  const conversationEndCallback = async () => {
54
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
58
  const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
@@ -81,18 +84,18 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
81
84
  };
82
85
  webChatStore = createStore({},
83
86
  //initial state
84
- preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
87
+ preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
85
88
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
- ...(((_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.storeMiddlewares) ?? []));
89
+ ...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
87
90
  WebChatStoreLoader.store = webChatStore;
88
91
  }
89
92
  const hyperlinkTextOverrideRenderer = new HyperlinkTextOverrideRenderer(hyperlinkTextOverride);
90
93
  const markdownRenderers = [hyperlinkTextOverrideRenderer];
91
94
  const renderMarkdown = text => {
92
- var _props$webChatContain6, _props$webChatContain7;
93
- if ((_props$webChatContain6 = props.webChatContainerProps) !== null && _props$webChatContain6 !== void 0 && (_props$webChatContain7 = _props$webChatContain6.webChatProps) !== null && _props$webChatContain7 !== void 0 && _props$webChatContain7.renderMarkdown) {
94
- var _props$webChatContain8;
95
- text = (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.webChatProps.renderMarkdown(text);
95
+ var _props$webChatContain8, _props$webChatContain9;
96
+ if ((_props$webChatContain8 = props.webChatContainerProps) !== null && _props$webChatContain8 !== void 0 && (_props$webChatContain9 = _props$webChatContain8.webChatProps) !== null && _props$webChatContain9 !== void 0 && _props$webChatContain9.renderMarkdown) {
97
+ var _props$webChatContain10;
98
+ text = (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatProps.renderMarkdown(text);
96
99
  } else {
97
100
  const render = disableMarkdownMessageFormatting ? markdown.renderInline.bind(markdown) : markdown.render.bind(markdown);
98
101
  text = render(text);
@@ -102,16 +105,19 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
102
105
  });
103
106
  const config = {
104
107
  FORBID_TAGS: ["form", "button", "script", "div", "input"],
105
- FORBID_ATTR: ["action"]
108
+ FORBID_ATTR: ["action"],
109
+ ADD_ATTR: ["target"]
106
110
  };
107
111
  text = DOMPurify.sanitize(text, config);
108
112
  return text;
109
113
  };
110
114
  function postDomPurifyActivities() {
111
115
  DOMPurify.addHook("afterSanitizeAttributes", function (node) {
112
- // set all elements owning target to target=_blank
113
- if ("target" in node) {
114
- node.setAttribute("target", "_blank");
116
+ const target = node.getAttribute(Constants.Target);
117
+ if (target === Constants.TargetSelf) {
118
+ node.setAttribute(Constants.Target, Constants.TargetTop);
119
+ } else if (!target) {
120
+ node.setAttribute(Constants.Target, Constants.Blank);
115
121
  }
116
122
  });
117
123
  }
@@ -121,18 +127,18 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
121
127
  dir: state.domainStates.globalDir,
122
128
  locale: changeLanguageCodeFormatForWebChat(getLocaleStringFromId((_state$domainStates$l4 = state.domainStates.liveChatConfig) === null || _state$domainStates$l4 === void 0 ? void 0 : (_state$domainStates$l5 = _state$domainStates$l4.ChatWidgetLanguage) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.msdyn_localeid)),
123
129
  store: webChatStore,
124
- activityMiddleware: (_props$webChatContain9 = props.webChatContainerProps) !== null && _props$webChatContain9 !== void 0 && (_props$webChatContain10 = _props$webChatContain9.renderingMiddlewareProps) !== null && _props$webChatContain10 !== void 0 && _props$webChatContain10.disableActivityMiddleware ? undefined : createActivityMiddleware(renderMarkdown, (_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
125
- attachmentMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableAttachmentMiddleware ? undefined : createAttachmentMiddleware(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? defaultAttachmentProps.enableInlinePlaying),
126
- activityStatusMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableActivityStatusMiddleware ? undefined : (_defaultWebChatContai = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
127
- toastMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableToastMiddleware ? undefined : createToastMiddleware(props.notificationPaneProps, endChat),
130
+ activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : createActivityMiddleware(renderMarkdown, (_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
131
+ attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : createAttachmentMiddleware(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? defaultAttachmentProps.enableInlinePlaying),
132
+ activityStatusMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableActivityStatusMiddleware ? undefined : (_defaultWebChatContai = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
133
+ toastMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableToastMiddleware ? undefined : createToastMiddleware(props.notificationPaneProps, endChat),
128
134
  renderMarkdown,
129
- avatarMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableAvatarMiddleware ? undefined : createAvatarMiddleware((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
130
- groupActivitiesMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
131
- typingIndicatorMiddleware: (_props$webChatContain21 = props.webChatContainerProps) !== null && _props$webChatContain21 !== void 0 && (_props$webChatContain22 = _props$webChatContain21.renderingMiddlewareProps) !== null && _props$webChatContain22 !== void 0 && _props$webChatContain22.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
135
+ avatarMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableAvatarMiddleware ? undefined : createAvatarMiddleware((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
136
+ groupActivitiesMiddleware: (_props$webChatContain21 = props.webChatContainerProps) !== null && _props$webChatContain21 !== void 0 && (_props$webChatContain22 = _props$webChatContain21.renderingMiddlewareProps) !== null && _props$webChatContain22 !== void 0 && _props$webChatContain22.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
137
+ typingIndicatorMiddleware: (_props$webChatContain23 = props.webChatContainerProps) !== null && _props$webChatContain23 !== void 0 && (_props$webChatContain24 = _props$webChatContain23.renderingMiddlewareProps) !== null && _props$webChatContain24 !== void 0 && _props$webChatContain24.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
132
138
  onTelemetry: createWebChatTelemetry(),
133
- cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain23 = props.webChatContainerProps) === null || _props$webChatContain23 === void 0 ? void 0 : _props$webChatContain23.botMagicCode) || undefined),
139
+ cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain25 = props.webChatContainerProps) === null || _props$webChatContain25 === void 0 ? void 0 : _props$webChatContain25.botMagicCode) || undefined),
134
140
  sendTypingIndicator: true,
135
- ...((_props$webChatContain24 = props.webChatContainerProps) === null || _props$webChatContain24 === void 0 ? void 0 : _props$webChatContain24.webChatProps)
141
+ ...((_props$webChatContain26 = props.webChatContainerProps) === null || _props$webChatContain26 === void 0 ? void 0 : _props$webChatContain26.webChatProps)
136
142
  };
137
143
  return webChatProps;
138
144
  };
@@ -56,7 +56,7 @@ import useChatContextStore from "../../../hooks/useChatContextStore";
56
56
  import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
57
57
  let uiTimer;
58
58
  export const LiveChatWidgetStateful = props => {
59
- var _props$webChatContain, _props$styleProps, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain5, _state$appStates14, _props$webChatContain7, _props$webChatContain8, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain9, _props$webChatContain10, _props$webChatContain11, _props$webChatContain12, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
59
+ var _props$webChatContain, _props$styleProps, _props$webChatContain2, _props$webChatContain3, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain7, _state$appStates14, _props$webChatContain9, _props$webChatContain10, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain11, _props$webChatContain12, _props$webChatContain13, _props$webChatContain14, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
60
60
  useEffect(() => {
61
61
  uiTimer = createTimer();
62
62
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -86,6 +86,7 @@ export const LiveChatWidgetStateful = props => {
86
86
 
87
87
  //Scrollbar styles
88
88
  const scrollbarProps = Object.assign({}, defaultScrollBarProps, props === null || props === void 0 ? void 0 : props.scrollBarProps);
89
+ const sendBoxTextArea = props === null || props === void 0 ? void 0 : (_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.sendBoxTextBox) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.textarea;
89
90
 
90
91
  // In case the broadcast channel is already initialized elsewhere; One tab can only hold 1 instance
91
92
  if ((props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.skipBroadcastChannelInit) !== true) {
@@ -605,8 +606,8 @@ export const LiveChatWidgetStateful = props => {
605
606
  });
606
607
  }
607
608
  if (state.appStates.conversationState === ConversationState.InActive) {
608
- var _props$webChatContain2, _props$webChatContain3;
609
- if ((props === null || props === void 0 ? void 0 : (_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.renderingMiddlewareProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.hideSendboxOnConversationEnd) !== false) {
609
+ var _props$webChatContain4, _props$webChatContain5;
610
+ if ((props === null || props === void 0 ? void 0 : (_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : (_props$webChatContain5 = _props$webChatContain4.renderingMiddlewareProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.hideSendboxOnConversationEnd) !== false) {
610
611
  setWebChatStyles(styles => {
611
612
  return {
612
613
  ...styles,
@@ -650,12 +651,12 @@ export const LiveChatWidgetStateful = props => {
650
651
  }
651
652
  }, [state.appStates.unreadMessageCount]);
652
653
  useEffect(() => {
653
- var _props$webChatContain4;
654
+ var _props$webChatContain6;
654
655
  setWebChatStyles({
655
656
  ...webChatStyles,
656
- ...((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.webChatStyles)
657
+ ...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
657
658
  });
658
- }, [(_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.webChatStyles]);
659
+ }, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.webChatStyles]);
659
660
  useEffect(() => {
660
661
  //Confirmation pane dismissing through OK option, so proceed with end chat
661
662
  if (state.domainStates.confirmationState === ConfirmationState.Ok) {
@@ -754,12 +755,12 @@ export const LiveChatWidgetStateful = props => {
754
755
 
755
756
  // if props state gets updates we need to update the renderingMiddlewareProps in the state
756
757
  useEffect(() => {
757
- var _props$webChatContain6;
758
+ var _props$webChatContain8;
758
759
  dispatch({
759
760
  type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
760
- payload: (_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.renderingMiddlewareProps
761
+ payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
761
762
  });
762
- }, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.renderingMiddlewareProps]);
763
+ }, [(_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.renderingMiddlewareProps]);
763
764
  useEffect(() => {
764
765
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
765
766
  Event: TelemetryEvent.UXLivechatwidgetCompleted,
@@ -801,7 +802,7 @@ export const LiveChatWidgetStateful = props => {
801
802
  const webChatProps = initWebChatComposer(props, state, dispatch, facadeChatSDK, endChatRelay);
802
803
  const downloadTranscriptProps = createDownloadTranscriptProps(props.downloadTranscriptProps, {
803
804
  ...(defaultWebChatContainerStatefulProps === null || defaultWebChatContainerStatefulProps === void 0 ? void 0 : defaultWebChatContainerStatefulProps.webChatStyles),
804
- ...((_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.webChatStyles)
805
+ ...((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatStyles)
805
806
  }, props.webChatContainerProps);
806
807
  const livechatProps = {
807
808
  ...props,
@@ -859,13 +860,16 @@ export const LiveChatWidgetStateful = props => {
859
860
  height: .75em;
860
861
  margin-left: .25em;
861
862
  }
862
- }
863
+ ${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
864
+ textarea.webchat__send-box-text-box__html-text-area {
865
+ min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight};
866
+ }`}
863
867
  `), /*#__PURE__*/React.createElement(DraggableChatWidget, chatWidgetDraggableConfig, /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
864
868
  userID: userID,
865
869
  styleOptions: {
866
870
  ...webChatStyles,
867
- bubbleBackground: ((_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : (_props$webChatContain10 = _props$webChatContain9.adaptiveCardStyles) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.background) ?? defaultAdaptiveCardStyles.background,
868
- bubbleTextColor: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.adaptiveCardStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.color) ?? defaultAdaptiveCardStyles.color
871
+ bubbleBackground: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.adaptiveCardStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.background) ?? defaultAdaptiveCardStyles.background,
872
+ bubbleTextColor: ((_props$webChatContain13 = props.webChatContainerProps) === null || _props$webChatContain13 === void 0 ? void 0 : (_props$webChatContain14 = _props$webChatContain13.adaptiveCardStyles) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.color) ?? defaultAdaptiveCardStyles.color
869
873
  },
870
874
  directLine: directLine
871
875
  }), /*#__PURE__*/React.createElement(Stack, {
@@ -136,11 +136,6 @@ export const PreChatSurveyPaneStateful = props => {
136
136
  }
137
137
  }
138
138
  }
139
- // Move focus to the first button
140
- const firstElement = findAllFocusableElement(`#${controlProps.id}`);
141
- if (firstElement && firstElement[0]) {
142
- firstElement[0].focus();
143
- }
144
139
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
145
140
  Event: TelemetryEvent.PrechatSurveyLoaded
146
141
  });
@@ -149,6 +144,16 @@ export const PreChatSurveyPaneStateful = props => {
149
144
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
150
145
  });
151
146
  }, []);
147
+
148
+ // Set focus to the first element
149
+ useEffect(() => {
150
+ if (!state.appStates.isMinimized) {
151
+ const firstElement = findAllFocusableElement(`#${controlProps.id}`);
152
+ if (firstElement && firstElement[0]) {
153
+ firstElement[0].focus();
154
+ }
155
+ }
156
+ }, [state.appStates.isMinimized]);
152
157
  return /*#__PURE__*/React.createElement(PreChatSurveyPane, {
153
158
  controlProps: controlProps,
154
159
  styleProps: styleProps
@@ -3,10 +3,10 @@
3
3
  import { Stack } from "@fluentui/react";
4
4
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
5
5
  import React, { useEffect } from "react";
6
- import { createTimer, setFocusOnSendBox } from "../../common/utils";
6
+ import { createTimer, getDeviceType, setFocusOnSendBox } from "../../common/utils";
7
7
  import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
8
8
  import { Components } from "botframework-webchat";
9
- import { Constants } from "../../common/Constants";
9
+ import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
10
10
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
11
11
  import { NotificationHandler } from "./webchatcontroller/notification/NotificationHandler";
12
12
  import { NotificationScenarios } from "./webchatcontroller/enums/NotificationScenarios";
@@ -75,7 +75,12 @@ export const WebChatContainerStateful = props => {
75
75
  };
76
76
  useEffect(() => {
77
77
  var _props$webChatContain, _props$webChatContain2;
78
- setFocusOnSendBox();
78
+ if (getDeviceType() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
79
+ const chatHistoryElement = document.querySelector(`.${HtmlClassNames.webChatHistoryContainer}`);
80
+ if (chatHistoryElement) {
81
+ chatHistoryElement.setAttribute(HtmlAttributeNames.ariaLabel, webChatContainerProps.webChatHistoryMobileAccessibilityLabel);
82
+ }
83
+ }
79
84
  dispatch({
80
85
  type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
81
86
  payload: webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.renderingMiddlewareProps
@@ -156,6 +161,13 @@ export const WebChatContainerStateful = props => {
156
161
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
157
162
  });
158
163
  }, []);
164
+
165
+ // Set focus to the sendbox
166
+ useEffect(() => {
167
+ if (!state.appStates.isMinimized) {
168
+ setFocusOnSendBox();
169
+ }
170
+ }, [state.appStates.isMinimized]);
159
171
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
160
172
  .webchat__stacked-layout__content .ac-pushButton {
161
173
  cursor: pointer;
@@ -9,6 +9,8 @@ export const defaultWebChatContainerStatefulProps = {
9
9
  containerStyles: defaultWebChatStatefulContainerStyles,
10
10
  disableNewLineMarkdownSupport: false,
11
11
  disableMarkdownMessageFormatting: false,
12
+ opensMarkdownLinksInSameTab: false,
13
+ honorsTargetInHTMLLinks: false,
12
14
  hyperlinkTextOverride: false,
13
15
  directLine: new MockAdapter(),
14
16
  adaptiveCardStyles: defaultAdaptiveCardStyles
@@ -54,5 +54,5 @@ export const defaultWebChatStyles = {
54
54
  "</3": "💔",
55
55
  "<\\3": "💔"
56
56
  },
57
- uploadMultiple: false
57
+ sendAttachmentOn: "attach"
58
58
  };