jodit
Version:
Jodit is awesome and usefully wysiwyg editor with filebrowser
179 lines (165 loc) • 4.44 kB
text/typescript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Licensed under GNU General Public License version 2 or later or a commercial license or MIT;
* For GPL see LICENSE-GPL.txt in the project root for license information.
* For MIT see LICENSE-MIT.txt in the project root for license information.
* For commercial licenses see https://xdsoft.net/jodit/commercial/
* Copyright (c) 2013-2019 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import * as consts from '../constants';
import { Dom } from '../modules/Dom';
import { Table } from '../modules/Table';
import { IJodit } from '../types';
/**
* Process navigate keypressing in table cell
*
* @param {Jodit} editor
*/
export function tableKeyboardNavigation(editor: IJodit) {
editor.events.on(
'keydown',
(event: KeyboardEvent): false | void => {
let current: Element, block: HTMLElement;
if (
event.which === consts.KEY_TAB ||
event.which === consts.KEY_LEFT ||
event.which === consts.KEY_RIGHT ||
event.which === consts.KEY_UP ||
event.which === consts.KEY_DOWN
) {
current = editor.selection.current() as Element;
block = Dom.up(
current,
(elm: Node | null) =>
elm && elm.nodeName && /^td|th$/i.test(elm.nodeName),
editor.editor
) as HTMLTableCellElement;
if (!block) {
return;
}
const range = editor.selection.range;
if (event.which !== consts.KEY_TAB && current !== block) {
if (
((event.which === consts.KEY_LEFT ||
event.which === consts.KEY_UP) &&
(Dom.prev(
current,
(elm: Node | null) =>
event.which === consts.KEY_UP
? elm && elm.nodeName === 'BR'
: !!elm,
block
) ||
(event.which !== consts.KEY_UP &&
current.nodeType === Node.TEXT_NODE &&
range.startOffset !== 0))) ||
((event.which === consts.KEY_RIGHT ||
event.which === consts.KEY_DOWN) &&
(Dom.next(
current,
(elm: Node | null) =>
event.which === consts.KEY_DOWN
? elm && elm.nodeName === 'BR'
: !!elm,
block
) ||
(event.which !== consts.KEY_DOWN &&
current.nodeType === Node.TEXT_NODE &&
current.nodeValue &&
range.startOffset !==
current.nodeValue.length)))
) {
return;
}
}
} else {
return;
}
const table = Dom.up(
block,
(elm: Node | null) => elm && /^table$/i.test(elm.nodeName),
editor.editor
) as HTMLTableElement;
let next: HTMLTableCellElement | null = null;
switch (event.which) {
case consts.KEY_TAB:
// case consts.KEY_RIGHT:
case consts.KEY_LEFT:
const sibling: string =
event.which === consts.KEY_LEFT || event.shiftKey
? 'prev'
: 'next';
next = (Dom as any)[sibling](
block,
(elm: Node | null) =>
elm &&
/^td|th$/i.test((elm as HTMLElement).tagName),
table
) as HTMLTableCellElement;
if (!next) {
Table.appendRow(
table,
sibling === 'next'
? false
: (table.querySelector(
'tr'
) as HTMLTableRowElement),
sibling === 'next'
);
next = (Dom as any)[sibling](
block,
(elm: Node | null) =>
elm && Dom.isCell(elm, editor.editorWindow),
table
) as HTMLTableCellElement;
}
break;
case consts.KEY_UP:
case consts.KEY_DOWN:
{
let i = 0,
j = 0;
const matrix = Table.formalMatrix(
table,
(elm, _i, _j) => {
if (elm === block) {
i = _i;
j = _j;
}
}
);
if (event.which === consts.KEY_UP) {
if (matrix[i - 1] !== undefined) {
next = matrix[i - 1][j];
}
} else {
if (matrix[i + 1] !== undefined) {
next = matrix[i + 1][j];
}
}
}
break;
}
if (next) {
if (!next.firstChild) {
const first: Node = editor.editorDocument.createElement(
'br'
);
next.appendChild(first);
editor.selection.setCursorBefore(first);
} else {
if (event.which === consts.KEY_TAB) {
editor.selection.select(next, true);
} else {
editor.selection.setCursorIn(
next,
event.which === consts.KEY_RIGHT ||
event.which === consts.KEY_DOWN
);
}
}
return false;
}
}
);
}