@microsoft/omnichannel-chat-widget 1.7.7-main.4955cc8 → 1.7.7-main.65ecd48
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 +2 -0
- 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/ISendBox.js +1 -0
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- 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 +8 -7
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/esm/common/Constants.js +2 -0
- 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/ISendBox.js +1 -0
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- 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 +8 -7
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/types/common/Constants.d.ts +2 -0
- package/lib/types/components/livechatwidget/common/createMarkdown.d.ts +1 -1
- package/lib/types/components/livechatwidget/interfaces/ISendBox.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +4 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.d.ts +1 -1
- package/package.json +1 -1
|
@@ -99,6 +99,8 @@ _defineProperty(Constants, "Zero", "zero");
|
|
|
99
99
|
_defineProperty(Constants, "Title", "title");
|
|
100
100
|
_defineProperty(Constants, "Target", "target");
|
|
101
101
|
_defineProperty(Constants, "Blank", "_blank");
|
|
102
|
+
_defineProperty(Constants, "TargetSelf", "_self");
|
|
103
|
+
_defineProperty(Constants, "TargetTop", "_top");
|
|
102
104
|
_defineProperty(Constants, "TargetRelationship", "rel");
|
|
103
105
|
_defineProperty(Constants, "TargetRelationshipAttributes", "noopener noreferrer");
|
|
104
106
|
// Markdown icons
|
|
@@ -11,7 +11,7 @@ var _defaultMarkdownLocalizedTexts = require("../../webchatcontainerstateful/com
|
|
|
11
11
|
var _markdownHelper = require("./helpers/markdownHelper");
|
|
12
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
-
const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
|
|
14
|
+
const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab) => {
|
|
15
15
|
let markdown;
|
|
16
16
|
if (!disableMarkdownMessageFormatting) {
|
|
17
17
|
markdown = new _markdownIt.default(_Constants.Constants.Default, {
|
|
@@ -45,10 +45,11 @@ const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdown
|
|
|
45
45
|
const targetAttrIndex = tokens[idx].attrIndex(_Constants.Constants.Target);
|
|
46
46
|
// Put a transparent pixel instead of the "open in new window" icon, so developers can easily modify the icon in CSS.
|
|
47
47
|
const TRANSPARENT_GIF = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
48
|
+
const targetValue = opensMarkdownLinksInSameTab ? _Constants.Constants.TargetTop : _Constants.Constants.Blank;
|
|
48
49
|
if (~targetAttrIndex) {
|
|
49
|
-
tokens[idx].attrs[targetAttrIndex][1] =
|
|
50
|
+
tokens[idx].attrs[targetAttrIndex][1] = targetValue;
|
|
50
51
|
} else {
|
|
51
|
-
tokens[idx].attrPush([_Constants.Constants.Target,
|
|
52
|
+
tokens[idx].attrPush([_Constants.Constants.Target, targetValue]);
|
|
52
53
|
}
|
|
53
54
|
const relAttrIndex = tokens[idx].attrIndex(_Constants.Constants.TargetRelationship);
|
|
54
55
|
if (~relAttrIndex) {
|
|
@@ -40,7 +40,7 @@ var _sanitizationMiddleware = _interopRequireDefault(require("../../webchatconta
|
|
|
40
40
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
41
41
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
42
|
const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
43
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$
|
|
43
|
+
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;
|
|
44
44
|
// Add a hook to make all links open a new window
|
|
45
45
|
postDomPurifyActivities();
|
|
46
46
|
const localizedTexts = {
|
|
@@ -50,12 +50,14 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
50
50
|
const hyperlinkTextOverride = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hyperlinkTextOverride) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.hyperlinkTextOverride;
|
|
51
51
|
const disableNewLineMarkdownSupport = ((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.disableNewLineMarkdownSupport) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.disableNewLineMarkdownSupport;
|
|
52
52
|
const disableMarkdownMessageFormatting = ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.disableMarkdownMessageFormatting) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.disableMarkdownMessageFormatting;
|
|
53
|
+
const opensMarkdownLinksInSameTab = (_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.opensMarkdownLinksInSameTab;
|
|
54
|
+
const honorsTargetInHTMLLinks = (_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.honorsTargetInHTMLLinks;
|
|
53
55
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
54
|
-
const markdown = (0, _createMarkdown.createMarkdown)(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
|
|
56
|
+
const markdown = (0, _createMarkdown.createMarkdown)(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab);
|
|
55
57
|
// Initialize Web Chat's redux store
|
|
56
58
|
let webChatStore = _WebChatStoreLoader.WebChatStoreLoader.store;
|
|
57
59
|
if (!webChatStore) {
|
|
58
|
-
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$
|
|
60
|
+
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
59
61
|
const conversationEndCallback = async () => {
|
|
60
62
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
63
|
const conversationDetails = await (0, _utils.getConversationDetailsCall)(facadeChatSDK);
|
|
@@ -87,18 +89,18 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
87
89
|
};
|
|
88
90
|
webChatStore = (0, _botframeworkWebchat.createStore)({},
|
|
89
91
|
//initial state
|
|
90
|
-
_preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_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.default, (0, _conversationEndMiddleware.default)(conversationEndCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.createMessageTimeStampMiddleware, _messageSequenceIdOverrideMiddleware.createMessageSequenceIdOverrideMiddleware, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, _htmlTextMiddleware.default, (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
|
|
92
|
+
_preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_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.default, (0, _conversationEndMiddleware.default)(conversationEndCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.createMessageTimeStampMiddleware, _messageSequenceIdOverrideMiddleware.createMessageSequenceIdOverrideMiddleware, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, (0, _htmlTextMiddleware.default)(honorsTargetInHTMLLinks), (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
|
|
91
93
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
-
...(((_props$
|
|
94
|
+
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
93
95
|
_WebChatStoreLoader.WebChatStoreLoader.store = webChatStore;
|
|
94
96
|
}
|
|
95
97
|
const hyperlinkTextOverrideRenderer = new _HyperlinkTextOverrideRenderer.default(hyperlinkTextOverride);
|
|
96
98
|
const markdownRenderers = [hyperlinkTextOverrideRenderer];
|
|
97
99
|
const renderMarkdown = text => {
|
|
98
|
-
var _props$
|
|
99
|
-
if ((_props$
|
|
100
|
-
var _props$
|
|
101
|
-
text = (_props$
|
|
100
|
+
var _props$webChatContain8, _props$webChatContain9;
|
|
101
|
+
if ((_props$webChatContain8 = props.webChatContainerProps) !== null && _props$webChatContain8 !== void 0 && (_props$webChatContain9 = _props$webChatContain8.webChatProps) !== null && _props$webChatContain9 !== void 0 && _props$webChatContain9.renderMarkdown) {
|
|
102
|
+
var _props$webChatContain10;
|
|
103
|
+
text = (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatProps.renderMarkdown(text);
|
|
102
104
|
} else {
|
|
103
105
|
const render = disableMarkdownMessageFormatting ? markdown.renderInline.bind(markdown) : markdown.render.bind(markdown);
|
|
104
106
|
text = render(text);
|
|
@@ -108,16 +110,19 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
108
110
|
});
|
|
109
111
|
const config = {
|
|
110
112
|
FORBID_TAGS: ["form", "button", "script", "div", "input"],
|
|
111
|
-
FORBID_ATTR: ["action"]
|
|
113
|
+
FORBID_ATTR: ["action"],
|
|
114
|
+
ADD_ATTR: ["target"]
|
|
112
115
|
};
|
|
113
116
|
text = _dompurify.default.sanitize(text, config);
|
|
114
117
|
return text;
|
|
115
118
|
};
|
|
116
119
|
function postDomPurifyActivities() {
|
|
117
120
|
_dompurify.default.addHook("afterSanitizeAttributes", function (node) {
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
node.setAttribute(
|
|
121
|
+
const target = node.getAttribute(_Constants.Constants.Target);
|
|
122
|
+
if (target === _Constants.Constants.TargetSelf) {
|
|
123
|
+
node.setAttribute(_Constants.Constants.Target, _Constants.Constants.TargetTop);
|
|
124
|
+
} else if (!target) {
|
|
125
|
+
node.setAttribute(_Constants.Constants.Target, _Constants.Constants.Blank);
|
|
121
126
|
}
|
|
122
127
|
});
|
|
123
128
|
}
|
|
@@ -127,18 +132,18 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
127
132
|
dir: state.domainStates.globalDir,
|
|
128
133
|
locale: (0, _utils.changeLanguageCodeFormatForWebChat)((0, _omnichannelChatSdk.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)),
|
|
129
134
|
store: webChatStore,
|
|
130
|
-
activityMiddleware: (_props$
|
|
131
|
-
attachmentMiddleware: (_props$
|
|
132
|
-
activityStatusMiddleware: (_props$
|
|
133
|
-
toastMiddleware: (_props$
|
|
135
|
+
activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : (0, _activityMiddleware.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),
|
|
136
|
+
attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : (0, _attachmentMiddleware.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.defaultAttachmentProps.enableInlinePlaying),
|
|
137
|
+
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.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
|
|
138
|
+
toastMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableToastMiddleware ? undefined : (0, _toastMiddleware.createToastMiddleware)(props.notificationPaneProps, endChat),
|
|
134
139
|
renderMarkdown,
|
|
135
|
-
avatarMiddleware: (_props$
|
|
136
|
-
groupActivitiesMiddleware: (_props$
|
|
137
|
-
typingIndicatorMiddleware: (_props$
|
|
140
|
+
avatarMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableAvatarMiddleware ? undefined : (0, _avatarMiddleware.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),
|
|
141
|
+
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.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
|
|
142
|
+
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.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
|
|
138
143
|
onTelemetry: (0, _WebChatLogger.createWebChatTelemetry)(),
|
|
139
|
-
cardActionMiddleware: (0, _cardActionMiddleware.createCardActionMiddleware)(((_props$
|
|
144
|
+
cardActionMiddleware: (0, _cardActionMiddleware.createCardActionMiddleware)(((_props$webChatContain25 = props.webChatContainerProps) === null || _props$webChatContain25 === void 0 ? void 0 : _props$webChatContain25.botMagicCode) || undefined),
|
|
140
145
|
sendTypingIndicator: true,
|
|
141
|
-
...((_props$
|
|
146
|
+
...((_props$webChatContain26 = props.webChatContainerProps) === null || _props$webChatContain26 === void 0 ? void 0 : _props$webChatContain26.webChatProps)
|
|
142
147
|
};
|
|
143
148
|
return webChatProps;
|
|
144
149
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -64,7 +64,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
64
64
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
65
65
|
let uiTimer;
|
|
66
66
|
const LiveChatWidgetStateful = props => {
|
|
67
|
-
var _props$webChatContain, _props$styleProps, _props$controlProps, _props$controlProps3, _state$appStates7, _props$
|
|
67
|
+
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;
|
|
68
68
|
(0, _react2.useEffect)(() => {
|
|
69
69
|
uiTimer = (0, _utils.createTimer)();
|
|
70
70
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -94,6 +94,7 @@ const LiveChatWidgetStateful = props => {
|
|
|
94
94
|
|
|
95
95
|
//Scrollbar styles
|
|
96
96
|
const scrollbarProps = Object.assign({}, _defaultScrollBarProps.defaultScrollBarProps, props === null || props === void 0 ? void 0 : props.scrollBarProps);
|
|
97
|
+
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;
|
|
97
98
|
|
|
98
99
|
// In case the broadcast channel is already initialized elsewhere; One tab can only hold 1 instance
|
|
99
100
|
if ((props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.skipBroadcastChannelInit) !== true) {
|
|
@@ -613,8 +614,8 @@ const LiveChatWidgetStateful = props => {
|
|
|
613
614
|
});
|
|
614
615
|
}
|
|
615
616
|
if (state.appStates.conversationState === _ConversationState.ConversationState.InActive) {
|
|
616
|
-
var _props$
|
|
617
|
-
if ((props === null || props === void 0 ? void 0 : (_props$
|
|
617
|
+
var _props$webChatContain4, _props$webChatContain5;
|
|
618
|
+
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) {
|
|
618
619
|
setWebChatStyles(styles => {
|
|
619
620
|
return {
|
|
620
621
|
...styles,
|
|
@@ -658,12 +659,12 @@ const LiveChatWidgetStateful = props => {
|
|
|
658
659
|
}
|
|
659
660
|
}, [state.appStates.unreadMessageCount]);
|
|
660
661
|
(0, _react2.useEffect)(() => {
|
|
661
|
-
var _props$
|
|
662
|
+
var _props$webChatContain6;
|
|
662
663
|
setWebChatStyles({
|
|
663
664
|
...webChatStyles,
|
|
664
|
-
...((_props$
|
|
665
|
+
...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
|
|
665
666
|
});
|
|
666
|
-
}, [(_props$
|
|
667
|
+
}, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.webChatStyles]);
|
|
667
668
|
(0, _react2.useEffect)(() => {
|
|
668
669
|
//Confirmation pane dismissing through OK option, so proceed with end chat
|
|
669
670
|
if (state.domainStates.confirmationState === _Constants.ConfirmationState.Ok) {
|
|
@@ -762,12 +763,12 @@ const LiveChatWidgetStateful = props => {
|
|
|
762
763
|
|
|
763
764
|
// if props state gets updates we need to update the renderingMiddlewareProps in the state
|
|
764
765
|
(0, _react2.useEffect)(() => {
|
|
765
|
-
var _props$
|
|
766
|
+
var _props$webChatContain8;
|
|
766
767
|
dispatch({
|
|
767
768
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
768
|
-
payload: (_props$
|
|
769
|
+
payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
|
|
769
770
|
});
|
|
770
|
-
}, [(_props$
|
|
771
|
+
}, [(_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.renderingMiddlewareProps]);
|
|
771
772
|
(0, _react2.useEffect)(() => {
|
|
772
773
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
773
774
|
Event: _TelemetryConstants.TelemetryEvent.UXLivechatwidgetCompleted,
|
|
@@ -809,7 +810,7 @@ const LiveChatWidgetStateful = props => {
|
|
|
809
810
|
const webChatProps = (0, _initWebChatComposer.initWebChatComposer)(props, state, dispatch, facadeChatSDK, endChatRelay);
|
|
810
811
|
const downloadTranscriptProps = (0, _createDownloadTranscriptProps.default)(props.downloadTranscriptProps, {
|
|
811
812
|
...(_defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps === null || _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps === void 0 ? void 0 : _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles),
|
|
812
|
-
...((_props$
|
|
813
|
+
...((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatStyles)
|
|
813
814
|
}, props.webChatContainerProps);
|
|
814
815
|
const livechatProps = {
|
|
815
816
|
...props,
|
|
@@ -867,13 +868,16 @@ const LiveChatWidgetStateful = props => {
|
|
|
867
868
|
height: .75em;
|
|
868
869
|
margin-left: .25em;
|
|
869
870
|
}
|
|
870
|
-
|
|
871
|
+
${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
|
|
872
|
+
textarea.webchat__send-box-text-box__html-text-area {
|
|
873
|
+
min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight};
|
|
874
|
+
}`}
|
|
871
875
|
`), /*#__PURE__*/_react2.default.createElement(_DraggableChatWidget.default, chatWidgetDraggableConfig, /*#__PURE__*/_react2.default.createElement(Composer, _extends({}, webChatProps, {
|
|
872
876
|
userID: userID,
|
|
873
877
|
styleOptions: {
|
|
874
878
|
...webChatStyles,
|
|
875
|
-
bubbleBackground: ((_props$
|
|
876
|
-
bubbleTextColor: ((_props$
|
|
879
|
+
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.defaultAdaptiveCardStyles.background,
|
|
880
|
+
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.defaultAdaptiveCardStyles.color
|
|
877
881
|
},
|
|
878
882
|
directLine: directLine
|
|
879
883
|
}), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
|
|
@@ -16,6 +16,8 @@ const defaultWebChatContainerStatefulProps = {
|
|
|
16
16
|
containerStyles: _defaultWebChatStatefulContainerStyles.defaultWebChatStatefulContainerStyles,
|
|
17
17
|
disableNewLineMarkdownSupport: false,
|
|
18
18
|
disableMarkdownMessageFormatting: false,
|
|
19
|
+
opensMarkdownLinksInSameTab: false,
|
|
20
|
+
honorsTargetInHTMLLinks: false,
|
|
19
21
|
hyperlinkTextOverride: false,
|
|
20
22
|
directLine: new _mockadapter.default(),
|
|
21
23
|
adaptiveCardStyles: _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles
|
|
@@ -18,7 +18,9 @@ class HyperlinkTextOverrideRenderer {
|
|
|
18
18
|
convertTextToHtmlNode(text) {
|
|
19
19
|
const htmlNode = document.createElement(_Constants.HtmlAttributeNames.div);
|
|
20
20
|
try {
|
|
21
|
-
text = _dompurify.default.sanitize(text
|
|
21
|
+
text = _dompurify.default.sanitize(text, {
|
|
22
|
+
ADD_ATTR: ["target"]
|
|
23
|
+
});
|
|
22
24
|
htmlNode.innerHTML = text;
|
|
23
25
|
} catch {
|
|
24
26
|
return htmlNode;
|
|
@@ -31,15 +31,28 @@ const DeliveredTimestamp = _ref => {
|
|
|
31
31
|
timestamp
|
|
32
32
|
}
|
|
33
33
|
} = args;
|
|
34
|
+
const getTimeElement = timestamp => {
|
|
35
|
+
const timeString = (0, _utils.getTimestampHourMinute)(timestamp);
|
|
36
|
+
const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
|
|
37
|
+
|
|
38
|
+
// For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
|
|
39
|
+
// make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
|
|
40
|
+
if (dir === "rtl" && isAmPmFormat) {
|
|
41
|
+
return /*#__PURE__*/_react.default.createElement("span", {
|
|
42
|
+
dir: "ltr"
|
|
43
|
+
}, (0, _utils.getTimestampHourMinute)(timestamp));
|
|
44
|
+
}
|
|
45
|
+
return timeString;
|
|
46
|
+
};
|
|
34
47
|
return /*#__PURE__*/_react.default.createElement(_react2.Stack, {
|
|
35
48
|
style: contentStyles,
|
|
36
49
|
dir: dir
|
|
37
50
|
}, role === _DirectLineSenderRole.DirectLineSenderRole.Bot && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
38
51
|
dir: dir,
|
|
39
52
|
"aria-hidden": "false"
|
|
40
|
-
}, name, " - ", (
|
|
53
|
+
}, name, " - ", getTimeElement(timestamp))), role === _DirectLineSenderRole.DirectLineSenderRole.User && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
41
54
|
"aria-hidden": "false",
|
|
42
55
|
dir: dir
|
|
43
|
-
}, " ", (
|
|
56
|
+
}, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
|
|
44
57
|
};
|
|
45
58
|
exports.DeliveredTimestamp = DeliveredTimestamp;
|
|
@@ -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
|
-
|
|
26
|
-
|
|
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
|
|
56
|
-
if (!aNode.target ||
|
|
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
|
|
|
@@ -92,7 +93,7 @@ const processHTMLText = (action, text) => {
|
|
|
92
93
|
};
|
|
93
94
|
|
|
94
95
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
|
95
|
-
const htmlTextMiddleware = _ref => {
|
|
96
|
+
const htmlTextMiddleware = honorsTargetInHTMLLinks => _ref => {
|
|
96
97
|
let {
|
|
97
98
|
dispatch
|
|
98
99
|
} = _ref;
|
|
@@ -102,7 +103,7 @@ const htmlTextMiddleware = _ref => {
|
|
|
102
103
|
var _action$payload, _action$payload$activ;
|
|
103
104
|
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
105
|
if (text) {
|
|
105
|
-
action = processHTMLText(action, text);
|
|
106
|
+
action = processHTMLText(action, text, honorsTargetInHTMLLinks ?? false);
|
|
106
107
|
}
|
|
107
108
|
} catch (e) {
|
|
108
109
|
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 = {
|
|
@@ -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
|
|
@@ -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] =
|
|
44
|
+
tokens[idx].attrs[targetAttrIndex][1] = targetValue;
|
|
44
45
|
} else {
|
|
45
|
-
tokens[idx].attrPush([Constants.Target,
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
93
|
-
if ((_props$
|
|
94
|
-
var _props$
|
|
95
|
-
text = (_props$
|
|
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
|
-
|
|
113
|
-
if (
|
|
114
|
-
node.setAttribute(
|
|
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$
|
|
125
|
-
attachmentMiddleware: (_props$
|
|
126
|
-
activityStatusMiddleware: (_props$
|
|
127
|
-
toastMiddleware: (_props$
|
|
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$
|
|
130
|
-
groupActivitiesMiddleware: (_props$
|
|
131
|
-
typingIndicatorMiddleware: (_props$
|
|
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$
|
|
139
|
+
cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain25 = props.webChatContainerProps) === null || _props$webChatContain25 === void 0 ? void 0 : _props$webChatContain25.botMagicCode) || undefined),
|
|
134
140
|
sendTypingIndicator: true,
|
|
135
|
-
...((_props$
|
|
141
|
+
...((_props$webChatContain26 = props.webChatContainerProps) === null || _props$webChatContain26 === void 0 ? void 0 : _props$webChatContain26.webChatProps)
|
|
136
142
|
};
|
|
137
143
|
return webChatProps;
|
|
138
144
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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) {
|
|
@@ -605,8 +606,8 @@ export const LiveChatWidgetStateful = props => {
|
|
|
605
606
|
});
|
|
606
607
|
}
|
|
607
608
|
if (state.appStates.conversationState === ConversationState.InActive) {
|
|
608
|
-
var _props$
|
|
609
|
-
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) {
|
|
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$
|
|
654
|
+
var _props$webChatContain6;
|
|
654
655
|
setWebChatStyles({
|
|
655
656
|
...webChatStyles,
|
|
656
|
-
...((_props$
|
|
657
|
+
...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
|
|
657
658
|
});
|
|
658
|
-
}, [(_props$
|
|
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$
|
|
758
|
+
var _props$webChatContain8;
|
|
758
759
|
dispatch({
|
|
759
760
|
type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
760
|
-
payload: (_props$
|
|
761
|
+
payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
|
|
761
762
|
});
|
|
762
|
-
}, [(_props$
|
|
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$
|
|
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$
|
|
868
|
-
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
|
|
869
873
|
},
|
|
870
874
|
directLine: directLine
|
|
871
875
|
}), /*#__PURE__*/React.createElement(Stack, {
|
|
@@ -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
|
|
|
@@ -86,7 +87,7 @@ const processHTMLText = (action, text) => {
|
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
|
89
|
-
const htmlTextMiddleware = _ref => {
|
|
90
|
+
const htmlTextMiddleware = honorsTargetInHTMLLinks => _ref => {
|
|
90
91
|
let {
|
|
91
92
|
dispatch
|
|
92
93
|
} = _ref;
|
|
@@ -96,7 +97,7 @@ const htmlTextMiddleware = _ref => {
|
|
|
96
97
|
var _action$payload, _action$payload$activ;
|
|
97
98
|
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
99
|
if (text) {
|
|
99
|
-
action = processHTMLText(action, text);
|
|
100
|
+
action = processHTMLText(action, text, honorsTargetInHTMLLinks ?? false);
|
|
100
101
|
}
|
|
101
102
|
} catch (e) {
|
|
102
103
|
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 = {
|
|
@@ -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";
|
|
@@ -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;
|
|
@@ -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,5 @@ export interface IWebChatContainerStatefulProps {
|
|
|
20
23
|
botAuthConfig?: IBotAuthConfig;
|
|
21
24
|
hyperlinkTextOverride?: boolean;
|
|
22
25
|
adaptiveCardStyles?: IAdaptiveCardStyles;
|
|
26
|
+
sendBoxTextBox?: ISendBox;
|
|
23
27
|
}
|
|
@@ -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;
|