usfm-editor
Version:
A WYSIWYG editor component for USFM
300 lines (231 loc) • 9.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MyEditor = void 0;
var _slate = require("slate");
var _NodeTypes = _interopRequireDefault(require("../../utils/NodeTypes"));
var _slateReact = require("slate-react");
var _identificationTransforms = require("../../transforms/identificationTransforms");
var _UsfmMarkers = require("../../utils/UsfmMarkers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const MyEditor = { ..._slate.Editor,
isMatchingNodeSelected,
isVerseOrChapterNumberSelected,
areMultipleBlocksSelected,
isNearbyBlockAnInlineContainer,
isNearbyBlockAnEmptyInlineContainer,
isNearbyBlockAVerseNumber,
isNearbyBlockAVerseOrChapterNumberOrNull,
getPreviousBlock,
getCurrentBlock,
getNextBlock,
getVerseNode,
getPreviousVerse,
getChapterNode,
getLastVerse,
getLastVerseNumberOrRange,
getPathFromDOMNode,
identification,
findVersePath
};
exports.MyEditor = MyEditor;
function isMatchingNodeSelected(editor, matchFcn) {
const [match] = _slate.Editor.nodes(editor, {
match: matchFcn
});
return !!match;
}
function isVerseOrChapterNumberSelected(editor) {
return isMatchingNodeSelected(editor, _UsfmMarkers.UsfmMarkers.isVerseOrChapterNumber);
}
function areMultipleBlocksSelected(editor) {
const {
selection
} = editor;
if (!selection) return false;
const anchorParent = _slate.Path.parent(selection.anchor.path);
const focusParent = _slate.Path.parent(selection.focus.path);
return !_slate.Path.equals(anchorParent, focusParent);
}
function isNearbyBlockAnInlineContainer(editor, direction) {
var _getNearbyBlock;
const block = (_getNearbyBlock = getNearbyBlock(editor, direction)) === null || _getNearbyBlock === void 0 ? void 0 : _getNearbyBlock[0];
return (block === null || block === void 0 ? void 0 : block.type) == _NodeTypes.default.INLINE_CONTAINER;
}
function isNearbyBlockAnEmptyInlineContainer(editor, direction) {
var _getNearbyBlock2;
const block = (_getNearbyBlock2 = getNearbyBlock(editor, direction)) === null || _getNearbyBlock2 === void 0 ? void 0 : _getNearbyBlock2[0];
return block !== undefined && block.type == _NodeTypes.default.INLINE_CONTAINER && _slate.Node.string(block) === "";
}
function isNearbyBlockAVerseNumber(editor, direction) {
var _getNearbyBlock3;
const block = (_getNearbyBlock3 = getNearbyBlock(editor, direction)) === null || _getNearbyBlock3 === void 0 ? void 0 : _getNearbyBlock3[0];
return (block === null || block === void 0 ? void 0 : block.type) == _UsfmMarkers.UsfmMarkers.CHAPTERS_AND_VERSES.v;
}
function isNearbyBlockAVerseOrChapterNumberOrNull(editor, direction) {
var _getNearbyBlock4;
const block = (_getNearbyBlock4 = getNearbyBlock(editor, direction)) === null || _getNearbyBlock4 === void 0 ? void 0 : _getNearbyBlock4[0];
return !block || _UsfmMarkers.UsfmMarkers.isVerseOrChapterNumber(block);
}
/**
* Finds the parent block of the text node at the current selection's anchor point,
* then returns the previous node
*/
function getPreviousBlock(editor) {
return getNearbyBlock(editor, "previous");
}
/**
* Finds the parent block of the text node at the current selection's anchor point
*/
function getCurrentBlock(editor) {
return getNearbyBlock(editor, "current");
}
/**
* Finds the parent block of the text node at the current selection's anchor point,
* then returns the next node
*/
function getNextBlock(editor) {
return getNearbyBlock(editor, "next");
}
/**
* Finds the parent block of the text node at the current selection's anchor point,
* then returns a node based on the direction:
* 'current' returns this parent block
* 'previous' returns the previous sibling of the parent block
* 'next' returns the next sibling of the parent block
*/
function getNearbyBlock(editor, direction = "current") {
var _editor$selection;
const point = (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : _editor$selection.anchor;
if (!point) return undefined;
const [_, path] = _slate.Editor.node(editor, point);
const [parent, parentPath] = _slate.Editor.parent(editor, path);
if (!_slate.Element.isElement(parent)) return undefined;
switch (direction) {
case "current":
return [parent, parentPath];
case "previous":
return _slate.Editor.previous(editor, {
at: parentPath
});
case "next":
return _slate.Editor.next(editor, {
at: parentPath
});
}
}
/**
* Get the verse corresponding to the given path.
* The verse node must be above the given path in the slate tree.
* If no path is given, the verse above the current selection will be returned.
*/
function getVerseNode(editor, path) {
const pathOption = path ? {
at: path
} : {};
return _slate.Editor.above(editor, {
match: isVerseNode,
...pathOption
});
}
/**
* Get the previous verse node (before the given path),
* optionally including the "front" verse (default is false)
*/
function getPreviousVerse(editor, path, includeFront = false) {
var _MyEditor$getVerseNod;
const [node] = _slate.Editor.node(editor, path);
const thisVersePath = isVerseNode(node) ? path : (_MyEditor$getVerseNod = MyEditor.getVerseNode(editor, path)) === null || _MyEditor$getVerseNod === void 0 ? void 0 : _MyEditor$getVerseNod[1];
const prevNode = thisVersePath ? _slate.Editor.node(editor, _slate.Path.previous(thisVersePath)) : undefined;
if (!prevNode || !prevNode[0]) return undefined;
const [prevVerseElement, prevVersePath] = prevNode;
if (!isVerseNode(prevVerseElement)) return undefined;
if (!_slate.Element.isElement(prevVerseElement)) return undefined;
return includeFront || _slate.Node.string(prevVerseElement.children[0]) !== "front" ? [prevVerseElement, prevVersePath] : undefined;
}
/**
* Get the chapter corresponding to the given path.
* The chapter node must be above the given path in the slate tree.
* If no path is given, the chapter above the current selection will be returned.
*/
function getChapterNode(editor, path) {
const pathOption = path ? {
at: path
} : {};
return _slate.Editor.above(editor, {
match: isChapterNode,
...pathOption
});
}
/**
* Get the last verse of the chapter above the given path.
*/
function getLastVerse(editor, path) {
var _MyEditor$getChapterN;
const chapter = (_MyEditor$getChapterN = MyEditor.getChapterNode(editor, path)) === null || _MyEditor$getChapterN === void 0 ? void 0 : _MyEditor$getChapterN[0];
if (!chapter) return undefined;
const children = _slate.Node.children(chapter, [], {
reverse: true
});
for (const child of children) {
if (isVerseNode(child[0])) {
return child;
}
}
}
/**
* Get the last verse number/range (string) of the chapter above the given path.
*/
function getLastVerseNumberOrRange(editor, path) {
var _MyEditor$getLastVers;
const lastVerse = (_MyEditor$getLastVers = MyEditor.getLastVerse(editor, path)) === null || _MyEditor$getLastVers === void 0 ? void 0 : _MyEditor$getLastVers[0];
return _slate.Element.isElement(lastVerse) ? _slate.Node.string(lastVerse.children[0]) : undefined;
}
/**
* Get the slate path for a given DOMNode
*/
function getPathFromDOMNode(editor, domNode) {
const slateNode = _slateReact.ReactEditor.toSlateNode(editor, domNode);
return _slateReact.ReactEditor.findPath(editor, slateNode);
}
/**
* Gets the identification headers in json format
*/
function identification(editor) {
return (0, _identificationTransforms.parseIdentificationFromSlateTree)(editor);
}
/**
* Finds the path of a verse that matches the given chapter and
* verse numbers. A value of "0" indicates "front".
*/
function findVersePath(editor, chapterNum, verseNum) {
if (chapterNum == 0) {
console.warn("Book front matter navigation not implemented yet");
return undefined;
}
const verseStr = verseNum == 0 ? "front" : verseNum.toString();
const chapterNumMatch = node => _slate.Element.isAncestor(node) && node.children.some(chapterNumNode => _slate.Element.isElement(chapterNumNode) && chapterNumNode.type == _UsfmMarkers.UsfmMarkers.CHAPTERS_AND_VERSES.c && _slate.Node.string(chapterNumNode) == chapterNum.toString());
const verseNumMatch = node => _slate.Element.isAncestor(node) && node.children.some(verseNumNode => {
if (!_slate.Element.isElement(verseNumNode) || verseNumNode.type != _UsfmMarkers.UsfmMarkers.CHAPTERS_AND_VERSES.v) return false;
const thisVerseNumStr = _slate.Node.string(verseNumNode);
if (thisVerseNumStr == verseStr) return true;
const [thisStart, thisEndOrNull] = thisVerseNumStr.split("-");
const thisEnd = thisEndOrNull !== null && thisEndOrNull !== void 0 ? thisEndOrNull : thisStart;
return verseNum >= parseInt(thisStart) && verseNum <= parseInt(thisEnd);
});
const chapter = editor.children.find(chapterNumMatch);
if (!_slate.Element.isElement(chapter)) return undefined;
const chapterChildren = chapter.children;
const verse = chapterChildren.find(verseNumMatch);
if (!verse) return undefined;
const chapterIdx = editor.children.indexOf(chapter);
const verseIdx = chapterChildren.indexOf(verse);
return [chapterIdx, verseIdx];
}
function isChapterNode(node) {
return _slate.Element.isElement(node) && node.type == _NodeTypes.default.CHAPTER;
}
function isVerseNode(node) {
return _slate.Element.isElement(node) && node.type == _NodeTypes.default.VERSE;
}