mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
fix(editor): Prevent opening NDV search if /
is typed in a contenteditable element (#7968)
## Summary Prevent opening NDV search if `/` is typed in a contenteditable element ... #### How to test the change: 1. Create a workflow with a Code node that has some input and output 2. Run the workflow and then open the Code node 3. Type `/` anywhere in the Code node #### Expected behavior: NDV search should not be opened and focused
This commit is contained in:
parent
7f0126915a
commit
e8a493f718
|
@ -26,7 +26,6 @@ const locale = useI18n();
|
|||
const inputRef = ref<HTMLInputElement | null>(null);
|
||||
const maxWidth = ref(INITIAL_WIDTH);
|
||||
const opened = ref(false);
|
||||
const focused = ref(false);
|
||||
const placeholder = computed(() =>
|
||||
props.paneType === 'input'
|
||||
? locale.baseText('ndv.search.placeholder.input')
|
||||
|
@ -34,11 +33,13 @@ const placeholder = computed(() =>
|
|||
);
|
||||
|
||||
const documentKeyHandler = (event: KeyboardEvent) => {
|
||||
const isTargetAnyFormElement =
|
||||
const isTargetFormElementOrEditable =
|
||||
event.target instanceof HTMLInputElement ||
|
||||
event.target instanceof HTMLTextAreaElement ||
|
||||
event.target instanceof HTMLSelectElement;
|
||||
if (event.key === '/' && !focused.value && props.isAreaActive && !isTargetAnyFormElement) {
|
||||
event.target instanceof HTMLSelectElement ||
|
||||
(event.target as HTMLElement)?.getAttribute?.('contentEditable') === 'true';
|
||||
|
||||
if (event.key === '/' && props.isAreaActive && !isTargetFormElementOrEditable) {
|
||||
inputRef.value?.focus();
|
||||
inputRef.value?.select();
|
||||
}
|
||||
|
@ -49,13 +50,11 @@ const onSearchUpdate = (value: string) => {
|
|||
};
|
||||
const onFocus = () => {
|
||||
opened.value = true;
|
||||
focused.value = true;
|
||||
maxWidth.value = '30%';
|
||||
inputRef.value?.select();
|
||||
emit('focus');
|
||||
};
|
||||
const onBlur = () => {
|
||||
focused.value = false;
|
||||
if (!props.modelValue) {
|
||||
opened.value = false;
|
||||
maxWidth.value = INITIAL_WIDTH;
|
||||
|
|
|
@ -2,21 +2,14 @@ import userEvent from '@testing-library/user-event';
|
|||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import RunDataSearch from '@/components/RunDataSearch.vue';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
||||
const renderComponent = createComponentRenderer(RunDataSearch);
|
||||
let pinia: ReturnType<typeof createPinia>;
|
||||
let uiStore: ReturnType<typeof useUIStore>;
|
||||
let settingsStore: ReturnType<typeof useSettingsStore>;
|
||||
|
||||
describe('RunDataSearch', () => {
|
||||
beforeEach(() => {
|
||||
pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
|
||||
uiStore = useUIStore();
|
||||
settingsStore = useSettingsStore();
|
||||
});
|
||||
|
||||
it('should not be focused on keyboard shortcut when area is not active', async () => {
|
||||
|
@ -66,7 +59,6 @@ describe('RunDataSearch', () => {
|
|||
});
|
||||
|
||||
it('should select all text when focused', async () => {
|
||||
vi.spyOn(settingsStore, 'isEnterpriseFeatureEnabled', 'get').mockReturnValue(() => true);
|
||||
const { getByRole, emitted } = renderComponent({
|
||||
pinia,
|
||||
props: {
|
||||
|
@ -91,4 +83,41 @@ describe('RunDataSearch', () => {
|
|||
|
||||
expect(isSelected).toBe(true);
|
||||
});
|
||||
|
||||
it('should not be focused on keyboard shortcut when a contenetEditable element is active', async () => {
|
||||
const { getByTestId } = createComponentRenderer({
|
||||
components: {
|
||||
RunDataSearch,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div data-test-id="mock-contenteditable" contenteditable="true"></div>
|
||||
<RunDataSearch
|
||||
v-model="modelValue"
|
||||
:isAreaActive="isAreaActive"
|
||||
/>
|
||||
</div>
|
||||
`,
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
isAreaActive: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
})({
|
||||
pinia,
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
const contentEditableElement = getByTestId('mock-contenteditable');
|
||||
await user.click(contentEditableElement);
|
||||
expect(document.activeElement).toBe(contentEditableElement);
|
||||
await user.type(contentEditableElement, '/');
|
||||
expect(contentEditableElement.textContent).toBe('/');
|
||||
expect(getByTestId('ndv-search')).not.toHaveFocus();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue