aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJay <jeremy.davis@sonarsource.com>2022-02-25 11:23:01 +0100
committersonartech <sonartech@sonarsource.com>2022-02-25 20:02:55 +0000
commit7f825acb518fcd15823d3fb279509816e25e1d85 (patch)
tree0c3afcaeb56134518651b189fff46ee67b441830 /server
parentf87f174aa6c07d0d5f39f427f4a07978e7e6a53b (diff)
downloadsonarqube-7f825acb518fcd15823d3fb279509816e25e1d85.tar.gz
sonarqube-7f825acb518fcd15823d3fb279509816e25e1d85.zip
SONAR-16008 Fix keyboad navigation conflict
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx24
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx61
2 files changed, 41 insertions, 44 deletions
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 63778962337..4d335618427 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
@@ -18,9 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import classNames from 'classnames';
-import key from 'keymaster';
import * as React from 'react';
import BoxedTabs from '../../../components/controls/BoxedTabs';
+import { KeyboardCodes } from '../../../helpers/keycodes';
import { translate } from '../../../helpers/l10n';
import { sanitizeString } from '../../../helpers/sanitize';
import { Hotspot } from '../../../types/security-hotspots';
@@ -49,8 +49,6 @@ export enum TabKeys {
FixRecommendation = 'fix'
}
-const HOTSPOT_KEYMASTER_SCOPE = 'hotspots-list';
-
export default class HotspotViewerTabs extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
@@ -87,20 +85,22 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
this.unregisterKeyboardEvents();
}
- registerKeyboardEvents() {
- key.setScope(HOTSPOT_KEYMASTER_SCOPE);
- key('left', HOTSPOT_KEYMASTER_SCOPE, () => {
+ handleKeyboardNavigation = (event: KeyboardEvent) => {
+ if (event.code === KeyboardCodes.LeftArrow) {
+ event.preventDefault();
this.selectNeighboringTab(-1);
- return false;
- });
- key('right', HOTSPOT_KEYMASTER_SCOPE, () => {
+ } else if (event.code === KeyboardCodes.RightArrow) {
+ event.preventDefault();
this.selectNeighboringTab(+1);
- return false;
- });
+ }
+ };
+
+ registerKeyboardEvents() {
+ window.addEventListener('keydown', this.handleKeyboardNavigation);
}
unregisterKeyboardEvents() {
- key.deleteScope(HOTSPOT_KEYMASTER_SCOPE);
+ window.removeEventListener('keydown', this.handleKeyboardNavigation);
}
handleSelectTabs = (tabKey: TabKeys) => {
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 ffbc475c3da..50fbf5f4392 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
@@ -22,29 +22,28 @@ import * as React from 'react';
import BoxedTabs, { BoxedTabsProps } from '../../../../components/controls/BoxedTabs';
import { KeyboardCodes } from '../../../../helpers/keycodes';
import { mockHotspot, mockHotspotRule } from '../../../../helpers/mocks/security-hotspots';
-import { mockUser } from '../../../../helpers/testMocks';
-import { KEYCODE_MAP, keydown } from '../../../../helpers/testUtils';
+import { mockEvent, mockUser } from '../../../../helpers/testMocks';
import HotspotViewerTabs, { TabKeys } from '../HotspotViewerTabs';
-jest.mock('keymaster', () => {
- const key: any = (bindKey: string, _: string, callback: Function) => {
- document.addEventListener('keydown', (event: KeyboardEvent) => {
- const keymasterCode = event.code && KEYCODE_MAP[event.code as KeyboardCodes];
- if (keymasterCode && bindKey.split(',').includes(keymasterCode)) {
- return callback();
- }
- return true;
- });
- };
- let scope = 'hotspots-list';
-
- key.getScope = () => scope;
- key.setScope = (newScope: string) => {
- scope = newScope;
- };
- key.deleteScope = jest.fn();
-
- return key;
+const originalAddEventListener = window.addEventListener;
+const originalRemoveEventListener = window.removeEventListener;
+
+beforeEach(() => {
+ Object.defineProperty(window, 'addEventListener', {
+ value: jest.fn()
+ });
+ Object.defineProperty(window, 'removeEventListener', {
+ value: jest.fn()
+ });
+});
+
+afterEach(() => {
+ Object.defineProperty(window, 'addEventListener', {
+ value: originalAddEventListener
+ });
+ Object.defineProperty(window, 'removeEventListener', {
+ value: originalRemoveEventListener
+ });
});
it('should render correctly', () => {
@@ -146,13 +145,13 @@ describe('keyboard navigation', () => {
const wrapper = shallowRender();
it.each([
- ['selecting next', 0, 1, 1],
- ['selecting previous', 1, -1, 0],
- ['selecting previous, non-existent', 0, -1, 0],
- ['selecting next, non-existent', 3, 1, 3]
- ])('should work when %s', (_, start, shift, expected) => {
+ ['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) => {
wrapper.setState({ currentTab: wrapper.state().tabs[start] });
- wrapper.instance().selectNeighboringTab(shift);
+ wrapper.instance().handleKeyboardNavigation(mockEvent({ code }));
expect(wrapper.state().currentTab.key).toBe(tabList[expected]);
});
@@ -163,13 +162,11 @@ it('should navigate when up and down key are pressed', () => {
<HotspotViewerTabs codeTabContent={<div>CodeTabContent</div>} hotspot={mockHotspot()} />
);
- const selectNeighboringTab = jest.spyOn(wrapper.instance(), 'selectNeighboringTab');
+ expect(window.addEventListener).toBeCalled();
- keydown({ code: KeyboardCodes.LeftArrow });
- expect(selectNeighboringTab).toBeCalledWith(-1);
+ wrapper.unmount();
- keydown({ code: KeyboardCodes.RightArrow });
- expect(selectNeighboringTab).toBeCalledWith(1);
+ expect(window.removeEventListener).toBeCalled();
});
function shallowRender(props?: Partial<HotspotViewerTabs['props']>) {