[7.6] Fix ace a11y listener (#60639) (#60726)

* Fix ace a11y listener (#60639)

Also move the hook use_ui_ace_keyboard_mode.tsx into es_ui_shared

This was defined (and used) in both Console and SearchProfiler.

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/use_ui_ace_keyboard_mode.tsx
#	src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx
#	src/plugins/console/public/application/containers/editor/legacy/use_ui_ace_keyboard_mode.tsx
#	src/plugins/es_ui_shared/public/index.ts
#	src/plugins/es_ui_shared/public/use_ui_ace_keyboard_mode.tsx
#	x-pack/legacy/plugins/searchprofiler/public/np_ready/application/editor/use_ui_ace_keyboard_mode.tsx
#	x-pack/plugins/searchprofiler/public/application/editor/editor.tsx

* Remove unused translations
This commit is contained in:
Jean-Louis Leysens 2020-03-22 00:57:19 +01:00 committed by GitHub
parent f94e7215de
commit bc82d6d0b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 5 additions and 117 deletions

View file

@ -28,7 +28,7 @@ import * as qs from 'querystring-browser';
import { EuiIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { useServicesContext, useEditorReadContext } from '../../../../contexts';
import { useUIAceKeyboardMode } from '../use_ui_ace_keyboard_mode';
import { useUIAceKeyboardMode } from '../../../../../../../../../../plugins/es_ui_shared/public';
import { ConsoleMenu } from '../../../../components';
import { autoIndent, getDocumentation } from '../console_menu_actions';

View file

@ -18,3 +18,5 @@
*/
export * from './components/json_editor';
export { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode';

View file

@ -96,7 +96,7 @@ export function useUIAceKeyboardMode(aceTextAreaElement: HTMLTextAreaElement | n
}
return () => {
if (aceTextAreaElement) {
document.removeEventListener('keydown', documentKeyDownListener);
document.removeEventListener('keydown', documentKeyDownListener, { capture: true });
aceTextAreaElement.removeEventListener('keydown', aceKeydownListener);
const textAreaContainer = aceTextAreaElement.parentElement;
if (textAreaContainer && textAreaContainer.contains(overlayMountNode.current!)) {

View file

@ -8,7 +8,7 @@ import React, { memo, useRef, useEffect, useState } from 'react';
import { Editor as AceEditor } from 'brace';
import { initializeEditor } from './init_editor';
import { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode';
import { useUIAceKeyboardMode } from '../../../../../../../../src/plugins/es_ui_shared/public';
interface EditorShim {
getValue(): string;

View file

@ -1,110 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/**
* Copied from Console plugin
*/
import React, { useEffect, useRef } from 'react';
import * as ReactDOM from 'react-dom';
import { keyCodes, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
const OverlayText = () => (
// The point of this element is for accessibility purposes, so ignore eslint error
// in this case
//
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<>
<EuiText size="s">
{i18n.translate('xpack.searchProfiler.aceAccessibilityOverlayInstructionEnter', {
defaultMessage: 'Press Enter to start editing.',
})}
</EuiText>
<EuiText size="s">
{i18n.translate('xpack.searchProfiler.aceAccessibilityOverlayInstructionExit', {
defaultMessage: `When you are done, press Escape to stop editing.`,
})}
</EuiText>
</>
);
export function useUIAceKeyboardMode(aceTextAreaElement: HTMLTextAreaElement | null) {
const overlayMountNode = useRef<HTMLDivElement | null>(null);
const autoCompleteVisibleRef = useRef<boolean>(false);
useEffect(() => {
function onDismissOverlay(event: KeyboardEvent) {
if (event.keyCode === keyCodes.ENTER) {
event.preventDefault();
aceTextAreaElement!.focus();
}
}
function enableOverlay() {
if (overlayMountNode.current) {
overlayMountNode.current.focus();
}
}
const isAutoCompleteVisible = () => {
const autoCompleter = document.querySelector<HTMLDivElement>('.ace_autocomplete');
if (!autoCompleter) {
return false;
}
// The autoComplete is just hidden when it's closed, not removed from the DOM.
return autoCompleter.style.display !== 'none';
};
const documentKeyDownListener = () => {
autoCompleteVisibleRef.current = isAutoCompleteVisible();
};
const aceKeydownListener = (event: KeyboardEvent) => {
if (event.keyCode === keyCodes.ESCAPE && !autoCompleteVisibleRef.current) {
event.preventDefault();
event.stopPropagation();
enableOverlay();
}
};
if (aceTextAreaElement) {
// We don't control HTML elements inside of ace so we imperatively create an element
// that acts as a container and insert it just before ace's textarea element
// so that the overlay lives at the correct spot in the DOM hierarchy.
overlayMountNode.current = document.createElement('div');
overlayMountNode.current.className = 'kbnUiAceKeyboardHint';
overlayMountNode.current.setAttribute('role', 'application');
overlayMountNode.current.tabIndex = 0;
overlayMountNode.current.addEventListener('focus', enableOverlay);
overlayMountNode.current.addEventListener('keydown', onDismissOverlay);
ReactDOM.render(<OverlayText />, overlayMountNode.current);
aceTextAreaElement.parentElement!.insertBefore(overlayMountNode.current, aceTextAreaElement);
aceTextAreaElement.setAttribute('tabindex', '-1');
// Order of events:
// 1. Document capture event fires first and we check whether an autocomplete menu is open on keydown
// (not ideal because this is scoped to the entire document).
// 2. Ace changes it's state (like hiding or showing autocomplete menu)
// 3. We check what button was pressed and whether autocomplete was visible then determine
// whether it should act like a dismiss or if we should display an overlay.
document.addEventListener('keydown', documentKeyDownListener, { capture: true });
aceTextAreaElement.addEventListener('keydown', aceKeydownListener);
}
return () => {
if (aceTextAreaElement) {
document.removeEventListener('keydown', documentKeyDownListener);
aceTextAreaElement.removeEventListener('keydown', aceKeydownListener);
const textAreaContainer = aceTextAreaElement.parentElement;
if (textAreaContainer && textAreaContainer.contains(overlayMountNode.current!)) {
textAreaContainer.removeChild(overlayMountNode.current!);
}
}
};
}, [aceTextAreaElement]);
}

View file

@ -11876,8 +11876,6 @@
"xpack.rollupJobs.rollupIndexPatternsTitle": "ロールアップインデックスパターンを有効にする",
"xpack.rollupJobs.startJobsAction.errorTitle": "ロールアップジョブの開始中にエラーが発生",
"xpack.rollupJobs.stopJobsAction.errorTitle": "ロールアップジョブの停止中にエラーが発生",
"xpack.searchProfiler.aceAccessibilityOverlayInstructionEnter": "編集を開始するにはEnterキーを押してください。",
"xpack.searchProfiler.aceAccessibilityOverlayInstructionExit": "完了したらEscapeキーで編集を終了します。",
"xpack.searchProfiler.advanceTimeDescription": "イテレーターを次のドキュメントに進めるためにかかった時間。",
"xpack.searchProfiler.aggregationProfileTabTitle": "集約プロフィール",
"xpack.searchProfiler.basicLicenseTitle": "ベーシック",

View file

@ -11878,8 +11878,6 @@
"xpack.rollupJobs.rollupIndexPatternsTitle": "启用汇总索引模式",
"xpack.rollupJobs.startJobsAction.errorTitle": "启动汇总/打包作业时出错",
"xpack.rollupJobs.stopJobsAction.errorTitle": "停止汇总/打包作业时出错",
"xpack.searchProfiler.aceAccessibilityOverlayInstructionEnter": "按 Enter 键开始编辑。",
"xpack.searchProfiler.aceAccessibilityOverlayInstructionExit": "完成后,按 Esc 键停止编辑。",
"xpack.searchProfiler.advanceTimeDescription": "将迭代器推进到下一文档所用的时间。",
"xpack.searchProfiler.aggregationProfileTabTitle": "聚合配置文件",
"xpack.searchProfiler.basicLicenseTitle": "基础级",