A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 131 lines 4.4 kB view raw
1export const hasTopClosestByClassName = (element: Node, className: string, top = false) => { 2 let closest = hasClosestByClassName(element, className, top); 3 let parentClosest: boolean | HTMLElement = false; 4 let findTop = false; 5 while (closest && (top ? closest.tagName !== "BODY" : !closest.classList.contains("protyle-wysiwyg")) && !findTop) { 6 parentClosest = hasClosestByClassName(closest.parentElement, className, top); 7 if (parentClosest) { 8 closest = parentClosest; 9 } else { 10 findTop = true; 11 } 12 } 13 return closest || false; 14}; 15 16export const hasTopClosestByTag = (element: Node, nodeName: string) => { 17 let closest = hasClosestByTag(element, nodeName); 18 let parentClosest: boolean | HTMLElement = false; 19 let findTop = false; 20 while (closest && !closest.classList.contains("protyle-wysiwyg") && !findTop) { 21 parentClosest = hasClosestByTag(closest.parentElement, nodeName); 22 if (parentClosest) { 23 closest = parentClosest; 24 } else { 25 findTop = true; 26 } 27 } 28 return closest || false; 29}; 30 31export const hasTopClosestByAttribute = (element: Node, attr: string, value: string | null, top = false) => { 32 let closest = hasClosestByAttribute(element, attr, value, top); 33 let parentClosest: boolean | HTMLElement = false; 34 let findTop = false; 35 while (closest && !closest.classList.contains("protyle-wysiwyg") && !findTop) { 36 parentClosest = hasClosestByAttribute(closest.parentElement, attr, value, top); 37 if (parentClosest) { 38 closest = parentClosest; 39 } else { 40 findTop = true; 41 } 42 } 43 return closest || false; 44}; 45 46export const hasClosestByAttribute = (element: Node, attr: string, value: string | null, top = false) => { 47 if (!element || element.nodeType === 9) { 48 return false; 49 } 50 if (element.nodeType === 3) { 51 element = element.parentElement; 52 } 53 let e = element as HTMLElement; 54 let isClosest = false; 55 while (e && !isClosest && (top ? e.tagName !== "BODY" : !e.classList.contains("protyle-wysiwyg"))) { 56 if (typeof value === "string" && e.getAttribute(attr)?.split(" ").includes(value)) { 57 isClosest = true; 58 } else if (typeof value !== "string" && e.hasAttribute(attr)) { 59 isClosest = true; 60 } else { 61 e = e.parentElement; 62 } 63 } 64 return isClosest && e; 65}; 66 67export const hasClosestByTag = (element: Node, nodeName: string) => { 68 if (!element || element.nodeType === 9) { 69 return false; 70 } 71 if (element.nodeType === 3) { 72 element = element.parentElement; 73 } 74 let e = element as HTMLElement; 75 let isClosest = false; 76 while (e && !isClosest && !e.classList.contains("protyle-wysiwyg")) { 77 if (e.nodeName === nodeName) { 78 isClosest = true; 79 } else { 80 e = e.parentElement; 81 } 82 } 83 return isClosest && e; 84}; 85 86export const hasClosestByClassName = (element: Node, className: string, top = false) => { 87 if (!element || element.nodeType === 9) { 88 return false; 89 } 90 if (element.nodeType === 3) { 91 element = element.parentElement; 92 } 93 let e = element as HTMLElement; 94 let isClosest = false; 95 while (e && !isClosest && (top ? e.tagName !== "BODY" : !e.classList.contains("protyle-wysiwyg"))) { 96 if (e.classList?.contains(className)) { 97 isClosest = true; 98 } else { 99 e = e.parentElement; 100 } 101 } 102 return isClosest && e; 103}; 104 105export const hasClosestBlock = (element: Node) => { 106 const nodeElement = hasClosestByAttribute(element, "data-node-id", null); 107 if (nodeElement && nodeElement.tagName !== "BUTTON" && nodeElement.getAttribute("data-type")?.startsWith("Node")) { 108 return nodeElement; 109 } 110 return false; 111}; 112 113export const isInEmbedBlock = (element: Element) => { 114 const embedElement = hasTopClosestByAttribute(element, "data-type", "NodeBlockQueryEmbed"); 115 if (embedElement) { 116 if (embedElement === element) { 117 return false; 118 } else { 119 return embedElement; 120 } 121 } else { 122 return false; 123 } 124}; 125 126export const isInAVBlock = (element: Element) => { 127 if (hasClosestByClassName(element, "av__gallery-cover")) { 128 return hasClosestByClassName(element, "av"); 129 } 130 return false; 131};