From 5391521c0855869807ff1210e7cd6ab25d665755 Mon Sep 17 00:00:00 2001 From: Zack Rauen Date: Sat, 30 Sep 2023 00:13:37 -0400 Subject: [PATCH] Enable sliding categories and extract TODOs --- TODO.md | 29 +++++++++++++++ src/scripts/index.ts | 61 -------------------------------- src/scripts/modules/expanders.ts | 40 +++------------------ src/scripts/modules/highlight.ts | 3 -- src/scripts/modules/search.ts | 3 +- src/scripts/modules/theme.ts | 1 - src/scripts/test.ts | 5 --- src/styles/navbar/navbar.css | 2 +- src/templates/page.ejs | 18 ++++------ src/templates/toc_item.ejs | 4 +-- src/templates/tree_item.ejs | 8 ++--- 11 files changed, 48 insertions(+), 126 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 000000000..4abd37e19 --- /dev/null +++ b/TODO.md @@ -0,0 +1,29 @@ +# TODOs + +This doc contains a list of TODOs taken from the code and organized. This _does not_ includes things like upcoming features or fixes. + +## Scripts + +- Create a logger +- Modify esbuild to allow for a development build to contain debug logs +- Modify custom highlight.js plugin to include highlighting for jQuery global functions +- Either move highlight.js inclusion to template or use a mapping of note IDs to files +- Adjust search to use separate function (clean code) +- Consider never removing the search results from the page and update container instead +- Consolidate theme initialization (DRY) + +## Styles + +- + +## Templates + +- Consider adding highlight.js into the templates instead of scripts +- Find a better way to integrate ts/js to templates (maybe via includes?) + +## Other + +- Create a logical set of attributes for setting open-graph/twitter metadata +- Consider making book type notes explicitly required for full-link category + - This lets text type notes still have content but require clicking arrow to expand +- Find a way to better map template to notes and allow for automatically creating new ones \ No newline at end of file diff --git a/src/scripts/index.ts b/src/scripts/index.ts index b05c31441..38f0933b1 100644 --- a/src/scripts/index.ts +++ b/src/scripts/index.ts @@ -1,30 +1,11 @@ -// import fixActiveLink from "./fixes/activelink"; -// import fixTableHeaders from "./fixes/tableheaders"; import highlight from "./modules/highlight"; -// import buildSidenav from "./navigation/sidenav"; -// import buildBreadcrumbs from "./navigation/breadcrumbs"; -// import fixSubMenus from "./fixes/submenu"; import setupToC from "./modules/toc"; -// import addExternalLinks from "./fixes/externallinks"; -// import injectSwagger from "./other/swagger"; -// import makeMobileMenu from "./other/mobile"; import setupExpanders from "./modules/expanders"; import setupMobileMenu from "./modules/mobile"; import setupSearch from "./modules/search"; import setupThemeSelector from "./modules/theme"; -// const ETAPI_REF_NOTE_ID = "pPIXi0uwF5GX"; -// const HIDDEN_SUBMENUS = ["blog"]; -// const EXTERNAL_LINKS = { -// EGFtX8Uw96FQ: "https://github.com/zadam/trilium", -// dXAKFE0fJtom: "https://discord.gg/eTaTXUgcBr" -// }; -// const ALIASES = { -// WqBnya4Ye8rS: "", -// ZapIU17QNEyU: "blog" -// }; - function $try unknown>(func: T, ...args: Parameters) { try { func.apply(func, args); @@ -33,51 +14,9 @@ function $try unknown>(func: T, ...args: Paramete console.error(e); // eslint-disable-line no-console } } - -/** - * Lots of these functions seem to depend on each other indirectly - * through DOM changes or classes or what-have-you. This is - * obviously not ideal as it makes things less clear, and also - * makes TypeScript less helpful. - * - * TODO: Find a good way of restructuring that allows things - * to act a bit more harmoniously. - * - * TODO: Make use of esbuild's define api to enable a debug - * build that contains all the console logs and such. - */ - -// Perform fixes first -// $try(fixActiveLink, ALIASES); -// $try(fixTableHeaders); -// $try(fixSubMenus, HIDDEN_SUBMENUS); -// $try(addExternalLinks, EXTERNAL_LINKS); - -// Now layout changes -// $try(buildBreadcrumbs); -// $try(buildSidenav); - $try(setupToC); - -// Finally, other features -// TODO: how difficult this would be to implement via -// templates or trilium $try(highlight); -// $try(injectSwagger, ETAPI_REF_NOTE_ID); - -// "Standard" Modules I would recommend the new share -// theme have $try(setupExpanders); $try(setupMobileMenu); $try(setupSearch); $try(setupThemeSelector); -// $try(makeMobileMenu); - -/** - * This no longer uses a traefik plugin and instead a custom - * template being served through Trilium. - * - * TODO: Figure out some good attributes to use to populate - * this inside the template to make it more dynamic - */ -// $try(addOpenGraphMeta); diff --git a/src/scripts/modules/expanders.ts b/src/scripts/modules/expanders.ts index ebcb2ba77..276f34507 100644 --- a/src/scripts/modules/expanders.ts +++ b/src/scripts/modules/expanders.ts @@ -1,30 +1,3 @@ -// function anchorToId(anchor: HTMLAnchorElement) { -// return anchor.href.replace("./", ""); -// } -// -// const stored = localStorage.getItem("expanded") ?? "[]"; -// let parsed: string[]; -// try { -// parsed = JSON.parse(stored) as string[]; -// } -// catch (e) { -// parsed = []; -// } -// const state = new Set(parsed); -// const submenus = Array.from(document.querySelectorAll("#menu .submenu-item")); -// for (const sub of submenus) { -// try { -// if (state.has(anchorToId(sub.children[0] as HTMLAnchorElement))) sub.classList.add("expanded"); -// } -// catch (e) { -// // TODO: create logger -// console.warn("Could not restore expanded state"); // eslint-disable-line no-console -// console.error(e); // eslint-disable-line no-console -// } -// } - -// TODO: Swap this system to use type-book for full-link category - // In case a linked article lead to a new tree const activeLink = document.querySelector("#menu a.active"); if (activeLink) { @@ -45,15 +18,10 @@ export default function setupExpanders() { if ((e.target as Element).closest(".submenu-item,.item") !== ex) return; e.preventDefault(); e.stopPropagation(); - // ex.parentElement.parentElement.classList.toggle("expanded"); - ex.classList.toggle("expanded"); - // const id = anchorToId(ex.closest("a")!); - // if (state.has(id)) state.delete(id); - // else state.add(id); - // // TODO: be able to remove all submenus of currently collapsed - // localStorage.setItem("expanded", JSON.stringify([...state])); + const ul = ex.querySelector("ul")!; + ul.style.height = `${ul.scrollHeight}px`; + setTimeout(() => ex.classList.toggle("expanded"), 1); + setTimeout(() => ul.style.height = ``, 200); }); } - - } \ No newline at end of file diff --git a/src/scripts/modules/highlight.ts b/src/scripts/modules/highlight.ts index 2465c5a68..5d59e7708 100644 --- a/src/scripts/modules/highlight.ts +++ b/src/scripts/modules/highlight.ts @@ -19,7 +19,6 @@ const highlightJQuery: HLJSPlugin = { result.value = result.value.replaceAll(/([^A-Za-z0-9.])\$\((.+)\)/g, function(match, prefix, variable) { return `${prefix}$(${variable})`; }); - // TODO: add highlighting for static calls like $.ajax } }; @@ -32,14 +31,12 @@ export default function addHljs() { if (!codeblocks.length) return; // If there are none, don't add dependency // Add the hightlight.js styles from the child note of this script - // TODO: make this a mapping const link = document.createElement("link"); link.rel = "stylesheet"; link.href = "api/notes/cVaK9ZJwx5Hs/download"; document.head.append(link); // Add the highlight.js script too - // TODO: make this a mappin as well const script = document.createElement("script"); script.src = "api/notes/6PVElIem02b5/download"; script.addEventListener("load", () => { diff --git a/src/scripts/modules/search.ts b/src/scripts/modules/search.ts index c7c77c014..f9c362da5 100644 --- a/src/scripts/modules/search.ts +++ b/src/scripts/modules/search.ts @@ -25,7 +25,6 @@ function buildResultItem(result: SearchResult) { export default function setupSearch() { const searchInput: HTMLInputElement = document.querySelector(".search-input")!; - // TODO: move listener to another function searchInput.addEventListener("keyup", debounce(async () => { // console.log("CHANGE EVENT"); const current = document.body.dataset.noteId; @@ -48,7 +47,7 @@ export default function setupSearch() { container.style.minWidth = `${rect.width}px`; const existing = document.querySelector(".search-results"); - if (existing) existing.replaceWith(container); // TODO: consider updating existing container and never removing + if (existing) existing.replaceWith(container); else document.body.append(container); }, 500)); diff --git a/src/scripts/modules/theme.ts b/src/scripts/modules/theme.ts index 1e3d57a3b..35a2400c2 100644 --- a/src/scripts/modules/theme.ts +++ b/src/scripts/modules/theme.ts @@ -12,7 +12,6 @@ if (preference) { export default function setupThemeSelector() { const themeSwitch: HTMLInputElement = document.querySelector(".theme-selection input")!; - // TODO: consolidate this with initialization (DRY) themeSwitch?.addEventListener("change", () => { if (themeSwitch.checked) { document.body.classList.add("theme-dark"); diff --git a/src/scripts/test.ts b/src/scripts/test.ts index 01a0c62a4..d809aa06a 100644 --- a/src/scripts/test.ts +++ b/src/scripts/test.ts @@ -1,10 +1,5 @@ /* eslint-disable no-console */ -/** - * This script was used for testing ToC generation in the page template... - * TODO: find a better way to integrate ts/js into the templates so I'm - * not debugging on the fly constantly. - */ // const data = `

Trilium  really does rock! Don't believe me? Well this entire website was made using the shared notes feature inside Trilium with a little bit of extra CSS and JS also contained in Trilium.

It turns Trilium into an insanely powerful WYSIWYG website creator. But that's just a side feature of Trilium, it's so much more powerful with endless possibilities.

Why It Rocks

If somehow you aren't already convinced, take a look below for even more reasons why Trilium rocks!

Built-in Features

This section is shamelessly borrowed from Trilium's README.

Community Addons

Nriver maintains an awesome list of addons for Trilium made by the community. Check out the official list on GitHub. We do mirror the list here on the Showcase page if you just want a quick look.

Custom Scripts

In addition to using community made scripts, widgets, themes, and everything in between, Trilium leaves things open-ended for you the end-user. You can script as much or as little as you like inside Trilium. You can automate all kinds of workflows, do data analysis, or even simple things like set a keybind to open a specific note. The world is your oyster as they say, and Trilium is your world. Pretend that made sense.

 

About This Site

This website is not at all affiliated with Trilium Notes or its creator(s). The site is broken up into a few main sections that you can see in the navigation bar at the top of the page. At a high level, there's two sections targeting end-users, two sections targeting developers, and one meant for everyone.

Status

This site is still a work-in-progress! Writing documentation isn't the most fun thing in the world so this will just be something I work on when I have free time. You'll usually find me working on one of my Trilium-related addons, Trilium itself, or my other open-source project: BetterDiscord.

Goals

Rather than saying some specific goals of what this site strives to be, I'll say what it strives not to be; This site is not meant to be a complete recreation of the Wiki with every detail and page included. It is meant to be a (mostly) one-stop shop for users and developers alike looking to supplement their knowledge. It may at some point expand and include everything from the wiki because users tend to prefer a fancier UI like this, but it is not the end-goal.

Contributing

Since this entire site is just a share from my personal Trilium instance, there is no easy way to contribute new pages or fixes for typos. At some point I will create a GitHub repository for this site's supplementary CSS and JS, and that repository can also act as a home for issues and discussion. But who knows, maybe within that time frame I'll think of some clever way to introduce contributions.

 

`; const data = `

Frontend API

The frontend api supports two styles, regular scripts that are run with the current app and note context, and widgets that export an object to Trilium to be used in the UI. In both cases, the frontend api of Trilium is available to scripts running in the frontend context as global variable api. The members and methods of the api can be seen on the FrontendScriptApi page.

Scripts

Scripts don't have any special requirements. They can be run at will using the execute button in the UI or they can be configured to run at certain times using Attributes on the note containing the script.

Global Events

This attribute is called #run and it can have any of the following values:

  • frontendStartup - executes on frontend upon startup.
  • mobileStartup - executes on mobile frontend upon startup.
  • backendStartup - executes on backend upon startup.
  • hourly - executes once an hour on backend.
  • daily - executes once a day on backend.

Entity Events

These events are triggered by certain relations to other notes. Meaning that the script is triggered only if the note has this script attached to it through relations (or it can inherit it).

  • runOnNoteCreation - executes when note is created on backend.
  • runOnNoteTitleChange - executes when note title is changed (includes note creation as well).
  • runOnNoteContentChange - executes when note content is changed (includes note creation as well).
  • runOnNoteChange - executes when note is changed (includes note creation as well).
  • runOnNoteDeletion - executes when note is being deleted.
  • runOnBranchCreation - executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note.
  • runOnBranchDeletion - executes when a branch is delete. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted).
  • runOnChildNoteCreation - executes when new note is created under this note.
  • runOnAttributeCreation - executes when new attribute is created under this note.
  • runOnAttributeChange - executes when attribute is changed under this note.

Widgets

Conversely to scripts, widgets do have some specific requirements in order to work. A widget must:

  • Extend BasicWidget or one of it's subclasses.
  • Create a new instance and assign it to module.exports.
  • Define a parentWidget member to determine where it should be displayed.
  • Define a position (integer) that determines the location via sort order.
  • Have a #widget attribute on the containing note.
  • Create, render, and return your element in the render function.

parentWidget

  • left-pane - This renders the widget on the left side of the screen where the note tree lives.
  • center-pane - This renders the widget in the center of the layout in the same location that notes and splits appear.
  • note-detail-pane - This renders the widget with the note in the center pane. This means it can appear multiple times with splits.
  • right-pane - This renders the widget to the right of any opened notes.

Tutorial

For more information on building widgets, take a look at Widget Basics.

`; const headingRe = /()(.+?)(<\/h[1-6]>)/g; diff --git a/src/styles/navbar/navbar.css b/src/styles/navbar/navbar.css index 7e1adf0e8..5b93d1d3e 100644 --- a/src/styles/navbar/navbar.css +++ b/src/styles/navbar/navbar.css @@ -50,7 +50,7 @@ } #menu li > ul { - transition: height 1000ms ease; + transition: height 200ms ease; } #menu li:not(.expanded) > ul { diff --git a/src/templates/page.ejs b/src/templates/page.ejs index 480f65c3c..afbded51a 100644 --- a/src/templates/page.ejs +++ b/src/templates/page.ejs @@ -65,7 +65,7 @@ const customServerYml = `- url: "{protocol}://{domain}:{port}/etapi" <% } %> <%- header %> <%= note.title %><% if (note.noteId !== subRoot.noteId) { %> - <%= subRoot.title %><% } %> - + @@ -97,9 +97,9 @@ content = content.replaceAll(headingRe, (...match) => { %>
- + <% if (subRoot.hasRelation("shareLogo")) { %> - /download" alt="Logo" /> + /logo.svg" alt="Logo" /> <% } %> <%= subRoot.title %> @@ -109,9 +109,9 @@ content = content.replaceAll(headingRe, (...match) => {