@azure/communication-react 1.34.0 → 1.35.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/dist/dist-cjs/communication-react/index.js +22 -5
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +21 -4
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../preprocess-dist/acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n// GENERATED FILE. DO NOT EDIT MANUALLY.\r\n\r\nmodule.exports = '1.
|
|
1
|
+
{"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../preprocess-dist/acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n// GENERATED FILE. DO NOT EDIT MANUALLY.\r\n\r\nmodule.exports = '1.35.0';\r\n"]}
|
|
@@ -4,11 +4,14 @@ import React from 'react';
|
|
|
4
4
|
import { _formatString } from "../../../../acs-ui-common/src";
|
|
5
5
|
import parse, { Element as DOMElement } from 'html-react-parser';
|
|
6
6
|
import { attributesToProps } from 'html-react-parser';
|
|
7
|
-
import
|
|
7
|
+
import { LinkifyIt } from 'linkify-it';
|
|
8
8
|
import { Link } from '@fluentui/react';
|
|
9
9
|
import LiveMessage from '../Announcer/LiveMessage';
|
|
10
10
|
import DOMPurify from 'dompurify';
|
|
11
11
|
import { messageTextContentStyles } from '../styles/MessageThread.styles';
|
|
12
|
+
const linkify = new LinkifyIt({
|
|
13
|
+
fuzzyLink: true
|
|
14
|
+
});
|
|
12
15
|
/** @private */
|
|
13
16
|
export const ChatMessageContent = (props) => {
|
|
14
17
|
switch (props.message.contentType) {
|
|
@@ -32,9 +35,23 @@ const MessageContentAsRichTextHTML = (props) => {
|
|
|
32
35
|
return React.createElement(MessageContentWithLiveAria, { message: props.message, liveMessage: generateLiveMessage(props), ariaLabel: messageContentAriaText(props), content: processHtmlToReact(props) });
|
|
33
36
|
};
|
|
34
37
|
const MessageContentAsText = (props) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
var _a;
|
|
39
|
+
return React.createElement(MessageContentWithLiveAria, { message: props.message, liveMessage: generateLiveMessage(props), ariaLabel: messageContentAriaText(props), className: messageTextContentStyles, content: React.createElement(React.Fragment, null, linkifyMessageContent((_a = props.message.content) !== null && _a !== void 0 ? _a : '')) });
|
|
40
|
+
};
|
|
41
|
+
const linkifyMessageContent = (content) => {
|
|
42
|
+
const matches = linkify.match(content);
|
|
43
|
+
if (!matches) {
|
|
44
|
+
return [content];
|
|
45
|
+
}
|
|
46
|
+
const contentParts = [];
|
|
47
|
+
let previousMatchEnd = 0;
|
|
48
|
+
matches.forEach(match => {
|
|
49
|
+
contentParts.push(content.slice(previousMatchEnd, match.index));
|
|
50
|
+
contentParts.push(React.createElement(Link, { target: "_blank", href: match.url, key: `${match.index}-${match.lastIndex}` }, match.text));
|
|
51
|
+
previousMatchEnd = match.lastIndex;
|
|
52
|
+
});
|
|
53
|
+
contentParts.push(content.slice(previousMatchEnd));
|
|
54
|
+
return contentParts;
|
|
38
55
|
};
|
|
39
56
|
const extractContentForAllyMessage = (props) => {
|
|
40
57
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../preprocess-dist/react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAsB,aAAa,EAAE,sCAAgC;AAC5E,OAAO,KAAK,EAAE,EAA0B,OAAO,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,OAAO,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAsC1E,eAAe;AACf,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAA8B,EAAe,EAAE;IAChF,QAAQ,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,KAAK,MAAM;YACT,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACrC,KAAK,MAAM;YACT,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAC;QAC7C,KAAK,eAAe;YAClB,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAC;QAC7C;YACE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC7C,OAAO,yCAAK,CAAC;IACjB,CAAC;AACH,CAAC,CAAC;AACF,MAAM,0BAA0B,GAAG,CAAC,KAAsC,EAAe,EAAE;IACzF,OAAO,+CAAqB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAC,MAAM,gBAAa,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS;QACjH,oBAAC,WAAW,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAC,QAAQ,GAAG;QAC5D,KAAK,CAAC,OAAO,CACV,CAAC;AACX,CAAC,CAAC;AACF,MAAM,4BAA4B,GAAG,CAAC,KAA8B,EAAe,EAAE;IACnF,OAAO,oBAAC,0BAA0B,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,sBAAsB,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAAI,CAAC;AACvL,CAAC,CAAC;AACF,MAAM,oBAAoB,GAAG,CAAC,KAA8B,EAAe,EAAE;IAC3E,OAAO,oBAAC,0BAA0B,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,sBAAsB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,wBAAwB,EAAE,OAAO,EAAE,oBAAC,OAAO,IAAC,kBAAkB,EAAE,CAAC,aAAqB,EAAE,aAAqB,EAAE,GAAW,EAAE,EAAE;gBACrR,OAAO,oBAAC,IAAI,IAAC,MAAM,EAAC,QAAQ,EAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,IAC7C,aAAa,CACT,CAAC;YACpB,CAAC,IACQ,KAAK,CAAC,OAAO,CAAC,OAAO,CACd,GAAI,CAAC;AACvB,CAAC,CAAC;AACF,MAAM,4BAA4B,GAAG,CAAC,KAA8B,EAAU,EAAE;;IAC9E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACvD,gDAAgD;QAChD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAA,KAAK,CAAC,OAAO,CAAC,OAAO,mCAAI,EAAE,EAAE;YACpE,YAAY,EAAE,CAAC,KAAK,CAAC;YACrB,mBAAmB,EAAE,IAAI;SAC1B,CAAC,CAAC;QACH,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACvC,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;gBAC3C,OAAO;YACT,CAAC;YACD,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACpD,aAAa,CAAC,SAAS,GAAG,QAAQ,CAAC;YACnC,aAAa,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,4CAA4C;QAC5C,mEAAmE;QACnE,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,yBAAyB,GAAG,8BAA8B,CAAC,KAAK,CAAC,CAAC;YACxE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACzD,kBAAkB,CAAC,SAAS,GAAG,GAAG,yBAAyB,EAAE,CAAC;YAC9D,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAChD,CAAC;QAED,iDAAiD;QACjD,IAAI,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE;YAC9C,YAAY,EAAE,EAAE;SACjB,CAAC,CAAC;QACH,4EAA4E;QAC5E,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AACF,MAAM,mBAAmB,GAAG,CAAC,KAA8B,EAAU,EAAE;IACrE,MAAM,cAAc,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,4BAA4B,EAAE;YAC3E,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE;SAC7C,CAAC,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,CAAC,UAAU,IAAI,cAAc,EAAE,CAAC;IACtH,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE;YAC9D,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE;SAC7C,CAAC,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,cAAc,GAAG,CAAC;IACtE,CAAC;AACH,CAAC,CAAC;AACF,MAAM,sBAAsB,GAAG,CAAC,KAA8B,EAAsB,EAAE;;IACpF,MAAM,OAAO,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,EAAE;QAClF,MAAM,EAAE,MAAA,KAAK,CAAC,OAAO,CAAC,MAAM,mCAAI,EAAE;QAClC,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE;QACvD,MAAM,EAAE,MAAA,KAAK,CAAC,OAAO,CAAC,MAAM,mCAAI,EAAE;QAClC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE;QAC5C,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,8BAA8B,GAAG,CAAC,KAA8B,EAAU,EAAE;IAChF,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;IAC9C,OAAO,6BAA6B,CAAC,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;AACpG,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,WAAiC,EAAE,0BAAkC,EAAU,EAAE;IAC7H,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,aAAa,CAAC,0BAA0B,EAAE;QAC/C,eAAe,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE;KACzC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,0BAA0B,GAAG,CAAC,WAAwB,EAAe,EAAE;IAC3E,OAAO,2CAAK,GAAG,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,gBAAc,WAAW,CAAC,eAAe,CAAC,EAAE,IAAM,WAAW,CAAC,eAAe,EAAI,CAAC;AAChJ,CAAC,CAAC;AACF,MAAM,kBAAkB,GAAG,CAAC,KAA8B,EAAe,EAAE;;IACzE,MAAM,OAAO,GAA2B;QACtC,SAAS,CAAC,SAAS,EAAE,OAAO;;YAC1B,IAAI,OAAO,YAAY,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrD,yCAAyC;gBACzC,0BAA0B;gBAC1B,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;oBACpF,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;wBACzB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;oBACvD,CAAC;oBACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACpD,MAAM,gBAAgB,GAAgB;wBACpC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS;wBAClC,eAAe,EAAE,QAAQ;qBAC1B,CAAC;oBACF,OAAO,CAAA,MAAA,KAAK,CAAC,kBAAkB,0CAAE,mBAAmB,EAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;gBACnM,CAAC;gBAED,qCAAqC;gBACrC,IAAI,OAAO,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,cAAc,CAAgD,SAAS,CAAC,EAAE,CAAC;oBAC3G,OAAO,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE;wBACnC,MAAM,EAAE,QAAQ;wBAChB,GAAG,EAAE,qBAAqB;qBAC3B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,iCAAiC;YACjC,OAAO,SAAmC,CAAC;QAC7C,CAAC;KACF,CAAC;IACF,OAAO,0CAAG,KAAK,CAAC,MAAA,KAAK,CAAC,OAAO,CAAC,OAAO,mCAAI,EAAE,EAAE,OAAO,CAAC,CAAI,CAAC;AAC5D,CAAC,CAAC;AACF,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAU,EAAE;IACvD,iDAAiD;IACjD,MAAM,YAAY,GAAG,0BAA0B,CAAC;IAChD,iEAAiE;IACjE,MAAM,SAAS,GAA2B;QACxC,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;QACT,EAAE,EAAE,GAAG;QACP,EAAE,EAAE,GAAG;KACR,CAAC;IACF,OAAO,aAAa;QACpB,gEAAgE;QAChE,2EAA2E;SAC1E,OAAO,CAAC,YAAY,EAAE,UAAU,KAAK,EAAE,MAAM;;QAC5C,OAAO,MAAA,SAAS,CAAC,MAAM,CAAC,mCAAI,KAAK,CAAC;IACpC,CAAC,CAAC;QACF,sCAAsC;QACtC,uFAAuF;QACvF,iDAAiD;SAChD,OAAO,CAAC,YAAY,EAAE,UAAU,KAAK,EAAE,MAAM;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { AttachmentMetadata, _formatString } from '@internal/acs-ui-common';\nimport parse, { HTMLReactParserOptions, Element as DOMElement } from 'html-react-parser';\nimport { attributesToProps } from 'html-react-parser';\nimport Linkify from 'react-linkify';\nimport { ChatMessage } from '../../types/ChatMessage';\nimport { Link } from '@fluentui/react';\nimport { MessageThreadStrings } from '../MessageThread';\nimport LiveMessage from '../Announcer/LiveMessage';\nimport DOMPurify from 'dompurify';\nimport { _AttachmentDownloadCardsStrings } from '../Attachment/AttachmentDownloadCards';\nimport { messageTextContentStyles } from '../styles/MessageThread.styles';\ntype ChatMessageContentProps = {\n message: ChatMessage;\n strings: MessageThreadStrings;\n inlineImageOptions?: InlineImageOptions;\n};\ntype MessageContentWithLiveAriaProps = {\n message: ChatMessage;\n liveMessage: string;\n ariaLabel?: string;\n content: JSX.Element;\n className?: string;\n};\n\n/**\r\n * InlineImage's state, as reflected in the UI.\r\n *\r\n * @public\r\n */\nexport interface InlineImage {\n /** ID of the message that the inline image is belonged to */\n messageId: string;\n /** Attributes of the inline image */\n imageAttributes: React.ImgHTMLAttributes<HTMLImageElement>;\n}\n\n/**\r\n * Options to display inline image in the inline image scenario.\r\n *\r\n * @public\r\n */\nexport interface InlineImageOptions {\n /**\r\n * Optional callback to render an inline image of in a message.\r\n */\n onRenderInlineImage?: (inlineImage: InlineImage, defaultOnRender: (inlineImage: InlineImage) => JSX.Element) => JSX.Element;\n}\n\n/** @private */\nexport const ChatMessageContent = (props: ChatMessageContentProps): JSX.Element => {\n switch (props.message.contentType) {\n case 'text':\n return MessageContentAsText(props);\n case 'html':\n return MessageContentAsRichTextHTML(props);\n case 'richtext/html':\n return MessageContentAsRichTextHTML(props);\n default:\n console.warn('unknown message content type');\n return <></>;\n }\n};\nconst MessageContentWithLiveAria = (props: MessageContentWithLiveAriaProps): JSX.Element => {\n return <div data-ui-status={props.message.status} role=\"text\" aria-label={props.ariaLabel} className={props.className}>\r\n <LiveMessage message={props.liveMessage} ariaLive=\"polite\" />\r\n {props.content}\r\n </div>;\n};\nconst MessageContentAsRichTextHTML = (props: ChatMessageContentProps): JSX.Element => {\n return <MessageContentWithLiveAria message={props.message} liveMessage={generateLiveMessage(props)} ariaLabel={messageContentAriaText(props)} content={processHtmlToReact(props)} />;\n};\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n return <MessageContentWithLiveAria message={props.message} liveMessage={generateLiveMessage(props)} ariaLabel={messageContentAriaText(props)} className={messageTextContentStyles} content={<Linkify componentDecorator={(decoratedHref: string, decoratedText: string, key: number) => {\n return <Link target=\"_blank\" href={decoratedHref} key={key}>\r\n {decoratedText}\r\n </Link>;\n }}>\r\n {props.message.content}\r\n </Linkify>} />;\n};\nconst extractContentForAllyMessage = (props: ChatMessageContentProps): string => {\n if (props.message.content || props.message.attachments) {\n // Replace all <img> tags with 'image' for aria.\n const parsedContent = DOMPurify.sanitize(props.message.content ?? '', {\n ALLOWED_TAGS: ['img'],\n RETURN_DOM_FRAGMENT: true\n });\n parsedContent.childNodes.forEach(child => {\n if (child.nodeName.toLowerCase() !== 'img') {\n return;\n }\n const imageTextNode = document.createElement('div');\n imageTextNode.innerHTML = 'image ';\n parsedContent.replaceChild(imageTextNode, child);\n });\n\n // Inject message attachment count for aria.\n // this is only applying to file attachments not for inline images.\n if (props.message.attachments && props.message.attachments.length > 0) {\n const attachmentCardDescription = attachmentCardGroupDescription(props);\n const attachmentTextNode = document.createElement('div');\n attachmentTextNode.innerHTML = `${attachmentCardDescription}`;\n parsedContent.appendChild(attachmentTextNode);\n }\n\n // Strip all html tags from the content for aria.\n let message = DOMPurify.sanitize(parsedContent, {\n ALLOWED_TAGS: []\n });\n // decode HTML entities so that screen reader can read the content properly.\n message = decodeEntities(message);\n return message;\n }\n return '';\n};\nconst generateLiveMessage = (props: ChatMessageContentProps): string => {\n const messageContent = extractContentForAllyMessage(props);\n if (props.message.editedOn) {\n const liveAuthor = _formatString(props.strings.editedMessageLiveAuthorIntro, {\n author: `${props.message.senderDisplayName}`\n });\n return `${props.message.mine ? props.strings.editedMessageLocalUserLiveAuthorIntro : liveAuthor} ${messageContent}`;\n } else {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, {\n author: `${props.message.senderDisplayName}`\n });\n return `${props.message.mine ? '' : liveAuthor} ${messageContent} `;\n }\n};\nconst messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n const message = extractContentForAllyMessage(props);\n return props.message.mine ? _formatString(props.strings.messageContentMineAriaText, {\n status: props.message.status ?? '',\n message: message\n }) : _formatString(props.strings.messageContentAriaText, {\n status: props.message.status ?? '',\n author: `${props.message.senderDisplayName}`,\n message: message\n });\n};\nconst attachmentCardGroupDescription = (props: ChatMessageContentProps): string => {\n const attachments = props.message.attachments;\n return getAttachmentCountLiveMessage(attachments ?? [], props.strings.attachmentCardGroupMessage);\n};\n\n/**\r\n * @private\r\n */\nexport const getAttachmentCountLiveMessage = (attachments: AttachmentMetadata[], attachmentCardGroupMessage: string): string => {\n if (attachments.length === 0) {\n return '';\n }\n return _formatString(attachmentCardGroupMessage, {\n attachmentCount: `${attachments.length}`\n });\n};\nconst defaultOnRenderInlineImage = (inlineImage: InlineImage): JSX.Element => {\n return <img key={inlineImage.imageAttributes.id} tabIndex={0} data-ui-id={inlineImage.imageAttributes.id} {...inlineImage.imageAttributes} />;\n};\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const options: HTMLReactParserOptions = {\n transform(reactNode, domNode) {\n if (domNode instanceof DOMElement && domNode.attribs) {\n // Transform custom rendering of mentions\n // Transform inline images\n if (domNode.name && domNode.name === 'img' && domNode.attribs && domNode.attribs.id) {\n if (domNode.attribs.name) {\n domNode.attribs['aria-label'] = domNode.attribs.name;\n }\n const imgProps = attributesToProps(domNode.attribs);\n const inlineImageProps: InlineImage = {\n messageId: props.message.messageId,\n imageAttributes: imgProps\n };\n return props.inlineImageOptions?.onRenderInlineImage ? props.inlineImageOptions.onRenderInlineImage(inlineImageProps, defaultOnRenderInlineImage) : defaultOnRenderInlineImage(inlineImageProps);\n }\n\n // Transform links to open in new tab\n if (domNode.name === 'a' && React.isValidElement<React.AnchorHTMLAttributes<HTMLAnchorElement>>(reactNode)) {\n return React.cloneElement(reactNode, {\n target: '_blank',\n rel: 'noreferrer noopener'\n });\n }\n }\n // Pass through the original node\n return reactNode as unknown as JSX.Element;\n }\n };\n return <>{parse(props.message.content ?? '', options)}</>;\n};\nconst decodeEntities = (encodedString: string): string => {\n // This regular expression matches HTML entities.\n const translate_re = /&(nbsp|amp|quot|lt|gt);/g;\n // This object maps HTML entities to their respective characters.\n const translate: Record<string, string> = {\n nbsp: ' ',\n amp: '&',\n quot: '\"',\n lt: '<',\n gt: '>'\n };\n return encodedString\n // Find all matches of HTML entities defined in translate_re and\n // replace them with the corresponding character from the translate object.\n .replace(translate_re, function (match, entity) {\n return translate[entity] ?? match;\n })\n // Find numeric entities (e.g., A)\n // and replace them with the equivalent character using the String.fromCharCode method,\n // which converts Unicode values into characters.\n .replace(/&#(\\d+);/gi, function (match, numStr) {\n const num = parseInt(numStr, 10);\n return String.fromCharCode(num);\n });\n};"]}
|
|
1
|
+
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../preprocess-dist/react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { AttachmentMetadata, _formatString } from '@internal/acs-ui-common';\nimport parse, { HTMLReactParserOptions, Element as DOMElement } from 'html-react-parser';\nimport { attributesToProps } from 'html-react-parser';\nimport { LinkifyIt } from 'linkify-it';\nimport { ChatMessage } from '../../types/ChatMessage';\nimport { Link } from '@fluentui/react';\nimport { MessageThreadStrings } from '../MessageThread';\nimport LiveMessage from '../Announcer/LiveMessage';\nimport DOMPurify from 'dompurify';\nimport { _AttachmentDownloadCardsStrings } from '../Attachment/AttachmentDownloadCards';\nimport { messageTextContentStyles } from '../styles/MessageThread.styles';\nconst linkify = new LinkifyIt({\n fuzzyLink: true\n});\ntype ChatMessageContentProps = {\n message: ChatMessage;\n strings: MessageThreadStrings;\n inlineImageOptions?: InlineImageOptions;\n};\ntype MessageContentWithLiveAriaProps = {\n message: ChatMessage;\n liveMessage: string;\n ariaLabel?: string;\n content: JSX.Element;\n className?: string;\n};\n\n/**\r\n * InlineImage's state, as reflected in the UI.\r\n *\r\n * @public\r\n */\nexport interface InlineImage {\n /** ID of the message that the inline image is belonged to */\n messageId: string;\n /** Attributes of the inline image */\n imageAttributes: React.ImgHTMLAttributes<HTMLImageElement>;\n}\n\n/**\r\n * Options to display inline image in the inline image scenario.\r\n *\r\n * @public\r\n */\nexport interface InlineImageOptions {\n /**\r\n * Optional callback to render an inline image of in a message.\r\n */\n onRenderInlineImage?: (inlineImage: InlineImage, defaultOnRender: (inlineImage: InlineImage) => JSX.Element) => JSX.Element;\n}\n\n/** @private */\nexport const ChatMessageContent = (props: ChatMessageContentProps): JSX.Element => {\n switch (props.message.contentType) {\n case 'text':\n return MessageContentAsText(props);\n case 'html':\n return MessageContentAsRichTextHTML(props);\n case 'richtext/html':\n return MessageContentAsRichTextHTML(props);\n default:\n console.warn('unknown message content type');\n return <></>;\n }\n};\nconst MessageContentWithLiveAria = (props: MessageContentWithLiveAriaProps): JSX.Element => {\n return <div data-ui-status={props.message.status} role=\"text\" aria-label={props.ariaLabel} className={props.className}>\r\n <LiveMessage message={props.liveMessage} ariaLive=\"polite\" />\r\n {props.content}\r\n </div>;\n};\nconst MessageContentAsRichTextHTML = (props: ChatMessageContentProps): JSX.Element => {\n return <MessageContentWithLiveAria message={props.message} liveMessage={generateLiveMessage(props)} ariaLabel={messageContentAriaText(props)} content={processHtmlToReact(props)} />;\n};\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n return <MessageContentWithLiveAria message={props.message} liveMessage={generateLiveMessage(props)} ariaLabel={messageContentAriaText(props)} className={messageTextContentStyles} content={<>{linkifyMessageContent(props.message.content ?? '')}</>} />;\n};\nconst linkifyMessageContent = (content: string): React.ReactNode[] => {\n const matches = linkify.match(content);\n if (!matches) {\n return [content];\n }\n const contentParts: React.ReactNode[] = [];\n let previousMatchEnd = 0;\n matches.forEach(match => {\n contentParts.push(content.slice(previousMatchEnd, match.index));\n contentParts.push(<Link target=\"_blank\" href={match.url} key={`${match.index}-${match.lastIndex}`}>\r\n {match.text}\r\n </Link>);\n previousMatchEnd = match.lastIndex;\n });\n contentParts.push(content.slice(previousMatchEnd));\n return contentParts;\n};\nconst extractContentForAllyMessage = (props: ChatMessageContentProps): string => {\n if (props.message.content || props.message.attachments) {\n // Replace all <img> tags with 'image' for aria.\n const parsedContent = DOMPurify.sanitize(props.message.content ?? '', {\n ALLOWED_TAGS: ['img'],\n RETURN_DOM_FRAGMENT: true\n });\n parsedContent.childNodes.forEach(child => {\n if (child.nodeName.toLowerCase() !== 'img') {\n return;\n }\n const imageTextNode = document.createElement('div');\n imageTextNode.innerHTML = 'image ';\n parsedContent.replaceChild(imageTextNode, child);\n });\n\n // Inject message attachment count for aria.\n // this is only applying to file attachments not for inline images.\n if (props.message.attachments && props.message.attachments.length > 0) {\n const attachmentCardDescription = attachmentCardGroupDescription(props);\n const attachmentTextNode = document.createElement('div');\n attachmentTextNode.innerHTML = `${attachmentCardDescription}`;\n parsedContent.appendChild(attachmentTextNode);\n }\n\n // Strip all html tags from the content for aria.\n let message = DOMPurify.sanitize(parsedContent, {\n ALLOWED_TAGS: []\n });\n // decode HTML entities so that screen reader can read the content properly.\n message = decodeEntities(message);\n return message;\n }\n return '';\n};\nconst generateLiveMessage = (props: ChatMessageContentProps): string => {\n const messageContent = extractContentForAllyMessage(props);\n if (props.message.editedOn) {\n const liveAuthor = _formatString(props.strings.editedMessageLiveAuthorIntro, {\n author: `${props.message.senderDisplayName}`\n });\n return `${props.message.mine ? props.strings.editedMessageLocalUserLiveAuthorIntro : liveAuthor} ${messageContent}`;\n } else {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, {\n author: `${props.message.senderDisplayName}`\n });\n return `${props.message.mine ? '' : liveAuthor} ${messageContent} `;\n }\n};\nconst messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n const message = extractContentForAllyMessage(props);\n return props.message.mine ? _formatString(props.strings.messageContentMineAriaText, {\n status: props.message.status ?? '',\n message: message\n }) : _formatString(props.strings.messageContentAriaText, {\n status: props.message.status ?? '',\n author: `${props.message.senderDisplayName}`,\n message: message\n });\n};\nconst attachmentCardGroupDescription = (props: ChatMessageContentProps): string => {\n const attachments = props.message.attachments;\n return getAttachmentCountLiveMessage(attachments ?? [], props.strings.attachmentCardGroupMessage);\n};\n\n/**\r\n * @private\r\n */\nexport const getAttachmentCountLiveMessage = (attachments: AttachmentMetadata[], attachmentCardGroupMessage: string): string => {\n if (attachments.length === 0) {\n return '';\n }\n return _formatString(attachmentCardGroupMessage, {\n attachmentCount: `${attachments.length}`\n });\n};\nconst defaultOnRenderInlineImage = (inlineImage: InlineImage): JSX.Element => {\n return <img key={inlineImage.imageAttributes.id} tabIndex={0} data-ui-id={inlineImage.imageAttributes.id} {...inlineImage.imageAttributes} />;\n};\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const options: HTMLReactParserOptions = {\n transform(reactNode, domNode) {\n if (domNode instanceof DOMElement && domNode.attribs) {\n // Transform custom rendering of mentions\n // Transform inline images\n if (domNode.name && domNode.name === 'img' && domNode.attribs && domNode.attribs.id) {\n if (domNode.attribs.name) {\n domNode.attribs['aria-label'] = domNode.attribs.name;\n }\n const imgProps = attributesToProps(domNode.attribs);\n const inlineImageProps: InlineImage = {\n messageId: props.message.messageId,\n imageAttributes: imgProps\n };\n return props.inlineImageOptions?.onRenderInlineImage ? props.inlineImageOptions.onRenderInlineImage(inlineImageProps, defaultOnRenderInlineImage) : defaultOnRenderInlineImage(inlineImageProps);\n }\n\n // Transform links to open in new tab\n if (domNode.name === 'a' && React.isValidElement<React.AnchorHTMLAttributes<HTMLAnchorElement>>(reactNode)) {\n return React.cloneElement(reactNode, {\n target: '_blank',\n rel: 'noreferrer noopener'\n });\n }\n }\n // Pass through the original node\n return reactNode as unknown as JSX.Element;\n }\n };\n return <>{parse(props.message.content ?? '', options)}</>;\n};\nconst decodeEntities = (encodedString: string): string => {\n // This regular expression matches HTML entities.\n const translate_re = /&(nbsp|amp|quot|lt|gt);/g;\n // This object maps HTML entities to their respective characters.\n const translate: Record<string, string> = {\n nbsp: ' ',\n amp: '&',\n quot: '\"',\n lt: '<',\n gt: '>'\n };\n return encodedString\n // Find all matches of HTML entities defined in translate_re and\n // replace them with the corresponding character from the translate object.\n .replace(translate_re, function (match, entity) {\n return translate[entity] ?? match;\n })\n // Find numeric entities (e.g., A)\n // and replace them with the equivalent character using the String.fromCharCode method,\n // which converts Unicode values into characters.\n .replace(/&#(\\d+);/gi, function (match, numStr) {\n const num = parseInt(numStr, 10);\n return String.fromCharCode(num);\n });\n};"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure/communication-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"description": "React library for building modern communication user experiences utilizing Azure Communication Services",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"immer": "10.1.1",
|
|
43
43
|
"memoize-one": "^5.2.1",
|
|
44
44
|
"nanoid": "3.3.8",
|
|
45
|
-
"
|
|
45
|
+
"linkify-it": "^6.1.0",
|
|
46
46
|
"react-use-draggable-scroll": "^0.4.7",
|
|
47
47
|
"reselect": "^4.0.0",
|
|
48
48
|
"roosterjs-content-model-api": "^9.27.0",
|