@cognigy/webchat 3.52.0 → 3.53.0
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/OSS_LICENSES.txt +4 -4
- package/dist/webchat.esm.js +1186 -353
- package/dist/webchat.js +34 -34
- package/package.json +2 -2
package/dist/webchat.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* webchat.esm.js v3.
|
|
3
|
-
* https://github.com/Cognigy/Webchat/tree/v3.
|
|
4
|
-
* https://github.com/Cognigy/Webchat/tree/v3.
|
|
2
|
+
* webchat.esm.js v3.53.0
|
|
3
|
+
* https://github.com/Cognigy/Webchat/tree/v3.53.0
|
|
4
|
+
* https://github.com/Cognigy/Webchat/tree/v3.53.0/OSS_LICENSES.txt
|
|
5
5
|
*/
|
|
6
6
|
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
|
|
7
7
|
import * as __WEBPACK_EXTERNAL_MODULE_react_dom_7dac9eee__ from "react-dom";
|
|
@@ -589,6 +589,89 @@ var SvgMinimize16Px = function SvgMinimize16Px(_ref) {
|
|
|
589
589
|
|
|
590
590
|
/***/ },
|
|
591
591
|
|
|
592
|
+
/***/ 21909
|
|
593
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
594
|
+
|
|
595
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
596
|
+
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
597
|
+
/* harmony export */ });
|
|
598
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
|
|
599
|
+
var _rect, _rect2;
|
|
600
|
+
var _excluded = ["title", "titleId"];
|
|
601
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
602
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
603
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
604
|
+
|
|
605
|
+
var SvgPause16Px = function SvgPause16Px(_ref) {
|
|
606
|
+
var title = _ref.title,
|
|
607
|
+
titleId = _ref.titleId,
|
|
608
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
609
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", _extends({
|
|
610
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
611
|
+
width: 16,
|
|
612
|
+
height: 16,
|
|
613
|
+
fill: "none",
|
|
614
|
+
"aria-hidden": "true",
|
|
615
|
+
viewBox: "0 0 16 16",
|
|
616
|
+
"aria-labelledby": titleId
|
|
617
|
+
}, props), title ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("title", {
|
|
618
|
+
id: titleId
|
|
619
|
+
}, title) : null, _rect || (_rect = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
|
|
620
|
+
width: 4,
|
|
621
|
+
height: 12,
|
|
622
|
+
x: 3,
|
|
623
|
+
y: 2,
|
|
624
|
+
fill: "currentColor",
|
|
625
|
+
rx: 1
|
|
626
|
+
})), _rect2 || (_rect2 = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
|
|
627
|
+
width: 4,
|
|
628
|
+
height: 12,
|
|
629
|
+
x: 9,
|
|
630
|
+
y: 2,
|
|
631
|
+
fill: "currentColor",
|
|
632
|
+
rx: 1
|
|
633
|
+
})));
|
|
634
|
+
};
|
|
635
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SvgPause16Px);
|
|
636
|
+
|
|
637
|
+
/***/ },
|
|
638
|
+
|
|
639
|
+
/***/ 6663
|
|
640
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
641
|
+
|
|
642
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
643
|
+
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
644
|
+
/* harmony export */ });
|
|
645
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
|
|
646
|
+
var _path;
|
|
647
|
+
var _excluded = ["title", "titleId"];
|
|
648
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
649
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
650
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
651
|
+
|
|
652
|
+
var SvgPlay16Px = function SvgPlay16Px(_ref) {
|
|
653
|
+
var title = _ref.title,
|
|
654
|
+
titleId = _ref.titleId,
|
|
655
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
656
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", _extends({
|
|
657
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
658
|
+
width: 16,
|
|
659
|
+
height: 16,
|
|
660
|
+
fill: "none",
|
|
661
|
+
"aria-hidden": "true",
|
|
662
|
+
viewBox: "0 0 16 16",
|
|
663
|
+
"aria-labelledby": titleId
|
|
664
|
+
}, props), title ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("title", {
|
|
665
|
+
id: titleId
|
|
666
|
+
}, title) : null, _path || (_path = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
|
|
667
|
+
fill: "currentColor",
|
|
668
|
+
d: "M5.5 2.6a1 1 0 0 0-1.5.86v9.08a1 1 0 0 0 1.5.86l7.6-4.54a1 1 0 0 0 0-1.72z"
|
|
669
|
+
})));
|
|
670
|
+
};
|
|
671
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SvgPlay16Px);
|
|
672
|
+
|
|
673
|
+
/***/ },
|
|
674
|
+
|
|
592
675
|
/***/ 34967
|
|
593
676
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
594
677
|
|
|
@@ -35116,6 +35199,33 @@ if (!g.fetch) {
|
|
|
35116
35199
|
|
|
35117
35200
|
/***/ },
|
|
35118
35201
|
|
|
35202
|
+
/***/ 36886
|
|
35203
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
35204
|
+
|
|
35205
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
35206
|
+
/* harmony export */ Z: () => (/* binding */ ALWAYS_BLOCKED_TAGS)
|
|
35207
|
+
/* harmony export */ });
|
|
35208
|
+
// Hard deny-list for HTML tags that must never be permitted via customAllowedHtmlTags,
|
|
35209
|
+
// regardless of tenant configuration. Each tag enables a distinct attack vector:
|
|
35210
|
+
// applet — Java applet execution
|
|
35211
|
+
// base — rewrites all relative URLs on the host page
|
|
35212
|
+
// body / html / head — structural document elements; no legitimate use in sanitised fragments
|
|
35213
|
+
// embed — loads arbitrary external content / plugins
|
|
35214
|
+
// form — posts user data to attacker-controlled URLs
|
|
35215
|
+
// frame / frameset / noframes — clickjacking and legacy frame injection
|
|
35216
|
+
// iframe — inline HTML documents; srcdoc = direct XSS vector
|
|
35217
|
+
// link — loads external stylesheets
|
|
35218
|
+
// meta — HTTP redirects and CSP bypass via http-equiv
|
|
35219
|
+
// object — loads Flash, PDFs, and arbitrary external content
|
|
35220
|
+
// style — CSS injection and attribute-value exfiltration
|
|
35221
|
+
//
|
|
35222
|
+
// This file has no imports so it can be consumed by both sanitize.ts (which imports
|
|
35223
|
+
// the Redux store) and config-reducer.ts (which the store imports) without creating
|
|
35224
|
+
// a circular dependency between them.
|
|
35225
|
+
const ALWAYS_BLOCKED_TAGS = new Set(["script", "iframe", "object", "embed", "applet", "frame", "frameset", "noframes", "meta", "base", "link", "style", "form", "body", "html", "head"]);
|
|
35226
|
+
|
|
35227
|
+
/***/ },
|
|
35228
|
+
|
|
35119
35229
|
/***/ 30871
|
|
35120
35230
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
35121
35231
|
|
|
@@ -35765,35 +35875,38 @@ const Modal = ({
|
|
|
35765
35875
|
/* harmony import */ var _webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(44557);
|
|
35766
35876
|
/* harmony import */ var _webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(31067);
|
|
35767
35877
|
/* harmony import */ var _presentational_FABDisabled__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(99526);
|
|
35768
|
-
/* harmony import */ var
|
|
35769
|
-
/* harmony import */ var
|
|
35770
|
-
/* harmony import */ var
|
|
35771
|
-
/* harmony import */ var
|
|
35772
|
-
/* harmony import */ var
|
|
35773
|
-
/* harmony import */ var
|
|
35774
|
-
/* harmony import */ var
|
|
35775
|
-
/* harmony import */ var
|
|
35776
|
-
/* harmony import */ var
|
|
35777
|
-
/* harmony import */ var
|
|
35778
|
-
/* harmony import */ var
|
|
35779
|
-
/* harmony import */ var
|
|
35780
|
-
/* harmony import */ var
|
|
35781
|
-
/* harmony import */ var
|
|
35782
|
-
/* harmony import */ var
|
|
35783
|
-
/* harmony import */ var
|
|
35784
|
-
/* harmony import */ var
|
|
35785
|
-
/* harmony import */ var
|
|
35786
|
-
/* harmony import */ var
|
|
35787
|
-
/* harmony import */ var
|
|
35788
|
-
/* harmony import */ var
|
|
35789
|
-
/* harmony import */ var
|
|
35790
|
-
/* harmony import */ var
|
|
35791
|
-
/* harmony import */ var
|
|
35792
|
-
/* harmony import */ var
|
|
35793
|
-
/* harmony import */ var
|
|
35794
|
-
/* harmony import */ var
|
|
35795
|
-
/* harmony import */ var
|
|
35796
|
-
/* harmony import */ var
|
|
35878
|
+
/* harmony import */ var _presentational_IconAnimationPauseButton__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(71374);
|
|
35879
|
+
/* harmony import */ var _webchat_helper_storage__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(62473);
|
|
35880
|
+
/* harmony import */ var _webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(69401);
|
|
35881
|
+
/* harmony import */ var _presentational_HomeScreen__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(42740);
|
|
35882
|
+
/* harmony import */ var _presentational_previous_conversations_ConversationsList__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(14704);
|
|
35883
|
+
/* harmony import */ var _cognigy_chat_components__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(2854);
|
|
35884
|
+
/* harmony import */ var _presentational_previous_conversations_helpers__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(21013);
|
|
35885
|
+
/* harmony import */ var _presentational_InformationMessage__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(25850);
|
|
35886
|
+
/* harmony import */ var _presentational_PrivacyNotice__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(9981);
|
|
35887
|
+
/* harmony import */ var _presentational_chat_options_ChatOptions__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(49687);
|
|
35888
|
+
/* harmony import */ var _history_QueueUpdates__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(59021);
|
|
35889
|
+
/* harmony import */ var _plugins_input_file_DropZone__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(1339);
|
|
35890
|
+
/* harmony import */ var react_transition_group__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(66492);
|
|
35891
|
+
/* harmony import */ var _presentational_TeaserMessage__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(49888);
|
|
35892
|
+
/* harmony import */ var _presentational_TeaserMessageAnnouncer__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(59359);
|
|
35893
|
+
/* harmony import */ var _presentational_UnreadMessagesAnnouncer__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(1715);
|
|
35894
|
+
/* harmony import */ var _functional_xapp_overlay_XAppOverlay__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(12381);
|
|
35895
|
+
/* harmony import */ var _utils_sourceMapping__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(25091);
|
|
35896
|
+
/* harmony import */ var _plugins_speech_output__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(83679);
|
|
35897
|
+
/* harmony import */ var _utils_filter_out_control_commands__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(70562);
|
|
35898
|
+
/* harmony import */ var _utils_isMobile__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(40794);
|
|
35899
|
+
/* harmony import */ var _webchat_helper_handleMarkdown__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(71621);
|
|
35900
|
+
/* harmony import */ var _presentational_previous_conversations_DeleteAllConversations__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(5196);
|
|
35901
|
+
/* harmony import */ var _presentational_ScreenReaderLiveRegion__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(41426);
|
|
35902
|
+
/* harmony import */ var _presentational_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(63813);
|
|
35903
|
+
/* harmony import */ var _presentational_FreezeOnExit__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(97475);
|
|
35904
|
+
/* harmony import */ var _presentational_HomeScreenAnnouncer__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(55115);
|
|
35905
|
+
/* harmony import */ var _presentational_FileUploadAnnouncer__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(32735);
|
|
35906
|
+
/* harmony import */ var _utils_ai_agent_notice__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(39191);
|
|
35907
|
+
/* harmony import */ var _utils_screen_visibility__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(48245);
|
|
35908
|
+
/* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(14176);
|
|
35909
|
+
/* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_61___default = /*#__PURE__*/__webpack_require__.n(classnames__WEBPACK_IMPORTED_MODULE_61__);
|
|
35797
35910
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
35798
35911
|
|
|
35799
35912
|
|
|
@@ -35850,11 +35963,18 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
|
|
|
35850
35963
|
|
|
35851
35964
|
|
|
35852
35965
|
|
|
35966
|
+
|
|
35967
|
+
|
|
35968
|
+
|
|
35853
35969
|
|
|
35854
35970
|
|
|
35855
35971
|
|
|
35856
35972
|
|
|
35857
35973
|
const stylisPlugins = [(0,_utils_css__WEBPACK_IMPORTED_MODULE_8__/* .isolate */ .az)("[data-cognigy-webchat-root]")];
|
|
35974
|
+
const ICON_ANIMATION_PAUSED_STORAGE_KEY = "cognigy-webchat-icon-animation-paused";
|
|
35975
|
+
|
|
35976
|
+
/** `layout.iconAnimation` names an animation ("bounce" | "pulse" | "swing"). */
|
|
35977
|
+
const isIconAnimationConfigured = animation => typeof animation === "string" && animation.trim().length > 0 && animation !== "none";
|
|
35858
35978
|
|
|
35859
35979
|
/**
|
|
35860
35980
|
* for RTL-layout websites, use the stylis-rtl plugin to convert CSS,
|
|
@@ -35870,7 +35990,7 @@ const styleCache = (0,_emotion_cache__WEBPACK_IMPORTED_MODULE_7__/* ["default"]
|
|
|
35870
35990
|
key: "cognigy-webchat",
|
|
35871
35991
|
stylisPlugins
|
|
35872
35992
|
});
|
|
35873
|
-
const TopStatusMessage = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(
|
|
35993
|
+
const TopStatusMessage = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_36__/* .Typography */ .o5)(({
|
|
35874
35994
|
theme
|
|
35875
35995
|
}) => ({
|
|
35876
35996
|
display: "block",
|
|
@@ -35954,9 +36074,10 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
35954
36074
|
timedOut: false,
|
|
35955
36075
|
showDeleteAllConversationsModal: false,
|
|
35956
36076
|
deleteConversationsModalState: false,
|
|
36077
|
+
isIconAnimationPaused: false,
|
|
35957
36078
|
liveContent: {},
|
|
35958
36079
|
isMobile: false,
|
|
35959
|
-
noticeSession:
|
|
36080
|
+
noticeSession: _utils_ai_agent_notice__WEBPACK_IMPORTED_MODULE_59__/* .INITIAL_NOTICE_SESSION */ .j_
|
|
35960
36081
|
};
|
|
35961
36082
|
unreadTitleIndicatorInterval = null;
|
|
35962
36083
|
originalTitle = window.document.title;
|
|
@@ -35966,6 +36087,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
35966
36087
|
visibilityCheckCompleted = false;
|
|
35967
36088
|
engagementMessageTimeout = null;
|
|
35968
36089
|
ratingFocusTimeout = null;
|
|
36090
|
+
deleteAllFocusTimeout = null;
|
|
35969
36091
|
homeScreenExitFocusTimeout = null;
|
|
35970
36092
|
xAppOverlayCloseFocusTimeout = null;
|
|
35971
36093
|
|
|
@@ -35993,6 +36115,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
35993
36115
|
this.closeButtonInHeaderRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
35994
36116
|
this.menuButtonInHeaderRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
35995
36117
|
this.deleteButtonInHeaderRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
36118
|
+
this.emptyPrevConversationsTextRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
35996
36119
|
this.startNewConversationButtonRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
35997
36120
|
this.ratingButtonInHeaderRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
35998
36121
|
this.webchatWindowRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
@@ -36005,9 +36128,9 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36005
36128
|
const secondaryColor = props?.config?.settings?.colors?.secondaryColor;
|
|
36006
36129
|
const chatInterfaceColor = props?.config?.settings?.colors?.chatInterfaceColor;
|
|
36007
36130
|
const sourceColorMapping = props?.config?.settings?.widgetSettings?.sourceColorMapping;
|
|
36008
|
-
const overrideBotMessageColor = (0,
|
|
36009
|
-
const overrideUserMessageColor = (0,
|
|
36010
|
-
const overrideAgentMessageColor = (0,
|
|
36131
|
+
const overrideBotMessageColor = (0,_utils_sourceMapping__WEBPACK_IMPORTED_MODULE_48__/* .getSourceBackgroundColor */ .N)(sourceColorMapping?.bot, props?.config?.settings?.colors);
|
|
36132
|
+
const overrideUserMessageColor = (0,_utils_sourceMapping__WEBPACK_IMPORTED_MODULE_48__/* .getSourceBackgroundColor */ .N)(sourceColorMapping?.user, props?.config?.settings?.colors);
|
|
36133
|
+
const overrideAgentMessageColor = (0,_utils_sourceMapping__WEBPACK_IMPORTED_MODULE_48__/* .getSourceBackgroundColor */ .N)(sourceColorMapping?.agent, props?.config?.settings?.colors);
|
|
36011
36134
|
const overrideBotMessageBorderColor = sourceColorMapping?.bot === "user" ? "transparent" : null;
|
|
36012
36135
|
const overrideUserMessageBorderColor = sourceColorMapping?.user === "bot" ? state.theme.black80 : null;
|
|
36013
36136
|
const overrideAgentMessageBorderColor = sourceColorMapping?.agent === "user" ? "transparent" : null;
|
|
@@ -36101,7 +36224,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36101
36224
|
}
|
|
36102
36225
|
}
|
|
36103
36226
|
}
|
|
36104
|
-
this.hideNotifications = (0,
|
|
36227
|
+
this.hideNotifications = (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isDisabledDueToConnectivity */ .l9)(this.props.config.settings, timeoutReached) || (0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isDisabledDueToMaintenance */ .$6)(this.props.config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isDisabledOutOfBusinessHours */ .dt)(this.props.config.settings.businessHours) || (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isInformingDueToConnectivity */ .u0)(this.props.config.settings, timeoutReached) || (0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isInformingDueToMaintenance */ .iF)(this.props.config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isInformingOutOfBusinessHours */ .Gr)(this.props.config.settings.businessHours) || (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isHiddenDueToConnectivity */ .VD)(this.props.config.settings, timeoutReached) || (0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isHiddenDueToMaintenance */ .Hs)(this.props.config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isHiddenOutOfBusinessHours */ .hN)(this.props.config.settings.businessHours) || false;
|
|
36105
36228
|
};
|
|
36106
36229
|
|
|
36107
36230
|
// `prevConversationsSnapshot` must predate the session change — see
|
|
@@ -36111,14 +36234,14 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36111
36234
|
evaluateNoticeSession(prevConversationsSnapshot) {
|
|
36112
36235
|
const id = this.props.currentSession || "";
|
|
36113
36236
|
this.setState(prev => ({
|
|
36114
|
-
noticeSession: (0,
|
|
36237
|
+
noticeSession: (0,_utils_ai_agent_notice__WEBPACK_IMPORTED_MODULE_59__/* .computeNoticeSession */ .Kr)(prev.noticeSession, id, prevConversationsSnapshot, this.props.hasRestoredPersistedHistory, this.props.willRestorePersistedConversation)
|
|
36115
36238
|
}));
|
|
36116
36239
|
}
|
|
36117
36240
|
handleNoticeIntroAnnounced = introKey => {
|
|
36118
36241
|
this.announcedNoticeKeys.add(introKey);
|
|
36119
36242
|
};
|
|
36120
36243
|
getNoticeIntro() {
|
|
36121
|
-
const text = (0,
|
|
36244
|
+
const text = (0,_utils_ai_agent_notice__WEBPACK_IMPORTED_MODULE_59__/* .getAIAgentNoticeIntroText */ .bu)({
|
|
36122
36245
|
behavior: this.props.config.settings.behavior,
|
|
36123
36246
|
showDisconnectOverlay: this.showDisconnectOverlay,
|
|
36124
36247
|
noticeSession: this.state.noticeSession,
|
|
@@ -36134,14 +36257,17 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36134
36257
|
componentDidMount() {
|
|
36135
36258
|
const defaultMessagePlugins = [];
|
|
36136
36259
|
if (this.props.ttsActive) {
|
|
36137
|
-
defaultMessagePlugins.push(
|
|
36260
|
+
defaultMessagePlugins.push(_plugins_speech_output__WEBPACK_IMPORTED_MODULE_49__/* ["default"] */ .A);
|
|
36138
36261
|
}
|
|
36139
36262
|
this.setState({
|
|
36140
36263
|
inputPlugins: [...(this.props.inputPlugins || []), _plugins_input_base__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .A],
|
|
36141
36264
|
messagePlugins: [...(this.props.messagePlugins || []), ...defaultMessagePlugins],
|
|
36142
|
-
isMobile: (0,
|
|
36265
|
+
isMobile: (0,_utils_isMobile__WEBPACK_IMPORTED_MODULE_51__/* .isMobileViewport */ .$)(),
|
|
36266
|
+
isIconAnimationPaused: this.readIconAnimationPaused()
|
|
36143
36267
|
});
|
|
36144
|
-
|
|
36268
|
+
// After the state above is committed: the interval is only started
|
|
36269
|
+
// when the animation is not paused.
|
|
36270
|
+
this.setState({}, () => this.setupIconAnimationInterval());
|
|
36145
36271
|
|
|
36146
36272
|
// No pre-change snapshot exists on mount; the current map predates
|
|
36147
36273
|
// any message activity of this page load.
|
|
@@ -36257,7 +36383,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36257
36383
|
if (prevProps.ttsActive !== this.props.ttsActive || prevProps.inputPlugins !== this.props.inputPlugins || prevProps.messagePlugins !== this.props.messagePlugins) {
|
|
36258
36384
|
const defaultMessagePlugins = [];
|
|
36259
36385
|
if (this.props.ttsActive) {
|
|
36260
|
-
defaultMessagePlugins.push(
|
|
36386
|
+
defaultMessagePlugins.push(_plugins_speech_output__WEBPACK_IMPORTED_MODULE_49__/* ["default"] */ .A);
|
|
36261
36387
|
}
|
|
36262
36388
|
this.setState({
|
|
36263
36389
|
inputPlugins: [...(this.props.inputPlugins || []), _plugins_input_base__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .A],
|
|
@@ -36307,7 +36433,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36307
36433
|
// TODO: Add markdown rendering if there is valid markdown and renderMarkdown is enabled
|
|
36308
36434
|
// adding react-markdown is blocked by updating React to v18
|
|
36309
36435
|
if (!this.props.config.settings.widgetSettings.disableTeaserMarkdownRemoval) {
|
|
36310
|
-
lastUnseenMessageText = (0,
|
|
36436
|
+
lastUnseenMessageText = (0,_webchat_helper_handleMarkdown__WEBPACK_IMPORTED_MODULE_52__/* .removeMarkdownChars */ .$)(lastUnseenMessageText);
|
|
36311
36437
|
}
|
|
36312
36438
|
this.setState({
|
|
36313
36439
|
lastUnseenMessageText
|
|
@@ -36326,7 +36452,10 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36326
36452
|
}
|
|
36327
36453
|
|
|
36328
36454
|
// Re-evaluate icon animation interval when related settings change
|
|
36329
|
-
if (prevProps?.config?.settings?.layout?.iconAnimationInterval !== this.props?.config?.settings?.layout?.iconAnimationInterval || prevProps?.config?.settings?.layout?.iconAnimationSpeed !== this.props?.config?.settings?.layout?.iconAnimationSpeed || prevProps?.config?.settings?.layout?.iconAnimation !== this.props?.config?.settings?.layout?.iconAnimation
|
|
36455
|
+
if (prevProps?.config?.settings?.layout?.iconAnimationInterval !== this.props?.config?.settings?.layout?.iconAnimationInterval || prevProps?.config?.settings?.layout?.iconAnimationSpeed !== this.props?.config?.settings?.layout?.iconAnimationSpeed || prevProps?.config?.settings?.layout?.iconAnimation !== this.props?.config?.settings?.layout?.iconAnimation ||
|
|
36456
|
+
// A persisted pause only counts while the control is offered, so
|
|
36457
|
+
// toggling the opt-in must restart (or stop) the timer as well
|
|
36458
|
+
prevProps?.config?.settings?.layout?.enableIconAnimationPauseButton !== this.props?.config?.settings?.layout?.enableIconAnimationPauseButton) {
|
|
36330
36459
|
this.setupIconAnimationInterval();
|
|
36331
36460
|
}
|
|
36332
36461
|
if (!this.hideNotifications) {
|
|
@@ -36364,6 +36493,10 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36364
36493
|
clearTimeout(this.ratingFocusTimeout);
|
|
36365
36494
|
this.ratingFocusTimeout = null;
|
|
36366
36495
|
}
|
|
36496
|
+
if (this.deleteAllFocusTimeout) {
|
|
36497
|
+
clearTimeout(this.deleteAllFocusTimeout);
|
|
36498
|
+
this.deleteAllFocusTimeout = null;
|
|
36499
|
+
}
|
|
36367
36500
|
|
|
36368
36501
|
// also removes the fallback's document pointerdown listener
|
|
36369
36502
|
this.cancelHomeScreenExitFocusFallback();
|
|
@@ -36380,7 +36513,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36380
36513
|
window.removeEventListener("resize", this.handleResize);
|
|
36381
36514
|
}
|
|
36382
36515
|
handleResize() {
|
|
36383
|
-
const isMobile = (0,
|
|
36516
|
+
const isMobile = (0,_utils_isMobile__WEBPACK_IMPORTED_MODULE_51__/* .isMobileViewport */ .$)();
|
|
36384
36517
|
if (isMobile !== this.state.isMobile) {
|
|
36385
36518
|
this.setState({
|
|
36386
36519
|
isMobile
|
|
@@ -36393,9 +36526,15 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36393
36526
|
clearInterval(this.iconAnimationIntervalHandle);
|
|
36394
36527
|
this.iconAnimationIntervalHandle = null;
|
|
36395
36528
|
}
|
|
36396
|
-
|
|
36397
|
-
|
|
36398
|
-
|
|
36529
|
+
// No timer without an animation
|
|
36530
|
+
if (!isIconAnimationConfigured(this.props?.config?.settings?.layout?.iconAnimation)) {
|
|
36531
|
+
return;
|
|
36532
|
+
}
|
|
36533
|
+
// … nor while the user has paused it (handleToggleIconAnimationPause and
|
|
36534
|
+
// componentDidUpdate re-run this on every change). A burst that is
|
|
36535
|
+
// playing right now is cut short instead of finishing.
|
|
36536
|
+
if (this.isIconAnimationPaused()) {
|
|
36537
|
+
this.chatToggleButtonRef?.current?.querySelector(".iconAnimationContainer")?.classList.remove("optionActive");
|
|
36399
36538
|
return;
|
|
36400
36539
|
}
|
|
36401
36540
|
const intervalSec = this.props.config?.settings?.layout?.iconAnimationInterval ?? 5;
|
|
@@ -36413,6 +36552,47 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36413
36552
|
}, intervalMs);
|
|
36414
36553
|
}
|
|
36415
36554
|
|
|
36555
|
+
/**
|
|
36556
|
+
* Pause / resume of the launcher icon animation (WCAG 2.2.2 — CGY-39786).
|
|
36557
|
+
* The choice is kept in the configured browser storage so it survives a
|
|
36558
|
+
* reload; with `disableLocalStorage` it lasts for the page lifetime only.
|
|
36559
|
+
*/
|
|
36560
|
+
readIconAnimationPaused() {
|
|
36561
|
+
try {
|
|
36562
|
+
const storage = (0,_webchat_helper_storage__WEBPACK_IMPORTED_MODULE_32__/* .getStorage */ .c)(this.props.config.settings.embeddingConfiguration);
|
|
36563
|
+
return storage?.getItem(ICON_ANIMATION_PAUSED_STORAGE_KEY) === "true";
|
|
36564
|
+
} catch {
|
|
36565
|
+
return false;
|
|
36566
|
+
}
|
|
36567
|
+
}
|
|
36568
|
+
persistIconAnimationPaused(paused) {
|
|
36569
|
+
try {
|
|
36570
|
+
const storage = (0,_webchat_helper_storage__WEBPACK_IMPORTED_MODULE_32__/* .getStorage */ .c)(this.props.config.settings.embeddingConfiguration);
|
|
36571
|
+
storage?.setItem(ICON_ANIMATION_PAUSED_STORAGE_KEY, String(paused));
|
|
36572
|
+
} catch {
|
|
36573
|
+
// Storage may be unavailable (restricted environments) — the state
|
|
36574
|
+
// still applies for this page load.
|
|
36575
|
+
}
|
|
36576
|
+
}
|
|
36577
|
+
|
|
36578
|
+
/**
|
|
36579
|
+
* A stored pause is only honored while the pause button is offered
|
|
36580
|
+
* (`layout.enableIconAnimationPauseButton`). Otherwise a value persisted
|
|
36581
|
+
* earlier, or a later `updateSettings()` that switches the opt-in off,
|
|
36582
|
+
* would leave the animation stopped with no control to resume it.
|
|
36583
|
+
*/
|
|
36584
|
+
isIconAnimationPaused() {
|
|
36585
|
+
return !!this.props.config?.settings?.layout?.enableIconAnimationPauseButton && this.state.isIconAnimationPaused;
|
|
36586
|
+
}
|
|
36587
|
+
handleToggleIconAnimationPause = () => {
|
|
36588
|
+
const paused = !this.state.isIconAnimationPaused;
|
|
36589
|
+
// Stops (or restarts) the interval itself once the state is committed
|
|
36590
|
+
this.setState({
|
|
36591
|
+
isIconAnimationPaused: paused
|
|
36592
|
+
}, () => this.setupIconAnimationInterval());
|
|
36593
|
+
this.persistIconAnimationPaused(paused);
|
|
36594
|
+
};
|
|
36595
|
+
|
|
36416
36596
|
/**
|
|
36417
36597
|
* This triggers the engagement message in case the webchat
|
|
36418
36598
|
* was not yet open and the history is empty
|
|
@@ -36467,7 +36647,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36467
36647
|
const {
|
|
36468
36648
|
messages
|
|
36469
36649
|
} = this.props;
|
|
36470
|
-
if ((0,
|
|
36650
|
+
if ((0,_presentational_previous_conversations_helpers__WEBPACK_IMPORTED_MODULE_37__/* .isConversationEnded */ .GP)(messages)) return null;
|
|
36471
36651
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_plugins_InputPluginRenderer__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .A, {
|
|
36472
36652
|
plugins: inputPlugins,
|
|
36473
36653
|
messages: this.props.messages,
|
|
@@ -36784,16 +36964,21 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36784
36964
|
disableMobileScrollLock
|
|
36785
36965
|
}
|
|
36786
36966
|
} = config.settings;
|
|
36787
|
-
if (!config.active && !config.settings.embeddingConfiguration.connectivity.enabled || !config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig || config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig && ((0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isHiddenOutOfBusinessHours */ .hN)(config.settings.businessHours) || (0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isHiddenDueToMaintenance */ .Hs)(config.settings) || (0,
|
|
36788
|
-
const isDisabled = config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig && ((0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isDisabledDueToMaintenance */ .$6)(config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isDisabledOutOfBusinessHours */ .dt)(config.settings.businessHours) || (0,
|
|
36789
|
-
|
|
36967
|
+
if (!config.active && !config.settings.embeddingConfiguration.connectivity.enabled || !config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig || config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig && ((0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isHiddenOutOfBusinessHours */ .hN)(config.settings.businessHours) || (0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isHiddenDueToMaintenance */ .Hs)(config.settings) || (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isHiddenDueToConnectivity */ .VD)(config.settings, state.timedOut))) return null;
|
|
36968
|
+
const isDisabled = config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig && ((0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isDisabledDueToMaintenance */ .$6)(config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isDisabledOutOfBusinessHours */ .dt)(config.settings.businessHours) || (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isDisabledDueToConnectivity */ .l9)(config.settings, state.timedOut));
|
|
36969
|
+
|
|
36970
|
+
// Opt-in pause control (layout.enableIconAnimationPauseButton), shown only
|
|
36971
|
+
// while the animation can play: chat closed, launcher enabled and an
|
|
36972
|
+
// animation configured (WCAG 2.2.2 — CGY-39786).
|
|
36973
|
+
const showIconAnimationPauseButton = !open && !isDisabled && !!config.settings?.layout?.enableIconAnimationPauseButton && isIconAnimationConfigured(config.settings?.layout?.iconAnimation);
|
|
36974
|
+
const isInforming = config.isConfigLoaded && config.settings.embeddingConfiguration.awaitEndpointConfig && ((0,_webchat_helper_maintenance__WEBPACK_IMPORTED_MODULE_29__/* .isInformingDueToMaintenance */ .iF)(config.settings) || (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isInformingOutOfBusinessHours */ .Gr)(config.settings.businessHours) || (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isInformingDueToConnectivity */ .u0)(config.settings, state.timedOut));
|
|
36790
36975
|
const showDisconnectOverlay = this.showDisconnectOverlay;
|
|
36791
36976
|
|
|
36792
36977
|
// Drives the home-screen announcer below; the announcer mounts only
|
|
36793
36978
|
// while the webchat is open, so no `open` check is needed here.
|
|
36794
36979
|
const {
|
|
36795
36980
|
showHomeScreenView
|
|
36796
|
-
} = (0,
|
|
36981
|
+
} = (0,_utils_screen_visibility__WEBPACK_IMPORTED_MODULE_60__/* .getScreenVisibility */ .p)(this.props, isInforming);
|
|
36797
36982
|
const openChatAriaLabel = () => {
|
|
36798
36983
|
if (open) return config.settings.customTranslations?.ariaLabels?.closeChat ?? "Close chat";
|
|
36799
36984
|
const openChat = config.settings.customTranslations?.ariaLabels?.openChat ?? "Open chat";
|
|
@@ -36813,7 +36998,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36813
36998
|
return this.props.config.settings.maintenance.text || "This chat is currently disabled due to maintenance";
|
|
36814
36999
|
} else if (isDisabled && (0,_webchat_helper_businessHours__WEBPACK_IMPORTED_MODULE_28__/* .isDisabledOutOfBusinessHours */ .dt)(this.props.config.settings.businessHours)) {
|
|
36815
37000
|
return this.props.config.settings.maintenance.text || "This chat is disabled out of our business hours";
|
|
36816
|
-
} else if (isDisabled && (0,
|
|
37001
|
+
} else if (isDisabled && (0,_webchat_helper_connectivity__WEBPACK_IMPORTED_MODULE_33__/* .isDisabledDueToConnectivity */ .l9)(this.props.config.settings, this.state.timedOut)) {
|
|
36817
37002
|
return this.props.config.settings.embeddingConfiguration.connectivity.text || "This chat is disabled due to connectivity issues";
|
|
36818
37003
|
}
|
|
36819
37004
|
};
|
|
@@ -36868,28 +37053,28 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36868
37053
|
el.removeAttribute("inert");
|
|
36869
37054
|
}
|
|
36870
37055
|
}
|
|
36871
|
-
}, !fullscreenMessage ? this.renderRegularLayout(isInforming) : this.renderFullscreenMessageLayout()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37056
|
+
}, !fullscreenMessage ? this.renderRegularLayout(isInforming) : this.renderFullscreenMessageLayout()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_55__/* .StatusLiveRegion */ .t, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_HomeScreenAnnouncer__WEBPACK_IMPORTED_MODULE_57__/* ["default"] */ .A, {
|
|
36872
37057
|
active: showHomeScreenView,
|
|
36873
37058
|
label: config.settings.customTranslations?.ariaLabels?.homeScreen ?? "Chat window home screen"
|
|
36874
|
-
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_20__/* ["default"] */ .A, {
|
|
37059
|
+
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_FileUploadAnnouncer__WEBPACK_IMPORTED_MODULE_58__/* ["default"] */ .A, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_20__/* ["default"] */ .A, {
|
|
36875
37060
|
isOpen: showDisconnectOverlay,
|
|
36876
37061
|
onConnect: onConnect,
|
|
36877
37062
|
isPermanent: !!reconnectionLimit,
|
|
36878
37063
|
isConnecting: !!this.props.connecting,
|
|
36879
37064
|
onClose: handleClose,
|
|
36880
37065
|
config: config
|
|
36881
|
-
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37066
|
+
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_UnreadMessagesAnnouncer__WEBPACK_IMPORTED_MODULE_46__/* ["default"] */ .A, {
|
|
36882
37067
|
active: config.settings.unreadMessages.enableBadge || config.settings.unreadMessages.enableIndicator,
|
|
36883
37068
|
count: unseenMessages.length,
|
|
36884
37069
|
singularText: config.settings.customTranslations?.ariaLabels?.unreadMessageSingularText ?? "One unread message in chat.",
|
|
36885
37070
|
pluralText: config.settings.customTranslations?.ariaLabels?.unreadMessagePluralText ?? "unread messages in chat."
|
|
36886
|
-
}), !disableToggleButton && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37071
|
+
}), !disableToggleButton && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_TeaserMessageAnnouncer__WEBPACK_IMPORTED_MODULE_45__/* ["default"] */ .A, {
|
|
36887
37072
|
active: !!lastUnseenMessageText && !open,
|
|
36888
37073
|
text: lastUnseenMessageText,
|
|
36889
37074
|
label: config.settings.customTranslations?.ariaLabels?.newMessagePreview ?? "New message preview"
|
|
36890
37075
|
}),
|
|
36891
37076
|
// Show the message teaser if there is a last bot message and the webchat is closed
|
|
36892
|
-
lastUnseenMessageText && !open && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37077
|
+
lastUnseenMessageText && !open && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_TeaserMessage__WEBPACK_IMPORTED_MODULE_44__/* .TeaserMessage */ .I, {
|
|
36893
37078
|
messageText: lastUnseenMessageText,
|
|
36894
37079
|
onClick: this.openConversationFromTeaser,
|
|
36895
37080
|
config: config,
|
|
@@ -36917,7 +37102,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36917
37102
|
onClick: this.handleFabClick
|
|
36918
37103
|
}, webchatToggleProps, {
|
|
36919
37104
|
type: "button",
|
|
36920
|
-
className:
|
|
37105
|
+
className: classnames__WEBPACK_IMPORTED_MODULE_61___default()("webchat-toggle-button burst", config.settings?.layout?.iconAnimation),
|
|
36921
37106
|
id: "webchatWindowToggleButton",
|
|
36922
37107
|
"aria-label": openChatAriaLabel(),
|
|
36923
37108
|
ref: this.chatToggleButtonRef,
|
|
@@ -36937,7 +37122,12 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
36937
37122
|
_content: unseenMessages.length,
|
|
36938
37123
|
className: "webchat-unread-message-badge",
|
|
36939
37124
|
"aria-hidden": "true"
|
|
36940
|
-
}) : null)
|
|
37125
|
+
}) : null), showIconAnimationPauseButton && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_IconAnimationPauseButton__WEBPACK_IMPORTED_MODULE_31__/* ["default"] */ .A, {
|
|
37126
|
+
paused: this.state.isIconAnimationPaused,
|
|
37127
|
+
onToggle: this.handleToggleIconAnimationPause,
|
|
37128
|
+
pauseLabel: config.settings.customTranslations?.ariaLabels?.pauseWebchatToggleAnimation ?? "Pause webchat toggle animation",
|
|
37129
|
+
resumeLabel: config.settings.customTranslations?.ariaLabels?.resumeWebchatToggleAnimation ?? "Resume webchat toggle animation"
|
|
37130
|
+
}))))))));
|
|
36941
37131
|
}
|
|
36942
37132
|
renderRegularLayout(isInforming) {
|
|
36943
37133
|
const {
|
|
@@ -37054,24 +37244,25 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37054
37244
|
}
|
|
37055
37245
|
};
|
|
37056
37246
|
const getRegularLayoutContent = () => {
|
|
37057
|
-
if (showInformationMessage) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37247
|
+
if (showInformationMessage) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_InformationMessage__WEBPACK_IMPORTED_MODULE_38__/* .InformationMessage */ .E, {
|
|
37058
37248
|
message: informMessage
|
|
37059
37249
|
});
|
|
37060
|
-
if (!hasAcceptedTerms && config.settings.privacyNotice.enabled) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37250
|
+
if (!hasAcceptedTerms && config.settings.privacyNotice.enabled) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_PrivacyNotice__WEBPACK_IMPORTED_MODULE_39__/* .PrivacyNotice */ .r, {
|
|
37061
37251
|
privacyNotice: config.settings.privacyNotice,
|
|
37062
37252
|
onAcceptTerms: handleAcceptTerms,
|
|
37063
37253
|
isHomeScreenEnabled: isHomeScreenEnabled
|
|
37064
37254
|
});
|
|
37065
|
-
if (isXAppOverlayOpen) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37066
|
-
if (showPrevConversations) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37255
|
+
if (isXAppOverlayOpen) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_functional_xapp_overlay_XAppOverlay__WEBPACK_IMPORTED_MODULE_47__/* ["default"] */ .A, null);
|
|
37256
|
+
if (showPrevConversations) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_previous_conversations_ConversationsList__WEBPACK_IMPORTED_MODULE_35__/* .PrevConversationsList */ .K, {
|
|
37067
37257
|
conversations: this.props.prevConversations,
|
|
37068
37258
|
onSetShowPrevConversations: onSetShowPrevConversations,
|
|
37069
37259
|
onSwitchSession: onSwitchSession,
|
|
37070
37260
|
config: config,
|
|
37071
37261
|
currentSession: currentSession,
|
|
37072
|
-
startNewConversationButtonRef: this.startNewConversationButtonRef
|
|
37262
|
+
startNewConversationButtonRef: this.startNewConversationButtonRef,
|
|
37263
|
+
emptyListTextRef: this.emptyPrevConversationsTextRef
|
|
37073
37264
|
});
|
|
37074
|
-
if (showChatOptionsScreen || showRatingScreen) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37265
|
+
if (showChatOptionsScreen || showRatingScreen) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_chat_options_ChatOptions__WEBPACK_IMPORTED_MODULE_40__/* .ChatOptions */ .b, {
|
|
37075
37266
|
config: config,
|
|
37076
37267
|
ratingTitleText: customRatingTitle || config.settings.chatOptions.rating.title,
|
|
37077
37268
|
ratingCommentText: customRatingCommentText || config.settings.chatOptions.rating.commentPlaceholder,
|
|
@@ -37088,7 +37279,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37088
37279
|
});
|
|
37089
37280
|
}
|
|
37090
37281
|
});
|
|
37091
|
-
if (isDropZoneVisible) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37282
|
+
if (isDropZoneVisible) return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_plugins_input_file_DropZone__WEBPACK_IMPORTED_MODULE_42__/* ["default"] */ .A, {
|
|
37092
37283
|
layoutSettings: config.settings.layout,
|
|
37093
37284
|
dropzoneText: config.settings.fileStorageSettings?.dropzoneText
|
|
37094
37285
|
});
|
|
@@ -37101,11 +37292,11 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37101
37292
|
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement("h3", {
|
|
37102
37293
|
className: "sr-only",
|
|
37103
37294
|
id: "webchatChatHistoryHeading"
|
|
37104
|
-
}, config.settings.customTranslations?.ariaLabels?.chatHistory ?? "Chat history"), this.renderHistory()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37295
|
+
}, config.settings.customTranslations?.ariaLabels?.chatHistory ?? "Chat history"), this.renderHistory()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_ScreenReaderLiveRegion__WEBPACK_IMPORTED_MODULE_54__/* ["default"] */ .A, {
|
|
37105
37296
|
liveContent: this.state.liveContent,
|
|
37106
37297
|
intro: this.getNoticeIntro(),
|
|
37107
37298
|
onIntroAnnounced: this.handleNoticeIntroAnnounced
|
|
37108
|
-
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37299
|
+
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_history_QueueUpdates__WEBPACK_IMPORTED_MODULE_41__/* ["default"] */ .A, null), this.renderInput());
|
|
37109
37300
|
};
|
|
37110
37301
|
const getTitles = () => {
|
|
37111
37302
|
if (showInformationMessage && informTitle) {
|
|
@@ -37132,7 +37323,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37132
37323
|
const {
|
|
37133
37324
|
showEnabledHomeScreen,
|
|
37134
37325
|
showChatScreen
|
|
37135
|
-
} = (0,
|
|
37326
|
+
} = (0,_utils_screen_visibility__WEBPACK_IMPORTED_MODULE_60__/* .getScreenVisibility */ .p)(this.props, isInforming);
|
|
37136
37327
|
const isChatOptionsButtonVisible = config.settings.chatOptions.enabled && showChatScreen;
|
|
37137
37328
|
const hideBackButton = showChatScreen && !isHomeScreenEnabled;
|
|
37138
37329
|
const showDeleteAllConversationButton = !!((config.settings.privacyNotice.enabled && this.props.hasAcceptedTerms || !config.settings.privacyNotice.enabled) && config.settings.homeScreen.previousConversations.enableDeleteAllConversations && showPrevConversations && Object.keys(this.props.prevConversations).length);
|
|
@@ -37150,7 +37341,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37150
37341
|
// hidden: it is static chrome with no live region, so nothing in it
|
|
37151
37342
|
// announces during the exit.
|
|
37152
37343
|
const isRegularLayoutActiveView = !!(!showEnabledHomeScreen || showInformationMessage);
|
|
37153
|
-
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(RegularLayoutRoot, null, !isXAppOverlayOpen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37344
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(RegularLayoutRoot, null, !isXAppOverlayOpen && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(react_transition_group__WEBPACK_IMPORTED_MODULE_43__/* ["default"] */ .A, {
|
|
37154
37345
|
in: isRegularLayoutActiveView,
|
|
37155
37346
|
timeout: 500,
|
|
37156
37347
|
classNames: "slide-in",
|
|
@@ -37180,11 +37371,11 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37180
37371
|
showChatScreen: showChatScreen,
|
|
37181
37372
|
autoFocusScreenTitle: autoFocusScreenTitle,
|
|
37182
37373
|
deleteIconColor: config.settings.customColors?.deleteAllConversationIconColor
|
|
37183
|
-
})), !isSecondaryView && isHomeScreenEnabled && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37374
|
+
})), !isSecondaryView && isHomeScreenEnabled && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(react_transition_group__WEBPACK_IMPORTED_MODULE_43__/* ["default"] */ .A, {
|
|
37184
37375
|
in: !showHomeScreen,
|
|
37185
37376
|
timeout: 500,
|
|
37186
37377
|
classNames: "hidebackground"
|
|
37187
|
-
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37378
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_HomeScreen__WEBPACK_IMPORTED_MODULE_34__/* .HomeScreen */ .u, {
|
|
37188
37379
|
showHomeScreen: showHomeScreen,
|
|
37189
37380
|
closeButtonRef: this.homeScreenCloseButtonRef,
|
|
37190
37381
|
onSetShowHomeScreen: onSetShowHomeScreen,
|
|
@@ -37194,7 +37385,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37194
37385
|
config: config,
|
|
37195
37386
|
onEmitAnalytics: onEmitAnalytics,
|
|
37196
37387
|
onSendActionButtonMessage: this.handleSendActionButtonMessage
|
|
37197
|
-
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37388
|
+
})), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(react_transition_group__WEBPACK_IMPORTED_MODULE_43__/* ["default"] */ .A, {
|
|
37198
37389
|
in: isRegularLayoutActiveView,
|
|
37199
37390
|
timeout: 500,
|
|
37200
37391
|
classNames: "slide-in",
|
|
@@ -37204,20 +37395,34 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37204
37395
|
className: "webchat-regular-layout-content",
|
|
37205
37396
|
"aria-hidden": isRegularLayoutActiveView ? undefined : true,
|
|
37206
37397
|
inert: isRegularLayoutActiveView ? undefined : ""
|
|
37207
|
-
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37398
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_FreezeOnExit__WEBPACK_IMPORTED_MODULE_56__/* ["default"] */ .A, {
|
|
37208
37399
|
active: isRegularLayoutActiveView
|
|
37209
|
-
}, getRegularLayoutContent()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37400
|
+
}, getRegularLayoutContent()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_previous_conversations_DeleteAllConversations__WEBPACK_IMPORTED_MODULE_53__/* ["default"] */ .A, {
|
|
37210
37401
|
config: config,
|
|
37211
37402
|
isOpen: this.state.showDeleteAllConversationsModal,
|
|
37212
37403
|
onOpenChange: (open, confirmDelete) => {
|
|
37213
37404
|
this.setState({
|
|
37214
37405
|
showDeleteAllConversationsModal: open
|
|
37215
37406
|
});
|
|
37216
|
-
if (
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
|
|
37407
|
+
if (open || !confirmDelete) {
|
|
37408
|
+
// Cancel / close: the Modal itself returns focus to
|
|
37409
|
+
// the element that opened it (the header delete button).
|
|
37410
|
+
return;
|
|
37220
37411
|
}
|
|
37412
|
+
// Confirmed: the header delete button is gone with the
|
|
37413
|
+
// last conversation, so focus the now-rendered empty-state
|
|
37414
|
+
// text and the outcome is read out (SC 4.1.3, CGY-39786).
|
|
37415
|
+
// Deferred like the Modal's own focus moves: focusing a
|
|
37416
|
+
// node in the same task that inserted it is not reliably
|
|
37417
|
+
// announced, and the Modal's close effect restores focus
|
|
37418
|
+
// to whatever was active when it opened (the header title
|
|
37419
|
+
// after a pointer click on browsers that do not focus
|
|
37420
|
+
// buttons on click) — this must run after that.
|
|
37421
|
+
if (this.deleteAllFocusTimeout) clearTimeout(this.deleteAllFocusTimeout);
|
|
37422
|
+
this.deleteAllFocusTimeout = setTimeout(() => {
|
|
37423
|
+
this.deleteAllFocusTimeout = null;
|
|
37424
|
+
(this.emptyPrevConversationsTextRef.current ?? this.startNewConversationButtonRef.current)?.focus();
|
|
37425
|
+
}, 200);
|
|
37221
37426
|
}
|
|
37222
37427
|
}))));
|
|
37223
37428
|
}
|
|
@@ -37265,11 +37470,11 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37265
37470
|
progressiveMessageRendering
|
|
37266
37471
|
} = config.settings.behavior;
|
|
37267
37472
|
const isTyping = typingIndicator !== "remove" && typingIndicator !== "hide";
|
|
37268
|
-
const isEnded = (0,
|
|
37473
|
+
const isEnded = (0,_presentational_previous_conversations_helpers__WEBPACK_IMPORTED_MODULE_37__/* .isConversationEnded */ .GP)(messages);
|
|
37269
37474
|
|
|
37270
37475
|
// Find privacy message and remove it from the messages list (these message types are not displayed in the chat log).
|
|
37271
37476
|
// If we do not remove, it will cause the collatation of the first user message.
|
|
37272
|
-
const messagesExcludingPrivacyMessage = (0,
|
|
37477
|
+
const messagesExcludingPrivacyMessage = (0,_utils_filter_out_control_commands__WEBPACK_IMPORTED_MODULE_50__/* ["default"] */ .A)(messages, ["acceptPrivacyPolicy"]);
|
|
37273
37478
|
|
|
37274
37479
|
// Filter messages based on progressive rendering settings
|
|
37275
37480
|
const visibleMessages = progressiveMessageRendering ? messagesExcludingPrivacyMessage.filter(message => {
|
|
@@ -37290,7 +37495,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37290
37495
|
variant: "body-regular",
|
|
37291
37496
|
component: "div",
|
|
37292
37497
|
className: "webchat-log-ai-agent-notice-text"
|
|
37293
|
-
}, AIAgentNoticeText ||
|
|
37498
|
+
}, AIAgentNoticeText || _utils_ai_agent_notice__WEBPACK_IMPORTED_MODULE_59__/* .DEFAULT_AI_AGENT_NOTICE_TEXT */ .S5), visibleMessages.map((message, index) => {
|
|
37294
37499
|
// Lookahead if there is a user reply that includes text or attachments
|
|
37295
37500
|
const hasReply = visibleMessages.slice(index + 1).some(message => {
|
|
37296
37501
|
const isUser = message.source === "user";
|
|
@@ -37299,7 +37504,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37299
37504
|
const hasAttachments = Array.isArray(message?.data?.attachments) && message.data.attachments.length > 0;
|
|
37300
37505
|
return isUser && noControlCommands && (hasText || hasAttachments);
|
|
37301
37506
|
});
|
|
37302
|
-
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37507
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_36__/* .Message */ .QB, {
|
|
37303
37508
|
key: message.id || JSON.stringify({
|
|
37304
37509
|
message,
|
|
37305
37510
|
index
|
|
@@ -37320,7 +37525,7 @@ class WebchatUI extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
37320
37525
|
onSetLiveRegionText: handleLiveRegionText,
|
|
37321
37526
|
"data-message-id": `webchatMessageId-${message.timestamp}`
|
|
37322
37527
|
});
|
|
37323
|
-
}), isEnded && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
37528
|
+
}), isEnded && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_36__/* .ChatEvent */ .b$, {
|
|
37324
37529
|
text: "Conversation ended",
|
|
37325
37530
|
className: "webchat-chip-conversation-ended"
|
|
37326
37531
|
}), enableTypingIndicator && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_history_TypingIndicator__WEBPACK_IMPORTED_MODULE_27__/* ["default"] */ .A, {
|
|
@@ -37539,6 +37744,20 @@ const Iframe = _emotion_styled__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A.
|
|
|
37539
37744
|
}
|
|
37540
37745
|
}));
|
|
37541
37746
|
|
|
37747
|
+
// Derive the canonical http(s) origin from an xApp URL, or null if the URL is
|
|
37748
|
+
// unparseable or uses a non-http(s) scheme. data:/about:/blob: URLs produce the
|
|
37749
|
+
// string "null" from new URL().origin — accepting them would let bot-supplied
|
|
37750
|
+
// data: xApps forge postMessages accepted by the handleSubmit origin check.
|
|
37751
|
+
const getXAppOrigin = url => {
|
|
37752
|
+
try {
|
|
37753
|
+
const parsed = new URL(url);
|
|
37754
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
37755
|
+
return parsed.origin;
|
|
37756
|
+
} catch {
|
|
37757
|
+
return null;
|
|
37758
|
+
}
|
|
37759
|
+
};
|
|
37760
|
+
|
|
37542
37761
|
// Visually hidden but reachable by sequential focus navigation. Not
|
|
37543
37762
|
// `aria-hidden`: a focusable aria-hidden node is an axe violation
|
|
37544
37763
|
// (aria-hidden-focus) — and focus never rests here anyway, the onFocus
|
|
@@ -37573,6 +37792,17 @@ const xAppOverlay = () => {
|
|
|
37573
37792
|
const rootRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
37574
37793
|
const closeButtonRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
37575
37794
|
const iframeRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
37795
|
+
const xAppOrigin = getXAppOrigin(url);
|
|
37796
|
+
|
|
37797
|
+
// For invalid or non-http(s) URLs close the overlay immediately so Redux
|
|
37798
|
+
// state is cleaned up and the widget does not dead-end. Dispatch must happen
|
|
37799
|
+
// in an effect — not during render — to satisfy React's rules.
|
|
37800
|
+
(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
|
|
37801
|
+
if (url && xAppOrigin === null) {
|
|
37802
|
+
console.error("[xApp] Invalid xApp URL — must be an absolute http(s) URL:", url);
|
|
37803
|
+
dispatch((0,_webchat_store_xapp_overlay_slice__WEBPACK_IMPORTED_MODULE_4__/* .closeOverlay */ .L9)());
|
|
37804
|
+
}
|
|
37805
|
+
}, [url, xAppOrigin]);
|
|
37576
37806
|
const handleClose = () => {
|
|
37577
37807
|
if (closeOnSubmit) {
|
|
37578
37808
|
dispatch((0,_webchat_store_xapp_overlay_slice__WEBPACK_IMPORTED_MODULE_4__/* .closeOverlay */ .L9)());
|
|
@@ -37589,20 +37819,26 @@ const xAppOverlay = () => {
|
|
|
37589
37819
|
dispatch((0,_webchat_store_xapp_overlay_slice__WEBPACK_IMPORTED_MODULE_4__/* .closeOverlay */ .L9)());
|
|
37590
37820
|
};
|
|
37591
37821
|
const handleSubmit = event => {
|
|
37592
|
-
//
|
|
37593
|
-
//
|
|
37594
|
-
//
|
|
37595
|
-
//
|
|
37596
|
-
//
|
|
37597
|
-
//
|
|
37598
|
-
|
|
37599
|
-
|
|
37600
|
-
|
|
37601
|
-
|
|
37602
|
-
|
|
37603
|
-
|
|
37604
|
-
|
|
37605
|
-
|
|
37822
|
+
// Reuse xAppOrigin from render scope (includes the http(s)-only scheme guard
|
|
37823
|
+
// from getXAppOrigin). This prevents opaque-origin ("null") postMessages from
|
|
37824
|
+
// data:/about:/blob: URLs — which stay in Redux until the cleanup effect fires —
|
|
37825
|
+
// from matching via event.origin === "null" between render and effect execution.
|
|
37826
|
+
//
|
|
37827
|
+
// NOTE — known limitation: cross-origin xApps receive allow-same-origin in the
|
|
37828
|
+
// sandbox so their postMessages carry the real origin and this check is sound.
|
|
37829
|
+
// However, a cross-origin xApp document could navigate itself to the embedding
|
|
37830
|
+
// origin and then use frameElement to remove the sandbox (the allow-top-navigation
|
|
37831
|
+
// restriction covers top-level navigation only, not self-navigation). A proper fix
|
|
37832
|
+
// requires a token-based handshake or CSP headers on the xApp host to prevent
|
|
37833
|
+
// cross-origin-to-same-origin navigation; tracked as a follow-up hardening.
|
|
37834
|
+
//
|
|
37835
|
+
// Same-origin xApps omit allow-same-origin so they run with an opaque origin;
|
|
37836
|
+
// their postMessages arrive with event.origin === "null" and are rejected here.
|
|
37837
|
+
// Accepting opaque-origin messages via event.source (WindowProxy) is also unsafe:
|
|
37838
|
+
// a navigated iframe retains the same WindowProxy, so an attacker document loaded
|
|
37839
|
+
// via navigation passes both checks. Same-origin xApp x-app-submit therefore
|
|
37840
|
+
// requires the xApp to be hosted at a cross-origin URL.
|
|
37841
|
+
if (xAppOrigin === null || xAppOrigin !== event.origin) {
|
|
37606
37842
|
return;
|
|
37607
37843
|
}
|
|
37608
37844
|
if (event.data.type !== "x-app-submit") {
|
|
@@ -37644,6 +37880,31 @@ const xAppOverlay = () => {
|
|
|
37644
37880
|
};
|
|
37645
37881
|
}, [closeOnSubmit, url, feedbackMessage]);
|
|
37646
37882
|
|
|
37883
|
+
// WCH-SI10-003: allow-scripts + allow-same-origin together let a same-origin
|
|
37884
|
+
// iframe remove its own sandbox via frameElement. Omitting allow-same-origin
|
|
37885
|
+
// for same-origin xApp URLs prevents that escape; the trade-off is that
|
|
37886
|
+
// same-origin xApp iframes run with an opaque origin, so their postMessage
|
|
37887
|
+
// x-app-submit events are rejected (event.origin === "null"). Tenants whose
|
|
37888
|
+
// xApps are hosted on the same domain as the embedding page must move them to
|
|
37889
|
+
// a cross-origin host to use the submit flow.
|
|
37890
|
+
// Cross-origin URLs include allow-same-origin so the frame can access its own
|
|
37891
|
+
// host's resources (cookies, localStorage) and postMessages carry the real origin.
|
|
37892
|
+
const isSameOrigin = xAppOrigin !== null && xAppOrigin === window.location.origin;
|
|
37893
|
+
const sandboxValue = ["allow-scripts",
|
|
37894
|
+
// Only include allow-same-origin when the URL is a valid, cross-origin http(s)
|
|
37895
|
+
// URL. When xAppOrigin is null the iframe is still rendered briefly before the
|
|
37896
|
+
// cleanup effect closes it — don't grant allow-same-origin during that window.
|
|
37897
|
+
...(xAppOrigin !== null && !isSameOrigin ? ["allow-same-origin"] : []), "allow-forms", "allow-popups",
|
|
37898
|
+
// Popups must not inherit the creator's sandbox flags — OAuth, SSO, and
|
|
37899
|
+
// payment-provider windows run under constraints they were never tested against.
|
|
37900
|
+
"allow-popups-to-escape-sandbox", "allow-modals",
|
|
37901
|
+
// Boarding-pass (.pkpass), signature, PDF, and other download-generating xApps.
|
|
37902
|
+
"allow-downloads",
|
|
37903
|
+
// Redirect-based payment flows (3DS, iDEAL, Bancontact) and SSO return URLs.
|
|
37904
|
+
"allow-top-navigation-by-user-activation",
|
|
37905
|
+
// Storage Access API in a third-party frame context (Safari ITP, Chrome 3P-cookie rules).
|
|
37906
|
+
"allow-storage-access-by-user-activation"].join(" ");
|
|
37907
|
+
|
|
37647
37908
|
// APG modal dialog: move focus into the dialog once on open — to the
|
|
37648
37909
|
// close button (the first control, as Modal does), else the frame itself.
|
|
37649
37910
|
// Deliberately NOT the title: the dialog is named by that heading, so
|
|
@@ -37717,9 +37978,10 @@ const xAppOverlay = () => {
|
|
|
37717
37978
|
closeButtonRef: closeButtonRef
|
|
37718
37979
|
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["default"].createElement(Iframe, {
|
|
37719
37980
|
ref: iframeRef,
|
|
37720
|
-
src: url,
|
|
37981
|
+
src: xAppOrigin === null ? undefined : url,
|
|
37721
37982
|
title: title || fallbackName,
|
|
37722
|
-
|
|
37983
|
+
sandbox: sandboxValue,
|
|
37984
|
+
allow: "autoplay; camera; display-capture; encrypted-media; fullscreen; geolocation; microphone; picture-in-picture; web-share; payment; publickey-credentials-get; otp-credentials; accelerometer; gyroscope; magnetometer; screen-wake-lock; speaker-selection"
|
|
37723
37985
|
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["default"].createElement(FocusGuard, {
|
|
37724
37986
|
tabIndex: 0,
|
|
37725
37987
|
onFocus: handleFocusGuard("end"),
|
|
@@ -38519,6 +38781,21 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
38519
38781
|
this.configureSpeechRecognition();
|
|
38520
38782
|
}
|
|
38521
38783
|
inputRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
38784
|
+
|
|
38785
|
+
/**
|
|
38786
|
+
* The textarea's `autoFocus` is meant for the first mount of this input
|
|
38787
|
+
* (entering the chat screen). The textarea also re-mounts every time the
|
|
38788
|
+
* persistent menu closes (the menu replaces it while open); on those
|
|
38789
|
+
* re-mounts it must not pull focus off the menu toggle (SC 2.4.3,
|
|
38790
|
+
* CGY-39786), so autoFocus is limited to the first mount.
|
|
38791
|
+
*/
|
|
38792
|
+
hasMountedInput = false;
|
|
38793
|
+
/**
|
|
38794
|
+
* The deferred autofocus armed in componentDidMount. Cancelled when the
|
|
38795
|
+
* user operates the persistent menu before it fires — otherwise it would
|
|
38796
|
+
* pull focus off the toggle onto the remounted textarea — and on unmount.
|
|
38797
|
+
*/
|
|
38798
|
+
autofocusTimeout = null;
|
|
38522
38799
|
menuRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
38523
38800
|
fileInputRef = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createRef();
|
|
38524
38801
|
|
|
@@ -38562,13 +38839,15 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
38562
38839
|
*/
|
|
38563
38840
|
restartPending = false;
|
|
38564
38841
|
componentDidMount() {
|
|
38842
|
+
this.hasMountedInput = true;
|
|
38565
38843
|
// Global handler to modify the input text
|
|
38566
38844
|
window.WebChatInputTextCallback = text => {
|
|
38567
38845
|
this.setState({
|
|
38568
38846
|
text
|
|
38569
38847
|
});
|
|
38570
38848
|
};
|
|
38571
|
-
setTimeout(() => {
|
|
38849
|
+
this.autofocusTimeout = setTimeout(() => {
|
|
38850
|
+
this.autofocusTimeout = null;
|
|
38572
38851
|
// Don't pull focus away from a modal dialog the widget has opened in
|
|
38573
38852
|
// the meantime (date picker, xApp overlay, Modal). Scoped to the
|
|
38574
38853
|
// widget root: a dialog elsewhere on the host page (cookie banner, a
|
|
@@ -38586,6 +38865,7 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
38586
38865
|
}
|
|
38587
38866
|
componentWillUnmount() {
|
|
38588
38867
|
this.clearSpeechTimeout();
|
|
38868
|
+
this.clearAutofocusTimeout();
|
|
38589
38869
|
|
|
38590
38870
|
// The input unmounts on every screen change (back to the home screen,
|
|
38591
38871
|
// into the previous-conversations list). Without releasing the engine
|
|
@@ -38636,6 +38916,12 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
38636
38916
|
this.speechRecognition.lang = sttLanguage;
|
|
38637
38917
|
}
|
|
38638
38918
|
}
|
|
38919
|
+
clearAutofocusTimeout() {
|
|
38920
|
+
if (this.autofocusTimeout) {
|
|
38921
|
+
clearTimeout(this.autofocusTimeout);
|
|
38922
|
+
this.autofocusTimeout = null;
|
|
38923
|
+
}
|
|
38924
|
+
}
|
|
38639
38925
|
clearSpeechTimeout() {
|
|
38640
38926
|
if (this.speechTimeout) {
|
|
38641
38927
|
clearTimeout(this.speechTimeout);
|
|
@@ -38987,20 +39273,31 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
38987
39273
|
selectionEnd: e.target.selectionEnd
|
|
38988
39274
|
});
|
|
38989
39275
|
};
|
|
39276
|
+
|
|
39277
|
+
// Opening or closing via the toggle does not move focus: the toggle keeps
|
|
39278
|
+
// it (APG disclosure pattern, SC 2.4.3 — CGY-39786). The message input
|
|
39279
|
+
// unmounts while the menu is open and remounts on close, but focus never
|
|
39280
|
+
// left the toggle, so nothing needs restoring here. The user has chosen
|
|
39281
|
+
// where focus is, so the initial deferred autofocus (componentDidMount)
|
|
39282
|
+
// must not fire afterwards and move it to the remounted textarea.
|
|
38990
39283
|
togglePeristentMenu = () => {
|
|
39284
|
+
this.clearAutofocusTimeout();
|
|
38991
39285
|
this.setState(prevState => ({
|
|
38992
39286
|
isMenuOpen: !prevState.isMenuOpen
|
|
38993
|
-
})
|
|
38994
|
-
if (!this.state.isMenuOpen) {
|
|
38995
|
-
if (this.inputRef.current) {
|
|
38996
|
-
this.inputRef.current?.setSelectionRange(this.state.selectionStart, this.state.selectionEnd);
|
|
38997
|
-
this.inputRef.current.focus();
|
|
38998
|
-
}
|
|
38999
|
-
}
|
|
39000
|
-
});
|
|
39287
|
+
}));
|
|
39001
39288
|
};
|
|
39002
39289
|
onSelectPersistentMenuItem = item => {
|
|
39003
|
-
|
|
39290
|
+
// The selected item unmounts together with the menu, so focus would fall
|
|
39291
|
+
// back to <body>. Hand it to the message input (remounted by this state
|
|
39292
|
+
// change) and restore the caret position recorded on its last blur.
|
|
39293
|
+
this.setState({
|
|
39294
|
+
isMenuOpen: false
|
|
39295
|
+
}, () => {
|
|
39296
|
+
if (this.inputRef.current) {
|
|
39297
|
+
this.inputRef.current.setSelectionRange(this.state.selectionStart, this.state.selectionEnd);
|
|
39298
|
+
this.inputRef.current.focus();
|
|
39299
|
+
}
|
|
39300
|
+
});
|
|
39004
39301
|
this.props.onSendMessage(item.payload, null, {
|
|
39005
39302
|
label: item.title
|
|
39006
39303
|
});
|
|
@@ -39083,7 +39380,7 @@ class BaseInput extends react__WEBPACK_IMPORTED_MODULE_0__["default"].PureCompon
|
|
|
39083
39380
|
// the `disableInputAutofocus` setting.
|
|
39084
39381
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
39085
39382
|
,
|
|
39086
|
-
autoFocus: !disableInputAutofocus,
|
|
39383
|
+
autoFocus: !disableInputAutofocus && !this.hasMountedInput,
|
|
39087
39384
|
value: combineStrings(text, speechInterim),
|
|
39088
39385
|
onChange: this.handleChangeTextValue,
|
|
39089
39386
|
onFocus: this.handleFocus,
|
|
@@ -39348,11 +39645,14 @@ const DropZone = props => {
|
|
|
39348
39645
|
/* harmony import */ var _emotion_styled__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(84937);
|
|
39349
39646
|
/* harmony import */ var _assets_close_10px_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(48761);
|
|
39350
39647
|
/* harmony import */ var _presentational_IconButton__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(39966);
|
|
39351
|
-
/* harmony import */ var
|
|
39352
|
-
/* harmony import */ var
|
|
39353
|
-
/* harmony import */ var
|
|
39354
|
-
/* harmony import */ var
|
|
39355
|
-
/* harmony import */ var
|
|
39648
|
+
/* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(58637);
|
|
39649
|
+
/* harmony import */ var _presentational_LinearProgressBar__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(51308);
|
|
39650
|
+
/* harmony import */ var _presentational_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(63813);
|
|
39651
|
+
/* harmony import */ var _helper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(22714);
|
|
39652
|
+
/* harmony import */ var _cognigy_chat_components__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2854);
|
|
39653
|
+
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(74506);
|
|
39654
|
+
/* harmony import */ var _webchat_store_input_input_reducer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(16967);
|
|
39655
|
+
|
|
39356
39656
|
|
|
39357
39657
|
|
|
39358
39658
|
|
|
@@ -39362,40 +39662,56 @@ const DropZone = props => {
|
|
|
39362
39662
|
|
|
39363
39663
|
|
|
39364
39664
|
|
|
39665
|
+
|
|
39666
|
+
const CHIP_HEIGHT = 33;
|
|
39667
|
+
const CHIP_GAP = 12;
|
|
39668
|
+
const MAX_VISIBLE_ROWS = 3;
|
|
39669
|
+
|
|
39670
|
+
// Chips wrap onto further rows instead of scrolling horizontally, so every
|
|
39671
|
+
// attachment stays readable at a glance. Past three rows the area scrolls
|
|
39672
|
+
// vertically, with the same scrollbar styling as the message textarea
|
|
39673
|
+
// (BaseInput.tsx) so both get restyled together.
|
|
39365
39674
|
const UploadedFilesContainer = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.div(({
|
|
39366
39675
|
theme
|
|
39367
39676
|
}) => ({
|
|
39368
39677
|
display: "flex",
|
|
39369
39678
|
flexDirection: "row",
|
|
39370
|
-
|
|
39371
|
-
overflowY: "hidden",
|
|
39679
|
+
flexWrap: "wrap",
|
|
39372
39680
|
alignItems: "center",
|
|
39373
|
-
gap:
|
|
39374
|
-
|
|
39681
|
+
gap: CHIP_GAP,
|
|
39682
|
+
maxHeight: MAX_VISIBLE_ROWS * CHIP_HEIGHT + (MAX_VISIBLE_ROWS - 1) * CHIP_GAP,
|
|
39683
|
+
overflowY: "auto",
|
|
39684
|
+
"::-webkit-scrollbar": {
|
|
39375
39685
|
width: 2,
|
|
39376
|
-
height: 2
|
|
39377
|
-
visibility: "hidden"
|
|
39686
|
+
height: 2
|
|
39378
39687
|
},
|
|
39379
|
-
"
|
|
39380
|
-
|
|
39381
|
-
|
|
39382
|
-
|
|
39383
|
-
|
|
39384
|
-
backgroundColor: theme.black60
|
|
39385
|
-
}
|
|
39688
|
+
"::-webkit-scrollbar-track": {
|
|
39689
|
+
backgroundColor: theme.black95
|
|
39690
|
+
},
|
|
39691
|
+
"::-webkit-scrollbar-thumb": {
|
|
39692
|
+
backgroundColor: theme.black60
|
|
39386
39693
|
}
|
|
39387
39694
|
}));
|
|
39388
39695
|
const FilePreviewWrapper = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.div(({
|
|
39696
|
+
hasUploadError,
|
|
39389
39697
|
theme
|
|
39390
39698
|
}) => ({
|
|
39391
39699
|
position: "relative",
|
|
39700
|
+
// Clips the progress bar's corners. Note a flex item with overflow:hidden
|
|
39701
|
+
// may shrink to 0 — the wrapping row above never asks it to, and maxWidth
|
|
39702
|
+
// caps long names to the FileName ellipsis instead of one huge chip.
|
|
39703
|
+
// A failed chip shows the failure reason instead of the name ("Upload
|
|
39704
|
+
// Failed: File size > 10MB" is ~160px at the default font); that text is
|
|
39705
|
+
// the only non-colour cue of the failure (SC 1.4.1) and must not be
|
|
39706
|
+
// ellipsised, so the cap is lifted to the row's width.
|
|
39392
39707
|
overflow: "hidden",
|
|
39708
|
+
maxWidth: hasUploadError ? "100%" : 200,
|
|
39393
39709
|
borderRadius: 15,
|
|
39394
|
-
height:
|
|
39395
|
-
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
39710
|
+
height: CHIP_HEIGHT,
|
|
39711
|
+
// A lone chip wider than its line could still shrink (and collapse its
|
|
39712
|
+
// name) — never shrink; maxWidth above keeps it fitting instead.
|
|
39713
|
+
flexShrink: 0,
|
|
39714
|
+
backgroundColor: theme.black95
|
|
39399
39715
|
}));
|
|
39400
39716
|
const UploadedFilePreview = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.div(() => ({
|
|
39401
39717
|
display: "flex",
|
|
@@ -39405,7 +39721,7 @@ const UploadedFilePreview = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["def
|
|
|
39405
39721
|
padding: "0 12px 0 6px",
|
|
39406
39722
|
height: "100%"
|
|
39407
39723
|
}));
|
|
39408
|
-
const FileName = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(
|
|
39724
|
+
const FileName = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_8__/* .Typography */ .o5)(({
|
|
39409
39725
|
hasUploadError,
|
|
39410
39726
|
theme
|
|
39411
39727
|
}) => ({
|
|
@@ -39415,66 +39731,104 @@ const FileName = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] *
|
|
|
39415
39731
|
color: hasUploadError ? theme.red40 : theme.black10,
|
|
39416
39732
|
alignSelf: "center"
|
|
39417
39733
|
}));
|
|
39418
|
-
const FileSize = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(
|
|
39734
|
+
const FileSize = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_8__/* .Typography */ .o5)(({
|
|
39419
39735
|
theme
|
|
39420
39736
|
}) => ({
|
|
39421
39737
|
color: theme.black40,
|
|
39422
39738
|
alignSelf: "center",
|
|
39423
39739
|
textWrap: "nowrap"
|
|
39424
39740
|
}));
|
|
39741
|
+
|
|
39742
|
+
// Keyboard focus is shown on the button itself as two rings (same construction
|
|
39743
|
+
// as the launcher's FAB): an outer ring in the primary's focus variant and an
|
|
39744
|
+
// inner ring in that colour's computed contrast colour — white on a dark
|
|
39745
|
+
// primary, black on a light one. The two rings always contrast with each
|
|
39746
|
+
// other, so at least one of them contrasts with the chip whatever primary the
|
|
39747
|
+
// customer configures (SC 1.4.11 / 2.4.7). The chip background stays
|
|
39748
|
+
// untouched, so its texts keep their idle contrast (black40 / red40 on black95).
|
|
39425
39749
|
const RemoveFileButton = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(_presentational_IconButton__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(({
|
|
39426
39750
|
theme
|
|
39427
39751
|
}) => ({
|
|
39428
39752
|
padding: 0,
|
|
39429
39753
|
marginRight: -6,
|
|
39754
|
+
borderRadius: "50%",
|
|
39430
39755
|
"& svg": {
|
|
39431
39756
|
width: 12,
|
|
39432
39757
|
height: 12
|
|
39433
39758
|
},
|
|
39434
|
-
"&:
|
|
39759
|
+
"&:hover": {
|
|
39435
39760
|
"& path": {
|
|
39436
|
-
fill: `${theme.primaryColor} !important
|
|
39437
|
-
outline: "none"
|
|
39761
|
+
fill: `${theme.primaryColor} !important`
|
|
39438
39762
|
}
|
|
39763
|
+
},
|
|
39764
|
+
"&:focus-visible": {
|
|
39765
|
+
outline: `2px solid ${theme.primaryColorFocus}`,
|
|
39766
|
+
outlineOffset: 2,
|
|
39767
|
+
boxShadow: `0 0 0 2px ${(0,_style__WEBPACK_IMPORTED_MODULE_4__/* .getContrastColor */ .w5)(theme.primaryColorFocus, theme)}`
|
|
39439
39768
|
}
|
|
39440
39769
|
}));
|
|
39441
39770
|
const PreviewUploadedFiles = () => {
|
|
39442
|
-
const
|
|
39443
|
-
const
|
|
39444
|
-
const
|
|
39445
|
-
|
|
39446
|
-
|
|
39447
|
-
|
|
39771
|
+
const fileList = (0,react_redux__WEBPACK_IMPORTED_MODULE_9__/* .useSelector */ .d4)(state => state.input.fileList);
|
|
39772
|
+
const ariaLabels = (0,react_redux__WEBPACK_IMPORTED_MODULE_9__/* .useSelector */ .d4)(state => state.config.settings.customTranslations?.ariaLabels);
|
|
39773
|
+
const dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_9__/* .useDispatch */ .wA)();
|
|
39774
|
+
|
|
39775
|
+
// Removing a chip unmounts its (focused) remove button, which would drop
|
|
39776
|
+
// keyboard focus to <body> (SC 2.4.3). Focus moves to the remove button of
|
|
39777
|
+
// the neighbouring chip instead — the one that takes the removed chip's
|
|
39778
|
+
// position, or the previous one when the last chip was removed — and to the
|
|
39779
|
+
// attach button once the list is empty, where a user would add the next
|
|
39780
|
+
// file (persistent-menu toggle / message input when that is not rendered).
|
|
39781
|
+
// Only when the removed button actually held focus, so a removal
|
|
39782
|
+
// triggered while focus is elsewhere does not yank it.
|
|
39783
|
+
const pendingFocusIndexRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
39784
|
+
const onRemoveFileButtonClick = (index, event) => {
|
|
39785
|
+
const removed = fileList[index];
|
|
39786
|
+
if (document.activeElement === event.currentTarget) {
|
|
39787
|
+
const remaining = fileList.length - 1;
|
|
39788
|
+
if (remaining > 0) {
|
|
39789
|
+
pendingFocusIndexRef.current = Math.min(index, remaining - 1);
|
|
39790
|
+
} else {
|
|
39791
|
+
// This component unmounts with the last chip, so its effect can't
|
|
39792
|
+
// run any more — focus the successor now. The attach button is
|
|
39793
|
+
// replaced by the persistent menu while that menu is open (its
|
|
39794
|
+
// toggle stays), and the message input is the last resort.
|
|
39795
|
+
const successor = document.getElementById("webchatInputMessageAttachFileButton") ?? document.getElementById("webchatInputButtonMenu") ?? document.getElementById("webchatInputMessageInputInTextMode");
|
|
39796
|
+
successor?.focus();
|
|
39797
|
+
}
|
|
39798
|
+
}
|
|
39799
|
+
dispatch((0,_webchat_store_input_input_reducer__WEBPACK_IMPORTED_MODULE_10__/* .removeFileFromList */ .RB)(index));
|
|
39800
|
+
// The chip disappearing is the only visible feedback; say so (SC 4.1.3).
|
|
39801
|
+
if (removed) {
|
|
39802
|
+
(0,_presentational_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_6__/* .announceStatus */ .a)((0,_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_8__/* .formatTemplate */ .sN)(ariaLabels?.fileAttachmentRemoved ?? "{fileName} removed", {
|
|
39803
|
+
fileName: removed.file.name
|
|
39804
|
+
}));
|
|
39805
|
+
}
|
|
39448
39806
|
};
|
|
39807
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
39808
|
+
const index = pendingFocusIndexRef.current;
|
|
39809
|
+
if (index === null) return;
|
|
39810
|
+
pendingFocusIndexRef.current = null;
|
|
39811
|
+
document.querySelector(`#filePreview${index} button`)?.focus();
|
|
39812
|
+
}, [fileList]);
|
|
39449
39813
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(UploadedFilesContainer, null, fileList?.map((item, index) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(FilePreviewWrapper, {
|
|
39450
39814
|
key: index,
|
|
39451
|
-
id: `filePreview${index}
|
|
39815
|
+
id: `filePreview${index}`,
|
|
39816
|
+
hasUploadError: item.hasUploadError
|
|
39452
39817
|
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(UploadedFilePreview, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(RemoveFileButton, {
|
|
39453
39818
|
type: "button",
|
|
39454
|
-
onClick:
|
|
39455
|
-
|
|
39456
|
-
|
|
39457
|
-
|
|
39458
|
-
|
|
39459
|
-
inline: "center",
|
|
39460
|
-
block: "nearest"
|
|
39461
|
-
});
|
|
39462
|
-
}
|
|
39463
|
-
},
|
|
39464
|
-
"aria-label": `${removeFileAttachment ?? "Remove file attachment"} ${index + 1}`,
|
|
39465
|
-
ref: ref => {
|
|
39466
|
-
if (ref) {
|
|
39467
|
-
removeFileButtonRefs.current[index] = ref;
|
|
39468
|
-
}
|
|
39469
|
-
}
|
|
39819
|
+
onClick: event => onRemoveFileButtonClick(index, event)
|
|
39820
|
+
// Position + file name: the chip's own text is not part of the
|
|
39821
|
+
// button's name, and a failed chip shows the reason, not the name.
|
|
39822
|
+
,
|
|
39823
|
+
"aria-label": `${ariaLabels?.removeFileAttachment ?? "Remove file attachment"} ${index + 1}, ${item.file.name}`
|
|
39470
39824
|
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_assets_close_10px_svg__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(FileName, {
|
|
39471
39825
|
component: "span",
|
|
39472
39826
|
variant: "title2-regular",
|
|
39473
39827
|
hasUploadError: item.hasUploadError
|
|
39474
|
-
}, !item.hasUploadError ? `${(0,
|
|
39828
|
+
}, !item.hasUploadError ? `${(0,_helper__WEBPACK_IMPORTED_MODULE_7__/* .getFileName */ .W)(item.file.name)}${(0,_helper__WEBPACK_IMPORTED_MODULE_7__/* .getFileExtension */ .Q)(item.file.name)}` : item.uploadErrorReason), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(FileSize, {
|
|
39475
39829
|
component: "span",
|
|
39476
39830
|
variant: "title2-regular"
|
|
39477
|
-
}, item.file.size > 1000000 ? `${(item.file.size / 1000000).toFixed(2)} MB` : `${(item.file.size / 1000).toFixed(2)} KB`)), item.progressPercentage && item.progressPercentage !== 100 && !item.hasUploadError && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(
|
|
39831
|
+
}, item.file.size > 1000000 ? `${(item.file.size / 1000000).toFixed(2)} MB` : `${(item.file.size / 1000).toFixed(2)} KB`)), item.progressPercentage && item.progressPercentage !== 100 && !item.hasUploadError && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_presentational_LinearProgressBar__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A, {
|
|
39478
39832
|
progressPercentage: item.progressPercentage
|
|
39479
39833
|
}))));
|
|
39480
39834
|
};
|
|
@@ -40158,6 +40512,21 @@ const FAB = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)
|
|
|
40158
40512
|
animationIterationCount: 1,
|
|
40159
40513
|
animationFillMode: "both"
|
|
40160
40514
|
},
|
|
40515
|
+
// Reveals the opt-in animation pause control (IconAnimationPauseButton, the
|
|
40516
|
+
// launcher's following sibling) while the launcher is hovered or keyboard
|
|
40517
|
+
// focused. Lives here because the stylis isolate plugin prefixes the root
|
|
40518
|
+
// selector in front of `&`, so the rule must start with the launcher.
|
|
40519
|
+
"&:hover ~ .webchat-toggle-button-animation-pause, &:focus-visible ~ .webchat-toggle-button-animation-pause": {
|
|
40520
|
+
opacity: 1
|
|
40521
|
+
},
|
|
40522
|
+
// SC 2.3.3 / project rule: no launcher motion under reduced motion. Same
|
|
40523
|
+
// selectors as the burst rules above (equal specificity, declared later),
|
|
40524
|
+
// so this wins; a shorter selector would lose to them.
|
|
40525
|
+
"@media (prefers-reduced-motion: reduce)": {
|
|
40526
|
+
"&.burst.bounce .iconAnimationContainer.optionActive, &.burst.swing .iconAnimationContainer.optionActive, &.burst.pulse .iconAnimationContainer.optionActive": {
|
|
40527
|
+
animationName: "none"
|
|
40528
|
+
}
|
|
40529
|
+
},
|
|
40161
40530
|
"@keyframes bounceBurst": {
|
|
40162
40531
|
"0%": {
|
|
40163
40532
|
transform: "translateY(0)"
|
|
@@ -40243,6 +40612,96 @@ const FABDisabled = (0,_emotion_styled__WEBPACK_IMPORTED_MODULE_0__/* ["default"
|
|
|
40243
40612
|
|
|
40244
40613
|
/***/ },
|
|
40245
40614
|
|
|
40615
|
+
/***/ 32735
|
|
40616
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
40617
|
+
|
|
40618
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
40619
|
+
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
40620
|
+
/* harmony export */ });
|
|
40621
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
|
|
40622
|
+
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74506);
|
|
40623
|
+
/* harmony import */ var _cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2854);
|
|
40624
|
+
/* harmony import */ var _StatusLiveRegion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(63813);
|
|
40625
|
+
|
|
40626
|
+
|
|
40627
|
+
|
|
40628
|
+
|
|
40629
|
+
|
|
40630
|
+
// Keyed by the File object, which stays the same across every snapshot the
|
|
40631
|
+
// middleware dispatches, and disappears with the chip (removed or sent) — so
|
|
40632
|
+
// nothing is announced twice and nothing is kept alive. Module-level like the
|
|
40633
|
+
// StatusLiveRegion listeners: one widget instance per page.
|
|
40634
|
+
const announcedFiles = new WeakSet();
|
|
40635
|
+
|
|
40636
|
+
// An attachment has an outcome once it failed (any reason), was cancelled by
|
|
40637
|
+
// removal, or finished uploading; 30/50 are the in-flight progress values.
|
|
40638
|
+
const hasSettled = item => Boolean(item.hasUploadError || item.isCancelled || item.progressPercentage === 100);
|
|
40639
|
+
|
|
40640
|
+
/**
|
|
40641
|
+
* Announces the outcome of file uploads through the status live region
|
|
40642
|
+
* (WCAG 4.1.3 Status Messages, techniques ARIA22 / ARIA19). Sighted users see
|
|
40643
|
+
* the attachment chip drop its progress bar, or turn red with the reason
|
|
40644
|
+
* ("Upload Failed", "Upload Failed: File size > 10MB", "Upload Failed:
|
|
40645
|
+
* Infected File"); neither reaches a screen reader,
|
|
40646
|
+
* and the failure additionally disables Send without saying why.
|
|
40647
|
+
*
|
|
40648
|
+
* Announced politely via <StatusLiveRegion> (role="status") — deliberately
|
|
40649
|
+
* not through role="alert": the user has just triggered the upload and is
|
|
40650
|
+
* waiting for its result, so a polite message is voiced promptly anyway, and
|
|
40651
|
+
* an assertive one may clear the queued announcement of an incoming chat
|
|
40652
|
+
* message (ARIA 1.2 lets assistive technology drop queued polite changes when
|
|
40653
|
+
* an assertive one arrives). This matches every other error in the widget
|
|
40654
|
+
* (connection and speech-recognition notifications), see docs/accessibility.md.
|
|
40655
|
+
*
|
|
40656
|
+
* Each attachment is announced as soon as it has an outcome — a file
|
|
40657
|
+
* rejected up front (too large) at once, even while a sibling is still
|
|
40658
|
+
* uploading: that rejection already disables Send, and the sibling's upload
|
|
40659
|
+
* has no timeout, so waiting for it could delay the announcement without
|
|
40660
|
+
* bound. Outcomes that land in the same store update are still read as one
|
|
40661
|
+
* message, failures first (file name + the reason shown in the chip), then
|
|
40662
|
+
* the successes as one count — several uploads finishing together, or every
|
|
40663
|
+
* file failing on the token request, stay a single sentence. Successive
|
|
40664
|
+
* messages are safe because <StatusLiveRegion> appends rather than replaces
|
|
40665
|
+
* (see SrOnlyLiveRegion's "append" mode), so an earlier outcome is never
|
|
40666
|
+
* pulled from under the screen reader by a later one.
|
|
40667
|
+
*
|
|
40668
|
+
* The middleware mutates the file items in place and re-dispatches snapshots
|
|
40669
|
+
* of the same array (+100ms and once the uploads settle), so the outcome is
|
|
40670
|
+
* derived from the items' fields on every store update rather than from the
|
|
40671
|
+
* array identity.
|
|
40672
|
+
*/
|
|
40673
|
+
const FileUploadAnnouncer = () => {
|
|
40674
|
+
const fileList = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__/* .useSelector */ .d4)(state => state.input.fileList);
|
|
40675
|
+
const ariaLabels = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__/* .useSelector */ .d4)(state => state.config.settings.customTranslations?.ariaLabels);
|
|
40676
|
+
// Re-evaluated on every dispatch; a string, so unchanged outcomes never re-render.
|
|
40677
|
+
const outcomeSignature = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__/* .useSelector */ .d4)(state => state.input.fileList.map(item => `${item.hasUploadError ? "e" : ""}${item.isCancelled ? "c" : ""}${item.progressPercentage ?? ""}`).join("|"));
|
|
40678
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
40679
|
+
const pending = fileList.filter(item => hasSettled(item) && !item.isCancelled && !announcedFiles.has(item.file));
|
|
40680
|
+
if (!pending.length) return;
|
|
40681
|
+
pending.forEach(item => announcedFiles.add(item.file));
|
|
40682
|
+
const failed = pending.filter(item => item.hasUploadError);
|
|
40683
|
+
const uploaded = pending.filter(item => !item.hasUploadError);
|
|
40684
|
+
const segments = failed.map(item => (0,_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__/* .formatTemplate */ .sN)(ariaLabels?.fileAttachmentFailed ?? "{fileName}: {reason}", {
|
|
40685
|
+
fileName: item.file.name,
|
|
40686
|
+
reason: item.uploadErrorReason ?? ""
|
|
40687
|
+
}));
|
|
40688
|
+
if (uploaded.length === 1) {
|
|
40689
|
+
segments.push((0,_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__/* .formatTemplate */ .sN)(ariaLabels?.fileAttachmentUploaded ?? "{fileName} attached", {
|
|
40690
|
+
fileName: uploaded[0].file.name
|
|
40691
|
+
}));
|
|
40692
|
+
} else if (uploaded.length > 1) {
|
|
40693
|
+
segments.push((0,_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__/* .formatTemplate */ .sN)(ariaLabels?.fileAttachmentsUploaded ?? "{count} files attached", {
|
|
40694
|
+
count: String(uploaded.length)
|
|
40695
|
+
}));
|
|
40696
|
+
}
|
|
40697
|
+
(0,_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_3__/* .announceStatus */ .a)(segments.join(". "));
|
|
40698
|
+
}, [fileList, outcomeSignature, ariaLabels]);
|
|
40699
|
+
return null;
|
|
40700
|
+
};
|
|
40701
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FileUploadAnnouncer);
|
|
40702
|
+
|
|
40703
|
+
/***/ },
|
|
40704
|
+
|
|
40246
40705
|
/***/ 97475
|
|
40247
40706
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
40248
40707
|
|
|
@@ -40845,6 +41304,108 @@ const HomeScreenAnnouncer = ({
|
|
|
40845
41304
|
|
|
40846
41305
|
/***/ },
|
|
40847
41306
|
|
|
41307
|
+
/***/ 71374
|
|
41308
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
41309
|
+
|
|
41310
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
41311
|
+
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
41312
|
+
/* harmony export */ });
|
|
41313
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
|
|
41314
|
+
/* harmony import */ var _emotion_styled__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(84937);
|
|
41315
|
+
/* harmony import */ var _assets_pause_16px_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21909);
|
|
41316
|
+
/* harmony import */ var _assets_play_16px_svg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6663);
|
|
41317
|
+
|
|
41318
|
+
|
|
41319
|
+
|
|
41320
|
+
|
|
41321
|
+
const PauseButton = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.button(({
|
|
41322
|
+
theme
|
|
41323
|
+
}) => ({
|
|
41324
|
+
// Fixed like the launcher (right 20px / bottom 14px, 50x50 — see
|
|
41325
|
+
// embedded-webchat-styles.css) and like the teaser message: a 24x24
|
|
41326
|
+
// pointer target (SC 2.5.8) centred on the launcher's bottom-right edge,
|
|
41327
|
+
// clear of its 20px icon and of the unread badge (top-right). stylis-rtl
|
|
41328
|
+
// mirrors `right` to `left` for RTL pages, matching the launcher's own
|
|
41329
|
+
// RTL rule.
|
|
41330
|
+
position: "fixed",
|
|
41331
|
+
right: 13,
|
|
41332
|
+
bottom: 7,
|
|
41333
|
+
width: 24,
|
|
41334
|
+
height: 24,
|
|
41335
|
+
padding: 0,
|
|
41336
|
+
margin: 0,
|
|
41337
|
+
display: "flex",
|
|
41338
|
+
alignItems: "center",
|
|
41339
|
+
justifyContent: "center",
|
|
41340
|
+
boxSizing: "border-box",
|
|
41341
|
+
cursor: "pointer",
|
|
41342
|
+
borderRadius: "50%",
|
|
41343
|
+
border: `2px solid ${theme.white}`,
|
|
41344
|
+
backgroundColor: theme.primaryColor,
|
|
41345
|
+
color: theme.primaryContrastColor,
|
|
41346
|
+
boxShadow: theme.shadow,
|
|
41347
|
+
// Above the launcher (z-index 1 in the widget root's stacking context)
|
|
41348
|
+
zIndex: 2,
|
|
41349
|
+
// Fine pointers: hidden until the launcher (its preceding sibling — the
|
|
41350
|
+
// sibling rule lives in FAB.tsx) is hovered or keyboard-focused, or the
|
|
41351
|
+
// button itself is; it overlaps the launcher's edge, so the pointer can
|
|
41352
|
+
// move onto it without a gap. It sits beside the launcher's icon, not
|
|
41353
|
+
// over it, so SC 1.4.13 needs no dismiss key. Kept in the DOM and
|
|
41354
|
+
// focusable at all times.
|
|
41355
|
+
opacity: 0,
|
|
41356
|
+
transition: "opacity 150ms ease-in-out",
|
|
41357
|
+
"&:hover": {
|
|
41358
|
+
opacity: 1
|
|
41359
|
+
},
|
|
41360
|
+
"&:focus-visible": {
|
|
41361
|
+
opacity: 1,
|
|
41362
|
+
outline: `2px solid ${theme.primaryColorFocus}`,
|
|
41363
|
+
outlineOffset: 2
|
|
41364
|
+
},
|
|
41365
|
+
// No hover on touch devices: always visible (SC 2.2.2 mechanism must be
|
|
41366
|
+
// reachable without opening the chat window).
|
|
41367
|
+
"@media (hover: none)": {
|
|
41368
|
+
opacity: 1
|
|
41369
|
+
},
|
|
41370
|
+
// The animation itself is suppressed under reduced motion (FAB.tsx), so
|
|
41371
|
+
// there is nothing to pause.
|
|
41372
|
+
"@media (prefers-reduced-motion: reduce)": {
|
|
41373
|
+
display: "none"
|
|
41374
|
+
},
|
|
41375
|
+
"& svg": {
|
|
41376
|
+
width: 12,
|
|
41377
|
+
height: 12,
|
|
41378
|
+
display: "block"
|
|
41379
|
+
}
|
|
41380
|
+
}));
|
|
41381
|
+
/**
|
|
41382
|
+
* Pause / resume control for the launcher icon animation (WCAG 2.2.2 Pause,
|
|
41383
|
+
* Stop, Hide — CGY-39786). Rendered by WebchatUI as the launcher's following
|
|
41384
|
+
* sibling, opt-in via `layout.enableIconAnimationPauseButton`. Like the audio player's play/pause button, the
|
|
41385
|
+
* accessible name states the action the press will perform and switches
|
|
41386
|
+
* together with the icon; no `aria-pressed`, which must not be combined with
|
|
41387
|
+
* a changing name (APG button pattern).
|
|
41388
|
+
*/
|
|
41389
|
+
const IconAnimationPauseButton = ({
|
|
41390
|
+
paused,
|
|
41391
|
+
onToggle,
|
|
41392
|
+
pauseLabel,
|
|
41393
|
+
resumeLabel
|
|
41394
|
+
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(PauseButton, {
|
|
41395
|
+
type: "button",
|
|
41396
|
+
className: "webchat-toggle-button-animation-pause",
|
|
41397
|
+
id: "webchatIconAnimationPauseButton",
|
|
41398
|
+
"aria-label": paused ? resumeLabel : pauseLabel,
|
|
41399
|
+
onClick: onToggle
|
|
41400
|
+
}, paused ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_assets_play_16px_svg__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, {
|
|
41401
|
+
"aria-hidden": true
|
|
41402
|
+
}) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_assets_pause_16px_svg__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A, {
|
|
41403
|
+
"aria-hidden": true
|
|
41404
|
+
}));
|
|
41405
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (IconAnimationPauseButton);
|
|
41406
|
+
|
|
41407
|
+
/***/ },
|
|
41408
|
+
|
|
40848
41409
|
/***/ 39966
|
|
40849
41410
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
40850
41411
|
|
|
@@ -41695,6 +42256,21 @@ const ScreenReaderLiveRegion = ({
|
|
|
41695
42256
|
// window later would otherwise read long-gone status text; removing the node
|
|
41696
42257
|
// is silent (removals are not announced under aria-relevant="additions text").
|
|
41697
42258
|
const CLEAR_DELAY_MS = 15000;
|
|
42259
|
+
|
|
42260
|
+
/**
|
|
42261
|
+
* How successive messages share the region:
|
|
42262
|
+
* - "replace" (default): one node at a time — the next message swaps the
|
|
42263
|
+
* node out. Right for regions whose messages supersede each other (chat
|
|
42264
|
+
* log, typing indicator, unread count, teaser).
|
|
42265
|
+
* - "append": every message gets its own node, kept until its own 15s clear,
|
|
42266
|
+
* and the region is not atomic so only the added node is voiced. Right for
|
|
42267
|
+
* independent status messages that may land moments apart: a swap removes
|
|
42268
|
+
* the previous node, and NVDA drops a queued polite announcement whose
|
|
42269
|
+
* node left the DOM before it was voiced — the earlier message would be
|
|
42270
|
+
* lost. The clear is per message, so browsing users still never meet
|
|
42271
|
+
* text older than 15s.
|
|
42272
|
+
*/
|
|
42273
|
+
|
|
41698
42274
|
/**
|
|
41699
42275
|
* Shared visually-hidden live region body (WCAG 4.1.3 Status Messages).
|
|
41700
42276
|
*
|
|
@@ -41704,8 +42280,8 @@ const CLEAR_DELAY_MS = 15000;
|
|
|
41704
42280
|
* cleared from the DOM after 15s.
|
|
41705
42281
|
*
|
|
41706
42282
|
* Used by <ScreenReaderLiveRegion> (chat messages) and <StatusLiveRegion>
|
|
41707
|
-
* (toasts + screen changes); they stay separate DOM regions
|
|
41708
|
-
* announcements queue instead of overwriting each other.
|
|
42283
|
+
* (toasts + screen changes + upload outcomes); they stay separate DOM regions
|
|
42284
|
+
* so simultaneous announcements queue instead of overwriting each other.
|
|
41709
42285
|
*
|
|
41710
42286
|
* The text is deliberately committed via state in an effect — one commit
|
|
41711
42287
|
* after the `message` prop changes — rather than rendered directly from the
|
|
@@ -41716,26 +42292,48 @@ const CLEAR_DELAY_MS = 15000;
|
|
|
41716
42292
|
const SrOnlyLiveRegion = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(({
|
|
41717
42293
|
id,
|
|
41718
42294
|
message,
|
|
41719
|
-
role
|
|
42295
|
+
role,
|
|
42296
|
+
mode = "replace"
|
|
41720
42297
|
}, ref) => {
|
|
41721
|
-
const [displayed, setDisplayed] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(
|
|
42298
|
+
const [displayed, setDisplayed] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
|
|
42299
|
+
// append mode: one clear timer per message, all cancelled on unmount
|
|
42300
|
+
const clearTimersRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(new Map());
|
|
41722
42301
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
41723
|
-
|
|
42302
|
+
if (mode === "replace") {
|
|
42303
|
+
setDisplayed(message ? [message] : []);
|
|
42304
|
+
if (!message) return;
|
|
42305
|
+
const clearTimer = setTimeout(() => setDisplayed([]), CLEAR_DELAY_MS);
|
|
42306
|
+
return () => clearTimeout(clearTimer);
|
|
42307
|
+
}
|
|
41724
42308
|
if (!message) return;
|
|
41725
|
-
const
|
|
41726
|
-
|
|
41727
|
-
|
|
42309
|
+
const {
|
|
42310
|
+
id: messageId
|
|
42311
|
+
} = message;
|
|
42312
|
+
setDisplayed(previous => previous.some(item => item.id === messageId) ? previous : [...previous, message]);
|
|
42313
|
+
const clearTimer = setTimeout(() => {
|
|
42314
|
+
clearTimersRef.current.delete(messageId);
|
|
42315
|
+
setDisplayed(previous => previous.filter(item => item.id !== messageId));
|
|
42316
|
+
}, CLEAR_DELAY_MS);
|
|
42317
|
+
clearTimersRef.current.set(messageId, clearTimer);
|
|
42318
|
+
}, [message, mode]);
|
|
42319
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
42320
|
+
const clearTimers = clearTimersRef.current;
|
|
42321
|
+
return () => {
|
|
42322
|
+
clearTimers.forEach(clearTimeout);
|
|
42323
|
+
clearTimers.clear();
|
|
42324
|
+
};
|
|
42325
|
+
}, []);
|
|
41728
42326
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement("div", {
|
|
41729
42327
|
ref: ref,
|
|
41730
42328
|
role: role,
|
|
41731
42329
|
"aria-live": "polite",
|
|
41732
42330
|
"aria-relevant": "additions text",
|
|
41733
|
-
"aria-atomic": "true",
|
|
42331
|
+
"aria-atomic": mode === "replace" ? "true" : "false",
|
|
41734
42332
|
id: id,
|
|
41735
42333
|
className: "sr-only"
|
|
41736
|
-
}, displayed
|
|
41737
|
-
key:
|
|
41738
|
-
},
|
|
42334
|
+
}, displayed.map(item => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement("div", {
|
|
42335
|
+
key: item.id
|
|
42336
|
+
}, item.text)));
|
|
41739
42337
|
});
|
|
41740
42338
|
SrOnlyLiveRegion.displayName = "SrOnlyLiveRegion";
|
|
41741
42339
|
|
|
@@ -41761,14 +42359,29 @@ SrOnlyLiveRegion.displayName = "SrOnlyLiveRegion";
|
|
|
41761
42359
|
// mounted instance would announce every other instance's statuses.
|
|
41762
42360
|
|
|
41763
42361
|
const statusListeners = new Set();
|
|
42362
|
+
const pendingAnnouncements = new Set();
|
|
41764
42363
|
let statusCounter = 0;
|
|
41765
42364
|
|
|
41766
42365
|
/**
|
|
41767
42366
|
* Announces arbitrary status text (e.g. a screen change) through the
|
|
41768
42367
|
* <StatusLiveRegion>. No-op while the region is not mounted (webchat closed).
|
|
42368
|
+
*
|
|
42369
|
+
* `delayMs` defers the announcement, e.g. past a focus move that would
|
|
42370
|
+
* otherwise cancel it. Pending delayed announcements belong to the region:
|
|
42371
|
+
* they are dropped when it unmounts (webchat closed), so a result from a
|
|
42372
|
+
* previous chat window is never voiced in the next one — and the caller
|
|
42373
|
+
* (typically a screen that unmounts right away) owns no timer.
|
|
41769
42374
|
*/
|
|
41770
|
-
function announceStatus(text) {
|
|
41771
|
-
|
|
42375
|
+
function announceStatus(text, options) {
|
|
42376
|
+
if (!options?.delayMs) {
|
|
42377
|
+
statusListeners.forEach(listener => listener(text));
|
|
42378
|
+
return;
|
|
42379
|
+
}
|
|
42380
|
+
const handle = setTimeout(() => {
|
|
42381
|
+
pendingAnnouncements.delete(handle);
|
|
42382
|
+
statusListeners.forEach(listener => listener(text));
|
|
42383
|
+
}, options.delayMs);
|
|
42384
|
+
pendingAnnouncements.add(handle);
|
|
41772
42385
|
}
|
|
41773
42386
|
|
|
41774
42387
|
/**
|
|
@@ -41784,7 +42397,14 @@ function announceStatus(text) {
|
|
|
41784
42397
|
* role="status" wrapper) to the DOM only when the notification fires,
|
|
41785
42398
|
* which live-region processing ignores — so toasts are mirrored here and
|
|
41786
42399
|
* silenced at the source (see silencedAriaProps in Notifications.tsx);
|
|
41787
|
-
* - direct announcements via announceStatus() (e.g. "home screen appeared"
|
|
42400
|
+
* - direct announcements via announceStatus() (e.g. "home screen appeared",
|
|
42401
|
+
* file upload outcomes and removals).
|
|
42402
|
+
*
|
|
42403
|
+
* Renders in "append" mode: these messages are independent of each other
|
|
42404
|
+
* and can land moments apart (a rejected attachment, then its sibling's
|
|
42405
|
+
* upload finishing), so each keeps its own node until its own 15s clear
|
|
42406
|
+
* instead of being swapped out by the next — a swap would let a screen
|
|
42407
|
+
* reader drop the earlier one before voicing it. See SrOnlyLiveRegion.
|
|
41788
42408
|
*/
|
|
41789
42409
|
const StatusLiveRegion = () => {
|
|
41790
42410
|
const {
|
|
@@ -41800,6 +42420,8 @@ const StatusLiveRegion = () => {
|
|
|
41800
42420
|
statusListeners.add(listener);
|
|
41801
42421
|
return () => {
|
|
41802
42422
|
statusListeners.delete(listener);
|
|
42423
|
+
pendingAnnouncements.forEach(clearTimeout);
|
|
42424
|
+
pendingAnnouncements.clear();
|
|
41803
42425
|
};
|
|
41804
42426
|
}, []);
|
|
41805
42427
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
@@ -41826,6 +42448,7 @@ const StatusLiveRegion = () => {
|
|
|
41826
42448
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_SrOnlyLiveRegion__WEBPACK_IMPORTED_MODULE_2__/* .SrOnlyLiveRegion */ .Y, {
|
|
41827
42449
|
id: "webchatStatusLiveRegion",
|
|
41828
42450
|
role: "status",
|
|
42451
|
+
mode: "append",
|
|
41829
42452
|
message: status
|
|
41830
42453
|
});
|
|
41831
42454
|
};
|
|
@@ -42540,6 +43163,8 @@ const ChatOptionsFooter = props => {
|
|
|
42540
43163
|
/* harmony import */ var _webchat_store_messages_message_reducer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(22284);
|
|
42541
43164
|
/* harmony import */ var _Modal_DeleteConfirmModal__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(75691);
|
|
42542
43165
|
/* harmony import */ var _webchat_store_options_options__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(48242);
|
|
43166
|
+
/* harmony import */ var _StatusLiveRegion__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(63813);
|
|
43167
|
+
|
|
42543
43168
|
|
|
42544
43169
|
|
|
42545
43170
|
|
|
@@ -42551,6 +43176,13 @@ const ChatOptionsFooter = props => {
|
|
|
42551
43176
|
|
|
42552
43177
|
|
|
42553
43178
|
|
|
43179
|
+
|
|
43180
|
+
// The chat screen that replaces this one autofocuses the message input 200ms
|
|
43181
|
+
// after it mounts; the announcement is delayed past that so it follows the
|
|
43182
|
+
// focus utterance instead of being cancelled by it (same reasoning as
|
|
43183
|
+
// HomeScreenAnnouncer's 600ms). The timer belongs to the status live region,
|
|
43184
|
+
// which drops it if the chat window is closed meanwhile.
|
|
43185
|
+
const ANNOUNCE_DELAY_MS = 600;
|
|
42554
43186
|
const Container = _emotion_styled__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.div({
|
|
42555
43187
|
display: "flex",
|
|
42556
43188
|
flexDirection: "column",
|
|
@@ -42602,6 +43234,12 @@ const DeleteConversation = props => {
|
|
|
42602
43234
|
onDeleteModalStateChange(false);
|
|
42603
43235
|
deleteButtonRef.current?.focus();
|
|
42604
43236
|
dispatch((0,_webchat_store_ui_ui_reducer__WEBPACK_IMPORTED_MODULE_5__/* .setShowChatOptionsScreen */ .QE)(false));
|
|
43237
|
+
// Status message for the completed deletion (SC 4.1.3, CGY-39786). The
|
|
43238
|
+
// live region lives in the open chat window and survives this screen's
|
|
43239
|
+
// unmount.
|
|
43240
|
+
(0,_StatusLiveRegion__WEBPACK_IMPORTED_MODULE_10__/* .announceStatus */ .a)(config.settings.customTranslations?.conversation_deleted ?? "Conversation deleted", {
|
|
43241
|
+
delayMs: ANNOUNCE_DELAY_MS
|
|
43242
|
+
});
|
|
42605
43243
|
};
|
|
42606
43244
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(react__WEBPACK_IMPORTED_MODULE_0__["default"].Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(Container, {
|
|
42607
43245
|
className: "webchat-delete-conversation-container"
|
|
@@ -42967,6 +43605,29 @@ const ConversationsList = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["defau
|
|
|
42967
43605
|
outline: "none"
|
|
42968
43606
|
}
|
|
42969
43607
|
}));
|
|
43608
|
+
|
|
43609
|
+
// Programmatic focus target (tabIndex -1, not in the Tab order): after
|
|
43610
|
+
// "Delete all conversations" focus lands here so the outcome is read out
|
|
43611
|
+
// without a live region (SC 4.1.3, CGY-39786). Centred in the empty list;
|
|
43612
|
+
// the focus ring shows for keyboard-initiated focus (SC 2.4.7).
|
|
43613
|
+
const EmptyListText = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.p(({
|
|
43614
|
+
theme
|
|
43615
|
+
}) => ({
|
|
43616
|
+
margin: "auto",
|
|
43617
|
+
padding: "4px 8px",
|
|
43618
|
+
fontSize: 16,
|
|
43619
|
+
fontWeight: 400,
|
|
43620
|
+
lineHeight: "24px",
|
|
43621
|
+
textAlign: "center",
|
|
43622
|
+
color: theme.black10,
|
|
43623
|
+
"&:focus": {
|
|
43624
|
+
outline: "none"
|
|
43625
|
+
},
|
|
43626
|
+
"&:focus-visible": {
|
|
43627
|
+
outline: `2px solid ${theme.primaryColorFocus}`,
|
|
43628
|
+
outlineOffset: 2
|
|
43629
|
+
}
|
|
43630
|
+
}));
|
|
42970
43631
|
const ConversationsListActions = _emotion_styled__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.div(({
|
|
42971
43632
|
theme
|
|
42972
43633
|
}) => ({
|
|
@@ -42996,7 +43657,8 @@ const PrevConversationsList = props => {
|
|
|
42996
43657
|
onSetShowPrevConversations,
|
|
42997
43658
|
onSwitchSession,
|
|
42998
43659
|
currentSession,
|
|
42999
|
-
startNewConversationButtonRef
|
|
43660
|
+
startNewConversationButtonRef,
|
|
43661
|
+
emptyListTextRef
|
|
43000
43662
|
} = props;
|
|
43001
43663
|
|
|
43002
43664
|
// we sort the conversation based on last message timestamp
|
|
@@ -43018,7 +43680,11 @@ const PrevConversationsList = props => {
|
|
|
43018
43680
|
className: "webchat-prev-conversations-root"
|
|
43019
43681
|
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(ConversationsList, {
|
|
43020
43682
|
className: "webchat-prev-conversations-content"
|
|
43021
|
-
}, sessions.length
|
|
43683
|
+
}, sessions.length === 0 && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(EmptyListText, {
|
|
43684
|
+
className: "webchat-prev-conversations-empty",
|
|
43685
|
+
ref: emptyListTextRef,
|
|
43686
|
+
tabIndex: -1
|
|
43687
|
+
}, config.settings.homeScreen?.previousConversations?.emptyListText || "No previous conversations"), sessions.length > 0 && sessions.map((session, i) => {
|
|
43022
43688
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["default"].createElement(_ConversationsListItem__WEBPACK_IMPORTED_MODULE_2__/* .ConversationsListItem */ .Q, {
|
|
43023
43689
|
key: i,
|
|
43024
43690
|
index: i,
|
|
@@ -45195,8 +45861,13 @@ function setHasAcceptedTermsInStorage(browserStorage, userId) {
|
|
|
45195
45861
|
/* unused harmony exports allowedHtmlTags, allowedHtmlAttributes */
|
|
45196
45862
|
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(99418);
|
|
45197
45863
|
/* harmony import */ var _store_store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6236);
|
|
45864
|
+
/* harmony import */ var _common_constants_blocked_tags__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(36886);
|
|
45865
|
+
|
|
45866
|
+
|
|
45198
45867
|
|
|
45199
45868
|
|
|
45869
|
+
// Re-export so existing consumers of sanitize.ts do not need a path change.
|
|
45870
|
+
|
|
45200
45871
|
|
|
45201
45872
|
// Tags removed from the previous allow-list to align with DOMPurify's secure defaults
|
|
45202
45873
|
// (WCH-SI10-001). Each tag enables a distinct attack vector:
|
|
@@ -45226,14 +45897,26 @@ const allowedHtmlTags = ["a", "abbr", "acronym", "address", "area", "article", "
|
|
|
45226
45897
|
const allowedHtmlAttributes = ["accept", "accept-charset", "accesskey", "align", "alt", "autocomplete", "autofocus", "autoplay", "bgcolor", "border", "charset", "checked", "cite", "class", "color", "cols", "colspan", "content", "contenteditable", "controls", "coords", "data", "data-*", "datetime", "default", "dir", "dirname", "disabled", "download", "draggable", "dropzone", "enctype", "for", "form", "headers", "height", "hidden", "high", "href", "hreflang", "http-equiv", "id", "ismap", "kind", "label", "lang", "list", "loop", "low", "max", "maxlength", "media", "method", "min", "multiple", "muted", "name", "novalidate", "open", "optimum", "pattern", "placeholder", "poster", "preload", "readonly", "rel", "required", "reversed", "rows", "rowspan", "scope", "selected", "shape", "size", "sizes", "span", "spellcheck", "src", "srclang", "srcset", "start", "step", "tabindex", "title", "translate", "type", "usemap", "value", "width", "wrap"];
|
|
45227
45898
|
const config = {
|
|
45228
45899
|
ALLOWED_TAGS: allowedHtmlTags,
|
|
45229
|
-
ALLOWED_ATTR: allowedHtmlAttributes
|
|
45900
|
+
ALLOWED_ATTR: allowedHtmlAttributes,
|
|
45901
|
+
// FORBID_TAGS overrides ALLOWED_TAGS inside DOMPurify — tags listed here are
|
|
45902
|
+
// stripped unconditionally, whether the default allow-list or a custom one is used.
|
|
45903
|
+
FORBID_TAGS: [..._common_constants_blocked_tags__WEBPACK_IMPORTED_MODULE_2__/* .ALWAYS_BLOCKED_TAGS */ .Z]
|
|
45230
45904
|
};
|
|
45231
45905
|
const sanitizeHTML = text => {
|
|
45232
45906
|
const customAllowedHtmlTags = _store_store__WEBPACK_IMPORTED_MODULE_1__/* .storeRef */ .PU?.getState().config.settings.widgetSettings.customAllowedHtmlTags;
|
|
45233
|
-
|
|
45234
|
-
|
|
45235
|
-
|
|
45236
|
-
|
|
45907
|
+
let configToUse = config;
|
|
45908
|
+
if (Array.isArray(customAllowedHtmlTags)) {
|
|
45909
|
+
// Pre-filter the tenant-supplied list before passing to DOMPurify (defence-in-depth).
|
|
45910
|
+
// config-reducer already strips blocked tags and non-strings at config-load time, but
|
|
45911
|
+
// we guard here too in case sanitizeHTML is ever called outside the normal config path.
|
|
45912
|
+
// Non-array values (e.g. a plain string) fall through to the default config — same
|
|
45913
|
+
// permissive fallback as config-reducer's sanitizeCustomAllowedHtmlTags().
|
|
45914
|
+
const safeTags = customAllowedHtmlTags.filter(tag => typeof tag === "string" && !_common_constants_blocked_tags__WEBPACK_IMPORTED_MODULE_2__/* .ALWAYS_BLOCKED_TAGS */ .Z.has(tag.toLowerCase().trim()));
|
|
45915
|
+
configToUse = {
|
|
45916
|
+
...config,
|
|
45917
|
+
ALLOWED_TAGS: safeTags
|
|
45918
|
+
};
|
|
45919
|
+
}
|
|
45237
45920
|
return dompurify__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.sanitize(text, configToUse).toString();
|
|
45238
45921
|
};
|
|
45239
45922
|
const stripHtmlToInertText = text => {
|
|
@@ -45616,7 +46299,13 @@ const createConfigMiddleware = (url, overrideWebchatSettings) => store => next =
|
|
|
45616
46299
|
/* unused harmony exports getInitialState, APPLY_WEBCHAT_SETTINGS_OVERRIDES, SET_CONFIG, UPDATE_SETTINGS */
|
|
45617
46300
|
/* harmony import */ var lodash_merge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(77202);
|
|
45618
46301
|
/* harmony import */ var lodash_merge__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_merge__WEBPACK_IMPORTED_MODULE_0__);
|
|
46302
|
+
/* harmony import */ var _common_constants_blocked_tags__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(36886);
|
|
45619
46303
|
|
|
46304
|
+
|
|
46305
|
+
function sanitizeCustomAllowedHtmlTags(tags) {
|
|
46306
|
+
if (!Array.isArray(tags)) return undefined;
|
|
46307
|
+
return tags.filter(tag => typeof tag === "string" && !_common_constants_blocked_tags__WEBPACK_IMPORTED_MODULE_1__/* .ALWAYS_BLOCKED_TAGS */ .Z.has(tag.toLowerCase().trim()));
|
|
46308
|
+
}
|
|
45620
46309
|
const getInitialState = () => ({
|
|
45621
46310
|
URLToken: "",
|
|
45622
46311
|
initialSessionId: "",
|
|
@@ -45640,12 +46329,14 @@ const getInitialState = () => ({
|
|
|
45640
46329
|
enableGenericHTMLStyling: false,
|
|
45641
46330
|
disableHtmlContentSanitization: false,
|
|
45642
46331
|
disableUrlButtonSanitization: false,
|
|
46332
|
+
enableIconAnimationPauseButton: false,
|
|
45643
46333
|
watermark: "default",
|
|
45644
46334
|
watermarkText: "Powered by Cognigy.AI",
|
|
45645
46335
|
watermarkUrl: "",
|
|
45646
46336
|
disableBotOutputBorder: false,
|
|
45647
46337
|
botOutputMaxWidthPercentage: 73,
|
|
45648
|
-
chatWindowWidth: 460
|
|
46338
|
+
chatWindowWidth: 460,
|
|
46339
|
+
galleryCardTitleBelowImage: false
|
|
45649
46340
|
},
|
|
45650
46341
|
colors: {
|
|
45651
46342
|
primaryColor: "",
|
|
@@ -45843,6 +46534,12 @@ const config = (state = getInitialState(), action) => {
|
|
|
45843
46534
|
{
|
|
45844
46535
|
// deepMerge the settings since we have nested settings since v3
|
|
45845
46536
|
const mergedSettings = lodash_merge__WEBPACK_IMPORTED_MODULE_0___default()({}, state.settings, action.config.settings);
|
|
46537
|
+
|
|
46538
|
+
// Strip dangerous tags from the tenant-supplied allow-list before storing so both
|
|
46539
|
+
// webchat's sanitizeHTML and @cognigy/chat-components receive the safe list.
|
|
46540
|
+
if (mergedSettings.widgetSettings?.customAllowedHtmlTags !== undefined) {
|
|
46541
|
+
mergedSettings.widgetSettings.customAllowedHtmlTags = sanitizeCustomAllowedHtmlTags(mergedSettings.widgetSettings.customAllowedHtmlTags);
|
|
46542
|
+
}
|
|
45846
46543
|
return {
|
|
45847
46544
|
...state,
|
|
45848
46545
|
...action.config,
|
|
@@ -45854,6 +46551,11 @@ const config = (state = getInitialState(), action) => {
|
|
|
45854
46551
|
{
|
|
45855
46552
|
// deepMerge the settings since we have nested settings since v3
|
|
45856
46553
|
const mergedSettings = lodash_merge__WEBPACK_IMPORTED_MODULE_0___default()({}, state.settings, action.payload);
|
|
46554
|
+
|
|
46555
|
+
// Same safety filter as SET_CONFIG — keep the stored list clean.
|
|
46556
|
+
if (mergedSettings.widgetSettings?.customAllowedHtmlTags !== undefined) {
|
|
46557
|
+
mergedSettings.widgetSettings.customAllowedHtmlTags = sanitizeCustomAllowedHtmlTags(mergedSettings.widgetSettings.customAllowedHtmlTags);
|
|
46558
|
+
}
|
|
45857
46559
|
return {
|
|
45858
46560
|
...state,
|
|
45859
46561
|
settings: mergedSettings
|
|
@@ -46242,6 +46944,8 @@ const inputCollation = (state = getInitialState(), action) => {
|
|
|
46242
46944
|
/* harmony export */ });
|
|
46243
46945
|
/* harmony import */ var _input_reducer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16967);
|
|
46244
46946
|
/* harmony import */ var _helper_endpoint__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11351);
|
|
46947
|
+
/* harmony import */ var _cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2854);
|
|
46948
|
+
|
|
46245
46949
|
|
|
46246
46950
|
|
|
46247
46951
|
const ADD_FILES_TO_LIST = "ADD_FILES_TO_LIST";
|
|
@@ -46257,18 +46961,34 @@ const createFileInputMiddleware = () => store => next => async action => {
|
|
|
46257
46961
|
fileAttachmentMaxSize,
|
|
46258
46962
|
embeddingConfiguration: {
|
|
46259
46963
|
_endpointTokenUrl
|
|
46260
|
-
}
|
|
46964
|
+
},
|
|
46965
|
+
customTranslations
|
|
46261
46966
|
} = store.getState().config.settings;
|
|
46262
46967
|
const existingFileList = store.getState().input.fileList;
|
|
46263
46968
|
let newFileList = [];
|
|
46264
46969
|
const fileAttachmentMaxSizeInMb = fileAttachmentMaxSize > 0 ? fileAttachmentMaxSize / (1024 * 1024) : 0;
|
|
46970
|
+
|
|
46971
|
+
// The reason is shown in the attachment chip and read out through
|
|
46972
|
+
// the status live region (FileUploadAnnouncer), so it is configurable
|
|
46973
|
+
// like every other user-facing string.
|
|
46974
|
+
const uploadFailedText = customTranslations?.file_upload_failed ?? "Upload Failed";
|
|
46975
|
+
// The specific reasons are prefixed with the generic failure text
|
|
46976
|
+
// ("Upload Failed: File size > 10MB", "Upload Failed: Infected
|
|
46977
|
+
// File"): on their own, next to the file's actual size, they read
|
|
46978
|
+
// as information about the file rather than as the reason it was
|
|
46979
|
+
// not attached, leaving the red colour as the only cue (SC 1.4.1)
|
|
46980
|
+
// — in the chip and in the announcement alike.
|
|
46981
|
+
const uploadInfectedText = `${uploadFailedText}: ${customTranslations?.file_upload_infected ?? "Infected File"}`;
|
|
46982
|
+
const uploadTooLargeText = `${uploadFailedText}: ${(0,_cognigy_chat_components__WEBPACK_IMPORTED_MODULE_2__/* .formatTemplate */ .sN)(customTranslations?.file_upload_too_large ?? "File size > {maxSizeInMb}MB", {
|
|
46983
|
+
maxSizeInMb: String(fileAttachmentMaxSizeInMb)
|
|
46984
|
+
})}`;
|
|
46265
46985
|
action.newFiles?.forEach(file => {
|
|
46266
46986
|
if (file.size > fileAttachmentMaxSize) {
|
|
46267
46987
|
newFileList.push({
|
|
46268
46988
|
file: file,
|
|
46269
46989
|
progressPercentage: 10,
|
|
46270
46990
|
hasUploadError: true,
|
|
46271
|
-
uploadErrorReason:
|
|
46991
|
+
uploadErrorReason: uploadTooLargeText
|
|
46272
46992
|
});
|
|
46273
46993
|
} else {
|
|
46274
46994
|
newFileList.push({
|
|
@@ -46278,6 +46998,14 @@ const createFileInputMiddleware = () => store => next => async action => {
|
|
|
46278
46998
|
}
|
|
46279
46999
|
});
|
|
46280
47000
|
store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileList */ .hM)(existingFileList.concat(newFileList)));
|
|
47001
|
+
|
|
47002
|
+
// The items are mutated in place below; the later dispatches only have
|
|
47003
|
+
// to re-render the CURRENT list. Re-dispatching the snapshot captured
|
|
47004
|
+
// above would resurrect chips the user removed (or a message sent) in
|
|
47005
|
+
// the meantime — and a removed file must not be uploaded or flag an
|
|
47006
|
+
// error either.
|
|
47007
|
+
const isStillListed = fileItem => store.getState().input.fileList.includes(fileItem);
|
|
47008
|
+
const refreshFileList = () => store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileList */ .hM)([...store.getState().input.fileList]));
|
|
46281
47009
|
const fileUploadTokenApiUrl = `${_endpointTokenUrl}/fileuploadtoken`;
|
|
46282
47010
|
let response;
|
|
46283
47011
|
let hasError = false;
|
|
@@ -46290,22 +47018,21 @@ const createFileInputMiddleware = () => store => next => async action => {
|
|
|
46290
47018
|
if (!fileItem.hasUploadError) {
|
|
46291
47019
|
fileItem.progressPercentage = 50;
|
|
46292
47020
|
fileItem.hasUploadError = hasError;
|
|
46293
|
-
fileItem.uploadErrorReason = hasError ?
|
|
47021
|
+
fileItem.uploadErrorReason = hasError ? uploadFailedText : fileItem.uploadErrorReason;
|
|
46294
47022
|
}
|
|
46295
47023
|
return fileItem;
|
|
46296
47024
|
});
|
|
46297
|
-
setTimeout(
|
|
46298
|
-
|
|
46299
|
-
|
|
46300
|
-
newFileList = (await Promise.all(newFileList.map(async fileItem => {
|
|
47025
|
+
setTimeout(refreshFileList, 100);
|
|
47026
|
+
await Promise.all(newFileList.map(async fileItem => {
|
|
47027
|
+
if (!isStillListed(fileItem)) return;
|
|
46301
47028
|
try {
|
|
46302
47029
|
if (!fileItem.hasUploadError && !fileItem.isCancelled) {
|
|
46303
47030
|
fileItem.abortController = new AbortController();
|
|
46304
47031
|
fileItem.uploadFileMeta = await (0,_helper_endpoint__WEBPACK_IMPORTED_MODULE_1__/* .uploadFile */ .QM)(fileItem.file, response.fileUploadUrl, response.token, fileItem.abortController);
|
|
46305
47032
|
if (fileItem.uploadFileMeta.status === "infected") {
|
|
46306
47033
|
fileItem.hasUploadError = true;
|
|
46307
|
-
fileItem.uploadErrorReason =
|
|
46308
|
-
store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileUploadError */ .AA)(true));
|
|
47034
|
+
fileItem.uploadErrorReason = uploadInfectedText;
|
|
47035
|
+
if (isStillListed(fileItem)) store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileUploadError */ .AA)(true));
|
|
46309
47036
|
}
|
|
46310
47037
|
fileItem.uploadFileMeta.fileName = fileItem.file.name;
|
|
46311
47038
|
fileItem.progressPercentage = 100;
|
|
@@ -46318,13 +47045,12 @@ const createFileInputMiddleware = () => store => next => async action => {
|
|
|
46318
47045
|
return;
|
|
46319
47046
|
} else {
|
|
46320
47047
|
fileItem.hasUploadError = true;
|
|
46321
|
-
fileItem.uploadErrorReason =
|
|
46322
|
-
store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileUploadError */ .AA)(true));
|
|
47048
|
+
fileItem.uploadErrorReason = uploadFailedText;
|
|
47049
|
+
if (isStillListed(fileItem)) store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileUploadError */ .AA)(true));
|
|
46323
47050
|
}
|
|
46324
47051
|
}
|
|
46325
|
-
|
|
46326
|
-
|
|
46327
|
-
store.dispatch((0,_input_reducer__WEBPACK_IMPORTED_MODULE_0__/* .setFileList */ .hM)(existingFileList.concat(newFileList)));
|
|
47052
|
+
}));
|
|
47053
|
+
refreshFileList();
|
|
46328
47054
|
break;
|
|
46329
47055
|
}
|
|
46330
47056
|
}
|
|
@@ -56408,9 +57134,10 @@ function _typeof(o) {
|
|
|
56408
57134
|
/* harmony export */ Vp: () => (/* binding */ TypingIndicator),
|
|
56409
57135
|
/* harmony export */ b$: () => (/* binding */ ChatEvent),
|
|
56410
57136
|
/* harmony export */ o5: () => (/* binding */ Typography),
|
|
57137
|
+
/* harmony export */ sN: () => (/* binding */ interpolateString),
|
|
56411
57138
|
/* harmony export */ wr: () => (/* binding */ ActionButtons)
|
|
56412
57139
|
/* harmony export */ });
|
|
56413
|
-
/* unused harmony exports PrimaryButton, SecondaryButton,
|
|
57140
|
+
/* unused harmony exports PrimaryButton, SecondaryButton, defaultAllowedHtmlTags, match */
|
|
56414
57141
|
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(71178);
|
|
56415
57142
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(51649);
|
|
56416
57143
|
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7516);
|
|
@@ -56420,6 +57147,10 @@ function _typeof(o) {
|
|
|
56420
57147
|
try {
|
|
56421
57148
|
if (typeof document != "undefined") {
|
|
56422
57149
|
var elementStyle = document.createElement("style");
|
|
57150
|
+
var nonce = document.head.querySelector("meta[property=csp-nonce]")?.getAttribute("content");
|
|
57151
|
+
if (nonce) {
|
|
57152
|
+
elementStyle.nonce = nonce;
|
|
57153
|
+
}
|
|
56423
57154
|
elementStyle.appendChild(document.createTextNode(`._bubble_1v5xk_1 {
|
|
56424
57155
|
border-radius: var(--cc-bubble-border-radius, 15px);
|
|
56425
57156
|
border: 1px solid var(--cc-border-bot-message);
|
|
@@ -56677,7 +57408,7 @@ article.user ._outgoing_1v5xk_52 {
|
|
|
56677
57408
|
._icon_ak7mc_52 svg {
|
|
56678
57409
|
fill: var(--cc-black-10);
|
|
56679
57410
|
}
|
|
56680
|
-
article .
|
|
57411
|
+
article ._wrapper_tochy_1 {
|
|
56681
57412
|
position: relative;
|
|
56682
57413
|
border-radius: var(--cc-bubble-border-radius);
|
|
56683
57414
|
max-width: 295px;
|
|
@@ -56685,53 +57416,58 @@ article ._wrapper_2f2tp_1 {
|
|
|
56685
57416
|
outline: none;
|
|
56686
57417
|
}
|
|
56687
57418
|
|
|
56688
|
-
article .
|
|
56689
|
-
article .
|
|
57419
|
+
article ._wrapper_tochy_1 ._fixedImage_tochy_9,
|
|
57420
|
+
article ._wrapper_tochy_1 ._flexImage_tochy_10 {
|
|
56690
57421
|
border-top-left-radius: var(--cc-bubble-border-radius);
|
|
56691
57422
|
border-top-right-radius: var(--cc-bubble-border-radius);
|
|
56692
57423
|
}
|
|
56693
57424
|
|
|
56694
|
-
|
|
56695
|
-
|
|
57425
|
+
/* Two-colour focus ring, as on the primary buttons and gallery links: the
|
|
57426
|
+
primary outline plus a 4px contrast band, so the ring stays visible whatever
|
|
57427
|
+
the image behind it (WCAG 2.4.7 Focus Visible, 1.4.11 Non-text Contrast). */
|
|
57428
|
+
article ._wrapper_tochy_1 ._fixedImage_tochy_9:focus-visible,
|
|
57429
|
+
article ._wrapper_tochy_1 ._flexImage_tochy_10:focus-visible {
|
|
56696
57430
|
outline: 2px solid var(--cc-primary-color-focus);
|
|
57431
|
+
outline-offset: 2px;
|
|
57432
|
+
box-shadow: 0 0 0 4px var(--cc-secondary-contrast-color);
|
|
56697
57433
|
}
|
|
56698
57434
|
|
|
56699
|
-
article .
|
|
57435
|
+
article ._wrapper_tochy_1 img {
|
|
56700
57436
|
border-radius: var(--cc-bubble-border-radius);
|
|
56701
57437
|
width: 100%;
|
|
56702
57438
|
display: block;
|
|
56703
57439
|
outline: none;
|
|
56704
57440
|
}
|
|
56705
|
-
.
|
|
57441
|
+
._wrapper_tochy_1._wrapperDownloadable_tochy_31 img {
|
|
56706
57442
|
border-bottom-left-radius: 0px;
|
|
56707
57443
|
border-bottom-right-radius: 0px;
|
|
56708
57444
|
}
|
|
56709
57445
|
|
|
56710
|
-
.
|
|
57446
|
+
._wrapperDownloadable_tochy_31 {
|
|
56711
57447
|
background-color: var(--cc-white);
|
|
56712
57448
|
cursor: pointer;
|
|
56713
57449
|
border: 1px solid var(--cc-black-80);
|
|
56714
57450
|
}
|
|
56715
|
-
.
|
|
56716
|
-
.
|
|
57451
|
+
._wrapperDownloadable_tochy_31 img:hover,
|
|
57452
|
+
._wrapperDownloadable_tochy_31 img:focus {
|
|
56717
57453
|
opacity: 0.8;
|
|
56718
57454
|
}
|
|
56719
57455
|
|
|
56720
|
-
.
|
|
57456
|
+
._flexImage_tochy_10 img {
|
|
56721
57457
|
aspect-ratio: 16/9;
|
|
56722
57458
|
object-fit: cover;
|
|
56723
57459
|
object-position: left;
|
|
56724
57460
|
}
|
|
56725
57461
|
|
|
56726
|
-
.
|
|
57462
|
+
._fixedImage_tochy_9 img {
|
|
56727
57463
|
height: auto;
|
|
56728
57464
|
}
|
|
56729
57465
|
|
|
56730
|
-
.
|
|
57466
|
+
._downloadButtonWrapper_tochy_56 {
|
|
56731
57467
|
padding: 16px;
|
|
56732
57468
|
}
|
|
56733
57469
|
|
|
56734
|
-
.
|
|
57470
|
+
._brokenImage_tochy_60 {
|
|
56735
57471
|
aspect-ratio: 16/9;
|
|
56736
57472
|
width: 100%;
|
|
56737
57473
|
display: block;
|
|
@@ -57743,19 +58479,19 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57743
58479
|
._mainButtonWrapper_zhv80_144 {
|
|
57744
58480
|
padding: 16px;
|
|
57745
58481
|
}
|
|
57746
|
-
.
|
|
58482
|
+
._slideItem_jw04w_1 {
|
|
57747
58483
|
position: relative;
|
|
57748
58484
|
width: 206px;
|
|
57749
58485
|
/* height: 150px; */
|
|
57750
58486
|
overflow: hidden;
|
|
57751
58487
|
}
|
|
57752
58488
|
|
|
57753
|
-
.
|
|
58489
|
+
._slideItem_jw04w_1 ._top_jw04w_8 {
|
|
57754
58490
|
position: relative;
|
|
57755
58491
|
border-radius: var(--cc-bubble-border-radius);
|
|
57756
58492
|
}
|
|
57757
58493
|
|
|
57758
|
-
.
|
|
58494
|
+
._slideItem_jw04w_1 ._bottom_jw04w_13 {
|
|
57759
58495
|
border-bottom-left-radius: var(--cc-bubble-border-radius);
|
|
57760
58496
|
border-bottom-right-radius: var(--cc-bubble-border-radius);
|
|
57761
58497
|
border: 1px solid var(--cc-black-80);
|
|
@@ -57766,7 +58502,7 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57766
58502
|
padding: 8px;
|
|
57767
58503
|
}
|
|
57768
58504
|
|
|
57769
|
-
.
|
|
58505
|
+
._slideItem_jw04w_1 ._top_jw04w_8 img {
|
|
57770
58506
|
aspect-ratio: 206/150;
|
|
57771
58507
|
object-fit: cover;
|
|
57772
58508
|
object-position: left;
|
|
@@ -57776,7 +58512,7 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57776
58512
|
outline: none;
|
|
57777
58513
|
}
|
|
57778
58514
|
|
|
57779
|
-
.
|
|
58515
|
+
._slideItem_jw04w_1 ._brokenImage_jw04w_34 {
|
|
57780
58516
|
aspect-ratio: 206/150;
|
|
57781
58517
|
width: 100%;
|
|
57782
58518
|
display: block;
|
|
@@ -57785,9 +58521,9 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57785
58521
|
background-color: var(--cc-black-80);
|
|
57786
58522
|
}
|
|
57787
58523
|
|
|
57788
|
-
.
|
|
57789
|
-
.
|
|
57790
|
-
.
|
|
58524
|
+
._slideItem_jw04w_1 ._hasExtraInfo_jw04w_43,
|
|
58525
|
+
._slideItem_jw04w_1 ._hasExtraInfo_jw04w_43 img,
|
|
58526
|
+
._slideItem_jw04w_1 ._brokenImage_jw04w_34 {
|
|
57791
58527
|
border-bottom-left-radius: 0px;
|
|
57792
58528
|
border-bottom-right-radius: 0px;
|
|
57793
58529
|
}
|
|
@@ -57796,7 +58532,7 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57796
58532
|
** Default (legacy) layout: the title overlays the bottom of the image.
|
|
57797
58533
|
** Used when \`galleryCardTitleBelowImage\` is not enabled.
|
|
57798
58534
|
*/
|
|
57799
|
-
.
|
|
58535
|
+
._slideItem_jw04w_1 ._top_jw04w_8 h4 {
|
|
57800
58536
|
position: absolute;
|
|
57801
58537
|
margin: 0px;
|
|
57802
58538
|
margin-inline-start: 8px;
|
|
@@ -57810,7 +58546,7 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57810
58546
|
** overlaid title switches to dark text there (WCAG 1.4.3 Contrast Minimum,
|
|
57811
58547
|
** CGY-37634).
|
|
57812
58548
|
*/
|
|
57813
|
-
.
|
|
58549
|
+
._slideItem_jw04w_1 ._top_jw04w_8:has(._brokenImage_jw04w_34) h4 {
|
|
57814
58550
|
color: var(--cc-black-10);
|
|
57815
58551
|
}
|
|
57816
58552
|
|
|
@@ -57818,13 +58554,13 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57818
58554
|
** Opt-in layout (galleryCardTitleBelowImage): the title moves into the content
|
|
57819
58555
|
** block beneath the image, so it shares the subtitle's flush margins/padding.
|
|
57820
58556
|
*/
|
|
57821
|
-
.
|
|
57822
|
-
.
|
|
58557
|
+
._slideItem_jw04w_1 ._bottom_jw04w_13 p,
|
|
58558
|
+
._slideItem_jw04w_1 ._bottom_jw04w_13 h4 {
|
|
57823
58559
|
padding: 0px;
|
|
57824
58560
|
margin: 0px;
|
|
57825
58561
|
}
|
|
57826
58562
|
|
|
57827
|
-
.
|
|
58563
|
+
._slideItem_jw04w_1 ._bottom_jw04w_13 ._buttonListItem_jw04w_82 {
|
|
57828
58564
|
width: 100%;
|
|
57829
58565
|
}
|
|
57830
58566
|
|
|
@@ -57833,24 +58569,45 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57833
58569
|
** block (keeping the block's column gap), or sits on the image area when the
|
|
57834
58570
|
** block has no text. Buttons are never inside it.
|
|
57835
58571
|
*/
|
|
57836
|
-
.
|
|
58572
|
+
._slideItem_jw04w_1 ._link_jw04w_91 {
|
|
57837
58573
|
display: flex;
|
|
57838
58574
|
flex-direction: column;
|
|
57839
58575
|
gap: 8px;
|
|
57840
58576
|
}
|
|
57841
|
-
.
|
|
58577
|
+
._slideItem_jw04w_1 [role="link"] {
|
|
57842
58578
|
cursor: pointer;
|
|
57843
58579
|
}
|
|
57844
|
-
|
|
58580
|
+
/* Two-colour focus ring, as on the primary buttons: the primary outline plus a
|
|
58581
|
+
4px contrast band, so the ring stays visible whatever the image or theme
|
|
58582
|
+
colour behind it (WCAG 2.4.7 Focus Visible, 1.4.11 Non-text Contrast). */
|
|
58583
|
+
._slideItem_jw04w_1 [role="link"]:focus-visible {
|
|
57845
58584
|
outline: 2px solid var(--cc-primary-color-focus);
|
|
57846
58585
|
outline-offset: 2px;
|
|
58586
|
+
box-shadow: 0 0 0 4px var(--cc-secondary-contrast-color);
|
|
57847
58587
|
}
|
|
57848
58588
|
/* .slideItem is overflow:hidden and the image area fills it edge to edge, so
|
|
57849
58589
|
the focus ring is drawn inside the card; an outset ring there is clipped
|
|
57850
|
-
away entirely
|
|
57851
|
-
|
|
57852
|
-
|
|
58590
|
+
away entirely. The text link sits inside the content block's 8px padding,
|
|
58591
|
+
so its outset ring is never clipped. The image-area ring is drawn by an
|
|
58592
|
+
overlay pseudo-element: an inset box-shadow on the element itself would be
|
|
58593
|
+
painted beneath the <img> that fills it, and the element's own outline is
|
|
58594
|
+
painted beneath its positioned pseudo-element. The outline is kept but
|
|
58595
|
+
transparent so forced-colors mode (which drops box-shadows and recolours
|
|
58596
|
+
outlines) still shows a ring. */
|
|
58597
|
+
._slideItem_jw04w_1 ._top_jw04w_8[role="link"]:focus-visible {
|
|
58598
|
+
outline-color: transparent;
|
|
57853
58599
|
outline-offset: -2px;
|
|
58600
|
+
box-shadow: none;
|
|
58601
|
+
}
|
|
58602
|
+
._slideItem_jw04w_1 ._top_jw04w_8[role="link"]:focus-visible::after {
|
|
58603
|
+
content: "";
|
|
58604
|
+
position: absolute;
|
|
58605
|
+
inset: 0;
|
|
58606
|
+
border-radius: inherit;
|
|
58607
|
+
box-shadow:
|
|
58608
|
+
inset 0 0 0 2px var(--cc-primary-color-focus),
|
|
58609
|
+
inset 0 0 0 4px var(--cc-secondary-contrast-color);
|
|
58610
|
+
pointer-events: none;
|
|
57854
58611
|
}
|
|
57855
58612
|
|
|
57856
58613
|
/*
|
|
@@ -57859,7 +58616,7 @@ article ._wrapper_zhv80_1 ._list_zhv80_8 ._listItemRoot_zhv80_8 {
|
|
|
57859
58616
|
** The idea is to integrate with modules CSS in order to increase the specificity
|
|
57860
58617
|
** and avoid conflicts on consumer apps
|
|
57861
58618
|
*/
|
|
57862
|
-
article .swiper.
|
|
58619
|
+
article .swiper._wrapper_jw04w_138 {
|
|
57863
58620
|
margin-left: -20px;
|
|
57864
58621
|
margin-right: -20px;
|
|
57865
58622
|
padding-left: 20px;
|
|
@@ -57875,7 +58632,7 @@ article .swiper._wrapper_fa7bu_117 {
|
|
|
57875
58632
|
z-index: 1;
|
|
57876
58633
|
display: block;
|
|
57877
58634
|
}
|
|
57878
|
-
article .swiper.
|
|
58635
|
+
article .swiper._wrapper_jw04w_138 .swiper-wrapper {
|
|
57879
58636
|
position: relative;
|
|
57880
58637
|
width: 100%;
|
|
57881
58638
|
/* height: 100%; */
|
|
@@ -57885,15 +58642,15 @@ article .swiper._wrapper_fa7bu_117 .swiper-wrapper {
|
|
|
57885
58642
|
transition-timing-function: initial;
|
|
57886
58643
|
box-sizing: content-box;
|
|
57887
58644
|
}
|
|
57888
|
-
article .swiper.
|
|
57889
|
-
article .swiper.
|
|
57890
|
-
article .swiper.
|
|
58645
|
+
article .swiper._wrapper_jw04w_138 .swiper-android .swiper-slide,
|
|
58646
|
+
article .swiper._wrapper_jw04w_138 .swiper-ios .swiper-slide,
|
|
58647
|
+
article .swiper._wrapper_jw04w_138 .swiper-wrapper {
|
|
57891
58648
|
transform: translate3d(0px, 0, 0);
|
|
57892
58649
|
}
|
|
57893
|
-
article .swiper.
|
|
58650
|
+
article .swiper._wrapper_jw04w_138 .swiper-horizontal {
|
|
57894
58651
|
touch-action: pan-y;
|
|
57895
58652
|
}
|
|
57896
|
-
article .swiper.
|
|
58653
|
+
article .swiper._wrapper_jw04w_138 .swiper-slide {
|
|
57897
58654
|
flex-shrink: 0;
|
|
57898
58655
|
width: 100%;
|
|
57899
58656
|
height: 100%;
|
|
@@ -57901,15 +58658,15 @@ article .swiper._wrapper_fa7bu_117 .swiper-slide {
|
|
|
57901
58658
|
transition-property: transform;
|
|
57902
58659
|
display: block;
|
|
57903
58660
|
}
|
|
57904
|
-
article .swiper.
|
|
58661
|
+
article .swiper._wrapper_jw04w_138 .swiper-slide-invisible-blank {
|
|
57905
58662
|
visibility: hidden;
|
|
57906
58663
|
}
|
|
57907
58664
|
|
|
57908
58665
|
/*
|
|
57909
58666
|
** SWIPER PAGINATION
|
|
57910
58667
|
*/
|
|
57911
|
-
article .swiper.
|
|
57912
|
-
article .swiper.
|
|
58668
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-prev,
|
|
58669
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-next {
|
|
57913
58670
|
position: absolute;
|
|
57914
58671
|
top: calc(150px / 2 - 8px);
|
|
57915
58672
|
z-index: 10;
|
|
@@ -57922,24 +58679,24 @@ article .swiper._wrapper_fa7bu_117 .gallery-button-next {
|
|
|
57922
58679
|
display: flex;
|
|
57923
58680
|
align-items: center;
|
|
57924
58681
|
}
|
|
57925
|
-
article .swiper.
|
|
58682
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-prev {
|
|
57926
58683
|
left: 20px;
|
|
57927
58684
|
}
|
|
57928
|
-
article .swiper.
|
|
58685
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-next {
|
|
57929
58686
|
right: 20px;
|
|
57930
58687
|
transform: rotate(180deg);
|
|
57931
58688
|
}
|
|
57932
|
-
article .swiper.
|
|
58689
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-prev:dir(rtl) {
|
|
57933
58690
|
left: unset;
|
|
57934
58691
|
right: 20px;
|
|
57935
58692
|
transform: rotate(180deg);
|
|
57936
58693
|
}
|
|
57937
|
-
article .swiper.
|
|
58694
|
+
article .swiper._wrapper_jw04w_138 .gallery-button-next:dir(rtl) {
|
|
57938
58695
|
right: unset;
|
|
57939
58696
|
left: 20px;
|
|
57940
58697
|
transform: rotate(0deg);
|
|
57941
58698
|
}
|
|
57942
|
-
article .swiper.
|
|
58699
|
+
article .swiper._wrapper_jw04w_138 .swiper-button-disabled {
|
|
57943
58700
|
opacity: 0;
|
|
57944
58701
|
}
|
|
57945
58702
|
|
|
@@ -57953,22 +58710,22 @@ article .swiper._wrapper_fa7bu_117 .swiper-button-disabled {
|
|
|
57953
58710
|
** the cards. A single row adds 28px: 2px gap + 24px row + 2px container
|
|
57954
58711
|
** padding.
|
|
57955
58712
|
*/
|
|
57956
|
-
article .swiper.
|
|
58713
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination {
|
|
57957
58714
|
position: relative;
|
|
57958
58715
|
text-align: center;
|
|
57959
58716
|
transition: 300ms opacity;
|
|
57960
58717
|
transform: translate3d(0, 0, 0);
|
|
57961
58718
|
z-index: 10;
|
|
57962
58719
|
}
|
|
57963
|
-
article .swiper.
|
|
58720
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination.swiper-pagination-hidden {
|
|
57964
58721
|
opacity: 0;
|
|
57965
58722
|
}
|
|
57966
|
-
article .swiper.
|
|
57967
|
-
article .swiper.
|
|
58723
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-disabled > .swiper-pagination,
|
|
58724
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination.swiper-pagination-disabled {
|
|
57968
58725
|
display: none !important;
|
|
57969
58726
|
}
|
|
57970
|
-
article .swiper.
|
|
57971
|
-
article .swiper.
|
|
58727
|
+
article .swiper._wrapper_jw04w_138 .swiper-horizontal > .swiper-pagination-bullets,
|
|
58728
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullets.swiper-pagination-horizontal {
|
|
57972
58729
|
margin-top: 2px;
|
|
57973
58730
|
width: 100%;
|
|
57974
58731
|
display: flex;
|
|
@@ -57982,7 +58739,7 @@ article .swiper._wrapper_fa7bu_117 .swiper-pagination-bullets.swiper-pagination-
|
|
|
57982
58739
|
** is unchanged while the hit area grows around it; focus styling therefore
|
|
57983
58740
|
** targets ::before too.
|
|
57984
58741
|
*/
|
|
57985
|
-
article .swiper.
|
|
58742
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet {
|
|
57986
58743
|
/* Fixed-size flex item: the 24px target never shrinks when the row is
|
|
57987
58744
|
full; overflowing bullets wrap (see .swiper-pagination). */
|
|
57988
58745
|
flex: 0 0 24px;
|
|
@@ -57996,7 +58753,7 @@ article .swiper._wrapper_fa7bu_117 .swiper-pagination-bullet {
|
|
|
57996
58753
|
background: transparent;
|
|
57997
58754
|
opacity: 1;
|
|
57998
58755
|
}
|
|
57999
|
-
article .swiper.
|
|
58756
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet::before {
|
|
58000
58757
|
content: "";
|
|
58001
58758
|
width: 6px;
|
|
58002
58759
|
height: 6px;
|
|
@@ -58005,21 +58762,21 @@ article .swiper._wrapper_fa7bu_117 .swiper-pagination-bullet::before {
|
|
|
58005
58762
|
}
|
|
58006
58763
|
/* Declared before the focus rules (and lower in specificity) so a focused
|
|
58007
58764
|
active bullet always shows the focus colour, not the active black. */
|
|
58008
|
-
article .swiper.
|
|
58765
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet-active::before {
|
|
58009
58766
|
background-color: black;
|
|
58010
58767
|
}
|
|
58011
|
-
article .swiper.
|
|
58768
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet:focus {
|
|
58012
58769
|
outline: none;
|
|
58013
58770
|
}
|
|
58014
|
-
article .swiper.
|
|
58771
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet:focus::before {
|
|
58015
58772
|
background-color: var(--cc-primary-color-focus);
|
|
58016
58773
|
box-shadow: 0 0 0 4px var(--cc-primary-color-opacity-10);
|
|
58017
58774
|
}
|
|
58018
|
-
article .swiper.
|
|
58775
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet:focus-visible::before {
|
|
58019
58776
|
outline: 2px solid var(--cc-primary-color-focus);
|
|
58020
58777
|
outline-offset: 2px;
|
|
58021
58778
|
}
|
|
58022
|
-
article .swiper.
|
|
58779
|
+
article .swiper._wrapper_jw04w_138 button.swiper-pagination-bullet {
|
|
58023
58780
|
border: none;
|
|
58024
58781
|
margin: 0;
|
|
58025
58782
|
padding: 0;
|
|
@@ -58027,17 +58784,17 @@ article .swiper._wrapper_fa7bu_117 button.swiper-pagination-bullet {
|
|
|
58027
58784
|
-webkit-appearance: none;
|
|
58028
58785
|
appearance: none;
|
|
58029
58786
|
}
|
|
58030
|
-
article .swiper.
|
|
58787
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-clickable .swiper-pagination-bullet {
|
|
58031
58788
|
cursor: pointer;
|
|
58032
58789
|
}
|
|
58033
|
-
article .swiper.
|
|
58790
|
+
article .swiper._wrapper_jw04w_138 .swiper-pagination-bullet:only-child {
|
|
58034
58791
|
display: none !important;
|
|
58035
58792
|
}
|
|
58036
58793
|
article
|
|
58037
|
-
.swiper.
|
|
58794
|
+
.swiper._wrapper_jw04w_138
|
|
58038
58795
|
.swiper-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet,
|
|
58039
58796
|
article
|
|
58040
|
-
.swiper.
|
|
58797
|
+
.swiper._wrapper_jw04w_138
|
|
58041
58798
|
.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet {
|
|
58042
58799
|
/* Adjacent 24px targets touch but never overlap (WCAG 2.5.8). */
|
|
58043
58800
|
margin: 0;
|
|
@@ -58953,8 +59710,8 @@ article
|
|
|
58953
59710
|
margin-top: 10px;
|
|
58954
59711
|
max-width: 295px;
|
|
58955
59712
|
}
|
|
58956
|
-
._ac-
|
|
58957
|
-
._ac-
|
|
59713
|
+
._ac-pushbutton_1yco4_1,
|
|
59714
|
+
._ac-pushbutton_1yco4_1._subdued_1yco4_2 {
|
|
58958
59715
|
background-color: transparent;
|
|
58959
59716
|
border: 1px solid primaryColor;
|
|
58960
59717
|
color: primaryColor;
|
|
@@ -58966,7 +59723,7 @@ article
|
|
|
58966
59723
|
border-radius: 14px;
|
|
58967
59724
|
}
|
|
58968
59725
|
|
|
58969
|
-
._ac-
|
|
59726
|
+
._ac-pushbutton_1yco4_1._style-default_1yco4_14._expandable_1yco4_14._expanded_1yco4_14 {
|
|
58970
59727
|
background: primaryGradient;
|
|
58971
59728
|
color: primaryContrastColor;
|
|
58972
59729
|
border: 1px solid primaryColor;
|
|
@@ -58984,19 +59741,19 @@ article
|
|
|
58984
59741
|
padding: \${theme.unitSize}px \${theme.unitSize * 2}px;
|
|
58985
59742
|
}*/
|
|
58986
59743
|
|
|
58987
|
-
._adaptivecard-
|
|
59744
|
+
._adaptivecard-wrapper_1yco4_32 {
|
|
58988
59745
|
width: 100%;
|
|
58989
59746
|
box-sizing: border-box;
|
|
58990
59747
|
max-width: 100%;
|
|
58991
59748
|
padding: 16px !important;
|
|
58992
59749
|
}
|
|
58993
59750
|
|
|
58994
|
-
._adaptivecard-
|
|
59751
|
+
._adaptivecard-wrapper_1yco4_32 > *:focus {
|
|
58995
59752
|
outline: 1px solid var(--cc-primary-color-focus);
|
|
58996
59753
|
border-color: var(--cc-primary-color-focus);
|
|
58997
59754
|
}
|
|
58998
59755
|
|
|
58999
|
-
._adaptivecard-
|
|
59756
|
+
._adaptivecard-wrapper_1yco4_32 button {
|
|
59000
59757
|
appearance: none;
|
|
59001
59758
|
background: var(--cc-primary-button-background, var(--cc-black-10));
|
|
59002
59759
|
border-radius: var(--cc-primary-button-border-radius, 10px);
|
|
@@ -59011,42 +59768,42 @@ article
|
|
|
59011
59768
|
width: 100%;
|
|
59012
59769
|
}
|
|
59013
59770
|
|
|
59014
|
-
._adaptivecard-
|
|
59771
|
+
._adaptivecard-wrapper_1yco4_32 button:hover {
|
|
59015
59772
|
background: var(--cc-primary-button-background-hover, var(--cc-black-30));
|
|
59016
59773
|
}
|
|
59017
59774
|
|
|
59018
|
-
._adaptivecard-
|
|
59775
|
+
._adaptivecard-wrapper_1yco4_32 button:focus-visible {
|
|
59019
59776
|
outline: 2px solid var(--cc-primary-color-focus);
|
|
59020
59777
|
outline-offset: 2px;
|
|
59021
59778
|
}
|
|
59022
59779
|
|
|
59023
|
-
._adaptivecard-
|
|
59024
|
-
._adaptivecard-
|
|
59780
|
+
._adaptivecard-wrapper_1yco4_32._chatDisabled_1yco4_68 button,
|
|
59781
|
+
._adaptivecard-wrapper_1yco4_32._chatDisabled_1yco4_68 button:hover {
|
|
59025
59782
|
background: var(--cc-primary-button-disabled-background, var(--cc-black-90));
|
|
59026
59783
|
opacity: var(--cc-primary-button-disabled-opacity, 1);
|
|
59027
59784
|
cursor: var(--cc-primary-button-disabled-cursor, default);
|
|
59028
59785
|
pointer-events: none;
|
|
59029
59786
|
}
|
|
59030
59787
|
|
|
59031
|
-
._adaptivecard-
|
|
59788
|
+
._adaptivecard-wrapper_1yco4_32 button:disabled {
|
|
59032
59789
|
background: var(--cc-primary-button-disabled-background, var(--cc-black-90));
|
|
59033
59790
|
opacity: var(--cc-primary-button-disabled-opacity, 1);
|
|
59034
59791
|
cursor: var(--cc-primary-button-disabled-cursor, default);
|
|
59035
59792
|
}
|
|
59036
59793
|
|
|
59037
|
-
._adaptivecard-
|
|
59794
|
+
._adaptivecard-wrapper_1yco4_32 .ac-textRun {
|
|
59038
59795
|
color: var(--cc-black-40) !important;
|
|
59039
59796
|
font-size: 12px !important;
|
|
59040
59797
|
line-height: 140%;
|
|
59041
59798
|
}
|
|
59042
59799
|
|
|
59043
|
-
._adaptivecard-
|
|
59800
|
+
._adaptivecard-wrapper_1yco4_32 .ac-container {
|
|
59044
59801
|
border-radius: 15px;
|
|
59045
59802
|
}
|
|
59046
59803
|
|
|
59047
|
-
._adaptivecard-
|
|
59048
|
-
._adaptivecard-
|
|
59049
|
-
._adaptivecard-
|
|
59804
|
+
._adaptivecard-wrapper_1yco4_32 input,
|
|
59805
|
+
._adaptivecard-wrapper_1yco4_32 textarea,
|
|
59806
|
+
._adaptivecard-wrapper_1yco4_32 select {
|
|
59050
59807
|
align-self: stretch;
|
|
59051
59808
|
background-position: right 12px center;
|
|
59052
59809
|
background-repeat: no-repeat;
|
|
@@ -59062,14 +59819,14 @@ article
|
|
|
59062
59819
|
}
|
|
59063
59820
|
|
|
59064
59821
|
@media screen and (max-width: 575px) {
|
|
59065
|
-
._adaptivecard-
|
|
59066
|
-
._adaptivecard-
|
|
59067
|
-
._adaptivecard-
|
|
59822
|
+
._adaptivecard-wrapper_1yco4_32 input,
|
|
59823
|
+
._adaptivecard-wrapper_1yco4_32 textarea,
|
|
59824
|
+
._adaptivecard-wrapper_1yco4_32 select {
|
|
59068
59825
|
font-size: 16px !important;
|
|
59069
59826
|
}
|
|
59070
59827
|
}
|
|
59071
59828
|
|
|
59072
|
-
._adaptivecard-
|
|
59829
|
+
._adaptivecard-wrapper_1yco4_32 textarea {
|
|
59073
59830
|
min-height: 98px;
|
|
59074
59831
|
}
|
|
59075
59832
|
|
|
@@ -59077,41 +59834,41 @@ article
|
|
|
59077
59834
|
height: 16px !important;
|
|
59078
59835
|
}
|
|
59079
59836
|
|
|
59080
|
-
._adaptivecard-
|
|
59837
|
+
._adaptivecard-wrapper_1yco4_32 textarea::-webkit-scrollbar {
|
|
59081
59838
|
width: 27px;
|
|
59082
59839
|
}
|
|
59083
59840
|
|
|
59084
|
-
._adaptivecard-
|
|
59841
|
+
._adaptivecard-wrapper_1yco4_32 textarea::-webkit-scrollbar-track {
|
|
59085
59842
|
background: transparent;
|
|
59086
59843
|
}
|
|
59087
59844
|
|
|
59088
|
-
._adaptivecard-
|
|
59845
|
+
._adaptivecard-wrapper_1yco4_32 textarea::-webkit-scrollbar-thumb {
|
|
59089
59846
|
background-color: var(--cc-black-80);
|
|
59090
59847
|
border-radius: 10px;
|
|
59091
59848
|
border: 12px solid var(--cc-white);
|
|
59092
59849
|
border-block: none;
|
|
59093
59850
|
}
|
|
59094
59851
|
|
|
59095
|
-
._adaptivecard-
|
|
59096
|
-
._adaptivecard-
|
|
59097
|
-
._adaptivecard-
|
|
59852
|
+
._adaptivecard-wrapper_1yco4_32 input:focus,
|
|
59853
|
+
._adaptivecard-wrapper_1yco4_32 textarea:focus,
|
|
59854
|
+
._adaptivecard-wrapper_1yco4_32 select:focus {
|
|
59098
59855
|
outline: 1px solid var(--cc-primary-color-focus);
|
|
59099
59856
|
border-color: 1px solid var(--cc-primary-color-focus);
|
|
59100
59857
|
}
|
|
59101
59858
|
|
|
59102
|
-
._adaptivecard-
|
|
59103
|
-
._adaptivecard-
|
|
59104
|
-
._adaptivecard-
|
|
59859
|
+
._adaptivecard-wrapper_1yco4_32 input:focus-visible,
|
|
59860
|
+
._adaptivecard-wrapper_1yco4_32 textarea:focus-visible,
|
|
59861
|
+
._adaptivecard-wrapper_1yco4_32 select:focus-visible {
|
|
59105
59862
|
outline: 2px solid var(--cc-primary-color-focus);
|
|
59106
59863
|
border-color: 1px solid var(--cc-primary-color-focus);
|
|
59107
59864
|
}
|
|
59108
59865
|
|
|
59109
|
-
._adaptivecard-
|
|
59866
|
+
._adaptivecard-wrapper_1yco4_32 .ac-actionSet {
|
|
59110
59867
|
flex-wrap: wrap;
|
|
59111
59868
|
gap: 8px;
|
|
59112
59869
|
}
|
|
59113
59870
|
|
|
59114
|
-
._adaptivecard-
|
|
59871
|
+
._adaptivecard-wrapper_1yco4_32 > * {
|
|
59115
59872
|
background-color: white;
|
|
59116
59873
|
border-radius: var(--cc-adaptivecard-inner-border-radius, var(--cc-bubble-border-radius, 15px));
|
|
59117
59874
|
box-shadow: none;
|
|
@@ -59120,7 +59877,7 @@ article
|
|
|
59120
59877
|
margin: -17px;
|
|
59121
59878
|
}
|
|
59122
59879
|
|
|
59123
|
-
._adaptivecard-
|
|
59880
|
+
._adaptivecard-wrapper_1yco4_32 [type="checkbox"] {
|
|
59124
59881
|
appearance: none;
|
|
59125
59882
|
background-color: var(--cc-white);
|
|
59126
59883
|
border: 1px solid var(--cc-black-10, #999);
|
|
@@ -59129,66 +59886,91 @@ article
|
|
|
59129
59886
|
height: 16px;
|
|
59130
59887
|
}
|
|
59131
59888
|
|
|
59132
|
-
._adaptivecard-
|
|
59889
|
+
._adaptivecard-wrapper_1yco4_32 [type="checkbox"]:checked {
|
|
59133
59890
|
background-color: var(--cc-black-10);
|
|
59134
59891
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12.5172 4.4569C12.8172 4.74256 12.8288 5.2173 12.5431 5.51724L7.19089 11.1371C6.69828 11.6543 5.87315 11.6543 5.38054 11.1371L3.4569 9.11724C3.17123 8.8173 3.18281 8.34256 3.48276 8.0569C3.78271 7.77123 4.25744 7.78281 4.5431 8.08276L6.28572 9.9125L11.4569 4.48276C11.7426 4.18281 12.2173 4.17123 12.5172 4.4569Z' fill='white'/%3E%3C/svg%3E");
|
|
59135
59892
|
background-position: -1px -1px;
|
|
59136
59893
|
}
|
|
59137
59894
|
|
|
59138
|
-
._adaptivecard-
|
|
59895
|
+
._adaptivecard-wrapper_1yco4_32 [type="checkbox"]:active {
|
|
59139
59896
|
background-color: var(--cc-black-60);
|
|
59140
59897
|
border-color: var(--cc-black-60);
|
|
59141
59898
|
}
|
|
59142
59899
|
|
|
59143
|
-
._adaptivecard-
|
|
59900
|
+
._adaptivecard-wrapper_1yco4_32 [type="checkbox"]:checked:hover {
|
|
59144
59901
|
background-color: var(--cc-black-40);
|
|
59145
59902
|
border-color: var(--cc-black-40);
|
|
59146
59903
|
}
|
|
59147
59904
|
|
|
59148
|
-
._adaptivecard-
|
|
59905
|
+
._adaptivecard-wrapper_1yco4_32 input:invalid {
|
|
59149
59906
|
border-color: red;
|
|
59150
59907
|
}
|
|
59151
59908
|
|
|
59152
|
-
|
|
59153
|
-
|
|
59909
|
+
/* Chromium's native picker button is kept (it is a keyboard stop of its own after the
|
|
59910
|
+
* mm/dd/yyyy segments) but its glyph is replaced by our SVG painted on the input at
|
|
59911
|
+
* \`right 12px center\`. Centre the button on that icon (16px content + 4px padding = a 24px
|
|
59912
|
+
* target, 2.5.8) so its focus ring wraps the icon instead of cutting across it (CGY-39786;
|
|
59913
|
+
* 2.4.13 best practice).
|
|
59914
|
+
*
|
|
59915
|
+
* Chromium ignores :focus/:focus-visible on this pseudo-element, and the host input matches
|
|
59916
|
+
* :focus only while a date/time segment has focus but :focus-within in both states, so
|
|
59917
|
+
* \`:focus-within:not(:focus)\` is exactly "the picker button has focus". Firefox has no such
|
|
59918
|
+
* pseudo-element or extra tab stop, so these rules are inert there. */
|
|
59919
|
+
._adaptivecard-wrapper_1yco4_32 [type="date"]::-webkit-calendar-picker-indicator,
|
|
59920
|
+
._adaptivecard-wrapper_1yco4_32 [type="time"]::-webkit-calendar-picker-indicator {
|
|
59154
59921
|
background: none;
|
|
59922
|
+
box-sizing: content-box;
|
|
59923
|
+
width: 16px;
|
|
59924
|
+
height: 16px;
|
|
59925
|
+
padding: 4px;
|
|
59926
|
+
/* Pull the box 4px past the input's 12px right padding so it is centred on the icon. */
|
|
59927
|
+
margin: 0 -4px 0 0;
|
|
59928
|
+
align-self: center;
|
|
59929
|
+
border-radius: 4px;
|
|
59930
|
+
cursor: pointer;
|
|
59155
59931
|
}
|
|
59156
59932
|
|
|
59157
|
-
._adaptivecard-
|
|
59158
|
-
._adaptivecard-
|
|
59933
|
+
._adaptivecard-wrapper_1yco4_32 [type="date"]:focus-within:not(:focus)::-webkit-calendar-picker-indicator,
|
|
59934
|
+
._adaptivecard-wrapper_1yco4_32 [type="time"]:focus-within:not(:focus)::-webkit-calendar-picker-indicator {
|
|
59935
|
+
outline: 2px solid var(--cc-primary-color-focus);
|
|
59936
|
+
outline-offset: 0;
|
|
59937
|
+
}
|
|
59938
|
+
|
|
59939
|
+
._adaptivecard-wrapper_1yco4_32 [type="date"],
|
|
59940
|
+
._adaptivecard-wrapper_1yco4_32 [type="time"] {
|
|
59159
59941
|
background-repeat: no-repeat;
|
|
59160
59942
|
background-position: right 12px center;
|
|
59161
59943
|
/* accent-color tints picker popup only; Firefox native indicator glyph is system-colored and unstyleable. */
|
|
59162
59944
|
accent-color: var(--cc-primary-color);
|
|
59163
59945
|
}
|
|
59164
59946
|
|
|
59165
|
-
._adaptivecard-
|
|
59947
|
+
._adaptivecard-wrapper_1yco4_32 [type="date"] {
|
|
59166
59948
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0.75C3 0.335786 3.33579 0 3.75 0C4.16421 0 4.5 0.335786 4.5 0.75V3H11V0.75C11 0.335786 11.3358 0 11.75 0C12.1642 0 12.5 0.335786 12.5 0.75V3H14C15.1046 3 16 3.89543 16 5V14C16 15.1046 15.1046 16 14 16H2C0.895431 16 0 15.1046 0 14V5C0 3.89543 0.895431 3 2 3H3V0.75ZM1.5 6H14.5V14C14.5 14.2761 14.2761 14.5 14 14.5H2C1.72386 14.5 1.5 14.2761 1.5 14V6Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
59167
59949
|
}
|
|
59168
59950
|
|
|
59169
|
-
._adaptivecard-
|
|
59951
|
+
._adaptivecard-wrapper_1yco4_32 [type="time"] {
|
|
59170
59952
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5ZM8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16Z' fill='%232455E6'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11.0303 12.0303C10.7374 12.3232 10.2626 12.3232 9.96967 12.0303L7.25 9.31066L7.25 4C7.25 3.58579 7.58578 3.25 8 3.25C8.41421 3.25 8.75 3.58579 8.75 4L8.75 8.68934L11.0303 10.9697C11.3232 11.2626 11.3232 11.7374 11.0303 12.0303Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
59171
59953
|
}
|
|
59172
59954
|
|
|
59173
59955
|
/* Firefox stacks native date button beside background-image SVG (double-icon). Drop SVG; native icon remains, system-colored. */
|
|
59174
59956
|
@supports (-moz-appearance: none) {
|
|
59175
|
-
._adaptivecard-
|
|
59957
|
+
._adaptivecard-wrapper_1yco4_32 [type="date"] {
|
|
59176
59958
|
background-image: none !important;
|
|
59177
59959
|
}
|
|
59178
59960
|
}
|
|
59179
59961
|
|
|
59180
|
-
._adaptivecard-
|
|
59962
|
+
._adaptivecard-wrapper_1yco4_32 select {
|
|
59181
59963
|
appearance: none;
|
|
59182
59964
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1.34923 4.24022C1.76855 3.8808 2.39985 3.92936 2.75927 4.34869L8.00002 10.4629L13.2408 4.34869C13.6002 3.92936 14.2315 3.8808 14.6508 4.24022C15.0701 4.59965 15.1187 5.23095 14.7593 5.65027L9.51853 11.7645C8.72034 12.6957 7.2797 12.6957 6.4815 11.7645L1.24076 5.65027C0.881339 5.23095 0.929901 4.59965 1.34923 4.24022Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
59183
59965
|
background-repeat: no-repeat;
|
|
59184
59966
|
background-position: right 12px center;
|
|
59185
59967
|
}
|
|
59186
59968
|
|
|
59187
|
-
._adaptivecard-
|
|
59969
|
+
._adaptivecard-wrapper_1yco4_32 select::-ms-expand {
|
|
59188
59970
|
display: none;
|
|
59189
59971
|
}
|
|
59190
59972
|
|
|
59191
|
-
._adaptivecard-
|
|
59973
|
+
._adaptivecard-wrapper_1yco4_32 select option {
|
|
59192
59974
|
color: var(--cc-black-40);
|
|
59193
59975
|
border-bottom: 1px solid var(--cc-black-10);
|
|
59194
59976
|
}
|
|
@@ -60204,6 +60986,9 @@ const getBackgroundImage = url => {
|
|
|
60204
60986
|
sanitized = sanitized.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\)/g, "\\)");
|
|
60205
60987
|
return `url("${sanitized}")`;
|
|
60206
60988
|
};
|
|
60989
|
+
function resolveAttachmentUrl(attachment) {
|
|
60990
|
+
return attachment.downloadUrl ?? attachment.url;
|
|
60991
|
+
}
|
|
60207
60992
|
const getRandomId = (prefix = "") => {
|
|
60208
60993
|
const id = window?.crypto?.randomUUID?.() || Date.now();
|
|
60209
60994
|
return prefix ? `${prefix}-${id}` : id;
|
|
@@ -60224,6 +61009,15 @@ const htmlToPlainText = html2 => {
|
|
|
60224
61009
|
}
|
|
60225
61010
|
return html2.replace(/<[^>]*>/g, "").trim();
|
|
60226
61011
|
};
|
|
61012
|
+
const INTERACTIVE_CONTENT_SELECTOR = ["a[href]", "area[href]", "audio[controls]", "video[controls]", "button", "details", "embed", "iframe", "img[usemap]", "object[usemap]", 'input:not([type="hidden"])', "label", "select", "textarea", '[contenteditable]:not([contenteditable="false"])', "[tabindex]"].join(", ");
|
|
61013
|
+
const htmlHasInteractiveContent = html2 => {
|
|
61014
|
+
if (!html2) return false;
|
|
61015
|
+
if (typeof DOMParser !== "undefined") {
|
|
61016
|
+
const doc = new DOMParser().parseFromString(html2, "text/html");
|
|
61017
|
+
return !!doc.body?.querySelector(INTERACTIVE_CONTENT_SELECTOR);
|
|
61018
|
+
}
|
|
61019
|
+
return /<(a|area|audio|video|button|details|embed|iframe|img|object|input|label|select|textarea)[\s>]|\s(contenteditable|tabindex)=/i.test(html2);
|
|
61020
|
+
};
|
|
60227
61021
|
const getFocusableElements = element2 => {
|
|
60228
61022
|
const interactiveEls = element2?.querySelectorAll('a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])');
|
|
60229
61023
|
const interactiveElsArray = interactiveEls && Array.from(interactiveEls);
|
|
@@ -61529,6 +62323,7 @@ function createDOMPurify() {
|
|
|
61529
62323
|
}
|
|
61530
62324
|
var purify = createDOMPurify();
|
|
61531
62325
|
const allowedHtmlTags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "noframes", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"];
|
|
62326
|
+
const defaultAllowedHtmlTags = Object.freeze([...allowedHtmlTags]);
|
|
61532
62327
|
const allowedHtmlAttributes = ["accept", "accept-charset", "accesskey", "action", "align", "alt", "autocomplete", "autofocus", "autoplay", "bgcolor", "border", "charset", "checked", "cite", "class", "color", "cols", "colspan", "content", "contenteditable", "controls", "coords", "data", "data-*", "datetime", "default", "dir", "dirname", "disabled", "download", "draggable", "dropzone", "enctype", "for", "form", "formaction", "headers", "height", "hidden", "high", "href", "hreflang", "http-equiv", "id", "ismap", "kind", "label", "lang", "list", "loop", "low", "max", "maxlength", "media", "method", "min", "multiple", "muted", "name", "novalidate", "open", "optimum", "pattern", "placeholder", "poster", "preload", "readonly", "rel", "required", "reversed", "rows", "rowspan", "sandbox", "scope", "selected", "shape", "size", "sizes", "span", "spellcheck", "src", "srcdoc", "srclang", "srcset", "start", "step", "style", "tabindex", "target", "title", "translate", "type", "usemap", "value", "width", "wrap"];
|
|
61533
62328
|
const config$2 = {
|
|
61534
62329
|
ALLOWED_TAGS: allowedHtmlTags,
|
|
@@ -85980,12 +86775,12 @@ const Lightbox = () => {
|
|
|
85980
86775
|
}), /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(LightboxHeader, {}), /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {})]
|
|
85981
86776
|
});
|
|
85982
86777
|
};
|
|
85983
|
-
const wrapper$5 = "
|
|
85984
|
-
const fixedImage = "
|
|
85985
|
-
const flexImage = "
|
|
85986
|
-
const wrapperDownloadable = "
|
|
85987
|
-
const downloadButtonWrapper$1 = "
|
|
85988
|
-
const brokenImage$1 = "
|
|
86778
|
+
const wrapper$5 = "_wrapper_tochy_1";
|
|
86779
|
+
const fixedImage = "_fixedImage_tochy_9";
|
|
86780
|
+
const flexImage = "_flexImage_tochy_10";
|
|
86781
|
+
const wrapperDownloadable = "_wrapperDownloadable_tochy_31";
|
|
86782
|
+
const downloadButtonWrapper$1 = "_downloadButtonWrapper_tochy_56";
|
|
86783
|
+
const brokenImage$1 = "_brokenImage_tochy_60";
|
|
85989
86784
|
const classes$g = {
|
|
85990
86785
|
wrapper: wrapper$5,
|
|
85991
86786
|
fixedImage,
|
|
@@ -86611,8 +87406,13 @@ const Image = () => {
|
|
|
86611
87406
|
const {
|
|
86612
87407
|
url,
|
|
86613
87408
|
altText,
|
|
86614
|
-
buttons: buttons2
|
|
87409
|
+
buttons: buttons2,
|
|
87410
|
+
downloadUrl
|
|
86615
87411
|
} = payload?.message?.attachment?.payload || {};
|
|
87412
|
+
const resolvedUrl = resolveAttachmentUrl({
|
|
87413
|
+
url,
|
|
87414
|
+
downloadUrl
|
|
87415
|
+
});
|
|
86616
87416
|
const button2 = buttons2?.[0];
|
|
86617
87417
|
const buttonRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
86618
87418
|
const isDownloadable = buttons2?.find(button22 => "type" in button22 && button22.type === "web_url") !== void 0;
|
|
@@ -86623,12 +87423,12 @@ const Image = () => {
|
|
|
86623
87423
|
setShowLightbox(false);
|
|
86624
87424
|
buttonRef.current?.focus();
|
|
86625
87425
|
},
|
|
86626
|
-
url,
|
|
87426
|
+
url: resolvedUrl ?? "",
|
|
86627
87427
|
altText,
|
|
86628
87428
|
isDownloadable,
|
|
86629
87429
|
button: button2
|
|
86630
|
-
}), [altText, button2, isDownloadable,
|
|
86631
|
-
if (!
|
|
87430
|
+
}), [altText, button2, isDownloadable, resolvedUrl]);
|
|
87431
|
+
if (!resolvedUrl) return null;
|
|
86632
87432
|
return /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(ImageMessageContext.Provider, {
|
|
86633
87433
|
value: contextValue,
|
|
86634
87434
|
children: [/* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ImageThumb, {
|
|
@@ -88236,8 +89036,13 @@ const Video = () => {
|
|
|
88236
89036
|
const {
|
|
88237
89037
|
url,
|
|
88238
89038
|
altText,
|
|
88239
|
-
captionsUrl
|
|
89039
|
+
captionsUrl,
|
|
89040
|
+
downloadUrl
|
|
88240
89041
|
} = payload?.message?.attachment?.payload || {};
|
|
89042
|
+
const resolvedUrl = resolveAttachmentUrl({
|
|
89043
|
+
url,
|
|
89044
|
+
downloadUrl
|
|
89045
|
+
});
|
|
88241
89046
|
const downloadTranscriptLinkRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
88242
89047
|
const [playing, setPlaying] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(false);
|
|
88243
89048
|
const videoPlayerWrapperRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
@@ -88248,7 +89053,7 @@ const Video = () => {
|
|
|
88248
89053
|
hasTranscript: !!altText,
|
|
88249
89054
|
hasCaptions: !!captionsUrl
|
|
88250
89055
|
},
|
|
88251
|
-
validation: () => !!
|
|
89056
|
+
validation: () => !!resolvedUrl
|
|
88252
89057
|
});
|
|
88253
89058
|
const handleFocus = (0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)(player2 => {
|
|
88254
89059
|
const chatHistory = document.getElementById("webchatChatHistoryWrapperLiveLogPanel");
|
|
@@ -88288,7 +89093,7 @@ const Video = () => {
|
|
|
88288
89093
|
label: "On"
|
|
88289
89094
|
}]
|
|
88290
89095
|
};
|
|
88291
|
-
if (!
|
|
89096
|
+
if (!resolvedUrl) return null;
|
|
88292
89097
|
const playVideoLabel = config2?.settings.customTranslations?.ariaLabels?.playVideo || "Play video";
|
|
88293
89098
|
return (
|
|
88294
89099
|
// Latest version of ReactPlayer at the moment supports previewTabIndex and previewArialLabel props for passing tabindex and aria-label to the video preview button (light mode),
|
|
@@ -88307,7 +89112,7 @@ const Video = () => {
|
|
|
88307
89112
|
onKeyDown: handleKeyDown,
|
|
88308
89113
|
children: /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ReactPlayer, {
|
|
88309
89114
|
ref: videoPlayerRef,
|
|
88310
|
-
url,
|
|
89115
|
+
url: resolvedUrl,
|
|
88311
89116
|
light: lightMode,
|
|
88312
89117
|
playing,
|
|
88313
89118
|
controls: true,
|
|
@@ -93121,8 +93926,13 @@ const Audio = () => {
|
|
|
93121
93926
|
const payload = getChannelPayload(message2, config2);
|
|
93122
93927
|
const {
|
|
93123
93928
|
url,
|
|
93124
|
-
altText
|
|
93929
|
+
altText,
|
|
93930
|
+
downloadUrl
|
|
93125
93931
|
} = payload?.message?.attachment?.payload || {};
|
|
93932
|
+
const resolvedUrl = resolveAttachmentUrl({
|
|
93933
|
+
url,
|
|
93934
|
+
downloadUrl
|
|
93935
|
+
});
|
|
93126
93936
|
const playerRef = (0,react__WEBPACK_IMPORTED_MODULE_1__.useRef)(null);
|
|
93127
93937
|
const [playing, setPlaying] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(false);
|
|
93128
93938
|
const [progress, setProgress] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)(0);
|
|
@@ -93155,14 +93965,14 @@ const Audio = () => {
|
|
|
93155
93965
|
data: {
|
|
93156
93966
|
hasTranscript: !!altText
|
|
93157
93967
|
},
|
|
93158
|
-
validation: () => !!
|
|
93968
|
+
validation: () => !!resolvedUrl
|
|
93159
93969
|
});
|
|
93160
|
-
if (!
|
|
93970
|
+
if (!resolvedUrl) return null;
|
|
93161
93971
|
return /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
|
|
93162
93972
|
className: classnames$1("webchat-media-template-audio", classes$b.wrapper),
|
|
93163
93973
|
"data-testid": "audio-message",
|
|
93164
93974
|
children: [/* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ReactPlayer, {
|
|
93165
|
-
url,
|
|
93975
|
+
url: resolvedUrl,
|
|
93166
93976
|
onReady: handleFocus,
|
|
93167
93977
|
ref: playerRef,
|
|
93168
93978
|
playing,
|
|
@@ -93249,16 +94059,21 @@ const File = props2 => {
|
|
|
93249
94059
|
const {
|
|
93250
94060
|
fileName: fileName2,
|
|
93251
94061
|
size: size2,
|
|
93252
|
-
url
|
|
94062
|
+
url,
|
|
94063
|
+
downloadUrl
|
|
93253
94064
|
} = attachment;
|
|
94065
|
+
const resolvedUrl = resolveAttachmentUrl({
|
|
94066
|
+
url,
|
|
94067
|
+
downloadUrl
|
|
94068
|
+
});
|
|
93254
94069
|
return /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("a", {
|
|
93255
|
-
href:
|
|
94070
|
+
href: resolvedUrl,
|
|
93256
94071
|
target: "_blank",
|
|
93257
94072
|
style: {
|
|
93258
94073
|
textDecoration: "none"
|
|
93259
94074
|
},
|
|
93260
94075
|
children: /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("img", {
|
|
93261
|
-
src:
|
|
94076
|
+
src: resolvedUrl,
|
|
93262
94077
|
alt: `${fileName2} (${getSizeLabel(size2)})`,
|
|
93263
94078
|
className: classnames$1(attachments.length > 1 ? classes$a.smallImagePrevew : classes$a.imagePreview, "webchat-media-template-image"),
|
|
93264
94079
|
"data-testid": "image-message",
|
|
@@ -93272,10 +94087,15 @@ const File = props2 => {
|
|
|
93272
94087
|
const {
|
|
93273
94088
|
fileName: fileName2,
|
|
93274
94089
|
size: size2,
|
|
93275
|
-
url
|
|
94090
|
+
url,
|
|
94091
|
+
downloadUrl
|
|
93276
94092
|
} = attachment;
|
|
94093
|
+
const resolvedUrl = resolveAttachmentUrl({
|
|
94094
|
+
url,
|
|
94095
|
+
downloadUrl
|
|
94096
|
+
});
|
|
93277
94097
|
return /* @__PURE__ */(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("a", {
|
|
93278
|
-
href:
|
|
94098
|
+
href: resolvedUrl,
|
|
93279
94099
|
target: "_blank",
|
|
93280
94100
|
style: {
|
|
93281
94101
|
textDecoration: "none"
|
|
@@ -93582,14 +94402,14 @@ const List = () => {
|
|
|
93582
94402
|
})]
|
|
93583
94403
|
});
|
|
93584
94404
|
};
|
|
93585
|
-
const slideItem = "
|
|
93586
|
-
const top = "
|
|
93587
|
-
const bottom = "
|
|
93588
|
-
const brokenImage = "
|
|
93589
|
-
const hasExtraInfo = "
|
|
93590
|
-
const buttonListItem = "
|
|
93591
|
-
const link = "
|
|
93592
|
-
const wrapper$1 = "
|
|
94405
|
+
const slideItem = "_slideItem_jw04w_1";
|
|
94406
|
+
const top = "_top_jw04w_8";
|
|
94407
|
+
const bottom = "_bottom_jw04w_13";
|
|
94408
|
+
const brokenImage = "_brokenImage_jw04w_34";
|
|
94409
|
+
const hasExtraInfo = "_hasExtraInfo_jw04w_43";
|
|
94410
|
+
const buttonListItem = "_buttonListItem_jw04w_82";
|
|
94411
|
+
const link = "_link_jw04w_91";
|
|
94412
|
+
const wrapper$1 = "_wrapper_jw04w_138";
|
|
93593
94413
|
const classes$8 = {
|
|
93594
94414
|
slideItem,
|
|
93595
94415
|
top,
|
|
@@ -99375,7 +100195,6 @@ const getHostname = url => {
|
|
|
99375
100195
|
return "";
|
|
99376
100196
|
}
|
|
99377
100197
|
};
|
|
99378
|
-
const NESTED_CONTROL_SELECTOR = "a[href], button, input, select, textarea, summary";
|
|
99379
100198
|
const GalleryItem = props2 => {
|
|
99380
100199
|
const {
|
|
99381
100200
|
slide: slide2,
|
|
@@ -99415,7 +100234,8 @@ const GalleryItem = props2 => {
|
|
|
99415
100234
|
const linkUrl = default_action?.url ? config2?.settings?.layout?.disableUrlButtonSanitization ? default_action.url : distExports.sanitizeUrl(default_action.url) : "";
|
|
99416
100235
|
const handleClick = event => {
|
|
99417
100236
|
const target = event.target;
|
|
99418
|
-
|
|
100237
|
+
const control = target.closest(INTERACTIVE_CONTENT_SELECTOR);
|
|
100238
|
+
if (control && control !== event.currentTarget) return;
|
|
99419
100239
|
if (!linkUrl || linkUrl === "about:blank") return;
|
|
99420
100240
|
window.open(linkUrl);
|
|
99421
100241
|
};
|
|
@@ -99441,7 +100261,8 @@ const GalleryItem = props2 => {
|
|
|
99441
100261
|
id: subtitleId,
|
|
99442
100262
|
className: "webchat-carousel-template-subtitle"
|
|
99443
100263
|
});
|
|
99444
|
-
const
|
|
100264
|
+
const blockTextHasControls = htmlHasInteractiveContent(subtitleHtml) || titleBelowImage && htmlHasInteractiveContent(titleHtml);
|
|
100265
|
+
const hasBlockText = (hasSubtitle || titleBelowImage && hasTitle) && !blockTextHasControls;
|
|
99445
100266
|
const linkTarget = linkUrl && linkUrl !== "about:blank" ? hasBlockText ? "text" : "top" : null;
|
|
99446
100267
|
const titleText = linkTarget ? htmlToPlainText(titleHtml) : "";
|
|
99447
100268
|
const subtitleText = linkTarget ? htmlToPlainText(subtitleHtml) : "";
|
|
@@ -118721,10 +119542,13 @@ function customElements(pluginConfig) {
|
|
|
118721
119542
|
function setTimeAlly() {
|
|
118722
119543
|
fp?.calendarContainer?.setAttribute("aria-labelledby", "webchatDatePickerHeaderLabel");
|
|
118723
119544
|
if (fp?.config?.enableTime) {
|
|
119545
|
+
const labels = customTranslations?.ariaLabels;
|
|
118724
119546
|
const hourField = fp?.timeContainer?.getElementsByClassName("flatpickr-hour")?.[0];
|
|
118725
119547
|
hourField?.setAttribute("tabIndex", "0");
|
|
119548
|
+
if (labels?.datePickerHour) hourField?.setAttribute("aria-label", labels.datePickerHour);
|
|
118726
119549
|
const minutesField = fp?.timeContainer?.getElementsByClassName("flatpickr-minute")?.[0];
|
|
118727
119550
|
minutesField?.setAttribute("tabIndex", "0");
|
|
119551
|
+
if (labels?.datePickerMinute) minutesField?.setAttribute("aria-label", labels.datePickerMinute);
|
|
118728
119552
|
const amPmField = fp?.timeContainer?.getElementsByClassName("flatpickr-am-pm")?.[0];
|
|
118729
119553
|
amPmField?.setAttribute("tabIndex", "0");
|
|
118730
119554
|
}
|
|
@@ -118815,6 +119639,9 @@ function customElements(pluginConfig) {
|
|
|
118815
119639
|
if (cell.classList.contains("endRange")) {
|
|
118816
119640
|
parts.push(labels?.datePickerRangeEnd || "end of range");
|
|
118817
119641
|
}
|
|
119642
|
+
if (isSelectedCell(cell)) {
|
|
119643
|
+
parts.push(labels?.datePickerSelected || "selected");
|
|
119644
|
+
}
|
|
118818
119645
|
return parts.join(", ");
|
|
118819
119646
|
}
|
|
118820
119647
|
function sameYMD(a, b) {
|
|
@@ -134993,6 +135820,12 @@ const AdaptiveCard = props2 => {
|
|
|
134993
135820
|
headings.forEach(heading2 => {
|
|
134994
135821
|
if (heading2.getAttribute("aria-level") === null) heading2.setAttribute("aria-level", "4");
|
|
134995
135822
|
});
|
|
135823
|
+
const placeholderOptions = targetRef.current.querySelectorAll("select.ac-choiceSetInput-compact > option[disabled][hidden][value='']");
|
|
135824
|
+
placeholderOptions.forEach(option => {
|
|
135825
|
+
if (!option.text) return;
|
|
135826
|
+
option.disabled = false;
|
|
135827
|
+
option.hidden = false;
|
|
135828
|
+
});
|
|
134996
135829
|
const container = targetRef.current.querySelector(".ac-container.ac-adaptiveCard[aria-label][tabindex='0']");
|
|
134997
135830
|
if (container) {
|
|
134998
135831
|
const ariaLabel = container.getAttribute("aria-label");
|
|
@@ -135016,9 +135849,9 @@ const AdaptiveCard = props2 => {
|
|
|
135016
135849
|
ref: targetRef
|
|
135017
135850
|
});
|
|
135018
135851
|
};
|
|
135019
|
-
const chatDisabled = "
|
|
135852
|
+
const chatDisabled = "_chatDisabled_1yco4_68";
|
|
135020
135853
|
const styles = {
|
|
135021
|
-
"adaptivecard-wrapper": "_adaptivecard-
|
|
135854
|
+
"adaptivecard-wrapper": "_adaptivecard-wrapper_1yco4_32",
|
|
135022
135855
|
chatDisabled
|
|
135023
135856
|
};
|
|
135024
135857
|
const adaptiveCardsHostConfig = {
|