@diplodoc/transform
Version:
A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML
1,253 lines (1,235 loc) • 51.4 kB
JavaScript
"use strict";
(() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// node_modules/get-root-node-polyfill/index.js
var require_get_root_node_polyfill = __commonJS({
"node_modules/get-root-node-polyfill/index.js"(exports, module) {
"use strict";
function getRootNode2(opt) {
var composed = typeof opt === "object" && Boolean(opt.composed);
return composed ? getShadowIncludingRoot(this) : getRoot(this);
}
function getShadowIncludingRoot(node) {
var root = getRoot(node);
if (isShadowRoot(root)) {
return getShadowIncludingRoot(root.host);
}
return root;
}
function getRoot(node) {
if (node.parentNode != null) {
return getRoot(node.parentNode);
}
return node;
}
function isShadowRoot(node) {
return node.nodeName === "#document-fragment" && node.constructor.name === "ShadowRoot";
}
if (typeof module === "object" && module.exports) {
module.exports = getRootNode2;
}
}
});
// node_modules/@diplodoc/cut-extension/build/runtime/index.js
(() => {
var i = "yfm_cut";
var n = { Cut: "yfm-cut", Title: "yfm-cut-title", Content: "yfm-cut-content", Highlight: "yfm-cut-highlight" };
var c = class {
constructor() {
__publicField(this, "disposers", []);
this.disposers.push(this.init());
}
init() {
let e = false, o = () => {
e = true;
}, t = () => {
e = false;
}, I = (C) => {
u(C.target) && !e && this.focusActiveCut(C.target);
};
return document.addEventListener("mousedown", o), document.addEventListener("mouseup", t), document.addEventListener("focus", I, true), () => {
document.removeEventListener("mousedown", o), document.removeEventListener("mouseup", t), document.removeEventListener("focus", I, true);
};
}
dispose() {
for (let e of this.disposers) e();
}
focusActiveCut(e) {
let o = e.parentNode;
if (!s(o)) return;
let t = o;
for (; t; ) s(t) && (t.open = true), t = t.parentElement;
setTimeout(() => {
o.classList.add(n.Highlight);
}, 70), setTimeout(() => {
o.classList.remove(n.Highlight);
}, 1e3);
}
};
function s(g) {
var _a;
return ((_a = g == null ? void 0 : g.tagName) == null ? void 0 : _a.toLowerCase()) === "details" && (g == null ? void 0 : g.classList.contains(n.Cut));
}
function u(g) {
var _a;
return ((_a = g == null ? void 0 : g.tagName) == null ? void 0 : _a.toLowerCase()) === "summary" && (g == null ? void 0 : g.classList.contains(n.Title));
}
typeof window < "u" && !window[i] && (window[i] = new c());
})();
// node_modules/@diplodoc/tabs-extension/build/runtime/index.js
(() => {
var x = "yfm-tabs", H = "yfm-tab", O = "yfm-tab-panel", L = "yfm-tab-list", l = "active";
var T = "data-diplodoc-group", G = "data-diplodoc-key", y = "data-diplodoc-variant", S = "data-diplodoc-id", U = "defaultTabsGroup-";
var F = "data-diplodoc-forced";
var w = "yfm-tabs-dropdown-select";
var W = "yfm-tabs-vertical";
var v = ((g) => (g.Regular = "regular", g.Radio = "radio", g.Dropdown = "dropdown", g.Accordion = "accordion", g))(v || {}), Z = /* @__PURE__ */ Symbol.for("diplodocTabs");
var h = (C) => {
let t = C.composedPath();
return Array.isArray(t) && t.length > 0 ? t[0] : C.target;
}, X = (C) => {
let t = h(C);
return !t || !t.matches;
}, R = (C) => Math.abs(C.scrollHeight - C.clientHeight) > 1 ? C : C.parentElement ? R(C.parentElement) : void 0, Q = (C, t) => {
let e = C.getBoundingClientRect(), o = t.getBoundingClientRect();
return { top: e.top - o.top, left: e.left - o.left, scrollTop: t.scrollTop, scrollLeft: t.scrollLeft };
};
var n = { TABS: `.${x}`, TAB_LIST: `.${L}`, TAB: `.${H}`, TAB_PANEL: `.${O}`, VERTICAL_TABS: `.${W}` }, f = class {
constructor(t, e = {}) {
this._onSelectTabHandlers = /* @__PURE__ */ new Set();
this._currentPageTabGroups = [];
this._isRestoringTabs = false;
this._document = t, this._options = Object.assign({ saveTabsToLocalStorage: false, saveTabsToQueryStateMode: "none" }, e), this._document.addEventListener("click", (o) => {
let g = h(o);
if (o.target && this.hideAllDropdown(o.target), X(o)) return;
if (this.isElementDropdownSelect(g)) {
g.classList.toggle(l);
return;
}
if (!this.isValidTabElement(g)) return;
let I = this.getTabDataFromHTMLElement(g);
I && this._selectTab(I, g);
}), this._document.addEventListener("keydown", (o) => {
let g = null;
switch (o.key) {
case "ArrowLeft": {
g = "left";
break;
}
case "ArrowRight": {
g = "right";
break;
}
case "ArrowUp": {
g = "left";
break;
}
case "ArrowDown": {
g = "right";
break;
}
}
if (!g) return;
let I = h(o);
if (X(o) || !this.isValidTabElement(I)) return;
let { tabs: a, nodes: c } = this.getTabs(I), i = this.getTabDataFromHTMLElement(I), r = a.findIndex(({ key: A }) => (i == null ? void 0 : i.key) && A === i.key);
if (!i || a.length <= 1 || r === -1) return;
let s = (r + (g === "left" ? -1 : 1) + a.length) % a.length;
this.selectTab(a[s]), c[s].focus();
});
}
configure(t) {
this._options = Object.assign(this._options, t);
}
onSelectTab(t) {
return this._onSelectTabHandlers.add(t), () => {
this._onSelectTabHandlers.delete(t);
};
}
selectTabById(t, e) {
let o = this._document.querySelector(`${n.TAB}[${S}="${t}"]`);
if (!o || !this.isValidTabElement(o)) return;
let g = this.getTabDataFromHTMLElement(o);
g && this._selectTab(g, o), e != null && e.scrollToElement && o.scrollIntoView();
}
selectTab(t) {
this._selectTab(t);
}
restoreTabs(t) {
this._isRestoringTabs = true;
try {
for (let [e, o] of Object.entries(t)) if (e) {
let g = { group: e, ...o };
this.selectTab(g);
}
} finally {
this._isRestoringTabs = false;
}
}
getTabsFromLocalStorage() {
return JSON.parse(localStorage.getItem("tabsHistory") || "{}");
}
getTabsFromSearchQuery() {
let t = {}, e = new URLSearchParams(window.location.search);
return e.has("tabs") && (e.get("tabs") || "").split(",").forEach((I) => {
let a = I.split("_"), [c, i] = a, r = "regular";
if (a.length === 3 && (r = a[2]), c && i && Object.values(v).includes(r)) {
let s = i;
t[c] = { key: s, variant: r };
}
}), t;
}
updateLocalStorageWithTabs(t) {
this._options.saveTabsToLocalStorage && (this._isRestoringTabs || localStorage.setItem("tabsHistory", JSON.stringify(t)));
}
updateQueryParamWithTabs(t) {
if (this._isRestoringTabs) return;
let e = new URLSearchParams(window.location.search), o = Object.entries(t).map(([a, { key: c, variant: i }]) => i === "regular" ? `${a}_${c}` : `${a}_${c}_${i}`);
o.length > 0 ? e.set("tabs", o.join(",")) : e.delete("tabs");
let g = history.state || {}, I = new URL(window.location.href);
I.search = e.toString(), window.history.replaceState({ ...g }, document.title, I.href);
}
getCurrentPageTabHistory(t) {
return Object.fromEntries(Object.entries(t).filter(([e]) => this._currentPageTabGroups.includes(e)));
}
onPageChanged() {
this._currentPageTabGroups = this.getCurrentPageTabGroups();
}
getCurrentPageTabGroups() {
let t = this._document.getElementsByClassName(x), e = /* @__PURE__ */ new Set();
return Array.from(t).forEach((o) => {
let g = o.getAttribute(T);
g && e.add(g);
}), Array.from(e);
}
clearTabsPreferred() {
localStorage.removeItem("tabsHistory"), this.updateQueryParamWithTabs({});
}
_selectTab(t, e) {
let { group: o, key: g, variant: I } = t;
if (!o) return;
this.saveTabPreferred({ group: o, key: g, variant: I });
let a = e && R(e), c = a && Q(e, a);
this.updateHTML({ group: o, key: g, variant: I }, e, I) > 0 && (this.fireSelectTabEvent({ group: o, key: g, variant: I }, e == null ? void 0 : e.dataset.diplodocId), c && this.resetScroll(e, a, c));
}
updateHTML(t, e, o) {
switch (o) {
case "radio":
return this.updateHTMLRadio(t, e);
case "accordion":
return this.updateHTMLAccordion(t, e);
case "regular":
return this.updateHTMLRegular(t);
case "dropdown":
return this.updateHTMLDropdown(t);
default:
return 0;
}
}
saveTabPreferred(t) {
let e = {};
switch (this._options.saveTabsToLocalStorage && (e = JSON.parse(localStorage.getItem("tabsHistory") || "{}")), e[t.group] = { key: t.key, variant: t.variant }, this._options.saveTabsToLocalStorage && this.updateLocalStorageWithTabs(e), this._options.saveTabsToQueryStateMode) {
case "all": {
this.updateQueryParamWithTabs(e);
break;
}
case "page": {
this.updateQueryParamWithTabs(this.getCurrentPageTabHistory(e));
break;
}
}
}
updateHTMLRadio(t, e) {
let { group: o, key: g } = t, { isForced: I, root: a } = this.didTabOpenForce(e), c = I ? `.yfm-vertical-tab[${F}="true"]` : "", i = this._document.querySelectorAll(`${n.TABS}[${T}="${o}"] ${n.TAB}[${G}="${g}"]${c}`);
I && (a == null || a.removeAttribute(F));
let r = 0;
return i.forEach((s) => {
let m = s.parentNode.children;
for (let p = 0; p < m.length; p += 2) {
let [d, b] = [m.item(p), m.item(p + 1)], u = d.children.item(0);
if (d === s) {
u.checked ? (d.classList.remove("active"), b == null || b.classList.remove("active"), u.removeAttribute("checked")) : (d.classList.add("active"), b == null || b.classList.add("active"), u.setAttribute("checked", "true"));
continue;
}
u.hasAttribute("checked") && (d.classList.remove("active"), b == null || b.classList.remove("active"), u.removeAttribute("checked")), r++;
}
}), r;
}
updateHTMLRegular(t) {
let { group: e, key: o } = t, g = this._document.querySelectorAll(`${n.TABS}[${T}="${e}"] ${n.TAB}[${G}="${o}"]`), I = 0;
return g.forEach((a) => {
let c = a;
if (!this.isValidTabElement(c) || c.dataset.diplodocIsActive === "true") return;
I++;
let i = a, r = i.parentNode, s = r == null ? void 0 : r.parentNode, A = Array.from((r == null ? void 0 : r.querySelectorAll(n.TAB)) || []), m = Array.from((s == null ? void 0 : s.children) || []).filter((d) => d.classList.contains(O)), p = A.indexOf(i);
A.forEach((d, b) => {
let u = m[b], B = b === p, N = d;
N.dataset.diplodocIsActive = B ? "true" : "false", d.classList.toggle(l, B), d.setAttribute("aria-selected", B.toString()), d.setAttribute("tabindex", B ? "0" : "-1"), u.classList.toggle(l, B);
});
}), I;
}
updateHTMLDropdown(t) {
let { group: e, key: o } = t, g = this._document.querySelectorAll(`${n.TABS}[${T}="${e}"] ${n.TAB}[${G}="${o}"]`), I = 0;
return g.forEach((a) => {
let c = a.closest(`[${y}=dropdown]`);
if (!(c != null && c.children)) return;
let i = c.children.item(0), r = c.children.item(1);
i == null || i.classList.remove(l);
let s = Array.from((r == null ? void 0 : r.children) || []).indexOf(a) + 2;
for (let A = 2; A < c.children.length; A++) {
let m = c.children.item(A), p = r == null ? void 0 : r.children.item(A - 2);
if (I++, s === A) {
m == null || m.classList.add(l), p.classList.add(l), i.innerHTML = a.innerHTML, i.classList.add("filled");
continue;
}
p.classList.remove(l), m.classList.remove(l);
}
}), I;
}
updateHTMLAccordion(t, e) {
let { group: o, key: g } = t, I = this._document.querySelectorAll(`${n.TABS}[${T}="${o}"] ${n.TAB}[${G}="${g}"]`), a = 0;
return I.forEach((c) => {
let i = c.closest(`[${y}=accordion]`);
if (i != null && i.children) for (let r = 0; r < i.children.length; r += 2) {
let s = i.children.item(r), A = i.children.item(r + 1);
if (a++, c === s) {
s == null || s.classList.toggle(l), A == null || A.classList.toggle(l);
continue;
}
s == null || s.classList.remove(l), A == null || A.classList.remove(l);
}
}), e && !this.checkVisible(e) && setTimeout(() => {
e.scrollIntoView({ block: "nearest" });
}), a;
}
checkVisible(t) {
let e = t.getBoundingClientRect(), o = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(e.bottom < 0 || e.top - o >= 0);
}
hideAllDropdown(t) {
this._document.querySelectorAll(".yfm-tabs-dropdown-select.active").forEach((o) => {
o.contains(t) || o.classList.remove(l);
});
}
resetScroll(t, e, o) {
let g = Q(t, e), I = g.top - o.top, a = g.left - o.left, c = g.scrollTop - o.scrollTop, i = g.scrollLeft - o.scrollLeft;
e.scrollTo(e.scrollLeft + a - i, e.scrollTop + I - c);
}
didTabOpenForce(t) {
if (!t) return {};
if (t.dataset.diplodocForced) return { root: t, isForced: true };
let e = t.dataset.diplodocVerticalTab ? t : t.parentElement, o = typeof (e == null ? void 0 : e.dataset.diplodocForced) != "undefined";
return { root: e, isForced: o };
}
fireSelectTabEvent(t, e) {
let { group: o, key: g, variant: I } = t, a = o.startsWith(U) ? { key: g, variant: I } : t;
this._onSelectTabHandlers.forEach((c) => {
c({ tab: a, currentTabId: e });
});
}
getTabsType(t) {
let e = t.closest(`[${y}]`);
if (e) return e.dataset.diplodocVariant;
}
isValidTabElement(t) {
return !!this.getTabsType(t);
}
isElementDropdownSelect(t) {
return t.classList.contains(w);
}
getTabDataFromHTMLElement(t) {
var I, a, c;
let e = this.getTabsType(t);
if (e === "radio") {
let i = t.dataset.diplodocVerticalTab ? t : t.parentElement, r = i.dataset.diplodocKey, s = (I = i.closest(n.TABS)) == null ? void 0 : I.dataset.diplodocGroup;
return r && s ? { group: s, key: r, variant: "radio" } : null;
}
if (e === "dropdown" || e === "accordion") {
let i = t.dataset.diplodocKey, r = (a = t.closest(n.TABS)) == null ? void 0 : a.dataset.diplodocGroup;
return i && r ? { group: r, key: i, variant: e } : null;
}
let o = t.dataset.diplodocKey, g = (c = t.closest(n.TABS)) == null ? void 0 : c.dataset.diplodocGroup;
return o && g ? { group: g, key: o, variant: "regular" } : null;
}
getTabs(t) {
var I, a;
let e = (I = t.closest(n.TABS)) == null ? void 0 : I.dataset.diplodocGroup, o = (a = t.closest(n.TAB_LIST)) == null ? void 0 : a.querySelectorAll(n.TAB), g = [];
return o.forEach((c) => {
let i = c == null ? void 0 : c.dataset.diplodocKey;
i && g.push({ group: e, key: i, variant: "regular" });
}), { tabs: g, nodes: o };
}
};
typeof window != "undefined" && typeof document != "undefined" && !window[Z] && (window[Z] = new f(document));
})();
// src/js/polyfill.js
var import_get_root_node_polyfill = __toESM(require_get_root_node_polyfill());
if (typeof document !== "undefined") {
(function(e) {
const matches = e.matches || e.matchesSelector || e.webkitMatchesSelector || e.mozMatchesSelector || e.msMatchesSelector || e.oMatchesSelector;
if (matches) {
e.matches = e.matchesSelector = matches;
} else {
e.matches = e.matchesSelector = function matches2(selector) {
const rootNode = e.getRootNode ? e.getRootNode() : import_get_root_node_polyfill.default.call(e);
const matches3 = rootNode.querySelectorAll(selector);
const th = this;
return Array.prototype.some.call(matches3, (e2) => {
return e2 === th;
});
};
}
})(Element.prototype);
}
// 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;
};
var copyToClipboard = async (text) => {
if (!text) {
return;
}
if (navigator.clipboard && typeof navigator.clipboard.writeText) {
return navigator.clipboard.writeText(text);
}
const textarea = document.createElement("textarea");
textarea.setAttribute("style", "position: absolute; left: 1000%");
textarea.textContent = text;
document.body.append(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
};
// src/js/code.ts
var COPY_BUTTON_SELECTOR = ".yfm-clipboard-button";
var WRAP_BUTTON_SELECTOR = ".yfm-wrapping-button";
function notifySuccess(svgButton) {
if (!svgButton) {
return;
}
const id = svgButton.getAttribute("data-animation");
const icon = svgButton.getRootNode().getElementById(`visibileAnimation-${id}`);
if (!icon) {
return;
}
icon.beginElement();
}
function buttonCopyFn(target) {
var _a;
const container2 = (_a = target.parentNode) == null ? void 0 : _a.parentNode;
const code = container2 == null ? void 0 : container2.querySelector("pre code");
if (!container2 || !code) {
return;
}
const textContent = Array.from(code.childNodes).filter((node) => {
if (node instanceof HTMLElement && node.classList.contains("yfm-line-number")) {
return false;
}
return true;
}).map((node) => node.textContent).join("");
copyToClipboard(textContent.trim()).then(() => {
notifySuccess(container2.querySelector(".yfm-clipboard-icon"));
setTimeout(() => target.blur(), 1500);
});
}
function buttonWrapFn(target) {
var _a;
const container2 = (_a = target.parentNode) == null ? void 0 : _a.parentNode;
const code = container2 == null ? void 0 : container2.querySelector("pre code");
if (!container2 || !code) {
return;
}
code.classList.toggle("wrap");
setTimeout(() => target.blur(), 500);
}
if (typeof document !== "undefined") {
document.addEventListener("click", (event) => {
if (isCustom(event)) {
return;
}
const target = getEventTarget(event);
if (target.matches(COPY_BUTTON_SELECTOR)) {
buttonCopyFn(target);
} else if (target.matches(WRAP_BUTTON_SELECTOR)) {
buttonWrapFn(target);
}
});
}
// src/js/tooltip/constant.ts
var PAGE_CONTAINER_SELECTOR = ".dc-doc-page__content";
var TOOLTIP_BASE_CLASS = "yfm yfm-tooltip";
var TOOLTIP_OPEN_CLASS = "open";
var TOOLTIP_DATA_ATTR = "data-tooltip-id";
var DEFAULT_OFFSET_VALUES = { mainAxis: 5 };
var OPPOSITE_SIDES = {
top: "bottom",
bottom: "top",
left: "right",
right: "left"
};
var DEFAULT_SIDE_OBJECT = {
top: 0,
bottom: 0,
left: 0,
right: 0
};
// src/js/tooltip/utils.ts
function isVerticalSide(side) {
return side === "top" || side === "bottom";
}
function createSideObject(value = 0) {
if (typeof value === "number") {
return { top: value, bottom: value, left: value, right: value };
}
return { ...DEFAULT_SIDE_OBJECT, ...value };
}
function parsePlacement(placement) {
const [side, alignment] = placement.split("-");
return { side, alignment };
}
function getOppositeSide(side) {
return OPPOSITE_SIDES[side];
}
function flipPlacement(placement) {
const { side, alignment } = parsePlacement(placement);
const opposite = getOppositeSide(side);
return alignment ? `${opposite}-${alignment}` : opposite;
}
function getOverflow(tooltip3, coords, viewport) {
const rect = updateRect(tooltip3, { top: coords.y, left: coords.x });
return detectOverflow(viewport, rect, 5);
}
function shouldFlip(overflow, flippedOverflow, side) {
const opposite = getOppositeSide(side);
return overflow[side] > 0 && flippedOverflow[opposite] < overflow[side];
}
function computePosition(reference, tooltip3, viewport, placement, offset, isRtl, flip = true) {
const coords = computeCoordsFromPlacement(reference, tooltip3, offset, placement, isRtl);
if (!flip) {
return { coords, placement };
}
const overflow = getOverflow(tooltip3, coords, viewport);
const { side } = parsePlacement(placement);
if (overflow[side] <= 0) {
return { coords, placement };
}
const flipped = flipPlacement(placement);
const flippedCoords = computeCoordsFromPlacement(reference, tooltip3, offset, flipped, isRtl);
const flippedOverflow = getOverflow(tooltip3, flippedCoords, viewport);
if (shouldFlip(overflow, flippedOverflow, side)) {
return { coords: flippedCoords, placement: flipped };
}
return { coords, placement };
}
function generateId() {
const random = Math.random().toString(36).substring(2, 6);
const now = Date.now().toString(36);
return `${random}${now}`;
}
function createRect(params) {
return {
...params,
right: params.left + params.width,
bottom: params.top + params.height
};
}
function updateRect(rect, params) {
var _a, _b, _c, _d;
return createRect({
top: (_a = params.top) != null ? _a : rect.top,
left: (_b = params.left) != null ? _b : rect.left,
width: (_c = params.width) != null ? _c : rect.width,
height: (_d = params.height) != null ? _d : rect.height
});
}
function getViewportRect() {
const { documentElement, body } = document;
const scrollTop = window.scrollY || documentElement.scrollTop || body.scrollTop;
const scrollLeft = window.scrollX || documentElement.scrollLeft || body.scrollLeft;
const clientTop = documentElement.clientTop || body.clientTop || 0;
const clientLeft = documentElement.clientLeft || body.clientLeft || 0;
return createRect({
top: Math.round(scrollTop - clientTop),
left: Math.round(scrollLeft - clientLeft),
width: document.body.clientWidth,
height: document.body.clientHeight
});
}
function getElementRect(element) {
const viewport = getViewportRect();
const box = element.getBoundingClientRect();
return createRect({
top: Math.round(box.top + viewport.top),
left: Math.round(box.left + viewport.left),
width: box.width,
height: box.height
});
}
function computeAxisOffset(offset, side, isRtl) {
const { mainAxis = 0, crossAxis = 0 } = offset;
const isVertical = isVerticalSide(side);
const mainDirection = side === "top" || side === "left" ? -1 : 1;
const crossDirection = isRtl && isVertical ? -1 : 1;
const mainOffset = mainAxis * mainDirection;
const crossOffset = crossAxis * crossDirection;
if (isVertical) {
return { x: crossOffset, y: mainOffset };
}
return { x: mainOffset, y: crossOffset };
}
function computeCoordsFromPlacement(reference, tooltip3, offset, placement, isRtl) {
const { side, alignment } = parsePlacement(placement);
const isVertical = isVerticalSide(side);
const alignmentAxis = isVertical ? "x" : "y";
const alignLength = alignmentAxis === "y" ? "height" : "width";
const centerX = reference.left + reference.width / 2 - tooltip3.width / 2;
const centerY = reference.top + reference.height / 2 - tooltip3.height / 2;
const alignmentOffset = reference[alignLength] / 2 - tooltip3[alignLength] / 2;
const coords = { x: reference.left, y: reference.top };
switch (side) {
case "top": {
coords.x = centerX;
coords.y = reference.top - tooltip3.height;
break;
}
case "bottom": {
coords.x = centerX;
coords.y = reference.top + reference.height;
break;
}
case "right": {
coords.x = reference.left + reference.width;
coords.y = centerY;
break;
}
case "left": {
coords.x = reference.left - tooltip3.width;
coords.y = centerY;
break;
}
}
switch (alignment) {
case "start": {
coords[alignmentAxis] -= alignmentOffset * (isRtl && isVertical ? -1 : 1);
break;
}
case "end": {
coords[alignmentAxis] += alignmentOffset * (isRtl && isVertical ? -1 : 1);
break;
}
}
const axisOffset = computeAxisOffset(offset, side, isRtl);
coords.x += axisOffset.x;
coords.y += axisOffset.y;
return coords;
}
function convertToRelativeToOffsetParentRect(rect, offsetParent) {
const offsetRect = getElementRect(offsetParent);
return createRect({
top: rect.top - offsetRect.top + offsetParent.offsetTop,
left: rect.left - offsetRect.left + offsetParent.offsetLeft,
width: rect.width,
height: rect.height
});
}
function detectOverflow(boundary, element, padding = 0) {
const { top, bottom, left, right } = createSideObject(padding);
return {
top: boundary.top - element.top + top,
bottom: element.bottom - boundary.bottom + bottom,
left: boundary.left - element.left + left,
right: element.right - boundary.right + right
};
}
// src/js/tooltip/tooltip.ts
function createTooltipFactory(options = {}) {
const { closeDelay = 1e3, additionalClassName } = options;
let initialized = false;
const state = {
currentId: null,
timer: null,
unsubscribe: null
};
const getActiveTooltip = () => {
if (!state.currentId) {
return null;
}
return document.getElementById(state.currentId);
};
const getActiveReference = () => {
if (!state.currentId) {
return null;
}
return getReferenceByTooltipId(state.currentId);
};
const hide = () => {
const tooltip3 = getActiveTooltip();
if (state.timer) {
clearTimeout(state.timer);
state.timer = null;
}
if (state.unsubscribe) {
state.unsubscribe();
state.unsubscribe = null;
}
if (tooltip3) {
tooltip3.classList.remove(TOOLTIP_OPEN_CLASS);
detachTooltip(tooltip3);
state.currentId = null;
}
};
const show = (reference, text) => {
hide();
const tooltip3 = createTooltipElement({ text, className: additionalClassName });
const update = updateTooltipPosition.bind(null, options, reference, tooltip3);
state.currentId = tooltip3.id;
attachTooltip(tooltip3, reference);
state.unsubscribe = subscribeToScroll(reference, update);
tooltip3.classList.add(TOOLTIP_OPEN_CLASS);
update();
if (closeDelay > 0) {
state.timer = setTimeout(hide, closeDelay);
}
};
const handleUpdate = () => {
const activeTooltip = getActiveTooltip();
const activeReference = getActiveReference();
if (activeTooltip && !activeReference) {
hide();
return;
}
if (activeTooltip && activeReference) {
updateTooltipPosition(options, activeReference, activeTooltip);
}
};
const init = () => {
if (!initialized) {
initialized = true;
window.addEventListener("scroll", handleUpdate);
window.addEventListener("resize", handleUpdate);
}
};
const cleanup = () => {
if (initialized) {
initialized = false;
window.removeEventListener("scroll", handleUpdate);
window.removeEventListener("resize", handleUpdate);
}
};
return {
get visible() {
return Boolean(state.currentId);
},
getActiveReference,
show,
hide,
init,
cleanup
};
}
function createTooltipElement(options) {
const { text, className } = options;
const id = generateId();
const tooltip3 = document.createElement("div");
tooltip3.id = id;
tooltip3.className = className ? `${TOOLTIP_BASE_CLASS} ${className}` : TOOLTIP_BASE_CLASS;
tooltip3.setAttribute("role", "tooltip");
tooltip3.setAttribute("aria-live", "polite");
tooltip3.textContent = text;
return tooltip3;
}
function attachTooltip(tooltip3, reference) {
const container2 = document.querySelector(PAGE_CONTAINER_SELECTOR) || document.body;
const ariaLive = reference.getAttribute("aria-live");
reference.setAttribute(TOOLTIP_DATA_ATTR, tooltip3.id);
if (ariaLive) {
tooltip3.setAttribute("aria-live", ariaLive);
}
container2.appendChild(tooltip3);
}
function detachTooltip(tooltip3) {
if (tooltip3.id) {
const reference = getReferenceByTooltipId(tooltip3.id);
reference == null ? void 0 : reference.removeAttribute(TOOLTIP_DATA_ATTR);
}
tooltip3.remove();
}
function getReferenceByTooltipId(id) {
return document.querySelector(`[${TOOLTIP_DATA_ATTR}="${id}"]`);
}
function subscribeToScroll(reference, update) {
const scrollableElement = getParentScrollableElement(reference);
scrollableElement.addEventListener("scroll", update);
return () => {
scrollableElement.removeEventListener("scroll", update);
};
}
function getParentScrollableElement(target) {
const closestScrollableParent = target.closest("table") || target.closest("code");
return closestScrollableParent || target.parentElement || document.body;
}
function createTooltipContext(referenceElement, tooltipElement) {
const tooltipParent = tooltipElement.parentElement;
if (!tooltipParent) {
return null;
}
const elements = {
reference: referenceElement,
tooltip: tooltipElement,
offsetParent: tooltipParent
};
const viewport = getViewportRect();
const reference = getElementRect(referenceElement);
const { width, height } = tooltipElement.getBoundingClientRect();
return {
isRtl: document.dir === "rtl",
viewport,
reference,
tooltip: createRect({ top: 0, left: 0, width, height }),
elements
};
}
function updateTooltipPosition(options, referenceElement, tooltipElement) {
const context = createTooltipContext(referenceElement, tooltipElement);
if (!context) {
return;
}
const coords = getTooltipCoords(context, options);
tooltipElement.style.top = `${coords.y}px`;
tooltipElement.style.left = `${coords.x}px`;
}
function getTooltipCoords(context, options) {
const { placement = "bottom-start", offset = DEFAULT_OFFSET_VALUES, flip = true } = options;
const { reference, tooltip: tooltip3, viewport, isRtl } = context;
const { coords } = computePosition(reference, tooltip3, viewport, placement, offset, isRtl, flip);
const rect = updateRect(tooltip3, { top: coords.y, left: coords.x });
const relativeRect = convertToRelativeToOffsetParentRect(rect, context.elements.offsetParent);
return {
x: relativeRect.left,
y: relativeRect.top
};
}
// src/js/constant.ts
var COPIED_LANG_TOKEN = {
ru: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u043E",
en: "Copied",
ar: "\u062A\u0645 \u0627\u0644\u0646\u0633\u062E",
cs: "Zkop\xEDrov\xE1no",
fr: "Copi\xE9",
es: "Copiado",
he: "\u05D4\u05D5\u05E2\u05EA\u05E7",
bg: "\u041A\u043E\u043F\u0438\u0440\u0430\u043D\u043E",
et: "Kopeeritud",
el: "\u0391\u03BD\u03C4\u03B9\u03B3\u03C1\u03AC\u03C6\u03B7\u03BA\u03B5",
pt: "Copiado",
zh: "\u5DF2\u590D\u5236",
"zh-tw": "\u5DF2\u8907\u88FD",
kk: "\u041A\u04E9\u0448\u0456\u0440\u0456\u043B\u0434\u0456",
tr: "Kopyaland\u0131",
uz: "Nusxalandi"
};
// src/js/anchor.ts
var ALLOWED_PROTOCOL_RE = /^(?:https?|file):$/;
var ANCHOR_BUTTON_SELECTOR = ".yfm-clipboard-anchor";
var tooltip = createTooltipFactory();
function getLink(target) {
const href = target.nodeName === "A" ? target.href : target.dataset.href;
const link = new URL(href || "", window.location.href);
if (ALLOWED_PROTOCOL_RE.test(link.protocol)) {
return link.href;
}
return window.location.href;
}
if (typeof document !== "undefined") {
tooltip.init();
document.addEventListener("click", (event) => {
const target = getEventTarget(event);
if (isCustom(event) || !target.matches(ANCHOR_BUTTON_SELECTOR)) {
return;
}
const link = getLink(target);
copyToClipboard(link).then(() => {
var _a;
const lang = document.documentElement.lang || "en";
const tooltipText = (_a = COPIED_LANG_TOKEN[lang]) != null ? _a : COPIED_LANG_TOKEN.en;
tooltip.show(target, tooltipText);
});
});
}
// src/js/inline-code/index.ts
var CLASS_INLINE_CODE = "yfm-clipboard-inline-code";
var INLINE_CODE = `.${CLASS_INLINE_CODE}`;
var tooltip2 = createTooltipFactory({
// NOTE: Add additional className for backward capability
additionalClassName: "inline_code_tooltip"
});
function inlineCopyFn(target) {
const innerText = target.innerText;
if (!innerText) {
return;
}
copyToClipboard(innerText).then(() => {
var _a;
const lang = document.documentElement.lang || "en";
const tooltipText = (_a = COPIED_LANG_TOKEN[lang]) != null ? _a : COPIED_LANG_TOKEN.en;
tooltip2.show(target, tooltipText);
});
}
if (typeof document !== "undefined") {
tooltip2.init();
document.addEventListener("click", (event) => {
const target = getEventTarget(event);
const inline = target.matches(INLINE_CODE);
if (isCustom(event) || !inline) {
return;
}
inlineCopyFn(target);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Enter" && document.activeElement) {
const activeElement = document.activeElement;
if (!activeElement.classList.contains(CLASS_INLINE_CODE)) {
return;
}
inlineCopyFn(activeElement);
}
if (event.key === "Escape" && tooltip2.visible) {
const reference = tooltip2.getActiveReference();
tooltip2.hide();
reference == null ? void 0 : reference.focus();
}
});
}
// 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 definitionId = `${termKey}_element`;
const isInModal = target.closest(".wide-container");
let definitionElement;
if (isInModal) {
const modalContent = target.closest(".wide-content");
if (!modalContent) {
return;
}
definitionElement = modalContent.querySelector(`[id="${definitionId}"]`);
} else {
definitionElement = document.getElementById(definitionId);
}
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");
if (!termId) {
return null;
}
const isInModal = definition.closest(".wide-container");
if (isInModal) {
const modalContent = definition.closest(".wide-content");
if (!modalContent) {
return null;
}
return modalContent.querySelector(`[id="${termId}"]`);
}
return document.getElementById(termId);
}
// 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);
});
}
// src/js/wide-mode/constants.ts
var WIDE_ELEMENTS_SELECTOR = "[wide-content]";
// src/js/wide-mode/icons/expand.ts
var expand_default = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M7.754 2.004a.75.75 0 0 0 0 1.5h4.75v4.742a.75.75 0 0 0 1.5 0V2.754a.75.75 0 0 0-.75-.75zm.492 11.992a.75.75 0 0 0 0-1.5h-4.75V7.754a.75.75 0 0 0-1.5 0v5.492a.75.75 0 0 0 .75.75z" clip-rule="evenodd"/></svg>`;
// src/js/wide-mode/icons/close.ts
var close_default = `<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg" class="close-action"><path fillRule="evenodd" clipRule="evenodd" d="M9.46967 9.46967C9.76256 9.17678 10.2374 9.17678 10.5303 9.46967L14 12.9393L17.4697 9.46967C17.7626 9.17678 18.2374 9.17678 18.5303 9.46967C18.8232 9.76256 18.8232 10.2374 18.5303 10.5303L15.0607 14L18.5303 17.4697C18.8232 17.7626 18.8232 18.2374 18.5303 18.5303C18.2374 18.8232 17.7626 18.8232 17.4697 18.5303L14 15.0607L10.5303 18.5303C10.2374 18.8232 9.76256 18.8232 9.46967 18.5303C9.17678 18.2374 9.17678 17.7626 9.46967 17.4697L12.9393 14L9.46967 10.5303C9.17678 10.2374 9.17678 9.76256 9.46967 9.46967Z" fill="var(--g-color-text-primary)" fillOpacity="0.85"/></svg>`;
// src/js/wide-mode/modal.ts
var remove = () => {
if (!window.wideTemplate) {
return;
}
window.wideTemplate.style.display = "none";
window.wideTemplate.content(void 0);
};
var tbodyOf = (node) => {
if (node.tagName !== "TABLE") {
return void 0;
}
const elements = Array.from(node.children);
const thead = elements.find((child) => child.tagName === "THEAD");
if (thead) {
return void 0;
}
const tbody = elements.find((child) => child.tagName === "TBODY");
return tbody;
};
var container = () => {
if (window.wideTemplate) {
return window.wideTemplate;
}
const template = document.createElement("div");
template.classList.add("dc-doc-page", "wide-container");
const overlay = document.createElement("div");
overlay.classList.add("wide-content-overlay");
overlay.addEventListener("click", remove);
const wrapper = document.createElement("div");
wrapper.classList.add("yfm", "wide-content-wrapper");
const toolbar = document.createElement("div");
toolbar.classList.add("wide-toolbar");
const close = document.createElement("div");
close.classList.add("wide-actions");
close.addEventListener("click", remove);
close.innerHTML = close_default;
const title = document.createElement("p");
title.classList.add("wide-entity-name");
template.label = (content2) => {
title.innerHTML = content2 || "";
};
const content = document.createElement("div");
content.classList.add("wide-content");
template.content = (target) => {
var _a;
if (typeof target === "undefined") {
content.innerHTML = "";
return;
}
const cloned = target.cloneNode(true);
const tbody = tbodyOf(cloned);
(_a = tbody == null ? void 0 : tbody.classList) == null ? void 0 : _a.add("wide-thead-content");
const termTitles = cloned.querySelectorAll(".yfm-term_title");
const termDefinitions = [];
termTitles.forEach((termTitle) => {
const termKey = termTitle.getAttribute("term-key");
if (termKey) {
const originalDefinition = document.getElementById(termKey + "_element");
if (originalDefinition) {
const clonedDefinition = originalDefinition.cloneNode(true);
termDefinitions.push(clonedDefinition);
}
}
});
content.replaceChildren(cloned, ...termDefinitions);
};
toolbar.append(title, close);
wrapper.append(toolbar, content);
template.append(overlay, wrapper);
template.style.display = "none";
document.body.appendChild(template);
window.wideTemplate = template;
return template;
};
var render = (conten