From 90774001db7a4dd95e9fc9ffa9ab9438cf2f2c05 Mon Sep 17 00:00:00 2001 From: Tony Anziano Date: Tue, 16 Jul 2019 12:26:35 -0700 Subject: [PATCH] Fixed click handling within all adaptive card inputs. --- CHANGELOG.md | 1 + .../editor/emulator/parts/chat/chat.spec.tsx | 39 ++++++++++++++++++- .../ui/editor/emulator/parts/chat/chat.tsx | 20 +++++++++- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ded385a4e..fcf9ef150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [client] Fixed some minor styling issues with the JSON inspector in PR [1691](https://github.com/microsoft/BotFramework-Emulator/pull/1691) - [client] Fixed issue where html errors were being displayed incorrectly in PR [1687](https://github.com/microsoft/BotFramework-Emulator/pull/1687/files) - [client] Fixed an issue where webSpeechFactories in store were being set to null in PR [1685](https://github.com/microsoft/BotFramework-Emulator/pull/1685) +- [client] Fixed click handling within all adaptive card inputs (multiline text inputs, input labels, compact choice sets) in PR [1690](https://github.com/microsoft/BotFramework-Emulator/pull/1690) ## v4.5.1 - 2019 - 07 - 13 ## Fixed diff --git a/packages/app/client/src/ui/editor/emulator/parts/chat/chat.spec.tsx b/packages/app/client/src/ui/editor/emulator/parts/chat/chat.spec.tsx index 06470fa01..7fc30e121 100644 --- a/packages/app/client/src/ui/editor/emulator/parts/chat/chat.spec.tsx +++ b/packages/app/client/src/ui/editor/emulator/parts/chat/chat.spec.tsx @@ -32,7 +32,7 @@ // import * as React from 'react'; -import { mount, ReactWrapper } from 'enzyme'; +import { mount, ReactWrapper, shallow } from 'enzyme'; import { Provider } from 'react-redux'; import ReactWebChat, { createDirectLine } from 'botframework-webchat'; import { ActivityTypes } from 'botframework-schema'; @@ -53,7 +53,7 @@ import { import webChatStyleOptions from './webChatTheme'; import { ChatContainer } from './chatContainer'; -import { ChatProps } from './chat'; +import { ChatProps, Chat } from './chat'; jest.mock('electron', () => ({ ipcMain: new Proxy( @@ -252,6 +252,41 @@ describe('', () => { expect(component.find('div').text()).toEqual('Connecting...'); }); }); + + it('should be able to tell when a click within an activity was on an Adaptive Card input', () => { + const wrapper = shallow( + null} + setInspectorObject={() => null} + webchatStore={null} + /> + ); + const instance: any = wrapper.instance(); + const mockElement = { tagName: 'SELECT', parentElement: undefined }; + + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(true); + + mockElement.tagName = 'OPTION'; + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(true); + + mockElement.tagName = 'INPUT'; + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(true); + + mockElement.tagName = 'TEXTAREA'; + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(true); + + mockElement.tagName = 'P'; + mockElement.parentElement = { tagName: 'LABEL' }; + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(true); + + mockElement.parentElement = undefined; + mockElement.tagName = 'SPAN'; + expect(instance.elementIsAnAdaptiveCardInput(mockElement)).toBe(false); + }); }); describe('event handlers', () => { diff --git a/packages/app/client/src/ui/editor/emulator/parts/chat/chat.tsx b/packages/app/client/src/ui/editor/emulator/parts/chat/chat.tsx index 9a0912d41..a155c7631 100644 --- a/packages/app/client/src/ui/editor/emulator/parts/chat/chat.tsx +++ b/packages/app/client/src/ui/editor/emulator/parts/chat/chat.tsx @@ -63,6 +63,13 @@ interface ChatState { highlightedActivities?: Activity[]; } +const adaptiveCardInputs = { + INPUT: null, + OPTION: null, + SELECT: null, + TEXTAREA: null, +}; + export class Chat extends Component { public state = { waitForSpeechToken: false } as ChatState; private activityMap: { [activityId: string]: Activity }; @@ -252,7 +259,7 @@ export class Chat extends Component { // if we click inside of an input within an adaptive card, we want to avoid selecting the activity // because it will cause a Web Chat re-render which will wipe the adaptive card state const { target = { tagName: '' } } = event; - if ((target as HTMLElement).tagName === 'INPUT') { + if (this.elementIsAnAdaptiveCardInput(target as HTMLElement)) { return; } const { activityId } = (event.currentTarget as any).dataset; @@ -266,7 +273,7 @@ export class Chat extends Component { // if we type inside of an input within an adaptive card, we want to avoid selecting the activity // on spacebar because it will cause a Web Chat re-render which will wipe the adaptive card state const { target = { tagName: '' } } = event; - if (event.key === ' ' && (target as HTMLElement).tagName === 'INPUT') { + if (event.key === ' ' && this.elementIsAnAdaptiveCardInput(target as HTMLElement)) { return; } const { activityId } = (event.currentTarget as any).dataset; @@ -280,4 +287,13 @@ export class Chat extends Component { this.updateSelectedActivity(activityId); this.props.showContextMenuForActivity(activity); }; + + private elementIsAnAdaptiveCardInput = (element: HTMLElement): boolean => { + const { tagName = '' } = element; + // adaptive cards embed

tags inside of input + if (element.parentElement && element.parentElement.tagName === 'LABEL') { + return true; + } + return tagName in adaptiveCardInputs; + }; }