Skip to content

Commit ccfb4fd

Browse files
authored
Merge branch 'master' into feat-redux-hooks-10
2 parents 09ea985 + 62e0e88 commit ccfb4fd

25 files changed

Lines changed: 228 additions & 103 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3333
- Resolves [#2337](https://github.com/microsoft/BotFramework-WebChat/issues/2337). Remove Cognitive Services Preview warning, by [@corinagum](https://github.com/corinagum) in PR [#2578](https://github.com/microsoft/BotFramework-WebChat/pull/2578)
3434
- Fixes [#2559](https://github.com/microsoft/BotFramework-WebChat/issues/2559). De-bump remark and strip-markdown, by [@corinagum](https://github.com/corinagum) in PR [#2576](https://github.com/microsoft/BotFramework-WebChat/pull/2576)
3535
- Fixes [#2512](https://github.com/microsoft/BotFramework-WebChat/issues/2512). Adds check to ensure Adaptive Card's content is an Object, by [@tdurnford](https://github.com/tdurnford) in PR [#2590](https://github.com/microsoft/BotFramework-WebChat/pull/2590)
36+
- Fixes [#1780](https://github.com/microsoft/BotFramework-WebChat/issues/1780), [#2277](https://github.com/microsoft/BotFramework-WebChat/issues/2277), and [#2285](https://github.com/microsoft/BotFramework-WebChat/issues/2285). Make Suggested Actions accessible, Fix Markdown card in carousel being read multiple times, and label widgets of Connectivity Status and Suggested Actions containers, by [@corinagum](https://github.com/corinagum) in PR [#2613](https://github.com/microsoft/BotFramework-WebChat/pull/2613)
3637

3738
### Added
3839

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/bundle/src/adaptiveCards/Attachment/AnimationCardAttachment.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const AnimationCardAttachment = ({
2121
<div className={animationCardAttachmentStyleSet}>
2222
<ul className="media-list">
2323
{media.map(({ profile = '', url }, index) => (
24-
<li key={index}>
24+
// Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 and Edge 44
25+
<li aria-label=" " key={index}>
2526
{/\.gif$/iu.test(url) ? <ImageContent alt={profile} src={url} /> : <VideoContent alt={profile} src={url} />}
2627
</li>
2728
))}

packages/bundle/src/adaptiveCards/Attachment/AudioCardAttachment.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const AudioCardAttachment = ({
2121
<div className={audioCardAttachmentStyleSet}>
2222
<ul className="media-list">
2323
{media.map(({ url }, index) => (
24-
<li key={index}>
24+
// Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 and Edge 44
25+
<li aria-label=" " key={index}>
2526
<AudioContent autoPlay={autostart} loop={autoloop} poster={imageURL} src={url} />
2627
</li>
2728
))}

packages/bundle/src/adaptiveCards/Attachment/VideoCardAttachment.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const VideoCardAttachment = ({
2020
<div className={audioCardAttachmentStyleSet}>
2121
<ul className="media-list">
2222
{media.map(({ url }, index) => (
23-
<li key={index}>
23+
// Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 and Edge 44
24+
<li aria-label=" " key={index}>
2425
<VideoContent autoPlay={autostart} loop={autoloop} poster={imageURL} src={url} />
2526
</li>
2627
))}

packages/component/src/Activity/CarouselFilmStrip.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Context as FilmContext } from 'react-film';
55
import classNames from 'classnames';
66
import PropTypes from 'prop-types';
77
import React from 'react';
8+
import remarkStripMarkdown from '../Utils/remarkStripMarkdown';
89

910
import { Constants } from 'botframework-webchat-core';
1011

@@ -114,10 +115,10 @@ const WebChatCarouselFilmStrip = ({
114115

115116
const fromUser = role === 'user';
116117
const activityDisplayText = messageBackDisplayText || text;
118+
const strippedActivityDisplayText = remarkStripMarkdown(activityDisplayText);
117119
const indented = fromUser ? bubbleFromUserNubSize : bubbleNubSize;
118120
const initials = fromUser ? userInitials : botInitials;
119121
const roleLabel = fromUser ? userRoleLabel : botRoleLabel;
120-
121122
return (
122123
<div
123124
className={classNames(ROOT_CSS + '', carouselFilmStripStyleSet + '', className + '', {
@@ -129,8 +130,8 @@ const WebChatCarouselFilmStrip = ({
129130
<div className="content">
130131
{!!activityDisplayText && (
131132
<div className="message">
132-
<ScreenReaderText text={roleLabel} />
133-
<Bubble className="bubble" fromUser={fromUser} nub={true}>
133+
<ScreenReaderText text={roleLabel + ' ' + strippedActivityDisplayText} />
134+
<Bubble aria-hidden="true" className="bubble" fromUser={fromUser} nub={true}>
134135
{children({
135136
activity,
136137
attachment: {
@@ -144,7 +145,8 @@ const WebChatCarouselFilmStrip = ({
144145
)}
145146
<ul className={classNames({ webchat__carousel__item_indented: indented })} ref={itemContainerRef}>
146147
{attachments.map((attachment, index) => (
147-
<li key={index}>
148+
// Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 and Edge 44
149+
<li aria-label=" " key={index}>
148150
<ScreenReaderText text={roleLabel} />
149151
<Bubble fromUser={fromUser} key={index} nub={false}>
150152
{children({ attachment })}

packages/component/src/Activity/StackedLayout.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
/* eslint react/no-array-index-key: "off" */
2-
/* eslint-disable no-sync */
32

43
import { Constants } from 'botframework-webchat-core';
54
import { css } from 'glamor';
65
import classNames from 'classnames';
76
import PropTypes from 'prop-types';
87
import React from 'react';
9-
import remark from 'remark';
10-
import stripMarkdown from 'strip-markdown';
8+
import remarkStripMarkdown from '../Utils/remarkStripMarkdown';
119

1210
import Avatar from './Avatar';
1311
import Bubble from './Bubble';
@@ -19,6 +17,7 @@ import Timestamp from './Timestamp';
1917
import useAvatarForBot from '../hooks/useAvatarForBot';
2018
import useAvatarForUser from '../hooks/useAvatarForUser';
2119
import useLocalize from '../hooks/useLocalize';
20+
import useLocalizeDate from '../hooks/useLocalizeDate';
2221
import useStyleOptions from '../hooks/useStyleOptions';
2322
import useStyleSet from '../hooks/useStyleSet';
2423

@@ -97,16 +96,15 @@ const StackedLayout = ({ activity, children, timestampClassName }) => {
9796
channelData: { messageBack: { displayText: messageBackDisplayText } = {}, state } = {},
9897
from: { role } = {},
9998
text,
100-
textFormat
99+
textFormat,
100+
timestamp
101101
} = activity;
102102

103103
const activityDisplayText = messageBackDisplayText || text;
104104
const fromUser = role === 'user';
105105
const initials = fromUser ? userInitials : botInitials;
106106
const showSendStatus = state === SENDING || state === SEND_FAILED;
107-
const plainText = remark()
108-
.use(stripMarkdown)
109-
.processSync(text);
107+
const plainText = remarkStripMarkdown(text);
110108
const indented = fromUser ? bubbleFromUserNubSize : bubbleNubSize;
111109

112110
const botRoleLabel = useLocalize('BotSent');
@@ -116,8 +114,11 @@ const StackedLayout = ({ activity, children, timestampClassName }) => {
116114

117115
const botAriaLabel = useLocalize('Bot said something', initials, plainText);
118116
const userAriaLabel = useLocalize('User said something', initials, plainText);
117+
const sentAtTimestamp = useLocalize('SentAt') + useLocalizeDate(timestamp);
119118

120-
const ariaLabel = fromUser ? userAriaLabel : botAriaLabel;
119+
const someoneSaidString = (fromUser ? userAriaLabel : botAriaLabel).trim();
120+
121+
const ariaLabel = someoneSaidString + (someoneSaidString.endsWith('.') ? '' : '.') + ' ' + sentAtTimestamp;
121122

122123
return (
123124
<div
@@ -146,8 +147,8 @@ const StackedLayout = ({ activity, children, timestampClassName }) => {
146147
<div className="filler" />
147148
</div>
148149
)}
149-
{/* Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 */}
150150
{attachments.map((attachment, index) => (
151+
// Because of differences in browser implementations, aria-label=" " is used to make the screen reader not repeat the same text multiple times in Chrome v75 and Edge 44
151152
<div
152153
aria-label=" "
153154
className={classNames('webchat__row attachment', { webchat__stacked_item_indented: indented })}
@@ -163,7 +164,7 @@ const StackedLayout = ({ activity, children, timestampClassName }) => {
163164
{showSendStatus ? (
164165
<SendStatus activity={activity} className="timestamp" />
165166
) : (
166-
<Timestamp activity={activity} className={classNames('timestamp', timestampClassName)} />
167+
<Timestamp activity={activity} aria-hidden={true} className={classNames('timestamp', timestampClassName)} />
167168
)}
168169
<div className="filler" />
169170
</div>

packages/component/src/Activity/Timestamp.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import RelativeTime from '../Utils/RelativeTime';
77
import useStyleOptions from '../hooks/useStyleOptions';
88
import useStyleSet from '../hooks/useStyleSet';
99

10-
const Timestamp = ({ activity: { timestamp }, className }) => {
10+
const Timestamp = ({ activity: { timestamp }, 'aria-hidden': ariaHidden, className }) => {
1111
const [{ timestampFormat }] = useStyleOptions();
1212
const [{ timestamp: timestampStyleSet }] = useStyleSet();
1313

@@ -16,20 +16,22 @@ const Timestamp = ({ activity: { timestamp }, className }) => {
1616
}
1717

1818
return (
19-
<span className={classNames(timestampStyleSet + '', (className || '') + '')}>
19+
<span aria-hidden={ariaHidden} className={classNames(timestampStyleSet + '', (className || '') + '')}>
2020
{timestampFormat === 'relative' ? <RelativeTime value={timestamp} /> : <AbsoluteTime value={timestamp} />}
2121
</span>
2222
);
2323
};
2424

2525
Timestamp.defaultProps = {
26+
'aria-hidden': false,
2627
className: ''
2728
};
2829

2930
Timestamp.propTypes = {
3031
activity: PropTypes.shape({
3132
timestamp: PropTypes.string.isRequired
3233
}).isRequired,
34+
'aria-hidden': PropTypes.bool,
3335
className: PropTypes.string
3436
};
3537

packages/component/src/Attachment/TextContent.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
// The content rendered here is sanitized.
21
/* eslint react/no-danger: "off" */
32
/* eslint react/no-array-index-key: "off" */
43

4+
// The content rendered here is sanitized.
5+
56
import classNames from 'classnames';
67
import PropTypes from 'prop-types';
78
import React from 'react';
9+
import remarkStripMarkdown from '../Utils/remarkStripMarkdown';
810

911
import ScreenReaderText from '../ScreenReaderText';
1012
import useRenderMarkdownAsHTML from '../hooks/useRenderMarkdownAsHTML';
@@ -13,10 +15,11 @@ import useStyleSet from '../hooks/useStyleSet';
1315
const TextContent = ({ contentType, text }) => {
1416
const renderMarkdownAsHTML = useRenderMarkdownAsHTML();
1517
const [{ textContent: textContentStyleSet }] = useStyleSet();
18+
const strippedText = remarkStripMarkdown(text).contents;
1619

1720
return contentType === 'text/markdown' && renderMarkdownAsHTML ? (
1821
<React.Fragment>
19-
<ScreenReaderText text={text} />
22+
<ScreenReaderText text={strippedText} />
2023
<div
2124
aria-hidden={true}
2225
className={classNames('markdown', textContentStyleSet + '')}
@@ -26,7 +29,7 @@ const TextContent = ({ contentType, text }) => {
2629
) : (
2730
(text || '').split('\n').map((line, index) => (
2831
<React.Fragment key={index}>
29-
<ScreenReaderText text={text} />
32+
<ScreenReaderText text={remarkStripMarkdown(line.trim()).contents} />
3033
<p aria-hidden={true} className={classNames('plain', textContentStyleSet + '')}>
3134
{line.trim()}
3235
</p>

packages/component/src/Attachment/UploadAttachment.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ const UploadAttachment = ({
2020
const [{ uploadAttachment: uploadAttachmentStyleSet }] = useStyleSet();
2121

2222
const attachmentIndex = attachments.indexOf(attachment);
23+
const uploadLabel = useLocalize('Upload file');
2324
const size = attachmentSizes[attachmentIndex];
2425
const formattedSize = typeof size === 'number' && format(size);
25-
const uploadFileWithFileSizeLabel = useLocalize('UploadFileWithFileSize', attachment.name, formattedSize);
26+
const uploadFileWithFileSizeLabel = useLocalize(
27+
'UploadFileWithFileSize',
28+
uploadLabel,
29+
attachment.name,
30+
formattedSize
31+
);
2632

2733
return (
2834
<React.Fragment>

0 commit comments

Comments
 (0)