Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Fix selection
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Oct 26, 2022
1 parent d001dde commit f1610da
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import React, { MutableRefObject, ReactNode } from 'react';
import { useComposerFunctions } from '../hooks/useComposerFunctions';
import { usePlainTextInitialization } from '../hooks/usePlainTextInitialization';
import { usePlainTextListeners } from '../hooks/usePlainTextListeners';
import { useSetCursorPosition } from '../hooks/useSetCursorPosition';
import { ComposerFunctions } from '../types';
import { Editor } from "./Editor";

Expand All @@ -40,6 +41,7 @@ export function PlainTextComposer({
const { ref, onInput, onPaste, onKeyDown } = usePlainTextListeners(onChange, onSend);
const composerFunctions = useComposerFunctions(ref);
usePlainTextInitialization(initialContent, ref);
useSetCursorPosition(disabled, ref);

return <div className={className} onInput={onInput} onPaste={onPaste} onKeyDown={onKeyDown}>
<Editor ref={ref} disabled={disabled} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ export const WysiwygComposer = memo(function WysiwygComposer(
}
}, [onChange, content, disabled]);

useSetCursorPosition(isWysiwygReady, ref);
const isReady = isWysiwygReady && !disabled;
useSetCursorPosition(!isReady, ref);

return (
<div className={className}>
<FormattingButtons composer={wysiwyg} formattingStates={formattingStates} />
<Editor ref={ref} disabled={!isWysiwygReady || disabled} />
<Editor ref={ref} disabled={!isReady} />
{ children?.(ref, wysiwyg) }
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import { RefObject, useEffect } from "react";

import { setCursorPositionAtTheEnd } from "./utils";

export function useSetCursorPosition(isComposerReady: boolean, ref: RefObject<HTMLElement>) {
export function useSetCursorPosition(disabled: boolean, ref: RefObject<HTMLElement>) {
useEffect(() => {
if (ref.current && isComposerReady) {
if (ref.current && !disabled) {
setCursorPositionAtTheEnd(ref.current);
}
}, [ref, isComposerReady]);
}, [ref, disabled]);
}
6 changes: 3 additions & 3 deletions src/components/views/rooms/wysiwyg_composer/hooks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export function setCursorPositionAtTheEnd(element: HTMLElement) {
const range = document.createRange();
range.selectNodeContents(element);
range.collapse(false);
const sel = document.getSelection();
sel.removeAllRanges();
sel.addRange(range);
const selection = document.getSelection();
selection.removeAllRanges();
selection.addRange(range);

element.focus();
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ describe('EditWysiwygComposer', () => {
it('Should focus when receiving an Action.FocusEditMessageComposer action', async () => {
// Given we don't have focus
customRender();
screen.getByLabelText('Bold').focus();
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send the right action
Expand All @@ -201,6 +202,7 @@ describe('EditWysiwygComposer', () => {
it('Should not focus when disabled', async () => {
// Given we don't have focus and we are disabled
customRender(true);
screen.getByLabelText('Bold').focus();
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send an action that would cause us to get focus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('SendWysiwygComposer', () => {
it('Should focus when receiving an Action.FocusSendMessageComposer action', async () => {
// Given we don't have focus
customRender(jest.fn(), jest.fn());
screen.getByLabelText('Bold').focus();
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send the right action
Expand All @@ -96,6 +97,7 @@ describe('SendWysiwygComposer', () => {
it('Should focus and clear when receiving an Action.ClearAndFocusSendMessageComposer', async () => {
// Given we don't have focus
customRender(jest.fn(), jest.fn());
screen.getByLabelText('Bold').focus();
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send the right action
Expand All @@ -112,6 +114,7 @@ describe('SendWysiwygComposer', () => {
it('Should focus when receiving a reply_to_event action', async () => {
// Given we don't have focus
customRender(jest.fn(), jest.fn());
screen.getByLabelText('Bold').focus();
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send the right action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,15 @@ describe('WysiwygComposer', () => {

const defaultRoomContext: IRoomState = getRoomContext(mockRoom, {});

const customRender = (onChange = (_content: string) => void 0, onSend = () => void 0, disabled = false) => {
const customRender = (
onChange = (_content: string) => void 0,
onSend = () => void 0,
disabled = false,
initialContent?: string) => {
return render(
<MatrixClientContext.Provider value={mockClient}>
<RoomContext.Provider value={defaultRoomContext}>
<WysiwygComposer onChange={onChange} onSend={onSend} disabled={disabled} />
<WysiwygComposer onChange={onChange} onSend={onSend} disabled={disabled} initialContent={initialContent} />
</RoomContext.Provider>
</MatrixClientContext.Provider>,
);
Expand All @@ -91,6 +95,14 @@ describe('WysiwygComposer', () => {
expect(screen.getByRole('textbox')).toHaveAttribute('contentEditable', "false");
});

it('Should have focus', () => {
// When
customRender(jest.fn(), jest.fn(), false);

// Then
expect(screen.getByRole('textbox')).toHaveFocus();
});

it('Should call onChange handler', (done) => {
const html = '<b>html</b>';
customRender((content) => {
Expand All @@ -104,7 +116,7 @@ describe('WysiwygComposer', () => {
const onSend = jest.fn();
customRender(jest.fn(), onSend);

// When we tell its inputEventProcesser that the user pressed Enter
// When we tell its inputEventProcessor that the user pressed Enter
const event = new InputEvent("insertParagraph", { inputType: "insertParagraph" });
const wysiwyg = { actions: { clear: () => {} } } as Wysiwyg;
inputEventProcessor(event, wysiwyg);
Expand Down

0 comments on commit f1610da

Please sign in to comment.