@microsoft/omnichannel-chat-widget 1.7.6-main.dca3f60 → 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.
- package/lib/cjs/common/Constants.js +3 -0
- package/lib/cjs/common/facades/FacadeChatSDK.js +76 -21
- package/lib/cjs/common/utils.js +14 -2
- package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
- package/lib/cjs/components/livechatwidget/LiveChatWidget.js +3 -2
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +4 -3
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +27 -22
- package/lib/cjs/components/livechatwidget/interfaces/IFeatureConfigProps.js +1 -0
- package/lib/cjs/components/livechatwidget/interfaces/ISendBox.js +1 -0
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +19 -13
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/cjs/plugins/createChatTranscript.js +5 -1
- package/lib/esm/common/Constants.js +3 -0
- package/lib/esm/common/facades/FacadeChatSDK.js +76 -21
- package/lib/esm/common/utils.js +11 -1
- package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
- package/lib/esm/components/livechatwidget/LiveChatWidget.js +3 -2
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +4 -3
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +28 -22
- package/lib/esm/components/livechatwidget/interfaces/IFeatureConfigProps.js +1 -0
- package/lib/esm/components/livechatwidget/interfaces/ISendBox.js +1 -0
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +19 -13
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/esm/plugins/createChatTranscript.js +5 -1
- package/lib/types/common/Constants.d.ts +3 -0
- package/lib/types/common/facades/FacadeChatSDK.d.ts +5 -2
- package/lib/types/common/utils.d.ts +1 -0
- package/lib/types/components/livechatwidget/common/createMarkdown.d.ts +1 -1
- package/lib/types/components/livechatwidget/interfaces/IFeatureConfigProps.d.ts +3 -0
- package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +9 -7
- package/lib/types/components/livechatwidget/interfaces/ISendBox.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +5 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.d.ts +1 -1
- package/package.json +2 -2
|
@@ -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$
|
|
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) {
|
|
@@ -580,6 +581,8 @@ export const LiveChatWidgetStateful = props => {
|
|
|
580
581
|
BroadcastService.postMessage({
|
|
581
582
|
eventName: BroadcastEvent.NewMessageNotification
|
|
582
583
|
});
|
|
584
|
+
}, {
|
|
585
|
+
disablePolling: true
|
|
583
586
|
});
|
|
584
587
|
facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.onAgentEndSession(event => {
|
|
585
588
|
var _inMemoryState$appSta6;
|
|
@@ -603,8 +606,8 @@ export const LiveChatWidgetStateful = props => {
|
|
|
603
606
|
});
|
|
604
607
|
}
|
|
605
608
|
if (state.appStates.conversationState === ConversationState.InActive) {
|
|
606
|
-
var _props$
|
|
607
|
-
if ((props === null || props === void 0 ? void 0 : (_props$
|
|
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) {
|
|
608
611
|
setWebChatStyles(styles => {
|
|
609
612
|
return {
|
|
610
613
|
...styles,
|
|
@@ -648,12 +651,12 @@ export const LiveChatWidgetStateful = props => {
|
|
|
648
651
|
}
|
|
649
652
|
}, [state.appStates.unreadMessageCount]);
|
|
650
653
|
useEffect(() => {
|
|
651
|
-
var _props$
|
|
654
|
+
var _props$webChatContain6;
|
|
652
655
|
setWebChatStyles({
|
|
653
656
|
...webChatStyles,
|
|
654
|
-
...((_props$
|
|
657
|
+
...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
|
|
655
658
|
});
|
|
656
|
-
}, [(_props$
|
|
659
|
+
}, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.webChatStyles]);
|
|
657
660
|
useEffect(() => {
|
|
658
661
|
//Confirmation pane dismissing through OK option, so proceed with end chat
|
|
659
662
|
if (state.domainStates.confirmationState === ConfirmationState.Ok) {
|
|
@@ -752,12 +755,12 @@ export const LiveChatWidgetStateful = props => {
|
|
|
752
755
|
|
|
753
756
|
// if props state gets updates we need to update the renderingMiddlewareProps in the state
|
|
754
757
|
useEffect(() => {
|
|
755
|
-
var _props$
|
|
758
|
+
var _props$webChatContain8;
|
|
756
759
|
dispatch({
|
|
757
760
|
type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
758
|
-
payload: (_props$
|
|
761
|
+
payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
|
|
759
762
|
});
|
|
760
|
-
}, [(_props$
|
|
763
|
+
}, [(_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.renderingMiddlewareProps]);
|
|
761
764
|
useEffect(() => {
|
|
762
765
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
763
766
|
Event: TelemetryEvent.UXLivechatwidgetCompleted,
|
|
@@ -799,7 +802,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
799
802
|
const webChatProps = initWebChatComposer(props, state, dispatch, facadeChatSDK, endChatRelay);
|
|
800
803
|
const downloadTranscriptProps = createDownloadTranscriptProps(props.downloadTranscriptProps, {
|
|
801
804
|
...(defaultWebChatContainerStatefulProps === null || defaultWebChatContainerStatefulProps === void 0 ? void 0 : defaultWebChatContainerStatefulProps.webChatStyles),
|
|
802
|
-
...((_props$
|
|
805
|
+
...((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatStyles)
|
|
803
806
|
}, props.webChatContainerProps);
|
|
804
807
|
const livechatProps = {
|
|
805
808
|
...props,
|
|
@@ -857,13 +860,16 @@ export const LiveChatWidgetStateful = props => {
|
|
|
857
860
|
height: .75em;
|
|
858
861
|
margin-left: .25em;
|
|
859
862
|
}
|
|
860
|
-
|
|
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
|
+
}`}
|
|
861
867
|
`), /*#__PURE__*/React.createElement(DraggableChatWidget, chatWidgetDraggableConfig, /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
|
|
862
868
|
userID: userID,
|
|
863
869
|
styleOptions: {
|
|
864
870
|
...webChatStyles,
|
|
865
|
-
bubbleBackground: ((_props$
|
|
866
|
-
bubbleTextColor: ((_props$
|
|
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
|
|
867
873
|
},
|
|
868
874
|
directLine: directLine
|
|
869
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
|
-
|
|
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
|
|
@@ -11,7 +11,9 @@ class HyperlinkTextOverrideRenderer {
|
|
|
11
11
|
convertTextToHtmlNode(text) {
|
|
12
12
|
const htmlNode = document.createElement(HtmlAttributeNames.div);
|
|
13
13
|
try {
|
|
14
|
-
text = DOMPurify.sanitize(text
|
|
14
|
+
text = DOMPurify.sanitize(text, {
|
|
15
|
+
ADD_ATTR: ["target"]
|
|
16
|
+
});
|
|
15
17
|
htmlNode.innerHTML = text;
|
|
16
18
|
} catch {
|
|
17
19
|
return htmlNode;
|
|
@@ -25,14 +25,27 @@ export const DeliveredTimestamp = _ref => {
|
|
|
25
25
|
timestamp
|
|
26
26
|
}
|
|
27
27
|
} = args;
|
|
28
|
+
const getTimeElement = timestamp => {
|
|
29
|
+
const timeString = getTimestampHourMinute(timestamp);
|
|
30
|
+
const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
|
|
31
|
+
|
|
32
|
+
// For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
|
|
33
|
+
// make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
|
|
34
|
+
if (dir === "rtl" && isAmPmFormat) {
|
|
35
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
36
|
+
dir: "ltr"
|
|
37
|
+
}, getTimestampHourMinute(timestamp));
|
|
38
|
+
}
|
|
39
|
+
return timeString;
|
|
40
|
+
};
|
|
28
41
|
return /*#__PURE__*/React.createElement(Stack, {
|
|
29
42
|
style: contentStyles,
|
|
30
43
|
dir: dir
|
|
31
44
|
}, role === DirectLineSenderRole.Bot && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
32
45
|
dir: dir,
|
|
33
46
|
"aria-hidden": "false"
|
|
34
|
-
}, name, " - ",
|
|
47
|
+
}, name, " - ", getTimeElement(timestamp))), role === DirectLineSenderRole.User && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
35
48
|
"aria-hidden": "false",
|
|
36
49
|
dir: dir
|
|
37
|
-
}, " ",
|
|
50
|
+
}, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
|
|
38
51
|
};
|
|
@@ -16,8 +16,9 @@ const convertTextToHtmlNode = text => {
|
|
|
16
16
|
if (!text) return "";
|
|
17
17
|
const element = document.createElement(HtmlAttributeNames.div);
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
text = DOMPurify.sanitize(text, {
|
|
20
|
+
ADD_ATTR: ["target"]
|
|
21
|
+
});
|
|
21
22
|
element.innerHTML = text;
|
|
22
23
|
} catch (e) {
|
|
23
24
|
const errorMessage = `Failed to purify and set innertHTML with text: ${text}`;
|
|
@@ -33,7 +34,7 @@ const convertTextToHtmlNode = text => {
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
-
const processHTMLText = (action, text) => {
|
|
37
|
+
const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
37
38
|
const htmlNode = convertTextToHtmlNode(text);
|
|
38
39
|
const aNodes = htmlNode.getElementsByTagName(HtmlAttributeNames.aTagName);
|
|
39
40
|
if ((aNodes === null || aNodes === void 0 ? void 0 : aNodes.length) > 0) {
|
|
@@ -46,8 +47,8 @@ const processHTMLText = (action, text) => {
|
|
|
46
47
|
continue;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
// Add target to 'a' node if target is missing or
|
|
50
|
-
if (!aNode.target ||
|
|
50
|
+
// Add target to 'a' node if target is missing or if honorsTargetInHTMLLinks is false
|
|
51
|
+
if (!aNode.target || !honorsTargetInHTMLLinks) {
|
|
51
52
|
aNode.target = Constants.blank;
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -63,9 +64,6 @@ const processHTMLText = (action, text) => {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
-
action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => htmlNode.innerHTML);
|
|
69
67
|
} catch (e) {
|
|
70
68
|
let errorMessage = "Failed to apply action: ";
|
|
71
69
|
try {
|
|
@@ -82,11 +80,12 @@ const processHTMLText = (action, text) => {
|
|
|
82
80
|
});
|
|
83
81
|
}
|
|
84
82
|
}
|
|
83
|
+
action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => htmlNode.innerHTML);
|
|
85
84
|
return action;
|
|
86
85
|
};
|
|
87
86
|
|
|
88
87
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
|
89
|
-
const htmlTextMiddleware = _ref => {
|
|
88
|
+
const htmlTextMiddleware = honorsTargetInHTMLLinks => _ref => {
|
|
90
89
|
let {
|
|
91
90
|
dispatch
|
|
92
91
|
} = _ref;
|
|
@@ -96,7 +95,7 @@ const htmlTextMiddleware = _ref => {
|
|
|
96
95
|
var _action$payload, _action$payload$activ;
|
|
97
96
|
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;
|
|
98
97
|
if (text) {
|
|
99
|
-
action = processHTMLText(action, text);
|
|
98
|
+
action = processHTMLText(action, text, honorsTargetInHTMLLinks ?? false);
|
|
100
99
|
}
|
|
101
100
|
} catch (e) {
|
|
102
101
|
let errorMessage = "Failed to validate action.";
|
|
@@ -20,7 +20,9 @@ const sanitizationMiddleware = _ref => {
|
|
|
20
20
|
var _action$payload;
|
|
21
21
|
let text = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.text;
|
|
22
22
|
if (text) {
|
|
23
|
-
text = DOMPurify.sanitize(text
|
|
23
|
+
text = DOMPurify.sanitize(text, {
|
|
24
|
+
ADD_ATTR: ["target"]
|
|
25
|
+
}) ?? " ";
|
|
24
26
|
}
|
|
25
27
|
} catch (e) {
|
|
26
28
|
const copyDataForTelemetry = {
|
|
@@ -5,6 +5,7 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
|
|
|
5
5
|
|
|
6
6
|
import { createFileAndDownload } from "../common/utils";
|
|
7
7
|
import defaultLibraryScripts from "../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts";
|
|
8
|
+
import DOMPurify from "dompurify";
|
|
8
9
|
class TranscriptHTMLBuilder {
|
|
9
10
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
10
11
|
|
|
@@ -669,7 +670,10 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
|
|
|
669
670
|
reader.readAsDataURL(blob);
|
|
670
671
|
});
|
|
671
672
|
};
|
|
672
|
-
let messages = transcriptMessages
|
|
673
|
+
let messages = transcriptMessages.filter(message => {
|
|
674
|
+
message.content = DOMPurify.sanitize(message.content);
|
|
675
|
+
return message.content.length > 0;
|
|
676
|
+
});
|
|
673
677
|
if (renderAttachments) {
|
|
674
678
|
messages = await Promise.all(transcriptMessages.map(async message => {
|
|
675
679
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -74,6 +74,8 @@ export declare class Constants {
|
|
|
74
74
|
static readonly Title = "title";
|
|
75
75
|
static readonly Target = "target";
|
|
76
76
|
static readonly Blank = "_blank";
|
|
77
|
+
static readonly TargetSelf = "_self";
|
|
78
|
+
static readonly TargetTop = "_top";
|
|
77
79
|
static readonly TargetRelationship = "rel";
|
|
78
80
|
static readonly TargetRelationshipAttributes = "noopener noreferrer";
|
|
79
81
|
static readonly OpenLinkIconCssClass = "webchat__render-markdown__external-link-icon";
|
|
@@ -102,6 +104,7 @@ export declare class HtmlIdNames {
|
|
|
102
104
|
export declare class HtmlClassNames {
|
|
103
105
|
static readonly webChatBannerCloseButton = "webchat__toast__dismissButton";
|
|
104
106
|
static readonly webChatBannerExpandButton = "webchat__toaster__expandIcon";
|
|
107
|
+
static readonly webChatHistoryContainer = "webchat__basic-transcript";
|
|
105
108
|
}
|
|
106
109
|
export declare class HtmlElementSelectors {
|
|
107
110
|
static readonly sendBoxSelector = "textarea[data-id=\"webchat-sendbox-input\"]";
|
|
@@ -32,13 +32,16 @@ export declare class FacadeChatSDK {
|
|
|
32
32
|
private isAuthenticated;
|
|
33
33
|
private getAuthToken?;
|
|
34
34
|
private sdkMocked;
|
|
35
|
+
private disableReauthentication;
|
|
35
36
|
isSDKMocked(): boolean;
|
|
36
37
|
getChatSDK(): OmnichannelChatSDK;
|
|
37
38
|
destroy(): void;
|
|
38
39
|
isTokenSet(): boolean;
|
|
39
|
-
constructor(input: IFacadeChatSDKInput);
|
|
40
|
+
constructor(input: IFacadeChatSDKInput, disableReauthentication: boolean);
|
|
40
41
|
private convertExpiration;
|
|
41
42
|
private isTokenExpired;
|
|
43
|
+
private enforceBase64Encoding;
|
|
44
|
+
private extractExpFromToken;
|
|
42
45
|
private setToken;
|
|
43
46
|
private tokenRing;
|
|
44
47
|
private validateAndExecuteCall;
|
|
@@ -55,7 +58,7 @@ export declare class FacadeChatSDK {
|
|
|
55
58
|
getMessages(): Promise<IMessage[] | OmnichannelMessage[] | undefined>;
|
|
56
59
|
getDataMaskingRules(): Promise<MaskingRules>;
|
|
57
60
|
sendMessage(message: ChatSDKMessage): Promise<void>;
|
|
58
|
-
onNewMessage(onNewMessageCallback: CallableFunction, optionalParams?: OnNewMessageOptionalParams
|
|
61
|
+
onNewMessage(onNewMessageCallback: CallableFunction, optionalParams?: OnNewMessageOptionalParams): Promise<void>;
|
|
59
62
|
sendTypingEvent(): Promise<void>;
|
|
60
63
|
onTypingEvent(onTypingEventCallback: CallableFunction): Promise<void>;
|
|
61
64
|
onAgentEndSession(onAgentEndSessionCallback: (message: IRawThread | ParticipantsRemovedEvent) => void): Promise<void>;
|
|
@@ -46,3 +46,4 @@ export declare const createFileAndDownload: (fileName: string, blobData: string,
|
|
|
46
46
|
export declare const formatTemplateString: (templateMessage: string, values: any) => string;
|
|
47
47
|
export declare const parseLowerCaseString: (property: string | boolean | undefined) => string;
|
|
48
48
|
export declare const setOcUserAgent: (chatSDK: any) => void;
|
|
49
|
+
export declare function getDeviceType(): string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import MarkdownIt from "markdown-it";
|
|
2
|
-
export declare const createMarkdown: (disableMarkdownMessageFormatting: boolean, disableNewLineMarkdownSupport: boolean) => MarkdownIt;
|
|
2
|
+
export declare const createMarkdown: (disableMarkdownMessageFormatting: boolean, disableNewLineMarkdownSupport: boolean, opensMarkdownLinksInSameTab?: boolean) => MarkdownIt;
|
|
@@ -3,29 +3,30 @@ import { IAudioNotificationProps } from "../../footerstateful/audionotifications
|
|
|
3
3
|
import { ICallingContainerProps } from "@microsoft/omnichannel-chat-components/lib/types/components/callingcontainer/interfaces/ICallingContainerProps";
|
|
4
4
|
import { IChatButtonProps } from "@microsoft/omnichannel-chat-components/lib/types/components/chatbutton/interfaces/IChatButtonProps";
|
|
5
5
|
import { IConfirmationPaneStatefulProps } from "../../confirmationpanestateful/interfaces/IConfirmationPaneStatefulProps";
|
|
6
|
+
import { IContextDataStore } from "../../../common/interfaces/IContextDataStore";
|
|
6
7
|
import { IDownloadTranscriptProps } from "../../footerstateful/downloadtranscriptstateful/interfaces/IDownloadTranscriptProps";
|
|
8
|
+
import { IDraggableChatWidgetProps } from "./IDraggableChatWidgetProps";
|
|
7
9
|
import { IEmailTranscriptPaneProps } from "../../emailtranscriptpanestateful/interfaces/IEmailTranscriptPaneProps";
|
|
10
|
+
import { IFeatureConfigProps } from "./IFeatureConfigProps";
|
|
8
11
|
import { IFooterProps } from "@microsoft/omnichannel-chat-components/lib/types/components/footer/interfaces/IFooterProps";
|
|
9
12
|
import { IHeaderProps } from "@microsoft/omnichannel-chat-components/lib/types/components/header/interfaces/IHeaderProps";
|
|
10
13
|
import { ILiveChatWidgetComponentOverrides } from "./ILiveChatWidgetComponentOverrides";
|
|
14
|
+
import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidgetContext";
|
|
11
15
|
import { ILiveChatWidgetControlProps } from "./ILiveChatWidgetControlProps";
|
|
12
16
|
import { ILiveChatWidgetStyleProps } from "./ILiveChatWidgetStyleProps";
|
|
13
17
|
import { ILoadingPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/loadingpane/interfaces/ILoadingPaneProps";
|
|
18
|
+
import { IMockProps } from "./IMockProps";
|
|
19
|
+
import { INotificationPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/notificationpane/interfaces/INotificationPaneProps";
|
|
14
20
|
import { IOOOHPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/outofofficehourspane/interfaces/IOOOHPaneProps";
|
|
21
|
+
import { IPostChatSurveyPaneStatefulProps } from "../../postchatsurveypanestateful/interfaces/IPostChatSurveyPaneStatefulProps";
|
|
15
22
|
import { IPreChatSurveyPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/prechatsurveypane/interfaces/IPreChatSurveyPaneProps";
|
|
16
23
|
import { IProactiveChatPaneStatefulProps } from "../../proactivechatpanestateful/interfaces/IProactiveChatPaneStatefulProps";
|
|
17
24
|
import { IReconnectChatPaneStatefulProps } from "../../reconnectchatpanestateful/interfaces/IReconnectChatPaneStatefulProps";
|
|
25
|
+
import { IScrollBarProps } from "./IScrollBarProps";
|
|
18
26
|
import { IStartChatErrorPaneProps } from "../../startchaterrorpanestateful/interfaces/IStartChatErrorPaneProps";
|
|
19
27
|
import { ITelemetryConfig } from "../../../common/telemetry/interfaces/ITelemetryConfig";
|
|
20
28
|
import { IWebChatContainerStatefulProps } from "../../webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps";
|
|
21
29
|
import { OmnichannelChatSDK } from "@microsoft/omnichannel-chat-sdk";
|
|
22
|
-
import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidgetContext";
|
|
23
|
-
import { IContextDataStore } from "../../../common/interfaces/IContextDataStore";
|
|
24
|
-
import { IPostChatSurveyPaneStatefulProps } from "../../postchatsurveypanestateful/interfaces/IPostChatSurveyPaneStatefulProps";
|
|
25
|
-
import { IScrollBarProps } from "./IScrollBarProps";
|
|
26
|
-
import { IDraggableChatWidgetProps } from "./IDraggableChatWidgetProps";
|
|
27
|
-
import { INotificationPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/notificationpane/interfaces/INotificationPaneProps";
|
|
28
|
-
import { IMockProps } from "./IMockProps";
|
|
29
30
|
export interface ILiveChatWidgetProps {
|
|
30
31
|
audioNotificationProps?: IAudioNotificationProps;
|
|
31
32
|
callingContainerProps?: ICallingContainerProps;
|
|
@@ -63,4 +64,5 @@ export interface ILiveChatWidgetProps {
|
|
|
63
64
|
initialCustomContext?: any;
|
|
64
65
|
draggableChatWidgetProps?: IDraggableChatWidgetProps;
|
|
65
66
|
mock?: IMockProps;
|
|
67
|
+
featureConfigProps?: IFeatureConfigProps;
|
|
66
68
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ISendBox {
|
|
2
|
+
/**
|
|
3
|
+
* Target the textarea element in the send box
|
|
4
|
+
*/
|
|
5
|
+
textarea?: {
|
|
6
|
+
/**
|
|
7
|
+
* Customer can increase minHeight as a work-around to avoid bug when some languages (like Arabic, Chinese,
|
|
8
|
+
* Hebrew, etc) will show a scrollbar in the textarea element when placeholder is visible
|
|
9
|
+
*/
|
|
10
|
+
minHeight?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts
CHANGED
|
@@ -6,10 +6,13 @@ import { IWebChatProps } from "./IWebChatProps";
|
|
|
6
6
|
import { StyleOptions } from "botframework-webchat-api";
|
|
7
7
|
import { IAdaptiveCardStyles } from "./IAdaptiveCardStyles";
|
|
8
8
|
import { IBotAuthConfig } from "./IBotAuthConfig";
|
|
9
|
+
import { ISendBox } from "../../livechatwidget/interfaces/ISendBox";
|
|
9
10
|
export interface IWebChatContainerStatefulProps {
|
|
10
11
|
containerStyles?: IStyle;
|
|
11
12
|
disableNewLineMarkdownSupport?: boolean;
|
|
12
13
|
disableMarkdownMessageFormatting?: boolean;
|
|
14
|
+
opensMarkdownLinksInSameTab?: boolean;
|
|
15
|
+
honorsTargetInHTMLLinks?: boolean;
|
|
13
16
|
webChatStyles?: StyleOptions;
|
|
14
17
|
webChatProps?: IWebChatProps;
|
|
15
18
|
directLine?: any;
|
|
@@ -20,4 +23,6 @@ export interface IWebChatContainerStatefulProps {
|
|
|
20
23
|
botAuthConfig?: IBotAuthConfig;
|
|
21
24
|
hyperlinkTextOverride?: boolean;
|
|
22
25
|
adaptiveCardStyles?: IAdaptiveCardStyles;
|
|
26
|
+
sendBoxTextBox?: ISendBox;
|
|
27
|
+
webChatHistoryMobileAccessibilityLabel?: string;
|
|
23
28
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Ensures that links within messages are processed so that the caller website cannot be traced.
|
|
5
5
|
******/
|
|
6
6
|
import { IWebChatAction } from "../../../interfaces/IWebChatAction";
|
|
7
|
-
declare const htmlTextMiddleware: ({ dispatch }: {
|
|
7
|
+
declare const htmlTextMiddleware: (honorsTargetInHTMLLinks?: boolean) => ({ dispatch }: {
|
|
8
8
|
dispatch: any;
|
|
9
9
|
}) => (next: any) => (action: IWebChatAction) => any;
|
|
10
10
|
export default htmlTextMiddleware;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/omnichannel-chat-widget",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.7-main.262d750",
|
|
4
4
|
"description": "Microsoft Omnichannel Chat Widget",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"types": "lib/types/index.d.ts",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@azure/core-tracing": "^1.2.0",
|
|
80
80
|
"@microsoft/omnichannel-chat-components": "1.1.8",
|
|
81
|
-
"@microsoft/omnichannel-chat-sdk": "^1.10.
|
|
81
|
+
"@microsoft/omnichannel-chat-sdk": "^1.10.15",
|
|
82
82
|
"@opentelemetry/api": "^1.9.0",
|
|
83
83
|
"abort-controller-es5": "^2.0.1",
|
|
84
84
|
"dompurify": "^3.2.4",
|