@microsoft/omnichannel-chat-widget 1.8.4-main.d4c4cb2 → 1.8.4-main.e0c2625
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 +4 -0
- package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/cjs/common/utils.js +56 -15
- package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +2 -1
- package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +2 -1
- package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +2 -1
- package/lib/cjs/components/livechatwidget/common/endChat.js +4 -0
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +182 -1
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +14 -2
- package/lib/cjs/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +36 -9
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +1 -0
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +2 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +2 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +138 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +3 -13
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +81 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +33 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +9 -3
- package/lib/esm/common/Constants.js +4 -0
- package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/esm/common/utils.js +53 -13
- package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +2 -1
- package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +2 -1
- package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +2 -1
- package/lib/esm/components/livechatwidget/common/endChat.js +4 -0
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +182 -1
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +15 -3
- package/lib/esm/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +37 -10
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +1 -0
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +2 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +2 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +130 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +3 -13
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +74 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +34 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +9 -3
- package/lib/types/common/Constants.d.ts +3 -0
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +1 -0
- package/lib/types/common/utils.d.ts +2 -1
- package/lib/types/components/webchatcontainerstateful/interfaces/IAdaptiveCardStyles.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.d.ts +18 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.d.ts +12 -0
- package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +5 -0
- package/package.json +5 -4
|
@@ -146,6 +146,9 @@ _defineProperty(Constants, "customEventValue", "customEventValue");
|
|
|
146
146
|
_defineProperty(Constants, "Hidden", "Hidden");
|
|
147
147
|
_defineProperty(Constants, "EndConversationDueToOverflow", "endconversationduetooverflow");
|
|
148
148
|
_defineProperty(Constants, "SkipSessionCloseForPersistentChatFlag", "skipSessionCloseForPersistentChat");
|
|
149
|
+
// Minimum font-size for input fields to prevent iOS Safari auto-zoom on focus
|
|
150
|
+
_defineProperty(Constants, "minInputFontSizePx", 16);
|
|
151
|
+
_defineProperty(Constants, "minInputFontSize", "16px");
|
|
149
152
|
const Regex = (_class = /*#__PURE__*/_createClass(function Regex() {
|
|
150
153
|
_classCallCheck(this, Regex);
|
|
151
154
|
}), _defineProperty(_class, "EmailRegex", "^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\])$"), _class);
|
|
@@ -155,6 +158,7 @@ let HtmlIdNames = /*#__PURE__*/_createClass(function HtmlIdNames() {
|
|
|
155
158
|
});
|
|
156
159
|
exports.HtmlIdNames = HtmlIdNames;
|
|
157
160
|
_defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
|
|
161
|
+
_defineProperty(HtmlIdNames, "fileSentAnnouncementRegionId", "ms_lcw_file_sent_announcement");
|
|
158
162
|
let HtmlClassNames = /*#__PURE__*/_createClass(function HtmlClassNames() {
|
|
159
163
|
_classCallCheck(this, HtmlClassNames);
|
|
160
164
|
});
|
|
@@ -202,6 +202,7 @@ exports.TelemetryEvent = TelemetryEvent;
|
|
|
202
202
|
TelemetryEvent["QueueOverflowEvent"] = "QueueOverflowEvent";
|
|
203
203
|
TelemetryEvent["ProcessingHTMLTextMiddlewareFailed"] = "ProcessingHTMLTextMiddlewareFailed";
|
|
204
204
|
TelemetryEvent["ProcessingSanitizationMiddlewareFailed"] = "ProcessingSanitizationMiddlewareFailed";
|
|
205
|
+
TelemetryEvent["HTMLSanitized"] = "HTMLSanitized";
|
|
205
206
|
TelemetryEvent["FormatTagsMiddlewareJSONStringifyFailed"] = "FormatTagsMiddlewareJSONStringifyFailed";
|
|
206
207
|
TelemetryEvent["AttachmentUploadValidatorMiddlewareFailed"] = "AttachmentUploadValidatorMiddlewareFailed";
|
|
207
208
|
TelemetryEvent["CitationMiddlewareFailed"] = "CitationMiddlewareFailed";
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.
|
|
|
9
9
|
exports.isEndConversationDueToOverflowActivity = isEndConversationDueToOverflowActivity;
|
|
10
10
|
exports.parseAdaptiveCardPayload = exports.newGuid = exports.isValidCustomEvent = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = void 0;
|
|
11
11
|
exports.parseBooleanFromConfig = parseBooleanFromConfig;
|
|
12
|
-
exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = void 0;
|
|
12
|
+
exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.setAriaHiddenForSiblings = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = void 0;
|
|
13
13
|
var _Constants = require("./Constants");
|
|
14
14
|
var _TelemetryConstants = require("./telemetry/TelemetryConstants");
|
|
15
15
|
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
@@ -85,28 +85,69 @@ exports.findAllFocusableElement = findAllFocusableElement;
|
|
|
85
85
|
const preventFocusToMoveOutOfElement = elementId => {
|
|
86
86
|
const container = document.getElementById(elementId);
|
|
87
87
|
if (!container) {
|
|
88
|
-
return;
|
|
88
|
+
return () => {/* no-op */};
|
|
89
89
|
}
|
|
90
90
|
const focusableElements = findAllFocusableElement(container);
|
|
91
91
|
if (!focusableElements) {
|
|
92
|
-
return;
|
|
92
|
+
return () => {/* no-op */};
|
|
93
93
|
}
|
|
94
94
|
const firstFocusableElement = focusableElements[0];
|
|
95
95
|
const lastFocusableElement = focusableElements[focusableElements.length - 1];
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
96
|
+
const cleanups = [];
|
|
97
|
+
if (firstFocusableElement === lastFocusableElement) {
|
|
98
|
+
const handler = e => {
|
|
99
|
+
if (e.key === _KeyCodes.KeyCodes.TAB && !e.shiftKey) {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
firstFocusableElement.focus();
|
|
102
|
+
} else if (e.key === _KeyCodes.KeyCodes.TAB && e.shiftKey) {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
firstFocusableElement.focus();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
firstFocusableElement.addEventListener("keydown", handler);
|
|
108
|
+
cleanups.push(() => firstFocusableElement.removeEventListener("keydown", handler));
|
|
109
|
+
} else {
|
|
110
|
+
const firstHandler = e => {
|
|
111
|
+
if (e.shiftKey && e.key === _KeyCodes.KeyCodes.TAB) {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
lastFocusableElement === null || lastFocusableElement === void 0 ? void 0 : lastFocusableElement.focus();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
firstFocusableElement.addEventListener("keydown", firstHandler);
|
|
117
|
+
cleanups.push(() => firstFocusableElement.removeEventListener("keydown", firstHandler));
|
|
118
|
+
const lastHandler = e => {
|
|
119
|
+
if (!e.shiftKey && e.key === _KeyCodes.KeyCodes.TAB) {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
firstFocusableElement === null || firstFocusableElement === void 0 ? void 0 : firstFocusableElement.focus();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
lastFocusableElement.addEventListener("keydown", lastHandler);
|
|
125
|
+
cleanups.push(() => lastFocusableElement.removeEventListener("keydown", lastHandler));
|
|
126
|
+
}
|
|
127
|
+
return () => cleanups.forEach(fn => fn());
|
|
108
128
|
};
|
|
109
129
|
exports.preventFocusToMoveOutOfElement = preventFocusToMoveOutOfElement;
|
|
130
|
+
const setAriaHiddenForSiblings = (elementId, shouldHide, stateMap) => {
|
|
131
|
+
const element = document.getElementById(elementId);
|
|
132
|
+
if (!(element !== null && element !== void 0 && element.parentElement)) return;
|
|
133
|
+
Array.from(element.parentElement.children).forEach(sibling => {
|
|
134
|
+
if (sibling !== element) {
|
|
135
|
+
if (shouldHide) {
|
|
136
|
+
stateMap.set(sibling, sibling.getAttribute("aria-hidden"));
|
|
137
|
+
sibling.setAttribute("aria-hidden", "true");
|
|
138
|
+
} else if (stateMap.has(sibling)) {
|
|
139
|
+
const original = stateMap.get(sibling);
|
|
140
|
+
if (original === null) {
|
|
141
|
+
sibling.removeAttribute("aria-hidden");
|
|
142
|
+
} else {
|
|
143
|
+
sibling.setAttribute("aria-hidden", original);
|
|
144
|
+
}
|
|
145
|
+
stateMap.delete(sibling);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
exports.setAriaHiddenForSiblings = setAriaHiddenForSiblings;
|
|
110
151
|
const setFocusOnSendBox = () => {
|
|
111
152
|
const sendBoxSelector = "textarea[data-id=\"webchat-sendbox-input\"]";
|
|
112
153
|
setFocusOnElement(sendBoxSelector);
|
|
@@ -44,7 +44,7 @@ const CitationPaneStateful = props => {
|
|
|
44
44
|
|
|
45
45
|
// Initial focus pattern (mirrors ConfirmationPaneStateful): focus first focusable element (will re-attempt after visibility becomes true)
|
|
46
46
|
(0, _react.useEffect)(() => {
|
|
47
|
-
(0, _utils.preventFocusToMoveOutOfElement)(controlId);
|
|
47
|
+
const cleanup = (0, _utils.preventFocusToMoveOutOfElement)(controlId);
|
|
48
48
|
const focusableElements = (0, _utils.findAllFocusableElement)(`#${controlId}`);
|
|
49
49
|
requestAnimationFrame(() => {
|
|
50
50
|
if (focusableElements && focusableElements.length > 0 && focusableElements[0]) {
|
|
@@ -62,6 +62,7 @@ const CitationPaneStateful = props => {
|
|
|
62
62
|
Event: _TelemetryConstants.TelemetryEvent.UXCitationPaneCompleted,
|
|
63
63
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
64
64
|
});
|
|
65
|
+
return cleanup;
|
|
65
66
|
}, []);
|
|
66
67
|
|
|
67
68
|
// Retry focus once pane is actually visible (isReady) in case initial attempt occurred while wrapper was visibility:hidden
|
|
@@ -82,7 +82,7 @@ const ConfirmationPaneStateful = props => {
|
|
|
82
82
|
|
|
83
83
|
// Move focus to the first button
|
|
84
84
|
(0, _react.useEffect)(() => {
|
|
85
|
-
(0, _utils.preventFocusToMoveOutOfElement)(controlProps.id);
|
|
85
|
+
const cleanup = (0, _utils.preventFocusToMoveOutOfElement)(controlProps.id);
|
|
86
86
|
const focusableElements = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
|
|
87
87
|
requestAnimationFrame(() => {
|
|
88
88
|
if (focusableElements && focusableElements.length > 0 && focusableElements[0]) {
|
|
@@ -100,6 +100,7 @@ const ConfirmationPaneStateful = props => {
|
|
|
100
100
|
Event: _TelemetryConstants.TelemetryEvent.UXConfirmationPaneCompleted,
|
|
101
101
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
102
102
|
});
|
|
103
|
+
return cleanup;
|
|
103
104
|
}, []);
|
|
104
105
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_DimLayer.DimLayer, {
|
|
105
106
|
brightness: (controlProps === null || controlProps === void 0 ? void 0 : controlProps.brightnessValueOnDim) ?? "0.2"
|
|
@@ -103,7 +103,7 @@ const EmailTranscriptPaneStateful = props => {
|
|
|
103
103
|
|
|
104
104
|
// Move focus to the first button
|
|
105
105
|
(0, _react.useEffect)(() => {
|
|
106
|
-
(0, _utils.preventFocusToMoveOutOfElement)(controlProps.id);
|
|
106
|
+
const cleanup = (0, _utils.preventFocusToMoveOutOfElement)(controlProps.id);
|
|
107
107
|
const focusableElements = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
|
|
108
108
|
if (focusableElements) {
|
|
109
109
|
focusableElements[0].focus();
|
|
@@ -118,6 +118,7 @@ const EmailTranscriptPaneStateful = props => {
|
|
|
118
118
|
Event: _TelemetryConstants.TelemetryEvent.UXEmailTranscriptPaneCompleted,
|
|
119
119
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
120
120
|
});
|
|
121
|
+
return cleanup;
|
|
121
122
|
}, [initialEmail]);
|
|
122
123
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_DimLayer.DimLayer, {
|
|
123
124
|
brightness: (controlProps === null || controlProps === void 0 ? void 0 : controlProps.brightnessValueOnDim) ?? "0.2"
|
|
@@ -346,6 +346,10 @@ const closeChatStateCleanUp = dispatch => {
|
|
|
346
346
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CITATIONS,
|
|
347
347
|
payload: {}
|
|
348
348
|
});
|
|
349
|
+
dispatch({
|
|
350
|
+
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_SHOW_EMAIL_TRANSCRIPT_PANE,
|
|
351
|
+
payload: false
|
|
352
|
+
});
|
|
349
353
|
|
|
350
354
|
// Dismiss the chat disconnect notification banner if it was shown
|
|
351
355
|
_NotificationHandler.NotificationHandler.dismissNotification(_NotificationScenarios.NotificationScenarios.ChatDisconnect);
|
|
@@ -16,6 +16,7 @@ var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidget
|
|
|
16
16
|
var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
|
|
17
17
|
var _WebChatStoreLoader = require("../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader");
|
|
18
18
|
var _attachmentProcessingMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentProcessingMiddleware"));
|
|
19
|
+
var _attachmentSentAnnouncementMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware"));
|
|
19
20
|
var _channelDataMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware"));
|
|
20
21
|
var _activityMiddleware = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware");
|
|
21
22
|
var _activityStatusMiddleware = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware");
|
|
@@ -125,7 +126,7 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
125
126
|
};
|
|
126
127
|
webChatStore = (0, _botframeworkWebchat.createStore)({},
|
|
127
128
|
//initial state
|
|
128
|
-
_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), (0, _customEventMiddleware.default)(_omnichannelChatComponents.BroadcastService), (0, _queueOverflowHandlerMiddleware.createQueueOverflowMiddleware)(state, dispatch), (0, _channelDataMiddleware.default)(addConversationalSurveyTagsCallback), (0, _conversationEndMiddleware.default)(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), (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, (0, _citationsMiddleware.createCitationsMiddleware)(state, dispatch), _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, (0, _htmlTextMiddleware.default)(honorsTargetInHTMLLinks), (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default, (0, _callActionMiddleware.default)(),
|
|
129
|
+
_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), _attachmentSentAnnouncementMiddleware.default, (0, _customEventMiddleware.default)(_omnichannelChatComponents.BroadcastService), (0, _queueOverflowHandlerMiddleware.createQueueOverflowMiddleware)(state, dispatch), (0, _channelDataMiddleware.default)(addConversationalSurveyTagsCallback), (0, _conversationEndMiddleware.default)(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), (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, (0, _citationsMiddleware.createCitationsMiddleware)(state, dispatch), _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, (0, _htmlTextMiddleware.default)(honorsTargetInHTMLLinks), (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default, (0, _callActionMiddleware.default)(),
|
|
129
130
|
// Pass a callback so middleware can push initials into React context for reactivity
|
|
130
131
|
(0, _localizedStringsBotInitialsMiddleware.localizedStringsBotInitialsMiddleware)(initials => {
|
|
131
132
|
dispatch({
|
|
@@ -151,14 +152,194 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
151
152
|
markdownRenderers.forEach(renderer => {
|
|
152
153
|
text = renderer.render(text);
|
|
153
154
|
});
|
|
155
|
+
|
|
156
|
+
// EXISTING sanitization (continues to work as before)
|
|
154
157
|
const config = {
|
|
155
158
|
FORBID_TAGS: ["form", "button", "script", "div", "input"],
|
|
156
159
|
FORBID_ATTR: ["action"],
|
|
157
160
|
ADD_ATTR: ["target"]
|
|
158
161
|
};
|
|
159
162
|
text = _dompurify.default.sanitize(text, config);
|
|
163
|
+
|
|
164
|
+
// MONITOR-ONLY: Test what the stricter allowlist would remove (Phase 1)
|
|
165
|
+
// This does NOT modify the text, only logs telemetry
|
|
166
|
+
// Run during browser idle time to avoid blocking message flow and adding latency
|
|
167
|
+
const textToMonitor = text; // Capture current text value
|
|
168
|
+
|
|
169
|
+
// Schedule monitoring to run during browser idle time
|
|
170
|
+
const scheduleMonitoring = () => {
|
|
171
|
+
try {
|
|
172
|
+
monitorStrictSanitization(textToMonitor, state);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
// Silently catch errors to prevent blocking message flow
|
|
175
|
+
if (process.env.NODE_ENV === "development") {
|
|
176
|
+
console.error("[Monitor] HTML sanitization monitoring failed:", error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Use requestIdleCallback for truly idle execution, fallback to setTimeout for older browsers
|
|
182
|
+
if (typeof window !== "undefined" && "requestIdleCallback" in window) {
|
|
183
|
+
window.requestIdleCallback(scheduleMonitoring);
|
|
184
|
+
} else {
|
|
185
|
+
setTimeout(scheduleMonitoring, 0);
|
|
186
|
+
}
|
|
160
187
|
return text;
|
|
161
188
|
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Monitor-only sanitization (Phase 1: Gather telemetry)
|
|
192
|
+
* Tests what a stricter allowlist-based sanitization would remove
|
|
193
|
+
* WITHOUT actually removing it. Logs telemetry for analysis.
|
|
194
|
+
*
|
|
195
|
+
* IMPORTANT: This function is wrapped in try-catch and runs asynchronously
|
|
196
|
+
* to ensure failures don't block message flow or add latency.
|
|
197
|
+
*
|
|
198
|
+
* ISOLATION: Uses a separate DOMPurify instance to completely isolate
|
|
199
|
+
* monitoring hooks from other sanitization paths (e.g., postDomPurifyActivities).
|
|
200
|
+
* The instance is garbage collected after use, no cleanup needed.
|
|
201
|
+
*
|
|
202
|
+
* @param html - The HTML text that was already sanitized with existing config
|
|
203
|
+
* @param state - Widget state containing orgId and chatId
|
|
204
|
+
*/
|
|
205
|
+
const monitorStrictSanitization = (html, state) => {
|
|
206
|
+
// Early exit for empty content
|
|
207
|
+
if (!html) return;
|
|
208
|
+
|
|
209
|
+
// Track execution time for performance monitoring
|
|
210
|
+
const startTime = performance.now();
|
|
211
|
+
try {
|
|
212
|
+
// Create a separate DOMPurify instance for monitoring
|
|
213
|
+
// This completely isolates monitoring from other sanitization paths
|
|
214
|
+
const monitorDOMPurify = (0, _dompurify.default)(window);
|
|
215
|
+
|
|
216
|
+
// Strict allowlist configuration (proposed new rules)
|
|
217
|
+
// Note: DOMPurify blocks event handlers (onclick, onerror, etc.) by default
|
|
218
|
+
const strictConfig = {
|
|
219
|
+
ALLOWED_TAGS: ["b", "strong",
|
|
220
|
+
// Bold text
|
|
221
|
+
"i", "em", "u",
|
|
222
|
+
// Italic, emphasis, underline
|
|
223
|
+
"br", "p",
|
|
224
|
+
// Line breaks and paragraphs
|
|
225
|
+
"ul", "ol", "li",
|
|
226
|
+
// Lists
|
|
227
|
+
"a" // Links (with restricted attributes)
|
|
228
|
+
],
|
|
229
|
+
|
|
230
|
+
ALLOWED_ATTR: ["href",
|
|
231
|
+
// For links (will be restricted to http/https)
|
|
232
|
+
"target",
|
|
233
|
+
// For link behavior
|
|
234
|
+
"rel" // For security (noopener, noreferrer)
|
|
235
|
+
],
|
|
236
|
+
|
|
237
|
+
FORBID_TAGS: ["img", "video", "audio",
|
|
238
|
+
// Media (tracking beacons)
|
|
239
|
+
"iframe", "object", "embed",
|
|
240
|
+
// Embedded content
|
|
241
|
+
"script", "style",
|
|
242
|
+
// Script and styling
|
|
243
|
+
"form", "input", "textarea", "button",
|
|
244
|
+
// Form elements
|
|
245
|
+
"link", "meta", "base",
|
|
246
|
+
// Document metadata
|
|
247
|
+
"div", "span" // Layout elements
|
|
248
|
+
],
|
|
249
|
+
|
|
250
|
+
FORBID_ATTR: ["style",
|
|
251
|
+
// Inline CSS
|
|
252
|
+
"action" // Form action attribute (event handlers blocked by default)
|
|
253
|
+
],
|
|
254
|
+
|
|
255
|
+
ALLOWED_URI_REGEXP: /^https?:/i,
|
|
256
|
+
ALLOW_DATA_ATTR: false,
|
|
257
|
+
ALLOW_UNKNOWN_PROTOCOLS: false
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// Track what would be removed
|
|
261
|
+
const removedTags = [];
|
|
262
|
+
const removedAttributes = [];
|
|
263
|
+
|
|
264
|
+
// Add hooks to the isolated monitoring instance
|
|
265
|
+
monitorDOMPurify.addHook("uponSanitizeElement", (node, data) => {
|
|
266
|
+
try {
|
|
267
|
+
const tagName = data.tagName.toLowerCase();
|
|
268
|
+
// Filter out "body" tag which is DOMPurify's internal wrapper
|
|
269
|
+
if (node.nodeType === 1 && !strictConfig.ALLOWED_TAGS.includes(tagName) && tagName !== "body") {
|
|
270
|
+
removedTags.push(tagName);
|
|
271
|
+
}
|
|
272
|
+
} catch (hookError) {
|
|
273
|
+
// Silently ignore hook errors
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
monitorDOMPurify.addHook("uponSanitizeAttribute", (node, data) => {
|
|
277
|
+
try {
|
|
278
|
+
const attrName = data.attrName.toLowerCase();
|
|
279
|
+
if (!strictConfig.ALLOWED_ATTR.includes(attrName) && attrName !== "class" && attrName !== "id") {
|
|
280
|
+
removedAttributes.push(attrName);
|
|
281
|
+
}
|
|
282
|
+
} catch (hookError) {
|
|
283
|
+
// Silently ignore hook errors
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
// Run sanitization on the isolated instance (we discard the result)
|
|
288
|
+
// No cleanup needed - the instance will be garbage collected with its hooks
|
|
289
|
+
monitorDOMPurify.sanitize(html, strictConfig);
|
|
290
|
+
|
|
291
|
+
// Log telemetry if content would be affected by strict rules
|
|
292
|
+
if (removedTags.length > 0 || removedAttributes.length > 0) {
|
|
293
|
+
try {
|
|
294
|
+
var _state$domainStates, _state$domainStates$t, _state$domainStates2, _state$domainStates2$;
|
|
295
|
+
const uniqueTags = [...new Set(removedTags)];
|
|
296
|
+
const uniqueAttrs = [...new Set(removedAttributes)];
|
|
297
|
+
|
|
298
|
+
// Calculate execution time
|
|
299
|
+
const endTime = performance.now();
|
|
300
|
+
const executionTimeMs = Math.round((endTime - startTime) * 100) / 100; // Round to 2 decimal places
|
|
301
|
+
|
|
302
|
+
// Get context for telemetry (with safe fallbacks)
|
|
303
|
+
const orgId = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$t = _state$domainStates.telemetryInternalData) === null || _state$domainStates$t === void 0 ? void 0 : _state$domainStates$t.orgId) || "unknown";
|
|
304
|
+
const conversationId = (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.chatToken) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.chatId) || "unknown";
|
|
305
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
306
|
+
Event: _TelemetryConstants.TelemetryEvent.HTMLSanitized,
|
|
307
|
+
Description: "HTML content would be sanitized by stricter allowlist (monitor-only)",
|
|
308
|
+
ElapsedTimeInMilliseconds: executionTimeMs,
|
|
309
|
+
CustomProperties: {
|
|
310
|
+
OrganizationId: orgId,
|
|
311
|
+
ConversationId: conversationId,
|
|
312
|
+
RemovedTags: uniqueTags.join(", "),
|
|
313
|
+
RemovedAttributes: uniqueAttrs.join(", "),
|
|
314
|
+
Phase: "Monitor"
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Log to console in development for debugging
|
|
319
|
+
if (process.env.NODE_ENV === "development") {
|
|
320
|
+
console.warn("[Monitor] Stricter HTML sanitization would remove:", {
|
|
321
|
+
orgId,
|
|
322
|
+
conversationId,
|
|
323
|
+
removedTags: uniqueTags,
|
|
324
|
+
removedAttributes: uniqueAttrs,
|
|
325
|
+
executionTimeMs
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
} catch (telemetryError) {
|
|
329
|
+
// Silently ignore telemetry errors to prevent blocking
|
|
330
|
+
if (process.env.NODE_ENV === "development") {
|
|
331
|
+
console.error("[Monitor] Telemetry logging failed:", telemetryError);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} catch (error) {
|
|
336
|
+
// Catch-all for any unexpected errors
|
|
337
|
+
// Silently fail to ensure monitoring never blocks message flow
|
|
338
|
+
if (process.env.NODE_ENV === "development") {
|
|
339
|
+
console.error("[Monitor] Monitoring failed:", error);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
};
|
|
162
343
|
function postDomPurifyActivities() {
|
|
163
344
|
_dompurify.default.addHook("afterSanitizeAttributes", function (node) {
|
|
164
345
|
const target = node.getAttribute(_Constants.Constants.Target);
|
|
@@ -66,7 +66,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
66
66
|
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); }
|
|
67
67
|
let uiTimer;
|
|
68
68
|
const LiveChatWidgetStateful = props => {
|
|
69
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates8, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _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;
|
|
69
|
+
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates8, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _props$headerProps, _props$headerProps$co, _props$headerProps$co2, _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;
|
|
70
70
|
(0, _react2.useEffect)(() => {
|
|
71
71
|
uiTimer = (0, _utils.createTimer)();
|
|
72
72
|
_TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -1029,6 +1029,15 @@ const LiveChatWidgetStateful = props => {
|
|
|
1029
1029
|
}));
|
|
1030
1030
|
}
|
|
1031
1031
|
}, [state.domainStates.botAvatarInitials]);
|
|
1032
|
+
const isWidgetOpen = !state.appStates.isMinimized && state.appStates.conversationState !== _ConversationState.ConversationState.Closed;
|
|
1033
|
+
const siblingAriaHiddenMapRef = (0, _react2.useRef)(new Map());
|
|
1034
|
+
(0, _react2.useEffect)(() => {
|
|
1035
|
+
const map = siblingAriaHiddenMapRef.current;
|
|
1036
|
+
(0, _utils.setAriaHiddenForSiblings)(widgetElementId, isWidgetOpen, map);
|
|
1037
|
+
return () => {
|
|
1038
|
+
(0, _utils.setAriaHiddenForSiblings)(widgetElementId, false, map);
|
|
1039
|
+
};
|
|
1040
|
+
}, [isWidgetOpen]);
|
|
1032
1041
|
|
|
1033
1042
|
// WebChat's Composer can only be rendered if a directLine object is defined
|
|
1034
1043
|
return directLine && /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("style", null, `
|
|
@@ -1152,7 +1161,10 @@ const LiveChatWidgetStateful = props => {
|
|
|
1152
1161
|
}), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
|
|
1153
1162
|
id: widgetElementId,
|
|
1154
1163
|
styles: generalStyles,
|
|
1155
|
-
className: (_livechatProps$styleP = livechatProps.styleProps) === null || _livechatProps$styleP === void 0 ? void 0 : _livechatProps$styleP.className
|
|
1164
|
+
className: (_livechatProps$styleP = livechatProps.styleProps) === null || _livechatProps$styleP === void 0 ? void 0 : _livechatProps$styleP.className,
|
|
1165
|
+
role: isWidgetOpen ? "dialog" : undefined,
|
|
1166
|
+
"aria-modal": isWidgetOpen ? true : undefined,
|
|
1167
|
+
"aria-label": isWidgetOpen ? ((_props$headerProps = props.headerProps) === null || _props$headerProps === void 0 ? void 0 : (_props$headerProps$co = _props$headerProps.controlProps) === null || _props$headerProps$co === void 0 ? void 0 : (_props$headerProps$co2 = _props$headerProps$co.headerTitleProps) === null || _props$headerProps$co2 === void 0 ? void 0 : _props$headerProps$co2.text) ?? "Live Chat" : undefined
|
|
1156
1168
|
}, !((_livechatProps$contro = livechatProps.controlProps) !== null && _livechatProps$contro !== void 0 && _livechatProps$contro.hideChatButton) && !((_livechatProps$contro2 = livechatProps.controlProps) !== null && _livechatProps$contro2 !== void 0 && _livechatProps$contro2.hideStartChatButton) && (0, _componentController.shouldShowChatButton)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon = livechatProps.componentOverrides) === null || _livechatProps$compon === void 0 ? void 0 : _livechatProps$compon.chatButton) || /*#__PURE__*/_react2.default.createElement(_ChatButtonStateful.default, {
|
|
1157
1169
|
buttonProps: livechatProps.chatButtonProps,
|
|
1158
1170
|
outOfOfficeButtonProps: livechatProps.outOfOfficeChatButtonProps,
|
|
@@ -12,6 +12,7 @@ const defaultGeneralPreChatSurveyPaneStyleProps = {
|
|
|
12
12
|
borderColor: "#F1F1F1",
|
|
13
13
|
overflowY: "auto",
|
|
14
14
|
height: "inherit",
|
|
15
|
-
width: "inherit"
|
|
15
|
+
width: "inherit",
|
|
16
|
+
overscrollBehavior: "none"
|
|
16
17
|
};
|
|
17
18
|
exports.defaultGeneralPreChatSurveyPaneStyleProps = defaultGeneralPreChatSurveyPaneStyleProps;
|
|
@@ -62,7 +62,7 @@ const createMagicCodeSuccessResponse = signin => {
|
|
|
62
62
|
};
|
|
63
63
|
};
|
|
64
64
|
const WebChatContainerStateful = props => {
|
|
65
|
-
var _props$webChatContain, _defaultWebChatContai, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _props$
|
|
65
|
+
var _props$webChatContain, _defaultWebChatContai, _props$webChatContain2, _props$webChatContain3, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai2, _props$webChatContain10, _props$webChatContain11, _defaultWebChatContai3, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _webChatContainerProp24, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _webChatContainerProp28, _webChatContainerProp29, _props$webChatContain12, _props$webChatContain13, _webChatContainerProp30, _webChatContainerProp31, _webChatContainerProp32, _webChatContainerProp33, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
|
|
66
66
|
const [facadeChatSDK] = (0, _useFacadeChatSDKStore.default)();
|
|
67
67
|
|
|
68
68
|
// Create a font family that includes emoji support, based on the primary font or default
|
|
@@ -71,6 +71,10 @@ const WebChatContainerStateful = props => {
|
|
|
71
71
|
|
|
72
72
|
// Use iOS-optimized emoji font that prioritizes system-ui for proper emoji rendering
|
|
73
73
|
const fontFamilyWithEmojis = (0, _fontUtils.createIOSOptimizedEmojiFont)(primaryFont);
|
|
74
|
+
|
|
75
|
+
// Enforce minimum input font-size to prevent iOS Safari auto-zoom on focus
|
|
76
|
+
const configuredInputFontSize = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.adaptiveCardStyles) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.inputFontSize) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.inputFontSize;
|
|
77
|
+
const inputFontSize = parseFloat(configuredInputFontSize ?? String(_Constants.Constants.minInputFontSizePx)) < _Constants.Constants.minInputFontSizePx ? _Constants.Constants.minInputFontSize : configuredInputFontSize;
|
|
74
78
|
(0, _react2.useEffect)(() => {
|
|
75
79
|
uiTimer = (0, _utils.createTimer)();
|
|
76
80
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -170,7 +174,7 @@ const WebChatContainerStateful = props => {
|
|
|
170
174
|
...(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.localizedTexts)
|
|
171
175
|
};
|
|
172
176
|
(0, _react2.useEffect)(() => {
|
|
173
|
-
var _props$
|
|
177
|
+
var _props$webChatContain4, _props$webChatContain5;
|
|
174
178
|
if ((0, _utils.getDeviceType)() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
|
|
175
179
|
const chatHistoryElement = document.querySelector(`.${_Constants.HtmlClassNames.webChatHistoryContainer}`);
|
|
176
180
|
if (chatHistoryElement) {
|
|
@@ -188,7 +192,7 @@ const WebChatContainerStateful = props => {
|
|
|
188
192
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
189
193
|
Event: _TelemetryConstants.TelemetryEvent.WebChatLoaded
|
|
190
194
|
});
|
|
191
|
-
if (((_props$
|
|
195
|
+
if (((_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.disableThirdPartyCookiesAlert) !== true && !contextDataStore) {
|
|
192
196
|
try {
|
|
193
197
|
localStorage;
|
|
194
198
|
sessionStorage;
|
|
@@ -203,8 +207,8 @@ const WebChatContainerStateful = props => {
|
|
|
203
207
|
}
|
|
204
208
|
}, []);
|
|
205
209
|
(0, _react2.useEffect)(() => {
|
|
206
|
-
var _props$
|
|
207
|
-
if (!((_props$
|
|
210
|
+
var _props$webChatContain6, _props$webChatContain7;
|
|
211
|
+
if (!((_props$webChatContain6 = props.webChatContainerProps) !== null && _props$webChatContain6 !== void 0 && (_props$webChatContain7 = _props$webChatContain6.botMagicCode) !== null && _props$webChatContain7 !== void 0 && _props$webChatContain7.disabled)) {
|
|
208
212
|
return;
|
|
209
213
|
}
|
|
210
214
|
if (!window.BroadcastChannel) {
|
|
@@ -302,9 +306,15 @@ const WebChatContainerStateful = props => {
|
|
|
302
306
|
${webChatContainerProps !== null && webChatContainerProps !== void 0 && (_webChatContainerProp12 = webChatContainerProps.adaptiveCardStyles) !== null && _webChatContainerProp12 !== void 0 && _webChatContainerProp12.choiceInputPadding ? `padding: ${webChatContainerProps.adaptiveCardStyles.choiceInputPadding} !important;` : ""}
|
|
303
307
|
}
|
|
304
308
|
|
|
309
|
+
div[class="ac-input-container"] input,
|
|
310
|
+
div[class="ac-input-container"] textarea,
|
|
311
|
+
div[class="ac-input-container"] select {
|
|
312
|
+
font-size: ${inputFontSize} !important;
|
|
313
|
+
}
|
|
314
|
+
|
|
305
315
|
.ms_lcw_webchat_received_message>div.webchat__stacked-layout>div.webchat__stacked-layout__main>div.webchat__stacked-layout__content>div.webchat__stacked-layout__message-row>[class^=webchat]:not(.webchat__bubble--from-user)>.webchat__bubble__content {
|
|
306
|
-
background-color: ${((_props$
|
|
307
|
-
color:${((_props$
|
|
316
|
+
background-color: ${((_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : (_props$webChatContain9 = _props$webChatContain8.webChatStyles) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.bubbleBackground) ?? ((_defaultWebChatContai2 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.bubbleBackground)};
|
|
317
|
+
color:${((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : (_props$webChatContain11 = _props$webChatContain10.webChatStyles) === null || _props$webChatContain11 === void 0 ? void 0 : _props$webChatContain11.bubbleTextColor) ?? ((_defaultWebChatContai3 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.bubbleTextColor)};
|
|
308
318
|
}
|
|
309
319
|
|
|
310
320
|
div[class="ac-textBlock"] a:link,
|
|
@@ -389,7 +399,7 @@ const WebChatContainerStateful = props => {
|
|
|
389
399
|
}
|
|
390
400
|
|
|
391
401
|
.webchat__stacked-layout_container>div {
|
|
392
|
-
background: ${(props === null || props === void 0 ? void 0 : (_props$
|
|
402
|
+
background: ${(props === null || props === void 0 ? void 0 : (_props$webChatContain12 = props.webChatContainerProps) === null || _props$webChatContain12 === void 0 ? void 0 : (_props$webChatContain13 = _props$webChatContain12.containerStyles) === null || _props$webChatContain13 === void 0 ? void 0 : _props$webChatContain13.background) ?? ""}
|
|
393
403
|
}
|
|
394
404
|
.webchat__toast_text {
|
|
395
405
|
display: flex;
|
|
@@ -418,6 +428,7 @@ const WebChatContainerStateful = props => {
|
|
|
418
428
|
|
|
419
429
|
.webchat__auto-resize-textarea__textarea.webchat__send-box-text-box__html-text-area {
|
|
420
430
|
font-family: ${fontFamilyWithEmojis} !important;
|
|
431
|
+
font-size: ${inputFontSize} !important;
|
|
421
432
|
}
|
|
422
433
|
|
|
423
434
|
/* Suggested actions carousel previous/next navigation focus */
|
|
@@ -434,7 +445,23 @@ const WebChatContainerStateful = props => {
|
|
|
434
445
|
height: "100%",
|
|
435
446
|
width: "100%"
|
|
436
447
|
}
|
|
437
|
-
}, shouldLoadPersistentHistoryMessages && /*#__PURE__*/_react2.default.createElement(_WebChatEventSubscribers.default, null), /*#__PURE__*/_react2.default.createElement(BasicWebChat, null))),
|
|
448
|
+
}, shouldLoadPersistentHistoryMessages && /*#__PURE__*/_react2.default.createElement(_WebChatEventSubscribers.default, null), /*#__PURE__*/_react2.default.createElement(BasicWebChat, null))), /*#__PURE__*/_react2.default.createElement("div", {
|
|
449
|
+
id: _Constants.HtmlIdNames.fileSentAnnouncementRegionId,
|
|
450
|
+
role: "alert",
|
|
451
|
+
"aria-live": "assertive",
|
|
452
|
+
"aria-atomic": "true",
|
|
453
|
+
style: {
|
|
454
|
+
position: "absolute",
|
|
455
|
+
width: "1px",
|
|
456
|
+
height: "1px",
|
|
457
|
+
padding: "0",
|
|
458
|
+
margin: "-1px",
|
|
459
|
+
overflow: "hidden",
|
|
460
|
+
clip: "rect(0, 0, 0, 0)",
|
|
461
|
+
whiteSpace: "nowrap",
|
|
462
|
+
border: "0"
|
|
463
|
+
}
|
|
464
|
+
}), citationPaneOpen && /*#__PURE__*/_react2.default.createElement(_CitationPaneStateful.default, {
|
|
438
465
|
id: ((_props$citationPanePr = props.citationPaneProps) === null || _props$citationPanePr === void 0 ? void 0 : _props$citationPanePr.id) || _Constants.HtmlAttributeNames.ocwCitationPaneClassName,
|
|
439
466
|
title: ((_props$citationPanePr2 = props.citationPaneProps) === null || _props$citationPanePr2 === void 0 ? void 0 : _props$citationPanePr2.title) || _Constants.HtmlAttributeNames.ocwCitationPaneTitle,
|
|
440
467
|
contentHtml: citationPaneText,
|
|
@@ -33,6 +33,7 @@ const defaultMiddlewareLocalizedTexts = {
|
|
|
33
33
|
MIDDLEWARE_BANNER_CHAT_DISCONNECT: "Your conversation has been disconnected. For additional assistance, please start a new chat.",
|
|
34
34
|
THIRD_PARTY_COOKIES_BLOCKED_ALERT_MESSAGE: "Allow sites to save/read cookies in browser settings. Reloading page starts a new chat.",
|
|
35
35
|
MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware.",
|
|
36
|
+
MIDDLEWARE_BANNER_FILE_SENT: "File sent successfully.",
|
|
36
37
|
MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS: "Email will be sent after chat ends!",
|
|
37
38
|
MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR: "Email {0} could not be saved, try again later.",
|
|
38
39
|
PREVIOUS_MESSAGES_LOADING: "Loading previous messages...",
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.defaultAdaptiveCardStyles = void 0;
|
|
7
|
+
var _Constants = require("../../../../common/Constants");
|
|
7
8
|
const defaultAdaptiveCardStyles = {
|
|
8
9
|
background: "white",
|
|
9
10
|
color: "black",
|
|
@@ -11,6 +12,7 @@ const defaultAdaptiveCardStyles = {
|
|
|
11
12
|
textWhiteSpace: "normal",
|
|
12
13
|
buttonWhiteSpace: "normal",
|
|
13
14
|
buttonFlexWrap: "nowrap",
|
|
14
|
-
buttonGap: "0px"
|
|
15
|
+
buttonGap: "0px",
|
|
16
|
+
inputFontSize: _Constants.Constants.minInputFontSize
|
|
15
17
|
};
|
|
16
18
|
exports.defaultAdaptiveCardStyles = defaultAdaptiveCardStyles;
|
|
@@ -65,6 +65,8 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
|
|
|
65
65
|
originalSystemMessageTexts.set(activityKey, card.activity.text);
|
|
66
66
|
}
|
|
67
67
|
const sourceText = (activityKey && originalSystemMessageTexts.get(activityKey)) ?? card.activity.text;
|
|
68
|
+
// renderMarkdown sanitizes the HTML using DOMPurify with allowlist-based configuration
|
|
69
|
+
// See initWebChatComposer.ts for sanitization details
|
|
68
70
|
const renderedHtml = renderMarkdown(sourceText);
|
|
69
71
|
// eslint-disable-next-line react/display-name
|
|
70
72
|
return () => /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -7,6 +7,7 @@ exports.createAttachmentMiddleware = void 0;
|
|
|
7
7
|
var _Constants = require("../../../../../common/Constants");
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
9
|
var _FileAttachmentIconManager = require("../../../common/utils/FileAttachmentIconManager");
|
|
10
|
+
var _AdaptiveCardAccessibilityWrapper = _interopRequireDefault(require("./attachments/AdaptiveCardAccessibilityWrapper"));
|
|
10
11
|
var _Attachment = _interopRequireDefault(require("./attachments/Attachment"));
|
|
11
12
|
var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
|
|
12
13
|
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
@@ -120,7 +121,7 @@ const createAttachmentMiddleware = enableInlinePlaying => {
|
|
|
120
121
|
...((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : _state$domainStates$r3.attachmentAdaptiveCardStyles)
|
|
121
122
|
};
|
|
122
123
|
if (type === _Constants.WebChatMiddlewareConstants.adaptiveCard || _Constants.Constants.supportedAdaptiveCardContentTypes.indexOf(contentType) >= 0) {
|
|
123
|
-
return /*#__PURE__*/_react.default.createElement(
|
|
124
|
+
return /*#__PURE__*/_react.default.createElement(_AdaptiveCardAccessibilityWrapper.default, {
|
|
124
125
|
id: attachmentId,
|
|
125
126
|
style: atttachmentAdaptiveCardStyles
|
|
126
127
|
}, next(...args));
|