From d585e8f5a72036ecec9210795f99444038728aec Mon Sep 17 00:00:00 2001 From: M Sarmad Qadeer Date: Sun, 11 Jun 2023 12:31:41 +0500 Subject: [PATCH] website: glossary extended (#2574) * web: quick fixes in glossary.md * website: update header tags * website: add glossary feature * website: add & style the tooltips & glossary terms * website: add overlay for glossary definition * website: add list styling & update links * website: fix tooltip alignment against multiple terms fix the issue of aligning tooltip if page has multiple terms against it * website: close already opened glossary overlay close the already opened glossary overlay before opening another * website: add popups for terms inside popups --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- website/.eleventy.js | 47 ++++++++++++++++++++++++++-------------- website/src/js/script.js | 38 +++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/website/.eleventy.js b/website/.eleventy.js index 28709bcf41..554e4a1db3 100644 --- a/website/.eleventy.js +++ b/website/.eleventy.js @@ -30,11 +30,6 @@ glossary.forEach(item => { while (sibling && sibling.tagName !== 'H2') { if (sibling.tagName === 'P') { - Array.from(sibling.getElementsByTagName('a')).forEach(a => { - if (a.getAttribute('href').startsWith('#')) { - a.setAttribute('href', '/docs/glossary.html' + a.getAttribute('href')) - } - }) paragraphCount += 1 if (firstParagraph === '') { firstParagraph = sibling.innerHTML @@ -102,14 +97,15 @@ module.exports = function (ty) { const { document } = dom.window const body = document.querySelector('body') const allContentNodes = document.querySelectorAll('p, td, a, h1, h2, h3, h4') + const overlayIds = [] glossary.forEach((term, index) => { let changeNoted = false - const id = `glossary-${index}` + const id = term.term.toLowerCase().replace(/\s/g, '-') allContentNodes.forEach((node) => { const regex = new RegExp(`(?${term.term}` + const replacement = `${term.term}` const beforeContent = node.innerHTML node.innerHTML = node.innerHTML.replace(regex, replacement) if (beforeContent !== node.innerHTML && !changeNoted) { @@ -119,7 +115,7 @@ module.exports = function (ty) { if (changeNoted) { const definitionTooltipDiv = document.createElement('div') - definitionTooltipDiv.id = id + definitionTooltipDiv.id = `tooltip-${id}` definitionTooltipDiv.className = "glossary-tooltip" const titleH4 = document.createElement('h4') titleH4.innerHTML = term.term @@ -133,20 +129,41 @@ module.exports = function (ty) { const readMoreBtn = document.createElement('button') readMoreBtn.innerHTML = "Read more" readMoreBtn.className = "read-more-btn open-overlay-btn" - readMoreBtn.setAttribute('data-show-overlay', `overlay-${id}`) + readMoreBtn.setAttribute('data-show-overlay', id) innerDiv.appendChild(readMoreBtn) + } + innerDiv.className = "tooltip-content" + definitionTooltipDiv.appendChild(innerDiv) + body.appendChild(definitionTooltipDiv) + } + + let tooltipDom = new JSDOM(term.definition) + let tooltipDocument = tooltipDom.window.document + const hashList = [term.term.toLowerCase().replace(/\s/g, '-')] + tooltipDocument.querySelectorAll('a[href*="#"]').forEach(a => { + let hashIndex = a.href.indexOf("#") + if (hashIndex !== -1) { + let hash = a.href.substring(hashIndex + 1) + hashList.push(hash) + } + }) + + hashList.forEach(hash => { + if (!overlayIds.includes(hash)) { + let termFromHash = glossary.find(term => term.term.toLowerCase().replace(/\s/g, '-') === hash) + if (!termFromHash) return const overlayDiv = document.createElement('div') - overlayDiv.id = `overlay-${id}` + overlayDiv.id = hash overlayDiv.className = "overlay glossary-overlay hidden" const overlayCardDiv = document.createElement('div') overlayCardDiv.className = "overlay-card" const overlayTitleH1 = document.createElement('h1') overlayTitleH1.className = "overlay-title" - overlayTitleH1.innerHTML = term.term + overlayTitleH1.innerHTML = termFromHash.term const overlayContent = document.createElement('div') overlayContent.className = "overlay-content" - overlayContent.innerHTML = term.definition + overlayContent.innerHTML = termFromHash.definition const crossSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg") crossSVG.setAttribute('class', 'close-overlay-btn') crossSVG.setAttribute('id', 'cross') @@ -163,11 +180,9 @@ module.exports = function (ty) { overlayCardDiv.appendChild(crossSVG) overlayDiv.appendChild(overlayCardDiv) body.appendChild(overlayDiv) + overlayIds.push(hash) } - innerDiv.className = "tooltip-content" - definitionTooltipDiv.appendChild(innerDiv) - body.appendChild(definitionTooltipDiv) - } + }) }) return dom.serialize() diff --git a/website/src/js/script.js b/website/src/js/script.js index 9577a97587..5f863f48ee 100644 --- a/website/src/js/script.js +++ b/website/src/js/script.js @@ -187,6 +187,13 @@ function openOverlay() { const scrollToEl = document.getElementById(scrollTo) if (scrollToEl) scrollToEl.scrollIntoView(true) } + + const currentOpenedGlossaryOverlay = document.querySelector('.glossary-overlay.flex') + if (currentOpenedGlossaryOverlay) { + currentOpenedGlossaryOverlay.classList.remove('flex') + currentOpenedGlossaryOverlay.classList.add('hidden') + } + el.classList.remove('hidden') el.classList.add('flex') document.body.classList.add('lock-scroll') @@ -254,15 +261,23 @@ function setupTooltip(glossaryTerm) { tooltip.style.opacity = '0' const privateSwiper = glossaryTerm.closest('.private-swiper') if (privateSwiper) glossaryTerm.closest('.card').classList.remove('hovered') + if (!glossaryTerm.matches(':hover') && !tooltip.matches(':hover')) { + glossaryTerm.classList.remove('active-term') + tooltip.removeEventListener('mouseover', showTooltip) + tooltip.removeEventListener('mouseout', hideTooltip) + } } let click = 0 - glossaryTerm.addEventListener('mouseover', showTooltip) + glossaryTerm.addEventListener('mouseover', () => { + glossaryTerm.classList.add('active-term') + showTooltip() + tooltip.addEventListener('mouseover', showTooltip) + tooltip.addEventListener('mouseout', hideTooltip) + }) glossaryTerm.addEventListener('mouseout', function (event) { click = 0 - if (event.relatedTarget !== tooltip) { - hideTooltip() - } + hideTooltip() }) glossaryTerm.addEventListener('click', function (event) { event.stopPropagation() @@ -275,25 +290,22 @@ function setupTooltip(glossaryTerm) { click = 1 } }) - - tooltip.addEventListener('mouseover', showTooltip) - tooltip.addEventListener('mouseout', hideTooltip) } window.addEventListener('load', () => { openOverlay() updatePointerEventsInPrivateSwiperCards() - const glossaryTerms = document.querySelectorAll('.glossary-term') - window.addEventListener('scroll', function () { - glossaryTerms.forEach(function (glossaryTerm) { - var tooltipId = glossaryTerm.getAttribute('data-glossary') + let activeTerm = document.querySelector('.active-term') + if (activeTerm) { + var tooltipId = activeTerm.getAttribute('data-glossary') var tooltip = document.getElementById(tooltipId) - updateTooltipPosition(glossaryTerm, tooltip) - }) + updateTooltipPosition(activeTerm, tooltip) + } }) + const glossaryTerms = document.querySelectorAll('.glossary-term') glossaryTerms.forEach(setupTooltip) }) window.addEventListener('hashchange', openOverlay)