mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	Modularize more and add swagger-ui
This commit is contained in:
		
							
								
								
									
										19
									
								
								.eslintrc
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								.eslintrc
									
									
									
									
									
								
							| @@ -2,25 +2,20 @@ | |||||||
|     "extends": [ |     "extends": [ | ||||||
|         "eslint:recommended", |         "eslint:recommended", | ||||||
|         "plugin:@typescript-eslint/recommended-type-checked", |         "plugin:@typescript-eslint/recommended-type-checked", | ||||||
|         "plugin:@typescript-eslint/stylistic-type-checked", |         "plugin:@typescript-eslint/stylistic-type-checked" | ||||||
|         "plugin:solid/typescript" |  | ||||||
|     ], |     ], | ||||||
|     "env": { |     "env": { | ||||||
|         "node": true, |  | ||||||
|         "es2020": true, |         "es2020": true, | ||||||
|         "browser": true, |         "browser": true | ||||||
|         "jquery": true |  | ||||||
|     }, |     }, | ||||||
|     "plugins": ["@typescript-eslint", "solid"], |     "plugins": ["@typescript-eslint"], | ||||||
|     "parser": "@typescript-eslint/parser", |     "parser": "@typescript-eslint/parser", | ||||||
|  |     "ignorePatterns": ["legacy/", "dist/"], | ||||||
|     "parserOptions": { |     "parserOptions": { | ||||||
|         "project": ["./tsconfig.eslint.json"], |         "project": ["./tsconfig.eslint.json"], | ||||||
|         "tsconfigRootDir": ".", |         "tsconfigRootDir": ".", | ||||||
|         "ecmaVersion": 2022, |         "ecmaVersion": 2022, | ||||||
|         "sourceType": "module", |         "sourceType": "module" | ||||||
|         "ecmaFeatures": { |  | ||||||
|             "jsx": true |  | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|     "rules": { |     "rules": { | ||||||
|         "accessor-pairs": "error", |         "accessor-pairs": "error", | ||||||
| @@ -92,9 +87,5 @@ | |||||||
|         "wrap-iife": ["error", "inside"], |         "wrap-iife": ["error", "inside"], | ||||||
|         "yield-star-spacing": "error", |         "yield-star-spacing": "error", | ||||||
|         "yoda": "error" |         "yoda": "error" | ||||||
|     }, |  | ||||||
|     "globals": { |  | ||||||
|         "api": "readonly", |  | ||||||
|         "NodeJS": "readonly" |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										7
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -10,6 +10,7 @@ | |||||||
|       "license": "ISC", |       "license": "ISC", | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@digitak/esrun": "^3.2.24", |         "@digitak/esrun": "^3.2.24", | ||||||
|  |         "@types/swagger-ui": "^3.52.0", | ||||||
|         "@typescript-eslint/eslint-plugin": "^6.7.2", |         "@typescript-eslint/eslint-plugin": "^6.7.2", | ||||||
|         "@typescript-eslint/parser": "^6.7.2", |         "@typescript-eslint/parser": "^6.7.2", | ||||||
|         "dotenv": "^16.3.1", |         "dotenv": "^16.3.1", | ||||||
| @@ -935,6 +936,12 @@ | |||||||
|       "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", |       "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@types/swagger-ui": { | ||||||
|  |       "version": "3.52.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/swagger-ui/-/swagger-ui-3.52.0.tgz", | ||||||
|  |       "integrity": "sha512-SlufixEmh+8CLHNgTfAfCT1icNOF7bXboWabhHr1+hIolqlvfwYJGe7HgRcpI3ChE7HWASmEKLkMu34rxseJjQ==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "node_modules/@typescript-eslint/eslint-plugin": { |     "node_modules/@typescript-eslint/eslint-plugin": { | ||||||
|       "version": "6.7.2", |       "version": "6.7.2", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", | ||||||
|   | |||||||
| @@ -7,12 +7,14 @@ | |||||||
|     "build": "esrun scripts/build.ts", |     "build": "esrun scripts/build.ts", | ||||||
|     "build-main": "esrun scripts/build.ts -- --module=main", |     "build-main": "esrun scripts/build.ts -- --module=main", | ||||||
|     "build-styles": "esrun scripts/build.ts -- --module=styles", |     "build-styles": "esrun scripts/build.ts -- --module=styles", | ||||||
|  |     "dist": "esrun scripts/build.ts -- --minify", | ||||||
|     "test": "echo \"Error: no test specified\" && exit 1" |     "test": "echo \"Error: no test specified\" && exit 1" | ||||||
|   }, |   }, | ||||||
|   "author": "", |   "author": "", | ||||||
|   "license": "ISC", |   "license": "ISC", | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@digitak/esrun": "^3.2.24", |     "@digitak/esrun": "^3.2.24", | ||||||
|  |     "@types/swagger-ui": "^3.52.0", | ||||||
|     "@typescript-eslint/eslint-plugin": "^6.7.2", |     "@typescript-eslint/eslint-plugin": "^6.7.2", | ||||||
|     "@typescript-eslint/parser": "^6.7.2", |     "@typescript-eslint/parser": "^6.7.2", | ||||||
|     "dotenv": "^16.3.1", |     "dotenv": "^16.3.1", | ||||||
|   | |||||||
| @@ -1,5 +1,8 @@ | |||||||
| { | { | ||||||
|     "extends": "../.eslintrc", |     "extends": "../.eslintrc", | ||||||
|  |     "env": { | ||||||
|  |         "node": true | ||||||
|  |     }, | ||||||
|     "rules": { |     "rules": { | ||||||
|         "no-console": "off" |         "no-console": "off" | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -73,9 +73,7 @@ async function runBuild() { | |||||||
|         bundle: true, |         bundle: true, | ||||||
|         outdir: path.join(rootDir, "dist"), |         outdir: path.join(rootDir, "dist"), | ||||||
|         format: "cjs", |         format: "cjs", | ||||||
|         external: ["fs", "path", "electron", "@electron/remote"], |         target: ["chrome96"], | ||||||
|         banner: {js: "const require = mod => {try{return window.require(mod);}catch{return {};}};"}, |  | ||||||
|         target: ["chrome96", "node16"], |  | ||||||
|         loader: { |         loader: { | ||||||
|             ".png": "dataurl", |             ".png": "dataurl", | ||||||
|             ".gif": "dataurl", |             ".gif": "dataurl", | ||||||
|   | |||||||
| @@ -1,31 +0,0 @@ | |||||||
| export default function buildBreadcrumbsFromNav() { |  | ||||||
|     const container = document.createElement("ul"); |  | ||||||
|     container.id = "breadcrumbs"; |  | ||||||
|      |  | ||||||
|     const current = document.querySelector("#menu .active"); |  | ||||||
|     if (!current) return; // Something went really wrong |  | ||||||
|     const wrap = document.createElement("li"); |  | ||||||
|     wrap.append(current.cloneNode(true)); |  | ||||||
|     container.prepend(wrap); |  | ||||||
|     let next = current.closest("ul"); |  | ||||||
|     while (next) { |  | ||||||
|         const clone = next?.previousElementSibling?.querySelector("a")?.cloneNode(true); |  | ||||||
|         if (!clone) continue; // This also means something went very wrong |  | ||||||
|         const wrap = document.createElement("li"); |  | ||||||
|         wrap.append(clone); |  | ||||||
|         container.prepend(wrap); |  | ||||||
|         next = next?.parentElement?.closest("ul") ?? null; |  | ||||||
|         if (!next) { |  | ||||||
|             clone.textContent = ""; |  | ||||||
|             const logo = document.createElement("img"); |  | ||||||
|             logo.src = "https://raw.githubusercontent.com/zadam/trilium/master/images/icon-black.svg"; |  | ||||||
|             clone.appendChild(logo); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // We don't need this at root |  | ||||||
|     if (container.children.length === 1) return; |  | ||||||
|      |  | ||||||
|     const main = document.getElementById("main"); |  | ||||||
|     main?.prepend(container); |  | ||||||
| } |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| export default function addExternalLinks() { |  | ||||||
|     const mapping = { |  | ||||||
|         EGFtX8Uw96FQ: "https://github.com/zadam/trilium" |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     for (const id in mapping) { |  | ||||||
|         const links = document.querySelectorAll<HTMLAnchorElement>(`a[href*="${id}"]`); |  | ||||||
|         if (!links.length) {console.warn(`Could not find link to note id ${id}`); continue;} |  | ||||||
|         for (const link of links) { |  | ||||||
|             link.href = mapping[id as keyof typeof mapping]; |  | ||||||
|             link.target = "_blank"; |  | ||||||
|             link.rel = "noopener noreferrer"; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,11 +1,24 @@ | |||||||
|  | /** | ||||||
|  |  * For some reason Trilium share chooses to have the | ||||||
|  |  * active link be just a <strong> rather than a true | ||||||
|  |  * link with a special style. This fixes that and | ||||||
|  |  * turns the <strong> back into an actual link | ||||||
|  |  * with the correct note id. | ||||||
|  |  */ | ||||||
| export default function fixActiveLink() { | export default function fixActiveLink() { | ||||||
|     const active = document.querySelector("#menu strong"); |     const active = document.querySelector("#menu strong"); | ||||||
|     if (!active) return; // Something is really wrong
 |     if (!active) return; // Something is really wrong
 | ||||||
|  |      | ||||||
|  |     // Currently active note id is stored on body
 | ||||||
|  |     const id = document.body.dataset.noteId; | ||||||
|  | 
 | ||||||
|  |     // Create the new link
 | ||||||
|     const link = document.createElement("a"); |     const link = document.createElement("a"); | ||||||
|     link.className = "type-text active"; |     link.className = "type-text active"; | ||||||
|     link.href = ``; |     link.href = ``; | ||||||
|     link.textContent = active.textContent; |     link.textContent = active.textContent; | ||||||
|     active.replaceWith(link); |  | ||||||
|     const id = document.body.dataset.noteId; |  | ||||||
|     link.href = `./${id}`; |     link.href = `./${id}`; | ||||||
|  | 
 | ||||||
|  |     // Replace the <strong>
 | ||||||
|  |     active.replaceWith(link); | ||||||
| } | } | ||||||
							
								
								
									
										19
									
								
								src/main/fixes/externallinks.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/main/fixes/externallinks.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | /** | ||||||
|  |  * This function just lets us map some note links to be external links. | ||||||
|  |  * This was originally designed to link the Trilium GitHub via a note. | ||||||
|  |  */ | ||||||
|  | export default function addExternalLinks(mapping: Record<string, string>) { | ||||||
|  |     for (const id in mapping) { | ||||||
|  |         const links = document.querySelectorAll<HTMLAnchorElement>(`a[href*="${id}"]`); | ||||||
|  |         if (!links.length) { | ||||||
|  |             // eslint-disable-next-line no-console | ||||||
|  |             console.warn(`Could not find link to note id ${id}`); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         for (const link of links) { | ||||||
|  |             link.href = mapping[id]; | ||||||
|  |             link.target = "_blank"; | ||||||
|  |             link.rel = "noopener noreferrer"; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										62
									
								
								src/main/fixes/submenu.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/main/fixes/submenu.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | const submenuBlacklist = ["ZapIU17QNEyU"]; | ||||||
|  | // if (item.innerHTML.includes(submenuBlacklist[0])) item.className += " hidden"; | ||||||
|  | /* function fixSubMenu() { | ||||||
|  |     const items = document.querySelectorAll("#menu > ul > li"); | ||||||
|  |     for (const item of items) { | ||||||
|  |         const sublist = item.querySelector("ul"); | ||||||
|  |         if (sublist) { | ||||||
|  |             if (sublist.children.length) { | ||||||
|  |                 item.className = "submenu"; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 sublist.remove(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * General premise here is to find all submenus/sublists | ||||||
|  |  * and give them a submenu class. Then any list item  | ||||||
|  |  * that contains one of these submenus gets a submenu-item  | ||||||
|  |  * class. Additionally, any sublist that itself has a  | ||||||
|  |  * sublist is given the class hasSubmenu. | ||||||
|  |  */ | ||||||
|  | export default function fixSubMenu() { | ||||||
|  |     // Get every list item in the navigation | ||||||
|  |     const items = document.querySelectorAll("#menu ul li"); | ||||||
|  |     for (const item of items) { | ||||||
|  |         const sublist = item.querySelector("ul"); | ||||||
|  |          | ||||||
|  |         // If the list item has no submenu, ignore and move on | ||||||
|  |         if (!sublist) continue; | ||||||
|  |  | ||||||
|  |         // There seems to be some weird edge cases where a  | ||||||
|  |         // sublist ul is added but has no list items and | ||||||
|  |         // in trilium the corresponding note has no children | ||||||
|  |         if (!sublist.children.length) { | ||||||
|  |             sublist.remove(); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // If the submenu is part of our blacklist, then | ||||||
|  |         // give it the hidden class. This is for pages | ||||||
|  |         // that have no subcategories and only a long | ||||||
|  |         // list of subpages. | ||||||
|  |         const ihtml = item.innerHTML; | ||||||
|  |         for (const bl of submenuBlacklist) { | ||||||
|  |             if (!ihtml.includes(bl)) continue; | ||||||
|  |             item.classList.add("hidden"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Finally, add the corresponding classes to the elements | ||||||
|  |         item.classList.add("submenu-item"); | ||||||
|  |         sublist.classList.add("submenu"); | ||||||
|  |  | ||||||
|  |         // Currently, this is only used by the sidebar styles to | ||||||
|  |         // adjust margins. TODO: Might be worth investigating a | ||||||
|  |         // different method. | ||||||
|  |         if (sublist.querySelector("ul")?.children.length) sublist.classList.add("hasSubmenu"); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								src/main/fixes/tableheaders.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/main/fixes/tableheaders.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | /** | ||||||
|  |  * This specifically fixes when you have empty corners | ||||||
|  |  * like on tables with column and row headers | ||||||
|  |  */ | ||||||
|  | export default function fixTableHeaders() { | ||||||
|  |     const headers = document.querySelectorAll("th"); | ||||||
|  |     for (const header of headers) { | ||||||
|  |         if (!header.textContent?.trim()) header.classList.add("empty"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| export default function fixTableHeaders() { |  | ||||||
|     Array.from(document.querySelectorAll("th")).forEach(el => { |  | ||||||
|         if (!el.textContent?.trim()) el.classList.add("empty"); |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| import {HLJSApi} from "highlight.js"; |  | ||||||
|  |  | ||||||
| declare const hljs: HLJSApi; |  | ||||||
|  |  | ||||||
| export default function addHljs() { |  | ||||||
|     const link = document.createElement("link"); |  | ||||||
|     link.rel = "stylesheet"; |  | ||||||
|     link.href = "api/notes/cVaK9ZJwx5Hs/download"; |  | ||||||
|     document.head.append(link); |  | ||||||
|  |  | ||||||
|     const script = document.createElement("script"); |  | ||||||
|     script.src = "api/notes/6PVElIem02b5/download"; |  | ||||||
|     script.addEventListener("load", () => { |  | ||||||
|         hljs.registerAliases(["application-javascript-env-frontend", "application-javascript-env-backend"], {languageName: "javascript"}); |  | ||||||
|         hljs.addPlugin({ |  | ||||||
|             "after:highlight": (result) => { |  | ||||||
|                 // Add api global |  | ||||||
|                 result.value = result.value.replaceAll(/([^A-Za-z0-9])api\./g, function(match, prefix) { |  | ||||||
|                     return `${prefix}<span class="hljs-variable language_">api</span>.`; |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|                 // Add jquery global |  | ||||||
|                 result.value = result.value.replaceAll(/([^A-Za-z0-9\.])\$\((.+)\)/g, function(match, prefix, variable) { |  | ||||||
|                     return `${prefix}<span class="hljs-variable language_">$(</span>${variable}<span class="hljs-variable language_">)</span>`; |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         hljs.highlightAll(); |  | ||||||
|     }); |  | ||||||
|     document.head.append(script); |  | ||||||
| } |  | ||||||
| @@ -1,22 +1,75 @@ | |||||||
| import fixActiveLink from "./fixactivelink"; | /* eslint-disable no-console */ | ||||||
| import fixTableHeaders from "./fixtableheaders"; | import fixActiveLink from "./fixes/activelink"; | ||||||
| import highlight from "./highlight"; | import fixTableHeaders from "./fixes/tableheaders"; | ||||||
| import buildSidenav from "./sidenav"; | import highlight from "./other/highlight"; | ||||||
| import buildBreadcrumbs from "./breadcrumbs"; | import buildSidenav from "./navigation/sidenav"; | ||||||
| import fixSubMenu from "./submenu"; | import buildBreadcrumbs from "./navigation/breadcrumbs"; | ||||||
| import generateTOC from "./toc"; | import fixSubMenu from "./fixes/submenu"; | ||||||
| import addExternalLinks from "./externallinks"; | import generateTOC from "./navigation/toc"; | ||||||
|  | import addExternalLinks from "./fixes/externallinks"; | ||||||
|  | import injectSwagger from "./other/swagger"; | ||||||
|  |  | ||||||
| // https://instance-name/api/notes/vW1cXaYNN7OM/download | // https://instance-name/api/notes/vW1cXaYNN7OM/download | ||||||
|  |  | ||||||
|  | const EXTERNAL_LINKS = { | ||||||
|  |     EGFtX8Uw96FQ: "https://github.com/zadam/trilium" | ||||||
|  | }; | ||||||
|  |  | ||||||
| try{fixActiveLink();} catch(e){console.error(e)} | function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Parameters<T>) { | ||||||
| try{highlight();} catch(e){console.error(e)} |     try { | ||||||
| try{fixTableHeaders();} catch(e){console.error(e)} |         func.apply(func, args); | ||||||
| // try{addLogo();} catch{} |     } | ||||||
|  |     catch (e) { | ||||||
|  |         console.error(e); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| try{fixSubMenu();} catch(e){console.error(e)} | // const $try = (func, ...args) => { | ||||||
| try{buildSidenav();} catch(e){console.error(e)} | //     try { | ||||||
| try{buildBreadcrumbs();} catch(e){console.error(e)} | //         func.apply() | ||||||
| try{generateTOC();} catch(e){console.error(e)} | //     } | ||||||
| try{addExternalLinks();} catch(e){console.error(e)} | // }; | ||||||
|  |  | ||||||
|  | // Perform fixes first | ||||||
|  | $try(fixActiveLink); | ||||||
|  | $try(fixTableHeaders); | ||||||
|  | $try(fixSubMenu); | ||||||
|  | $try(addExternalLinks, EXTERNAL_LINKS); | ||||||
|  |  | ||||||
|  | // Now layout changes | ||||||
|  | $try(buildBreadcrumbs); | ||||||
|  | $try(buildSidenav); | ||||||
|  | $try(generateTOC); | ||||||
|  |  | ||||||
|  | // Finally, other features | ||||||
|  | $try(highlight); | ||||||
|  | $try(injectSwagger); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // try {fixActiveLink();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {highlight();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {fixTableHeaders();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try{addLogo();} | ||||||
|  | // catch{} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // try {fixSubMenu();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {buildSidenav();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {buildBreadcrumbs();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {generateTOC();} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|  |  | ||||||
|  | // try {addExternalLinks(EXTERNAL_LINKS);} | ||||||
|  | // catch (e) {console.error(e);} | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								src/main/navigation/breadcrumbs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/main/navigation/breadcrumbs.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | /** | ||||||
|  |  * This build breadcrumb-style navigation using the existing | ||||||
|  |  * tree menu generated by Trilium. The concept is to find | ||||||
|  |  * the currently active link (fixed by an earlier script) | ||||||
|  |  * and follow that up to the root part of the menu | ||||||
|  |  */ | ||||||
|  | export default function buildBreadcrumbsFromNav() { | ||||||
|  |     const container = document.createElement("ul"); | ||||||
|  |     container.id = "breadcrumbs"; | ||||||
|  |      | ||||||
|  |     // Find currently active link | ||||||
|  |     const current = document.querySelector("#menu .active"); | ||||||
|  |     if (!current) return; // Something went really wrong | ||||||
|  |  | ||||||
|  |     // Clone the link and add it to the front of the breadcrumb list | ||||||
|  |     const firstItem = document.createElement("li"); | ||||||
|  |     firstItem.append(current.cloneNode(true)); | ||||||
|  |     container.prepend(firstItem); | ||||||
|  |  | ||||||
|  |     // Walk the sublists upward until the root | ||||||
|  |     let next = current.closest("ul"); | ||||||
|  |     while (next) { | ||||||
|  |         const clone = next?.previousElementSibling?.querySelector("a")?.cloneNode(true); | ||||||
|  |         if (!clone) continue; // This also means something went very wrong | ||||||
|  |  | ||||||
|  |         // Get the parent of the previous and add to front of breadcrumbs | ||||||
|  |         const ancestorItem = document.createElement("li"); | ||||||
|  |         ancestorItem.append(clone); | ||||||
|  |         container.prepend(ancestorItem); | ||||||
|  |  | ||||||
|  |         // Get the next sublist upward | ||||||
|  |         next = next?.parentElement?.closest("ul") ?? null; | ||||||
|  |  | ||||||
|  |         // We are not yet at root, continue | ||||||
|  |         if (next) continue; | ||||||
|  |          | ||||||
|  |         // Since next == null, we are at root, let's ue a pretty logo | ||||||
|  |         clone.textContent = ""; | ||||||
|  |         const logo = document.createElement("img"); | ||||||
|  |         logo.src = "https://raw.githubusercontent.com/zadam/trilium/master/images/icon-black.svg"; | ||||||
|  |         clone.appendChild(logo); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // We don't need this at root | ||||||
|  |     if (container.children.length === 1) return; | ||||||
|  |      | ||||||
|  |     // Add breadcrumb container to the main layout | ||||||
|  |     const main = document.getElementById("main"); | ||||||
|  |     main?.prepend(container); | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								src/main/navigation/sidenav.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/main/navigation/sidenav.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | /** | ||||||
|  |  * This generates a docs-style sidebar navigation using the Trilium tree | ||||||
|  |  */ | ||||||
|  | export default function addSideNav() { | ||||||
|  |     // Give all tier 2 list items category class... TODO: should this be done elsewhere? | ||||||
|  |     const categories = document.querySelectorAll("#menu > ul > li > ul > li"); | ||||||
|  |     for (const cat of categories) cat.classList.add("category"); | ||||||
|  |  | ||||||
|  |     // Use the active link as our reference point | ||||||
|  |     const active = document.querySelector("#menu .active"); | ||||||
|  |  | ||||||
|  |     // From the active link, find the nearest category that is also a submenu item | ||||||
|  |     // If there is none, try to grab the nearest hidden submenu item (for non- | ||||||
|  |     // category style pages) | ||||||
|  |     const treeToClone = active?.closest(".category.submenu-item") ?? active?.closest(".submenu-item.hidden"); | ||||||
|  |     if (!treeToClone) return; // If neither exist, 99% chance it's the homepage | ||||||
|  |  | ||||||
|  |     // Clone the found node and add it to the sidebar | ||||||
|  |     const sidebar = document.createElement("ul"); | ||||||
|  |     sidebar.id = "sidebar"; | ||||||
|  |     const clone = treeToClone.cloneNode(true); | ||||||
|  |     sidebar.append(clone); | ||||||
|  |  | ||||||
|  |     // If there's only a single item... probably not worth having a sidebar | ||||||
|  |     if (sidebar.querySelectorAll("li").length <= 1) return; | ||||||
|  |  | ||||||
|  |     // Add the sidebar to the front of the layout container | ||||||
|  |     const layout = document.querySelector("#layout"); | ||||||
|  |     layout?.prepend(sidebar); | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								src/main/navigation/toc.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/main/navigation/toc.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | const slugify = (text: string) => text.toLowerCase().replace(/[^\w]/g, "-"); | ||||||
|  |  | ||||||
|  | const getDepth = (el: Element) => parseInt(el.tagName.replace("H","").replace("h","")); | ||||||
|  |  | ||||||
|  | const buildItem = (heading: Element) => { | ||||||
|  |     const slug = slugify(heading.textContent ?? ""); | ||||||
|  |  | ||||||
|  |     const anchor = document.createElement("a"); | ||||||
|  |     anchor.setAttribute("href", `#${slug}`); | ||||||
|  |     anchor.setAttribute("name", slug); | ||||||
|  |     anchor.setAttribute("id", slug); | ||||||
|  |     anchor.textContent = "#"; | ||||||
|  |  | ||||||
|  |     const link = document.createElement("a"); | ||||||
|  |     link.setAttribute("href", `#${slug}`); | ||||||
|  |     link.textContent = heading.textContent; | ||||||
|  |  | ||||||
|  |     heading.append(anchor); | ||||||
|  |  | ||||||
|  |     const li = document.createElement("li"); | ||||||
|  |     li.append(link); | ||||||
|  |     return li; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Generate a ToC from all heading elements in the main content area. | ||||||
|  |  * This should go to full h6 depth and not be too opinionated. It  | ||||||
|  |  * does assume a "sensible" structure in that you don't go from | ||||||
|  |  * h2 > h4 > h1 but rather h2 > h3 > h2 so you change by 1 and end | ||||||
|  |  * up at the same level as before. | ||||||
|  |  */ | ||||||
|  | export default function generateTOC() { | ||||||
|  |     // Get all headings from the page and map them to already built elements | ||||||
|  |     const headings = Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, h6")); | ||||||
|  |     if (headings.length <= 1) return; // But if there are none, let's do nothing | ||||||
|  |     const items = headings.map(h => buildItem(h)); | ||||||
|  |      | ||||||
|  |     // Setup the ToC list | ||||||
|  |     const toc = document.createElement("ul"); | ||||||
|  |     toc.id = "toc"; | ||||||
|  |  | ||||||
|  |     // Get the depth of the first content heading on the page. | ||||||
|  |     // This depth will be used as reference for all other headings. | ||||||
|  |     // headings[0] === the <h1> from Trilium | ||||||
|  |     const firstDepth = getDepth(headings[1]); | ||||||
|  |  | ||||||
|  |     // Loop over ALL headings including the first | ||||||
|  |     for (let h = 0; h < headings.length; h++) { | ||||||
|  |         // Get current heading and determine depth | ||||||
|  |         const current = headings[h]; | ||||||
|  |         const currentDepth = getDepth(current); | ||||||
|  |  | ||||||
|  |         // If it's the same depth as our first heading, add to ToC | ||||||
|  |         if (currentDepth === firstDepth) toc.append(items[h]); | ||||||
|  |  | ||||||
|  |         // If this is the last element then it will have already | ||||||
|  |         // been added as a child or as same depth as first | ||||||
|  |         let nextIndex = h + 1; | ||||||
|  |         if (nextIndex >= headings.length) continue; | ||||||
|  |  | ||||||
|  |         // Time to find all children of this heading | ||||||
|  |         const children = []; | ||||||
|  |         const childDepth = currentDepth + 1; | ||||||
|  |         let depthOfNext = getDepth(headings[nextIndex]); | ||||||
|  |         while (depthOfNext > currentDepth) { | ||||||
|  |             // If it's the expected depth, add as child | ||||||
|  |             if (depthOfNext === childDepth) children.push(nextIndex); | ||||||
|  |             nextIndex++; | ||||||
|  |  | ||||||
|  |             // If the next index is valid, grab the depth for next loop | ||||||
|  |             // TODO: could this be done cleaner with a for loop? | ||||||
|  |             if (nextIndex < headings.length) depthOfNext = getDepth(headings[nextIndex]); | ||||||
|  |             else depthOfNext = currentDepth; // If the index was invalid, break loop | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // If this heading had children, add them as children | ||||||
|  |         if (children.length) { | ||||||
|  |             const ul = document.createElement("ul"); | ||||||
|  |             for (const c of children) ul.append(items[c]); | ||||||
|  |             items[h].append(ul); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Setup a moving "active" in the ToC that adjusts with the scroll state | ||||||
|  |     const sections = headings.slice(1); | ||||||
|  |     const links = toc.querySelectorAll("a"); | ||||||
|  |     function changeLinkState() { | ||||||
|  |         let index = sections.length; | ||||||
|  |  | ||||||
|  |         // Work backkwards to find the first matching section | ||||||
|  |         while (--index && window.scrollY + 50 < (sections[index] as HTMLElement).offsetTop) {} // eslint-disable-line no-empty | ||||||
|  |  | ||||||
|  |         // Update the "active" item in ToC | ||||||
|  |         links.forEach((link) => link.classList.remove("active")); | ||||||
|  |         links[index].classList.add("active"); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Initial render | ||||||
|  |     changeLinkState(); | ||||||
|  |     window.addEventListener("scroll", changeLinkState); | ||||||
|  |  | ||||||
|  |     // Finally, add the ToC to the end of layout. Give the layout a class for adjusting widths. | ||||||
|  |     const layout = document.querySelector("#layout"); | ||||||
|  |     layout?.classList.add("toc"); | ||||||
|  |     layout?.append(toc); | ||||||
|  | } | ||||||
							
								
								
									
										53
									
								
								src/main/other/highlight.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/main/other/highlight.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | import {HLJSApi, HLJSPlugin} from "highlight.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | declare const hljs: HLJSApi; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Custom highlight.js plugin to highlight the `api` globals for Trilium | ||||||
|  | const highlightTriliumApi: HLJSPlugin = { | ||||||
|  |     "after:highlight": (result) => { | ||||||
|  |         result.value = result.value.replaceAll(/([^A-Za-z0-9])api\./g, function(match, prefix) { | ||||||
|  |             return `${prefix}<span class="hljs-variable language_">api</span>.`; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Custom highlight.js plugin to highlight JQuery function usage | ||||||
|  | const highlightJQuery: HLJSPlugin = { | ||||||
|  |     "after:highlight": (result) => { | ||||||
|  |         result.value = result.value.replaceAll(/([^A-Za-z0-9.])\$\((.+)\)/g, function(match, prefix, variable) { | ||||||
|  |             return `${prefix}<span class="hljs-variable language_">$(</span>${variable}<span class="hljs-variable language_">)</span>`; | ||||||
|  |         }); | ||||||
|  |         // TODO: add highlighting for static calls like $.ajax | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Let's highlight some codeblocks! | ||||||
|  |  * TODO: check if there are codeblocks on the page before performing this action | ||||||
|  |  */ | ||||||
|  | export default function addHljs() { | ||||||
|  |     // 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", () => { | ||||||
|  |         // This registers the JS Frontend and JS Backend types as javascript aliases for highlighting purposes | ||||||
|  |         hljs.registerAliases(["application-javascript-env-frontend", "application-javascript-env-backend"], {languageName: "javascript"}); | ||||||
|  |  | ||||||
|  |         // Add our custom plugins and highlight all on page | ||||||
|  |         hljs.addPlugin(highlightTriliumApi); | ||||||
|  |         hljs.addPlugin(highlightJQuery); | ||||||
|  |         hljs.highlightAll(); | ||||||
|  |     }); | ||||||
|  |     document.head.append(script); | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								src/main/other/swagger.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/main/other/swagger.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | import SwaggerUI, {SwaggerUIOptions} from "swagger-ui"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | declare const SwaggerUIBundle: typeof SwaggerUI; | ||||||
|  | const opts: SwaggerUIOptions = { | ||||||
|  |     url: "https://raw.githubusercontent.com/zadam/trilium/master/src/etapi/etapi.openapi.yaml" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add swagger to the ETAPI page! | ||||||
|  |  */ | ||||||
|  | export default function injectSwagger() { | ||||||
|  |     // Check if it's the ETAPI page, otherwise avoid dependency | ||||||
|  |     const noteId = document.body.dataset.noteId; | ||||||
|  |     if (noteId !== "pPIXi0uwF5GX") return; // TODO: make this a param | ||||||
|  |     const main = document.getElementById("main")!; | ||||||
|  |     main.innerHTML = ""; | ||||||
|  |     opts.domNode = main; | ||||||
|  |     // Add the swagger-ui styles from unpkg | ||||||
|  |     // TODO: make this hosted by trilium | ||||||
|  |     const link = document.createElement("link"); | ||||||
|  |     link.rel = "stylesheet"; | ||||||
|  |     link.href = "https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css"; | ||||||
|  |     document.head.append(link); | ||||||
|  |  | ||||||
|  |     // Add the swagger-ui script too | ||||||
|  |     // TODO: make this hosted by trilium | ||||||
|  |     const script = document.createElement("script"); | ||||||
|  |     script.src = "https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js"; | ||||||
|  |     script.addEventListener("load", () => { | ||||||
|  |         // This immediately generated the swagger-ui in the main element | ||||||
|  |         SwaggerUIBundle(opts); // eslint-disable-line new-cap | ||||||
|  |     }); | ||||||
|  |     document.head.append(script); | ||||||
|  | } | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| export default function addSideNav() { |  | ||||||
|     const categories = document.querySelectorAll("#menu > ul > li > ul > li"); |  | ||||||
|     for (const cat of categories) cat.classList.add("category"); |  | ||||||
|     const active = document.querySelector("#menu .active"); |  | ||||||
|     const treeToClone = active?.closest(".category.submenu-item") ?? active?.closest(".submenu-item.hidden"); |  | ||||||
|     if (!treeToClone) return; // probably homepage |  | ||||||
|     const layout = document.querySelector("#layout"); |  | ||||||
|     const sidebar = document.createElement("ul"); |  | ||||||
|     sidebar.id = "sidebar"; |  | ||||||
|     const clone = treeToClone.cloneNode(true); |  | ||||||
|     /*const title = document.createElement("div"); |  | ||||||
|     title.className = "title"; |  | ||||||
|     title.append(clone.querySelector("p > a")); |  | ||||||
|     sidebar.append(title); |  | ||||||
|     sidebar.append(clone.querySelector("ul"));*/ |  | ||||||
|     sidebar.append(clone); |  | ||||||
|     if (sidebar.querySelectorAll("li").length <= 1) return; |  | ||||||
|     layout?.prepend(sidebar); |  | ||||||
| } |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| const submenuBlacklist = ["ZapIU17QNEyU"] |  | ||||||
| //if (item.innerHTML.includes(submenuBlacklist[0])) item.className += " hidden"; |  | ||||||
| /*function fixSubMenu() { |  | ||||||
|     const items = document.querySelectorAll("#menu > ul > li"); |  | ||||||
|     for (const item of items) { |  | ||||||
|         const sublist = item.querySelector("ul"); |  | ||||||
|         if (sublist) { |  | ||||||
|             if (sublist.children.length) { |  | ||||||
|                 item.className = "submenu"; |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 sublist.remove(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| }*/ |  | ||||||
|  |  | ||||||
| export default function fixSubMenu() { |  | ||||||
|     const items = document.querySelectorAll("#menu ul li"); |  | ||||||
|     for (const item of items) { |  | ||||||
|         const sublist = item.querySelector("ul"); |  | ||||||
|         if (sublist) { |  | ||||||
|             if (sublist.children.length) { |  | ||||||
|                 const ihtml = item.innerHTML; |  | ||||||
|                 for (const bl of submenuBlacklist) { |  | ||||||
|                     if (!ihtml.includes(bl)) continue; |  | ||||||
|                     item.classList.add("hidden"); |  | ||||||
|                 } |  | ||||||
|                 item.classList.add("submenu-item"); |  | ||||||
|                 sublist.classList.add("submenu"); |  | ||||||
|                 if (sublist.querySelector("ul")?.children.length) sublist.classList.add("hasSubmenu"); |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 sublist.remove(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,76 +0,0 @@ | |||||||
| export default function generateTOC() { |  | ||||||
|     const slugify = (text: string) => text.toLowerCase().replace(/[^\w]/g, "-"); |  | ||||||
|     const buildItem = (heading: Element) => { |  | ||||||
|         const slug = slugify(heading.textContent ?? ""); |  | ||||||
|  |  | ||||||
|         const anchor = document.createElement("a"); |  | ||||||
|         anchor.setAttribute("href", `#${slug}`); |  | ||||||
|         anchor.setAttribute("name", slug); |  | ||||||
|         anchor.setAttribute("id", slug); |  | ||||||
|         anchor.textContent = "#"; |  | ||||||
|  |  | ||||||
|         const link = document.createElement("a"); |  | ||||||
|         link.setAttribute("href", `#${slug}`); |  | ||||||
|         link.textContent = heading.textContent; |  | ||||||
|  |  | ||||||
|         heading.append(anchor); |  | ||||||
|  |  | ||||||
|         const li = document.createElement("li"); |  | ||||||
|         li.append(link); |  | ||||||
|         return li; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     const headings = Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, h6")); |  | ||||||
|     const items = headings.map(h => buildItem(h)); |  | ||||||
|     if (headings.length <= 1) return; |  | ||||||
|  |  | ||||||
|     const getNum = (el: Element) => parseInt(el.tagName.replace("H","").replace("h","")); |  | ||||||
|  |  | ||||||
|     const toc = document.createElement("ul"); |  | ||||||
|     toc.id = "toc"; |  | ||||||
|     const first = headings[1]; |  | ||||||
|     const firstDepth = getNum(first); |  | ||||||
|  |  | ||||||
|     for (let h = 0; h < headings.length; h++) { |  | ||||||
|         const current = headings[h]; |  | ||||||
|         const currentDepth = getNum(current); |  | ||||||
|         if (currentDepth === firstDepth) toc.append(items[h]); |  | ||||||
|  |  | ||||||
|         let nextIndex = h + 1; |  | ||||||
|         if (nextIndex >= headings.length) continue; |  | ||||||
|  |  | ||||||
|         const children = []; |  | ||||||
|         const childDepth = currentDepth + 1; |  | ||||||
|         let nextDepth = getNum(headings[nextIndex]); |  | ||||||
|         while (nextDepth > currentDepth) { |  | ||||||
|             if (nextDepth === childDepth) children.push(nextIndex); |  | ||||||
|             nextIndex++; |  | ||||||
|             if (nextIndex < headings.length) nextDepth = getNum(headings[nextIndex]); |  | ||||||
|             else nextDepth = currentDepth; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (children.length) { |  | ||||||
|             const ul = document.createElement("ul"); |  | ||||||
|             for (const c of children) ul.append(items[c]); |  | ||||||
|             items[h].append(ul); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const sections = headings.slice(1); |  | ||||||
|     const links = toc.querySelectorAll("a"); |  | ||||||
|     function changeLinkState() { |  | ||||||
|         let index = sections.length; |  | ||||||
|  |  | ||||||
|         while(--index && window.scrollY + 50 < (sections[index] as HTMLElement).offsetTop) {} |  | ||||||
|  |  | ||||||
|         links.forEach((link) => link.classList.remove('active')); |  | ||||||
|         links[index].classList.add('active'); |  | ||||||
|     } |  | ||||||
|        |  | ||||||
|     changeLinkState(); |  | ||||||
|     window.addEventListener('scroll', changeLinkState); |  | ||||||
|  |  | ||||||
|     const layout = document.querySelector("#layout"); |  | ||||||
|     layout?.classList.add("toc"); |  | ||||||
|     layout?.append(toc) |  | ||||||
| } |  | ||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | @import "./swagger.css"; | ||||||
|  |  | ||||||
| * {box-sizing: border-box;} | * {box-sizing: border-box;} | ||||||
|  |  | ||||||
| :root { | :root { | ||||||
| @@ -8,6 +10,7 @@ | |||||||
|     --ck-color-table-caption-text: gray; |     --ck-color-table-caption-text: gray; | ||||||
|     --bg-primary: #1E1E1E; |     --bg-primary: #1E1E1E; | ||||||
|     --bg-secondary: #3C3C3C; |     --bg-secondary: #3C3C3C; | ||||||
|  |     --text-muted: #777; | ||||||
|     --text-primary: #ddd; |     --text-primary: #ddd; | ||||||
|     --text-heading: #fff; |     --text-heading: #fff; | ||||||
|      |      | ||||||
| @@ -20,6 +23,7 @@ | |||||||
|     --container-width: 1400px /*calc(100% - 10%)*/; |     --container-width: 1400px /*calc(100% - 10%)*/; | ||||||
|     --pane-size: 20%; |     --pane-size: 20%; | ||||||
|     scroll-padding-top: calc(72px + 1rem); |     scroll-padding-top: calc(72px + 1rem); | ||||||
|  |     color-scheme: dark; | ||||||
| } | } | ||||||
|  |  | ||||||
| body { | body { | ||||||
|   | |||||||
							
								
								
									
										85
									
								
								src/styles/swagger.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/styles/swagger.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | #main .swagger-ui .scheme-container { | ||||||
|  |     background: #20212B; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .opblock .opblock-section-header { | ||||||
|  |     background: rgba(0, 0, 0, 0.2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .opblock-body pre.microlight { | ||||||
|  |     background: #20212B!important; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui, | ||||||
|  | #main .swagger-ui .info li, | ||||||
|  | #main .swagger-ui .info p, | ||||||
|  | #main .swagger-ui .info table, | ||||||
|  | #main .swagger-ui .opblock-description-wrapper p, | ||||||
|  | #main .swagger-ui .opblock-external-docs-wrapper p, | ||||||
|  | #main .swagger-ui .opblock-title_normal p, | ||||||
|  | #main .swagger-ui .response-col_status, | ||||||
|  | #main .swagger-ui .response-col_links { | ||||||
|  |     color: var(--text-primary); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .btn, | ||||||
|  | #main .swagger-ui .model, | ||||||
|  | #main .swagger-ui .tab li, | ||||||
|  | #main .swagger-ui table thead tr td, | ||||||
|  | #main .swagger-ui table thead tr th, | ||||||
|  | #main .swagger-ui .parameter__type, | ||||||
|  | #main .swagger-ui .parameter__name, | ||||||
|  | #main .swagger-ui thead tr td.col_header, | ||||||
|  | #main .swagger-ui .model-title { | ||||||
|  |     color: var(--text-heading); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .model .property.primitive { | ||||||
|  |     color: var(--text-muted); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .prop-type { | ||||||
|  |     color: var(--accent-color); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui svg { | ||||||
|  |     fill: var(--text-heading); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #main .swagger-ui .model-toggle::after { | ||||||
|  |     filter: invert(100%); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .btn { | ||||||
|  |     border: 2px solid var(--text-heading); | ||||||
|  |     transition: transform 200ms ease; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .btn:hover { | ||||||
|  |     transform: translateY(-5px); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui input[disabled], | ||||||
|  | #main .swagger-ui select[disabled], | ||||||
|  | #main .swagger-ui textarea[disabled], | ||||||
|  | #main .swagger-ui select { | ||||||
|  |     background: rgba(0, 0, 0, 0.2); | ||||||
|  |     color: var(--text-primary); | ||||||
|  |     border: 2px solid rgba(0,0,0,0.3); | ||||||
|  |     appearance: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #main .models > h4 { | ||||||
|  |     margin: 5px 10px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #main .swagger-ui .opblock-summary-control { | ||||||
|  |     margin-right: 10px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main .swagger-ui .authorization__btn { | ||||||
|  |     padding-left: 0; | ||||||
|  | } | ||||||
| @@ -4,5 +4,5 @@ | |||||||
|         "rootDir": ".", |         "rootDir": ".", | ||||||
|         "noEmit": true |         "noEmit": true | ||||||
|     }, |     }, | ||||||
|     "include": ["src/**/*", "scripts/*", "static/*"], |     "include": ["src/**/*", "scripts/*"], | ||||||
| } | } | ||||||
| @@ -5,30 +5,12 @@ | |||||||
|         "esModuleInterop": true, |         "esModuleInterop": true, | ||||||
|         "allowSyntheticDefaultImports": true, |         "allowSyntheticDefaultImports": true, | ||||||
|         "resolveJsonModule": true, |         "resolveJsonModule": true, | ||||||
|         "declaration": true, |  | ||||||
|         "strictNullChecks": true, |         "strictNullChecks": true, | ||||||
|         "moduleResolution": "Node16", |         "moduleResolution": "Node16", | ||||||
|         "target": "ES2021", |         "target": "ES2021", | ||||||
|         "rootDir": "src", |         "rootDir": "src", | ||||||
|         "outDir": "lib/cjs", |         "outDir": "lib/cjs", | ||||||
|         "module": "Node16", |         "module": "Node16" | ||||||
|         "jsx": "preserve", |  | ||||||
|         "jsxImportSource": "solid-js", |  | ||||||
|     }, |     }, | ||||||
|     "include": ["src/**/*"], |     "include": ["src/**/*"] | ||||||
|     "typedocOptions": { |  | ||||||
|         "name": "TriliumETAPI", |  | ||||||
|         "entryPoints": ["src/index.ts"], |  | ||||||
|         "out": "docs", |  | ||||||
|         "includeVersion": true, |  | ||||||
|         "navigationLinks": { |  | ||||||
|             "Trilium": "https://github.com/zadam/trilium" |  | ||||||
|         }, |  | ||||||
|         "sidebarLinks": {}, |  | ||||||
|         "navigation": { |  | ||||||
|             "fullTree": true, |  | ||||||
|             "includeCategories": true, |  | ||||||
|             "includeGroups": false |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user