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>
This commit is contained in:
M Sarmad Qadeer
2023-06-11 12:31:41 +05:00
committed by GitHub
parent 060e7cdf52
commit d585e8f5a7
2 changed files with 56 additions and 29 deletions
+31 -16
View File
@@ -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(`(?<![/#])\\b${term.term}\\b`, 'gi')
const replacement = `<span data-glossary=${id} class="glossary-term">${term.term}</span>`
const replacement = `<span data-glossary="tooltip-${id}" class="glossary-term">${term.term}</span>`
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()
+25 -13
View File
@@ -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)