@microsoft/omnichannel-chat-widget 1.8.4-main.ab10cbb → 1.8.4-main.adf2da0
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/README.md +1 -0
- package/lib/cjs/common/Constants.js +4 -0
- package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/cjs/common/utils.js +92 -16
- 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 +32 -13
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +96 -5
- 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/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +15 -3
- package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +1 -0
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +64 -2
- package/lib/cjs/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +87 -9
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
- package/lib/cjs/components/webchatcontainerstateful/common/utils/citationA11y.js +195 -0
- 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 +153 -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/cjs/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
- package/lib/esm/common/Constants.js +4 -0
- package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/esm/common/utils.js +87 -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 +33 -14
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +96 -5
- 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/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +16 -4
- package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +1 -0
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +65 -3
- package/lib/esm/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +88 -10
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
- package/lib/esm/components/webchatcontainerstateful/common/utils/citationA11y.js +188 -0
- 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 +145 -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/esm/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
- 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 +3 -1
- package/lib/types/components/webchatcontainerstateful/common/utils/citationA11y.d.ts +1 -0
- 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/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.d.ts +7 -0
- package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +17 -0
- package/package.json +24 -5
|
@@ -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,
|
|
@@ -16,13 +16,22 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
16
16
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
17
|
let uiTimer;
|
|
18
18
|
const PostChatLoadingPaneStateful = props => {
|
|
19
|
-
var _props$styleProps;
|
|
19
|
+
var _props$controlProps, _props$styleProps;
|
|
20
|
+
const defaultSubtitleText = "Please take a moment to give us feedback about your chat experience. We are loading the survey for you now.";
|
|
21
|
+
const subtitleText = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.subtitleText) ?? defaultSubtitleText;
|
|
22
|
+
const [announcedSubtitleText, setAnnouncedSubtitleText] = (0, _react.useState)("");
|
|
20
23
|
(0, _react.useEffect)(() => {
|
|
21
24
|
uiTimer = (0, _utils.createTimer)();
|
|
22
25
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
23
26
|
Event: _TelemetryConstants.TelemetryEvent.UXPostChatLoadingPaneStart
|
|
24
27
|
});
|
|
25
28
|
}, []);
|
|
29
|
+
(0, _react.useEffect)(() => {
|
|
30
|
+
const timeout = window.setTimeout(() => {
|
|
31
|
+
setAnnouncedSubtitleText(subtitleText);
|
|
32
|
+
}, 0);
|
|
33
|
+
return () => window.clearTimeout(timeout);
|
|
34
|
+
}, [subtitleText]);
|
|
26
35
|
const [state] = (0, _useChatContextStore.default)();
|
|
27
36
|
const generalStyleProps = Object.assign({}, _defaultgeneralPostChatLoadingPaneStyleProps.defaultGeneralPostChatLoadingPaneStyleProps, (_props$styleProps = props.styleProps) === null || _props$styleProps === void 0 ? void 0 : _props$styleProps.generalStyleProps);
|
|
28
37
|
const styleProps = {
|
|
@@ -36,8 +45,11 @@ const PostChatLoadingPaneStateful = props => {
|
|
|
36
45
|
hideTitle: true,
|
|
37
46
|
hideSpinner: true,
|
|
38
47
|
hideSpinnerText: true,
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
...props.controlProps,
|
|
49
|
+
role: "status",
|
|
50
|
+
"aria-live": "polite",
|
|
51
|
+
"aria-atomic": "true",
|
|
52
|
+
subtitleText: announcedSubtitleText
|
|
41
53
|
};
|
|
42
54
|
|
|
43
55
|
// Move focus to the first button
|
|
@@ -67,6 +67,7 @@ const PostChatSurveyPaneStateful = props => {
|
|
|
67
67
|
};
|
|
68
68
|
const controlProps = {
|
|
69
69
|
id: "oc-lcw-postchatsurvey-pane",
|
|
70
|
+
title: "Post-chat survey",
|
|
70
71
|
surveyURL: ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.surveyURL) ?? surveyInviteLink,
|
|
71
72
|
...props.controlProps
|
|
72
73
|
};
|
|
@@ -20,6 +20,34 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
20
20
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
21
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
22
22
|
let uiTimer;
|
|
23
|
+
const getFocusedElementAnnouncement = element => {
|
|
24
|
+
var _element$textContent;
|
|
25
|
+
const ariaLabel = element.getAttribute(_Constants.HtmlAttributeNames.ariaLabel);
|
|
26
|
+
if (ariaLabel) {
|
|
27
|
+
return ariaLabel.trim();
|
|
28
|
+
}
|
|
29
|
+
const ariaLabelledBy = element.getAttribute(_Constants.HtmlAttributeNames.ariaLabelledby);
|
|
30
|
+
if (ariaLabelledBy) {
|
|
31
|
+
const labelledByText = ariaLabelledBy.split(/\s+/).map(id => {
|
|
32
|
+
var _document$getElementB, _document$getElementB2;
|
|
33
|
+
return (_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : (_document$getElementB2 = _document$getElementB.textContent) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.trim();
|
|
34
|
+
}).filter(Boolean).join(" ");
|
|
35
|
+
if (labelledByText) {
|
|
36
|
+
return labelledByText;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (element.id) {
|
|
40
|
+
const label = Array.from(document.querySelectorAll("label")).find(candidate => candidate.htmlFor === element.id || candidate.getAttribute("for") === element.id);
|
|
41
|
+
if (label !== null && label !== void 0 && label.textContent) {
|
|
42
|
+
return label.textContent.trim();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const parentLabel = element.closest("label");
|
|
46
|
+
if (parentLabel !== null && parentLabel !== void 0 && parentLabel.textContent) {
|
|
47
|
+
return parentLabel.textContent.trim();
|
|
48
|
+
}
|
|
49
|
+
return ((_element$textContent = element.textContent) === null || _element$textContent === void 0 ? void 0 : _element$textContent.trim()) ?? "";
|
|
50
|
+
};
|
|
23
51
|
|
|
24
52
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
53
|
const PreChatSurveyPaneStateful = props => {
|
|
@@ -42,6 +70,8 @@ const PreChatSurveyPaneStateful = props => {
|
|
|
42
70
|
surveyProps,
|
|
43
71
|
initStartChat
|
|
44
72
|
} = props;
|
|
73
|
+
const [preChatFocusAnnouncement, setPreChatFocusAnnouncement] = (0, _react.useState)("");
|
|
74
|
+
const liveRegionUpdateTimeout = (0, _react.useRef)();
|
|
45
75
|
const generalStyleProps = Object.assign({}, _defaultGeneralPreChatSurveyPaneStyleProps.defaultGeneralPreChatSurveyPaneStyleProps, surveyProps === null || surveyProps === void 0 ? void 0 : (_surveyProps$stylePro = surveyProps.styleProps) === null || _surveyProps$stylePro === void 0 ? void 0 : _surveyProps$stylePro.generalStyleProps, {
|
|
46
76
|
display: state.appStates.isMinimized ? "none" : ""
|
|
47
77
|
});
|
|
@@ -128,6 +158,16 @@ const PreChatSurveyPaneStateful = props => {
|
|
|
128
158
|
...(surveyProps === null || surveyProps === void 0 ? void 0 : surveyProps.styleProps),
|
|
129
159
|
generalStyleProps: generalStyleProps
|
|
130
160
|
};
|
|
161
|
+
const announceFocusedElement = event => {
|
|
162
|
+
if (liveRegionUpdateTimeout.current) {
|
|
163
|
+
window.clearTimeout(liveRegionUpdateTimeout.current);
|
|
164
|
+
}
|
|
165
|
+
const announcement = getFocusedElementAnnouncement(event.target);
|
|
166
|
+
setPreChatFocusAnnouncement("");
|
|
167
|
+
liveRegionUpdateTimeout.current = window.setTimeout(() => {
|
|
168
|
+
setPreChatFocusAnnouncement(announcement);
|
|
169
|
+
}, 0);
|
|
170
|
+
};
|
|
131
171
|
(0, _react.useEffect)(() => {
|
|
132
172
|
// Set Aria-Label Attribute for Inputs
|
|
133
173
|
const adaptiveCardElements = document.getElementsByClassName(_Constants.HtmlAttributeNames.adaptiveCardClassName);
|
|
@@ -175,10 +215,32 @@ const PreChatSurveyPaneStateful = props => {
|
|
|
175
215
|
}
|
|
176
216
|
}
|
|
177
217
|
}, [state.appStates.isMinimized]);
|
|
178
|
-
|
|
218
|
+
(0, _react.useEffect)(() => () => {
|
|
219
|
+
if (liveRegionUpdateTimeout.current) {
|
|
220
|
+
window.clearTimeout(liveRegionUpdateTimeout.current);
|
|
221
|
+
}
|
|
222
|
+
}, []);
|
|
223
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
224
|
+
onFocusCapture: announceFocusedElement
|
|
225
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
226
|
+
role: "status",
|
|
227
|
+
"aria-live": "polite",
|
|
228
|
+
"aria-atomic": "true",
|
|
229
|
+
style: {
|
|
230
|
+
position: "absolute",
|
|
231
|
+
width: "1px",
|
|
232
|
+
height: "1px",
|
|
233
|
+
margin: "-1px",
|
|
234
|
+
padding: 0,
|
|
235
|
+
border: 0,
|
|
236
|
+
clip: "rect(0, 0, 0, 0)",
|
|
237
|
+
overflow: "hidden",
|
|
238
|
+
whiteSpace: "nowrap"
|
|
239
|
+
}
|
|
240
|
+
}, preChatFocusAnnouncement), /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.PreChatSurveyPane, {
|
|
179
241
|
controlProps: controlProps,
|
|
180
242
|
styleProps: styleProps
|
|
181
|
-
});
|
|
243
|
+
}));
|
|
182
244
|
};
|
|
183
245
|
exports.PreChatSurveyPaneStateful = PreChatSurveyPaneStateful;
|
|
184
246
|
var _default = PreChatSurveyPaneStateful;
|
|
@@ -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;
|
|
@@ -31,6 +31,7 @@ var _liveChatConfigUtils = require("../livechatwidget/common/liveChatConfigUtils
|
|
|
31
31
|
var _ = require("../..");
|
|
32
32
|
var _useFacadeChatSDKStore = _interopRequireDefault(require("../../hooks/useFacadeChatSDKStore"));
|
|
33
33
|
var _usePersistentChatHistory = _interopRequireDefault(require("./hooks/usePersistentChatHistory"));
|
|
34
|
+
var _citationA11y = require("./common/utils/citationA11y");
|
|
34
35
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
36
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
36
37
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -62,7 +63,7 @@ const createMagicCodeSuccessResponse = signin => {
|
|
|
62
63
|
};
|
|
63
64
|
};
|
|
64
65
|
const WebChatContainerStateful = props => {
|
|
65
|
-
var _props$webChatContain, _defaultWebChatContai, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _props$
|
|
66
|
+
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
67
|
const [facadeChatSDK] = (0, _useFacadeChatSDKStore.default)();
|
|
67
68
|
|
|
68
69
|
// Create a font family that includes emoji support, based on the primary font or default
|
|
@@ -71,6 +72,10 @@ const WebChatContainerStateful = props => {
|
|
|
71
72
|
|
|
72
73
|
// Use iOS-optimized emoji font that prioritizes system-ui for proper emoji rendering
|
|
73
74
|
const fontFamilyWithEmojis = (0, _fontUtils.createIOSOptimizedEmojiFont)(primaryFont);
|
|
75
|
+
|
|
76
|
+
// Enforce minimum input font-size to prevent iOS Safari auto-zoom on focus
|
|
77
|
+
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;
|
|
78
|
+
const inputFontSize = parseFloat(configuredInputFontSize ?? String(_Constants.Constants.minInputFontSizePx)) < _Constants.Constants.minInputFontSizePx ? _Constants.Constants.minInputFontSize : configuredInputFontSize;
|
|
74
79
|
(0, _react2.useEffect)(() => {
|
|
75
80
|
uiTimer = (0, _utils.createTimer)();
|
|
76
81
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -151,6 +156,56 @@ const WebChatContainerStateful = props => {
|
|
|
151
156
|
document.addEventListener("click", clickHandler);
|
|
152
157
|
return () => document.removeEventListener("click", clickHandler);
|
|
153
158
|
}, [state]);
|
|
159
|
+
|
|
160
|
+
// Accessibility: Merge citation card's number badge and link text into a single
|
|
161
|
+
// focusable element. WebChat's LinkDefinitionItem renders an <a> containing a
|
|
162
|
+
// badge <div> (the number, e.g. "1") and a text <div> (the title). On iOS
|
|
163
|
+
// VoiceOver and Android TalkBack, those block-level descendants are otherwise
|
|
164
|
+
// announced as two separate focusable links. The patch sets a combined
|
|
165
|
+
// aria-label on the anchor and hides every descendant from the a11y tree so
|
|
166
|
+
// the whole card is announced as one link.
|
|
167
|
+
(0, _react2.useEffect)(() => {
|
|
168
|
+
const webChatRoot = document.getElementById("ms_lcw_webchat_root");
|
|
169
|
+
if (!webChatRoot) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
(0, _citationA11y.patchCitationAnchorsForA11y)(webChatRoot);
|
|
173
|
+
const observer = new MutationObserver(mutations => {
|
|
174
|
+
for (const m of mutations) {
|
|
175
|
+
if (m.type === "childList") {
|
|
176
|
+
m.addedNodes.forEach(node => {
|
|
177
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
178
|
+
var _parentElement, _parentElement$closes;
|
|
179
|
+
(0, _citationA11y.patchCitationAnchorsForA11y)(node);
|
|
180
|
+
// A child added inside an existing anchor (e.g. React
|
|
181
|
+
// mounting OpenInNewWindowIcon after the anchor) means
|
|
182
|
+
// the parent anchor needs to re-walk its descendants.
|
|
183
|
+
const ancestor = (_parentElement = node.parentElement) === null || _parentElement === void 0 ? void 0 : (_parentElement$closes = _parentElement.closest) === null || _parentElement$closes === void 0 ? void 0 : _parentElement$closes.call(_parentElement, "a.webchat__link-definitions__list-item-box");
|
|
184
|
+
if (ancestor) {
|
|
185
|
+
(0, _citationA11y.patchCitationAnchorsForA11y)(ancestor);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
} else if (m.type === "attributes" && m.target.nodeType === Node.ELEMENT_NODE) {
|
|
190
|
+
var _target$closest;
|
|
191
|
+
// React may strip our aria-hidden during a re-render; reapply
|
|
192
|
+
// by re-patching the closest matching anchor ancestor.
|
|
193
|
+
const target = m.target;
|
|
194
|
+
const ancestor = (_target$closest = target.closest) === null || _target$closest === void 0 ? void 0 : _target$closest.call(target, "a.webchat__link-definitions__list-item-box");
|
|
195
|
+
if (ancestor) {
|
|
196
|
+
(0, _citationA11y.patchCitationAnchorsForA11y)(ancestor);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
observer.observe(webChatRoot, {
|
|
202
|
+
childList: true,
|
|
203
|
+
subtree: true,
|
|
204
|
+
attributes: true,
|
|
205
|
+
attributeFilter: ["aria-hidden", "role", "tabindex", "inert"]
|
|
206
|
+
});
|
|
207
|
+
return () => observer.disconnect();
|
|
208
|
+
}, []);
|
|
154
209
|
const minimizedStyles = state.appStates.isMinimized ? shouldLoadPersistentHistoryMessages ? {
|
|
155
210
|
visibility: "hidden",
|
|
156
211
|
position: "absolute",
|
|
@@ -170,7 +225,7 @@ const WebChatContainerStateful = props => {
|
|
|
170
225
|
...(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.localizedTexts)
|
|
171
226
|
};
|
|
172
227
|
(0, _react2.useEffect)(() => {
|
|
173
|
-
var _props$
|
|
228
|
+
var _props$webChatContain4, _props$webChatContain5;
|
|
174
229
|
if ((0, _utils.getDeviceType)() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
|
|
175
230
|
const chatHistoryElement = document.querySelector(`.${_Constants.HtmlClassNames.webChatHistoryContainer}`);
|
|
176
231
|
if (chatHistoryElement) {
|
|
@@ -188,7 +243,7 @@ const WebChatContainerStateful = props => {
|
|
|
188
243
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
189
244
|
Event: _TelemetryConstants.TelemetryEvent.WebChatLoaded
|
|
190
245
|
});
|
|
191
|
-
if (((_props$
|
|
246
|
+
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
247
|
try {
|
|
193
248
|
localStorage;
|
|
194
249
|
sessionStorage;
|
|
@@ -203,8 +258,8 @@ const WebChatContainerStateful = props => {
|
|
|
203
258
|
}
|
|
204
259
|
}, []);
|
|
205
260
|
(0, _react2.useEffect)(() => {
|
|
206
|
-
var _props$
|
|
207
|
-
if (!((_props$
|
|
261
|
+
var _props$webChatContain6, _props$webChatContain7;
|
|
262
|
+
if (!((_props$webChatContain6 = props.webChatContainerProps) !== null && _props$webChatContain6 !== void 0 && (_props$webChatContain7 = _props$webChatContain6.botMagicCode) !== null && _props$webChatContain7 !== void 0 && _props$webChatContain7.disabled)) {
|
|
208
263
|
return;
|
|
209
264
|
}
|
|
210
265
|
if (!window.BroadcastChannel) {
|
|
@@ -302,9 +357,15 @@ const WebChatContainerStateful = props => {
|
|
|
302
357
|
${webChatContainerProps !== null && webChatContainerProps !== void 0 && (_webChatContainerProp12 = webChatContainerProps.adaptiveCardStyles) !== null && _webChatContainerProp12 !== void 0 && _webChatContainerProp12.choiceInputPadding ? `padding: ${webChatContainerProps.adaptiveCardStyles.choiceInputPadding} !important;` : ""}
|
|
303
358
|
}
|
|
304
359
|
|
|
360
|
+
div[class="ac-input-container"] input,
|
|
361
|
+
div[class="ac-input-container"] textarea,
|
|
362
|
+
div[class="ac-input-container"] select {
|
|
363
|
+
font-size: ${inputFontSize} !important;
|
|
364
|
+
}
|
|
365
|
+
|
|
305
366
|
.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$
|
|
367
|
+
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)};
|
|
368
|
+
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
369
|
}
|
|
309
370
|
|
|
310
371
|
div[class="ac-textBlock"] a:link,
|
|
@@ -389,7 +450,7 @@ const WebChatContainerStateful = props => {
|
|
|
389
450
|
}
|
|
390
451
|
|
|
391
452
|
.webchat__stacked-layout_container>div {
|
|
392
|
-
background: ${(props === null || props === void 0 ? void 0 : (_props$
|
|
453
|
+
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
454
|
}
|
|
394
455
|
.webchat__toast_text {
|
|
395
456
|
display: flex;
|
|
@@ -418,6 +479,7 @@ const WebChatContainerStateful = props => {
|
|
|
418
479
|
|
|
419
480
|
.webchat__auto-resize-textarea__textarea.webchat__send-box-text-box__html-text-area {
|
|
420
481
|
font-family: ${fontFamilyWithEmojis} !important;
|
|
482
|
+
font-size: ${inputFontSize} !important;
|
|
421
483
|
}
|
|
422
484
|
|
|
423
485
|
/* Suggested actions carousel previous/next navigation focus */
|
|
@@ -434,7 +496,23 @@ const WebChatContainerStateful = props => {
|
|
|
434
496
|
height: "100%",
|
|
435
497
|
width: "100%"
|
|
436
498
|
}
|
|
437
|
-
}, shouldLoadPersistentHistoryMessages && /*#__PURE__*/_react2.default.createElement(_WebChatEventSubscribers.default, null), /*#__PURE__*/_react2.default.createElement(BasicWebChat, null))),
|
|
499
|
+
}, shouldLoadPersistentHistoryMessages && /*#__PURE__*/_react2.default.createElement(_WebChatEventSubscribers.default, null), /*#__PURE__*/_react2.default.createElement(BasicWebChat, null))), /*#__PURE__*/_react2.default.createElement("div", {
|
|
500
|
+
id: _Constants.HtmlIdNames.fileSentAnnouncementRegionId,
|
|
501
|
+
role: "alert",
|
|
502
|
+
"aria-live": "assertive",
|
|
503
|
+
"aria-atomic": "true",
|
|
504
|
+
style: {
|
|
505
|
+
position: "absolute",
|
|
506
|
+
width: "1px",
|
|
507
|
+
height: "1px",
|
|
508
|
+
padding: "0",
|
|
509
|
+
margin: "-1px",
|
|
510
|
+
overflow: "hidden",
|
|
511
|
+
clip: "rect(0, 0, 0, 0)",
|
|
512
|
+
whiteSpace: "nowrap",
|
|
513
|
+
border: "0"
|
|
514
|
+
}
|
|
515
|
+
}), citationPaneOpen && /*#__PURE__*/_react2.default.createElement(_CitationPaneStateful.default, {
|
|
438
516
|
id: ((_props$citationPanePr = props.citationPaneProps) === null || _props$citationPanePr === void 0 ? void 0 : _props$citationPanePr.id) || _Constants.HtmlAttributeNames.ocwCitationPaneClassName,
|
|
439
517
|
title: ((_props$citationPanePr2 = props.citationPaneProps) === null || _props$citationPanePr2 === void 0 ? void 0 : _props$citationPanePr2.title) || _Constants.HtmlAttributeNames.ocwCitationPaneTitle,
|
|
440
518
|
contentHtml: citationPaneText,
|
|
@@ -33,8 +33,11 @@ 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.",
|
|
39
|
+
MIDDLEWARE_SR_PREFIX_SUCCESS: "Success. ",
|
|
40
|
+
MIDDLEWARE_SR_PREFIX_ERROR: "Error. ",
|
|
38
41
|
PREVIOUS_MESSAGES_LOADING: "Loading previous messages...",
|
|
39
42
|
CONVERSATION_DIVIDER_ARIA_LABEL: "Conversation history divider"
|
|
40
43
|
};
|
|
@@ -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;
|