Skip to content

Commit

Permalink
Fixed click handling within all adaptive card inputs.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyanziano committed Jul 17, 2019
1 parent fc36309 commit a190d54
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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(
Expand Down Expand Up @@ -252,6 +252,41 @@ describe('<ChatContainer />', () => {
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(
<Chat
document={{} as any}
mode={'livechat'}
currentUser={null}
locale={'en-US'}
showContextMenuForActivity={() => 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', () => {
Expand Down
20 changes: 18 additions & 2 deletions packages/app/client/src/ui/editor/emulator/parts/chat/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ interface ChatState {
highlightedActivities?: Activity[];
}

const adaptiveCardInputs = {
INPUT: null,
OPTION: null,
SELECT: null,
TEXTAREA: null,
};

export class Chat extends Component<ChatProps, ChatState> {
public state = { waitForSpeechToken: false } as ChatState;
private activityMap: { [activityId: string]: Activity };
Expand Down Expand Up @@ -252,7 +259,7 @@ export class Chat extends Component<ChatProps, ChatState> {
// 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;
Expand All @@ -266,7 +273,7 @@ export class Chat extends Component<ChatProps, ChatState> {
// 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;
Expand All @@ -280,4 +287,13 @@ export class Chat extends Component<ChatProps, ChatState> {
this.updateSelectedActivity(activityId);
this.props.showContextMenuForActivity(activity);
};

private elementIsAnAdaptiveCardInput = (element: HTMLElement): boolean => {
const { tagName = '' } = element;
// adaptive cards embed <p> tags inside of input <labels>
if (element.parentElement && element.parentElement.tagName === 'LABEL') {
return true;
}
return tagName in adaptiveCardInputs;
};
}

0 comments on commit a190d54

Please sign in to comment.