Initial commit (after 2 months)
This commit is contained in:
@@ -0,0 +1,937 @@
|
||||
|
||||
//#region Helpers
|
||||
|
||||
function getAbsoluteRootPath()
|
||||
{
|
||||
if (typeof rootPath == 'undefined') setupRootPath(document);
|
||||
return new URL(window.location.href + "/../" + rootPath).pathname;
|
||||
}
|
||||
|
||||
function getURLPath(url = window.location.pathname)
|
||||
{
|
||||
let absoluteRoot = getAbsoluteRootPath();
|
||||
let pathname = url.substring(absoluteRoot.length);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
function getURLRootPath(url = window.location.pathname)
|
||||
{
|
||||
let path = getURLPath(url);
|
||||
let splitPath = path.split("/");
|
||||
let rootPath = "";
|
||||
for (let i = 0; i < splitPath.length - 1; i++)
|
||||
{
|
||||
rootPath += "../";
|
||||
}
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
async function setTreeCollapsed(element, collapsed, animate = true)
|
||||
{
|
||||
if (!element || !element.classList.contains("mod-collapsible")) return;
|
||||
|
||||
let children = element.querySelector(".tree-item-children");
|
||||
|
||||
if (collapsed)
|
||||
{
|
||||
element.classList.add("is-collapsed");
|
||||
if(animate) slideUp(children, 100);
|
||||
else children.style.display = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
element.classList.remove("is-collapsed");
|
||||
if(animate) slideDown(children, 100);
|
||||
else children.style.removeProperty("display");
|
||||
}
|
||||
}
|
||||
|
||||
async function setTreeCollapsedAll(elements, collapsed, animate = true)
|
||||
{
|
||||
let childrenList = [];
|
||||
elements.forEach(async element =>
|
||||
{
|
||||
if (!element || !element.classList.contains("mod-collapsible")) return;
|
||||
|
||||
let children = element.querySelector(".tree-item-children");
|
||||
|
||||
if (collapsed)
|
||||
{
|
||||
element.classList.add("is-collapsed");
|
||||
}
|
||||
else
|
||||
{
|
||||
element.classList.remove("is-collapsed");
|
||||
}
|
||||
|
||||
childrenList.push(children);
|
||||
});
|
||||
|
||||
if (collapsed)
|
||||
{
|
||||
if(animate) slideUpAll(childrenList, 100);
|
||||
else childrenList.forEach(async children => children.style.display = "none");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(animate) slideDownAll(childrenList, 100);
|
||||
else childrenList.forEach(async children => children.style.removeProperty("display"));
|
||||
}
|
||||
}
|
||||
|
||||
function toggleTreeCollapsed(element)
|
||||
{
|
||||
if (!element) return;
|
||||
setTreeCollapsed(element, !element.classList.contains("is-collapsed"));
|
||||
}
|
||||
|
||||
function toggleTreeCollapsedAll(elements)
|
||||
{
|
||||
if (!elements) return;
|
||||
setTreeCollapsedAll(elements, !elements[0].classList.contains("is-collapsed"));
|
||||
}
|
||||
|
||||
function getHeaderEl(headerDiv)
|
||||
{
|
||||
let possibleChildHeader = headerDiv.firstChild;
|
||||
let isHeader = false;
|
||||
|
||||
while (possibleChildHeader != null)
|
||||
{
|
||||
isHeader = possibleChildHeader ? /[Hh][1-6]/g.test(possibleChildHeader.tagName) : false;
|
||||
if (isHeader) break;
|
||||
|
||||
possibleChildHeader = possibleChildHeader.nextElementSibling;
|
||||
}
|
||||
|
||||
return possibleChildHeader;
|
||||
}
|
||||
|
||||
function getPreviousHeader(headerDiv)
|
||||
{
|
||||
let possibleParent = headerDiv.previousElementSibling;
|
||||
let isHeader = false;
|
||||
|
||||
while (possibleParent != null)
|
||||
{
|
||||
let possibleChildHeader = getHeaderEl(possibleParent);
|
||||
isHeader = possibleChildHeader ? /[Hh][1-6]/g.test(possibleChildHeader.tagName) : false;
|
||||
if (isHeader) break;
|
||||
|
||||
possibleParent = possibleParent.previousElementSibling;
|
||||
}
|
||||
|
||||
return possibleParent;
|
||||
}
|
||||
|
||||
function setHeaderOpen(headerDiv, open, openParents = true)
|
||||
{
|
||||
if(headerDiv.tagName != "DIV" || !getHeaderEl(headerDiv))
|
||||
{
|
||||
console.error("setHeaderOpen() must be called with a header div");
|
||||
return;
|
||||
}
|
||||
|
||||
// let selector = getHeadingContentsSelector(header);
|
||||
if (open)
|
||||
{
|
||||
headerDiv.classList.remove("is-collapsed");
|
||||
headerDiv.style.display = "";
|
||||
}
|
||||
if (!open)
|
||||
{
|
||||
headerDiv.classList.add("is-collapsed");
|
||||
}
|
||||
|
||||
let headerEl = getHeaderEl(headerDiv);
|
||||
|
||||
let childHeaders = [];
|
||||
|
||||
let possibleChild = headerDiv.nextElementSibling;
|
||||
|
||||
// loop through next siblings showing/ hiding children until we reach a header of the same or lower level
|
||||
while (possibleChild != null)
|
||||
{
|
||||
let possibleChildHeader = getHeaderEl(possibleChild);
|
||||
|
||||
if(possibleChildHeader)
|
||||
{
|
||||
// if header is a sibling of this header then break
|
||||
if (possibleChildHeader.tagName <= headerEl.tagName) break;
|
||||
|
||||
// save child headers to be re closed afterwards
|
||||
childHeaders.push(possibleChild);
|
||||
}
|
||||
|
||||
if (!open) possibleChild.style.display = "none";
|
||||
else possibleChild.style.display = "";
|
||||
|
||||
possibleChild = possibleChild.nextElementSibling;
|
||||
}
|
||||
|
||||
if(open)
|
||||
{
|
||||
// if we are opening the header then we need to make sure that all closed child headers stay closed
|
||||
childHeaders.forEach(function(item)
|
||||
{
|
||||
if (item.classList.contains("is-collapsed"))
|
||||
{
|
||||
setHeaderOpen(item, false);
|
||||
}
|
||||
});
|
||||
|
||||
// if we are opening the header then we need to make sure that all parent headers are open
|
||||
if (openParents)
|
||||
{
|
||||
let previousHeader = getPreviousHeader(headerDiv);
|
||||
|
||||
while (previousHeader != null)
|
||||
{
|
||||
let previousHeaderEl = getHeaderEl(previousHeader);
|
||||
|
||||
if (previousHeaderEl.tagName < headerEl.tagName)
|
||||
{
|
||||
// if header is a parent of this header then unhide
|
||||
setHeaderOpen(previousHeader, true);
|
||||
break;
|
||||
}
|
||||
|
||||
previousHeader = getPreviousHeader(previousHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let slideUp = (target, duration=500) => {
|
||||
|
||||
target.style.transitionProperty = 'height, margin, padding';
|
||||
target.style.transitionDuration = duration + 'ms';
|
||||
target.style.boxSizing = 'border-box';
|
||||
target.style.height = target.offsetHeight + 'px';
|
||||
target.offsetHeight;
|
||||
target.style.overflow = 'hidden';
|
||||
target.style.height = 0;
|
||||
target.style.paddingTop = 0;
|
||||
target.style.paddingBottom = 0;
|
||||
target.style.marginTop = 0;
|
||||
target.style.marginBottom = 0;
|
||||
window.setTimeout(async () => {
|
||||
target.style.display = 'none';
|
||||
target.style.removeProperty('height');
|
||||
target.style.removeProperty('padding-top');
|
||||
target.style.removeProperty('padding-bottom');
|
||||
target.style.removeProperty('margin-top');
|
||||
target.style.removeProperty('margin-bottom');
|
||||
target.style.removeProperty('overflow');
|
||||
target.style.removeProperty('transition-duration');
|
||||
target.style.removeProperty('transition-property');
|
||||
}, duration);
|
||||
}
|
||||
|
||||
let slideUpAll = (targets, duration=500) => {
|
||||
|
||||
targets.forEach(async target => {
|
||||
target.style.transitionProperty = 'height, margin, padding';
|
||||
target.style.transitionDuration = duration + 'ms';
|
||||
target.style.boxSizing = 'border-box';
|
||||
target.style.height = target.offsetHeight + 'px';
|
||||
target.offsetHeight;
|
||||
target.style.overflow = 'hidden';
|
||||
target.style.height = 0;
|
||||
target.style.paddingTop = 0;
|
||||
target.style.paddingBottom = 0;
|
||||
target.style.marginTop = 0;
|
||||
target.style.marginBottom = 0;
|
||||
});
|
||||
|
||||
window.setTimeout(async () => {
|
||||
targets.forEach(async target => {
|
||||
target.style.display = 'none';
|
||||
target.style.removeProperty('height');
|
||||
target.style.removeProperty('padding-top');
|
||||
target.style.removeProperty('padding-bottom');
|
||||
target.style.removeProperty('margin-top');
|
||||
target.style.removeProperty('margin-bottom');
|
||||
target.style.removeProperty('overflow');
|
||||
target.style.removeProperty('transition-duration');
|
||||
target.style.removeProperty('transition-property');
|
||||
});
|
||||
}, duration);
|
||||
}
|
||||
|
||||
let slideDown = (target, duration=500) => {
|
||||
|
||||
target.style.removeProperty('display');
|
||||
let display = window.getComputedStyle(target).display;
|
||||
if (display === 'none') display = 'block';
|
||||
target.style.display = display;
|
||||
let height = target.offsetHeight;
|
||||
target.style.overflow = 'hidden';
|
||||
target.style.height = 0;
|
||||
target.style.paddingTop = 0;
|
||||
target.style.paddingBottom = 0;
|
||||
target.style.marginTop = 0;
|
||||
target.style.marginBottom = 0;
|
||||
target.offsetHeight;
|
||||
target.style.boxSizing = 'border-box';
|
||||
target.style.transitionProperty = "height, margin, padding";
|
||||
target.style.transitionDuration = duration + 'ms';
|
||||
target.style.height = height + 'px';
|
||||
target.style.removeProperty('padding-top');
|
||||
target.style.removeProperty('padding-bottom');
|
||||
target.style.removeProperty('margin-top');
|
||||
target.style.removeProperty('margin-bottom');
|
||||
window.setTimeout(async () => {
|
||||
target.style.removeProperty('height');
|
||||
target.style.removeProperty('overflow');
|
||||
target.style.removeProperty('transition-duration');
|
||||
target.style.removeProperty('transition-property');
|
||||
}, duration);
|
||||
}
|
||||
|
||||
let slideDownAll = (targets, duration=500) => {
|
||||
|
||||
targets.forEach(async target => {
|
||||
target.style.removeProperty('display');
|
||||
let display = window.getComputedStyle(target).display;
|
||||
if (display === 'none') display = 'block';
|
||||
target.style.display = display;
|
||||
let height = target.offsetHeight;
|
||||
target.style.overflow = 'hidden';
|
||||
target.style.height = 0;
|
||||
target.style.paddingTop = 0;
|
||||
target.style.paddingBottom = 0;
|
||||
target.style.marginTop = 0;
|
||||
target.style.marginBottom = 0;
|
||||
target.offsetHeight;
|
||||
target.style.boxSizing = 'border-box';
|
||||
target.style.transitionProperty = "height, margin, padding";
|
||||
target.style.transitionDuration = duration + 'ms';
|
||||
target.style.height = height + 'px';
|
||||
target.style.removeProperty('padding-top');
|
||||
target.style.removeProperty('padding-bottom');
|
||||
target.style.removeProperty('margin-top');
|
||||
target.style.removeProperty('margin-bottom');
|
||||
});
|
||||
|
||||
window.setTimeout( async () => {
|
||||
targets.forEach(async target => {
|
||||
target.style.removeProperty('height');
|
||||
target.style.removeProperty('overflow');
|
||||
target.style.removeProperty('transition-duration');
|
||||
target.style.removeProperty('transition-property');
|
||||
});
|
||||
}, duration);
|
||||
}
|
||||
|
||||
var slideToggle = (target, duration = 500) => {
|
||||
if (window.getComputedStyle(target).display === 'none') {
|
||||
return slideDown(target, duration);
|
||||
} else {
|
||||
return slideUp(target, duration);
|
||||
}
|
||||
}
|
||||
|
||||
var slideToggleAll = (targets, duration = 500) => {
|
||||
if (window.getComputedStyle(targets[0]).display === 'none') {
|
||||
return slideDownAll(targets, duration);
|
||||
} else {
|
||||
return slideUpAll(targets, duration);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
async function loadDocument(url, pushHistory = true, scrollTo = true)
|
||||
{
|
||||
console.log("Loading document: " + url);
|
||||
|
||||
// change the active file
|
||||
setActiveDocument(url, scrollTo, pushHistory);
|
||||
|
||||
let response;
|
||||
|
||||
// if(typeof embeddedDocuments == 'undefined')
|
||||
// {
|
||||
try
|
||||
{
|
||||
response = await fetch(url);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
console.log("Cannot use fetch API (likely due to CORS), just loading the page normally.");
|
||||
window.location.assign(url);
|
||||
return;
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// response = new Response(embeddedDocuments[url], {status: 200, statusText: "OK"});
|
||||
// }
|
||||
|
||||
let doc = document.implementation.createHTMLDocument();
|
||||
|
||||
if (response.ok)
|
||||
{
|
||||
let html = (await response.text()).replaceAll("<!DOCTYPE html>", "").replaceAll("<html>", "").replaceAll("</html>", "");
|
||||
doc.documentElement.innerHTML = html;
|
||||
|
||||
// copy document content and outline tree
|
||||
document.querySelector(".document-container").innerHTML = doc.querySelector(".document-container").innerHTML;
|
||||
document.querySelector(".outline-tree").innerHTML = doc.querySelector(".outline-tree").innerHTML;
|
||||
|
||||
// if the url has a heading, scroll to it
|
||||
let splitURL = url.split("#");
|
||||
let pathnameTarget = splitURL[0] ?? url;
|
||||
let headingTarget = splitURL.length > 1 ? splitURL[1] : null;
|
||||
if (headingTarget) document.getElementById(headingTarget).scrollIntoView();
|
||||
|
||||
// Change the root path to match the match from the new page
|
||||
setupRootPath(doc);
|
||||
|
||||
// initialize events on the new page
|
||||
initializePage(document.querySelector(".document-container"));
|
||||
initializePage(document.querySelector(".outline-tree"));
|
||||
|
||||
document.title = doc.title;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the page is not able to load instead add a header saying the page doesn't exist
|
||||
document.querySelector(".markdown-preview-view").innerHTML =
|
||||
`
|
||||
<div>
|
||||
<center style='position: relative; transform: translateY(20vh); width: 100%; text-align: center;'>
|
||||
<h1 style>Page Not Found</h1>
|
||||
</center>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.querySelector(".outline-tree").innerHTML = "";
|
||||
|
||||
console.log("Page not found: " + getAbsoluteRootPath() + url);
|
||||
let newRootPath = getURLRootPath(getAbsoluteRootPath() + url);
|
||||
rootPath = newRootPath;
|
||||
document.querySelector("base").href = newRootPath;
|
||||
|
||||
document.title = "Page Not Found";
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
function setActiveDocument(url, scrollTo = true, pushHistory = true)
|
||||
{
|
||||
let pathnameTarget = url.split("#")[0] ?? url; // path with no header
|
||||
|
||||
// switch active file in file tree
|
||||
document.querySelector(".tree-item.mod-active")?.classList.remove("mod-active");
|
||||
let treeItems = Array.from(document.querySelectorAll(".tree-item > .tree-item-contents > .tree-item-link"));
|
||||
let treeItem = undefined;
|
||||
for (let item of treeItems)
|
||||
{
|
||||
if (item.getAttribute("href") == url)
|
||||
{
|
||||
let parent = item.parentElement.parentElement;
|
||||
|
||||
parent.classList.add("mod-active");
|
||||
treeItem = parent;
|
||||
|
||||
while (parent.hasAttribute("data-depth"))
|
||||
{
|
||||
setTreeCollapsed(parent, false, false);
|
||||
parent = parent.parentElement.parentElement;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(scrollTo) treeItem?.scrollIntoView({block: "center", inline: "nearest"});
|
||||
|
||||
// set the active file in th graph view
|
||||
if(typeof nodes != 'undefined' && window.renderWorker)
|
||||
{
|
||||
let activeNode = nodes?.paths.findIndex(function(item) { return item.endsWith(pathnameTarget); }) ?? -1;
|
||||
|
||||
if(activeNode >= 0)
|
||||
{
|
||||
window.renderWorker.activeNode = activeNode;
|
||||
}
|
||||
}
|
||||
|
||||
if(pushHistory && window.location.protocol != "file:") window.history.pushState({ path: pathnameTarget }, '', pathnameTarget);
|
||||
}
|
||||
|
||||
//#region Initialization
|
||||
function setupThemeToggle(setupOnNode)
|
||||
{
|
||||
if (localStorage.getItem("theme_toggle") != null)
|
||||
{
|
||||
setThemeToggle(localStorage.getItem("theme_toggle") == "true");
|
||||
}
|
||||
|
||||
var lastScheme = "theme-dark";
|
||||
|
||||
// change theme to match current system theme
|
||||
if (localStorage.getItem("theme_toggle") == null && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
{
|
||||
setThemeToggle(true);
|
||||
lastScheme = "theme-dark";
|
||||
}
|
||||
if (localStorage.getItem("theme_toggle") == null && window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches)
|
||||
{
|
||||
setThemeToggle(true);
|
||||
lastScheme = "theme-light";
|
||||
}
|
||||
|
||||
// set initial toggle state based on body theme class
|
||||
if (document.body.classList.contains("theme-light"))
|
||||
{
|
||||
setThemeToggle(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setThemeToggle(true);
|
||||
}
|
||||
|
||||
function setThemeToggle(state, instant = false)
|
||||
{
|
||||
let toggle = document.querySelector(".theme-toggle-input");
|
||||
|
||||
toggle.checked = state;
|
||||
|
||||
if (instant)
|
||||
{
|
||||
var oldTransition = document.body.style.transition;
|
||||
document.body.style.transition = "none";
|
||||
}
|
||||
|
||||
if(!toggle.classList.contains("is-checked") && state)
|
||||
{
|
||||
toggle.classList.add("is-checked");
|
||||
}
|
||||
else if (toggle.classList.contains("is-checked") && !state)
|
||||
{
|
||||
toggle.classList.remove("is-checked");
|
||||
}
|
||||
|
||||
if(!state)
|
||||
{
|
||||
if (document.body.classList.contains("theme-dark"))
|
||||
{
|
||||
document.body.classList.remove("theme-dark");
|
||||
}
|
||||
|
||||
if (!document.body.classList.contains("theme-light"))
|
||||
{
|
||||
document.body.classList.add("theme-light");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (document.body.classList.contains("theme-light"))
|
||||
{
|
||||
document.body.classList.remove("theme-light");
|
||||
}
|
||||
|
||||
if (!document.body.classList.contains("theme-dark"))
|
||||
{
|
||||
document.body.classList.add("theme-dark");
|
||||
}
|
||||
}
|
||||
|
||||
if (instant)
|
||||
{
|
||||
setTimeout(function()
|
||||
{
|
||||
document.body.style.transition = oldTransition;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
localStorage.setItem("theme_toggle", state ? "true" : "false");
|
||||
}
|
||||
|
||||
setupOnNode.querySelector(".theme-toggle-input")?.addEventListener("change", event =>
|
||||
{
|
||||
setThemeToggle(!(localStorage.getItem("theme_toggle") == "true"));
|
||||
});
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event =>
|
||||
{
|
||||
// return if we are printing
|
||||
if (window.matchMedia('print').matches)
|
||||
{
|
||||
printing = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let newColorScheme = event.matches ? "theme-dark" : "theme-light";
|
||||
|
||||
if (newColorScheme == lastScheme) return;
|
||||
|
||||
if (newColorScheme == "theme-dark")
|
||||
{
|
||||
setThemeToggle(true);
|
||||
}
|
||||
|
||||
if (newColorScheme == "theme-light")
|
||||
{
|
||||
setThemeToggle(false);
|
||||
}
|
||||
|
||||
lastScheme = newColorScheme;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function setupHeaders(setupOnNode)
|
||||
{
|
||||
// MAKE HEADERS COLLAPSIBLE
|
||||
setupOnNode.querySelectorAll(".heading-collapse-indicator").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function ()
|
||||
{
|
||||
var isOpen = !this.parentElement.parentElement.classList.contains("is-collapsed");
|
||||
setHeaderOpen(this.parentElement.parentElement, !isOpen);
|
||||
});
|
||||
});
|
||||
|
||||
// unfold header when an internal link that points to that header is clicked
|
||||
setupOnNode.querySelectorAll("a.internal-link, a.tree-item-link").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function (event)
|
||||
{
|
||||
event.preventDefault();
|
||||
let target = this.getAttribute("href");
|
||||
|
||||
// if the target is a header uncollapse it
|
||||
if (target.startsWith("#"))
|
||||
{
|
||||
console.log("Uncollapsing header: " + target);
|
||||
let header = document.getElementById(target.substring(1));
|
||||
setHeaderOpen(header.parentElement, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupTrees(setupOnNode)
|
||||
{
|
||||
const fileTreeItems = Array.from(setupOnNode.querySelectorAll(".tree-container.file-tree .tree-item"));
|
||||
|
||||
setupOnNode.querySelectorAll(".tree-item-contents > .collapse-icon").forEach(function(item)
|
||||
{
|
||||
item.addEventListener("click", function()
|
||||
{
|
||||
toggleTreeCollapsed(item.parentElement.parentElement);
|
||||
});
|
||||
});
|
||||
|
||||
let fileTreeCollapse = setupOnNode.querySelector(".tree-container.file-tree .collapse-tree-button");
|
||||
if (fileTreeCollapse) fileTreeCollapse.addEventListener("click", async function()
|
||||
{
|
||||
let fileTreeIsCollapsed = fileTreeCollapse.classList.contains("is-collapsed");
|
||||
|
||||
setTreeCollapsedAll(fileTreeItems, !fileTreeIsCollapsed, fileTreeItems.length < 100);
|
||||
|
||||
fileTreeCollapse.classList.toggle("is-collapsed");
|
||||
fileTreeCollapse.querySelector("iconify-icon").setAttribute("icon", fileTreeIsCollapsed ? "ph:arrows-out-line-horizontal-bold" : "ph:arrows-in-line-horizontal-bold");
|
||||
});
|
||||
|
||||
|
||||
let outlineTreeCollapse = setupOnNode.querySelector(".tree-container.outline-tree .collapse-tree-button");
|
||||
if(outlineTreeCollapse) outlineTreeCollapse.addEventListener("click", async function()
|
||||
{
|
||||
let outlineTreeIsCollapsed = outlineTreeCollapse.classList.contains("is-collapsed");
|
||||
|
||||
let items = Array.from(outlineTreeCollapse.parentElement.parentElement.querySelectorAll(".tree-item"));
|
||||
setTreeCollapsedAll(items, !outlineTreeIsCollapsed, items.length < 100);
|
||||
|
||||
outlineTreeCollapse.classList.toggle("is-collapsed");
|
||||
outlineTreeCollapse.querySelector("iconify-icon").setAttribute("icon", outlineTreeIsCollapsed ? "ph:arrows-out-line-horizontal-bold" : "ph:arrows-in-line-horizontal-bold");
|
||||
});
|
||||
|
||||
// start with all closed
|
||||
setupOnNode.querySelectorAll(".tree-container .tree-item").forEach(function(item)
|
||||
{
|
||||
if (item.classList.contains("is-collapsed")) setTreeCollapsed(item, true, false);
|
||||
});
|
||||
|
||||
// make sure the icons match their starting collaped state
|
||||
setupOnNode.querySelectorAll(".tree-container > .tree-header > .collapse-tree-button").forEach(function(item)
|
||||
{
|
||||
if (item.classList.contains("is-collapsed"))
|
||||
{
|
||||
item.querySelector("iconify-icon").setAttribute("icon", "ph:arrows-out-line-horizontal-bold");
|
||||
}
|
||||
else
|
||||
{
|
||||
item.querySelector("iconify-icon").setAttribute("icon", "ph:arrows-in-line-horizontal-bold");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setupCallouts(setupOnNode)
|
||||
{
|
||||
// MAKE CALLOUTS COLLAPSIBLE
|
||||
// if the callout title is clicked, toggle the display of .callout-content
|
||||
setupOnNode.querySelectorAll(".callout.is-collapsible .callout-title").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function ()
|
||||
{
|
||||
var parent = this.parentElement;
|
||||
var isCollapsed = parent.classList.contains("is-collapsed");
|
||||
|
||||
parent.classList.toggle("is-collapsed");
|
||||
element.querySelector(".callout-fold").classList.toggle("is-collapsed");
|
||||
|
||||
slideToggle(parent.querySelector(".callout-content"), 100);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function setupCheckboxes(setupOnNode)
|
||||
{
|
||||
// Fix checkboxed toggling .is-checked
|
||||
setupOnNode.querySelectorAll(".task-list-item-checkbox").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function ()
|
||||
{
|
||||
var parent = this.parentElement;
|
||||
parent.classList.toggle("is-checked");
|
||||
parent.setAttribute("data-task", parent.classList.contains("is-checked") ? "x" : " ");
|
||||
});
|
||||
});
|
||||
|
||||
setupOnNode.querySelectorAll(`.plugin-tasks-list-item input[type="checkbox"]`).forEach(function(checkbox)
|
||||
{
|
||||
checkbox.checked = checkbox.parentElement.classList.contains("is-checked");
|
||||
});
|
||||
|
||||
setupOnNode.querySelectorAll('.kanban-plugin__item.is-complete').forEach(function(checkbox)
|
||||
{
|
||||
checkbox.querySelector('input[type="checkbox"]').checked = true;
|
||||
});
|
||||
}
|
||||
|
||||
function setupCanvas(setupOnNode)
|
||||
{
|
||||
let focusedNode = null;
|
||||
|
||||
// make canvas nodes selectable
|
||||
setupOnNode.querySelectorAll(".canvas-node-content-blocker").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function ()
|
||||
{
|
||||
var parent = this.parentElement.parentElement;
|
||||
parent.classList.toggle("is-focused");
|
||||
this.style.display = "none";
|
||||
|
||||
if (focusedNode)
|
||||
{
|
||||
focusedNode.classList.remove("is-focused");
|
||||
focusedNode.querySelector(".canvas-node-content-blocker").style.display = "";
|
||||
}
|
||||
|
||||
focusedNode = parent;
|
||||
});
|
||||
});
|
||||
|
||||
// make canvas node deselect when clicking outside
|
||||
// document.addEventListener("click", function (event)
|
||||
// {
|
||||
// if (!event.target.closest(".canvas-node"))
|
||||
// {
|
||||
// document.querySelectorAll(".canvas-node").forEach(function (node)
|
||||
// {
|
||||
// node.classList.remove("is-focused");
|
||||
// node.querySelector(".canvas-node-content-blocker").style.display = "";
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
function setupCodeblocks(setupOnNode)
|
||||
{
|
||||
// make code snippet block copy button copy the code to the clipboard
|
||||
setupOnNode.querySelectorAll(".copy-code-button").forEach(function (element)
|
||||
{
|
||||
element.addEventListener("click", function ()
|
||||
{
|
||||
var code = this.parentElement.querySelector("code").textContent;
|
||||
navigator.clipboard.writeText(code);
|
||||
this.textContent = "Copied!";
|
||||
// set a timeout to change the text back
|
||||
setTimeout(function ()
|
||||
{
|
||||
setupOnNode.querySelectorAll(".copy-code-button").forEach(function (button)
|
||||
{
|
||||
button.textContent = "Copy";
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupLinks(setupOnNode)
|
||||
{
|
||||
setupOnNode.querySelectorAll(".internal-link, .footnote-link, .tree-item-link").forEach(function(link)
|
||||
{
|
||||
link.addEventListener("click", function(event)
|
||||
{
|
||||
let target = link.getAttribute("href");
|
||||
event.preventDefault();
|
||||
|
||||
// this is linking to a different page
|
||||
if (!target.startsWith("#"))
|
||||
{
|
||||
// load doc, if it is a tree link then don't scroll to the active doc in the file tree
|
||||
loadDocument(target, true, !link.classList.contains("tree-item-link"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
let headerTarget = document.getElementById(target.substring(1));
|
||||
setHeaderOpen(headerTarget.parentElement, true);
|
||||
headerTarget.scrollIntoView();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.onpopstate = function(event)
|
||||
{
|
||||
loadDocument(getURLPath(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// What the FUCK is this abomination??? - Endermanch, 2023
|
||||
/* let sidebarWidth = undefined;
|
||||
let lineWidth = undefined;
|
||||
function setupResize(setupOnNode)
|
||||
{
|
||||
if (setupOnNode != document) return;
|
||||
|
||||
function updateSidebars()
|
||||
{
|
||||
let rightSidebar = document.querySelector(".sidebar-right");
|
||||
let leftSidebar = document.querySelector(".sidebar-left");
|
||||
let sidebarCount = (rightSidebar ? 1 : 0) + (leftSidebar ? 1 : 0);
|
||||
|
||||
if (sidebarCount == 0) return;
|
||||
|
||||
if(!sidebarWidth) sidebarWidth = Math.max(rightSidebar?.clientWidth, leftSidebar?.clientWidth);
|
||||
|
||||
if (!lineWidth)
|
||||
{
|
||||
let docWidthTestEl = document.createElement("div");
|
||||
document.querySelector(".markdown-preview-view").appendChild(docWidthTestEl);
|
||||
docWidthTestEl.style.width = "var(--line-width)";
|
||||
docWidthTestEl.style.minWidth = "var(--line-width)";
|
||||
docWidthTestEl.style.maxWidth = "var(--line-width)";
|
||||
lineWidth = docWidthTestEl.clientWidth;
|
||||
docWidthTestEl.remove();
|
||||
}
|
||||
|
||||
let letHideRightThreshold = sidebarWidth * sidebarCount + lineWidth / 2;
|
||||
|
||||
if (window.innerWidth < letHideRightThreshold)
|
||||
{
|
||||
rightSidebar.style.display = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
rightSidebar.style.display = "";
|
||||
}
|
||||
|
||||
let letHideLeftThreshold = lineWidth / 2 + sidebarWidth;
|
||||
|
||||
if (window.innerWidth < letHideLeftThreshold)
|
||||
{
|
||||
leftSidebar.style.display = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
leftSidebar.style.display = "";
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", function()
|
||||
{
|
||||
updateSidebars();
|
||||
});
|
||||
|
||||
updateSidebars();
|
||||
}
|
||||
*/
|
||||
|
||||
function setupRootPath(fromDocument)
|
||||
{
|
||||
let basePath = fromDocument.querySelector("#root-path").getAttribute("root-path");
|
||||
document.querySelector("base").href = basePath;
|
||||
document.querySelector("#root-path").setAttribute("root-path", basePath);
|
||||
rootPath = basePath;
|
||||
}
|
||||
|
||||
let touchDrag = false;
|
||||
|
||||
function initializePage(setupOnNode)
|
||||
{
|
||||
setupThemeToggle(setupOnNode);
|
||||
setupHeaders(setupOnNode);
|
||||
setupTrees(setupOnNode);
|
||||
setupCallouts(setupOnNode);
|
||||
setupCheckboxes(setupOnNode);
|
||||
setupCanvas(setupOnNode);
|
||||
setupCodeblocks(setupOnNode);
|
||||
setupLinks(setupOnNode);
|
||||
|
||||
setupOnNode.querySelectorAll("*").forEach(function(element)
|
||||
{
|
||||
element.addEventListener("touchend", function(event)
|
||||
{
|
||||
if (touchDrag)
|
||||
{
|
||||
touchDrag = false;
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (element instanceof HTMLElement) element.click();
|
||||
});
|
||||
});
|
||||
|
||||
if(setupOnNode == document)
|
||||
{
|
||||
document.body.addEventListener("touchmove", function(event)
|
||||
{
|
||||
event.stopImmediatePropagation();
|
||||
touchDrag = true;
|
||||
});
|
||||
|
||||
setupRootPath(document);
|
||||
setActiveDocument(getURLPath());
|
||||
}
|
||||
}
|
||||
|
||||
function initializeForFileProtocol()
|
||||
{
|
||||
let graphEl = document.querySelector(".graph-view-placeholder");
|
||||
if(graphEl)
|
||||
{
|
||||
console.log("Running locally, skipping graph view initialization and hiding graph.");
|
||||
graphEl.style.display = "none";
|
||||
graphEl.previousElementSibling.style.display = "none"; // hide the graph's header
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
window.onload = function()
|
||||
{
|
||||
if (window.location.protocol == "file:") initializeForFileProtocol();
|
||||
initializePage(document);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,733 @@
|
||||
/*#region Code Copy */
|
||||
|
||||
/* Make code block copy button fade in and out */
|
||||
.markdown-rendered pre:not(:hover) > button.copy-code-button
|
||||
{
|
||||
display: unset;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.markdown-rendered pre:hover > button.copy-code-button
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.markdown-rendered pre button.copy-code-button
|
||||
{
|
||||
transition: opacity 0.2s ease-in-out, width 0.3s ease-in-out, background-color 0.2s ease-in-out;
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.markdown-rendered pre > button.copy-code-button:hover
|
||||
{
|
||||
background-color: var(--interactive-normal);
|
||||
}
|
||||
|
||||
.markdown-rendered pre > button.copy-code-button:active
|
||||
{
|
||||
background-color: var(--interactive-hover);
|
||||
box-shadow: var(--input-shadow);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Canvas */
|
||||
.canvas-card-menu {
|
||||
display: none;
|
||||
cursor: default !important;
|
||||
|
||||
}
|
||||
|
||||
.canvas-controls {
|
||||
display: none;
|
||||
cursor: default !important;
|
||||
|
||||
}
|
||||
|
||||
.canvas-node-connection-point
|
||||
{
|
||||
display: none;
|
||||
cursor: default !important;
|
||||
|
||||
}
|
||||
|
||||
.canvas-menu-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.canvas-node-content-blocker
|
||||
{
|
||||
display: none;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.canvas-wrapper
|
||||
{
|
||||
position: relative;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.canvas-node-resizer
|
||||
{
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.canvas-node-container
|
||||
{
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Sidebars */
|
||||
|
||||
.sidebar {
|
||||
background-color: var(--background-secondary);
|
||||
flex: 1 0 min-content;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sidebar-section-header
|
||||
{
|
||||
margin: 0em 0 0em var(--sidebar-margin);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar-content {
|
||||
width: var(--sidebar-width);
|
||||
line-height: var(--line-height-tight);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sidebar-scroll-area
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: var(--line-height-tight);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.sidebar-left
|
||||
{
|
||||
border-right: 1px dashed var(--divider-color);
|
||||
z-index: 1000;
|
||||
align-items: flex-end;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.sidebar-right
|
||||
{
|
||||
border-left: 1px dashed var(--divider-color);
|
||||
z-index: 1000;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@media print
|
||||
{
|
||||
.sidebar, .outline-container, .theme-toggle-container, .theme-toggle-container-inline, .toggle-background, .theme-toggle-input
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Content / Markdown Preview View */
|
||||
|
||||
.webpage-container {
|
||||
background-color: var(--background-primary);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
align-items: stretch;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.document-container
|
||||
{
|
||||
flex-basis: var(--content-width);
|
||||
}
|
||||
|
||||
.markdown-reading-view
|
||||
{
|
||||
align-self: center;
|
||||
-ms-flex-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.markdown-preview-view
|
||||
{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding-bottom: 30em;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.document-container > .markdown-preview-view > .markdown-preview-sizer
|
||||
{
|
||||
padding: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
margin: unset;
|
||||
max-width: unset;
|
||||
min-height: unset;
|
||||
max-width: var(--line-width);
|
||||
flex-basis: var(--line-width);
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Kanban */
|
||||
|
||||
.markdown-preview-view.kanban-plugin__markdown-preview-view {
|
||||
font-family: var(--font-text, var(--default-font));
|
||||
font-size: .875rem;
|
||||
line-height: var(--line-height-tight);
|
||||
padding: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
position: unset;
|
||||
overflow-y: unset;
|
||||
overflow-wrap: unset;
|
||||
color: unset;
|
||||
user-select: unset;
|
||||
-webkit-user-select: unset;
|
||||
}
|
||||
|
||||
.kanban-plugin__item-button-wrapper, .kanban-plugin__lane-grip, .kanban-plugin__lane-settings-button.clickable-icon, .kanban-plugin__item-postfix-button.clickable-icon
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Tree */
|
||||
|
||||
/* Base tree */
|
||||
.tree-container
|
||||
{
|
||||
/* padding-bottom: 12px; */
|
||||
/* margin: 12px; */
|
||||
/* height: 100%; */
|
||||
/* position: relative; */
|
||||
/* display: contents; */
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
margin: var(--sidebar-margin);
|
||||
margin-top: 3em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tree-container .tree-header
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: -3em;
|
||||
}
|
||||
|
||||
.tree-container .tree-header .sidebar-section-header
|
||||
{
|
||||
margin: 1em;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.tree-container:has(.tree-scroll-area:empty)
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tree-container .tree-scroll-area
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
overflow-y: scroll;
|
||||
padding: 1em;
|
||||
padding-right: calc(1em + var(--sidebar-margin));
|
||||
padding-bottom: 3em;
|
||||
border-radius: var(--radius-m);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tree-container .tree-item
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tree-container .tree-item-children
|
||||
{
|
||||
padding: 0;
|
||||
margin-left: 0;
|
||||
border-left: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tree-container .tree-item.mod-active > .tree-item-contents > .tree-item-link
|
||||
{
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.tree-container .tree-item-contents {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border-radius: 0.4em;
|
||||
color: var(--nav-item-color);
|
||||
width: 100%;
|
||||
margin-left: var(--tree-horizontal-spacing);
|
||||
}
|
||||
|
||||
.tree-container .tree-item-contents:active
|
||||
{
|
||||
color: var(--nav-item-color-active);
|
||||
}
|
||||
|
||||
.tree-container a.tree-item-link
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: background-color 0.1s;
|
||||
border-radius: var(--radius-s);
|
||||
padding-left: calc(var(--tree-horizontal-spacing) + var(--collapse-arrow-size)/2 + 1px);
|
||||
padding-bottom: calc(var(--tree-vertical-spacing) / 2);
|
||||
padding-top: calc(var(--tree-vertical-spacing) / 2);
|
||||
color: var(--nav-item-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tree-container .tree-item-icon.collapse-icon {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
border-radius: var(--radius-s);
|
||||
transition: background-color 0.1s;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tree-container .tree-item.mod-tree-folder > .tree-item-contents > .tree-item-icon.collapse-icon
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.collapse-icon > svg {
|
||||
color: unset !important;
|
||||
}
|
||||
|
||||
.collapse-icon:hover
|
||||
{
|
||||
color: var(--nav-item-color-hover);
|
||||
}
|
||||
|
||||
.tree-container a.tree-item-link:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
color: var(--nav-item-color-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Indentation guide */
|
||||
|
||||
.tree-container > .tree-scroll-area > * .tree-item
|
||||
{
|
||||
margin-left: calc(var(--tree-horizontal-spacing) + var(--collapse-arrow-size) / 2 + 1px);
|
||||
border-left: var(--nav-indentation-guide-width) solid var(--nav-indentation-guide-color);
|
||||
}
|
||||
|
||||
.tree-container .tree-scroll-area > * > * > .tree-item
|
||||
{
|
||||
margin-left: calc(var(--collapse-arrow-size) / 2 + 1px);
|
||||
}
|
||||
|
||||
.tree-container .tree-item.mod-active
|
||||
{
|
||||
border-left: var(--nav-indentation-guide-width) solid var(--color-accent);
|
||||
}
|
||||
|
||||
|
||||
.tree-container .tree-item:hover:not(.mod-active):not(.mod-collapsible):not(:has(.tree-item:hover)) /* Hover */
|
||||
{
|
||||
border-left: var(--nav-indentation-guide-width) solid var(--nav-item-color-hover);
|
||||
}
|
||||
|
||||
.webpage-container .tree-container .tree-item:not(.mod-collapsible) > .tree-item-children > .tree-item,
|
||||
.webpage-container .tree-container > .tree-scroll-area > .tree-item,
|
||||
.webpage-container .tree-container:not(.mod-nav-indicator) .tree-item
|
||||
{
|
||||
border-left: none !important;
|
||||
}
|
||||
|
||||
.webpage-container .tree-container .tree-item:not(.mod-collapsible) > .tree-item-children > .tree-item > .tree-item-contents,
|
||||
.webpage-container .tree-container:not(.mod-nav-indicator) .tree-item .tree-item-contents,
|
||||
.webpage-container .tree-container > .tree-scroll-area > .tree-item > .tree-item-contents
|
||||
{
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
/* Special */
|
||||
|
||||
.tree-container.outline-tree .tree-item[data-depth='1'] > .tree-item-contents > .tree-item-link
|
||||
{
|
||||
font-weight: 900;
|
||||
font-size: 1.1em;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.tree-container .tree-item.is-collapsed > .tree-item-contents > .tree-item-icon.collapse-icon > svg
|
||||
{
|
||||
transition: transform 0.1s ease-in-out;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Headers */
|
||||
|
||||
.collapse-icon svg.svg-icon {
|
||||
color: var(--nav-collapse-icon-color);
|
||||
stroke-width: 4px;
|
||||
width: var(--collapse-arrow-size);
|
||||
height: var(--collapse-arrow-size);
|
||||
transition: transform 100ms ease-in-out 0s;
|
||||
min-width: 10px;
|
||||
min-height: 10px;
|
||||
}
|
||||
|
||||
div.is-collapsed > * > .heading-collapse-indicator.collapse-icon > svg
|
||||
{
|
||||
transition: transform 0.1s ease-in-out;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Text Wrapping */
|
||||
a {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
*
|
||||
{
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Obsidian Columns Plugin */
|
||||
.columnParent {
|
||||
display: flex;
|
||||
padding: 15px 20px;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.columnParent {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.columnChild {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0px;
|
||||
}
|
||||
/*#endregion */
|
||||
|
||||
/*#region Theme Toggle */
|
||||
|
||||
.theme-toggle-container {
|
||||
--toggle-width: 50px;
|
||||
--toggle-height: 23px;
|
||||
--border-radius: calc(var(--toggle-height) / 2);
|
||||
--handle-width: calc(var(--toggle-height) * 0.65);
|
||||
--handle-radius: calc(var(--handle-width) / 2);
|
||||
--handle-margin: calc((var(--toggle-height) / 2.0) - var(--handle-radius));
|
||||
--handle-translation: calc(var(--toggle-width) - var(--handle-width) - (var(--handle-margin) * 2));
|
||||
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
/* animation to expand width, move handle, then contract width */
|
||||
@keyframes toggle-slide-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
transform: translateX(0);
|
||||
}
|
||||
50%
|
||||
{
|
||||
width: calc(var(--toggle-width) * 0.5);
|
||||
}
|
||||
90%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
}
|
||||
100%
|
||||
{
|
||||
transform: translateX(var(--handle-translation));
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes toggle-slide-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
transform: translateX(calc(var(--handle-translation) - ((var(--toggle-width) * 0.33) - var(--handle-width))));
|
||||
}
|
||||
70%
|
||||
{
|
||||
width: calc(var(--toggle-width) * 0.5);
|
||||
}
|
||||
100%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* just exapnd and contract */
|
||||
@keyframes toggle-expand-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
}
|
||||
100%
|
||||
{
|
||||
width: calc(var(--toggle-width) * 0.33);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes toggle-expand-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
transform: translateX(var(--handle-translation));
|
||||
}
|
||||
100%
|
||||
{
|
||||
width: calc(var(--toggle-width) * 0.33);
|
||||
transform: translateX(calc(var(--handle-translation) - ((var(--toggle-width) * 0.33) - var(--handle-width))));
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes toggle-contract
|
||||
{
|
||||
0%
|
||||
{
|
||||
width: calc(var(--toggle-width) * 0.33);
|
||||
}
|
||||
100%
|
||||
{
|
||||
width: var(--handle-width);
|
||||
}
|
||||
}
|
||||
|
||||
.theme-toggle-input {
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Fill in dark mode / default */
|
||||
.toggle-background {
|
||||
position: relative;
|
||||
width: var(--toggle-width);
|
||||
height: var(--toggle-height);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--background-modifier-border);
|
||||
|
||||
transition: background-color 0.2s;
|
||||
z-index: 1000;
|
||||
|
||||
/* box-shadow: inset 0px 0px 100px -70px var(--color-accent); */
|
||||
}
|
||||
|
||||
/* Handle default */
|
||||
.toggle-background::before
|
||||
{
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: var(--handle-margin);
|
||||
top: var(--handle-margin);
|
||||
height: var(--handle-width);
|
||||
width: var(--handle-width);
|
||||
|
||||
border-radius: var(--handle-radius);
|
||||
background-color: var(--text-normal);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
animation: toggle-slide-left 0.2s ease-in-out normal both;
|
||||
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* handle light*/
|
||||
.theme-toggle-input:checked ~ .toggle-background::before
|
||||
{
|
||||
animation: toggle-slide-right 0.2s ease-in-out normal both;
|
||||
}
|
||||
|
||||
.theme-toggle-input:active ~ .toggle-background::before
|
||||
{
|
||||
animation: toggle-expand-right 0.2s ease-in-out normal both;
|
||||
}
|
||||
|
||||
.theme-toggle-input:active:checked ~ .toggle-background::before
|
||||
{
|
||||
animation: toggle-expand-left 0.2s ease-in-out normal both;
|
||||
}
|
||||
|
||||
/* sun moon icon icon default */
|
||||
.toggle-background::after
|
||||
{
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: var(--handle-margin);
|
||||
top: calc(var(--handle-margin));
|
||||
height: var(--handle-width);
|
||||
width: var(--handle-width);
|
||||
transition: transform 0.3s;
|
||||
background: url('https://api.iconify.design/lucide/sun.svg') no-repeat center center;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
/* sun moon icon icon light */
|
||||
.theme-toggle-input:checked ~ .toggle-background::after
|
||||
{
|
||||
transform: translateX(calc(var(--handle-translation) * -1)) scale(0.9);
|
||||
background: url('https://api.iconify.design/lucide/moon.svg?color=white') no-repeat center center;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Graph View */
|
||||
#graph-canvas
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid var(--modal-border-color);
|
||||
border-radius: var(--modal-radius);
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
|
||||
.graph-view-container.expanded
|
||||
{
|
||||
position: fixed;
|
||||
width: 60%;
|
||||
height: 90%;
|
||||
right: 20%;
|
||||
top: 5%;
|
||||
background-color: var(--background-secondary);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.graph-view-container
|
||||
{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 1/1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.graph-icon
|
||||
{
|
||||
cursor: pointer;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.graph-view-container .graph-icon > svg
|
||||
{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
background-color: var(--color-base-00);
|
||||
outline-width: 6px;
|
||||
outline-color: var(--color-base-00);
|
||||
outline-offset: -1px;
|
||||
outline-style: solid;
|
||||
border-radius: 100px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.graph-view-placeholder
|
||||
{
|
||||
padding: 0;
|
||||
width: auto;
|
||||
aspect-ratio: 1/1;
|
||||
position: relative;
|
||||
flex: none;
|
||||
margin: var(--sidebar-margin);
|
||||
}
|
||||
|
||||
.graph-view-placeholder:has(.expanded)
|
||||
{
|
||||
border-radius: var(--modal-radius);
|
||||
border: 1px solid var(--modal-border-color);
|
||||
}
|
||||
|
||||
.scale-down
|
||||
{
|
||||
transition: transform 0.2s ease-in-out;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.scale-up
|
||||
{
|
||||
transition: transform 0.2s ease-in-out;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.graph-expand
|
||||
{
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*#endregion */
|
||||
|
||||
/*#region Tweaks */
|
||||
|
||||
hr
|
||||
{
|
||||
border: none;
|
||||
border-top: var(--hr-thickness) solid;
|
||||
border-color: var(--hr-color);
|
||||
}
|
||||
|
||||
.markdown-embed-link
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*#endregion */
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* Using default theme. */
|
||||
Reference in New Issue
Block a user