From 921cf12efecec4e87848ee2dcfff948f0e7f3980 Mon Sep 17 00:00:00 2001 From: Guillaume Peoc'h Date: Wed, 8 Jun 2022 18:22:55 +0200 Subject: [PATCH] [NO JIRA] Event - Change from KeyboardCodes to KeyboardKeys --- .../nav/component/branch-like/Menu.tsx | 10 ++-- .../branch-like/__tests__/Menu-test.tsx | 10 ++-- .../account/notifications/ProjectModal.tsx | 10 ++-- .../main/js/apps/code/components/Search.tsx | 10 ++-- .../components/Breadcrumbs.tsx | 4 +- .../components/__tests__/Breadcrumbs-test.tsx | 4 +- .../drilldown/FilesView.tsx | 8 ++-- .../drilldown/__tests__/FilesView-test.tsx | 10 ++-- .../js/apps/issues/components/IssuesApp.tsx | 12 ++--- .../components/__tests__/IssuesApp-test.tsx | 34 ++++++------- .../security-hotspots/SecurityHotspotsApp.tsx | 8 ++-- .../__tests__/SecurityHotspotsApp-test.tsx | 10 ++-- .../components/HotspotViewerTabs.tsx | 6 +-- .../__tests__/HotspotViewerTabs-test.tsx | 16 +++---- .../components/assignee/AssigneeSelection.tsx | 10 ++-- .../__tests__/AssigneeSelection-test.tsx | 16 +++---- .../settings/components/SettingsSearch.tsx | 10 ++-- .../__tests__/SettingsSearch-test.tsx | 18 +++---- .../components/inputs/SimpleInput.tsx | 6 +-- .../inputs/__tests__/SimpleInput-test.tsx | 8 ++-- .../main/js/components/common/MultiSelect.tsx | 14 +++--- .../main/js/components/common/SelectList.tsx | 8 ++-- .../common/__tests__/MultiSelect-test.tsx | 14 +++--- .../common/__tests__/SelectList-test.tsx | 12 ++--- .../components/controls/EscKeydownHandler.tsx | 4 +- .../main/js/components/controls/SearchBox.tsx | 4 +- .../__tests__/EscKeydownHandler-test.tsx | 4 +- .../__tests__/withKeyboardNavigation-test.tsx | 48 +++++++++---------- .../components/hoc/withKeyboardNavigation.tsx | 10 ++-- .../components/issue/popups/CommentPopup.tsx | 14 +++--- .../popups/__tests__/CommentPopup-test.tsx | 6 +-- .../sonar-web/src/main/js/helpers/keycodes.ts | 15 ++---- .../src/main/js/helpers/testUtils.ts | 21 ++++---- 33 files changed, 190 insertions(+), 204 deletions(-) diff --git a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/Menu.tsx b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/Menu.tsx index eee007e5998..bbfb7738e85 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/Menu.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/Menu.tsx @@ -28,7 +28,7 @@ import { isPullRequest, isSameBranchLike } from '../../../../../helpers/branch-like'; -import { KeyboardCodes } from '../../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../../helpers/keycodes'; import { translate } from '../../../../../helpers/l10n'; import { getBranchLikeUrl } from '../../../../../helpers/urls'; import { BranchLike, BranchLikeTree } from '../../../../../types/branch-like'; @@ -110,16 +110,16 @@ export class Menu extends React.PureComponent { }; handleKeyDown = (event: React.KeyboardEvent) => { - switch (event.nativeEvent.code) { - case KeyboardCodes.Enter: + switch (event.nativeEvent.key) { + case KeyboardKeys.Enter: event.preventDefault(); this.openHighlightedBranchLike(); break; - case KeyboardCodes.UpArrow: + case KeyboardKeys.UpArrow: event.preventDefault(); this.highlightSiblingBranchlike(-1); break; - case KeyboardCodes.DownArrow: + case KeyboardKeys.DownArrow: event.preventDefault(); this.highlightSiblingBranchlike(+1); break; diff --git a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/Menu-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/Menu-test.tsx index 91a78560011..261de2df20e 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/Menu-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/Menu-test.tsx @@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { Link } from 'react-router'; import SearchBox from '../../../../../../components/controls/SearchBox'; -import { KeyboardCodes } from '../../../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../../../helpers/keycodes'; import { mockPullRequest, mockSetOfBranchAndPullRequest @@ -93,14 +93,14 @@ it('should handle keyboard shortcut correctly', () => { const { onKeyDown } = wrapper.find(SearchBox).props(); - onKeyDown!(mockEvent({ nativeEvent: { code: KeyboardCodes.UpArrow } })); + onKeyDown!(mockEvent({ nativeEvent: { key: KeyboardKeys.UpArrow } })); expect(wrapper.state().selectedBranchLike).toBe(branchLikes[3]); - onKeyDown!(mockEvent({ nativeEvent: { code: KeyboardCodes.DownArrow } })); - onKeyDown!(mockEvent({ nativeEvent: { code: KeyboardCodes.DownArrow } })); + onKeyDown!(mockEvent({ nativeEvent: { key: KeyboardKeys.DownArrow } })); + onKeyDown!(mockEvent({ nativeEvent: { key: KeyboardKeys.DownArrow } })); expect(wrapper.state().selectedBranchLike).toBe(branchLikes[0]); - onKeyDown!(mockEvent({ nativeEvent: { code: KeyboardCodes.Enter } })); + onKeyDown!(mockEvent({ nativeEvent: { key: KeyboardKeys.Enter } })); expect(push).toHaveBeenCalled(); }); diff --git a/server/sonar-web/src/main/js/apps/account/notifications/ProjectModal.tsx b/server/sonar-web/src/main/js/apps/account/notifications/ProjectModal.tsx index 3d74aeea294..98a57c6e893 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/ProjectModal.tsx +++ b/server/sonar-web/src/main/js/apps/account/notifications/ProjectModal.tsx @@ -25,7 +25,7 @@ import { ResetButtonLink, SubmitButton } from '../../../components/controls/butt import { DropdownOverlay } from '../../../components/controls/Dropdown'; import SearchBox from '../../../components/controls/SearchBox'; import SimpleModal from '../../../components/controls/SimpleModal'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; import { NotificationProject } from '../../../types/notifications'; @@ -63,16 +63,16 @@ export default class ProjectModal extends React.PureComponent { } handleKeyDown = (event: React.KeyboardEvent) => { - switch (event.nativeEvent.code) { - case KeyboardCodes.Enter: + switch (event.nativeEvent.key) { + case KeyboardKeys.Enter: event.preventDefault(); this.handleSelectHighlighted(); break; - case KeyboardCodes.UpArrow: + case KeyboardKeys.UpArrow: event.preventDefault(); this.handleHighlightPrevious(); break; - case KeyboardCodes.DownArrow: + case KeyboardKeys.DownArrow: event.preventDefault(); this.handleHighlightNext(); break; diff --git a/server/sonar-web/src/main/js/apps/code/components/Search.tsx b/server/sonar-web/src/main/js/apps/code/components/Search.tsx index 31a78e9b2e5..f896094ac1e 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Search.tsx +++ b/server/sonar-web/src/main/js/apps/code/components/Search.tsx @@ -24,7 +24,7 @@ import SearchBox from '../../../components/controls/SearchBox'; import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; import DeferredSpinner from '../../../components/ui/DeferredSpinner'; import { getBranchLikeQuery } from '../../../helpers/branch-like'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; import { BranchLike } from '../../../types/branch-like'; import { ComponentMeasure } from '../../../types/types'; @@ -76,10 +76,10 @@ export class Search extends React.PureComponent { } handleKeyDown = (event: React.KeyboardEvent) => { - switch (event.nativeEvent.code) { - case KeyboardCodes.Enter: - case KeyboardCodes.UpArrow: - case KeyboardCodes.DownArrow: + switch (event.nativeEvent.key) { + case KeyboardKeys.Enter: + case KeyboardKeys.UpArrow: + case KeyboardKeys.DownArrow: event.preventDefault(); event.currentTarget.blur(); break; diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/Breadcrumbs.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/Breadcrumbs.tsx index 9fd2ddcbf7a..510c721f40d 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/Breadcrumbs.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/Breadcrumbs.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { getBreadcrumbs } from '../../../api/components'; import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { BranchLike } from '../../../types/branch-like'; import { ComponentMeasure, ComponentMeasureIntern } from '../../../types/types'; import Breadcrumb from './Breadcrumb'; @@ -63,7 +63,7 @@ export default class Breadcrumbs extends React.PureComponent { } handleKeyDown = (event: KeyboardEvent) => { - if (event.code === KeyboardCodes.LeftArrow) { + if (event.key === KeyboardKeys.LeftArrow) { event.preventDefault(); const { breadcrumbs } = this.state; if (breadcrumbs.length > 1) { diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/Breadcrumbs-test.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/Breadcrumbs-test.tsx index 0a5167a2723..9da19435ad3 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/Breadcrumbs-test.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/Breadcrumbs-test.tsx @@ -20,7 +20,7 @@ import { mount, shallow } from 'enzyme'; import * as React from 'react'; import { getBreadcrumbs } from '../../../../api/components'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { keydown, waitAndUpdate } from '../../../../helpers/testUtils'; import Breadcrumbs from '../Breadcrumbs'; @@ -75,7 +75,7 @@ it('should correctly handle keyboard action', async () => { const handleSelect = jest.fn(); const wrapper = shallowRender({ handleSelect }); await waitAndUpdate(wrapper); - keydown({ code: KeyboardCodes.LeftArrow }); + keydown({ key: KeyboardKeys.LeftArrow }); expect(handleSelect).toHaveBeenCalled(); }); diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx index a9a0eadb745..c35f5500921 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx @@ -23,7 +23,7 @@ import { Button } from '../../../components/controls/buttons'; import ListFooter from '../../../components/controls/ListFooter'; import { Alert } from '../../../components/ui/Alert'; import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { formatMeasure, isDiffMetric, isPeriodBestValue } from '../../../helpers/measures'; import { scrollToElement } from '../../../helpers/scrolling'; @@ -96,13 +96,13 @@ export default class FilesView extends React.PureComponent { if (isInput(event) || isShortcut(event)) { return true; } - if (event.code === KeyboardCodes.UpArrow) { + if (event.key === KeyboardKeys.UpArrow) { event.preventDefault(); this.selectPrevious(); - } else if (event.code === KeyboardCodes.DownArrow) { + } else if (event.key === KeyboardKeys.DownArrow) { event.preventDefault(); this.selectNext(); - } else if (event.code === KeyboardCodes.RightArrow) { + } else if (event.key === KeyboardKeys.RightArrow) { event.preventDefault(); this.openSelected(); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/__tests__/FilesView-test.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/__tests__/FilesView-test.tsx index 5d4b6754548..1d10df5fa23 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/__tests__/FilesView-test.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/__tests__/FilesView-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { mockMetric } from '../../../../helpers/testMocks'; import { keydown } from '../../../../helpers/testUtils'; import FilesView from '../FilesView'; @@ -86,16 +86,16 @@ it('should correctly bind key events for file navigation', () => { components: FILES }); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(handleSelect).toBeCalledWith(FILES[0]); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(handleSelect).toBeCalledWith(FILES[2]); - keydown({ code: KeyboardCodes.RightArrow, ctrlKey: true }); + keydown({ key: KeyboardKeys.RightArrow, ctrlKey: true }); expect(handleOpen).not.toBeCalled(); - keydown({ code: KeyboardCodes.RightArrow }); + keydown({ key: KeyboardKeys.RightArrow }); expect(handleOpen).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx index b5f8d364f32..34f4dd92f3c 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx @@ -47,7 +47,7 @@ import { import handleRequiredAuthentication from '../../../helpers/handleRequiredAuthentication'; import { parseIssueFromResponse } from '../../../helpers/issues'; import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers'; -import { KeyboardCodes, KeyboardKeys } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { addSideBarClass, @@ -274,8 +274,8 @@ export default class App extends React.PureComponent { return; } - switch (event.code) { - case KeyboardCodes.DownArrow: { + switch (event.key) { + case KeyboardKeys.DownArrow: { event.preventDefault(); if (event.altKey) { this.selectNextLocation(); @@ -284,7 +284,7 @@ export default class App extends React.PureComponent { } break; } - case KeyboardCodes.UpArrow: { + case KeyboardKeys.UpArrow: { event.preventDefault(); if (event.altKey) { this.selectPreviousLocation(); @@ -293,7 +293,7 @@ export default class App extends React.PureComponent { } break; } - case KeyboardCodes.LeftArrow: { + case KeyboardKeys.LeftArrow: { event.preventDefault(); if (event.altKey) { this.selectPreviousFlow(); @@ -302,7 +302,7 @@ export default class App extends React.PureComponent { } break; } - case KeyboardCodes.RightArrow: { + case KeyboardKeys.RightArrow: { event.preventDefault(); if (event.altKey) { this.selectNextFlow(); diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesApp-test.tsx b/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesApp-test.tsx index 952aeb5d9b7..6b69a551563 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesApp-test.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesApp-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import { searchIssues } from '../../../../api/issues'; import { getRuleDetails } from '../../../../api/rules'; import handleRequiredAuthentication from '../../../../helpers/handleRequiredAuthentication'; -import { KeyboardCodes, KeyboardKeys } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; import { mockComponent } from '../../../../helpers/mocks/component'; import { @@ -226,27 +226,27 @@ it('should correctly bind key events for issue navigation', async () => { expect(wrapper.state('selected')).toBe(ISSUES[0].key); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(wrapper.state('selected')).toBe(ISSUES[1].key); - keydown({ code: KeyboardCodes.UpArrow }); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(wrapper.state('selected')).toBe(ISSUES[0].key); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(wrapper.state('selected')).toBe(ISSUES[3].key); - keydown({ code: KeyboardCodes.RightArrow, ctrlKey: true }); + keydown({ key: KeyboardKeys.RightArrow, ctrlKey: true }); expect(push).not.toBeCalled(); - keydown({ code: KeyboardCodes.RightArrow }); + keydown({ key: KeyboardKeys.RightArrow }); expect(push).toBeCalledTimes(1); - keydown({ code: KeyboardCodes.LeftArrow }); + keydown({ key: KeyboardKeys.LeftArrow }); expect(push).toBeCalledTimes(2); addEventListenerSpy.mockReset(); @@ -433,19 +433,19 @@ describe('keydown event handler', () => { expect(instance.setState).toHaveBeenCalledWith(enableLocationsNavigator); }); it('should handle alt+↓', () => { - instance.handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.DownArrow })); + instance.handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.DownArrow })); expect(instance.setState).toHaveBeenCalledWith(selectNextLocation); }); it('should handle alt+↑', () => { - instance.handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.UpArrow })); + instance.handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.UpArrow })); expect(instance.setState).toHaveBeenCalledWith(selectPreviousLocation); }); it('should handle alt+←', () => { - instance.handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.LeftArrow })); + instance.handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.LeftArrow })); expect(instance.setState).toHaveBeenCalledWith(selectPreviousFlow); }); it('should handle alt+→', () => { - instance.handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.RightArrow })); + instance.handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.RightArrow })); expect(instance.setState).toHaveBeenCalledWith(selectNextFlow); }); it('should ignore if modal is open', () => { diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx index 164fa8ba9cc..fce568a6aed 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx @@ -27,7 +27,7 @@ import withCurrentUserContext from '../../app/components/current-user/withCurren import { Router } from '../../components/hoc/withRouter'; import { getLeakValue } from '../../components/measure/utils'; import { getBranchLikeQuery, isPullRequest, isSameBranchLike } from '../../helpers/branch-like'; -import { KeyboardCodes, KeyboardKeys } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; import { scrollToElement } from '../../helpers/scrolling'; import { getStandards } from '../../helpers/security-standard'; import { BranchLike } from '../../types/branch-like'; @@ -150,8 +150,8 @@ export class SecurityHotspotsApp extends React.PureComponent { return; } - switch (event.code) { - case KeyboardCodes.DownArrow: { + switch (event.key) { + case KeyboardKeys.DownArrow: { event.preventDefault(); if (event.altKey) { this.selectNextLocation(); @@ -160,7 +160,7 @@ export class SecurityHotspotsApp extends React.PureComponent { } break; } - case KeyboardCodes.UpArrow: { + case KeyboardKeys.UpArrow: { event.preventDefault(); if (event.altKey) { this.selectPreviousLocation(); diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx index d2442f4d8e6..5f1904aaa30 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx @@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { getMeasures } from '../../../api/measures'; import { getSecurityHotspotList, getSecurityHotspots } from '../../../api/security-hotspots'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { mockBranch, mockPullRequest } from '../../../helpers/mocks/branch-like'; import { mockComponent } from '../../../helpers/mocks/component'; import { mockHtmlElement } from '../../../helpers/mocks/dom'; @@ -465,7 +465,7 @@ describe('keyboard navigation', () => { ['selecting next locations, non-existent', 2, undefined] ])('should work when %s', (_, start, expected) => { wrapper.setState({ selectedHotspotLocationIndex: start, selectedHotspot: hotspotsForLocation }); - wrapper.instance().handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.DownArrow })); + wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.DownArrow })); expect(wrapper.state().selectedHotspotLocationIndex).toBe(expected); }); @@ -476,7 +476,7 @@ describe('keyboard navigation', () => { ['selecting previous locations, non-existent', 0, undefined] ])('should work when %s', (_, start, expected) => { wrapper.setState({ selectedHotspotLocationIndex: start, selectedHotspot: hotspotsForLocation }); - wrapper.instance().handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.UpArrow })); + wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.UpArrow })); expect(wrapper.state().selectedHotspotLocationIndex).toBe(expected); }); @@ -484,10 +484,10 @@ describe('keyboard navigation', () => { it('should not change location index when locations are empty', () => { wrapper.setState({ selectedHotspotLocationIndex: undefined, selectedHotspot: hotspots[0] }); - wrapper.instance().handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.UpArrow })); + wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.UpArrow })); expect(wrapper.state().selectedHotspotLocationIndex).toBeUndefined(); - wrapper.instance().handleKeyDown(mockEvent({ altKey: true, code: KeyboardCodes.DownArrow })); + wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.DownArrow })); expect(wrapper.state().selectedHotspotLocationIndex).toBeUndefined(); }); }); diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx index 100a42eb9de..dfb2a477ec2 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx @@ -21,7 +21,7 @@ import classNames from 'classnames'; import * as React from 'react'; import BoxedTabs from '../../../components/controls/BoxedTabs'; import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; import { sanitizeString } from '../../../helpers/sanitize'; import { Hotspot } from '../../../types/security-hotspots'; @@ -90,10 +90,10 @@ export default class HotspotViewerTabs extends React.PureComponent if (isInput(event) || isShortcut(event)) { return true; } - if (event.code === KeyboardCodes.LeftArrow) { + if (event.key === KeyboardKeys.LeftArrow) { event.preventDefault(); this.selectNeighboringTab(-1); - } else if (event.code === KeyboardCodes.RightArrow) { + } else if (event.key === KeyboardKeys.RightArrow) { event.preventDefault(); this.selectNeighboringTab(+1); } diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx index db529dd1645..12033dedd99 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx @@ -20,7 +20,7 @@ import { mount, shallow } from 'enzyme'; import * as React from 'react'; import BoxedTabs, { BoxedTabsProps } from '../../../../components/controls/BoxedTabs'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { mockHotspot, mockHotspotRule } from '../../../../helpers/mocks/security-hotspots'; import { mockEvent, mockUser } from '../../../../helpers/testMocks'; import HotspotViewerTabs, { TabKeys } from '../HotspotViewerTabs'; @@ -145,13 +145,13 @@ describe('keyboard navigation', () => { const wrapper = shallowRender(); it.each([ - ['selecting next', 0, KeyboardCodes.RightArrow, 1], - ['selecting previous', 1, KeyboardCodes.LeftArrow, 0], - ['selecting previous, non-existent', 0, KeyboardCodes.LeftArrow, 0], - ['selecting next, non-existent', 3, KeyboardCodes.RightArrow, 3] - ])('should work when %s', (_, start, code, expected) => { + ['selecting next', 0, KeyboardKeys.RightArrow, 1], + ['selecting previous', 1, KeyboardKeys.LeftArrow, 0], + ['selecting previous, non-existent', 0, KeyboardKeys.LeftArrow, 0], + ['selecting next, non-existent', 3, KeyboardKeys.RightArrow, 3] + ])('should work when %s', (_, start, key, expected) => { wrapper.setState({ currentTab: wrapper.state().tabs[start] }); - wrapper.instance().handleKeyboardNavigation(mockEvent({ code })); + wrapper.instance().handleKeyboardNavigation(mockEvent({ key })); expect(wrapper.state().currentTab.key).toBe(tabList[expected]); }); @@ -165,7 +165,7 @@ it("shouldn't navigate when ctrl or command are pressed with up and down", () => wrapper.setState({ currentTab: wrapper.state().tabs[0] }); wrapper .instance() - .handleKeyboardNavigation(mockEvent({ code: KeyboardCodes.LeftArrow, metaKey: true })); + .handleKeyboardNavigation(mockEvent({ key: KeyboardKeys.LeftArrow, metaKey: true })); expect(wrapper.state().currentTab.key).toBe(TabKeys.Code); }); diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx index 70058208c50..5d08d591408 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx @@ -20,7 +20,7 @@ import { debounce } from 'lodash'; import * as React from 'react'; import { searchUsers } from '../../../../api/users'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { translate } from '../../../../helpers/l10n'; import { isUserActive, LoggedInUser, UserActive } from '../../../../types/users'; import AssigneeSelectionRenderer from './AssigneeSelectionRenderer'; @@ -104,16 +104,16 @@ export default class AssigneeSelection extends React.PureComponent }; handleKeyDown = (event: React.KeyboardEvent) => { - switch (event.nativeEvent.code) { - case KeyboardCodes.Enter: + switch (event.nativeEvent.key) { + case KeyboardKeys.Enter: event.preventDefault(); this.selectHighlighted(); break; - case KeyboardCodes.UpArrow: + case KeyboardKeys.UpArrow: event.preventDefault(); this.highlightPrevious(); break; - case KeyboardCodes.DownArrow: + case KeyboardKeys.DownArrow: event.preventDefault(); this.highlightNext(); break; diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx index 0e59e23a6e2..e7dcd4c7238 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx @@ -20,7 +20,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { searchUsers } from '../../../../../api/users'; -import { KeyboardCodes } from '../../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../../helpers/keycodes'; import { mockLoggedInUser, mockUser } from '../../../../../helpers/testMocks'; import { waitAndUpdate } from '../../../../../helpers/testUtils'; import { UserActive } from '../../../../../types/users'; @@ -35,7 +35,7 @@ it('should render correctly', () => { }); it('should handle keydown', () => { - const mockEvent = (code: KeyboardCodes) => ({ preventDefault: jest.fn(), nativeEvent: { code } }); + const mockEvent = (key: KeyboardKeys) => ({ preventDefault: jest.fn(), nativeEvent: { key } }); const suggestedUsers = [ mockUser({ login: '1' }) as UserActive, mockUser({ login: '2' }) as UserActive, @@ -45,29 +45,29 @@ it('should handle keydown', () => { const onSelect = jest.fn(); const wrapper = shallowRender({ onSelect }); - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.UpArrow) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.UpArrow) as any); expect(wrapper.state().highlighted).toEqual({ login: '', name: 'unassigned' }); wrapper.setState({ suggestedUsers }); // press down to highlight the first - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.DownArrow) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.DownArrow) as any); expect(wrapper.state().highlighted).toBe(suggestedUsers[0]); // press up to loop around to last - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.UpArrow) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.UpArrow) as any); expect(wrapper.state().highlighted).toBe(suggestedUsers[2]); // press down to loop around to first - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.DownArrow) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.DownArrow) as any); expect(wrapper.state().highlighted).toBe(suggestedUsers[0]); // press down highlight the next - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.DownArrow) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.DownArrow) as any); expect(wrapper.state().highlighted).toBe(suggestedUsers[1]); // press enter to select the highlighted user - wrapper.instance().handleKeyDown(mockEvent(KeyboardCodes.Enter) as any); + wrapper.instance().handleKeyDown(mockEvent(KeyboardKeys.Enter) as any); expect(onSelect).toBeCalledWith(suggestedUsers[1]); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx b/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx index 92460003ab9..b78a17052e3 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/SettingsSearch.tsx @@ -22,7 +22,7 @@ import lunr, { LunrIndex } from 'lunr'; import * as React from 'react'; import { InjectedRouter } from 'react-router'; import { withRouter } from '../../../components/hoc/withRouter'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { ExtendedSettingDefinition } from '../../../types/settings'; import { Component, Dict } from '../../../types/types'; import { @@ -124,16 +124,16 @@ export class SettingsSearch extends React.Component { }; handleKeyDown = (event: React.KeyboardEvent) => { - switch (event.nativeEvent.code) { - case KeyboardCodes.Enter: + switch (event.nativeEvent.key) { + case KeyboardKeys.Enter: event.preventDefault(); this.openSelected(); return; - case KeyboardCodes.UpArrow: + case KeyboardKeys.UpArrow: event.preventDefault(); this.selectPrevious(); return; - case KeyboardCodes.DownArrow: + case KeyboardKeys.DownArrow: event.preventDefault(); this.selectNext(); // keep this return to prevent fall-through in case more cases will be adder later diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx index 16b39b9711f..5cc275bc881 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/SettingsSearch-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { mockComponent } from '../../../../helpers/mocks/component'; import { mockDefinition } from '../../../../helpers/mocks/settings'; import { mockRouter } from '../../../../helpers/testMocks'; @@ -98,11 +98,11 @@ describe('instance', () => { it('should handle "enter" keyboard event', () => { wrapper.setState({ selectedResult: undefined }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.Enter } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.Enter } })); expect(router.push).not.toBeCalled(); wrapper.setState({ selectedResult: 'foo' }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.Enter } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.Enter } })); expect(router.push).toBeCalledWith({ hash: '#foo', @@ -113,27 +113,27 @@ describe('instance', () => { it('should handle "down" keyboard event', () => { wrapper.setState({ selectedResult: undefined }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.DownArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.DownArrow } })); expect(wrapper.state().selectedResult).toBeUndefined(); wrapper.setState({ selectedResult: 'foo' }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.DownArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.DownArrow } })); expect(wrapper.state().selectedResult).toBe('sonar.new_code_period'); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.DownArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.DownArrow } })); expect(wrapper.state().selectedResult).toBe('sonar.new_code_period'); }); it('should handle "up" keyboard event', () => { wrapper.setState({ selectedResult: undefined }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.UpArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.UpArrow } })); expect(wrapper.state().selectedResult).toBeUndefined(); wrapper.setState({ selectedResult: 'sonar.new_code_period' }); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.UpArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.UpArrow } })); expect(wrapper.state().selectedResult).toBe('foo'); - wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.UpArrow } })); + wrapper.instance().handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.UpArrow } })); expect(wrapper.state().selectedResult).toBe('foo'); }); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.tsx index 110972e4864..3eaf9aa2e99 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.tsx @@ -19,7 +19,7 @@ */ import classNames from 'classnames'; import * as React from 'react'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { DefaultSpecializedInputProps } from '../../utils'; export interface SimpleInputProps extends DefaultSpecializedInputProps { @@ -32,9 +32,9 @@ export default class SimpleInput extends React.PureComponent { }; handleKeyDown = (event: React.KeyboardEvent) => { - if (event.nativeEvent.code === KeyboardCodes.Enter && this.props.onSave) { + if (event.nativeEvent.key === KeyboardKeys.Enter && this.props.onSave) { this.props.onSave(); - } else if (event.nativeEvent.code === KeyboardCodes.Escape && this.props.onCancel) { + } else if (event.nativeEvent.key === KeyboardKeys.Escape && this.props.onCancel) { this.props.onCancel(); } }; diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.tsx index 831827746d4..010c32668c0 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../../helpers/keycodes'; import { mockSetting } from '../../../../../helpers/mocks/settings'; import { mockEvent } from '../../../../../helpers/testMocks'; import { change } from '../../../../../helpers/testUtils'; @@ -49,7 +49,7 @@ it('should handle enter', () => { const onSave = jest.fn(); shallowRender({ onSave }) .instance() - .handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.Enter } })); + .handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.Enter } })); expect(onSave).toBeCalled(); }); @@ -57,7 +57,7 @@ it('should handle esc', () => { const onCancel = jest.fn(); shallowRender({ onCancel }) .instance() - .handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.Escape } })); + .handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.Escape } })); expect(onCancel).toBeCalled(); }); @@ -66,7 +66,7 @@ it('should ignore other keys', () => { const onCancel = jest.fn(); shallowRender({ onCancel, onSave }) .instance() - .handleKeyDown(mockEvent({ nativeEvent: { code: KeyboardCodes.LeftArrow } })); + .handleKeyDown(mockEvent({ nativeEvent: { key: KeyboardKeys.LeftArrow } })); expect(onSave).not.toBeCalled(); expect(onCancel).not.toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/components/common/MultiSelect.tsx b/server/sonar-web/src/main/js/components/common/MultiSelect.tsx index b042c9b196d..942721bf728 100644 --- a/server/sonar-web/src/main/js/components/common/MultiSelect.tsx +++ b/server/sonar-web/src/main/js/components/common/MultiSelect.tsx @@ -22,7 +22,7 @@ import { difference } from 'lodash'; import * as React from 'react'; import SearchBox from '../../components/controls/SearchBox'; import { isShortcut } from '../../helpers/keyboardEventHelpers'; -import { KeyboardCodes } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; import { translateWithParameters } from '../../helpers/l10n'; import MultiSelectOption from './MultiSelectOption'; @@ -143,22 +143,22 @@ export default class MultiSelect extends React.PureComponent= 0) { this.toggleSelect(this.getAllElements(this.props, this.state)[this.state.activeIdx]); } diff --git a/server/sonar-web/src/main/js/components/common/SelectList.tsx b/server/sonar-web/src/main/js/components/common/SelectList.tsx index 9b25a4b6f08..16f93925d42 100644 --- a/server/sonar-web/src/main/js/components/common/SelectList.tsx +++ b/server/sonar-web/src/main/js/components/common/SelectList.tsx @@ -19,7 +19,7 @@ */ import classNames from 'classnames'; import * as React from 'react'; -import { KeyboardCodes } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; import SelectListItem from './SelectListItem'; interface Props { @@ -59,15 +59,15 @@ export default class SelectList extends React.PureComponent { } handleKeyDown = (event: KeyboardEvent) => { - if (event.code === KeyboardCodes.DownArrow) { + if (event.key === KeyboardKeys.DownArrow) { event.preventDefault(); event.stopImmediatePropagation(); this.setState(this.selectNextElement); - } else if (event.code === KeyboardCodes.UpArrow) { + } else if (event.key === KeyboardKeys.UpArrow) { event.preventDefault(); event.stopImmediatePropagation(); this.setState(this.selectPreviousElement); - } else if (event.code === KeyboardCodes.Enter) { + } else if (event.key === KeyboardKeys.Enter) { event.preventDefault(); event.stopImmediatePropagation(); if (this.state.active != null) { diff --git a/server/sonar-web/src/main/js/components/common/__tests__/MultiSelect-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/MultiSelect-test.tsx index b34fd2d3053..a963bdf5449 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/MultiSelect-test.tsx +++ b/server/sonar-web/src/main/js/components/common/__tests__/MultiSelect-test.tsx @@ -19,7 +19,7 @@ */ import { mount, shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { mockEvent } from '../../../helpers/testUtils'; import MultiSelect, { MultiSelectProps } from '../MultiSelect'; @@ -63,15 +63,15 @@ it('should render with the focus inside the search input', () => { }); it.each([ - [KeyboardCodes.DownArrow, 1, 1], - [KeyboardCodes.UpArrow, 1, 1], - [KeyboardCodes.LeftArrow, 1, 0] -])('should handle keyboard event: %s', (code, stopPropagationCalls, preventDefaultCalls) => { + [KeyboardKeys.DownArrow, 1, 1], + [KeyboardKeys.UpArrow, 1, 1], + [KeyboardKeys.LeftArrow, 1, 0] +])('should handle keyboard event: %s', (key, stopPropagationCalls, preventDefaultCalls) => { const wrapper = shallowRender(); const stopPropagation = jest.fn(); const preventDefault = jest.fn(); - const event = mockEvent({ preventDefault, stopPropagation, code }); + const event = mockEvent({ preventDefault, stopPropagation, key }); wrapper.instance().handleKeyboard(event); @@ -84,7 +84,7 @@ it('should handle keyboard event: enter', () => { wrapper.instance().toggleSelect = jest.fn(); - wrapper.instance().handleKeyboard(mockEvent({ code: KeyboardCodes.Enter })); + wrapper.instance().handleKeyboard(mockEvent({ key: KeyboardKeys.Enter })); expect(wrapper.instance().toggleSelect).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx index cc6caf4c1ed..3fee816dd25 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx +++ b/server/sonar-web/src/main/js/components/common/__tests__/SelectList-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { keydown } from '../../../helpers/testUtils'; import SelectList from '../SelectList'; import SelectListItem from '../SelectListItem'; @@ -54,15 +54,15 @@ it('should correclty handle user actions', () => { )); const list = shallowRender({ items, onSelect }, children); expect(list.state().active).toBe('seconditem'); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(list.state().active).toBe('third'); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(list.state().active).toBe('item'); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(list.state().active).toBe('third'); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(list.state().active).toBe('seconditem'); - keydown({ code: KeyboardCodes.Enter }); + keydown({ key: KeyboardKeys.Enter }); expect(onSelect).toBeCalledWith('seconditem'); list.instance().componentWillUnmount!(); }); diff --git a/server/sonar-web/src/main/js/components/controls/EscKeydownHandler.tsx b/server/sonar-web/src/main/js/components/controls/EscKeydownHandler.tsx index be07168eaeb..130985cd48d 100644 --- a/server/sonar-web/src/main/js/components/controls/EscKeydownHandler.tsx +++ b/server/sonar-web/src/main/js/components/controls/EscKeydownHandler.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { KeyboardCodes } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; interface Props { children: React.ReactNode; @@ -37,7 +37,7 @@ export default class EscKeydownHandler extends React.Component { } handleKeyDown = (event: KeyboardEvent) => { - if (event.code === KeyboardCodes.Escape) { + if (event.key === KeyboardKeys.Escape) { this.props.onKeydown(); } }; diff --git a/server/sonar-web/src/main/js/components/controls/SearchBox.tsx b/server/sonar-web/src/main/js/components/controls/SearchBox.tsx index a40879e76e3..a37029ef26c 100644 --- a/server/sonar-web/src/main/js/components/controls/SearchBox.tsx +++ b/server/sonar-web/src/main/js/components/controls/SearchBox.tsx @@ -20,7 +20,7 @@ import classNames from 'classnames'; import { Cancelable, debounce } from 'lodash'; import * as React from 'react'; -import { KeyboardCodes } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; import { translate, translateWithParameters } from '../../helpers/l10n'; import SearchIcon from '../icons/SearchIcon'; import DeferredSpinner from '../ui/DeferredSpinner'; @@ -95,7 +95,7 @@ export default class SearchBox extends React.PureComponent { }; handleInputKeyDown = (event: React.KeyboardEvent) => { - if (event.nativeEvent.code === KeyboardCodes.Escape) { + if (event.nativeEvent.key === KeyboardKeys.Escape) { event.preventDefault(); this.handleResetClick(); } diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/EscKeydownHandler-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/EscKeydownHandler-test.tsx index dc773cb476b..c132782d0d4 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/EscKeydownHandler-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/EscKeydownHandler-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { keydown } from '../../../helpers/testUtils'; import EscKeydownHandler from '../EscKeydownHandler'; @@ -40,7 +40,7 @@ it('should correctly trigger the keydown handler when hitting Esc', () => { const onKeydown = jest.fn(); shallowRender({ onKeydown }); jest.runAllTimers(); - keydown({ code: KeyboardCodes.Escape }); + keydown({ key: KeyboardKeys.Escape }); expect(onKeydown).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/components/hoc/__tests__/withKeyboardNavigation-test.tsx b/server/sonar-web/src/main/js/components/hoc/__tests__/withKeyboardNavigation-test.tsx index 4ee53ee75b2..4655585f85f 100644 --- a/server/sonar-web/src/main/js/components/hoc/__tests__/withKeyboardNavigation-test.tsx +++ b/server/sonar-web/src/main/js/components/hoc/__tests__/withKeyboardNavigation-test.tsx @@ -19,7 +19,7 @@ */ import { mount, shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { mockComponent } from '../../../helpers/mocks/component'; import { keydown } from '../../../helpers/testUtils'; import { ComponentMeasure } from '../../../types/types'; @@ -64,32 +64,32 @@ it('should correctly bind key events for component navigation', () => { }) ); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[2]); expect(onSelect).not.toBeCalled(); - keydown({ code: KeyboardCodes.UpArrow }); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[0]); expect(onSelect).not.toBeCalled(); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[2]); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[0]); - keydown({ code: KeyboardCodes.RightArrow, metaKey: true }); + keydown({ key: KeyboardKeys.RightArrow, metaKey: true }); expect(onSelect).not.toBeCalled(); - keydown({ code: KeyboardCodes.RightArrow }); + keydown({ key: KeyboardKeys.RightArrow }); expect(onSelect).toBeCalledWith(COMPONENTS[0]); - keydown({ code: KeyboardCodes.Enter }); + keydown({ key: KeyboardKeys.Enter }); expect(onSelect).toBeCalledWith(COMPONENTS[0]); - keydown({ code: KeyboardCodes.LeftArrow, metaKey: true }); + keydown({ key: KeyboardKeys.LeftArrow, metaKey: true }); expect(onGoToParent).not.toBeCalled(); - keydown({ code: KeyboardCodes.LeftArrow }); + keydown({ key: KeyboardKeys.LeftArrow }); expect(onGoToParent).toBeCalled(); }); @@ -106,18 +106,18 @@ it('should support not cycling through elements, and triggering a callback on re }) ); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[0]); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[2]); expect(onEndOfList).toBeCalled(); - keydown({ code: KeyboardCodes.UpArrow }); - keydown({ code: KeyboardCodes.UpArrow }); - keydown({ code: KeyboardCodes.UpArrow }); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(onHighlight).toBeCalledWith(COMPONENTS[0]); }); @@ -138,19 +138,19 @@ it('should correctly bind key events for codeview navigation', () => { expect(onHighlight).not.toBeCalled(); - keydown({ code: KeyboardCodes.DownArrow }); + keydown({ key: KeyboardKeys.DownArrow }); expect(onHighlight).not.toBeCalled(); - keydown({ code: KeyboardCodes.UpArrow }); + keydown({ key: KeyboardKeys.UpArrow }); expect(onHighlight).not.toBeCalled(); - keydown({ code: KeyboardCodes.RightArrow }); + keydown({ key: KeyboardKeys.RightArrow }); expect(onSelect).not.toBeCalled(); - keydown({ code: KeyboardCodes.Enter }); + keydown({ key: KeyboardKeys.Enter }); expect(onSelect).not.toBeCalled(); - keydown({ code: KeyboardCodes.LeftArrow }); + keydown({ key: KeyboardKeys.LeftArrow }); expect(onGoToParent).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/components/hoc/withKeyboardNavigation.tsx b/server/sonar-web/src/main/js/components/hoc/withKeyboardNavigation.tsx index 4232c27bc57..e69e696c266 100644 --- a/server/sonar-web/src/main/js/components/hoc/withKeyboardNavigation.tsx +++ b/server/sonar-web/src/main/js/components/hoc/withKeyboardNavigation.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import PageActions from '../../components/ui/PageActions'; import { getComponentMeasureUniqueKey } from '../../helpers/component'; import { isInput, isShortcut } from '../../helpers/keyboardEventHelpers'; -import { KeyboardCodes } from '../../helpers/keycodes'; +import { KeyboardKeys } from '../../helpers/keycodes'; import { ComponentMeasure } from '../../types/types'; import { getWrappedDisplayName } from './utils'; @@ -54,16 +54,16 @@ export default function withKeyboardNavigation

( if (isInput(event) || isShortcut(event)) { return true; } - if (event.code === KeyboardCodes.UpArrow) { + if (event.key === KeyboardKeys.UpArrow) { event.preventDefault(); return this.skipIfFile(this.handleHighlightPrevious); - } else if (event.code === KeyboardCodes.DownArrow) { + } else if (event.key === KeyboardKeys.DownArrow) { event.preventDefault(); return this.skipIfFile(this.handleHighlightNext); - } else if (event.code === KeyboardCodes.RightArrow || event.code === KeyboardCodes.Enter) { + } else if (event.key === KeyboardKeys.RightArrow || event.key === KeyboardKeys.Enter) { event.preventDefault(); return this.skipIfFile(this.handleSelectCurrent); - } else if (event.code === KeyboardCodes.LeftArrow) { + } else if (event.key === KeyboardKeys.LeftArrow) { event.preventDefault(); this.handleSelectParent(); return false; // always hijack left / Why did you put this @wouter? diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx b/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx index 413385d2f60..8b0bae9e518 100644 --- a/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx +++ b/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { Button, ResetButtonLink } from '../../../components/controls/buttons'; import { DropdownOverlay } from '../../../components/controls/Dropdown'; import { PopupPlacement } from '../../../components/ui/popups'; -import { KeyboardCodes } from '../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; import { IssueComment } from '../../../types/types'; import FormattingTips from '../../common/FormattingTips'; @@ -62,15 +62,15 @@ export default class CommentPopup extends React.PureComponent { - if (event.nativeEvent.code === KeyboardCodes.Enter && (event.metaKey || event.ctrlKey)) { + if (event.nativeEvent.key === KeyboardKeys.Enter && (event.metaKey || event.ctrlKey)) { this.handleCommentClick(); } else if ( [ - KeyboardCodes.UpArrow, - KeyboardCodes.DownArrow, - KeyboardCodes.LeftArrow, - KeyboardCodes.RightArrow - ].includes(event.nativeEvent.code as KeyboardCodes) + KeyboardKeys.UpArrow, + KeyboardKeys.DownArrow, + KeyboardKeys.LeftArrow, + KeyboardKeys.RightArrow + ].includes(event.nativeEvent.key as KeyboardKeys) ) { // Arrow keys event.stopPropagation(); diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.tsx b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.tsx index ce562ae6a59..62fcb621c1c 100644 --- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.tsx +++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { KeyboardCodes } from '../../../../helpers/keycodes'; +import { KeyboardKeys } from '../../../../helpers/keycodes'; import { mockEvent } from '../../../../helpers/testMocks'; import { click } from '../../../../helpers/testUtils'; import CommentPopup, { CommentPopupProps } from '../CommentPopup'; @@ -58,7 +58,7 @@ it('should handle ctrl+enter', () => { wrapper .instance() - .handleKeyboard(mockEvent({ ctrlKey: true, nativeEvent: { code: KeyboardCodes.Enter } })); + .handleKeyboard(mockEvent({ ctrlKey: true, nativeEvent: { key: KeyboardKeys.Enter } })); expect(onComment).toBeCalled(); }); @@ -67,7 +67,7 @@ it('should stopPropagation for arrow keys events', () => { const wrapper = shallowRender(); const event = mockEvent({ - nativeEvent: { code: KeyboardCodes.UpArrow }, + nativeEvent: { key: KeyboardKeys.UpArrow }, stopPropagation: jest.fn() }); wrapper.instance().handleKeyboard(event); diff --git a/server/sonar-web/src/main/js/helpers/keycodes.ts b/server/sonar-web/src/main/js/helpers/keycodes.ts index f061e98713c..bf6c0fc0533 100644 --- a/server/sonar-web/src/main/js/helpers/keycodes.ts +++ b/server/sonar-web/src/main/js/helpers/keycodes.ts @@ -17,7 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export enum KeyboardCodes { + +export enum KeyboardKeys { LeftArrow = 'ArrowLeft', UpArrow = 'ArrowUp', RightArrow = 'ArrowRight', @@ -33,17 +34,7 @@ export enum KeyboardCodes { PageDown = 'PageDown', PageUp = 'PageUp', Space = 'Space', - Tab = 'Tab' -} - -export enum KeyboardKeys { - Escape = 'Escape', - UpArrow = 'ArrowUp', - DownArrow = 'ArrowDown', - RightArrow = 'ArrowRight', - LeftArrow = 'ArrowLeft', - Enter = 'Enter', - Space = ' ', + Tab = 'Tab', Alt = 'Alt', KeyF = 'f', KeyA = 'a', diff --git a/server/sonar-web/src/main/js/helpers/testUtils.ts b/server/sonar-web/src/main/js/helpers/testUtils.ts index 72228cf16e0..603c3f32a02 100644 --- a/server/sonar-web/src/main/js/helpers/testUtils.ts +++ b/server/sonar-web/src/main/js/helpers/testUtils.ts @@ -19,7 +19,7 @@ */ import { ReactWrapper, ShallowWrapper } from 'enzyme'; import { setImmediate } from 'timers'; -import { KeyboardCodes, KeyboardKeys } from './keycodes'; +import { KeyboardKeys } from './keycodes'; export function mockEvent(overrides = {}) { return { @@ -74,20 +74,15 @@ export function change( } } -export const KEYCODE_MAP: { [code in KeyboardCodes]?: string } = { - [KeyboardCodes.Enter]: 'enter', - [KeyboardCodes.LeftArrow]: 'left', - [KeyboardCodes.UpArrow]: 'up', - [KeyboardCodes.RightArrow]: 'right', - [KeyboardCodes.DownArrow]: 'down' +export const KEYCODE_MAP: { [code in KeyboardKeys]?: string } = { + [KeyboardKeys.Enter]: 'enter', + [KeyboardKeys.LeftArrow]: 'left', + [KeyboardKeys.UpArrow]: 'up', + [KeyboardKeys.RightArrow]: 'right', + [KeyboardKeys.DownArrow]: 'down' }; -export function keydown(args: { - code?: KeyboardCodes; - key?: KeyboardKeys; - metaKey?: boolean; - ctrlKey?: boolean; -}): void { +export function keydown(args: { key?: KeyboardKeys; metaKey?: boolean; ctrlKey?: boolean }): void { const event = new KeyboardEvent('keydown', args as KeyboardEventInit); document.dispatchEvent(event); } -- 2.39.5