vditor
Version:
♏ 易于使用的 Markdown 编辑器,为适配不同的应用场景而生
155 lines (143 loc) • 4.68 kB
text/typescript
import {hasClosestByTag} from "./hasClosestByHeadings";
export const hasTopClosestByClassName = (element: Node, className: string) => {
let closest = hasClosestByClassName(element, className);
let parentClosest: boolean | HTMLElement = false;
let findTop = false;
while (closest && !closest.classList.contains("vditor-reset") && !findTop) {
parentClosest = hasClosestByClassName(closest.parentElement, className);
if (parentClosest) {
closest = parentClosest;
} else {
findTop = true;
}
}
return closest || false;
};
export const hasTopClosestByAttribute = (element: Node, attr: string, value: string) => {
let closest = hasClosestByAttribute(element, attr, value);
let parentClosest: boolean | HTMLElement = false;
let findTop = false;
while (closest && !closest.classList.contains("vditor-reset") && !findTop) {
parentClosest = hasClosestByAttribute(closest.parentElement, attr, value);
if (parentClosest) {
closest = parentClosest;
} else {
findTop = true;
}
}
return closest || false;
};
export const hasTopClosestByTag = (element: Node, nodeName: string) => {
let closest = hasClosestByTag(element, nodeName);
let parentClosest: boolean | HTMLElement = false;
let findTop = false;
while (closest && !closest.classList.contains("vditor-reset") && !findTop) {
parentClosest = hasClosestByTag(closest.parentElement, nodeName);
if (parentClosest) {
closest = parentClosest;
} else {
findTop = true;
}
}
return closest || false;
};
export const getTopList = (element: Node) => {
const topUlElement = hasTopClosestByTag(element, "UL");
const topOlElement = hasTopClosestByTag(element, "OL");
let topListElement = topUlElement;
if (topOlElement && (!topUlElement || (topUlElement && topOlElement.contains(topUlElement)))) {
topListElement = topOlElement;
}
return topListElement;
};
export const hasClosestByAttribute = (element: Node, attr: string, value: string) => {
if (!element) {
return false;
}
if (element.nodeType === 3) {
element = element.parentElement;
}
let e = element as HTMLElement;
let isClosest = false;
while (e && !isClosest && !e.classList.contains("vditor-reset")) {
if (e.getAttribute(attr) === value) {
isClosest = true;
} else {
e = e.parentElement;
}
}
return isClosest && e;
};
export const hasClosestBlock = (element: Node) => {
if (!element) {
return false;
}
if (element.nodeType === 3) {
element = element.parentElement;
}
let e = element as HTMLElement;
let isClosest = false;
const blockElement = hasClosestByAttribute(element as HTMLElement, "data-block", "0");
if (blockElement) {
return blockElement;
}
while (e && !isClosest && !e.classList.contains("vditor-reset")) {
if (e.tagName === "H1" ||
e.tagName === "H2" ||
e.tagName === "H3" ||
e.tagName === "H4" ||
e.tagName === "H5" ||
e.tagName === "H6" ||
e.tagName === "P" ||
e.tagName === "BLOCKQUOTE" ||
e.tagName === "OL" ||
e.tagName === "UL") {
isClosest = true;
} else {
e = e.parentElement;
}
}
return isClosest && e;
};
export const hasClosestByMatchTag = (element: Node, nodeName: string) => {
if (!element) {
return false;
}
if (element.nodeType === 3) {
element = element.parentElement;
}
let e = element as HTMLElement;
let isClosest = false;
while (e && !isClosest && !e.classList.contains("vditor-reset")) {
if (e.nodeName === nodeName) {
isClosest = true;
} else {
e = e.parentElement;
}
}
return isClosest && e;
};
export const hasClosestByClassName = (element: Node, className: string) => {
if (!element) {
return false;
}
if (element.nodeType === 3) {
element = element.parentElement;
}
let e = element as HTMLElement;
let isClosest = false;
while (e && !isClosest && !e.classList.contains("vditor-reset")) {
if (e.classList.contains(className)) {
isClosest = true;
} else {
e = e.parentElement;
}
}
return isClosest && e;
};
export const getLastNode = (node: Node) => {
while (node && node.lastChild) {
node = node.lastChild;
}
return node;
};