mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-15 03:46:23 +00:00
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:
+31
-16
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user