anki/ts/editor/helpers.ts

98 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-04-13 10:57:08 +02:00
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
2021-02-09 04:38:04 +01:00
2021-06-18 02:44:15 +02:00
/* eslint
@typescript-eslint/no-non-null-assertion: "off",
*/
2021-01-30 17:54:07 +01:00
export function nodeIsElement(node: Node): node is Element {
return node.nodeType === Node.ELEMENT_NODE;
}
2021-08-31 16:56:03 +02:00
// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
const BLOCK_TAGS = [
"ADDRESS",
"ARTICLE",
"ASIDE",
"BLOCKQUOTE",
"DETAILS",
"DIALOG",
"DD",
"DIV",
"DL",
"DT",
"FIELDSET",
"FIGCAPTION",
"FIGURE",
"FOOTER",
"FORM",
"H1",
"H2",
"H3",
"H4",
"H5",
"H6",
"HEADER",
"HGROUP",
"HR",
"LI",
"MAIN",
"NAV",
"OL",
"P",
"PRE",
"SECTION",
"TABLE",
"UL",
2021-01-30 17:54:07 +01:00
];
export function elementIsBlock(element: Element): boolean {
return BLOCK_TAGS.includes(element.tagName);
2021-01-30 17:54:07 +01:00
}
export function caretToEnd(node: Node): void {
const range = document.createRange();
range.selectNodeContents(node);
range.collapse(false);
const selection = (node.getRootNode() as Document | ShadowRoot).getSelection()!;
selection.removeAllRanges();
selection.addRange(range);
}
const getAnchorParent =
<T extends Element>(predicate: (element: Element) => element is T) =>
(currentField: DocumentOrShadowRoot): T | null => {
const anchor = currentField.getSelection()?.anchorNode;
if (!anchor) {
return null;
}
let anchorParent: T | null = null;
let element = nodeIsElement(anchor) ? anchor : anchor.parentElement;
while (element) {
anchorParent = anchorParent || (predicate(element) ? element : null);
element = element.parentElement;
}
return anchorParent;
};
const isListItem = (element: Element): element is HTMLLIElement =>
window.getComputedStyle(element).display === "list-item";
const isParagraph = (element: Element): element is HTMLParamElement =>
element.tagName === "P";
const isBlockElement = (
element: Element
): element is HTMLLIElement & HTMLParamElement =>
2021-04-21 14:40:16 +02:00
isListItem(element) || isParagraph(element);
export const getListItem = getAnchorParent(isListItem);
export const getParagraph = getAnchorParent(isParagraph);
export const getBlockElement = getAnchorParent(isBlockElement);
export function appendInParentheses(text: string, appendix: string): string {
return `${text} (${appendix})`;
}