mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-23 03:56:23 +00:00
fix: attempt to merge cached folder state between builds (closes #691)
This commit is contained in:
parent
f68872c09f
commit
76be137283
3 changed files with 68 additions and 97 deletions
|
@ -69,9 +69,8 @@ export default ((userOpts?: Partial<Options>) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all folders of tree. Initialize with collapsed state
|
// Get all folders of tree. Initialize with collapsed state
|
||||||
const folders = fileTree.getFolderPaths(opts.folderDefaultState === "collapsed")
|
|
||||||
|
|
||||||
// Stringify to pass json tree as data attribute ([data-tree])
|
// Stringify to pass json tree as data attribute ([data-tree])
|
||||||
|
const folders = fileTree.getFolderPaths(opts.folderDefaultState === "collapsed")
|
||||||
jsonTree = JSON.stringify(folders)
|
jsonTree = JSON.stringify(folders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,132 +1,106 @@
|
||||||
import { FolderState } from "../ExplorerNode"
|
import { FolderState } from "../ExplorerNode"
|
||||||
|
|
||||||
// Current state of folders
|
type MaybeHTMLElement = HTMLElement | undefined
|
||||||
let explorerState: FolderState[]
|
let currentExplorerState: FolderState[]
|
||||||
|
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
// If last element is observed, remove gradient of "overflow" class so element is visible
|
// If last element is observed, remove gradient of "overflow" class so element is visible
|
||||||
const explorer = document.getElementById("explorer-ul")
|
const explorerUl = document.getElementById("explorer-ul")
|
||||||
|
if (!explorerUl) return
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
explorer?.classList.add("no-background")
|
explorerUl.classList.add("no-background")
|
||||||
} else {
|
} else {
|
||||||
explorer?.classList.remove("no-background")
|
explorerUl.classList.remove("no-background")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function toggleExplorer(this: HTMLElement) {
|
function toggleExplorer(this: HTMLElement) {
|
||||||
// Toggle collapsed state of entire explorer
|
|
||||||
this.classList.toggle("collapsed")
|
this.classList.toggle("collapsed")
|
||||||
const content = this.nextElementSibling as HTMLElement
|
const content = this.nextElementSibling as MaybeHTMLElement
|
||||||
|
if (!content) return
|
||||||
|
|
||||||
content.classList.toggle("collapsed")
|
content.classList.toggle("collapsed")
|
||||||
content.style.maxHeight = content.style.maxHeight === "0px" ? content.scrollHeight + "px" : "0px"
|
content.style.maxHeight = content.style.maxHeight === "0px" ? content.scrollHeight + "px" : "0px"
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFolder(evt: MouseEvent) {
|
function toggleFolder(evt: MouseEvent) {
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
|
const target = evt.target as MaybeHTMLElement
|
||||||
|
if (!target) return
|
||||||
|
|
||||||
// Element that was clicked
|
|
||||||
const target = evt.target as HTMLElement
|
|
||||||
|
|
||||||
// Check if target was svg icon or button
|
|
||||||
const isSvg = target.nodeName === "svg"
|
const isSvg = target.nodeName === "svg"
|
||||||
|
const childFolderContainer = (
|
||||||
|
isSvg
|
||||||
|
? target.parentElement?.nextSibling
|
||||||
|
: target.parentElement?.parentElement?.nextElementSibling
|
||||||
|
) as MaybeHTMLElement
|
||||||
|
const currentFolderParent = (
|
||||||
|
isSvg ? target.nextElementSibling : target.parentElement
|
||||||
|
) as MaybeHTMLElement
|
||||||
|
if (!(childFolderContainer && currentFolderParent)) return
|
||||||
|
|
||||||
// corresponding <ul> element relative to clicked button/folder
|
childFolderContainer.classList.toggle("open")
|
||||||
let childFolderContainer: HTMLElement
|
|
||||||
|
|
||||||
// <li> element of folder (stores folder-path dataset)
|
|
||||||
let currentFolderParent: HTMLElement
|
|
||||||
|
|
||||||
// Get correct relative container and toggle collapsed class
|
|
||||||
if (isSvg) {
|
|
||||||
childFolderContainer = target.parentElement?.nextSibling as HTMLElement
|
|
||||||
currentFolderParent = target.nextElementSibling as HTMLElement
|
|
||||||
|
|
||||||
childFolderContainer.classList.toggle("open")
|
|
||||||
} else {
|
|
||||||
childFolderContainer = target.parentElement?.parentElement?.nextElementSibling as HTMLElement
|
|
||||||
currentFolderParent = target.parentElement as HTMLElement
|
|
||||||
|
|
||||||
childFolderContainer.classList.toggle("open")
|
|
||||||
}
|
|
||||||
if (!childFolderContainer) return
|
|
||||||
|
|
||||||
// Collapse folder container
|
|
||||||
const isCollapsed = childFolderContainer.classList.contains("open")
|
const isCollapsed = childFolderContainer.classList.contains("open")
|
||||||
setFolderState(childFolderContainer, !isCollapsed)
|
setFolderState(childFolderContainer, !isCollapsed)
|
||||||
|
const fullFolderPath = currentFolderParent.dataset.folderpath as string
|
||||||
// Save folder state to localStorage
|
toggleCollapsedByPath(currentExplorerState, fullFolderPath)
|
||||||
const clickFolderPath = currentFolderParent.dataset.folderpath as string
|
const stringifiedFileTree = JSON.stringify(currentExplorerState)
|
||||||
|
|
||||||
const fullFolderPath = clickFolderPath
|
|
||||||
toggleCollapsedByPath(explorerState, fullFolderPath)
|
|
||||||
|
|
||||||
const stringifiedFileTree = JSON.stringify(explorerState)
|
|
||||||
localStorage.setItem("fileTree", stringifiedFileTree)
|
localStorage.setItem("fileTree", stringifiedFileTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupExplorer() {
|
function setupExplorer() {
|
||||||
// Set click handler for collapsing entire explorer
|
|
||||||
const explorer = document.getElementById("explorer")
|
const explorer = document.getElementById("explorer")
|
||||||
|
if (!explorer) return
|
||||||
|
|
||||||
|
if (explorer.dataset.behavior === "collapse") {
|
||||||
|
for (const item of document.getElementsByClassName(
|
||||||
|
"folder-button",
|
||||||
|
) as HTMLCollectionOf<HTMLElement>) {
|
||||||
|
item.removeEventListener("click", toggleFolder)
|
||||||
|
item.addEventListener("click", toggleFolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
explorer.removeEventListener("click", toggleExplorer)
|
||||||
|
explorer.addEventListener("click", toggleExplorer)
|
||||||
|
|
||||||
|
// Set up click handlers for each folder (click handler on folder "icon")
|
||||||
|
for (const item of document.getElementsByClassName(
|
||||||
|
"folder-icon",
|
||||||
|
) as HTMLCollectionOf<HTMLElement>) {
|
||||||
|
item.removeEventListener("click", toggleFolder)
|
||||||
|
item.addEventListener("click", toggleFolder)
|
||||||
|
}
|
||||||
|
|
||||||
// Get folder state from local storage
|
// Get folder state from local storage
|
||||||
const storageTree = localStorage.getItem("fileTree")
|
const storageTree = localStorage.getItem("fileTree")
|
||||||
|
|
||||||
// Convert to bool
|
|
||||||
const useSavedFolderState = explorer?.dataset.savestate === "true"
|
const useSavedFolderState = explorer?.dataset.savestate === "true"
|
||||||
|
const oldExplorerState: FolderState[] =
|
||||||
|
storageTree && useSavedFolderState ? JSON.parse(storageTree) : []
|
||||||
|
const oldIndex = new Map(oldExplorerState.map((entry) => [entry.path, entry.collapsed]))
|
||||||
|
const newExplorerState: FolderState[] = explorer.dataset.tree
|
||||||
|
? JSON.parse(explorer.dataset.tree)
|
||||||
|
: []
|
||||||
|
currentExplorerState = []
|
||||||
|
for (const { path, collapsed } of newExplorerState) {
|
||||||
|
currentExplorerState.push({ path, collapsed: oldIndex.get(path) ?? collapsed })
|
||||||
|
}
|
||||||
|
|
||||||
if (explorer) {
|
currentExplorerState.map((folderState) => {
|
||||||
// Get config
|
const folderLi = document.querySelector(
|
||||||
const collapseBehavior = explorer.dataset.behavior
|
`[data-folderpath='${folderState.path}']`,
|
||||||
|
) as MaybeHTMLElement
|
||||||
// Add click handlers for all folders (click handler on folder "label")
|
const folderUl = folderLi?.parentElement?.nextElementSibling as MaybeHTMLElement
|
||||||
if (collapseBehavior === "collapse") {
|
if (folderUl) {
|
||||||
Array.prototype.forEach.call(
|
setFolderState(folderUl, folderState.collapsed)
|
||||||
document.getElementsByClassName("folder-button"),
|
|
||||||
function (item) {
|
|
||||||
item.removeEventListener("click", toggleFolder)
|
|
||||||
item.addEventListener("click", toggleFolder)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add click handler to main explorer
|
|
||||||
explorer.removeEventListener("click", toggleExplorer)
|
|
||||||
explorer.addEventListener("click", toggleExplorer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up click handlers for each folder (click handler on folder "icon")
|
|
||||||
Array.prototype.forEach.call(document.getElementsByClassName("folder-icon"), function (item) {
|
|
||||||
item.removeEventListener("click", toggleFolder)
|
|
||||||
item.addEventListener("click", toggleFolder)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (storageTree && useSavedFolderState) {
|
|
||||||
// Get state from localStorage and set folder state
|
|
||||||
explorerState = JSON.parse(storageTree)
|
|
||||||
explorerState.map((folderUl) => {
|
|
||||||
// grab <li> element for matching folder path
|
|
||||||
const folderLi = document.querySelector(`[data-folderpath='${folderUl.path}']`) as HTMLElement
|
|
||||||
|
|
||||||
// Get corresponding content <ul> tag and set state
|
|
||||||
if (folderLi) {
|
|
||||||
const folderUL = folderLi.parentElement?.nextElementSibling
|
|
||||||
if (folderUL) {
|
|
||||||
setFolderState(folderUL as HTMLElement, folderUl.collapsed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (explorer?.dataset.tree) {
|
|
||||||
// If tree is not in localStorage or config is disabled, use tree passed from Explorer as dataset
|
|
||||||
explorerState = JSON.parse(explorer.dataset.tree)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("resize", setupExplorer)
|
window.addEventListener("resize", setupExplorer)
|
||||||
document.addEventListener("nav", () => {
|
document.addEventListener("nav", () => {
|
||||||
setupExplorer()
|
setupExplorer()
|
||||||
|
|
||||||
observer.disconnect()
|
observer.disconnect()
|
||||||
|
|
||||||
// select pseudo element at end of list
|
// select pseudo element at end of list
|
||||||
|
@ -142,11 +116,7 @@ document.addEventListener("nav", () => {
|
||||||
* @param collapsed if folder should be set to collapsed or not
|
* @param collapsed if folder should be set to collapsed or not
|
||||||
*/
|
*/
|
||||||
function setFolderState(folderElement: HTMLElement, collapsed: boolean) {
|
function setFolderState(folderElement: HTMLElement, collapsed: boolean) {
|
||||||
if (collapsed) {
|
return collapsed ? folderElement.classList.remove("open") : folderElement.classList.add("open")
|
||||||
folderElement?.classList.remove("open")
|
|
||||||
} else {
|
|
||||||
folderElement?.classList.add("open")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,8 @@ const observer = new IntersectionObserver((entries) => {
|
||||||
|
|
||||||
function toggleToc(this: HTMLElement) {
|
function toggleToc(this: HTMLElement) {
|
||||||
this.classList.toggle("collapsed")
|
this.classList.toggle("collapsed")
|
||||||
const content = this.nextElementSibling as HTMLElement
|
const content = this.nextElementSibling as HTMLElement | undefined
|
||||||
|
if (!content) return
|
||||||
content.classList.toggle("collapsed")
|
content.classList.toggle("collapsed")
|
||||||
content.style.maxHeight = content.style.maxHeight === "0px" ? content.scrollHeight + "px" : "0px"
|
content.style.maxHeight = content.style.maxHeight === "0px" ? content.scrollHeight + "px" : "0px"
|
||||||
}
|
}
|
||||||
|
@ -25,7 +26,8 @@ function setupToc() {
|
||||||
const toc = document.getElementById("toc")
|
const toc = document.getElementById("toc")
|
||||||
if (toc) {
|
if (toc) {
|
||||||
const collapsed = toc.classList.contains("collapsed")
|
const collapsed = toc.classList.contains("collapsed")
|
||||||
const content = toc.nextElementSibling as HTMLElement
|
const content = toc.nextElementSibling as HTMLElement | undefined
|
||||||
|
if (!content) return
|
||||||
content.style.maxHeight = collapsed ? "0px" : content.scrollHeight + "px"
|
content.style.maxHeight = collapsed ? "0px" : content.scrollHeight + "px"
|
||||||
toc.removeEventListener("click", toggleToc)
|
toc.removeEventListener("click", toggleToc)
|
||||||
toc.addEventListener("click", toggleToc)
|
toc.addEventListener("click", toggleToc)
|
||||||
|
|
Loading…
Reference in a new issue