diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4ef5d28e06..0f858f4c49 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -117,7 +117,6 @@ If your development box has less than 4 cores, you will need to reduce the numbe Our CI pipeline run tests with 4 agents simultaneously. If new tests are added, please make sure they can run simultaneously. - ### Troubleshooting the test suite We run test suite on every commit and requires 100% test pass. If the test suite did not complete successfully, they are likely: diff --git a/.github/ISSUE_TEMPLATE/question-template.md b/.github/ISSUE_TEMPLATE/question-template.md index e1e0a509e5..539937ccfd 100644 --- a/.github/ISSUE_TEMPLATE/question-template.md +++ b/.github/ISSUE_TEMPLATE/question-template.md @@ -20,5 +20,4 @@ This repo focuses on the development of Web Chat, a client/channel for Bot Frame | Bot Framework Questions | Ask implementation questions related to the BotFramework SDK | https://stackoverflow.com/questions/tagged/botframework | | Bot Builder | A comprehensive list of Bot Framework SDKs and tools | https://github.com/microsoft/BotBuilder | - [Question] diff --git a/CHANGELOG.md b/CHANGELOG.md index 93eba826f1..9ca9b846ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixes [#3672](https://github.com/microsoft/BotFramework-WebChat/issues/3672). Center the icon of send box buttons vertically and horizontally, by [@compulim](https://github.com/compulim) in PR [#3673](https://github.com/microsoft/BotFramework-WebChat/pull/3673) - Fixes [#3683](https://github.com/microsoft/BotFramework-WebChat/issues/3683). Activities should be acknowledged when user scrolls to bottom, by [@compulim](https://github.com/compulim) in PR [#3684](https://github.com/microsoft/BotFramework-WebChat/pull/3684) - Fixes [#3676](https://github.com/microsoft/BotFramework-WebChat/issues/3676). Activities without text should not generate bogus `aria-labelledby`, by [@compulim](https://github.com/compulim) in PR [#3697](https://github.com/microsoft/BotFramework-WebChat/pull/3697) +- Fixes [#3625](https://github.com/microsoft/BotFramework-WebChat/issues/3625). Update 'no screen reader for custom activity middleware' warning and add screen reader renderer documentation to `ACCESSIBILITY.md`, by [@corinagum](https://github.com/corinagum) in PR [#3689](https://github.com/microsoft/BotFramework-WebChat/pull/3689) ### Changed @@ -96,8 +97,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Samples - Fixes [#3473](https://github.com/microsoft/BotFramework-WebChat/issues/3473). Fix samples using activityMiddleware (from 4.10.0 breaking changes), by [@corinagum](https://github.com/corinagum) in PR [#3601](https://github.com/microsoft/BotFramework-WebChat/pull/3601) -- Fixes [#3434](https://github.com/microsoft/BotFramework-WebChat/issues/3434). Dispatched event, postBack, or messageBack + activityMiddleware causes fatal error, by [@amal-khalaf](https://github.com/amal-khalaf) in PR [#3671](https://github.com/microsoft/BotFramework-WebChat/pull/3671) - Fixes [#3582](https://github.com/microsoft/BotFramework-WebChat/issues/3582). Fix Disable Adaptive Cards sample, by [@corinagum](https://github.com/corinagum) in PR [#3687](https://github.com/microsoft/BotFramework-WebChat/pull/3687) +- Fixes [#3434](https://github.com/microsoft/BotFramework-WebChat/issues/3434). Dispatched event, postBack, or messageBack + activityMiddleware causes fatal error, by [@amal-khalaf](https://github.com/amal-khalaf) in PR [#3671](https://github.com/microsoft/BotFramework-WebChat/pull/3671) - Fixes [#3215](https://github.com/microsoft/BotFramework-WebChat/issues/3215). Fix SSO samples `window.opener.postMessage`, by [@corinagum](https://github.com/corinagum) in PR [#3696](https://github.com/microsoft/BotFramework-WebChat/pull/3696) ## [4.11.0] - 2020-11-04 diff --git a/README.md b/README.md index e176b3f5fc..63840e5f51 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ This repo is part of the [Microsoft Bot Framework](https://github.com/microsoft/ > This section points out important version notes. For further information, please see the related links and check the [`CHANGELOG.md`](https://github.com/microsoft/BotFramework-WebChat/blob/master/CHANGELOG.md) ## API refactor into new package in Web Chat 4.11.0 -The Web Chat API has been refactored into a separate package. To learn more, check out the [API refactor summary](https://github.com/microsoft/BotFramework-WebChat/pull/3543). +The Web Chat API has been refactored into a separate package. To learn more, check out the [API refactor summary](https://github.com/microsoft/BotFramework-WebChat/pull/3543). ## Direct Line Speech support in Web Chat 4.7.0 diff --git a/__tests__/__image_snapshots__/html/accessibility-live-region-attachment-unknown-card-js-accessibility-requirement-attachments-in-live-region-unknown-card-1-snap.png b/__tests__/__image_snapshots__/html/accessibility-live-region-attachment-unknown-card-js-accessibility-requirement-attachments-in-live-region-unknown-card-1-snap.png index acc618d3b3..815845cf1a 100644 Binary files a/__tests__/__image_snapshots__/html/accessibility-live-region-attachment-unknown-card-js-accessibility-requirement-attachments-in-live-region-unknown-card-1-snap.png and b/__tests__/__image_snapshots__/html/accessibility-live-region-attachment-unknown-card-js-accessibility-requirement-attachments-in-live-region-unknown-card-1-snap.png differ diff --git a/__tests__/adaptiveCards.js b/__tests__/adaptiveCards.js index dcc23b3002..1ba611d521 100644 --- a/__tests__/adaptiveCards.js +++ b/__tests__/adaptiveCards.js @@ -1,5 +1,6 @@ -import { imageSnapshotOptions, timeouts } from './constants.json'; +import { logging } from 'selenium-webdriver'; +import { imageSnapshotOptions, timeouts } from './constants.json'; import allImagesLoaded from './setup/conditions/allImagesLoaded'; import minNumActivitiesShown from './setup/conditions/minNumActivitiesShown'; import scrollToBottomCompleted from './setup/conditions/scrollToBottomCompleted'; @@ -152,3 +153,17 @@ test('broken card of invalid version', async () => { expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions); }); + +test('unknown card', async () => { + const { driver, pageObjects } = await setupWebDriver(); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('card unknown', { waitForSend: true }); + + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + const browserConsoleErrors = await driver.manage().logs().get(logging.Type.BROWSER); + + expect(browserConsoleErrors[0].level.name_).toEqual('WARNING'); + expect(browserConsoleErrors[0].message).toContain('No renderer for attachment for screen reader of type'); +}); diff --git a/docs/ACCESSIBILITY.md b/docs/ACCESSIBILITY.md index 848c0f65de..96a4d2a48f 100644 --- a/docs/ACCESSIBILITY.md +++ b/docs/ACCESSIBILITY.md @@ -187,7 +187,7 @@ To make the live region more consistent across browsers and easier to control, w - 0-100 ms: Chrome and TalkBack on Android may miss some of the activities - The development team settled on using one second after some experimentation -## Do and don't +## Do's and don't ### Do @@ -211,6 +211,22 @@ To make the live region more consistent across browsers and easier to control, w - It is okay to disable all buttons, as long as the answer will be read by the screen reader - Related to [#3135](https://github.com/microsoft/BotFramework-WebChat/issues/3135) - Don't move focus when an activity arrives (or asynchronously) - - Screen reader reading will be interrupted when focus change + - Screen reader reading will be interrupted when focus changes - Only change focus synchronous to user gesture - Related to [#3135](https://github.com/microsoft/BotFramework-WebChat/issues/3135) + +# Screen reader renderer for custom activities and attachments + +Web Chat render components are accompanied by a screen reader renderer to maximize accessibility. In the case of custom components, the bot/Web Chat developer will need to implement a screen reader renderer for the equivalent custom visual component. + +![image: Console warning: "No renderer for attachment for screen reader of type "application/mnd.microsoft.card.adaptive"](https://user-images.githubusercontent.com/14900841/106323546-6f47ed80-622c-11eb-96d7-de6f72818525.png) + +The Web Chat team **DOES NOT** recommend disabling warning messages regarding screen readers and accessibility. However, if the developer decides to suppress these messages, it can be done by adding the following code to `attachmentForScreenReaderMiddleware` in the `Composer` props. + +```js +const attachmentForScreenReaderMiddleware = () => next => () => { + return false; +}; +``` + +This will prevent the screen reader renderer warning from appearing in the browser console. diff --git a/lint-staged.config.js b/lint-staged.config.js index fc79c206f9..27af537e89 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -6,8 +6,10 @@ function prettierMarkdown(filenames) { return filenames.map(filename => `prettier --write ${filename} --tab-width 3 --single-quote true`); } +// eslint-disable-next-line no-undef module.exports = { - '{__tests__,samples}/**/*.{html,js,jsx,ts,tsx}': prettierCode, + '{__tests__,docs,samples}/**/*.{html,js,jsx,ts,tsx}': prettierCode, '**/*.md': prettierMarkdown, - 'packages/{bundle,component,core,embed,playground}/src/**/*.{js,jsx,ts,tsx}': prettierCode + 'packages/{api,bundle,component,core,directlinespeech,playground}/src/**/*.{js,jsx,ts,tsx}': prettierCode, + '*.{js,jsx,ts,tsx}': 'npm run eslint' }; diff --git a/package.json b/package.json index 85885c7be7..32982bfa17 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "homepage": "https://github.com/microsoft/BotFramework-WebChat#readme", "husky": { "hooks": { - "pre-commit": "lint-staged --no-stash" + "pre-commit": "lint-staged --no-stash --config lint-staged.config.js" } }, "keywords": [], @@ -25,9 +25,7 @@ "bootstrap": "lerna bootstrap --ci", "build": "lerna run --ignore playground --stream build", "coveralls": "cat ./coverage/lcov.info | coveralls", - "eslint": "lerna run --parallel --stream eslint", - "posteslint": "npm run prettier-readmes", - "prettier-readmes": "prettier --write **/**/*.md --tab-width 3 --single-quote true", + "eslint": "lerna run --parallel --stream eslint -- ", "start": "concurrently --kill-others --raw \"serve\" \"serve -p 5001 -c serve-test.json\" \"lerna run --ignore playground --parallel --stream start\"", "start:docker": "npm run start:docker:build && npm run start:docker:up", "start:docker:build": "docker-compose -f docker-compose-wsl2.yml build --parallel", @@ -75,4 +73,4 @@ "xmlbuilder": "^15.1.1" }, "dependencies": {} -} +} \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index ce4097dea6..1a55debb09 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -21,7 +21,7 @@ "build:babel": "babel src --copy-files --extensions .js,.ts,.tsx --ignore **/*.spec.js,**/*.spec.ts,**/*.spec.tsx,**/*.test.js,**/*.test.ts,**/*.test.tsx,__tests__/**/*.js,__tests__/**/*.ts,__tests__/**/*.tsx --no-copy-ignored --out-dir lib --verbose", "build:globalize": "node scripts/createPrecompiledGlobalize.js", "build:typescript": "tsc --project src/tsconfig.json", - "eslint": "eslint src/**/*.js src/**/*.ts", + "eslint": "eslint src/**/*.js src/**/*.ts --fix", "prestart": "npm run build:babel", "start": "concurrently --kill-others --names \"babel,globalize,tsc\" \"npm run start:babel\" \"npm run start:globalize\" \"npm run start:typescript\"", "start:babel": "npm run build:babel -- --skip-initial-build --watch", diff --git a/packages/api/src/hooks/Composer.js b/packages/api/src/hooks/Composer.js index 94fb0d1070..e8ea4bff7a 100644 --- a/packages/api/src/hooks/Composer.js +++ b/packages/api/src/hooks/Composer.js @@ -92,10 +92,11 @@ function createCardActionContext({ cardActionMiddleware, directLine, dispatch }) const { value } = cardAction; if (directLine.getSessionId) { - // TODO: [P3] We should change this one to async/await. - // This is the first place in this project to use async. - // Thus, we need to add @babel/plugin-transform-runtime and @babel/runtime. - + /** + * @todo TODO: [P3] We should change this one to async/await. + * This is the first place in this project to use async. + * Thus, we need to add @babel/plugin-transform-runtime and @babel/runtime. + */ return observableToPromise(directLine.getSessionId()).then( sessionId => `${value}${encodeURIComponent(`&code_challenge=${sessionId}`)}` ); @@ -211,7 +212,9 @@ const Composer = ({ ); return () => { - // TODO: [P3] disconnect() is an async call (pending -> fulfilled), we need to wait, or change it to reconnect() + /** + * @todo TODO: [P3] disconnect() is an async call (pending -> fulfilled), we need to wait, or change it to reconnect() + */ dispatch(disconnect()); }; }, [dispatch, directLine, userID, username]); @@ -319,12 +322,18 @@ const Composer = ({ 'attachment for screen reader', { strict: true }, ...singleToArray(attachmentForScreenReaderMiddleware), - () => () => ({ attachment }) => () => { + () => () => ({ attachment }) => { if (attachment) { - throw new Error(`No renderer for attachment for screen reader of type "${attachment.contentType}"`); - } else { - throw new Error('No attachment to render'); + console.warn(`No renderer for attachment for screen reader of type "${attachment.contentType}"`); + return false; } + + return () => { + /** + * @todo TODO: [P4] Might be able to throw without returning a function -- investigate and possibly fix + */ + throw new Error('No attachment to render'); + }; } )({}), [attachmentForScreenReaderMiddleware] @@ -403,17 +412,17 @@ const Composer = ({ ); }, [typingIndicatorMiddleware, typingIndicatorRenderer]); - // This is a heavy function, and it is expected to be only called when there is a need to recreate business logic, e.g. - // - User ID changed, causing all send* functions to be updated - // - send - - // TODO: [P3] We should think about if we allow the user to change onSendBoxValueChanged/sendBoxValue, e.g. - // 1. Turns text into UPPERCASE - // 2. Filter out profanity - - // TODO: [P4] Revisit all members of context - // This context should consist of members that are not in the Redux store - // i.e. members that are not interested in other types of UIs + /** + * This is a heavy function, and it is expected to be only called when there is a need to recreate business logic, e.g. + * - User ID changed, causing all send* functions to be updated + * - send + * @todo TODO: [P3] We should think about if we allow the user to change onSendBoxValueChanged/sendBoxValue, e.g. + * 1. Turns text into UPPERCASE + * 2. Filter out profanity + * @todo TODO: [P4] Revisit all members of context + * This context should consist of members that are not in the Redux store + * i.e. members that are not interested in other types of UIs + */ const context = useMemo( () => ({ ...cardActionContext, @@ -526,11 +535,12 @@ ComposeWithStore.propTypes = { export default ComposeWithStore; -// TODO: [P3] We should consider moving some data from Redux store to props -// Although we use `connectToWebChat` to hide the details of accessor of Redux store, -// we should clean up the responsibility between Context and Redux store -// We should decide which data is needed for React but not in other environment such as CLI/VSCode - +/** + * @todo TODO: [P3] We should consider moving some data from Redux store to props + * Although we use `connectToWebChat` to hide the details of accessor of Redux store, + * we should clean up the responsibility between Context and Redux store + * We should decide which data is needed for React but not in other environment such as CLI/VSCode + */ Composer.defaultProps = { activityMiddleware: undefined, activityRenderer: undefined, diff --git a/packages/api/src/hooks/internal/ErrorBox.js b/packages/api/src/hooks/internal/ErrorBox.js index 69d98ec578..a5437831ac 100644 --- a/packages/api/src/hooks/internal/ErrorBox.js +++ b/packages/api/src/hooks/internal/ErrorBox.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { createElement, useEffect } from 'react'; import PropTypes from 'prop-types'; diff --git a/packages/api/src/hooks/middleware/applyMiddleware.js b/packages/api/src/hooks/middleware/applyMiddleware.js index d3abeaa2dd..091bf7b62f 100644 --- a/packages/api/src/hooks/middleware/applyMiddleware.js +++ b/packages/api/src/hooks/middleware/applyMiddleware.js @@ -10,17 +10,21 @@ export default function applyMiddleware(type, ...middleware) { throw new Error(`reached terminator of ${type}`); }); } - +/** + * + * @param {string} type Required. String equivalent of type of container to be rendered. + * @param { strict = false } - Used to enforce new middleware format which cooperates with new activity grouping. + * @see See {@link https://github.com/microsoft/BotFramework-WebChat/blob/master/CHANGELOG.md#4100---2020-08-18} and {@link https://github.com/microsoft/BotFramework-WebChat/pull/3365} for middleware breaking changes. + * @param {middleware[]} middleware list of middleware to be applied. + * 'createRendererArgs' is "what to render"; for example, an activity. + * @returns Returns a function if there is a renderer *committed* to render OR returns false if nothing should be rendered. + */ export function forRenderer(type, { strict = false } = {}, ...middleware) { return (...setupArgs) => { const runMiddleware = concatMiddleware(...middleware)(...setupArgs)(() => ( )); - // The createRendererArgs is "what to render", for example, activity. - // The function should return with only one of the two results: - // - Returns a function if there is a renderer *committed* to render; - // - Returns false if nothing should be rendered. return (...createRendererArgs) => { try { const render = runMiddleware(...createRendererArgs); diff --git a/packages/api/src/hooks/utils/ErrorBoundary.js b/packages/api/src/hooks/utils/ErrorBoundary.js index f7c90af392..229fbd489b 100644 --- a/packages/api/src/hooks/utils/ErrorBoundary.js +++ b/packages/api/src/hooks/utils/ErrorBoundary.js @@ -11,13 +11,18 @@ class ErrorBoundary extends Component { } componentDidCatch(error) { + const { onError } = this.props; + this.setState({ hasError: true }); - this.props.onError(error); + onError(error); } render() { - return !this.state.hasError && {this.props.children}; + const { children } = this.props; + const { hasError } = this.state; + + return !hasError && {children}; } } diff --git a/packages/api/src/patchStyleOptions.js b/packages/api/src/patchStyleOptions.js index b9d5500608..b50a248695 100644 --- a/packages/api/src/patchStyleOptions.js +++ b/packages/api/src/patchStyleOptions.js @@ -22,6 +22,7 @@ function parseBorder(border) { const PIXEL_UNIT_PATTERN = /^\d+px$/u; +// eslint-disable-next-line complexity export default function patchStyleOptions( options, { groupTimestamp: groupTimestampFromProps, sendTimeout: sendTimeoutFromProps } diff --git a/packages/bundle/package.json b/packages/bundle/package.json index 9ba9a248cc..a45b7e64ec 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -21,7 +21,7 @@ "build:babel": "babel src --extensions .js,.ts,.tsx --ignore **/*.spec.js,**/*.spec.ts,**/*.spec.tsx,**/*.test.js,**/*.test.ts,**/*.test.tsx,__tests__/**/*.js,__tests__/**/*.ts,__tests__/**/*.tsx --out-dir lib --verbose", "build:typescript": "tsc --project src/tsconfig.json", "build:webpack": "webpack-cli", - "eslint": "eslint src/**/*.js src/**/*.ts", + "eslint": "eslint src/**/*.js src/**/*.ts --fix", "prestart": "npm run build:babel", "start": "concurrently --kill-others --names \"babel,tsc,webpack\" \"npm run start:babel\" \"npm run start:typescript\" \"npm run start:webpack\"", "start:babel": "npm run build:babel -- --skip-initial-build --watch", diff --git a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js index 93d609c098..b7b3dc643b 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js +++ b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js @@ -11,6 +11,7 @@ import useAdaptiveCardsPackage from '../hooks/useAdaptiveCardsPackage'; const { ErrorBox } = Components; const { useDisabled, useLocalizer, usePerformCardAction, useRenderMarkdownAsHTML, useScrollToEnd, useStyleSet } = hooks; +// eslint-disable-next-line no-undef const node_env = process.env.node_env || process.env.NODE_ENV; function addClass(element, className) { diff --git a/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/AdaptiveCardAttachment.js b/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/AdaptiveCardAttachment.js index 1320a2a7f1..fb266e4da5 100644 --- a/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/AdaptiveCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/AdaptiveCardAttachment.js @@ -1,3 +1,5 @@ +/* eslint-disable react/no-array-index-key */ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-component'; import PropTypes from 'prop-types'; import React, { useMemo } from 'react'; @@ -50,8 +52,9 @@ AdaptiveCardChoiceSetInput.propTypes = { value: PropTypes.any }) ), + defaultValue: PropTypes.any, value: PropTypes.any - }) + }).isRequired }; const AdaptiveCardAttachment = ({ content }) => { @@ -93,7 +96,18 @@ const AdaptiveCardAttachment = ({ content }) => { }); return inputs; - }, [card]); + }, [ + card, + ChoiceSetInput, + DateInput, + NumberInput, + OpenUrlAction, + ShowCardAction, + SubmitAction, + TextInput, + TimeInput, + ToggleInput + ]); const cardLabel = localize('ATTACHMENT_CARD', card.speak || '', '', ''); diff --git a/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/RichCardAttachment.js b/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/RichCardAttachment.js index 86b2d1d1de..eb49468f12 100644 --- a/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/RichCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/AttachmentForScreenReader/RichCardAttachment.js @@ -1,3 +1,5 @@ +/* eslint-disable react/forbid-dom-props */ +/* eslint-disable react/no-array-index-key */ import PropTypes from 'prop-types'; import React from 'react'; import { hooks } from 'botframework-webchat-component'; diff --git a/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.js b/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.js index 360c4ccb36..8ac1094a21 100644 --- a/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.js +++ b/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.js @@ -69,6 +69,7 @@ export default function createCognitiveServicesSpeechServicesPonyfillFactory({ // We will not need this code when using Speech SDK 1.14.0 or up. // TODO: [P1] #3575 Remove the following lines when bumping to Speech SDK 1.14.0 or higher source.createAudioContext = () => { + // eslint-disable-next-line no-extra-boolean-cast if (!!source.privContext) { return; } diff --git a/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js b/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js index fc474c8111..a22b2687e0 100644 --- a/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js +++ b/packages/bundle/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js @@ -1,3 +1,4 @@ +/* eslint-disable no-global-assign */ let consoleWarns; let createCognitiveServicesSpeechServicesPonyfillFactory; let createPonyfill; diff --git a/packages/bundle/webpack.config.js b/packages/bundle/webpack.config.js index d59ab25b92..268e0d5c7e 100644 --- a/packages/bundle/webpack.config.js +++ b/packages/bundle/webpack.config.js @@ -38,11 +38,23 @@ let config = { ], resolve: { alias: { - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig.js'), + 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig': resolve( + __dirname, + 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig.js' + ), // TODO: [P1] #3575 Remove the following line when bumping to Speech SDK 1.14.0 or higher - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource.js'), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js'), - 'microsoft-cognitiveservices-speech-sdk': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js'), + 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource': resolve( + __dirname, + 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource.js' + ), + 'microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk': resolve( + __dirname, + 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js' + ), + 'microsoft-cognitiveservices-speech-sdk': resolve( + __dirname, + 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js' + ), react: resolve(__dirname, 'node_modules/isomorphic-react/dist/react.js'), 'react-dom': resolve(__dirname, 'node_modules/isomorphic-react-dom/dist/react-dom.js') }, diff --git a/packages/component/package.json b/packages/component/package.json index 0cf0406dde..14677d9c43 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -20,7 +20,7 @@ "build": "npm run build:typescript && npm run build:babel", "build:babel": "babel src --copy-files --extensions .js,.ts,.tsx --ignore **/*.spec.js,**/*.spec.ts,**/*.spec.tsx,**/*.test.js,**/*.test.ts,**/*.test.tsx,__tests__/**/*.js,__tests__/**/*.ts,__tests__/**/*.tsx --no-copy-ignored --out-dir lib --verbose", "build:typescript": "tsc --project src/tsconfig.json", - "eslint": "eslint src/**/*.js src/**/*.ts", + "eslint": "eslint src/**/*.js src/**/*.ts --fix", "prestart": "npm run build:babel", "start": "concurrently --kill-others --names \"babel,tsc\" \"npm run start:babel\" \"npm run start:typescript\"", "start:babel": "npm run build:babel -- --skip-initial-build --watch", diff --git a/packages/component/src/BasicTranscript.js b/packages/component/src/BasicTranscript.js index 2af5ff3187..cec43e1fa1 100644 --- a/packages/component/src/BasicTranscript.js +++ b/packages/component/src/BasicTranscript.js @@ -704,9 +704,9 @@ const SetScroller = ({ activityElementsRef, scrollerRef }) => { } return values.reduce((minValue, value) => Math.min(minValue, value), Infinity); - } else { - return Infinity; } + + return Infinity; }, [ activityElementsRef, diff --git a/packages/component/src/Composer.js b/packages/component/src/Composer.js index df24451ab0..9bc1ab4454 100644 --- a/packages/component/src/Composer.js +++ b/packages/component/src/Composer.js @@ -30,6 +30,7 @@ import WebChatUIContext from './hooks/internal/WebChatUIContext'; const { useReferenceGrammarID, useStyleOptions } = hooks; +// eslint-disable-next-line no-undef const node_env = process.env.node_env || process.env.NODE_ENV; const emotionPool = {}; diff --git a/packages/component/src/ErrorBox.js b/packages/component/src/ErrorBox.js index 120c9dea8a..99339ab9a2 100644 --- a/packages/component/src/ErrorBox.js +++ b/packages/component/src/ErrorBox.js @@ -29,13 +29,10 @@ const ErrorBox = ({ error, type }) => { }; ErrorBox.defaultProps = { - children: undefined, - error: undefined, type: '' }; ErrorBox.propTypes = { - children: PropTypes.any, error: PropTypes.instanceOf(Error).isRequired, type: PropTypes.string }; diff --git a/packages/component/src/Middleware/AttachmentForScreenReader/AudioAttachment.js b/packages/component/src/Middleware/AttachmentForScreenReader/AudioAttachment.js index cdb720dad2..3fe4d8bea8 100644 --- a/packages/component/src/Middleware/AttachmentForScreenReader/AudioAttachment.js +++ b/packages/component/src/Middleware/AttachmentForScreenReader/AudioAttachment.js @@ -1,3 +1,4 @@ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-api'; import React from 'react'; diff --git a/packages/component/src/Middleware/AttachmentForScreenReader/FileAttachment.js b/packages/component/src/Middleware/AttachmentForScreenReader/FileAttachment.js index 752f17eed8..95bc57a2a3 100644 --- a/packages/component/src/Middleware/AttachmentForScreenReader/FileAttachment.js +++ b/packages/component/src/Middleware/AttachmentForScreenReader/FileAttachment.js @@ -1,3 +1,4 @@ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-api'; import PropTypes from 'prop-types'; import React from 'react'; diff --git a/packages/component/src/Middleware/AttachmentForScreenReader/ImageAttachment.js b/packages/component/src/Middleware/AttachmentForScreenReader/ImageAttachment.js index 060215e653..f6728db1a1 100644 --- a/packages/component/src/Middleware/AttachmentForScreenReader/ImageAttachment.js +++ b/packages/component/src/Middleware/AttachmentForScreenReader/ImageAttachment.js @@ -1,3 +1,4 @@ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-api'; import React from 'react'; diff --git a/packages/component/src/Middleware/AttachmentForScreenReader/TextAttachment.js b/packages/component/src/Middleware/AttachmentForScreenReader/TextAttachment.js index 0d3d1ab5c5..c6d5cb72e6 100644 --- a/packages/component/src/Middleware/AttachmentForScreenReader/TextAttachment.js +++ b/packages/component/src/Middleware/AttachmentForScreenReader/TextAttachment.js @@ -1,3 +1,4 @@ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-api'; import PropTypes from 'prop-types'; import React from 'react'; diff --git a/packages/component/src/Middleware/AttachmentForScreenReader/VideoAttachment.js b/packages/component/src/Middleware/AttachmentForScreenReader/VideoAttachment.js index 04c75041f2..efff299809 100644 --- a/packages/component/src/Middleware/AttachmentForScreenReader/VideoAttachment.js +++ b/packages/component/src/Middleware/AttachmentForScreenReader/VideoAttachment.js @@ -1,3 +1,4 @@ +/* eslint-disable react/forbid-dom-props */ import { hooks } from 'botframework-webchat-api'; import React from 'react'; diff --git a/packages/component/src/Middleware/CardAction/createCoreMiddleware.js b/packages/component/src/Middleware/CardAction/createCoreMiddleware.js index a7f9e561d4..e9054da0b2 100644 --- a/packages/component/src/Middleware/CardAction/createCoreMiddleware.js +++ b/packages/component/src/Middleware/CardAction/createCoreMiddleware.js @@ -61,9 +61,12 @@ export default function createDefaultCardActionMiddleware() { break; case 'signin': { - // TODO: [P3] We should prime the URL into the OAuthCard directly, instead of calling getSessionId on-demand - // This is to eliminate the delay between window.open() and location.href call + /** + * @todo TODO: [P3] We should prime the URL into the OAuthCard directly, instead of calling getSessionId on-demand + * This is to eliminate the delay between window.open() and location.href call + */ + // eslint-disable-next-line wrap-iife (async function () { const popup = window.open(); const url = await getSignInUrl(); diff --git a/packages/component/src/ScreenReaderActivity.js b/packages/component/src/ScreenReaderActivity.js index bfe142b775..2fa9489cd5 100644 --- a/packages/component/src/ScreenReaderActivity.js +++ b/packages/component/src/ScreenReaderActivity.js @@ -82,6 +82,7 @@ const ScreenReaderActivity = ({ activity }) => { {!!attachmentForScreenReaderRenderers.length && ( diff --git a/packages/component/src/hooks/internal/useRegisterScrollToEnd.js b/packages/component/src/hooks/internal/useRegisterScrollToEnd.js index 4033ecf856..91ecbee72a 100644 --- a/packages/component/src/hooks/internal/useRegisterScrollToEnd.js +++ b/packages/component/src/hooks/internal/useRegisterScrollToEnd.js @@ -12,5 +12,5 @@ export default function useRegisterScrollTo(callback) { scrollToEndCallbacks.push(callback); return () => removeInline(scrollToEndCallbacks, callback); - }, [scrollToEndCallbacksRef]); + }, [callback, scrollToEndCallbacksRef]); } diff --git a/packages/core/package.json b/packages/core/package.json index 3f1e59eee2..f05e17acde 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,7 +20,7 @@ "build": "npm run build:typescript && npm run build:babel", "build:babel": "babel src --extensions .js,.ts,.tsx --ignore **/*.spec.js,**/*.spec.ts,**/*.spec.tsx,**/*.test.js,**/*.test.ts,**/*.test.tsx,__tests__/**/*.js,__tests__/**/*.ts,__tests__/**/*.tsx --out-dir lib --verbose", "build:typescript": "tsc --project src/tsconfig.json", - "eslint": "eslint src/**/*.js src/**/*.ts", + "eslint": "eslint src/**/*.js src/**/*.ts --fix", "prestart": "npm run build:babel", "start": "concurrently --kill-others --names \"babel,tsc\" \"npm run start:babel\" \"npm run start:typescript\"", "start:babel": "npm run build:babel -- --skip-initial-build --watch", diff --git a/packages/directlinespeech/package.json b/packages/directlinespeech/package.json index 4c1d37bfed..ec17ca6f05 100644 --- a/packages/directlinespeech/package.json +++ b/packages/directlinespeech/package.json @@ -13,7 +13,7 @@ "build:webpack": "concurrently --names \"dev,prod\" \"npm run build:webpack:development\" \"npm run build:webpack:production\"", "build:webpack:development": "cross-env node_env=development webpack-cli", "build:webpack:production": "cross-env node_env=production webpack-cli", - "eslint": "eslint src/**/*.js", + "eslint": "eslint src/**/*.js --fix", "prestart": "npm run build:babel", "start": "npm run start:babel && concurrently --kill-others --names \"babel,serve,webpack\" \"npm run start:babel:watch\" \"npm run start:serve\" \"npm run start:webpack\"", "start:babel": "npm run build:babel --", diff --git a/packages/directlinespeech/src/createAdapters.js b/packages/directlinespeech/src/createAdapters.js index 129b0bc245..c0fe56753e 100644 --- a/packages/directlinespeech/src/createAdapters.js +++ b/packages/directlinespeech/src/createAdapters.js @@ -79,6 +79,7 @@ export default async function create({ const { privSource: source } = audioConfig; source.createAudioContext = () => { + // eslint-disable-next-line no-extra-boolean-cast if (!!source.privContext) { return; } diff --git a/packages/isomorphic-react-dom/package.json b/packages/isomorphic-react-dom/package.json index a440f95fa6..23db49cdbc 100644 --- a/packages/isomorphic-react-dom/package.json +++ b/packages/isomorphic-react-dom/package.json @@ -8,7 +8,7 @@ "build": "npm run build:babel && npm run build:webpack", "build:babel": "babel src --out-dir lib --verbose", "build:webpack": "webpack-cli", - "eslint": "eslint src/**/*.js", + "eslint": "eslint src/**/*.js --fix", "start": "npm run start:note && npm run start:babel && npm run start:webpack", "start:babel": "npm run build:babel", "start:note": "echo \"isomorphic-react-dom is not under active development; running in non-watch mode.\"", diff --git a/packages/isomorphic-react/package.json b/packages/isomorphic-react/package.json index dd7d9a211f..22020d034b 100644 --- a/packages/isomorphic-react/package.json +++ b/packages/isomorphic-react/package.json @@ -7,7 +7,7 @@ "build": "npm run build:babel && npm run build:webpack", "build:babel": "babel src --out-dir lib --verbose", "build:webpack": "webpack-cli", - "eslint": "eslint src/**/*.js", + "eslint": "eslint src/**/*.js --fix", "start": "npm run start:note && npm run start:babel && npm run start:webpack", "start:babel": "npm run build:babel", "start:note": "echo \"isomorphic-react is not under active development; running in non-watch mode.\"", diff --git a/samples/01.getting-started/i.protocol-direct-line-app-service-extension/README.md b/samples/01.getting-started/i.protocol-direct-line-app-service-extension/README.md index e0a083da31..1ba6e38d22 100644 --- a/samples/01.getting-started/i.protocol-direct-line-app-service-extension/README.md +++ b/samples/01.getting-started/i.protocol-direct-line-app-service-extension/README.md @@ -140,7 +140,7 @@ Check out the hosted samples and source code for other CDN bundle options below. - [Full bundle bot](https://microsoft.github.io/BotFramework-WebChat/01.getting-started/a.full-bundle) | [(Full bundle source code)](https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/01.getting-started/a.full-bundle) - [Full bundle with polyfills for ES5 browsers bot](https://microsoft.github.io/BotFramework-WebChat/01.getting-started/c.es5-bundle) | [(Full bundle with polyfills for ES5 browsers source code)](https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/01.getting-started/c.es5-bundle) - [Direct Line App Service Extension](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-directline-extension?view=azure-bot-service-4.0) -- [Cross-Origin Resource Sharing (CORS)](https://docs.microsoft.com/en-us/learn/modules/set-up-cors-website-storage/) +- [Cross-Origin Resource Sharing (CORS)](https://docs.microsoft.com/en-us/learn/modules/set-up-cors-website-storage/) ## Full list of Web Chat hosted samples