Добавлены функции для аннотирования ссылок и улучшения стилей заголовков в документации
This commit is contained in:
@@ -185,6 +185,99 @@ const topLinks = [
|
||||
});
|
||||
};
|
||||
|
||||
const trimDestination = (value, maxLength = 42) => {
|
||||
if (value.length <= maxLength) return value;
|
||||
return `${value.slice(0, Math.max(0, maxLength - 1))}…`;
|
||||
};
|
||||
|
||||
const decodePath = (value) => {
|
||||
try {
|
||||
return decodeURIComponent(value);
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
const annotateLinkDestinations = () => {
|
||||
const links = document.querySelectorAll('a[href]');
|
||||
|
||||
links.forEach((linkNode) => {
|
||||
if (!(linkNode instanceof HTMLAnchorElement)) return;
|
||||
if (linkNode.dataset.linkAnnotated === 'true') return;
|
||||
|
||||
const rawHref = linkNode.getAttribute('href')?.trim();
|
||||
if (!rawHref || rawHref.toLowerCase().startsWith('javascript:')) return;
|
||||
|
||||
let parsedUrl;
|
||||
try {
|
||||
parsedUrl = new URL(rawHref, window.location.href);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
const isHashOnly = rawHref.startsWith('#');
|
||||
const isHttp = parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
|
||||
const isMail = parsedUrl.protocol === 'mailto:';
|
||||
const isTel = parsedUrl.protocol === 'tel:';
|
||||
const isExternal = isHttp && parsedUrl.origin !== window.location.origin;
|
||||
const isSamePageAnchor =
|
||||
!isExternal && !!parsedUrl.hash && parsedUrl.pathname === window.location.pathname;
|
||||
|
||||
const isContentLink = linkNode.closest('.sl-markdown-content') instanceof HTMLElement;
|
||||
const shouldDecorate =
|
||||
isContentLink &&
|
||||
!isHashOnly &&
|
||||
!linkNode.classList.contains('sl-anchor-link') &&
|
||||
!linkNode.classList.contains('map-cta-button') &&
|
||||
!linkNode.classList.contains('map-ghost-button') &&
|
||||
!linkNode.classList.contains('sl-link-button');
|
||||
|
||||
if (shouldDecorate) {
|
||||
let kind = 'internal';
|
||||
if (isExternal) kind = 'external';
|
||||
else if (isMail) kind = 'mail';
|
||||
else if (isTel) kind = 'tel';
|
||||
else if (isSamePageAnchor) kind = 'anchor';
|
||||
linkNode.dataset.linkKind = kind;
|
||||
|
||||
let destination = '';
|
||||
if (isExternal) destination = parsedUrl.hostname.replace(/^www\./, '');
|
||||
else if (isMail) destination = rawHref.replace(/^mailto:/i, '');
|
||||
else if (isTel) destination = rawHref.replace(/^tel:/i, '');
|
||||
else destination = `${decodePath(parsedUrl.pathname)}${parsedUrl.hash || ''}`;
|
||||
if (destination) {
|
||||
linkNode.dataset.linkDestination = trimDestination(destination);
|
||||
}
|
||||
}
|
||||
|
||||
if (isExternal) {
|
||||
const relValues = new Set((linkNode.rel || '').split(/\s+/).filter(Boolean));
|
||||
relValues.add('noopener');
|
||||
relValues.add('noreferrer');
|
||||
linkNode.rel = Array.from(relValues).join(' ');
|
||||
if (!linkNode.target) {
|
||||
linkNode.target = '_blank';
|
||||
}
|
||||
}
|
||||
|
||||
if (!linkNode.title) {
|
||||
if (isHashOnly || isSamePageAnchor) {
|
||||
linkNode.title = `Переход к разделу: ${parsedUrl.hash || rawHref}`;
|
||||
} else if (isExternal) {
|
||||
linkNode.title = `Внешняя ссылка: ${parsedUrl.hostname.replace(/^www\./, '')}`;
|
||||
} else if (isMail) {
|
||||
linkNode.title = `Написать: ${rawHref.replace(/^mailto:/i, '')}`;
|
||||
} else if (isTel) {
|
||||
linkNode.title = `Позвонить: ${rawHref.replace(/^tel:/i, '')}`;
|
||||
} else {
|
||||
linkNode.title = `Перейти: ${decodePath(parsedUrl.pathname)}${parsedUrl.hash || ''}`;
|
||||
}
|
||||
}
|
||||
|
||||
linkNode.dataset.linkAnnotated = 'true';
|
||||
});
|
||||
};
|
||||
|
||||
const copyTextToClipboard = async (value) => {
|
||||
if (navigator.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(value);
|
||||
@@ -312,6 +405,7 @@ const topLinks = [
|
||||
sanitizeNavLabels();
|
||||
sanitizeDocHeadings();
|
||||
decorateSectionIcons();
|
||||
annotateLinkDestinations();
|
||||
bindCopyIpChips();
|
||||
setReadProgress();
|
||||
window.addEventListener('scroll', setReadProgress, { passive: true });
|
||||
@@ -329,6 +423,7 @@ const topLinks = [
|
||||
sanitizeNavLabels();
|
||||
sanitizeDocHeadings();
|
||||
decorateSectionIcons();
|
||||
annotateLinkDestinations();
|
||||
bindCopyIpChips();
|
||||
setReadProgress();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user