Compare commits

...

29 Commits

Author SHA1 Message Date
Elian Doran
1d259aab9d Improve documentation building & static Swagger (#7570) 2025-11-02 20:24:58 +02:00
Elian Doran
5171675dee chore(build-docs): fix URL 2025-11-02 20:13:10 +02:00
Elian Doran
6bc54892a3 Update apps/build-docs/src/swagger.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 20:12:50 +02:00
Elian Doran
0a6670ce5e Update apps/build-docs/src/backend_script_entrypoint.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-11-02 20:05:44 +02:00
Elian Doran
beb7c66ff5 feat(build-docs): rewrite URLs for in-app help 2025-11-02 19:45:16 +02:00
Elian Doran
966e5a2ef3 chore(build-docs): update meta 2025-11-02 18:33:13 +02:00
Elian Doran
4f5be54030 chore(build-docs): generate types for doc 2025-11-02 18:28:31 +02:00
Elian Doran
68c6260e45 chore(build-docs): relocate OpenAPI location 2025-11-02 18:14:03 +02:00
Elian Doran
85bfd49d1c Merge remote-tracking branch 'origin/main' into feature/api_docs
; Conflicts:
;	_regroup/package.json
;	pnpm-lock.yaml
2025-11-02 18:05:02 +02:00
Elian Doran
3ac248169f chore(build-docs): fix typecheck issues 2025-11-01 23:40:27 +02:00
Elian Doran
15e240ac33 refactor(build-docs): remove old Swagger integration 2025-11-01 23:37:17 +02:00
Elian Doran
d30fc09e73 chore(build-docs): fix link to FNote 2025-11-01 23:13:35 +02:00
Elian Doran
6a2b9b748f chore(build-docs): add project names to typedoc 2025-11-01 23:03:14 +02:00
Elian Doran
b5e2187c0d chore(build-docs): update meta 2025-11-01 23:00:14 +02:00
Elian Doran
d9a349a531 refactor(build-docs): define output for typedoc at script level 2025-11-01 22:54:42 +02:00
Elian Doran
2c1cebfbc3 feat(build-docs): split documentation in two 2025-11-01 22:51:33 +02:00
Elian Doran
c6738ac52f feat(build-docs): generate script API 2025-11-01 22:42:27 +02:00
Elian Doran
604f2abf5a chore(build-docs): fix wrong mkdir 2025-11-01 21:47:07 +02:00
Elian Doran
617703899f chore(build-docs): relocate to /rest-api 2025-11-01 21:35:18 +02:00
Elian Doran
6322ca11c9 feat(share): improve webview layout 2025-11-01 21:28:31 +02:00
Elian Doran
d62aecc551 fix(build-docs): crash in clean environment 2025-11-01 21:15:34 +02:00
Elian Doran
953b376ce3 refactor(build-docs): trigger build of share theme internally 2025-11-01 20:58:32 +02:00
Elian Doran
80f1707d8b chore(build-docs): integrate with docs:build 2025-11-01 20:52:28 +02:00
Elian Doran
4f9f8652e2 fix(build-docs): links to API reference 2025-11-01 20:47:00 +02:00
Elian Doran
6e06d7169f refactor(build-docs): integrate with original build-docs script 2025-11-01 20:37:03 +02:00
Elian Doran
ecf12a4063 feat(build-docs): build both docs 2025-11-01 20:22:17 +02:00
Elian Doran
64428ae761 feat(build-docs): clean before building 2025-11-01 20:16:59 +02:00
Elian Doran
3524c34ff9 feat(build-docs): switch to redocly 2025-11-01 20:15:38 +02:00
Elian Doran
3f99c8b337 feat(build-docs): copy swagger UI 2025-11-01 20:03:53 +02:00
32 changed files with 1520 additions and 431 deletions

View File

@@ -48,9 +48,7 @@
"lorem-ipsum": "2.0.8",
"rcedit": "4.0.1",
"rimraf": "6.1.0",
"tslib": "2.8.1",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
"tslib": "2.8.1"
},
"optionalDependencies": {
"appdmg": "0.6.6"

View File

@@ -1,15 +0,0 @@
{
"entryPoints": [
"src/services/backend_script_entrypoint.ts",
"src/public/app/services/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
],
"outputs": [
{
"name": "html",
"path": "./docs/Script API"
}
]
}

View File

@@ -0,0 +1,22 @@
{
"name": "build-docs",
"version": "1.0.0",
"description": "",
"main": "src/main.ts",
"scripts": {
"start": "tsx ."
},
"keywords": [],
"author": "Elian Doran <contact@eliandoran.me>",
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.19.0",
"devDependencies": {
"@redocly/cli": "2.10.0",
"archiver": "7.0.1",
"fs-extra": "11.3.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

View File

@@ -0,0 +1,36 @@
/**
* The backend script API is accessible to code notes with the "JS (backend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Backend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note on the server side.
*
* Make sure to keep in line with backend's `script_context.ts`.
*/
export type { default as AbstractBeccaEntity } from "../../server/src/becca/entities/abstract_becca_entity.js";
export type { default as BAttachment } from "../../server/src/becca/entities/battachment.js";
export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js";
export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js";
export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js";
export type { BNote };
export type { default as BOption } from "../../server/src/becca/entities/boption.js";
export type { default as BRecentNote } from "../../server/src/becca/entities/brecent_note.js";
export type { default as BRevision } from "../../server/src/becca/entities/brevision.js";
import BNote from "../../server/src/becca/entities/bnote.js";
import BackendScriptApi, { type Api } from "../../server/src/services/backend_script_api.js";
export type { Api };
const fakeNote = new BNote();
/**
* The `api` global variable allows access to the backend script API, which is documented in {@link Api}.
*/
export const api: Api = new BackendScriptApi(fakeNote, {});

View File

@@ -4,14 +4,17 @@ process.env.NODE_ENV = "development";
import cls from "@triliumnext/server/src/services/cls.js";
import { dirname, join, resolve } from "path";
import fs, { copyFile } from "fs/promises";
import fsExtra, { createWriteStream, type WriteStream } from "fs-extra";
import * as fs from "fs/promises";
import * as fsExtra from "fs-extra";
import archiver from "archiver";
import { WriteStream } from "fs";
import { execSync } from "child_process";
import BuildContext from "./context.js";
const DOCS_ROOT = "../../../docs";
const OUTPUT_DIR = "../../site";
async function main() {
async function buildDocsInner() {
const i18n = await import("@triliumnext/server/src/services/i18n.js");
await i18n.initializeTranslations();
@@ -30,7 +33,7 @@ async function main() {
"export",
null
);
const fileOutputStream = createWriteStream(zipFilePath);
const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
await exportToZip(taskContext, branch, "share", fileOutputStream);
await waitForStreamToFinish(fileOutputStream);
await extractZip(zipFilePath, OUTPUT_DIR);
@@ -41,7 +44,7 @@ async function main() {
}
// Copy favicon.
await copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
console.log("Documentation built successfully!");
}
@@ -106,4 +109,19 @@ export async function extractZip(zipFilePath: string, outputPath: string, ignore
});
}
cls.init(main);
export default async function buildDocs({ gitRootDir }: BuildContext) {
// Build the share theme.
execSync(`pnpm run --filter share-theme build`, {
stdio: "inherit",
cwd: gitRootDir
});
// Trigger the actual build.
await new Promise((res, rej) => {
cls.init(() => {
buildDocsInner()
.catch(rej)
.then(res);
});
});
}

View File

@@ -0,0 +1,4 @@
export default interface BuildContext {
gitRootDir: string;
baseDir: string;
}

View File

@@ -0,0 +1,28 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
export type { default as FAttachment } from "../../client/src/entities/fattachment.js";
export type { default as FAttribute } from "../../client/src/entities/fattribute.js";
export type { default as FBranch } from "../../client/src/entities/fbranch.js";
export type { default as FNote } from "../../client/src/entities/fnote.js";
export type { Api } from "../../client/src/services/frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../../client/src/widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@@ -0,0 +1,26 @@
import { join } from "path";
import BuildContext from "./context";
import buildSwagger from "./swagger";
import { existsSync, mkdirSync, rmSync } from "fs";
import buildDocs from "./build-docs";
import buildScriptApi from "./script-api";
const context: BuildContext = {
gitRootDir: join(__dirname, "../../../"),
baseDir: join(__dirname, "../../../site")
};
async function main() {
// Clean input dir.
if (existsSync(context.baseDir)) {
rmSync(context.baseDir, { recursive: true });
}
mkdirSync(context.baseDir);
// Start building.
await buildDocs(context);
buildSwagger(context);
buildScriptApi(context);
}
main();

View File

@@ -0,0 +1,15 @@
import { execSync } from "child_process";
import BuildContext from "./context";
import { join } from "path";
export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) {
// Generate types
execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir });
for (const config of [ "backend", "frontend" ]) {
const outDir = join(baseDir, "script-api", config);
execSync(`pnpm typedoc --options typedoc.${config}.json --html "${outDir}"`, {
stdio: "inherit"
});
}
}

View File

@@ -0,0 +1,32 @@
import BuildContext from "./context";
import { join } from "path";
import { execSync } from "child_process";
import { mkdirSync } from "fs";
interface BuildInfo {
specPath: string;
outDir: string;
}
const DIR_PREFIX = "rest-api";
const buildInfos: BuildInfo[] = [
{
// Paths are relative to Git root.
specPath: "apps/server/internal.openapi.yaml",
outDir: `${DIR_PREFIX}/internal`
},
{
specPath: "apps/server/etapi.openapi.yaml",
outDir: `${DIR_PREFIX}/etapi`
}
];
export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) {
for (const { specPath, outDir } of buildInfos) {
const absSpecPath = join(gitRootDir, specPath);
const targetDir = join(baseDir, outDir);
mkdirSync(targetDir, { recursive: true });
execSync(`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, { stdio: "inherit" });
}
}

View File

@@ -0,0 +1,36 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"outDir": "dist",
"strict": false,
"types": [
"node",
"express"
],
"rootDir": "src",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
},
"include": [
"src/**/*.ts",
"../server/src/*.d.ts"
],
"exclude": [
"eslint.config.js",
"eslint.config.cjs",
"eslint.config.mjs"
],
"references": [
{
"path": "../server/tsconfig.app.json"
},
{
"path": "../desktop/tsconfig.app.json"
},
{
"path": "../client/tsconfig.app.json"
}
]
}

View File

@@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.base.json",
"include": [],
"references": [
{
"path": "../server"
},
{
"path": "../client"
},
{
"path": "./tsconfig.app.json"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Backend API",
"entryPoints": [
"src/backend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Frontend API",
"entryPoints": [
"src/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@@ -1,28 +0,0 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../widgets/basic_widget.js";
export type { default as FAttachment } from "../entities/fattachment.js";
export type { default as FAttribute } from "../entities/fattribute.js";
export type { default as FBranch } from "../entities/fbranch.js";
export type { default as FNote } from "../entities/fnote.js";
export type { Api } from "./frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "./frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@@ -23,6 +23,8 @@ if (!DOCS_ROOT || !USER_GUIDE_ROOT) {
throw new Error("Missing DOCS_ROOT or USER_GUIDE_ROOT environment variable.");
}
const BASE_URL = "https://docs.triliumnotes.org";
const NOTE_MAPPINGS: NoteMapping[] = [
{
rootNoteId: "pOsGYCXsbNQG",
@@ -158,6 +160,14 @@ async function cleanUpMeta(outputPath: string, minify: boolean) {
}
el.isExpanded = false;
// Rewrite web view URLs that point to root.
if (el.type === "webView" && minify) {
const srcAttr = el.attributes.find(attr => attr.name === "webViewSrc");
if (srcAttr.value.startsWith("/")) {
srcAttr.value = BASE_URL + srcAttr.value;
}
}
}
if (minify) {

View File

@@ -4,12 +4,12 @@ info:
title: ETAPI
description: External Trilium API
contact:
name: zadam
email: zadam.apps@gmail.com
url: https://github.com/zadam/trilium
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:37740/etapi
- url: http://localhost:8080/etapi

View File

@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: Trilium Notes Internal API
version: 0.98.0
title: Internal Trilium API
version: 0.99.3
description: |
This is the internal API used by the Trilium Notes client application.
@@ -24,11 +24,12 @@ info:
State-changing operations require CSRF tokens when using session authentication.
contact:
name: TriliumNext Issue Tracker
url: https://github.com/TriliumNext/Trilium/issues
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: GNU Affero General Public License v3.0
url: https://www.gnu.org/licenses/agpl-3.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:8080

View File

@@ -61,7 +61,6 @@
"@types/serve-static": "2.2.0",
"@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.3",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.6",
"@types/ws": "8.18.1",
@@ -123,7 +122,6 @@
"striptags": "3.2.0",
"supertest": "7.1.4",
"swagger-jsdoc": "6.2.8",
"swagger-ui-express": "5.0.1",
"time2fa": "1.4.2",
"tmp": "0.2.5",
"turndown": "7.2.2",

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import { BNote } from "../../services/backend_script_entrypoint";
import BNote from '../../becca/entities/bnote.js';
import cls from "../../services/cls";
import { buildNote } from "../../test/becca_easy_mocking";
import { processContent } from "./clipper";

View File

@@ -1,33 +0,0 @@
import type { Application } from "express";
import swaggerUi from "swagger-ui-express";
import { join } from "path";
import yaml from "js-yaml";
import type { JsonObject } from "swagger-ui-express";
import { readFileSync } from "fs";
import { RESOURCE_DIR } from "../services/resource_dir";
export default function register(app: Application) {
const etapiDocument = yaml.load(readFileSync(join(RESOURCE_DIR, "etapi.openapi.yaml"), "utf8")) as JsonObject;
// Load the comprehensive API documentation from YAML
const apiDocument = yaml.load(readFileSync(join(RESOURCE_DIR, "api-openapi.yaml"), "utf8")) as JsonObject;
app.use(
"/etapi/docs/",
swaggerUi.serveFiles(etapiDocument),
swaggerUi.setup(etapiDocument, {
explorer: true,
customSiteTitle: "TriliumNext ETAPI Documentation"
})
);
app.use(
"/api/docs/",
swaggerUi.serveFiles(apiDocument),
swaggerUi.setup(apiDocument, {
explorer: true,
customSiteTitle: "TriliumNext Internal API Documentation",
customCss: '.swagger-ui .topbar { display: none }'
})
);
}

View File

@@ -70,7 +70,6 @@ import etapiSpecialNoteRoutes from "../etapi/special_notes.js";
import etapiSpecRoute from "../etapi/spec.js";
import etapiBackupRoute from "../etapi/backup.js";
import etapiMetricsRoute from "../etapi/metrics.js";
import apiDocsRoute from "./api_docs.js";
import { apiResultHandler, apiRoute, asyncApiRoute, asyncRoute, route, router, uploadMiddlewareWithErrorHandling } from "./route_api.js";
const GET = "get",
@@ -383,9 +382,6 @@ function register(app: express.Application) {
asyncApiRoute(GET, "/api/llm/providers/openai/models", openaiRoute.listModels);
asyncApiRoute(GET, "/api/llm/providers/anthropic/models", anthropicRoute.listModels);
// API Documentation
apiDocsRoute(app);
app.use("", router);
}

View File

@@ -1,37 +0,0 @@
/**
* The backend script API is accessible to code notes with the "JS (backend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Backend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note on the server side.
*
* Make sure to keep in line with backend's `script_context.ts`.
*/
export type { default as AbstractBeccaEntity } from "../becca/entities/abstract_becca_entity.js";
export type { default as BAttachment } from "../becca/entities/battachment.js";
export type { default as BAttribute } from "../becca/entities/battribute.js";
export type { default as BBranch } from "../becca/entities/bbranch.js";
export type { default as BEtapiToken } from "../becca/entities/betapi_token.js";
export type { BNote };
export type { default as BOption } from "../becca/entities/boption.js";
export type { default as BRecentNote } from "../becca/entities/brecent_note.js";
export type { default as BRevision } from "../becca/entities/brevision.js";
import BNote from "../becca/entities/bnote.js";
import type { Api } from "./backend_script_api.js";
import BackendScriptApi from "./backend_script_api.js";
export type { Api };
const fakeNote = new BNote();
/**
* The `code` api global variable allows access to the backend script API, which is documented in {@link Api}.
*/
export const api: Api = new BackendScriptApi(fakeNote, {});

View File

@@ -9,7 +9,7 @@ import log from '../../log.js';
import becca from '../../../becca/becca.js';
import notes from '../../notes.js';
import attributes from '../../attributes.js';
import type { BNote } from '../../backend_script_entrypoint.js';
import BNote from '../../../becca/entities/bnote.js';
/**
* Definition of the note creation tool

View File

@@ -9,7 +9,7 @@ import searchService from "./search/services/search.js";
import SearchContext from "./search/search_context.js";
import { LBTPL_NOTE_LAUNCHER, LBTPL_CUSTOM_WIDGET, LBTPL_SPACER, LBTPL_SCRIPT } from "./hidden_subtree.js";
import { t } from "i18next";
import { BNote } from "./backend_script_entrypoint.js";
import BNote from '../becca/entities/bnote.js';
import { SaveSearchNoteResponse, SaveSqlConsoleResponse } from "@triliumnext/commons";
function getInboxNote(date: string) {

View File

@@ -16,7 +16,7 @@ import { join } from "path";
import { readFileSync } from "fs";
import { highlightAuto } from "@triliumnext/highlightjs";
import becca from "../becca/becca.js";
import { BAttachment } from "../services/backend_script_entrypoint.js";
import BAttachment from '../becca/entities/battachment.js';
import SAttachment from "./shaca/entities/sattachment.js";
import { sanitizeUrl } from "@braintree/sanitize-url";

View File

@@ -12594,7 +12594,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "/etapi/docs",
"value": "/rest-api/etapi/",
"isInheritable": false,
"position": 10
},
@@ -13612,7 +13612,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "/api/docs",
"value": "/rest-api/internal/",
"isInheritable": false,
"position": 10
},
@@ -14968,7 +14968,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html",
"value": "/script-api/frontend",
"isInheritable": false,
"position": 10
},
@@ -15003,7 +15003,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/classes/Frontend_Script_API.FNote.html",
"value": "/script-api/frontend/interfaces/FNote.html",
"isInheritable": false,
"position": 10
},
@@ -15039,7 +15039,7 @@
{
"type": "label",
"name": "webViewSrc",
"value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html",
"value": "/script-api/backend",
"isInheritable": false,
"position": 10
},

View File

@@ -26,7 +26,7 @@
"chore:generate-openapi": "tsx ./scripts/generate-openapi.ts",
"chore:update-build-info": "tsx ./scripts/update-build-info.ts",
"chore:update-version": "tsx ./scripts/update-version.ts",
"docs:build": "pnpm run --filter share-theme build && cd ./apps/edit-docs && tsx ./src/build-docs.ts",
"docs:build": "pnpm run --filter build-docs start",
"edit-docs:edit-docs": "pnpm run --filter edit-docs edit-docs",
"edit-docs:edit-demo": "pnpm run --filter edit-docs edit-demo",
"test:all": "pnpm test:parallel && pnpm test:sequential",

View File

@@ -32,7 +32,6 @@
"devDependencies": {
"@digitak/esrun": "3.2.26",
"@triliumnext/ckeditor5": "workspace:*",
"@types/swagger-ui": "5.21.1",
"@typescript-eslint/eslint-plugin": "8.46.2",
"@typescript-eslint/parser": "8.46.2",
"dotenv": "17.2.3",

View File

@@ -54,17 +54,25 @@ body:not(.math-loaded) .math-tex {
visibility: hidden;
}
body.type-webView #main {
max-width: unset;
}
body.type-webView {
#main {
max-width: unset;
padding: 0;
}
body.type-webView #content {
display: flex;
flex-direction: column;
height: 100%;
}
#content {
display: flex;
flex-direction: column;
height: 100%;
iframe.webview {
width: 100%;
flex-grow: 1;
h1 {
display: none;
}
iframe.webview {
width: 100%;
flex-grow: 1;
border: 0;
}
}
}

1478
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff