diff --git a/static/css/styles.css b/static/css/styles.css
index c2540e67a..34a9800dd 100644
--- a/static/css/styles.css
+++ b/static/css/styles.css
@@ -4386,7 +4386,7 @@ html.dark-theme body main .feedback-wrapper .feedback-modal a {
text-decoration: none;
}
-.documentation h1:hover > a.anchor-link, .documentation h2:hover > a.anchor-link, .documentation h3:hover > a.anchor-link, .documentation h4:hover > a.anchor-link {
+.documentation h1:hover > a.anchor-link, .documentation h2:hover > a.anchor-link, .documentation h3:hover > a.anchor-link, .documentation h4:hover > a.anchor-link, .documentation tr:hover > a.anchor-link {
opacity: 1;
}
@@ -4398,6 +4398,14 @@ html.dark-theme body main .feedback-wrapper .feedback-modal a {
content: none;
}
+.documentation tr {
+ overflow-x: hidden;
+}
+
+.documentation tr a.anchor-link {
+ position: absolute;
+}
+
.documentation aside.menu {
padding-bottom: 7.5rem;
}
diff --git a/static/js/main.js b/static/js/main.js
index fa3786fe3..a3844e823 100644
--- a/static/js/main.js
+++ b/static/js/main.js
@@ -1107,26 +1107,42 @@ const addCopyButtons = (clipboard)=>{
pre.appendChild(button);
});
};
-const addAnchorLinks = ()=>{
- document.querySelectorAll(".content h1, .content h2, .content h3, .content h4").forEach((heading)=>{
- let id = heading.innerText.toLowerCase().replace(/[`~!@#$%^&*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, "").replace(/ +/g, "-");
- heading.setAttribute("id", id);
- heading.classList.add("heading-anchor");
- let anchor = document.createElement("a");
- anchor.className = "anchor-link";
- anchor.href = "#" + id;
- anchor.innerHTML = '';
- heading.append(anchor);
- anchor.addEventListener("click", (e)=>{
+const addAnchorLinks = () => {
+ const elementsToProcess = document.querySelectorAll(".content h1, .content h2, .content h3, .content h4, .content tr");
+
+ elementsToProcess.forEach(element => {
+ let uniqueId;
+ if (element.tagName.toLowerCase() === 'tr') {
+ const closestHeading = element.closest('.content').querySelector('.heading-anchor');
+ const rowText = Array.from(element.cells).map(cell => cell.textContent.trim()).join(' ').toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+
+ if (closestHeading) {
+ const headingText = closestHeading.textContent.trim().toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+ uniqueId = `${headingText}-${rowText}`;
+ } else {
+ uniqueId = rowText;
+ }
+ } else {
+ uniqueId = element.textContent.trim().toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+ }
+
+ element.classList.add("heading-anchor");
+ element.setAttribute('id', uniqueId);
+ let anchor = document.createElement('a');
+ anchor.className = 'anchor-link';
+ anchor.href = '#' + uniqueId;
+ anchor.innerHTML = '';
+ element.append(anchor);
+ anchor.addEventListener("click", (e) => {
e.preventDefault();
window.location = anchor.href;
- document.querySelector(anchor.getAttribute("href")).scrollIntoView({
- behavior: "smooth",
- block: "start" //scroll to top of the target element
- });
- });
- });
-};
+ document.querySelector(anchor.getAttribute('href')).scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ })
+ })
+ })
+}
function removeExpiredEvents() {
let events = document.querySelectorAll(".community-highlight .carousel-cell");
let eventsNumber = events.length;
diff --git a/static/js/src/modules/utils.js b/static/js/src/modules/utils.js
index ed3324950..bc3b41a72 100644
--- a/static/js/src/modules/utils.js
+++ b/static/js/src/modules/utils.js
@@ -82,23 +82,37 @@ const addCopyButtons = (clipboard) => {
};
const addAnchorLinks = () => {
- document.querySelectorAll(".content h1, .content h2, .content h3, .content h4").forEach(heading => {
- let id = heading.innerText.toLowerCase()
- .replace(/[`~!@#$%^&*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, '')
- .replace(/ +/g, '-');
- heading.setAttribute("id", id);
- heading.classList.add("heading-anchor");
+ const elementsToProcess = document.querySelectorAll(".content h1, .content h2, .content h3, .content h4, .content tr");
+
+ elementsToProcess.forEach(element => {
+ let uniqueId;
+ if (element.tagName.toLowerCase() === 'tr') {
+ const closestHeading = element.closest('.content').querySelector('.heading-anchor');
+ const rowText = Array.from(element.cells).map(cell => cell.textContent.trim()).join(' ').toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+
+ if (closestHeading) {
+ const headingText = closestHeading.textContent.trim().toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+ uniqueId = `${headingText}-${rowText}`;
+ } else {
+ uniqueId = rowText;
+ }
+ } else {
+ uniqueId = element.textContent.trim().toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
+ }
+
+ element.classList.add("heading-anchor");
+ element.setAttribute('id', uniqueId);
let anchor = document.createElement('a');
anchor.className = 'anchor-link';
- anchor.href = '#' + id;
- anchor.innerHTML = '';
- heading.append(anchor);
+ anchor.href = '#' + uniqueId;
+ anchor.innerHTML = '';
+ element.append(anchor);
anchor.addEventListener("click", (e) => {
- e.preventDefault()
- window.location = anchor.href
+ e.preventDefault();
+ window.location = anchor.href;
document.querySelector(anchor.getAttribute('href')).scrollIntoView({
behavior: 'smooth',
- block: 'start' //scroll to top of the target element
+ block: 'start'
})
})
})
diff --git a/static/sass/styles.scss b/static/sass/styles.scss
index bcc3a1ce8..a47339b7b 100644
--- a/static/sass/styles.scss
+++ b/static/sass/styles.scss
@@ -409,6 +409,13 @@ Importing color and theme updates for the brand 1.5 refresh
}
}
}
+ tr {
+ &:hover {
+ >a.anchor-link {
+ opacity: 1;
+ }
+ }
+ }
a {
font-weight: 600;
@@ -419,6 +426,13 @@ Importing color and theme updates for the brand 1.5 refresh
content: none;
}
}
+
+ tr {
+ overflow-x: hidden;
+ a.anchor-link {
+ position: absolute;
+ }
+ }
aside.menu {
padding-bottom: 7.5rem;