Add RTE keyboard navigation in editing (#9980)
Add Keyboard navigation in editing
This commit is contained in:
parent
8161da1054
commit
afda774471
9 changed files with 585 additions and 48 deletions
46
src/components/views/rooms/wysiwyg_composer/utils/event.ts
Normal file
46
src/components/views/rooms/wysiwyg_composer/utils/event.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import EditorStateTransfer from "../../../../../utils/EditorStateTransfer";
|
||||
import { IRoomState } from "../../../../structures/RoomView";
|
||||
|
||||
// From EditMessageComposer private get events(): MatrixEvent[]
|
||||
export function getEventsFromEditorStateTransfer(
|
||||
editorStateTransfer: EditorStateTransfer,
|
||||
roomContext: IRoomState,
|
||||
mxClient: MatrixClient,
|
||||
): MatrixEvent[] | undefined {
|
||||
const liveTimelineEvents = roomContext.liveTimeline?.getEvents();
|
||||
if (!liveTimelineEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
const roomId = editorStateTransfer.getEvent().getRoomId();
|
||||
if (!roomId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const room = mxClient.getRoom(roomId);
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pendingEvents = room.getPendingEvents();
|
||||
const isInThread = Boolean(editorStateTransfer.getEvent().getThread());
|
||||
return liveTimelineEvents.concat(isInThread ? [] : pendingEvents);
|
||||
}
|
|
@ -39,3 +39,50 @@ export function isSelectionEmpty(): boolean {
|
|||
const selection = document.getSelection();
|
||||
return Boolean(selection?.isCollapsed);
|
||||
}
|
||||
|
||||
export function isCaretAtStart(editor: HTMLElement): boolean {
|
||||
const selection = document.getSelection();
|
||||
|
||||
// No selection or the caret is not at the beginning of the selected element
|
||||
if (!selection || selection.anchorOffset !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In case of nested html elements (list, code blocks), we are going through all the first child
|
||||
let child = editor.firstChild;
|
||||
do {
|
||||
if (child === selection.anchorNode) {
|
||||
return true;
|
||||
}
|
||||
} while ((child = child?.firstChild || null));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isCaretAtEnd(editor: HTMLElement): boolean {
|
||||
const selection = document.getSelection();
|
||||
|
||||
if (!selection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When we are cycling across all the timeline message with the keyboard
|
||||
// The caret is on the last text element but focusNode and anchorNode refers to the editor div
|
||||
// In this case, the focusOffset & anchorOffset match the index + 1 of the selected text
|
||||
const isOnLastElement = selection.focusNode === editor && selection.focusOffset === editor.childNodes?.length;
|
||||
if (isOnLastElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// In case of nested html elements (list, code blocks), we are going through all the last child
|
||||
// The last child of the editor is always a <br> tag, we skip it
|
||||
let child: ChildNode | null = editor.childNodes.item(editor.childNodes.length - 2);
|
||||
do {
|
||||
if (child === selection.focusNode) {
|
||||
// Checking that the cursor is at end of the selected text
|
||||
return selection.focusOffset === child.textContent?.length;
|
||||
}
|
||||
} while ((child = child.lastChild));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue