UNPKG

@diplodoc/transform

Version:

A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML

214 lines (211 loc) 8.69 kB
"use strict"; (() => { // src/js/utils.ts var getEventTarget = (event) => { const path = event.composedPath(); return Array.isArray(path) && path.length > 0 ? path[0] : event.target; }; var isCustom = (event) => { const target = getEventTarget(event); return !target || !target.matches; }; // src/js/term/utils.ts var Selector = { TITLE: ".yfm .yfm-term_title", CONTENT: ".yfm .yfm-term_dfn" }; var openClass = "open"; var openDefinitionClass = Selector.CONTENT.replace(/\./g, "") + " " + openClass; var isListenerNeeded = true; function setDefinitionId(definitionElement, termElement) { const termId = termElement.getAttribute("id") || Math.random().toString(36).substr(2, 8); definitionElement == null ? void 0 : definitionElement.setAttribute("term-id", termId); } function setDefinitonAriaAttributes(definitionElement, termElement) { const ariaLive = termElement.getAttribute("aria-live") || "polite"; definitionElement == null ? void 0 : definitionElement.setAttribute("aria-live", ariaLive); definitionElement == null ? void 0 : definitionElement.setAttribute("aria-modal", "true"); } function setDefinitionPosition(definitionElement, termElement) { const { x: termX, y: termY, right: termRight, left: termLeft, width: termWidth, height: termHeight } = termElement.getBoundingClientRect(); const termParent = termParentElement(termElement); if (!termParent) { return; } const { right: termParentRight, left: termParentLeft } = termParent.getBoundingClientRect(); if ((termParentRight < termLeft || termParentLeft > termRight) && !isListenerNeeded) { closeDefinition(definitionElement); return; } if (isListenerNeeded && termParent) { termParent.addEventListener("scroll", termOnResize); isListenerNeeded = false; } const relativeX = Number(definitionElement.getAttribute("relativeX")); const relativeY = Number(definitionElement.getAttribute("relativeY")); if (relativeX === termX && relativeY === termY) { return; } definitionElement.setAttribute("relativeX", String(termX)); definitionElement.setAttribute("relativeY", String(termY)); const offsetTop = termHeight + 5; const definitionParent = definitionElement.parentElement; if (!definitionParent) { return; } const { width: definitionWidth } = definitionElement.getBoundingClientRect(); const { left: definitionParentLeft } = definitionParent.getBoundingClientRect(); const definitionLeftCoordinate = Number(getCoords(termElement).left); const definitionRightCoordinate = definitionWidth + definitionLeftCoordinate; const definitionOutOfScreenOnLeft = definitionLeftCoordinate - definitionWidth < 0; const definitionOutOfScreenOnRight = definitionRightCoordinate > document.body.clientWidth; const isAlignSwapped = definitionOutOfScreenOnRight || document.dir === "rtl"; const fitDefinitionDocument = isAlignSwapped && !definitionOutOfScreenOnLeft ? definitionWidth - termWidth : 0; const customHeaderTop = getCoords(definitionParent).top - definitionParent.offsetTop; const offsetRight = 5; const shiftLeft = definitionOutOfScreenOnRight ? definitionRightCoordinate - document.body.clientWidth + offsetRight : 0; const offsetLeft = getCoords(termElement).left - definitionParentLeft + definitionParent.offsetLeft - fitDefinitionDocument; const isShiftLeftNeeded = offsetLeft + definitionWidth >= document.body.clientWidth; definitionElement.style.top = Number(getCoords(termElement).top + offsetTop - customHeaderTop) + "px"; definitionElement.style.left = Number(offsetLeft - (isShiftLeftNeeded ? shiftLeft : 0)) + "px"; } function termOnResize() { const openedDefinition = document.getElementsByClassName(openDefinitionClass)[0]; if (!openedDefinition) { return; } const termId = openedDefinition.getAttribute("term-id") || ""; const termElement = document.getElementById(termId); if (!termElement) { return; } setDefinitionPosition(openedDefinition, termElement); } function termParentElement(term) { if (!term) { return null; } const closestScrollableParent = term.closest("table") || term.closest("code"); return closestScrollableParent || term.parentElement; } function openDefinition(target) { const openedDefinition = document.getElementsByClassName(openDefinitionClass)[0]; const termId = target.getAttribute("id"); const termKey = target.getAttribute("term-key"); const definitionElement = document.getElementById(termKey + "_element"); const isSameTerm = openedDefinition && termId === openedDefinition.getAttribute("term-id"); if (isSameTerm) { closeDefinition(openedDefinition); return; } const isTargetDefinitionContent = target.closest( [Selector.CONTENT.replace(" ", ""), openClass].join(".") ); if (openedDefinition && !isTargetDefinitionContent) { closeDefinition(openedDefinition); } if (!target.matches(Selector.TITLE) || !definitionElement) { return; } setDefinitionId(definitionElement, target); setDefinitonAriaAttributes(definitionElement, target); setDefinitionPosition(definitionElement, target); definitionElement.classList.toggle(openClass); trapFocus(definitionElement); } function closeDefinition(definition) { definition.classList.remove(openClass); const term = getTermByDefinition(definition); const termParent = termParentElement(term); if (!termParent) { return; } termParent.removeEventListener("scroll", termOnResize); isListenerNeeded = true; } function getCoords(elem) { const box = elem.getBoundingClientRect(); const body = document.body; const docEl = document.documentElement; const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; const clientTop = docEl.clientTop || body.clientTop || 0; const clientLeft = docEl.clientLeft || body.clientLeft || 0; const top = box.top + scrollTop - clientTop; const left = box.left + scrollLeft - clientLeft; return { top: Math.round(top), left: Math.round(left) }; } function trapFocus(element) { const focusableElements = element.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); const firstFocusableElement = focusableElements[0]; const lastFocusableElement = focusableElements[focusableElements.length - 1]; if (firstFocusableElement) { firstFocusableElement.focus(); } element.addEventListener("keydown", function(e) { const isTabPressed = e.key === "Tab" || e.keyCode === 9; if (!isTabPressed) { return; } if (e.shiftKey) { if (document.activeElement === firstFocusableElement) { lastFocusableElement.focus(); e.preventDefault(); } } else if (document.activeElement === lastFocusableElement) { firstFocusableElement.focus(); e.preventDefault(); } }); } function getTermByDefinition(definition) { const termId = definition.getAttribute("term-id"); return termId ? document.getElementById(termId) : null; } // src/js/term/index.ts if (typeof document !== "undefined") { document.addEventListener("click", (event) => { if (getEventTarget(event) || !isCustom(event)) { openDefinition(getEventTarget(event)); } }); document.addEventListener("keydown", (event) => { var _a; const openedDefinition = document.getElementsByClassName( openDefinitionClass )[0]; if (event.key === "Enter" && document.activeElement) { openDefinition(document.activeElement); } if (event.key === "Escape" && openedDefinition) { closeDefinition(openedDefinition); (_a = getTermByDefinition(openedDefinition)) == null ? void 0 : _a.focus(); } }); window.addEventListener("resize", () => { const openedDefinition = document.getElementsByClassName( openDefinitionClass )[0]; if (!openedDefinition) { return; } const termId = openedDefinition.getAttribute("term-id") || ""; const termElement = document.getElementById(termId); if (!termElement) { openedDefinition.classList.toggle(openClass); return; } setDefinitionPosition(openedDefinition, termElement); }); } })(); //# sourceMappingURL=_yfm-only.js.map