usfm-editor
Version:
A WYSIWYG editor component for USFM
191 lines (143 loc) • 6.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.handleKeyPress = handleKeyPress;
exports.withEnter = exports.withDelete = exports.withBackspace = void 0;
var _slate = require("slate");
var _MyEditor = require("./helpers/MyEditor");
var _MyTransforms = require("./helpers/MyTransforms");
var _UsfmMarkers = require("../utils/UsfmMarkers");
var _SelectionTransforms = require("./helpers/SelectionTransforms");
function handleKeyPress(event, editor) {
if (event.key === "ArrowLeft") {
onLeftArrowPress(event, editor);
} else if (event.key === "ArrowRight") {
onRightArrowPress(event, editor);
}
if (!isNavigationKey(event) && isVerseOrChapterNumSelected(editor)) {
console.debug("Verse or chapter number selected, preventing action");
event.preventDefault();
}
}
const withEnter = editor => {
editor.insertBreak = () => {
splitToInsertParagraph(editor);
};
return editor;
};
exports.withEnter = withEnter;
const withBackspace = editor => {
const {
deleteBackward
} = editor;
editor.deleteBackward = (...args) => {
var _Editor$parent;
const {
selection
} = editor;
if (selection !== null && selection !== void 0 && selection.anchor && _slate.Range.isCollapsed(selection) && _slate.Editor.isStart(editor, selection.anchor, (_Editor$parent = _slate.Editor.parent(editor, selection === null || selection === void 0 ? void 0 : selection.anchor)) === null || _Editor$parent === void 0 ? void 0 : _Editor$parent[1])) {
if (_MyEditor.MyEditor.isNearbyBlockAVerseOrChapterNumberOrNull(editor, "previous")) {
console.debug("Invalid previous node, skipping backspace");
return;
} else if (_MyEditor.MyEditor.isNearbyBlockAnInlineContainer(editor, "previous")) {
_MyTransforms.MyTransforms.mergeSelectedBlockAndSetToInlineContainer(editor, {
mode: "previous"
});
return;
}
}
deleteBackward(...args);
};
return editor;
};
exports.withBackspace = withBackspace;
const withDelete = editor => {
const {
deleteForward
} = editor;
editor.deleteForward = (...args) => {
var _Editor$parent2;
const {
selection
} = editor;
if (selection !== null && selection !== void 0 && selection.focus && _slate.Range.isCollapsed(selection) && _slate.Editor.isEnd(editor, selection.focus, (_Editor$parent2 = _slate.Editor.parent(editor, selection === null || selection === void 0 ? void 0 : selection.focus)) === null || _Editor$parent2 === void 0 ? void 0 : _Editor$parent2[1])) {
if (_MyEditor.MyEditor.isNearbyBlockAVerseOrChapterNumberOrNull(editor, "next")) {
console.debug("Invalid next node, skipping delete");
return;
} else if (_MyEditor.MyEditor.isNearbyBlockAnEmptyInlineContainer(editor, "current")) {
_MyTransforms.MyTransforms.mergeSelectedBlockAndSetToInlineContainer(editor, {
mode: "next"
});
return;
}
}
deleteForward(...args);
};
return editor;
};
exports.withDelete = withDelete;
function onLeftArrowPress(event, editor) {
var _MyEditor$getCurrentB, _MyEditor$getPrevious;
const blockPath = (_MyEditor$getCurrentB = _MyEditor.MyEditor.getCurrentBlock(editor)) === null || _MyEditor$getCurrentB === void 0 ? void 0 : _MyEditor$getCurrentB[1];
const prevBlock = (_MyEditor$getPrevious = _MyEditor.MyEditor.getPreviousBlock(editor)) === null || _MyEditor$getPrevious === void 0 ? void 0 : _MyEditor$getPrevious[0];
const selection = editor.selection; // Move left through a verse number node to the end of the previous verse,
// but do not attempt to move left through a "front" verse node.
if (blockPath && prevBlock && selection && _MyEditor.MyEditor.isNearbyBlockAVerseNumber(editor, "previous") && _slate.Range.isCollapsed(selection) && _slate.Editor.isStart(editor, selection.anchor, blockPath)) {
event.preventDefault();
if (_slate.Node.string(prevBlock) == "front") return;
const prevVerseEntry = _MyEditor.MyEditor.getPreviousVerse(editor, selection.focus.path, true);
if (prevVerseEntry) {
_SelectionTransforms.SelectionTransforms.moveToEndOfLastLeaf(editor, prevVerseEntry[1]);
} else {
console.debug("Previous node is a non-front verse number, but no prior verse exists");
}
}
}
function onRightArrowPress(event, editor) {
const chapterNodeEntry = _MyEditor.MyEditor.getChapterNode(editor);
if (chapterNodeEntry && editor.selection && _slate.Range.isCollapsed(editor.selection) && _slate.Editor.isEnd(editor, editor.selection.anchor, chapterNodeEntry[1])) {
event.preventDefault();
}
}
/**
* Splits the block container and changes the resulting block to a paragraph type
*/
function splitToInsertParagraph(editor) {
var _editor$selection;
// If there is an empty text selected, we need to move the selecton forward,
// or else the selection will stay on the previous line
_MyTransforms.MyTransforms.selectNextSiblingNonEmptyText(editor);
const point = (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : _editor$selection.anchor;
if (!point) {
console.error("Couldn't get splitToInsertParagraph point.");
return;
}
const [_, parentPath] = _slate.Editor.parent(editor, point); // After splitting a node, the resulting nodes may be combined via normalization,
// so run these together without normalizing
_slate.Editor.withoutNormalizing(editor, () => {
_slate.Transforms.splitNodes(editor, {
always: true
});
_slate.Transforms.setNodes(editor, {
type: _UsfmMarkers.UsfmMarkers.PARAGRAPHS.p
}, {
at: _slate.Path.next(parentPath)
});
});
}
function isVerseOrChapterNumSelected(editor) {
if (!editor.selection) return false;
for (const [node] of _slate.Editor.nodes(editor, {
at: editor.selection
})) {
if (_UsfmMarkers.UsfmMarkers.isVerseOrChapterNumber(node)) {
return true;
}
}
return false;
}
const navigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
function isNavigationKey(event) {
return navigationKeys.includes(event.key);
}