usfm-editor
Version:
A WYSIWYG editor component for USFM
123 lines (93 loc) • 3.63 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withNormalize = void 0;
var _slate = require("slate");
var _NodeTypes = _interopRequireDefault(require("../utils/NodeTypes"));
var _basicSlateNodeFactory = require("../transforms/basicSlateNodeFactory");
var _UsfmMarkers = require("../utils/UsfmMarkers");
var _NodeRules = _interopRequireDefault(require("../utils/NodeRules"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const withNormalize = editor => {
const {
normalizeNode
} = editor;
editor.normalizeNode = entry => {
customNormalizeNode(editor, entry);
return normalizeNode(entry);
};
return editor;
};
exports.withNormalize = withNormalize;
const customNormalizeNode = (editor, entry) => {
const [node] = entry;
if (_slate.Element.isElement(node) && node.type === _NodeTypes.default.VERSE) {
const modified = addInlineContainerIfMissing(editor, entry);
if (modified) return;
transformExcessInlineContainers(editor, entry);
}
};
/**
* Each verse should only contain one inline container, at index 1.
* Extra inline containers should be handled according to the preceding
* block node.
*/
function transformExcessInlineContainers(editor, verseNodeEntry) {
const [verse, versePath] = verseNodeEntry;
if (!_slate.Element.isElement(verse)) return; // Search the verse for inline containers
for (let i = verse.children.length - 1; i > 0; i--) {
const child = verse.children[i];
if (!_slate.Element.isElement(child) || child.type !== _NodeTypes.default.INLINE_CONTAINER) {
continue;
}
const path = versePath.concat(i);
const prevChild = verse.children[i - 1];
if (_slate.Element.isElement(prevChild) && _NodeRules.default.canMergeAIntoB(_NodeTypes.default.INLINE_CONTAINER, prevChild.type)) {
mergeAndAssumePreviousNodeType(editor, path);
} else if (i > 1) {
setToParagraphType(editor, path);
}
}
}
function mergeAndAssumePreviousNodeType(editor, path) {
const prevChild = _slate.Editor.node(editor, _slate.Path.previous(path))[0];
_slate.Editor.withoutNormalizing(editor, () => {
_slate.Transforms.mergeNodes(editor, {
at: path
});
_slate.Transforms.setNodes(editor, {
type: prevChild.type
}, {
at: _slate.Path.previous(path)
});
});
}
function setToParagraphType(editor, path) {
_slate.Transforms.setNodes(editor, {
type: _UsfmMarkers.UsfmMarkers.PARAGRAPHS.p
}, {
at: path
});
}
/**
* If a verse node has a verseNumber (this will be the first child),
* then the second child node of the verse must be an inline container.
* There may not be a verseNumber if there is a pending transformation, such as
* a verse join.
* @returns true if an inline container was added.
*/
function addInlineContainerIfMissing(editor, verseNodeEntry) {
const [node, path] = verseNodeEntry;
if (nodeHasVerseNumberButMissingInlineContainer(node)) {
const inlineContainer = (0, _basicSlateNodeFactory.emptyInlineContainer)();
_slate.Transforms.insertNodes(editor, inlineContainer, {
at: path.concat(1)
});
return true;
}
return false;
}
function nodeHasVerseNumberButMissingInlineContainer(node) {
return _slate.Element.isElement(node) && node.children.length > 0 && _slate.Element.isElement(node.children[0]) && node.children[0].type === _UsfmMarkers.UsfmMarkers.CHAPTERS_AND_VERSES.v && (node.children.length < 2 || !_slate.Element.isElement(node.children[1]) || node.children[1].type != _NodeTypes.default.INLINE_CONTAINER);
}