From 6f83b932b0d0890d44d008416d9ef6fe0768f7cd Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 21:28:31 +0200
Subject: [PATCH 01/49] feat(print/table): basic implementation using export
module
---
.../src/widgets/collections/NoteList.tsx | 9 ++-
.../collections/table/TablePrintView.tsx | 38 +++++++++
.../src/widgets/collections/table/data.tsx | 77 ++++++++++++++++++
.../src/widgets/collections/table/index.tsx | 79 ++-----------------
.../widgets/collections/table/tabulator.tsx | 4 +-
5 files changed, 130 insertions(+), 77 deletions(-)
create mode 100644 apps/client/src/widgets/collections/table/TablePrintView.tsx
create mode 100644 apps/client/src/widgets/collections/table/data.tsx
diff --git a/apps/client/src/widgets/collections/NoteList.tsx b/apps/client/src/widgets/collections/NoteList.tsx
index c613f8d39..bd007a40f 100644
--- a/apps/client/src/widgets/collections/NoteList.tsx
+++ b/apps/client/src/widgets/collections/NoteList.tsx
@@ -14,6 +14,7 @@ import { WebSocketMessage } from "@triliumnext/commons";
import froca from "../../services/froca";
import PresentationView from "./presentation";
import { ListPrintView } from "./legacy/ListPrintView";
+import TablePrintView from "./table/TablePrintView";
interface NoteListProps {
note: FNote | null | undefined;
@@ -117,9 +118,13 @@ function getComponentByViewType(viewType: ViewTypeOptions, props: ViewModeProps<
case "geoMap":
return ;
case "calendar":
- return
+ return ;
case "table":
- return
+ if (props.media !== "print") {
+ return ;
+ } else {
+ return ;
+ }
case "board":
return
case "presentation":
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
new file mode 100644
index 000000000..a7e36dfb3
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -0,0 +1,38 @@
+import { useRef, useState } from "preact/hooks";
+import { ViewModeProps } from "../interface";
+import useData, { TableConfig } from "./data";
+import { ExportModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
+import Tabulator from "./tabulator";
+import { RawHtmlBlock } from "../../react/RawHtml";
+
+export default function TablePrintView({ note, noteIds, viewConfig }: ViewModeProps) {
+ const tabulatorRef = useRef(null);
+ const { columnDefs, rowData, movableRows, hasChildren } = useData(note, noteIds, viewConfig, undefined, () => {});
+ const [ html, setHtml ] = useState();
+
+ return rowData && (
+
+ {!html ? (
+ {
+ const tabulator = tabulatorRef.current;
+ if (!tabulator) return;
+ setHtml(tabulator.getHtml());
+ }}
+ />
+ ) : (
+
+ )}
+
+
+ )
+}
diff --git a/apps/client/src/widgets/collections/table/data.tsx b/apps/client/src/widgets/collections/table/data.tsx
new file mode 100644
index 000000000..b77a1545e
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/data.tsx
@@ -0,0 +1,77 @@
+import type { ColumnDefinition } from "tabulator-tables";
+import FNote from "../../../entities/fnote";
+import { useNoteLabelBoolean, useNoteLabelInt, useTriliumEvent } from "../../react/hooks";
+import { useEffect, useState } from "preact/hooks";
+import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
+import froca from "../../../services/froca";
+import { buildColumnDefinitions } from "./columns";
+import attributes from "../../../services/attributes";
+import { RefObject } from "preact";
+
+export interface TableConfig {
+ tableData: {
+ columns?: ColumnDefinition[];
+ };
+}
+
+export default function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject | undefined, resetNewAttributePosition: () => void) {
+ const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
+ const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
+
+ const [ columnDefs, setColumnDefs ] = useState();
+ const [ rowData, setRowData ] = useState();
+ const [ hasChildren, setHasChildren ] = useState();
+ const [ isSorted ] = useNoteLabelBoolean(note, "sorted");
+ const [ movableRows, setMovableRows ] = useState(false);
+
+ async function refresh() {
+ const info = getAttributeDefinitionInformation(note);
+
+ // Ensure all note IDs are loaded.
+ await froca.getNotes(noteIds);
+
+ const { definitions: rowData, hasSubtree: hasChildren, rowNumber } = await buildRowDefinitions(note, info, includeArchived, maxDepth);
+ const columnDefs = buildColumnDefinitions({
+ info,
+ movableRows,
+ existingColumnData: viewConfig?.tableData?.columns,
+ rowNumberHint: rowNumber,
+ position: newAttributePosition?.current ?? undefined
+ });
+ setColumnDefs(columnDefs);
+ setRowData(rowData);
+ setHasChildren(hasChildren);
+ resetNewAttributePosition();
+ }
+
+ useEffect(() => { refresh() }, [ note, noteIds, maxDepth, movableRows ]);
+
+ useTriliumEvent("entitiesReloaded", ({ loadResults}) => {
+ if (glob.device === "print") return;
+
+ // React to column changes.
+ if (loadResults.getAttributeRows().find(attr =>
+ attr.type === "label" &&
+ (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) &&
+ attributes.isAffecting(attr, note))) {
+ refresh();
+ return;
+ }
+
+ // React to external row updates.
+ if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? ""))
+ || loadResults.getNoteIds().some(noteId => noteIds.includes(noteId))
+ || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!))
+ || loadResults.getAttributeRows().some(attr => attr.name === "archived" && attr.noteId && noteIds.includes(attr.noteId))) {
+ refresh();
+ return;
+ }
+ });
+
+ // Identify if movable rows.
+ useEffect(() => {
+ setMovableRows(!isSorted && note.type !== "search" && !hasChildren);
+ }, [ isSorted, note, hasChildren ]);
+
+ return { columnDefs, rowData, movableRows, hasChildren };
+}
diff --git a/apps/client/src/widgets/collections/table/index.tsx b/apps/client/src/widgets/collections/table/index.tsx
index f6ae82009..d557f12d3 100644
--- a/apps/client/src/widgets/collections/table/index.tsx
+++ b/apps/client/src/widgets/collections/table/index.tsx
@@ -1,10 +1,9 @@
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { ViewModeProps } from "../interface";
-import { buildColumnDefinitions } from "./columns";
-import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
-import { useLegacyWidget, useNoteLabelBoolean, useNoteLabelInt, useTriliumEvent } from "../../react/hooks";
+import { TableData } from "./rows";
+import { useLegacyWidget } from "../../react/hooks";
import Tabulator from "./tabulator";
-import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent} from 'tabulator-tables';
+import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule, Options, RowComponent} from 'tabulator-tables';
import { useContextMenu } from "./context_menu";
import { ParentComponent } from "../../react/react_utils";
import FNote from "../../../entities/fnote";
@@ -14,16 +13,8 @@ import "./index.css";
import useRowTableEditing from "./row_editing";
import useColTableEditing from "./col_editing";
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
-import attributes from "../../../services/attributes";
-import { RefObject } from "preact";
import SpacedUpdate from "../../../services/spaced_update";
-import froca from "../../../services/froca";
-
-interface TableConfig {
- tableData: {
- columns?: ColumnDefinition[];
- };
-}
+import useData, { TableConfig } from "./data";
export default function TableView({ note, noteIds, notePath, viewConfig, saveConfig }: ViewModeProps) {
const tabulatorRef = useRef(null);
@@ -118,67 +109,7 @@ function usePersistence(viewConfig: TableConfig | null | undefined, saveConfig:
return () => {
spacedUpdate.updateNowIfNecessary();
};
- }, [ viewConfig, saveConfig ])
+ }, [ viewConfig, saveConfig ]);
return persistenceProps;
}
-
-function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject, resetNewAttributePosition: () => void) {
- const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
- const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
-
- const [ columnDefs, setColumnDefs ] = useState();
- const [ rowData, setRowData ] = useState();
- const [ hasChildren, setHasChildren ] = useState();
- const [ isSorted ] = useNoteLabelBoolean(note, "sorted");
- const [ movableRows, setMovableRows ] = useState(false);
-
- async function refresh() {
- const info = getAttributeDefinitionInformation(note);
-
- // Ensure all note IDs are loaded.
- await froca.getNotes(noteIds);
-
- const { definitions: rowData, hasSubtree: hasChildren, rowNumber } = await buildRowDefinitions(note, info, includeArchived, maxDepth);
- const columnDefs = buildColumnDefinitions({
- info,
- movableRows,
- existingColumnData: viewConfig?.tableData?.columns,
- rowNumberHint: rowNumber,
- position: newAttributePosition.current ?? undefined
- });
- setColumnDefs(columnDefs);
- setRowData(rowData);
- setHasChildren(hasChildren);
- resetNewAttributePosition();
- }
-
- useEffect(() => { refresh() }, [ note, noteIds, maxDepth, movableRows ]);
-
- useTriliumEvent("entitiesReloaded", ({ loadResults}) => {
- // React to column changes.
- if (loadResults.getAttributeRows().find(attr =>
- attr.type === "label" &&
- (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) &&
- attributes.isAffecting(attr, note))) {
- refresh();
- return;
- }
-
- // React to external row updates.
- if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? ""))
- || loadResults.getNoteIds().some(noteId => noteIds.includes(noteId))
- || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!))
- || loadResults.getAttributeRows().some(attr => attr.name === "archived" && attr.noteId && noteIds.includes(attr.noteId))) {
- refresh();
- return;
- }
- });
-
- // Identify if movable rows.
- useEffect(() => {
- setMovableRows(!isSorted && note.type !== "search" && !hasChildren);
- }, [ isSorted, note, hasChildren ]);
-
- return { columnDefs, rowData, movableRows, hasChildren };
-}
diff --git a/apps/client/src/widgets/collections/table/tabulator.tsx b/apps/client/src/widgets/collections/table/tabulator.tsx
index 6301d5b38..31fb8d4f8 100644
--- a/apps/client/src/widgets/collections/table/tabulator.tsx
+++ b/apps/client/src/widgets/collections/table/tabulator.tsx
@@ -14,9 +14,10 @@ interface TableProps extends Omit;
index: keyof T;
footerElement?: string | HTMLElement | JSX.Element;
+ onReady?: () => void;
}
-export default function Tabulator({ className, columns, data, modules, tabulatorRef: externalTabulatorRef, footerElement, events, index, dataTree, ...restProps }: TableProps) {
+export default function Tabulator({ className, columns, data, modules, tabulatorRef: externalTabulatorRef, footerElement, events, index, dataTree, onReady, ...restProps }: TableProps) {
const parentComponent = useContext(ParentComponent);
const containerRef = useRef(null);
const tabulatorRef = useRef(null);
@@ -43,6 +44,7 @@ export default function Tabulator({ className, columns, data, modules, tabula
tabulator.on("tableBuilt", () => {
tabulatorRef.current = tabulator;
externalTabulatorRef.current = tabulator;
+ onReady?.();
});
return () => tabulator.destroy();
From f864746b5493220c1dfaa3602b1e71db4a94b8c2 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:05:22 +0200
Subject: [PATCH 02/49] feat(print/table): render using internal mechanism
---
.../src/widgets/collections/table/TablePrintView.css | 7 +++++++
.../src/widgets/collections/table/TablePrintView.tsx | 10 +++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
create mode 100644 apps/client/src/widgets/collections/table/TablePrintView.css
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
new file mode 100644
index 000000000..09c6cae07
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -0,0 +1,7 @@
+.tabulator-print-table table,
+.tabulator-print-table th,
+.tabulator-print-table tr,
+.tabulator-print-table td {
+ border: 1px solid black !important;
+ border-collapse: collapse;
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index a7e36dfb3..cc73d7cd2 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -4,6 +4,7 @@ import useData, { TableConfig } from "./data";
import { ExportModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
import Tabulator from "./tabulator";
import { RawHtmlBlock } from "../../react/RawHtml";
+import "./TablePrintView.css";
export default function TablePrintView({ note, noteIds, viewConfig }: ViewModeProps) {
const tabulatorRef = useRef(null);
@@ -21,16 +22,19 @@ export default function TablePrintView({ note, noteIds, viewConfig }: ViewModePr
data={rowData}
index="branchId"
dataTree={hasChildren}
- printAsHtml={true}
printStyled={true}
onReady={() => {
const tabulator = tabulatorRef.current;
if (!tabulator) return;
- setHtml(tabulator.getHtml());
+ const generatedTable = tabulator.modules.export.generateTable(tabulator.options.printConfig, tabulator.options.printStyled, tabulator.options.printRowRange, "print");
+ if(tabulator.options.printFormatter){
+ tabulator.options.printFormatter(tabulator.element, generatedTable);
+ }
+ setHtml(generatedTable.outerHTML);
}}
/>
) : (
-
+
)}
From 749740242efcb19c3454a796e719f7f5a3154727 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:09:07 +0200
Subject: [PATCH 03/49] fix(print/table) formatters not rendering
---
.../client/src/widgets/collections/table/TablePrintView.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index cc73d7cd2..09f551969 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -1,14 +1,14 @@
import { useRef, useState } from "preact/hooks";
import { ViewModeProps } from "../interface";
import useData, { TableConfig } from "./data";
-import { ExportModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
+import { ExportModule, FormatModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
import Tabulator from "./tabulator";
import { RawHtmlBlock } from "../../react/RawHtml";
import "./TablePrintView.css";
export default function TablePrintView({ note, noteIds, viewConfig }: ViewModeProps) {
const tabulatorRef = useRef(null);
- const { columnDefs, rowData, movableRows, hasChildren } = useData(note, noteIds, viewConfig, undefined, () => {});
+ const { columnDefs, rowData, hasChildren } = useData(note, noteIds, viewConfig, undefined, () => {});
const [ html, setHtml ] = useState();
return rowData && (
@@ -17,7 +17,7 @@ export default function TablePrintView({ note, noteIds, viewConfig }: ViewModePr
Date: Fri, 21 Nov 2025 22:12:05 +0200
Subject: [PATCH 04/49] fix(print/table): missing title
---
.../collections/table/TablePrintView.tsx | 55 ++++++++++---------
1 file changed, 30 insertions(+), 25 deletions(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index 09f551969..278df6413 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -12,31 +12,36 @@ export default function TablePrintView({ note, noteIds, viewConfig }: ViewModePr
const [ html, setHtml ] = useState();
return rowData && (
-
- {!html ? (
- {
- const tabulator = tabulatorRef.current;
- if (!tabulator) return;
- const generatedTable = tabulator.modules.export.generateTable(tabulator.options.printConfig, tabulator.options.printStyled, tabulator.options.printRowRange, "print");
- if(tabulator.options.printFormatter){
- tabulator.options.printFormatter(tabulator.element, generatedTable);
- }
- setHtml(generatedTable.outerHTML);
- }}
- />
- ) : (
-
- )}
-
+ <>
+ {note.title}
+
+
+
+ {!html ? (
+ {
+ const tabulator = tabulatorRef.current;
+ if (!tabulator) return;
+ const generatedTable = tabulator.modules.export.generateTable(tabulator.options.printConfig, tabulator.options.printStyled, tabulator.options.printRowRange, "print");
+ if(tabulator.options.printFormatter){
+ tabulator.options.printFormatter(tabulator.element, generatedTable);
+ }
+ setHtml(generatedTable.outerHTML);
+ }}
+ />
+ ) : (
+
+ )}
+
+ >
)
}
From 670cc474a47316ceba3afbc4db1bd914fe564564 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:13:55 +0200
Subject: [PATCH 05/49] chore(print/table): grayed out table headers
---
apps/client/src/widgets/collections/table/TablePrintView.css | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
index 09c6cae07..ce7eec9ec 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.css
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -4,4 +4,8 @@
.tabulator-print-table td {
border: 1px solid black !important;
border-collapse: collapse;
+}
+
+.tabulator-print-table th {
+ background-color: #f0f0f0 !important;
}
\ No newline at end of file
From 644e3e200da10f09d38b609ddb3e204284ff277f Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:15:01 +0200
Subject: [PATCH 06/49] chore(print/table): stop copying styles and apply own
---
apps/client/src/widgets/collections/table/TablePrintView.css | 5 +++++
apps/client/src/widgets/collections/table/TablePrintView.tsx | 3 ++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
index ce7eec9ec..14c1e6dc4 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.css
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -8,4 +8,9 @@
.tabulator-print-table th {
background-color: #f0f0f0 !important;
+}
+
+.tabulator-print-table th,
+.tabulator-print-table td {
+ padding: 0.25rem 0.5rem !important;
}
\ No newline at end of file
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index 278df6413..abf73f1ee 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -26,7 +26,8 @@ export default function TablePrintView({ note, noteIds, viewConfig }: ViewModePr
data={rowData}
index="branchId"
dataTree={hasChildren}
- printStyled={true}
+ printAsHtml={true}
+ printStyled={false}
onReady={() => {
const tabulator = tabulatorRef.current;
if (!tabulator) return;
From 779e2f4633751e5e60f66c05bde0cae4cc2ad922 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:15:56 +0200
Subject: [PATCH 07/49] chore(print/table): monochrome checkboxes
---
apps/client/src/widgets/collections/table/TablePrintView.css | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
index 14c1e6dc4..74e282aaf 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.css
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -13,4 +13,8 @@
.tabulator-print-table th,
.tabulator-print-table td {
padding: 0.25rem 0.5rem !important;
+}
+
+.tabulator-print-table td[aria-checked] svg path {
+ fill: currentColor !important;
}
\ No newline at end of file
From 0c5a6a75481bc816768d593f664c92240cb8e764 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:17:54 +0200
Subject: [PATCH 08/49] feat(print/table): integrate with the printing
mechanism
---
.../src/widgets/collections/table/TablePrintView.tsx | 9 +++++++--
apps/client/src/widgets/ribbon/NoteActions.tsx | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index abf73f1ee..9582b4360 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -1,4 +1,4 @@
-import { useRef, useState } from "preact/hooks";
+import { useEffect, useRef, useState } from "preact/hooks";
import { ViewModeProps } from "../interface";
import useData, { TableConfig } from "./data";
import { ExportModule, FormatModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
@@ -6,11 +6,16 @@ import Tabulator from "./tabulator";
import { RawHtmlBlock } from "../../react/RawHtml";
import "./TablePrintView.css";
-export default function TablePrintView({ note, noteIds, viewConfig }: ViewModeProps) {
+export default function TablePrintView({ note, noteIds, viewConfig, onReady }: ViewModeProps) {
const tabulatorRef = useRef(null);
const { columnDefs, rowData, hasChildren } = useData(note, noteIds, viewConfig, undefined, () => {});
const [ html, setHtml ] = useState();
+ useEffect(() => {
+ if (!html) return;
+ onReady?.();
+ }, [ html ]);
+
return rowData && (
<>
{note.title}
diff --git a/apps/client/src/widgets/ribbon/NoteActions.tsx b/apps/client/src/widgets/ribbon/NoteActions.tsx
index d7e344dd8..33017221b 100644
--- a/apps/client/src/widgets/ribbon/NoteActions.tsx
+++ b/apps/client/src/widgets/ribbon/NoteActions.tsx
@@ -49,7 +49,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
const canBeConvertedToAttachment = note?.isEligibleForConversionToAttachment();
const isSearchable = ["text", "code", "book", "mindMap", "doc"].includes(note.type);
const isInOptionsOrHelp = note?.noteId.startsWith("_options") || note?.noteId.startsWith("_help");
- const isPrintable = ["text", "code"].includes(note.type) || (note.type === "book" && ["presentation", "list"].includes(note.getLabelValue("viewType") ?? ""));
+ const isPrintable = ["text", "code"].includes(note.type) || (note.type === "book" && ["presentation", "list", "table"].includes(note.getLabelValue("viewType") ?? ""));
const isElectron = getIsElectron();
const isMac = getIsMac();
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(note.type);
From 8dc43dab59203dffcbdfff87fee35fe05b645f64 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:28:43 +0200
Subject: [PATCH 09/49] docs(user): update printing documentation
---
.../Notes/Printing & Exporting as PDF.html | 63 +++++++++++--------
.../User Guide/Collections/List View.html | 11 ++--
.../Developer Guide/Documentation.md | 2 +-
docs/User Guide/!!!meta.json | 43 +++++++------
.../Notes/Printing & Exporting as PDF.md | 9 ++-
5 files changed, 74 insertions(+), 54 deletions(-)
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
index 35ae5862b..2e3b2c92c 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
@@ -59,9 +59,9 @@ class="admonition note">
orientation, size. However, there are a few Attributes to adjust some of the settings:
- - To print in landscape mode instead of portrait (useful for big diagrams
+
- To print in landscape mode instead of portrait (useful for big diagrams
or slides), add
#printLandscape.
- - By default, the resulting PDF will be in Letter format. It is possible
+
- By default, the resulting PDF will be in Letter format. It is possible
to adjust it to another page size via the
#printPageSize attribute,
with one of the following values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
@@ -71,12 +71,12 @@ class="admonition note">
Printing multiple notes
Since v0.100.0, it is possible to print more than one note at the time
- by using Collections:
+ by using Collections:
- - First create a collection.
- - Configure it to use List View.
+ - First create a collection.
+ - Configure it to use List View.
- Print the collection note normally.
+ data-list-item-id="ecaad5f90dcbfd65da21689c54b063ff9">Print the collection note normally.
The resulting collection will contain all the children of the collection,
while maintaining the hierarchy.
@@ -86,9 +86,9 @@ class="admonition note">
href="#root/_help_4TIF1oA4VQRO">Options and assigning a key combination
for:
- - Print Active Note
+
- Print Active Note
- - Export Active Note as PDF
+
- Export Active Note as PDF
Constraints & limitations
@@ -96,28 +96,39 @@ class="admonition note">
supported when printing, in which case the Print and Export as PDF options
will be disabled.
- - For Code notes:
+
- For Code notes:
- - Line numbers are not printed.
- - Syntax highlighting is enabled, however a default theme (Visual Studio)
+
- Line numbers are not printed.
+ - Syntax highlighting is enabled, however a default theme (Visual Studio)
is enforced.
- - For Collections:
+
- For Collections,
+ the following are supported:
- - List View is
- supported, allowing to print multiple notes at once while preserving hierarchy
- (similar to a book).
- - Presentation is
- also supported, where each slide/subnote is displayed.
- - The rest of the collections are not supported, but we plan to add support
+
- List View, allowing
+ to print multiple notes at once while preserving hierarchy (similar to
+ a book).
+ - Presentation,
+ where each slide/sub-note is displayed.
+ - Table,
+ where the table is rendered in a print-friendly way.
+
+ - Tables that are too complex (especially if they have multiple columns)
+ might not fit properly, however tables with a large number of rows are
+ supported thanks to pagination.
+ - Consider printing in landscape mode, or using
#printLandscape if
+ exporting to PDF.
+
+
+ - The rest of the collections are not supported, but we plan to add support
for all the collection types at some point.
- - Using Custom app-wide CSS for
+
- Using Custom app-wide CSS for
printing is not longer supported, due to a more stable but isolated mechanism.
- - We plan to introduce a new mechanism specifically for a print CSS.
+ - We plan to introduce a new mechanism specifically for a print CSS.
@@ -128,10 +139,10 @@ class="admonition note">
printing.
To do so:
- - Create a CSS code note.
- - On the note being printed, apply the
~printCss relation to
+ - Create a CSS code note.
+ - On the note being printed, apply the
~printCss relation to
point to the newly created CSS code note.
- - To apply the CSS to multiple notes, consider using inheritable attributes or
+
- To apply the CSS to multiple notes, consider using inheritable attributes or
Templates.
@@ -142,11 +153,11 @@ class="admonition note">
}
To remark:
- - Multiple CSS notes can be add by using multiple
~printCss relations.
+ - Multiple CSS notes can be add by using multiple
~printCss relations.
- If the note pointing to the
printCss doesn't have the right
+ data-list-item-id="e5989879c4432018bf90fecc5e31e090b">If the note pointing to the printCss doesn't have the right
note type or mime type, it will be ignored.
- - If migrating from a previous version where If migrating from a previous version where Custom app-wide CSS, there's no need for
@media print { since
the style-sheet is used only for printing.
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
index 64c09e024..4c8a97257 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
@@ -12,22 +12,21 @@
as a single continuous document.
Interaction
- - Each note can be expanded or collapsed by clicking on the arrow to the
+
- Each note can be expanded or collapsed by clicking on the arrow to the
left of the title.
- - In the Ribbon,
+
- In the Ribbon,
in the Collection tab there are options to expand and to collapse
all notes easily.
Printing and exporting to PDF
-Since v0.100.0, list collections can be printed or exported to PDF.
+Since v0.100.0, list collections can be printed or exported to PDF.
A printed list collection will print all the notes in the collection,
in the right order and preserving the full hierarchy.
If exported to PDF within the desktop application, there is additional
functionality:
- - The table of contents of the PDF will reflect the structure of the notes.
- - Reference and inline links to other notes within the same hierarchy will
+
- The table of contents of the PDF will reflect the structure of the notes.
+ - Reference and inline links to other notes within the same hierarchy will
be functional (will jump to the corresponding page). If a link refers to
a note that is not in the printed hierarchy, it will be unlinked.
\ No newline at end of file
diff --git a/docs/Developer Guide/Developer Guide/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md
index b8eca125b..6e7ea215f 100644
--- a/docs/Developer Guide/Developer Guide/Documentation.md
+++ b/docs/Developer Guide/Developer Guide/Documentation.md
@@ -1,5 +1,5 @@
# Documentation
-There are multiple types of documentation for Trilium:
+There are multiple types of documentation for Trilium:
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json
index 7b77cb46a..014f86614 100644
--- a/docs/User Guide/!!!meta.json
+++ b/docs/User Guide/!!!meta.json
@@ -4062,66 +4062,73 @@
{
"type": "relation",
"name": "internalLink",
- "value": "4TIF1oA4VQRO",
+ "value": "GTwFsgaA0lCt",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
- "value": "KSZ04uQ2D1St",
+ "value": "mULW0Q3VojwY",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
- "value": "6f9hih2hXXZk",
+ "value": "4TIF1oA4VQRO",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
- "value": "GTwFsgaA0lCt",
+ "value": "KSZ04uQ2D1St",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
- "value": "zP3PMqaG71Ct",
+ "value": "6f9hih2hXXZk",
"isInheritable": false,
"position": 80
},
{
"type": "relation",
"name": "internalLink",
- "value": "AlhDUqhENtH7",
+ "value": "zP3PMqaG71Ct",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
- "value": "bwZpz2ajCEwO",
+ "value": "AlhDUqhENtH7",
"isInheritable": false,
"position": 100
},
{
"type": "relation",
"name": "internalLink",
- "value": "KC1HB96bqqHX",
+ "value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 110
},
{
"type": "relation",
"name": "internalLink",
- "value": "0ESUbbAxVnoK",
+ "value": "KC1HB96bqqHX",
"isInheritable": false,
"position": 120
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "0ESUbbAxVnoK",
+ "isInheritable": false,
+ "position": 130
+ },
{
"type": "label",
"name": "iconClass",
@@ -4139,9 +4146,9 @@
{
"type": "relation",
"name": "internalLink",
- "value": "mULW0Q3VojwY",
+ "value": "2FvYrpmOXm29",
"isInheritable": false,
- "position": 130
+ "position": 140
}
],
"format": "markdown",
@@ -10472,6 +10479,13 @@
"isInheritable": false,
"position": 20
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "NRnIZmSMc5sj",
+ "isInheritable": false,
+ "position": 30
+ },
{
"type": "label",
"name": "iconClass",
@@ -10485,13 +10499,6 @@
"value": "list",
"isInheritable": false,
"position": 30
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "NRnIZmSMc5sj",
- "isInheritable": false,
- "position": 40
}
],
"format": "markdown",
diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
index 083ad6ec7..56b0adb74 100644
--- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
+++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
@@ -73,9 +73,12 @@ Not all Note Types
* For Code notes:
* Line numbers are not printed.
* Syntax highlighting is enabled, however a default theme (Visual Studio) is enforced.
-* For Collections:
- * List View is supported, allowing to print multiple notes at once while preserving hierarchy (similar to a book).
- * Presentation is also supported, where each slide/subnote is displayed.
+* For Collections, the following are supported:
+ * List View, allowing to print multiple notes at once while preserving hierarchy (similar to a book).
+ * Presentation, where each slide/sub-note is displayed.
+ * Table, where the table is rendered in a print-friendly way.
+ * Tables that are too complex (especially if they have multiple columns) might not fit properly, however tables with a large number of rows are supported thanks to pagination.
+ * Consider printing in landscape mode, or using `#printLandscape` if exporting to PDF.
* The rest of the collections are not supported, but we plan to add support for all the collection types at some point.
* Using Custom app-wide CSS for printing is not longer supported, due to a more stable but isolated mechanism.
* We plan to introduce a new mechanism specifically for a print CSS.
From ab14bdbb18f1a2a8243bbf3fa8a8f2a3c91571b3 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:33:48 +0200
Subject: [PATCH 10/49] chore(print/table): address review
---
.../collections/table/TablePrintView.css | 24 +++++++++----------
.../src/widgets/collections/table/data.tsx | 2 +-
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
index 74e282aaf..fef53c299 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.css
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -1,20 +1,20 @@
-.tabulator-print-table table,
-.tabulator-print-table th,
-.tabulator-print-table tr,
-.tabulator-print-table td {
- border: 1px solid black !important;
+.table-print-view .tabulator-print-table table,
+.table-print-view .tabulator-print-table th,
+.table-print-view .tabulator-print-table tr,
+.table-print-view .tabulator-print-table td {
+ border: 1px solid black;
border-collapse: collapse;
}
-.tabulator-print-table th {
- background-color: #f0f0f0 !important;
+.table-print-view .tabulator-print-table th {
+ background-color: #f0f0f0;
}
-.tabulator-print-table th,
-.tabulator-print-table td {
- padding: 0.25rem 0.5rem !important;
+.table-print-view .tabulator-print-table th,
+.table-print-view .tabulator-print-table td {
+ padding: 0.25rem 0.5rem;
}
-.tabulator-print-table td[aria-checked] svg path {
- fill: currentColor !important;
+.table-print-view .tabulator-print-table td[aria-checked] svg path {
+ fill: currentColor;
}
\ No newline at end of file
diff --git a/apps/client/src/widgets/collections/table/data.tsx b/apps/client/src/widgets/collections/table/data.tsx
index b77a1545e..94909939d 100644
--- a/apps/client/src/widgets/collections/table/data.tsx
+++ b/apps/client/src/widgets/collections/table/data.tsx
@@ -15,7 +15,7 @@ export interface TableConfig {
}
export default function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject | undefined, resetNewAttributePosition: () => void) {
- const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
+ const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth");
const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
const [ columnDefs, setColumnDefs ] = useState();
From 5c0cf09c425b742389e1cc1878e8e56ef4deeb5e Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Fri, 21 Nov 2025 22:35:29 +0200
Subject: [PATCH 11/49] chore(print/table): revert back to using the export
module only
---
.../src/widgets/collections/table/TablePrintView.tsx | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
index 9582b4360..534ba5764 100644
--- a/apps/client/src/widgets/collections/table/TablePrintView.tsx
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "preact/hooks";
import { ViewModeProps } from "../interface";
import useData, { TableConfig } from "./data";
-import { ExportModule, FormatModule, PrintModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
+import { ExportModule, FormatModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
import Tabulator from "./tabulator";
import { RawHtmlBlock } from "../../react/RawHtml";
import "./TablePrintView.css";
@@ -26,7 +26,7 @@ export default function TablePrintView({ note, noteIds, viewConfig, onReady }: V
{
const tabulator = tabulatorRef.current;
if (!tabulator) return;
- const generatedTable = tabulator.modules.export.generateTable(tabulator.options.printConfig, tabulator.options.printStyled, tabulator.options.printRowRange, "print");
- if(tabulator.options.printFormatter){
- tabulator.options.printFormatter(tabulator.element, generatedTable);
- }
- setHtml(generatedTable.outerHTML);
+ setHtml(tabulator.getHtml());
}}
/>
) : (
From 7e6e10e3ef48a325ed42c599c6db2afd836cbeb2 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 01:40:32 +0000
Subject: [PATCH 12/49] chore(deps): update dependency express-openid-connect
to v2.19.3
---
apps/server/package.json | 2 +-
pnpm-lock.yaml | 34 +++++++++++++---------------------
2 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/apps/server/package.json b/apps/server/package.json
index 97038b99d..d719f625d 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -86,7 +86,7 @@
"escape-html": "1.0.3",
"express": "5.1.0",
"express-http-proxy": "2.1.2",
- "express-openid-connect": "2.19.2",
+ "express-openid-connect": "2.19.3",
"express-rate-limit": "8.2.1",
"express-session": "1.18.2",
"file-uri-to-path": "2.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d66f9bfa2..46af00d3d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -667,8 +667,8 @@ importers:
specifier: 2.1.2
version: 2.1.2
express-openid-connect:
- specifier: 2.19.2
- version: 2.19.2(express@5.1.0)
+ specifier: 2.19.3
+ version: 2.19.3(express@5.1.0)
express-rate-limit:
specifier: 8.2.1
version: 8.2.1(express@5.1.0)
@@ -8196,8 +8196,8 @@ packages:
resolution: {integrity: sha512-FXcAcs7Nf/hF73Mzh0WDWPwaOlsEUL/fCHW3L4wU6DH79dypsaxmbnAildCLniFs7HQuuvoiR6bjNVUvGuTb5g==}
engines: {node: '>=6.0.0'}
- express-openid-connect@2.19.2:
- resolution: {integrity: sha512-hRRRBS+mH9hrhVcbg7+APe+dIsYB4BDLILv7QfTmM1jSDyaU9NYpTxqWourAnlud/E4Gf4Q0qCVmSJguh4BTaA==}
+ express-openid-connect@2.19.3:
+ resolution: {integrity: sha512-3XTQBa6Bzuw1GozlIQcruJ7vaWkjHaSDHTTJFuAvQwq/B42Brzn/MiVQUsxPXHnLCs/tN9Scg+G12dS2RGgT4Q==}
engines: {node: ^10.19.0 || >=12.0.0 < 13 || >=13.7.0 < 14 || >= 14.2.0}
peerDependencies:
express: '>= 4.17.0'
@@ -14245,6 +14245,9 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+ util-promisify@3.0.0:
+ resolution: {integrity: sha512-uWRZJMjSWt/A1J1exfqz7xiKx2kVpAHR5qIDr6WwwBMQHDoKbo2I1kQN62iA2uXHxOSVpZRDvbm8do+4ijfkNA==}
+
utils-merge@1.0.1:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
@@ -15719,8 +15722,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies:
@@ -15954,8 +15955,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-classic@47.2.0':
dependencies:
@@ -15965,8 +15964,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-decoupled@47.2.0':
dependencies:
@@ -15985,8 +15982,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-multi-root@47.2.0':
dependencies:
@@ -16009,8 +16004,6 @@ snapshots:
'@ckeditor/ckeditor5-table': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-emoji@47.2.0':
dependencies:
@@ -16036,8 +16029,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-engine': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-essentials@47.2.0':
dependencies:
@@ -16169,8 +16160,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
'@ckeditor/ckeditor5-widget': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-html-embed@47.2.0':
dependencies:
@@ -16587,8 +16576,6 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-special-characters@47.2.0':
dependencies:
@@ -24356,7 +24343,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- express-openid-connect@2.19.2(express@5.1.0):
+ express-openid-connect@2.19.3(express@5.1.0):
dependencies:
base64url: 3.0.1
clone: 2.1.2
@@ -24370,6 +24357,7 @@ snapshots:
on-headers: 1.1.0
openid-client: 4.9.1
url-join: 4.0.1
+ util-promisify: 3.0.0
transitivePeerDependencies:
- supports-color
@@ -31602,6 +31590,10 @@ snapshots:
util-deprecate@1.0.2: {}
+ util-promisify@3.0.0:
+ dependencies:
+ object.getownpropertydescriptors: 2.1.8
+
utils-merge@1.0.1: {}
uuid@11.1.0: {}
From 097e36677ae4e88b066f7f384d65d6711a9ae87d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 01:42:35 +0000
Subject: [PATCH 13/49] chore(deps): update dependency stylelint to v16.26.0
---
packages/ckeditor5-admonition/package.json | 2 +-
packages/ckeditor5-footnotes/package.json | 2 +-
.../ckeditor5-keyboard-marker/package.json | 2 +-
packages/ckeditor5-math/package.json | 2 +-
packages/ckeditor5-mermaid/package.json | 2 +-
pnpm-lock.yaml | 189 +++++++++++-------
6 files changed, 117 insertions(+), 82 deletions(-)
diff --git a/packages/ckeditor5-admonition/package.json b/packages/ckeditor5-admonition/package.json
index 0d01ce409..ba46d61f4 100644
--- a/packages/ckeditor5-admonition/package.json
+++ b/packages/ckeditor5-admonition/package.json
@@ -33,7 +33,7 @@
"eslint-config-ckeditor5": ">=9.1.0",
"http-server": "14.1.1",
"lint-staged": "16.2.7",
- "stylelint": "16.25.0",
+ "stylelint": "16.26.0",
"stylelint-config-ckeditor5": ">=9.1.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
diff --git a/packages/ckeditor5-footnotes/package.json b/packages/ckeditor5-footnotes/package.json
index 974da5771..4a14f5f7a 100644
--- a/packages/ckeditor5-footnotes/package.json
+++ b/packages/ckeditor5-footnotes/package.json
@@ -34,7 +34,7 @@
"eslint-config-ckeditor5": ">=9.1.0",
"http-server": "14.1.1",
"lint-staged": "16.2.7",
- "stylelint": "16.25.0",
+ "stylelint": "16.26.0",
"stylelint-config-ckeditor5": ">=9.1.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
diff --git a/packages/ckeditor5-keyboard-marker/package.json b/packages/ckeditor5-keyboard-marker/package.json
index c076f208f..82069dc9e 100644
--- a/packages/ckeditor5-keyboard-marker/package.json
+++ b/packages/ckeditor5-keyboard-marker/package.json
@@ -36,7 +36,7 @@
"eslint-config-ckeditor5": ">=9.1.0",
"http-server": "14.1.1",
"lint-staged": "16.2.7",
- "stylelint": "16.25.0",
+ "stylelint": "16.26.0",
"stylelint-config-ckeditor5": ">=9.1.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
diff --git a/packages/ckeditor5-math/package.json b/packages/ckeditor5-math/package.json
index fbd21f7d1..537260c27 100644
--- a/packages/ckeditor5-math/package.json
+++ b/packages/ckeditor5-math/package.json
@@ -37,7 +37,7 @@
"eslint-config-ckeditor5": ">=9.1.0",
"http-server": "14.1.1",
"lint-staged": "16.2.7",
- "stylelint": "16.25.0",
+ "stylelint": "16.26.0",
"stylelint-config-ckeditor5": ">=9.1.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
diff --git a/packages/ckeditor5-mermaid/package.json b/packages/ckeditor5-mermaid/package.json
index 76e0e9df9..2d637efc5 100644
--- a/packages/ckeditor5-mermaid/package.json
+++ b/packages/ckeditor5-mermaid/package.json
@@ -36,7 +36,7 @@
"eslint-config-ckeditor5": ">=9.1.0",
"http-server": "14.1.1",
"lint-staged": "16.2.7",
- "stylelint": "16.25.0",
+ "stylelint": "16.26.0",
"stylelint-config-ckeditor5": ">=9.1.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d66f9bfa2..626849a30 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -915,11 +915,11 @@ importers:
specifier: 16.2.7
version: 16.2.7
stylelint:
- specifier: 16.25.0
- version: 16.25.0(typescript@5.9.3)
+ specifier: 16.26.0
+ version: 16.26.0(typescript@5.9.3)
stylelint-config-ckeditor5:
specifier: '>=9.1.0'
- version: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ version: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.9.3)
@@ -975,11 +975,11 @@ importers:
specifier: 16.2.7
version: 16.2.7
stylelint:
- specifier: 16.25.0
- version: 16.25.0(typescript@5.9.3)
+ specifier: 16.26.0
+ version: 16.26.0(typescript@5.9.3)
stylelint-config-ckeditor5:
specifier: '>=9.1.0'
- version: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ version: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.9.3)
@@ -1035,11 +1035,11 @@ importers:
specifier: 16.2.7
version: 16.2.7
stylelint:
- specifier: 16.25.0
- version: 16.25.0(typescript@5.9.3)
+ specifier: 16.26.0
+ version: 16.26.0(typescript@5.9.3)
stylelint-config-ckeditor5:
specifier: '>=9.1.0'
- version: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ version: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.9.3)
@@ -1102,11 +1102,11 @@ importers:
specifier: 16.2.7
version: 16.2.7
stylelint:
- specifier: 16.25.0
- version: 16.25.0(typescript@5.9.3)
+ specifier: 16.26.0
+ version: 16.26.0(typescript@5.9.3)
stylelint-config-ckeditor5:
specifier: '>=9.1.0'
- version: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ version: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.9.3)
@@ -1169,11 +1169,11 @@ importers:
specifier: 16.2.7
version: 16.2.7
stylelint:
- specifier: 16.25.0
- version: 16.25.0(typescript@5.9.3)
+ specifier: 16.26.0
+ version: 16.26.0(typescript@5.9.3)
stylelint-config-ckeditor5:
specifier: '>=9.1.0'
- version: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ version: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
ts-node:
specifier: 10.9.2
version: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.9.3)
@@ -1748,6 +1748,12 @@ packages:
'@bundled-es-modules/tough-cookie@0.1.6':
resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
+ '@cacheable/memory@2.0.5':
+ resolution: {integrity: sha512-fkiAxCvssEyJZ5fxX4tcdZFRmW9JehSTGvvqmXn6rTzG5cH6V/3C4ad8yb01vOjp2xBydHkHrgpW0qeGtzt6VQ==}
+
+ '@cacheable/utils@2.3.1':
+ resolution: {integrity: sha512-38NJXjIr4W1Sghun8ju+uYWD8h2c61B4dKwfnQHVDFpAJ9oS28RpfqZQJ6Dgd3RceGkILDY9YT+72HJR3LoeSQ==}
+
'@chevrotain/cst-dts-gen@11.0.3':
resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==}
@@ -3477,8 +3483,14 @@ packages:
peerDependencies:
tslib: '2'
- '@keyv/serialize@1.1.0':
- resolution: {integrity: sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==}
+ '@keyv/bigmap@1.3.0':
+ resolution: {integrity: sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ keyv: ^5.5.4
+
+ '@keyv/serialize@1.1.1':
+ resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
'@kwsites/file-exists@1.1.1':
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
@@ -6507,8 +6519,8 @@ packages:
resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==}
engines: {node: '>=8'}
- cacheable@1.10.4:
- resolution: {integrity: sha512-Gd7ccIUkZ9TE2odLQVS+PDjIvQCdJKUlLdJRVvZu0aipj07Qfx+XIej7hhDrKGGoIxV5m5fT/kOJNJPQhQneRg==}
+ cacheable@2.2.0:
+ resolution: {integrity: sha512-LEJxRqfeomiiRd2t0uON6hxAtgOoWDfY3fugebbz+J3vDLO+SkdfFChQcOHTZhj9SYa9iwE9MGYNX72dKiOE4w==}
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
@@ -8317,8 +8329,8 @@ packages:
fflate@0.8.2:
resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
- file-entry-cache@10.1.4:
- resolution: {integrity: sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==}
+ file-entry-cache@11.1.1:
+ resolution: {integrity: sha512-TPVFSDE7q91Dlk1xpFLvFllf8r0HyOMOlnWy7Z2HBku5H3KhIeOGInexrIeg2D64DosVB/JXkrrk6N/7Wriq4A==}
file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
@@ -8394,8 +8406,8 @@ packages:
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
engines: {node: '>=16'}
- flat-cache@6.1.13:
- resolution: {integrity: sha512-gmtS2PaUjSPa4zjObEIn4WWliKyZzYljgxODBfxugpK6q6HU9ClXzgCJ+nlcPKY9Bt090ypTOLIFWkV0jbKFjw==}
+ flat-cache@6.1.19:
+ resolution: {integrity: sha512-l/K33newPTZMTGAnnzaiqSl6NnH7Namh8jBNjrgjprWxGmZUuxx/sJNIRaijOh3n7q7ESbhNZC+pvVZMFdeU4A==}
flat@5.0.2:
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
@@ -8822,6 +8834,10 @@ packages:
resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
engines: {node: '>= 0.4.0'}
+ hashery@1.2.0:
+ resolution: {integrity: sha512-43XJKpwle72Ik5Zpam7MuzRWyNdwwdf6XHlh8wCj2PggvWf+v/Dm5B0dxGZOmddidgeO6Ofu9As/o231Ti/9PA==}
+ engines: {node: '>=20'}
+
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
@@ -8901,8 +8917,8 @@ packages:
hoist-non-react-statics@2.5.5:
resolution: {integrity: sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==}
- hookified@1.12.0:
- resolution: {integrity: sha512-hMr1Y9TCLshScrBbV2QxJ9BROddxZ12MX9KsCtuGGy/3SmmN5H1PllKerrVlSotur9dlE8hmUKAOSa3WDzsZmQ==}
+ hookified@1.13.0:
+ resolution: {integrity: sha512-6sPYUY8olshgM/1LDNW4QZQN0IqgKhtl/1C8koNZBJrKLBk3AZl6chQtNwpNztvfiApHMEwMHek5rv993PRbWw==}
hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@@ -9755,8 +9771,8 @@ packages:
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
- keyv@5.5.0:
- resolution: {integrity: sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==}
+ keyv@5.5.4:
+ resolution: {integrity: sha512-eohl3hKTiVyD1ilYdw9T0OiB4hnjef89e3dMYKz+mVKDzj+5IteTseASUsOB+EU9Tf6VNTCjDePcP6wkDGmLKQ==}
khroma@2.1.0:
resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
@@ -12261,6 +12277,10 @@ packages:
pwacompat@2.0.17:
resolution: {integrity: sha512-6Du7IZdIy7cHiv7AhtDy4X2QRM8IAD5DII69mt5qWibC2d15ZU8DmBG1WdZKekG11cChSu4zkSUGPF9sweOl6w==}
+ qified@0.5.2:
+ resolution: {integrity: sha512-7gJ6mxcQb9vUBOtbKm5mDevbe2uRcOEVp1g4gb/Q+oLntB3HY8eBhOYRxFI2mlDFlY1e4DOSCptzxarXRvzxCA==}
+ engines: {node: '>=20'}
+
qjobs@1.2.0:
resolution: {integrity: sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==}
engines: {node: '>=0.9'}
@@ -13568,8 +13588,8 @@ packages:
peerDependencies:
stylelint: '>=16.0.0'
- stylelint@16.25.0:
- resolution: {integrity: sha512-Li0avYWV4nfv1zPbdnxLYBGq4z8DVZxbRgx4Kn6V+Uftz1rMoF1qiEI3oL4kgWqyYgCgs7gT5maHNZ82Gk03vQ==}
+ stylelint@16.26.0:
+ resolution: {integrity: sha512-Y/3AVBefrkqqapVYH3LBF5TSDZ1kw+0XpdKN2KchfuhMK6lQ85S4XOG4lIZLcrcS4PWBmvcY6eS2kCQFz0jukQ==}
engines: {node: '>=18.12.0'}
hasBin: true
@@ -15537,6 +15557,18 @@ snapshots:
tough-cookie: 4.1.4
optional: true
+ '@cacheable/memory@2.0.5':
+ dependencies:
+ '@cacheable/utils': 2.3.1
+ '@keyv/bigmap': 1.3.0(keyv@5.5.4)
+ hookified: 1.13.0
+ keyv: 5.5.4
+
+ '@cacheable/utils@2.3.1':
+ dependencies:
+ hashery: 1.2.0
+ keyv: 5.5.4
+
'@chevrotain/cst-dts-gen@11.0.3':
dependencies:
'@chevrotain/gast': 11.0.3
@@ -15719,8 +15751,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies:
@@ -15954,8 +15984,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-classic@47.2.0':
dependencies:
@@ -15965,8 +15993,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-decoupled@47.2.0':
dependencies:
@@ -16036,8 +16062,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-engine': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-essentials@47.2.0':
dependencies:
@@ -16169,8 +16193,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
'@ckeditor/ckeditor5-widget': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-html-embed@47.2.0':
dependencies:
@@ -16403,8 +16425,8 @@ snapshots:
process: 0.11.10
raw-loader: 4.0.2(webpack@5.101.3(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.0))
style-loader: 2.0.0(webpack@5.101.3(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.0))
- stylelint: 16.25.0(typescript@5.0.4)
- stylelint-config-ckeditor5: 2.0.1(stylelint@16.25.0(typescript@5.9.3))
+ stylelint: 16.26.0(typescript@5.0.4)
+ stylelint-config-ckeditor5: 2.0.1(stylelint@16.26.0(typescript@5.9.3))
terser-webpack-plugin: 5.3.14(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.0)(webpack@5.101.3(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.0))
ts-loader: 9.5.4(typescript@5.0.4)(webpack@5.101.3(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.0))
ts-node: 10.9.2(@swc/core@1.11.29(@swc/helpers@0.5.17))(@types/node@24.10.1)(typescript@5.0.4)
@@ -16499,8 +16521,6 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-restricted-editing@47.2.0':
dependencies:
@@ -16587,8 +16607,6 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-special-characters@47.2.0':
dependencies:
@@ -18451,7 +18469,13 @@ snapshots:
'@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1)
tslib: 2.8.1
- '@keyv/serialize@1.1.0': {}
+ '@keyv/bigmap@1.3.0(keyv@5.5.4)':
+ dependencies:
+ hashery: 1.2.0
+ hookified: 1.13.0
+ keyv: 5.5.4
+
+ '@keyv/serialize@1.1.1': {}
'@kwsites/file-exists@1.1.1':
dependencies:
@@ -20193,7 +20217,7 @@ snapshots:
- supports-color
- typescript
- '@stylistic/stylelint-plugin@3.1.3(stylelint@16.25.0(typescript@5.9.3))':
+ '@stylistic/stylelint-plugin@3.1.3(stylelint@16.26.0(typescript@5.9.3))':
dependencies:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
@@ -20203,7 +20227,7 @@ snapshots:
postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
style-search: 0.1.0
- stylelint: 16.25.0(typescript@5.9.3)
+ stylelint: 16.26.0(typescript@5.9.3)
'@swc/core-darwin-arm64@1.11.29':
optional: true
@@ -22079,10 +22103,13 @@ snapshots:
normalize-url: 6.1.0
responselike: 2.0.1
- cacheable@1.10.4:
+ cacheable@2.2.0:
dependencies:
- hookified: 1.12.0
- keyv: 5.5.0
+ '@cacheable/memory': 2.0.5
+ '@cacheable/utils': 2.3.1
+ hookified: 1.13.0
+ keyv: 5.5.4
+ qified: 0.5.2
call-bind-apply-helpers@1.0.2:
dependencies:
@@ -24555,9 +24582,9 @@ snapshots:
fflate@0.8.2: {}
- file-entry-cache@10.1.4:
+ file-entry-cache@11.1.1:
dependencies:
- flat-cache: 6.1.13
+ flat-cache: 6.1.19
file-entry-cache@8.0.0:
dependencies:
@@ -24664,11 +24691,11 @@ snapshots:
flatted: 3.3.3
keyv: 4.5.4
- flat-cache@6.1.13:
+ flat-cache@6.1.19:
dependencies:
- cacheable: 1.10.4
+ cacheable: 2.2.0
flatted: 3.3.3
- hookified: 1.12.0
+ hookified: 1.13.0
flat@5.0.2: {}
@@ -25171,6 +25198,10 @@ snapshots:
has@1.0.4: {}
+ hashery@1.2.0:
+ dependencies:
+ hookified: 1.13.0
+
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
@@ -25310,7 +25341,7 @@ snapshots:
hoist-non-react-statics@2.5.5: {}
- hookified@1.12.0: {}
+ hookified@1.13.0: {}
hosted-git-info@2.8.9: {}
@@ -26243,9 +26274,9 @@ snapshots:
dependencies:
json-buffer: 3.0.1
- keyv@5.5.0:
+ keyv@5.5.4:
dependencies:
- '@keyv/serialize': 1.1.0
+ '@keyv/serialize': 1.1.1
khroma@2.1.0: {}
@@ -29105,6 +29136,10 @@ snapshots:
pwacompat@2.0.17: {}
+ qified@0.5.2:
+ dependencies:
+ hookified: 1.13.0
+
qjobs@1.2.0: {}
qs@6.13.0:
@@ -30683,31 +30718,31 @@ snapshots:
postcss: 8.5.6
postcss-selector-parser: 7.1.0
- stylelint-config-ckeditor5@13.0.0(stylelint@16.25.0(typescript@5.9.3)):
+ stylelint-config-ckeditor5@13.0.0(stylelint@16.26.0(typescript@5.9.3)):
dependencies:
- '@stylistic/stylelint-plugin': 3.1.3(stylelint@16.25.0(typescript@5.9.3))
- stylelint: 16.25.0(typescript@5.9.3)
- stylelint-config-recommended: 16.0.0(stylelint@16.25.0(typescript@5.9.3))
- stylelint-plugin-ckeditor5-rules: 13.0.0(stylelint@16.25.0(typescript@5.9.3))
+ '@stylistic/stylelint-plugin': 3.1.3(stylelint@16.26.0(typescript@5.9.3))
+ stylelint: 16.26.0(typescript@5.9.3)
+ stylelint-config-recommended: 16.0.0(stylelint@16.26.0(typescript@5.9.3))
+ stylelint-plugin-ckeditor5-rules: 13.0.0(stylelint@16.26.0(typescript@5.9.3))
- stylelint-config-ckeditor5@2.0.1(stylelint@16.25.0(typescript@5.9.3)):
+ stylelint-config-ckeditor5@2.0.1(stylelint@16.26.0(typescript@5.9.3)):
dependencies:
- stylelint: 16.25.0(typescript@5.9.3)
- stylelint-config-recommended: 3.0.0(stylelint@16.25.0(typescript@5.9.3))
+ stylelint: 16.26.0(typescript@5.9.3)
+ stylelint-config-recommended: 3.0.0(stylelint@16.26.0(typescript@5.9.3))
- stylelint-config-recommended@16.0.0(stylelint@16.25.0(typescript@5.9.3)):
+ stylelint-config-recommended@16.0.0(stylelint@16.26.0(typescript@5.9.3)):
dependencies:
- stylelint: 16.25.0(typescript@5.9.3)
+ stylelint: 16.26.0(typescript@5.9.3)
- stylelint-config-recommended@3.0.0(stylelint@16.25.0(typescript@5.9.3)):
+ stylelint-config-recommended@3.0.0(stylelint@16.26.0(typescript@5.9.3)):
dependencies:
- stylelint: 16.25.0(typescript@5.9.3)
+ stylelint: 16.26.0(typescript@5.9.3)
- stylelint-plugin-ckeditor5-rules@13.0.0(stylelint@16.25.0(typescript@5.9.3)):
+ stylelint-plugin-ckeditor5-rules@13.0.0(stylelint@16.26.0(typescript@5.9.3)):
dependencies:
- stylelint: 16.25.0(typescript@5.9.3)
+ stylelint: 16.26.0(typescript@5.9.3)
- stylelint@16.25.0(typescript@5.0.4):
+ stylelint@16.26.0(typescript@5.0.4):
dependencies:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
@@ -30722,7 +30757,7 @@ snapshots:
debug: 4.4.3(supports-color@6.0.0)
fast-glob: 3.3.3
fastest-levenshtein: 1.0.16
- file-entry-cache: 10.1.4
+ file-entry-cache: 11.1.1
global-modules: 2.0.0
globby: 11.1.0
globjoin: 0.1.4
@@ -30751,7 +30786,7 @@ snapshots:
- supports-color
- typescript
- stylelint@16.25.0(typescript@5.9.3):
+ stylelint@16.26.0(typescript@5.9.3):
dependencies:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
@@ -30766,7 +30801,7 @@ snapshots:
debug: 4.4.3(supports-color@6.0.0)
fast-glob: 3.3.3
fastest-levenshtein: 1.0.16
- file-entry-cache: 10.1.4
+ file-entry-cache: 11.1.1
global-modules: 2.0.0
globby: 11.1.0
globjoin: 0.1.4
From 1e5b95f64a0afde80afd458d2e9d6fe50e4c7a3f Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 06:05:44 +0000
Subject: [PATCH 14/49] fix(deps): update dependency better-sqlite3 to v12.4.6
---
apps/desktop/package.json | 2 +-
apps/dump-db/package.json | 2 +-
apps/edit-docs/package.json | 2 +-
apps/server/docker/package.json | 2 +-
apps/server/package.json | 2 +-
pnpm-lock.yaml | 32 ++++++++++++--------------------
6 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/apps/desktop/package.json b/apps/desktop/package.json
index 284551e29..0753e7bb3 100644
--- a/apps/desktop/package.json
+++ b/apps/desktop/package.json
@@ -23,7 +23,7 @@
},
"dependencies": {
"@electron/remote": "2.1.3",
- "better-sqlite3": "12.4.1",
+ "better-sqlite3": "12.4.6",
"electron-debug": "4.1.0",
"electron-dl": "4.0.0",
"electron-squirrel-startup": "1.0.1",
diff --git a/apps/dump-db/package.json b/apps/dump-db/package.json
index 029eca464..0495eb038 100644
--- a/apps/dump-db/package.json
+++ b/apps/dump-db/package.json
@@ -4,7 +4,7 @@
"description": "Standalone tool to dump contents of Trilium document.db file into a directory tree of notes",
"private": true,
"dependencies": {
- "better-sqlite3": "12.4.1",
+ "better-sqlite3": "12.4.6",
"mime-types": "3.0.1",
"sanitize-filename": "1.6.3",
"tsx": "4.20.6",
diff --git a/apps/edit-docs/package.json b/apps/edit-docs/package.json
index af66c3623..9aa8ebe82 100644
--- a/apps/edit-docs/package.json
+++ b/apps/edit-docs/package.json
@@ -5,7 +5,7 @@
"description": "Desktop version of Trilium which imports the demo database (presented to new users at start-up) or the user guide and other documentation and saves the modifications for committing.",
"dependencies": {
"archiver": "7.0.1",
- "better-sqlite3": "12.4.1"
+ "better-sqlite3": "12.4.6"
},
"devDependencies": {
"@triliumnext/client": "workspace:*",
diff --git a/apps/server/docker/package.json b/apps/server/docker/package.json
index 73a44e831..6ed152f94 100644
--- a/apps/server/docker/package.json
+++ b/apps/server/docker/package.json
@@ -1,5 +1,5 @@
{
"dependencies": {
- "better-sqlite3": "12.4.1"
+ "better-sqlite3": "12.4.6"
}
}
\ No newline at end of file
diff --git a/apps/server/package.json b/apps/server/package.json
index 97038b99d..71223bc00 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -25,7 +25,7 @@
"docker-start-rootless-alpine": "pnpm docker-build-rootless-alpine && docker run -p 8081:8080 triliumnext-rootless-alpine"
},
"dependencies": {
- "better-sqlite3": "12.4.1",
+ "better-sqlite3": "12.4.6",
"html-to-text": "9.0.5",
"node-html-parser": "7.0.1"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d66f9bfa2..b4f904a41 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -369,8 +369,8 @@ importers:
specifier: 2.1.3
version: 2.1.3(electron@38.7.1)
better-sqlite3:
- specifier: 12.4.1
- version: 12.4.1
+ specifier: 12.4.6
+ version: 12.4.6
electron-debug:
specifier: 4.1.0
version: 4.1.0
@@ -433,8 +433,8 @@ importers:
apps/dump-db:
dependencies:
better-sqlite3:
- specifier: 12.4.1
- version: 12.4.1
+ specifier: 12.4.6
+ version: 12.4.6
mime-types:
specifier: 3.0.1
version: 3.0.1
@@ -464,8 +464,8 @@ importers:
specifier: 7.0.1
version: 7.0.1
better-sqlite3:
- specifier: 12.4.1
- version: 12.4.1
+ specifier: 12.4.6
+ version: 12.4.6
devDependencies:
'@triliumnext/client':
specifier: workspace:*
@@ -489,8 +489,8 @@ importers:
apps/server:
dependencies:
better-sqlite3:
- specifier: 12.4.1
- version: 12.4.1
+ specifier: 12.4.6
+ version: 12.4.6
html-to-text:
specifier: 9.0.5
version: 9.0.5
@@ -6342,9 +6342,9 @@ packages:
peerDependencies:
ajv: 4.11.8 - 8
- better-sqlite3@12.4.1:
- resolution: {integrity: sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ==}
- engines: {node: 20.x || 22.x || 23.x || 24.x}
+ better-sqlite3@12.4.6:
+ resolution: {integrity: sha512-gaYt9yqTbQ1iOxLpJA8FPR5PiaHP+jlg8I5EX0Rs2KFwNzhBsF40KzMZS5FwelY7RG0wzaucWdqSAJM3uNCPCg==}
+ engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x}
bezier-easing@2.1.0:
resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==}
@@ -15954,8 +15954,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-classic@47.2.0':
dependencies:
@@ -16036,8 +16034,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-engine': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-essentials@47.2.0':
dependencies:
@@ -16169,8 +16165,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
'@ckeditor/ckeditor5-widget': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-html-embed@47.2.0':
dependencies:
@@ -16587,8 +16581,6 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-special-characters@47.2.0':
dependencies:
@@ -21813,7 +21805,7 @@ snapshots:
jsonpointer: 5.0.1
leven: 3.1.0
- better-sqlite3@12.4.1:
+ better-sqlite3@12.4.6:
dependencies:
bindings: 1.5.0
prebuild-install: 7.1.3
From a8e9f7b44522fe26e362c0c7f19be413e001c6f5 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 07:08:13 +0000
Subject: [PATCH 15/49] fix(deps): update dependency mime-types to v3.0.2
---
apps/dump-db/package.json | 2 +-
apps/server/package.json | 2 +-
pnpm-lock.yaml | 32 +++++++++++++-------------------
3 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/apps/dump-db/package.json b/apps/dump-db/package.json
index 0495eb038..ccbd40097 100644
--- a/apps/dump-db/package.json
+++ b/apps/dump-db/package.json
@@ -5,7 +5,7 @@
"private": true,
"dependencies": {
"better-sqlite3": "12.4.6",
- "mime-types": "3.0.1",
+ "mime-types": "3.0.2",
"sanitize-filename": "1.6.3",
"tsx": "4.20.6",
"yargs": "18.0.0"
diff --git a/apps/server/package.json b/apps/server/package.json
index 71223bc00..6dcf2820e 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -104,7 +104,7 @@
"is-svg": "6.1.0",
"jimp": "1.6.0",
"marked": "17.0.1",
- "mime-types": "3.0.1",
+ "mime-types": "3.0.2",
"multer": "2.0.2",
"normalize-strings": "1.1.1",
"ollama": "0.6.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b4f904a41..99da4b588 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -436,8 +436,8 @@ importers:
specifier: 12.4.6
version: 12.4.6
mime-types:
- specifier: 3.0.1
- version: 3.0.1
+ specifier: 3.0.2
+ version: 3.0.2
sanitize-filename:
specifier: 1.6.3
version: 1.6.3
@@ -721,8 +721,8 @@ importers:
specifier: 17.0.1
version: 17.0.1
mime-types:
- specifier: 3.0.1
- version: 3.0.1
+ specifier: 3.0.2
+ version: 3.0.2
multer:
specifier: 2.0.2
version: 2.0.2
@@ -10369,9 +10369,9 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
- mime-types@3.0.1:
- resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
- engines: {node: '>= 0.6'}
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
@@ -15719,8 +15719,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies:
@@ -15963,8 +15961,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-decoupled@47.2.0':
dependencies:
@@ -15983,8 +15979,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
- transitivePeerDependencies:
- - supports-color
'@ckeditor/ckeditor5-editor-multi-root@47.2.0':
dependencies:
@@ -21381,7 +21375,7 @@ snapshots:
accepts@2.0.0:
dependencies:
- mime-types: 3.0.1
+ mime-types: 3.0.2
negotiator: 1.0.0
accessor-fn@1.5.3: {}
@@ -24435,7 +24429,7 @@ snapshots:
fresh: 2.0.0
http-errors: 2.0.0
merge-descriptors: 2.0.0
- mime-types: 3.0.1
+ mime-types: 3.0.2
on-finished: 2.4.1
once: 1.4.0
parseurl: 1.3.3
@@ -27131,7 +27125,7 @@ snapshots:
dependencies:
mime-db: 1.52.0
- mime-types@3.0.1:
+ mime-types@3.0.2:
dependencies:
mime-db: 1.54.0
@@ -29980,7 +29974,7 @@ snapshots:
etag: 1.8.1
fresh: 2.0.0
http-errors: 2.0.0
- mime-types: 3.0.1
+ mime-types: 3.0.2
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
@@ -31311,7 +31305,7 @@ snapshots:
dependencies:
content-type: 1.0.5
media-typer: 1.1.0
- mime-types: 3.0.1
+ mime-types: 3.0.2
typed-array-buffer@1.0.3:
dependencies:
@@ -31879,7 +31873,7 @@ snapshots:
dependencies:
colorette: 2.0.20
memfs: 4.42.0
- mime-types: 3.0.1
+ mime-types: 3.0.2
on-finished: 2.4.1
range-parser: 1.2.1
schema-utils: 4.3.2
From d7519660786d56226424cb0ed50239371a8e5ccf Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 09:10:41 +0200
Subject: [PATCH 16/49] chore(server/mime): remove mp4 workaround
---
apps/server/src/services/import/mime.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/apps/server/src/services/import/mime.ts b/apps/server/src/services/import/mime.ts
index 0a129ae1e..b25e98926 100644
--- a/apps/server/src/services/import/mime.ts
+++ b/apps/server/src/services/import/mime.ts
@@ -73,8 +73,7 @@ const EXTENSION_TO_MIME = new Map([
[".ts", "text/x-typescript"],
[".excalidraw", "application/json"],
[".mermaid", "text/vnd.mermaid"],
- [".mmd", "text/vnd.mermaid"],
- [".mp4", "video/mp4"] // https://github.com/jshttp/mime-types/issues/138
+ [".mmd", "text/vnd.mermaid"]
]);
/** @returns false if MIME is not detected */
From 790454f194c8d5ac7b987f280e6103884de4bccb Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 07:10:46 +0000
Subject: [PATCH 17/49] chore(deps): update vitest monorepo to v4.0.13
---
_regroup/package.json | 2 +-
apps/website/package.json | 2 +-
package.json | 8 +-
packages/ckeditor5-admonition/package.json | 6 +-
packages/ckeditor5-footnotes/package.json | 6 +-
.../ckeditor5-keyboard-marker/package.json | 6 +-
packages/ckeditor5-math/package.json | 6 +-
packages/ckeditor5-mermaid/package.json | 6 +-
pnpm-lock.yaml | 240 +++++++++---------
9 files changed, 146 insertions(+), 136 deletions(-)
diff --git a/_regroup/package.json b/_regroup/package.json
index b6a98a290..2875c903c 100644
--- a/_regroup/package.json
+++ b/_regroup/package.json
@@ -40,7 +40,7 @@
"@types/express": "5.0.5",
"@types/node": "24.10.1",
"@types/yargs": "17.0.35",
- "@vitest/coverage-v8": "4.0.12",
+ "@vitest/coverage-v8": "4.0.13",
"eslint": "9.39.1",
"eslint-plugin-simple-import-sort": "12.1.1",
"esm": "3.2.25",
diff --git a/apps/website/package.json b/apps/website/package.json
index 6f5c81858..aea8a520f 100644
--- a/apps/website/package.json
+++ b/apps/website/package.json
@@ -23,7 +23,7 @@
"typescript": "5.9.3",
"user-agent-data-types": "0.4.2",
"vite": "7.2.4",
- "vitest": "4.0.12"
+ "vitest": "4.0.13"
},
"eslintConfig": {
"extends": "preact"
diff --git a/package.json b/package.json
index c69db6253..0b68b16f1 100644
--- a/package.json
+++ b/package.json
@@ -44,9 +44,9 @@
"@triliumnext/server": "workspace:*",
"@types/express": "5.0.5",
"@types/node": "24.10.1",
- "@vitest/browser-webdriverio": "4.0.12",
- "@vitest/coverage-v8": "4.0.12",
- "@vitest/ui": "4.0.12",
+ "@vitest/browser-webdriverio": "4.0.13",
+ "@vitest/coverage-v8": "4.0.13",
+ "@vitest/ui": "4.0.13",
"chalk": "5.6.2",
"cross-env": "10.1.0",
"dpdm": "3.14.0",
@@ -68,7 +68,7 @@
"upath": "2.0.1",
"vite": "7.2.4",
"vite-plugin-dts": "~4.5.0",
- "vitest": "4.0.12"
+ "vitest": "4.0.13"
},
"license": "AGPL-3.0-only",
"author": {
diff --git a/packages/ckeditor5-admonition/package.json b/packages/ckeditor5-admonition/package.json
index ba46d61f4..a0babdad9 100644
--- a/packages/ckeditor5-admonition/package.json
+++ b/packages/ckeditor5-admonition/package.json
@@ -26,8 +26,8 @@
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.47.0",
"@typescript-eslint/parser": "8.47.0",
- "@vitest/browser": "4.0.12",
- "@vitest/coverage-istanbul": "4.0.12",
+ "@vitest/browser": "4.0.13",
+ "@vitest/coverage-istanbul": "4.0.13",
"ckeditor5": "47.2.0",
"eslint": "9.39.1",
"eslint-config-ckeditor5": ">=9.1.0",
@@ -38,7 +38,7 @@
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
- "vitest": "4.0.12",
+ "vitest": "4.0.13",
"webdriverio": "9.20.1"
},
"peerDependencies": {
diff --git a/packages/ckeditor5-footnotes/package.json b/packages/ckeditor5-footnotes/package.json
index 4a14f5f7a..a61a8cf19 100644
--- a/packages/ckeditor5-footnotes/package.json
+++ b/packages/ckeditor5-footnotes/package.json
@@ -27,8 +27,8 @@
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.47.0",
"@typescript-eslint/parser": "8.47.0",
- "@vitest/browser": "4.0.12",
- "@vitest/coverage-istanbul": "4.0.12",
+ "@vitest/browser": "4.0.13",
+ "@vitest/coverage-istanbul": "4.0.13",
"ckeditor5": "47.2.0",
"eslint": "9.39.1",
"eslint-config-ckeditor5": ">=9.1.0",
@@ -39,7 +39,7 @@
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
- "vitest": "4.0.12",
+ "vitest": "4.0.13",
"webdriverio": "9.20.1"
},
"peerDependencies": {
diff --git a/packages/ckeditor5-keyboard-marker/package.json b/packages/ckeditor5-keyboard-marker/package.json
index 82069dc9e..1385ba605 100644
--- a/packages/ckeditor5-keyboard-marker/package.json
+++ b/packages/ckeditor5-keyboard-marker/package.json
@@ -29,8 +29,8 @@
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.47.0",
"@typescript-eslint/parser": "8.47.0",
- "@vitest/browser": "4.0.12",
- "@vitest/coverage-istanbul": "4.0.12",
+ "@vitest/browser": "4.0.13",
+ "@vitest/coverage-istanbul": "4.0.13",
"ckeditor5": "47.2.0",
"eslint": "9.39.1",
"eslint-config-ckeditor5": ">=9.1.0",
@@ -41,7 +41,7 @@
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
- "vitest": "4.0.12",
+ "vitest": "4.0.13",
"webdriverio": "9.20.1"
},
"peerDependencies": {
diff --git a/packages/ckeditor5-math/package.json b/packages/ckeditor5-math/package.json
index 537260c27..fad4a8ae7 100644
--- a/packages/ckeditor5-math/package.json
+++ b/packages/ckeditor5-math/package.json
@@ -30,8 +30,8 @@
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.47.0",
"@typescript-eslint/parser": "8.47.0",
- "@vitest/browser": "4.0.12",
- "@vitest/coverage-istanbul": "4.0.12",
+ "@vitest/browser": "4.0.13",
+ "@vitest/coverage-istanbul": "4.0.13",
"ckeditor5": "47.2.0",
"eslint": "9.39.1",
"eslint-config-ckeditor5": ">=9.1.0",
@@ -42,7 +42,7 @@
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
- "vitest": "4.0.12",
+ "vitest": "4.0.13",
"webdriverio": "9.20.1"
},
"peerDependencies": {
diff --git a/packages/ckeditor5-mermaid/package.json b/packages/ckeditor5-mermaid/package.json
index 2d637efc5..0b3b85649 100644
--- a/packages/ckeditor5-mermaid/package.json
+++ b/packages/ckeditor5-mermaid/package.json
@@ -29,8 +29,8 @@
"@ckeditor/ckeditor5-package-tools": "5.0.1",
"@typescript-eslint/eslint-plugin": "~8.47.0",
"@typescript-eslint/parser": "8.47.0",
- "@vitest/browser": "4.0.12",
- "@vitest/coverage-istanbul": "4.0.12",
+ "@vitest/browser": "4.0.13",
+ "@vitest/coverage-istanbul": "4.0.13",
"ckeditor5": "47.2.0",
"eslint": "9.39.1",
"eslint-config-ckeditor5": ">=9.1.0",
@@ -41,7 +41,7 @@
"ts-node": "10.9.2",
"typescript": "5.9.3",
"vite-plugin-svgo": "~2.0.0",
- "vitest": "4.0.12",
+ "vitest": "4.0.13",
"webdriverio": "9.20.1"
},
"peerDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4dbec7854..d27bf175c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -56,14 +56,14 @@ importers:
specifier: 24.10.1
version: 24.10.1
'@vitest/browser-webdriverio':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-v8':
- specifier: 4.0.12
- version: 4.0.12(@vitest/browser@4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(@vitest/browser@4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13))(vitest@4.0.13)
'@vitest/ui':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
chalk:
specifier: 5.6.2
version: 5.6.2
@@ -128,8 +128,8 @@ importers:
specifier: ~4.5.0
version: 4.5.4(@types/node@24.10.1)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
apps/build-docs:
devDependencies:
@@ -839,8 +839,8 @@ importers:
specifier: 7.2.4
version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
packages/ckeditor5:
dependencies:
@@ -894,11 +894,11 @@ importers:
specifier: 8.47.0
version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
'@vitest/coverage-istanbul':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
ckeditor5:
specifier: 47.2.0
version: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
@@ -930,8 +930,8 @@ importers:
specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio:
specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@@ -954,11 +954,11 @@ importers:
specifier: 8.47.0
version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
'@vitest/coverage-istanbul':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
ckeditor5:
specifier: 47.2.0
version: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
@@ -990,8 +990,8 @@ importers:
specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio:
specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@@ -1014,11 +1014,11 @@ importers:
specifier: 8.47.0
version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
'@vitest/coverage-istanbul':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
ckeditor5:
specifier: 47.2.0
version: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
@@ -1050,8 +1050,8 @@ importers:
specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio:
specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@@ -1081,11 +1081,11 @@ importers:
specifier: 8.47.0
version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
'@vitest/coverage-istanbul':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
ckeditor5:
specifier: 47.2.0
version: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
@@ -1117,8 +1117,8 @@ importers:
specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio:
specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@@ -1148,11 +1148,11 @@ importers:
specifier: 8.47.0
version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser':
- specifier: 4.0.12
- version: 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
'@vitest/coverage-istanbul':
- specifier: 4.0.12
- version: 4.0.12(vitest@4.0.12)
+ specifier: 4.0.13
+ version: 4.0.13(vitest@4.0.13)
ckeditor5:
specifier: 47.2.0
version: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
@@ -1184,8 +1184,8 @@ importers:
specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest:
- specifier: 4.0.12
- version: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ specifier: 4.0.13
+ version: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio:
specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@@ -5744,36 +5744,36 @@ packages:
resolution: {integrity: sha512-ir6xo6HLy3TVn4lVJ+9fOOcq8vvgMmcXoSP/mM+l1CTKKJmd0hzXqNkZ1CYyz7PiRhLPUC6fprmUuA7rnVC87g==}
engines: {node: '>=16'}
- '@vitest/browser-webdriverio@4.0.12':
- resolution: {integrity: sha512-Z9aiTXwI9wqocxE6pnZRoC+lypbFVfOGUYGhUnlRDQx4DGYRUgWhHwQvBGiLLAOrJdWERkrcRdp+Keu9G2VdDA==}
+ '@vitest/browser-webdriverio@4.0.13':
+ resolution: {integrity: sha512-eDKpZx3Y6ciiOrO+ZVdAd2p7vwfG/amN1Sp6lkQPoGpD2kxNcgP0MpfoV0gE9p6WAauyuwEH6lO64cmivRu6Pw==}
peerDependencies:
- vitest: 4.0.12
+ vitest: 4.0.13
webdriverio: '*'
- '@vitest/browser@4.0.12':
- resolution: {integrity: sha512-8zE2ksJ7V4B7Mc++L6rBRZOZHnE/f9URvj7oLYKIS5wcDaSi6EhfalN0EG6+R/OlTYZarbK6RqmhKDLYNC9KfQ==}
+ '@vitest/browser@4.0.13':
+ resolution: {integrity: sha512-lruSgrYPVAJzKmX6EJYCg9nY+0A4VkeTLpTzf1jRD/XMjNbzD9yy7D499xmVKglwJczANYJXBvZSPGcRlon+0w==}
peerDependencies:
- vitest: 4.0.12
+ vitest: 4.0.13
- '@vitest/coverage-istanbul@4.0.12':
- resolution: {integrity: sha512-2cdoONLhTCxAxbQmjeiguupFSSyVSMKWXmPOAffUGzAnH3uPMigX5Mf2F8fUuciKo0WxM6vdSucA9K7qxRTFwA==}
+ '@vitest/coverage-istanbul@4.0.13':
+ resolution: {integrity: sha512-bkoHarZBdrLDMLEQV3AJ+wcD3cETOLCjZrKO+nA4IbIY74uPPJ2pT7CEvdp8OF5AR5NNSYyafn6kAXTJBbDAaA==}
peerDependencies:
- vitest: 4.0.12
+ vitest: 4.0.13
- '@vitest/coverage-v8@4.0.12':
- resolution: {integrity: sha512-d+w9xAFJJz6jyJRU4BUU7MH409Ush7FWKNkxJU+jASKg6WX33YT0zc+YawMR1JesMWt9QRFQY/uAD3BTn23FaA==}
+ '@vitest/coverage-v8@4.0.13':
+ resolution: {integrity: sha512-w77N6bmtJ3CFnL/YHiYotwW/JI3oDlR3K38WEIqegRfdMSScaYxwYKB/0jSNpOTZzUjQkG8HHEz4sdWQMWpQ5g==}
peerDependencies:
- '@vitest/browser': 4.0.12
- vitest: 4.0.12
+ '@vitest/browser': 4.0.13
+ vitest: 4.0.13
peerDependenciesMeta:
'@vitest/browser':
optional: true
- '@vitest/expect@4.0.12':
- resolution: {integrity: sha512-is+g0w8V3/ZhRNrRizrJNr8PFQKwYmctWlU4qg8zy5r9aIV5w8IxXLlfbbxJCwSpsVl2PXPTm2/zruqTqz3QSg==}
+ '@vitest/expect@4.0.13':
+ resolution: {integrity: sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==}
- '@vitest/mocker@4.0.12':
- resolution: {integrity: sha512-GsmA/tD5Ht3RUFoz41mZsMU1AXch3lhmgbTnoSPTdH231g7S3ytNN1aU0bZDSyxWs8WA7KDyMPD5L4q6V6vj9w==}
+ '@vitest/mocker@4.0.13':
+ resolution: {integrity: sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==}
peerDependencies:
msw: ^2.4.9
vite: ^6.0.0 || ^7.0.0-0
@@ -5783,25 +5783,25 @@ packages:
vite:
optional: true
- '@vitest/pretty-format@4.0.12':
- resolution: {integrity: sha512-R7nMAcnienG17MvRN8TPMJiCG8rrZJblV9mhT7oMFdBXvS0x+QD6S1G4DxFusR2E0QIS73f7DqSR1n87rrmE+g==}
+ '@vitest/pretty-format@4.0.13':
+ resolution: {integrity: sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==}
- '@vitest/runner@4.0.12':
- resolution: {integrity: sha512-hDlCIJWuwlcLumfukPsNfPDOJokTv79hnOlf11V+n7E14rHNPz0Sp/BO6h8sh9qw4/UjZiKyYpVxK2ZNi+3ceQ==}
+ '@vitest/runner@4.0.13':
+ resolution: {integrity: sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==}
- '@vitest/snapshot@4.0.12':
- resolution: {integrity: sha512-2jz9zAuBDUSbnfyixnyOd1S2YDBrZO23rt1bicAb6MA/ya5rHdKFRikPIDpBj/Dwvh6cbImDmudegnDAkHvmRQ==}
+ '@vitest/snapshot@4.0.13':
+ resolution: {integrity: sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==}
- '@vitest/spy@4.0.12':
- resolution: {integrity: sha512-GZjI9PPhiOYNX8Nsyqdw7JQB+u0BptL5fSnXiottAUBHlcMzgADV58A7SLTXXQwcN1yZ6gfd1DH+2bqjuUlCzw==}
+ '@vitest/spy@4.0.13':
+ resolution: {integrity: sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==}
- '@vitest/ui@4.0.12':
- resolution: {integrity: sha512-RCqeApCnbwd5IFvxk6OeKMXTvzHU/cVqY8HAW0gWk0yAO6wXwQJMKhDfDtk2ss7JCy9u7RNC3kyazwiaDhBA/g==}
+ '@vitest/ui@4.0.13':
+ resolution: {integrity: sha512-MFV6GhTflgBj194+vowTB2iLI5niMZhqiW7/NV7U4AfWbX/IAtsq4zA+gzCLyGzpsQUdJlX26hrQ1vuWShq2BQ==}
peerDependencies:
- vitest: 4.0.12
+ vitest: 4.0.13
- '@vitest/utils@4.0.12':
- resolution: {integrity: sha512-DVS/TLkLdvGvj1avRy0LSmKfrcI9MNFvNGN6ECjTUHWJdlcgPDOXhjMis5Dh7rBH62nAmSXnkPbE+DZ5YD75Rw==}
+ '@vitest/utils@4.0.13':
+ resolution: {integrity: sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==}
'@volar/language-core@2.4.13':
resolution: {integrity: sha512-MnQJ7eKchJx5Oz+YdbqyFUk8BN6jasdJv31n/7r6/WwlOOv7qzvot6B66887l2ST3bUW4Mewml54euzpJWA6bg==}
@@ -14386,8 +14386,8 @@ packages:
yaml:
optional: true
- vitest@4.0.12:
- resolution: {integrity: sha512-pmW4GCKQ8t5Ko1jYjC3SqOr7TUKN7uHOHB/XGsAIb69eYu6d1ionGSsb5H9chmPf+WeXt0VE7jTXsB1IvWoNbw==}
+ vitest@4.0.13:
+ resolution: {integrity: sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
hasBin: true
peerDependencies:
@@ -14395,10 +14395,10 @@ packages:
'@opentelemetry/api': ^1.9.0
'@types/debug': ^4.1.12
'@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
- '@vitest/browser-playwright': 4.0.12
- '@vitest/browser-preview': 4.0.12
- '@vitest/browser-webdriverio': 4.0.12
- '@vitest/ui': 4.0.12
+ '@vitest/browser-playwright': 4.0.13
+ '@vitest/browser-preview': 4.0.13
+ '@vitest/browser-webdriverio': 4.0.13
+ '@vitest/ui': 4.0.13
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
@@ -15754,6 +15754,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies:
@@ -15987,6 +15989,8 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-editor-classic@47.2.0':
dependencies:
@@ -16014,6 +16018,8 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-editor-multi-root@47.2.0':
dependencies:
@@ -16036,6 +16042,8 @@ snapshots:
'@ckeditor/ckeditor5-table': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-emoji@47.2.0':
dependencies:
@@ -16061,6 +16069,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-engine': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-essentials@47.2.0':
dependencies:
@@ -21099,10 +21109,10 @@ snapshots:
- bufferutil
- utf-8-validate
- '@vitest/browser-webdriverio@4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
+ '@vitest/browser-webdriverio@4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
dependencies:
- '@vitest/browser': 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
- vitest: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ '@vitest/browser': 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
+ vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies:
- bufferutil
@@ -21110,16 +21120,16 @@ snapshots:
- utf-8-validate
- vite
- '@vitest/browser@4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)':
+ '@vitest/browser@4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)':
dependencies:
- '@vitest/mocker': 4.0.12(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
- '@vitest/utils': 4.0.12
+ '@vitest/mocker': 4.0.13(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
+ '@vitest/utils': 4.0.13
magic-string: 0.30.21
pixelmatch: 7.1.0
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.0.3
- vitest: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies:
- bufferutil
@@ -21127,7 +21137,7 @@ snapshots:
- utf-8-validate
- vite
- '@vitest/coverage-istanbul@4.0.12(vitest@4.0.12)':
+ '@vitest/coverage-istanbul@4.0.13(vitest@4.0.13)':
dependencies:
'@istanbuljs/schema': 0.1.3
debug: 4.4.3(supports-color@6.0.0)
@@ -21138,14 +21148,14 @@ snapshots:
istanbul-reports: 3.2.0
magicast: 0.5.1
tinyrainbow: 3.0.3
- vitest: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
- '@vitest/coverage-v8@4.0.12(@vitest/browser@4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12))(vitest@4.0.12)':
+ '@vitest/coverage-v8@4.0.13(@vitest/browser@4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13))(vitest@4.0.13)':
dependencies:
'@bcoe/v8-coverage': 1.0.2
- '@vitest/utils': 4.0.12
+ '@vitest/utils': 4.0.13
ast-v8-to-istanbul: 0.3.8
debug: 4.4.3(supports-color@6.0.0)
istanbul-lib-coverage: 3.2.2
@@ -21155,61 +21165,61 @@ snapshots:
magicast: 0.5.1
std-env: 3.10.0
tinyrainbow: 3.0.3
- vitest: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
optionalDependencies:
- '@vitest/browser': 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)
+ '@vitest/browser': 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)
transitivePeerDependencies:
- supports-color
- '@vitest/expect@4.0.12':
+ '@vitest/expect@4.0.13':
dependencies:
'@standard-schema/spec': 1.0.0
'@types/chai': 5.2.2
- '@vitest/spy': 4.0.12
- '@vitest/utils': 4.0.12
+ '@vitest/spy': 4.0.13
+ '@vitest/utils': 4.0.13
chai: 6.2.1
tinyrainbow: 3.0.3
- '@vitest/mocker@4.0.12(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))':
+ '@vitest/mocker@4.0.13(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))':
dependencies:
- '@vitest/spy': 4.0.12
+ '@vitest/spy': 4.0.13
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
msw: 2.7.5(@types/node@24.10.1)(typescript@5.9.3)
vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
- '@vitest/pretty-format@4.0.12':
+ '@vitest/pretty-format@4.0.13':
dependencies:
tinyrainbow: 3.0.3
- '@vitest/runner@4.0.12':
+ '@vitest/runner@4.0.13':
dependencies:
- '@vitest/utils': 4.0.12
+ '@vitest/utils': 4.0.13
pathe: 2.0.3
- '@vitest/snapshot@4.0.12':
+ '@vitest/snapshot@4.0.13':
dependencies:
- '@vitest/pretty-format': 4.0.12
+ '@vitest/pretty-format': 4.0.13
magic-string: 0.30.21
pathe: 2.0.3
- '@vitest/spy@4.0.12': {}
+ '@vitest/spy@4.0.13': {}
- '@vitest/ui@4.0.12(vitest@4.0.12)':
+ '@vitest/ui@4.0.13(vitest@4.0.13)':
dependencies:
- '@vitest/utils': 4.0.12
+ '@vitest/utils': 4.0.13
fflate: 0.8.2
flatted: 3.3.3
pathe: 2.0.3
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vitest: 4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+ vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
- '@vitest/utils@4.0.12':
+ '@vitest/utils@4.0.13':
dependencies:
- '@vitest/pretty-format': 4.0.12
+ '@vitest/pretty-format': 4.0.13
tinyrainbow: 3.0.3
'@volar/language-core@2.4.13':
@@ -31744,15 +31754,15 @@ snapshots:
tsx: 4.20.6
yaml: 2.8.1
- vitest@4.0.12(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.12)(@vitest/ui@4.0.12)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
+ vitest@4.0.13(@opentelemetry/api@1.9.0)(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.13)(@vitest/ui@4.0.13)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
dependencies:
- '@vitest/expect': 4.0.12
- '@vitest/mocker': 4.0.12(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
- '@vitest/pretty-format': 4.0.12
- '@vitest/runner': 4.0.12
- '@vitest/snapshot': 4.0.12
- '@vitest/spy': 4.0.12
- '@vitest/utils': 4.0.12
+ '@vitest/expect': 4.0.13
+ '@vitest/mocker': 4.0.13(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
+ '@vitest/pretty-format': 4.0.13
+ '@vitest/runner': 4.0.13
+ '@vitest/snapshot': 4.0.13
+ '@vitest/spy': 4.0.13
+ '@vitest/utils': 4.0.13
debug: 4.4.3(supports-color@6.0.0)
es-module-lexer: 1.7.0
expect-type: 1.2.2
@@ -31770,8 +31780,8 @@ snapshots:
'@opentelemetry/api': 1.9.0
'@types/debug': 4.1.12
'@types/node': 24.10.1
- '@vitest/browser-webdriverio': 4.0.12(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.12)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
- '@vitest/ui': 4.0.12(vitest@4.0.12)
+ '@vitest/browser-webdriverio': 4.0.13(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.13)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
+ '@vitest/ui': 4.0.13(vitest@4.0.13)
happy-dom: 20.0.10
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies:
From 66cc739bb2adb16fa1c6ba0e7152b48ef76e5284 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 22 Nov 2025 07:12:56 +0000
Subject: [PATCH 18/49] chore(deps): update dependency @anthropic-ai/sdk to
v0.70.1
---
apps/server/package.json | 2 +-
pnpm-lock.yaml | 20 +++++++++++++++-----
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/apps/server/package.json b/apps/server/package.json
index 1da6d1ab7..b7178714e 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -30,7 +30,7 @@
"node-html-parser": "7.0.1"
},
"devDependencies": {
- "@anthropic-ai/sdk": "0.70.0",
+ "@anthropic-ai/sdk": "0.70.1",
"@braintree/sanitize-url": "7.1.1",
"@electron/remote": "2.1.3",
"@preact/preset-vite": "2.10.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4dbec7854..5f54138a3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -499,8 +499,8 @@ importers:
version: 7.0.1
devDependencies:
'@anthropic-ai/sdk':
- specifier: 0.70.0
- version: 0.70.0(zod@4.1.12)
+ specifier: 0.70.1
+ version: 0.70.1(zod@4.1.12)
'@braintree/sanitize-url':
specifier: 7.1.1
version: 7.1.1
@@ -1439,8 +1439,8 @@ packages:
'@antfu/utils@9.2.0':
resolution: {integrity: sha512-Oq1d9BGZakE/FyoEtcNeSwM7MpDO2vUBi11RWBZXf75zPsbUVWmUs03EqkRFrcgbXyKTas0BdZWC1wcuSoqSAw==}
- '@anthropic-ai/sdk@0.70.0':
- resolution: {integrity: sha512-FYIuhF/lSCa+pgtaMGgsTF14aOIiWtBnu3azXITDOELv6yxsDNJwcjjt+Zr7vwyuTUjZJE/YL7s9m5r1jXkoeQ==}
+ '@anthropic-ai/sdk@0.70.1':
+ resolution: {integrity: sha512-AGEhifuvE22VxfQ5ROxViTgM8NuVQzEvqcN8bttR4AP24ythmNE/cL/SrOz79xiv7/osrsmCyErjsistJi7Z8A==}
hasBin: true
peerDependencies:
zod: ^3.25.0 || ^4.0.0
@@ -14933,7 +14933,7 @@ snapshots:
'@antfu/utils@9.2.0': {}
- '@anthropic-ai/sdk@0.70.0(zod@4.1.12)':
+ '@anthropic-ai/sdk@0.70.1(zod@4.1.12)':
dependencies:
json-schema-to-ts: 3.1.1
optionalDependencies:
@@ -15754,6 +15754,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies:
@@ -15996,6 +15998,8 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-editor-decoupled@47.2.0':
dependencies:
@@ -16014,6 +16018,8 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-editor-multi-root@47.2.0':
dependencies:
@@ -16036,6 +16042,8 @@ snapshots:
'@ckeditor/ckeditor5-table': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-emoji@47.2.0':
dependencies:
@@ -16520,6 +16528,8 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
+ transitivePeerDependencies:
+ - supports-color
'@ckeditor/ckeditor5-restricted-editing@47.2.0':
dependencies:
From 135ce2285d74a3aa4df7f9bca71c096a0479c53f Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 09:45:08 +0200
Subject: [PATCH 19/49] feat(collections): don't load all collection types at
once
---
.../src/widgets/collections/NoteList.tsx | 36 +++++++++----------
1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/apps/client/src/widgets/collections/NoteList.tsx b/apps/client/src/widgets/collections/NoteList.tsx
index bd007a40f..1f6427978 100644
--- a/apps/client/src/widgets/collections/NoteList.tsx
+++ b/apps/client/src/widgets/collections/NoteList.tsx
@@ -2,20 +2,12 @@ import { allViewTypes, ViewModeMedia, ViewModeProps, ViewTypeOptions } from "./i
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "../react/hooks";
import FNote from "../../entities/fnote";
import "./NoteList.css";
-import { ListView, GridView } from "./legacy/ListOrGridView";
import { useEffect, useRef, useState } from "preact/hooks";
-import GeoView from "./geomap";
import ViewModeStorage from "./view_mode_storage";
-import CalendarView from "./calendar";
-import TableView from "./table";
-import BoardView from "./board";
import { subscribeToMessages, unsubscribeToMessage as unsubscribeFromMessage } from "../../services/ws";
import { WebSocketMessage } from "@triliumnext/commons";
import froca from "../../services/froca";
-import PresentationView from "./presentation";
-import { ListPrintView } from "./legacy/ListPrintView";
-import TablePrintView from "./table/TablePrintView";
-
+import { lazy, Suspense } from "preact/compat";
interface NoteListProps {
note: FNote | null | undefined;
notePath: string | null | undefined;
@@ -94,11 +86,15 @@ export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePa
}
}
+ const ComponentToRender = viewType && props && isEnabled && getComponentByViewType(viewType, props);
+
return (
- {props && isEnabled && (
+ {ComponentToRender && props && (
- {getComponentByViewType(viewType, props)}
+
+
+
)}
@@ -109,26 +105,26 @@ function getComponentByViewType(viewType: ViewTypeOptions, props: ViewModeProps<
switch (viewType) {
case "list":
if (props.media !== "print") {
- return ;
+ return lazy(() => import("./legacy/ListOrGridView.js").then(i => i.ListView));
} else {
- return ;
+ return lazy(() => import("./legacy/ListPrintView.js").then(i => i.ListPrintView));
}
case "grid":
- return ;
+ return lazy(() => import("./legacy/ListOrGridView.js").then(i => i.GridView));
case "geoMap":
- return ;
+ return lazy(() => import("./geomap/index.js"));
case "calendar":
- return ;
+ return lazy(() => import("./calendar/index.js"));
case "table":
if (props.media !== "print") {
- return ;
+ return lazy(() => import("./table/index.js"));
} else {
- return ;
+ return lazy(() => import("./table/TablePrintView.js"));
}
case "board":
- return
+ return lazy(() => import("./board/index.js"));
case "presentation":
- return
+ return lazy(() => import("./presentation/index.js"));
}
}
From 494bd425afd4e12bcdb019177896df3126a374cb Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 10:13:46 +0200
Subject: [PATCH 20/49] feat(print): avoid error message for print job
cancelled
---
apps/server/src/services/window.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/server/src/services/window.ts b/apps/server/src/services/window.ts
index 626ab851f..4431226ab 100644
--- a/apps/server/src/services/window.ts
+++ b/apps/server/src/services/window.ts
@@ -82,7 +82,7 @@ interface ExportAsPdfOpts {
electron.ipcMain.on("print-note", async (e, { notePath }: PrintOpts) => {
const browserWindow = await getBrowserWindowForPrinting(e, notePath, "printing");
browserWindow.webContents.print({}, (success, failureReason) => {
- if (!success) {
+ if (!success && failureReason !== "Print job canceled") {
electron.dialog.showErrorBox(t("pdf.unable-to-print"), failureReason);
}
e.sender.send("print-done");
From 6692de33b1ecc70622ad90f77346f366af0ec1ba Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 10:49:46 +0200
Subject: [PATCH 21/49] fix(sidebar): not displayed if items are enabled from
the start
---
apps/client/src/widgets/containers/right_pane_container.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/containers/right_pane_container.ts b/apps/client/src/widgets/containers/right_pane_container.ts
index 84875bec1..1c88f3695 100644
--- a/apps/client/src/widgets/containers/right_pane_container.ts
+++ b/apps/client/src/widgets/containers/right_pane_container.ts
@@ -5,6 +5,7 @@ import type { EventData, EventNames } from "../../components/app_context.js";
export default class RightPaneContainer extends FlexContainer {
private rightPaneHidden: boolean;
+ private firstRender: boolean;
constructor() {
super("column");
@@ -14,6 +15,7 @@ export default class RightPaneContainer extends FlexContainer
this.collapsible();
this.rightPaneHidden = false;
+ this.firstRender = true;
}
isEnabled() {
@@ -41,10 +43,11 @@ export default class RightPaneContainer extends FlexContainer
const oldToggle = !this.isHiddenInt();
const newToggle = this.isEnabled();
- if (oldToggle !== newToggle) {
+ if (oldToggle !== newToggle || this.firstRender) {
this.toggleInt(newToggle);
splitService.setupRightPaneResizer();
+ this.firstRender = false;
}
}
From 5fc10fe0414738dfce22b9f3ab3cb18f740c1c48 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 10:51:48 +0200
Subject: [PATCH 22/49] chore(react/sidebar): basic right panel widget
implementation
---
apps/client/src/layouts/desktop_layout.tsx | 1 +
.../src/widgets/sidebar/RightPanelWidget.tsx | 33 +++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 apps/client/src/widgets/sidebar/RightPanelWidget.tsx
diff --git a/apps/client/src/layouts/desktop_layout.tsx b/apps/client/src/layouts/desktop_layout.tsx
index 17c77f8d8..cbce8fb18 100644
--- a/apps/client/src/layouts/desktop_layout.tsx
+++ b/apps/client/src/layouts/desktop_layout.tsx
@@ -44,6 +44,7 @@ import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
import utils from "../services/utils.js";
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
import NoteDetail from "../widgets/NoteDetail.jsx";
+import RightPanelWidget from "../widgets/sidebar/RightPanelWidget.jsx";
export default class DesktopLayout {
diff --git a/apps/client/src/widgets/sidebar/RightPanelWidget.tsx b/apps/client/src/widgets/sidebar/RightPanelWidget.tsx
new file mode 100644
index 000000000..94a5cf04c
--- /dev/null
+++ b/apps/client/src/widgets/sidebar/RightPanelWidget.tsx
@@ -0,0 +1,33 @@
+import { useContext, useRef } from "preact/hooks";
+import { ParentComponent } from "../react/react_utils";
+import { ComponentChildren } from "preact";
+
+interface RightPanelWidgetProps {
+ title: string;
+ children: ComponentChildren;
+ buttons?: ComponentChildren;
+}
+
+export default function RightPanelWidget({ title, buttons, children }: RightPanelWidgetProps) {
+ const containerRef = useRef(null);
+ const parentComponent = useContext(ParentComponent);
+
+ if (parentComponent) {
+ parentComponent.initialized = Promise.resolve();
+ }
+
+ return (
+
+ );
+}
From 7daee36d3ed684d0a93cad08b00ee3c786925a65 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 10:59:50 +0200
Subject: [PATCH 23/49] fix(toc): table of contents not rendering for doc notes
---
apps/client/src/widgets/toc.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/toc.ts b/apps/client/src/widgets/toc.ts
index a58ea2fa7..49e311149 100644
--- a/apps/client/src/widgets/toc.ts
+++ b/apps/client/src/widgets/toc.ts
@@ -199,6 +199,7 @@ export default class TocWidget extends RightPanelWidget {
* For document note types, we obtain the content directly from the DOM since it allows us to obtain processed data without
* requesting data twice. However, when immediately navigating to a new note the new document is not yet attached to the hierarchy,
* resulting in an empty TOC. The fix is to simply wait for it to pop up.
+ * TODO: Use a better method that is not prone to unnecessary delays and race conditions.
*/
setTimeout(async () => {
const $contentEl = await this.noteContext?.getContentElement();
@@ -209,7 +210,7 @@ export default class TocWidget extends RightPanelWidget {
} else {
console.warn("Unable to get content element for doctype");
}
- }, 10);
+ }, 250);
}
}
From 664d28f1054b4e598aa7cd71b16f852ab63076a7 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 11:03:00 +0200
Subject: [PATCH 24/49] docs(scripting): remove workaround for sidebar
visibility
---
.../Notes/Printing & Exporting as PDF.html | 61 +++++++++----------
.../Custom Widgets/Right pane widget.html | 20 +++---
.../Developer Guide/Documentation.md | 2 +-
docs/User Guide/!!!meta.json | 22 +++----
.../Custom Widgets/Right pane widget.md | 17 ++++--
5 files changed, 65 insertions(+), 57 deletions(-)
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
index 2e3b2c92c..744d1d5e5 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
@@ -4,6 +4,7 @@
Screenshot of the note contextual menu indicating the “Export as PDF”
option.
+
Printing
This feature allows printing of notes. It works on both the desktop client,
but also on the web.
@@ -59,9 +60,9 @@ class="admonition note">
orientation, size. However, there are a few Attributes to adjust some of the settings:
- - To print in landscape mode instead of portrait (useful for big diagrams
+
- To print in landscape mode instead of portrait (useful for big diagrams
or slides), add
#printLandscape.
- - By default, the resulting PDF will be in Letter format. It is possible
+
- By default, the resulting PDF will be in Letter format. It is possible
to adjust it to another page size via the
#printPageSize attribute,
with one of the following values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
@@ -73,10 +74,9 @@ class="admonition note">
Since v0.100.0, it is possible to print more than one note at the time
by using Collections:
- - First create a collection.
- - Configure it to use List View.
- - Print the collection note normally.
+ - First create a collection.
+ - Configure it to use List View.
+ - Print the collection note normally.
The resulting collection will contain all the children of the collection,
while maintaining the hierarchy.
@@ -86,9 +86,9 @@ class="admonition note">
href="#root/_help_4TIF1oA4VQRO">Options and assigning a key combination
for:
- - Print Active Note
+
- Print Active Note
- - Export Active Note as PDF
+
- Export Active Note as PDF
Constraints & limitations
@@ -96,39 +96,39 @@ class="admonition note">
supported when printing, in which case the Print and Export as PDF options
will be disabled.
- - For Code notes:
+
- For Code notes:
- - Line numbers are not printed.
- - Syntax highlighting is enabled, however a default theme (Visual Studio)
+
- Line numbers are not printed.
+ - Syntax highlighting is enabled, however a default theme (Visual Studio)
is enforced.
- - For Collections,
+
- For Collections,
the following are supported:
- - List View, allowing
+
- List View, allowing
to print multiple notes at once while preserving hierarchy (similar to
a book).
- - Presentation,
+
- Presentation,
where each slide/sub-note is displayed.
- - Table,
- where the table is rendered in a print-friendly way.
+
- Table, where the
+ table is rendered in a print-friendly way.
- - Tables that are too complex (especially if they have multiple columns)
+
- Tables that are too complex (especially if they have multiple columns)
might not fit properly, however tables with a large number of rows are
- supported thanks to pagination.
- - Consider printing in landscape mode, or using
#printLandscape if
+ supported thanks to pagination.
+ - Consider printing in landscape mode, or using
#printLandscape if
exporting to PDF.
- - The rest of the collections are not supported, but we plan to add support
+
- The rest of the collections are not supported, but we plan to add support
for all the collection types at some point.
- - Using Custom app-wide CSS for
+
- Using Custom app-wide CSS for
printing is not longer supported, due to a more stable but isolated mechanism.
- - We plan to introduce a new mechanism specifically for a print CSS.
+ - We plan to introduce a new mechanism specifically for a print CSS.
@@ -139,10 +139,10 @@ class="admonition note">
printing.
To do so:
- - Create a CSS code note.
- - On the note being printed, apply the
~printCss relation to
+ - Create a CSS code note.
+ - On the note being printed, apply the
~printCss relation to
point to the newly created CSS code note.
- - To apply the CSS to multiple notes, consider using inheritable attributes or
+
- To apply the CSS to multiple notes, consider using inheritable attributes or
Templates.
@@ -153,13 +153,12 @@ class="admonition note">
}
To remark:
- - Multiple CSS notes can be add by using multiple
~printCss relations.
- - If the note pointing to the
printCss doesn't have the right
+ - Multiple CSS notes can be add by using multiple
~printCss relations.
+ - If the note pointing to the
printCss doesn't have the right
note type or mime type, it will be ignored.
- - If migrating from a previous version where Custom app-wide CSS, there's no need for
@media print { since
- the style-sheet is used only for printing.
+ - If migrating from a previous version where Custom app-wide CSS, there's no need for
@media print { since
+ the style-sheet is used only for printing.
Under the hood
Both printing and exporting as PDF use the same mechanism: a note is rendered
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.html
index 27437786f..e4706e317 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.html
@@ -1,12 +1,13 @@
- doRender must not be overridden, instead doRenderBody() has
+ doRender must not be overridden, instead doRenderBody() has
to be overridden.
- doRenderBody can optionally be async.
+ doRenderBody can optionally be async.
- parentWidget() must be set to “rightPane”.
- widgetTitle() getter can optionally be overriden, otherwise
+ parentWidget() must be set to “rightPane”.
+ widgetTitle() getter can optionally be overriden, otherwise
the widget will be displayed as “Untitled widget”.
const template = `<div>Hi</div>`;
@@ -23,12 +24,13 @@ class ToDoListWidget extends api.RightPanelWidget {
}
async refreshWithNote(note) {
- this.toggleInt(false);
- this.triggerCommand("reEvaluateRightPaneVisibility");
- this.toggleInt(true);
- this.triggerCommand("reEvaluateRightPaneVisibility");
+ // Do something when the note changes.
}
}
module.exports = new ToDoListWidget();
-The implementation is in src/public/app/widgets/right_panel_widget.js.
\ No newline at end of file
+The implementation is in src/public/app/widgets/right_panel_widget.js.
+Conditionally changing visibility
+In refreshWithNote:
const visible = true; // replace with your own visibility logic
+this.toggleInt(visible);
+this.triggerCommand("reEvaluateRightPaneVisibility");
\ No newline at end of file
diff --git a/docs/Developer Guide/Developer Guide/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md
index 6e7ea215f..f891e39c9 100644
--- a/docs/Developer Guide/Developer Guide/Documentation.md
+++ b/docs/Developer Guide/Developer Guide/Documentation.md
@@ -1,5 +1,5 @@
# Documentation
-There are multiple types of documentation for Trilium:
+There are multiple types of documentation for Trilium:
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json
index 014f86614..9932db6be 100644
--- a/docs/User Guide/!!!meta.json
+++ b/docs/User Guide/!!!meta.json
@@ -4104,31 +4104,38 @@
{
"type": "relation",
"name": "internalLink",
- "value": "AlhDUqhENtH7",
+ "value": "2FvYrpmOXm29",
"isInheritable": false,
"position": 100
},
{
"type": "relation",
"name": "internalLink",
- "value": "bwZpz2ajCEwO",
+ "value": "AlhDUqhENtH7",
"isInheritable": false,
"position": 110
},
{
"type": "relation",
"name": "internalLink",
- "value": "KC1HB96bqqHX",
+ "value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 120
},
{
"type": "relation",
"name": "internalLink",
- "value": "0ESUbbAxVnoK",
+ "value": "KC1HB96bqqHX",
"isInheritable": false,
"position": 130
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "0ESUbbAxVnoK",
+ "isInheritable": false,
+ "position": 140
+ },
{
"type": "label",
"name": "iconClass",
@@ -4142,13 +4149,6 @@
"value": "printing-and-pdf-export",
"isInheritable": false,
"position": 110
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "2FvYrpmOXm29",
- "isInheritable": false,
- "position": 140
}
],
"format": "markdown",
diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md
index 7a8cf8cd4..e64364fc8 100644
--- a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md
+++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md
@@ -20,14 +20,21 @@ class ToDoListWidget extends api.RightPanelWidget {
}
async refreshWithNote(note) {
- this.toggleInt(false);
- this.triggerCommand("reEvaluateRightPaneVisibility");
- this.toggleInt(true);
- this.triggerCommand("reEvaluateRightPaneVisibility");
+ // Do something when the note changes.
}
}
module.exports = new ToDoListWidget();
```
-The implementation is in `src/public/app/widgets/right_panel_widget.js`.
\ No newline at end of file
+The implementation is in `src/public/app/widgets/right_panel_widget.js`.
+
+## Conditionally changing visibility
+
+In `refreshWithNote`:
+
+```
+const visible = true; // replace with your own visibility logic
+this.toggleInt(visible);
+this.triggerCommand("reEvaluateRightPaneVisibility");
+```
\ No newline at end of file
From c76f368fa0ea4af5c7a6dacbb32bf8ad75b89728 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 11:21:51 +0200
Subject: [PATCH 25/49] fix(text): classic toolbar sometimes not showing
---
apps/client/src/components/app_context.ts | 1 +
.../src/widgets/ribbon/FormattingToolbar.tsx | 19 ++++++++++--
.../type_widgets/text/EditableText.tsx | 30 +------------------
3 files changed, 18 insertions(+), 32 deletions(-)
diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts
index c73fe5a42..bda3536da 100644
--- a/apps/client/src/components/app_context.ts
+++ b/apps/client/src/components/app_context.ts
@@ -445,6 +445,7 @@ type EventMappings = {
error: string;
};
searchRefreshed: { ntxId?: string | null };
+ textEditorRefreshed: { ntxId?: string | null, editor: CKTextEditor };
hoistedNoteChanged: {
noteId: string;
ntxId: string | null;
diff --git a/apps/client/src/widgets/ribbon/FormattingToolbar.tsx b/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
index 8828b15ee..f25234ead 100644
--- a/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
+++ b/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
@@ -1,4 +1,5 @@
-import { useTriliumOption } from "../react/hooks";
+import { useRef } from "preact/hooks";
+import { useTriliumEvent, useTriliumOption } from "../react/hooks";
import { TabContext } from "./ribbon-interface";
/**
@@ -10,10 +11,22 @@ import { TabContext } from "./ribbon-interface";
*
* ! The toolbar is not only used in the ribbon, but also in the quick edit feature.
*/
-export default function FormattingToolbar({ hidden }: TabContext) {
+export default function FormattingToolbar({ hidden, ntxId }: TabContext) {
+ const containerRef = useRef(null);
const [ textNoteEditorType ] = useTriliumOption("textNoteEditorType");
+ useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
+ if (eventNtxId !== ntxId) return;
+ const toolbar = editor.ui.view.toolbar?.element;
+ if (toolbar && containerRef.current) {
+ containerRef.current.replaceChildren(toolbar);
+ }
+ });
+
return (textNoteEditorType === "ckeditor-classic" &&
-
+
)
};
diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
index 15c235f3f..490eba95d 100644
--- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx
+++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
@@ -251,6 +251,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
}
initialized.current.resolve();
+ parentComponent?.triggerEvent("textEditorRefreshed", { ntxId, editor });
}}
/>}
@@ -304,19 +305,8 @@ function onNotificationWarning(data, evt) {
function setupClassicEditor(editor: CKTextEditor, parentComponent: Component | undefined) {
if (!parentComponent) return;
- const $classicToolbarWidget = findClassicToolbar(parentComponent);
-
- $classicToolbarWidget.empty();
- if ($classicToolbarWidget.length) {
- const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
- if (toolbarView.element) {
- $classicToolbarWidget[0].appendChild(toolbarView.element);
- }
- }
if (utils.isMobile()) {
- $classicToolbarWidget.addClass("visible");
-
// Reposition all dropdowns to point upwards instead of downwards.
// See https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for more info.
const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
@@ -333,24 +323,6 @@ function setupClassicEditor(editor: CKTextEditor, parentComponent: Component | u
}
}
-function findClassicToolbar(parentComponent: Component): JQuery {
- const $widget = $(parentComponent.$widget);
-
- if (!utils.isMobile()) {
- const $parentSplit = $widget.parents(".note-split.type-text");
-
- if ($parentSplit.length) {
- // The editor is in a normal tab.
- return $parentSplit.find("> .ribbon-container .classic-toolbar-widget");
- } else {
- // The editor is in a popup.
- return $widget.closest(".modal-body").find(".classic-toolbar-widget");
- }
- } else {
- return $("body").find(".classic-toolbar-widget");
- }
-}
-
function EditableTextTouchBar({ watchdogRef, refreshTouchBarRef }: { watchdogRef: RefObject, refreshTouchBarRef: RefObject<() => void> }) {
const [ headingSelectedIndex, setHeadingSelectedIndex ] = useState();
From 9b3ca654922e86986cc880e7e35bc5b5a945c140 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 11:37:34 +0200
Subject: [PATCH 26/49] fix(text): classic toolbar broken on mobile due to
prior change
---
.../src/widgets/ribbon/FormattingToolbar.tsx | 9 +++-
.../type_widgets/text/EditableText.tsx | 26 ----------
.../text/mobile_editor_toolbar.tsx | 49 ++++++++++++++++---
3 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/apps/client/src/widgets/ribbon/FormattingToolbar.tsx b/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
index f25234ead..47963b2bf 100644
--- a/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
+++ b/apps/client/src/widgets/ribbon/FormattingToolbar.tsx
@@ -10,16 +10,21 @@ import { TabContext } from "./ribbon-interface";
* The ribbon item is active by default for text notes, as long as they are not in read-only mode.
*
* ! The toolbar is not only used in the ribbon, but also in the quick edit feature.
+ * * The mobile toolbar is handled separately (see `MobileEditorToolbar`).
*/
export default function FormattingToolbar({ hidden, ntxId }: TabContext) {
const containerRef = useRef(null);
const [ textNoteEditorType ] = useTriliumOption("textNoteEditorType");
+ // Attach the toolbar from the CKEditor.
useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
- if (eventNtxId !== ntxId) return;
+ if (eventNtxId !== ntxId || !containerRef.current) return;
const toolbar = editor.ui.view.toolbar?.element;
- if (toolbar && containerRef.current) {
+
+ if (toolbar) {
containerRef.current.replaceChildren(toolbar);
+ } else {
+ containerRef.current.replaceChildren();
}
});
diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
index 490eba95d..9b3915abd 100644
--- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx
+++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
@@ -233,12 +233,6 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
onWatchdogStateChange={onWatchdogStateChange}
onChange={() => spacedUpdate.scheduleUpdate()}
onEditorInitialized={(editor) => {
- console.log("Editor has been initialized!", parentComponent, editor);
-
- if (isClassicEditor) {
- setupClassicEditor(editor, parentComponent);
- }
-
if (hasTouchBar) {
const handler = () => refreshTouchBarRef.current?.();
for (const event of [ "bold", "italic", "underline", "paragraph", "heading" ]) {
@@ -303,26 +297,6 @@ function onNotificationWarning(data, evt) {
evt.stop();
}
-function setupClassicEditor(editor: CKTextEditor, parentComponent: Component | undefined) {
- if (!parentComponent) return;
-
- if (utils.isMobile()) {
- // Reposition all dropdowns to point upwards instead of downwards.
- // See https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for more info.
- const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
- for (const item of toolbarView.items) {
- if (!("panelView" in item)) continue;
-
- item.on("change:isOpen", () => {
- if (!("isOpen" in item) || !item.isOpen) return;
-
- // @ts-ignore
- item.panelView.position = item.panelView.position.replace("s", "n");
- });
- }
- }
-}
-
function EditableTextTouchBar({ watchdogRef, refreshTouchBarRef }: { watchdogRef: RefObject, refreshTouchBarRef: RefObject<() => void> }) {
const [ headingSelectedIndex, setHeadingSelectedIndex ] = useState();
diff --git a/apps/client/src/widgets/type_widgets/text/mobile_editor_toolbar.tsx b/apps/client/src/widgets/type_widgets/text/mobile_editor_toolbar.tsx
index 71965761b..4b2ac7e1c 100644
--- a/apps/client/src/widgets/type_widgets/text/mobile_editor_toolbar.tsx
+++ b/apps/client/src/widgets/type_widgets/text/mobile_editor_toolbar.tsx
@@ -1,7 +1,8 @@
import { MutableRef, useCallback, useEffect, useRef, useState } from "preact/hooks";
-import { useNoteContext } from "../../react/hooks";
+import { useNoteContext, useTriliumEvent } from "../../react/hooks";
import "./mobile_editor_toolbar.css";
import { isIOS } from "../../../services/utils";
+import { CKTextEditor, ClassicEditor } from "@triliumnext/ckeditor5";
/**
* Handles the editing toolbar for CKEditor in mobile mode. The toolbar acts as a floating bar, with two different mechanism:
@@ -10,12 +11,12 @@ import { isIOS } from "../../../services/utils";
* - On Android, the viewport change makes the keyboard resize the content area, all we have to do is to hide the tab bar and global menu (handled in the global style).
*/
export default function MobileEditorToolbar() {
- const wrapperRef = useRef(null);
- const { note, noteContext } = useNoteContext();
+ const containerRef = useRef(null);
+ const { note, noteContext, ntxId } = useNoteContext();
const [ shouldDisplay, setShouldDisplay ] = useState(false);
const [ dropdownActive, setDropdownActive ] = useState(false);
- usePositioningOniOS(wrapperRef);
+ usePositioningOniOS(containerRef);
useEffect(() => {
noteContext?.isReadOnly().then(isReadOnly => {
@@ -23,15 +24,28 @@ export default function MobileEditorToolbar() {
});
}, [ note ]);
+ // Attach the toolbar from the CKEditor.
+ useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
+ if (eventNtxId !== ntxId || !containerRef.current) return;
+ const toolbar = editor.ui.view.toolbar?.element;
+
+ repositionDropdowns(editor);
+ if (toolbar) {
+ containerRef.current.replaceChildren(toolbar);
+ } else {
+ containerRef.current.replaceChildren();
+ }
+ });
+
// Observe when a dropdown is expanded to apply a style that allows the dropdown to be visible, since we can't have the element both visible and the toolbar scrollable.
useEffect(() => {
- if (!wrapperRef.current) return;
+ if (!containerRef.current) return;
const observer = new MutationObserver(e => {
setDropdownActive(e.map((e) => (e.target as any).ariaExpanded === "true").reduce((acc, e) => acc && e));
});
- observer.observe(wrapperRef.current, {
+ observer.observe(containerRef.current, {
attributeFilter: ["aria-expanded"],
subtree: true
});
@@ -41,7 +55,7 @@ export default function MobileEditorToolbar() {
return (
)
}
@@ -50,7 +64,7 @@ function usePositioningOniOS(wrapperRef: MutableRef) {
const adjustPosition = useCallback(() => {
if (!wrapperRef.current) return;
let bottom = window.innerHeight - (window.visualViewport?.height || 0);
- wrapperRef.current.style.bottom = `${bottom}px`;
+ wrapperRef.current.style.bottom = `${bottom}px`;
}, []);
useEffect(() => {
@@ -65,3 +79,22 @@ function usePositioningOniOS(wrapperRef: MutableRef) {
};
}, []);
}
+
+/**
+ * Reposition all dropdowns to point upwards instead of downwards.
+ * See https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for more info.
+ * @param editor
+ */
+function repositionDropdowns(editor: CKTextEditor) {
+ const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
+ for (const item of toolbarView.items) {
+ if (!("panelView" in item)) continue;
+
+ item.on("change:isOpen", () => {
+ if (!("isOpen" in item) || !item.isOpen) return;
+
+ // @ts-ignore
+ item.panelView.position = item.panelView.position.replace("s", "n");
+ });
+ }
+}
From 6040eea3bd9686ff67b084551bce5f7cd1940fd0 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 11:52:16 +0200
Subject: [PATCH 27/49] fix(text): note with empty table carries over to new
notes
---
.../src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx | 6 +-----
apps/client/src/widgets/type_widgets/text/EditableText.tsx | 7 ++++---
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
index fd6814528..1c3a85e23 100644
--- a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
+++ b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
@@ -20,7 +20,6 @@ export interface CKEditorApi {
}
interface CKEditorWithWatchdogProps extends Pick, "className" | "tabIndex"> {
- content: string | undefined;
contentLanguage: string | null | undefined;
isClassicEditor?: boolean;
watchdogRef: RefObject;
@@ -35,7 +34,7 @@ interface CKEditorWithWatchdogProps extends Pick, "cla
containerRef?: RefObject;
}
-export default function CKEditorWithWatchdog({ containerRef: externalContainerRef, content, contentLanguage, className, tabIndex, isClassicEditor, watchdogRef: externalWatchdogRef, watchdogConfig, onNotificationWarning, onWatchdogStateChange, onChange, onEditorInitialized, editorApi, templates }: CKEditorWithWatchdogProps) {
+export default function CKEditorWithWatchdog({ containerRef: externalContainerRef, contentLanguage, className, tabIndex, isClassicEditor, watchdogRef: externalWatchdogRef, watchdogConfig, onNotificationWarning, onWatchdogStateChange, onChange, onEditorInitialized, editorApi, templates }: CKEditorWithWatchdogProps) {
const containerRef = useSyncedRef(externalContainerRef, null);
const watchdogRef = useRef(null);
const [ uiLanguage ] = useTriliumOption("locale");
@@ -185,9 +184,6 @@ export default function CKEditorWithWatchdog({ containerRef: externalContainerRe
return () => watchdog.destroy();
}, [ contentLanguage, templates, uiLanguage ]);
- // React to content changes.
- useEffect(() => editor?.setData(content ?? ""), [ editor, content ]);
-
// React to notification warning callback.
useEffect(() => {
if (!onNotificationWarning || !editor) return;
diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
index 9b3915abd..e3fa1ecee 100644
--- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx
+++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
@@ -27,7 +27,7 @@ import { deferred } from "@triliumnext/commons";
*/
export default function EditableText({ note, parentComponent, ntxId, noteContext }: TypeWidgetProps) {
const containerRef = useRef(null);
- const [ content, setContent ] = useState();
+ const contentRef = useRef("");
const watchdogRef = useRef(null);
const editorApiRef = useRef(null);
const refreshTouchBarRef = useRef<() => void>(null);
@@ -55,7 +55,8 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
};
},
onContentChange(newContent) {
- setContent(newContent);
+ contentRef.current = newContent;
+ watchdogRef.current?.editor?.setData(newContent);
}
});
const templates = useTemplates();
@@ -215,7 +216,6 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
containerRef={containerRef}
className={`note-detail-editable-text-editor use-tn-links ${codeBlockWordWrap ? "word-wrap" : ""}`}
tabIndex={300}
- content={content}
contentLanguage={language}
isClassicEditor={isClassicEditor}
editorApi={editorApiRef}
@@ -245,6 +245,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
}
initialized.current.resolve();
+ editor.setData(contentRef.current ?? "");
parentComponent?.triggerEvent("textEditorRefreshed", { ntxId, editor });
}}
/>}
From 33aece6f96a6b58fe08bdea05bd5de9339e39e1a Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 12:16:48 +0200
Subject: [PATCH 28/49] fix(collections): flicker when adding new entries
---
.../src/widgets/collections/NoteList.tsx | 59 ++++++++++---------
1 file changed, 31 insertions(+), 28 deletions(-)
diff --git a/apps/client/src/widgets/collections/NoteList.tsx b/apps/client/src/widgets/collections/NoteList.tsx
index 1f6427978..1081cd6df 100644
--- a/apps/client/src/widgets/collections/NoteList.tsx
+++ b/apps/client/src/widgets/collections/NoteList.tsx
@@ -8,6 +8,7 @@ import { subscribeToMessages, unsubscribeToMessage as unsubscribeFromMessage } f
import { WebSocketMessage } from "@triliumnext/commons";
import froca from "../../services/froca";
import { lazy, Suspense } from "preact/compat";
+import { VNode } from "preact";
interface NoteListProps {
note: FNote | null | undefined;
notePath: string | null | undefined;
@@ -22,6 +23,33 @@ interface NoteListProps {
onProgressChanged?(progress: number): void;
}
+type LazyLoadedComponent = ((props: ViewModeProps) => VNode | undefined);
+const ViewComponents: Record = {
+ list: {
+ normal: lazy(() => import("./legacy/ListOrGridView.js").then(i => i.ListView)),
+ print: lazy(() => import("./legacy/ListPrintView.js").then(i => i.ListPrintView))
+ },
+ grid: {
+ normal: lazy(() => import("./legacy/ListOrGridView.js").then(i => i.GridView)),
+ },
+ geoMap: {
+ normal: lazy(() => import("./geomap/index.js")),
+ },
+ calendar: {
+ normal: lazy(() => import("./calendar/index.js"))
+ },
+ table: {
+ normal: lazy(() => import("./table/index.js")),
+ print: lazy(() => import("./table/TablePrintView.js"))
+ },
+ board: {
+ normal: lazy(() => import("./board/index.js"))
+ },
+ presentation: {
+ normal: lazy(() => import("./presentation/index.js"))
+ }
+}
+
export default function NoteList(props: Pick) {
const { note, noteContext, notePath, ntxId } = useNoteContext();
const viewType = useNoteViewType(note);
@@ -86,7 +114,9 @@ export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePa
}
}
- const ComponentToRender = viewType && props && isEnabled && getComponentByViewType(viewType, props);
+ const ComponentToRender = viewType && props && isEnabled && (
+ props.media === "print" ? ViewComponents[viewType].print : ViewComponents[viewType].normal
+ );
return (
@@ -101,33 +131,6 @@ export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePa
);
}
-function getComponentByViewType(viewType: ViewTypeOptions, props: ViewModeProps
) {
- switch (viewType) {
- case "list":
- if (props.media !== "print") {
- return lazy(() => import("./legacy/ListOrGridView.js").then(i => i.ListView));
- } else {
- return lazy(() => import("./legacy/ListPrintView.js").then(i => i.ListPrintView));
- }
- case "grid":
- return lazy(() => import("./legacy/ListOrGridView.js").then(i => i.GridView));
- case "geoMap":
- return lazy(() => import("./geomap/index.js"));
- case "calendar":
- return lazy(() => import("./calendar/index.js"));
- case "table":
- if (props.media !== "print") {
- return lazy(() => import("./table/index.js"));
- } else {
- return lazy(() => import("./table/TablePrintView.js"));
- }
- case "board":
- return lazy(() => import("./board/index.js"));
- case "presentation":
- return lazy(() => import("./presentation/index.js"));
- }
-}
-
export function useNoteViewType(note?: FNote | null): ViewTypeOptions | undefined {
const [ viewType ] = useNoteLabel(note, "viewType");
From 8b997cffdd2435dff4286d39d0b6ede529f031d6 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 12:37:08 +0200
Subject: [PATCH 29/49] fix(collections/board): mouse horizontal scroll no
longer working
---
apps/client/src/widgets/collections/board/index.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/client/src/widgets/collections/board/index.css b/apps/client/src/widgets/collections/board/index.css
index 8b6ab9180..28cc98a2c 100644
--- a/apps/client/src/widgets/collections/board/index.css
+++ b/apps/client/src/widgets/collections/board/index.css
@@ -2,6 +2,7 @@
position: relative;
height: 100%;
user-select: none;
+ overflow-x: auto;
--card-font-size: 0.9em;
--card-line-height: 1.2;
From 08e542dfb3331eebbfee619ac8e253469fdf70d3 Mon Sep 17 00:00:00 2001
From: "Francis C."
Date: Fri, 21 Nov 2025 13:40:45 +0100
Subject: [PATCH 30/49] Translated using Weblate (Chinese (Simplified Han
script))
Currently translated at 100.0% (1628 of 1628 strings)
Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
---
apps/client/src/translations/cn/translation.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/apps/client/src/translations/cn/translation.json b/apps/client/src/translations/cn/translation.json
index 8a6d19554..95e2c73a3 100644
--- a/apps/client/src/translations/cn/translation.json
+++ b/apps/client/src/translations/cn/translation.json
@@ -2091,5 +2091,10 @@
"auto-read-only-note": "这条笔记以只读模式显示便于快速加载。",
"auto-read-only-learn-more": "了解更多",
"edit-note": "编辑笔记"
+ },
+ "note-color": {
+ "clear-color": "清除笔记颜色",
+ "set-color": "设置笔记颜色",
+ "set-custom-color": "设置自定义笔记颜色"
}
}
From 6b64d85db0f25d7f6fb6e25384246b807c8929c6 Mon Sep 17 00:00:00 2001
From: Marc
Date: Fri, 21 Nov 2025 13:51:08 +0100
Subject: [PATCH 31/49] Translated using Weblate (French)
Currently translated at 97.3% (148 of 152 strings)
Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/fr/
---
apps/website/src/translations/fr/translation.json | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/apps/website/src/translations/fr/translation.json b/apps/website/src/translations/fr/translation.json
index b464b2d71..4724c2ac5 100644
--- a/apps/website/src/translations/fr/translation.json
+++ b/apps/website/src/translations/fr/translation.json
@@ -51,7 +51,8 @@
"mermaid_description": "Créez des diagrammes tels que des organigrammes, des diagrammes de classes et de séquences, des diagrammes de Gantt et bien d'autres, en utilisant la syntaxe Mermaid.",
"mindmap_title": "Carte mentale",
"mindmap_description": "Organisez vos pensées visuellement ou faites une séance de brainstorming.",
- "others_list": "et autres : <0>carte de notes0>, <1>carte de relations1>, <2>recherches enregistrées2>, <3>note de rendu3> et <4>vues Web4>."
+ "others_list": "et autres : <0>carte de notes0>, <1>carte de relations1>, <2>recherches enregistrées2>, <3>note de rendu3> et <4>vues Web4>.",
+ "title": "Plusieurs façons de représenter vos informations"
},
"faq": {
"database_question": "Où sont les données stockées?",
@@ -168,7 +169,9 @@
"board_title": "Tableau de bord",
"board_description": "Organisez vos tâches ou l'état de vos projets dans un tableau Kanban avec un moyen simple de créer de nouveaux éléments et colonnes et de modifier simplement leur état en les faisant glisser sur le tableau.",
"geomap_title": "Géocarte",
- "geomap_description": "Planifiez vos vacances ou marquez vos points d'intérêt directement sur une carte géographique grâce à des marqueurs personnalisables. Affichez les traces GPX enregistrées pour suivre vos itinéraires."
+ "geomap_description": "Planifiez vos vacances ou marquez vos points d'intérêt directement sur une carte géographique grâce à des marqueurs personnalisables. Affichez les traces GPX enregistrées pour suivre vos itinéraires.",
+ "title": "Collections",
+ "presentation_title": "Présentation"
},
"download_now": {
"text": "Télécharger maintenant. ",
From 24cdeb06e88f276580a680c01f2d65660dee551f Mon Sep 17 00:00:00 2001
From: Marc
Date: Fri, 21 Nov 2025 13:48:09 +0100
Subject: [PATCH 32/49] Translated using Weblate (French)
Currently translated at 99.2% (1616 of 1628 strings)
Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/fr/
---
apps/client/src/translations/fr/translation.json | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/translations/fr/translation.json b/apps/client/src/translations/fr/translation.json
index fe9e28ba9..71222b6e9 100644
--- a/apps/client/src/translations/fr/translation.json
+++ b/apps/client/src/translations/fr/translation.json
@@ -39,7 +39,10 @@
"help_on_tree_prefix": "Aide sur le préfixe de l'arbre",
"prefix": "Préfixe : ",
"save": "Sauvegarder",
- "branch_prefix_saved": "Le préfixe de la branche a été enregistré."
+ "branch_prefix_saved": "Le préfixe de la branche a été enregistré.",
+ "edit_branch_prefix_multiple": "Modifier le préfixe de branche pour {{count}} branches",
+ "branch_prefix_saved_multiple": "Le préfixe de la branche a été sauvegardé pour {{count}} branches.",
+ "affected_branches": "Branches impactées ({{count}}):"
},
"bulk_actions": {
"bulk_actions": "Actions groupées",
From 268bbf3b9e256f81b205a07cb356a571a01d99ff Mon Sep 17 00:00:00 2001
From: green
Date: Fri, 21 Nov 2025 10:11:26 +0100
Subject: [PATCH 33/49] Translated using Weblate (Japanese)
Currently translated at 100.0% (1628 of 1628 strings)
Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
---
apps/client/src/translations/ja/translation.json | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/translations/ja/translation.json b/apps/client/src/translations/ja/translation.json
index 20b0d786c..6c9f9b924 100644
--- a/apps/client/src/translations/ja/translation.json
+++ b/apps/client/src/translations/ja/translation.json
@@ -1930,7 +1930,7 @@
"search-for": "「{{term}}」を検索",
"create-note": "子ノート「{{term}}」を作成してリンクする",
"insert-external-link": "「{{term}}」への外部リンクを挿入",
- "clear-text-field": "テキストフィールドを消去",
+ "clear-text-field": "テキストフィールドをクリア",
"show-recent-notes": "最近のノートを表示",
"full-text-search": "全文検索"
},
@@ -2091,5 +2091,10 @@
"auto-read-only-note": "このノートは読み込みを高速化するために読み取り専用モードで表示されています。",
"auto-read-only-learn-more": "さらに詳しく",
"edit-note": "ノートを編集"
+ },
+ "note-color": {
+ "clear-color": "ノートの色をクリア",
+ "set-color": "ノートの色を設定",
+ "set-custom-color": "ノートの色をカスタム設定"
}
}
From 4a71b00b710808a336635ebf6e308a78937ba08d Mon Sep 17 00:00:00 2001
From: "Francis C."
Date: Fri, 21 Nov 2025 13:39:09 +0100
Subject: [PATCH 34/49] Translated using Weblate (Chinese (Traditional Han
script))
Currently translated at 100.0% (1628 of 1628 strings)
Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
---
apps/client/src/translations/tw/translation.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/apps/client/src/translations/tw/translation.json b/apps/client/src/translations/tw/translation.json
index 767bb8ffc..6efe59822 100644
--- a/apps/client/src/translations/tw/translation.json
+++ b/apps/client/src/translations/tw/translation.json
@@ -2091,5 +2091,10 @@
"auto-read-only-note": "此筆記以唯讀模式顯示以加快載入速度。",
"auto-read-only-learn-more": "了解更多",
"edit-note": "編輯筆記"
+ },
+ "note-color": {
+ "clear-color": "清除筆記顏色",
+ "set-color": "設定筆記顏色",
+ "set-custom-color": "設定自訂筆記顏色"
}
}
From b4b1b7a3fabbf7bb2417904652e2d0fac57a3bd1 Mon Sep 17 00:00:00 2001
From: Adorian Doran
Date: Sat, 22 Nov 2025 13:33:48 +0200
Subject: [PATCH 35/49] client/context menus: skip consecutive separators
---
apps/client/src/menus/context_menu.ts | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts
index 4e28d7768..32d55085f 100644
--- a/apps/client/src/menus/context_menu.ts
+++ b/apps/client/src/menus/context_menu.ts
@@ -165,16 +165,19 @@ class ContextMenu {
let $group = $parent; // The current group or parent element to which items are being appended
let shouldStartNewGroup = false; // If true, the next item will start a new group
let shouldResetGroup = false; // If true, the next item will be the last one from the group
+ let prevItemKind: string = "";
for (let index = 0; index < items.length; index++) {
const item = items[index];
+ const itemKind = ("kind" in item) ? item.kind : "";
+
if (!item) {
continue;
}
// If the current item is a header, start a new group. This group will contain the
// header and the next item that follows the header.
- if ("kind" in item && item.kind === "header") {
+ if (itemKind === "header") {
if (multicolumn && !shouldResetGroup) {
shouldStartNewGroup = true;
}
@@ -200,14 +203,18 @@ class ContextMenu {
shouldStartNewGroup = false;
}
- if ("kind" in item && item.kind === "separator") {
+ if (itemKind === "separator") {
+ if (prevItemKind === "separator") {
+ // Skip consecutive separators
+ continue;
+ }
$group.append($("").addClass("dropdown-divider"));
shouldResetGroup = true; // End the group after the next item
- } else if ("kind" in item && item.kind === "header") {
+ } else if (itemKind === "header") {
$group.append($("
").addClass("dropdown-header").text(item.title));
shouldResetGroup = true;
} else {
- if ("kind" in item && item.kind === "custom") {
+ if (itemKind === "custom") {
// Custom menu item
$group.append(this.createCustomMenuItem(item));
} else {
@@ -222,6 +229,9 @@ class ContextMenu {
shouldResetGroup = false;
};
}
+
+ prevItemKind = itemKind;
+
}
}
From beb7d09aeeadb0f78502fba66792f065abada2e8 Mon Sep 17 00:00:00 2001
From: Adorian Doran
Date: Sat, 22 Nov 2025 13:35:36 +0200
Subject: [PATCH 36/49] client/tree context menu: improve handling the case
when the note color picker is not available
---
apps/client/src/menus/tree_context_menu.ts | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/apps/client/src/menus/tree_context_menu.ts b/apps/client/src/menus/tree_context_menu.ts
index 19e6f4e16..901a16559 100644
--- a/apps/client/src/menus/tree_context_menu.ts
+++ b/apps/client/src/menus/tree_context_menu.ts
@@ -244,16 +244,12 @@ export default class TreeContextMenu implements SelectMenuItemEventListener {
- if (notOptionsOrHelp && selectedNotes.length === 1) {
- return NoteColorPicker({note});
- } else {
- return null;
- }
+ return NoteColorPicker({note});
}
- },
+ } : null,
{ kind: "separator" },
From af62526b92bdb9f07fd51284474215e8e8bd99fd Mon Sep 17 00:00:00 2001
From: Adorian Doran
Date: Sat, 22 Nov 2025 13:43:40 +0200
Subject: [PATCH 37/49] client/context menu: fix data type errors
---
apps/client/src/menus/context_menu.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts
index 32d55085f..7096953e2 100644
--- a/apps/client/src/menus/context_menu.ts
+++ b/apps/client/src/menus/context_menu.ts
@@ -211,15 +211,15 @@ class ContextMenu {
$group.append($("").addClass("dropdown-divider"));
shouldResetGroup = true; // End the group after the next item
} else if (itemKind === "header") {
- $group.append($("
").addClass("dropdown-header").text(item.title));
+ $group.append($("").addClass("dropdown-header").text((item as MenuHeader).title));
shouldResetGroup = true;
} else {
if (itemKind === "custom") {
// Custom menu item
- $group.append(this.createCustomMenuItem(item));
+ $group.append(this.createCustomMenuItem(item as CustomMenuItem));
} else {
// Standard menu item
- $group.append(this.createMenuItem(item));
+ $group.append(this.createMenuItem(item as MenuCommandItem));
}
// After adding a menu item, if the previous item was a separator or header,
From 435b856b72ae0539ab923b974069fb592319b259 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 18:35:07 +0200
Subject: [PATCH 38/49] fix(quick_edit): keyboard shortcuts triggering on wrong
editor
---
apps/client/src/services/keyboard_actions.ts | 6 ++++--
apps/client/src/widgets/react/hooks.tsx | 6 +++---
apps/client/src/widgets/type_widgets/code/Code.tsx | 2 +-
.../src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx | 4 ++--
apps/client/src/widgets/type_widgets/text/EditableText.tsx | 5 ++---
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/apps/client/src/services/keyboard_actions.ts b/apps/client/src/services/keyboard_actions.ts
index 5678d6196..d447a9001 100644
--- a/apps/client/src/services/keyboard_actions.ts
+++ b/apps/client/src/services/keyboard_actions.ts
@@ -28,7 +28,7 @@ async function getActionsForScope(scope: string) {
return actions.filter((action) => action.scope === scope);
}
-async function setupActionsForElement(scope: string, $el: JQuery, component: Component) {
+async function setupActionsForElement(scope: string, $el: JQuery, component: Component, ntxId: string | null | undefined) {
if (!$el[0]) return [];
const actions = await getActionsForScope(scope);
@@ -36,7 +36,9 @@ async function setupActionsForElement(scope: string, $el: JQuery, c
for (const action of actions) {
for (const shortcut of action.effectiveShortcuts ?? []) {
- const binding = shortcutService.bindElShortcut($el, shortcut, () => component.triggerCommand(action.actionName, { ntxId: appContext.tabManager.activeNtxId }));
+ const binding = shortcutService.bindElShortcut($el, shortcut, () => {
+ component.triggerCommand(action.actionName, { ntxId });
+ });
if (binding) {
bindings.push(binding);
}
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index 0ee92f8af..856896f2c 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -760,18 +760,18 @@ export function useResizeObserver(ref: RefObject, callback: () => v
}, [ callback, ref ]);
}
-export function useKeyboardShortcuts(scope: "code-detail" | "text-detail", containerRef: RefObject, parentComponent: Component | undefined) {
+export function useKeyboardShortcuts(scope: "code-detail" | "text-detail", containerRef: RefObject, parentComponent: Component | undefined, ntxId: string | null | undefined) {
useEffect(() => {
if (!parentComponent) return;
const $container = refToJQuerySelector(containerRef);
- const bindingPromise = keyboard_actions.setupActionsForElement(scope, $container, parentComponent);
+ const bindingPromise = keyboard_actions.setupActionsForElement(scope, $container, parentComponent, ntxId);
return async () => {
const bindings = await bindingPromise;
for (const binding of bindings) {
removeIndividualBinding(binding);
}
}
- }, []);
+ }, [ scope, containerRef, parentComponent, ntxId ]);
}
/**
diff --git a/apps/client/src/widgets/type_widgets/code/Code.tsx b/apps/client/src/widgets/type_widgets/code/Code.tsx
index 0c089b9a8..02117f19f 100644
--- a/apps/client/src/widgets/type_widgets/code/Code.tsx
+++ b/apps/client/src/widgets/type_widgets/code/Code.tsx
@@ -100,7 +100,7 @@ export function EditableCode({ note, ntxId, noteContext, debounceUpdate, parentC
}
});
- useKeyboardShortcuts("code-detail", containerRef, parentComponent);
+ useKeyboardShortcuts("code-detail", containerRef, parentComponent, ntxId);
return (
<>
diff --git a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
index 1c3a85e23..e19032d46 100644
--- a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
+++ b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
@@ -39,9 +39,9 @@ export default function CKEditorWithWatchdog({ containerRef: externalContainerRe
const watchdogRef = useRef(null);
const [ uiLanguage ] = useTriliumOption("locale");
const [ editor, setEditor ] = useState();
- const { parentComponent } = useNoteContext();
+ const { parentComponent, ntxId } = useNoteContext();
- useKeyboardShortcuts("text-detail", containerRef, parentComponent);
+ useKeyboardShortcuts("text-detail", containerRef, parentComponent, ntxId);
useImperativeHandle(editorApi, () => ({
hasSelection() {
diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
index e3fa1ecee..828989671 100644
--- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx
+++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx
@@ -2,12 +2,11 @@ import { useEffect, useRef, useState } from "preact/hooks";
import dialog from "../../../services/dialog";
import toast from "../../../services/toast";
import utils, { hasTouchBar, isMobile } from "../../../services/utils";
-import { useEditorSpacedUpdate, useKeyboardShortcuts, useLegacyImperativeHandlers, useNoteLabel, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
+import { useEditorSpacedUpdate, useLegacyImperativeHandlers, useNoteLabel, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
import { TypeWidgetProps } from "../type_widget";
import CKEditorWithWatchdog, { CKEditorApi } from "./CKEditorWithWatchdog";
import "./EditableText.css";
-import { CKTextEditor, ClassicEditor, EditorWatchdog, TemplateDefinition } from "@triliumnext/ckeditor5";
-import Component from "../../../components/component";
+import { CKTextEditor, EditorWatchdog, TemplateDefinition } from "@triliumnext/ckeditor5";
import options from "../../../services/options";
import { loadIncludedNote, refreshIncludedNote, setupImageOpening } from "./utils";
import getTemplates, { updateTemplateCache } from "./snippets.js";
From 31180afbd1199580f57786b9d0592a0bdf7fcbeb Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 19:07:50 +0200
Subject: [PATCH 39/49] react(quick_edit): set up empty dialog
---
apps/client/src/layouts/layout_commons.tsx | 22 +----
.../src/widgets/dialogs/PopupEditor.css | 62 ++++++++++++++
.../src/widgets/dialogs/PopupEditor.tsx | 31 +++++++
.../src/widgets/dialogs/popup_editor.ts | 80 -------------------
.../text/CKEditorWithWatchdog.tsx | 1 +
5 files changed, 96 insertions(+), 100 deletions(-)
create mode 100644 apps/client/src/widgets/dialogs/PopupEditor.css
create mode 100644 apps/client/src/widgets/dialogs/PopupEditor.tsx
diff --git a/apps/client/src/layouts/layout_commons.tsx b/apps/client/src/layouts/layout_commons.tsx
index 031ef03de..62f810430 100644
--- a/apps/client/src/layouts/layout_commons.tsx
+++ b/apps/client/src/layouts/layout_commons.tsx
@@ -22,16 +22,8 @@ import RevisionsDialog from "../widgets/dialogs/revisions.js";
import DeleteNotesDialog from "../widgets/dialogs/delete_notes.js";
import InfoDialog from "../widgets/dialogs/info.js";
import IncorrectCpuArchDialog from "../widgets/dialogs/incorrect_cpu_arch.js";
-import PopupEditorDialog from "../widgets/dialogs/popup_editor.js";
-import FlexContainer from "../widgets/containers/flex_container.js";
-import NoteIconWidget from "../widgets/note_icon";
-import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import CallToActionDialog from "../widgets/dialogs/call_to_action.jsx";
-import NoteTitleWidget from "../widgets/note_title.jsx";
-import FormattingToolbar from "../widgets/ribbon/FormattingToolbar.js";
-import NoteList from "../widgets/collections/NoteList.jsx";
-import NoteDetail from "../widgets/NoteDetail.jsx";
-import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
+import PopupEditorDialog from "../widgets/dialogs/PopupEditor.jsx";
export function applyModals(rootContainer: RootContainer) {
rootContainer
@@ -57,16 +49,6 @@ export function applyModals(rootContainer: RootContainer) {
.child()
.child()
.child()
- .child(new PopupEditorDialog()
- .child(new FlexContainer("row")
- .class("title-row")
- .css("align-items", "center")
- .cssBlock(".title-row > * { margin: 5px; }")
- .child()
- .child())
- .child()
- .child(new PromotedAttributesWidget())
- .child()
- .child())
+ .child()
.child();
}
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.css b/apps/client/src/widgets/dialogs/PopupEditor.css
new file mode 100644
index 000000000..ce6494f33
--- /dev/null
+++ b/apps/client/src/widgets/dialogs/PopupEditor.css
@@ -0,0 +1,62 @@
+/** Reduce the z-index of modals so that ckeditor popups are properly shown on top of it. */
+body.popup-editor-open > .modal-backdrop { z-index: 998; }
+body.popup-editor-open .popup-editor-dialog { z-index: 999; }
+body.popup-editor-open .ck-clipboard-drop-target-line { z-index: 1000; }
+
+body.desktop .modal.popup-editor-dialog .modal-dialog {
+ max-width: 75vw;
+}
+
+.modal.popup-editor-dialog .modal-header .modal-title {
+ font-size: 1.1em;
+}
+
+.modal.popup-editor-dialog .modal-header .title-row {
+ flex-grow: 1;
+ display: flex;
+ align-items: center;
+}
+
+.modal.popup-editor-dialog .modal-header .title-row > * {
+ margin: 5px;
+}
+
+.modal.popup-editor-dialog .modal-body {
+ padding: 0;
+ height: 75vh;
+ overflow: auto;
+}
+
+.modal.popup-editor-dialog .note-detail-editable-text {
+ padding: 0 1em;
+}
+
+.modal.popup-editor-dialog .title-row,
+.modal.popup-editor-dialog .modal-title,
+.modal.popup-editor-dialog .note-icon-widget {
+ height: 32px;
+}
+
+.modal.popup-editor-dialog .note-icon-widget {
+ width: 32px;
+ margin: 0;
+ padding: 0;
+}
+
+.modal.popup-editor-dialog .note-icon-widget button.note-icon,
+.modal.popup-editor-dialog .note-title-widget input.note-title {
+ font-size: 1em;
+}
+
+.modal.popup-editor-dialog .classic-toolbar-widget {
+ position: sticky;
+ top: 0;
+ inset-inline-start: 0;
+ inset-inline-end: 0;
+ background: var(--modal-background-color);
+ z-index: 998;
+}
+
+.modal.popup-editor-dialog .note-detail-file {
+ padding: 0;
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
new file mode 100644
index 000000000..7969e3ac0
--- /dev/null
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -0,0 +1,31 @@
+import { useState } from "preact/hooks";
+import Modal from "../react/Modal";
+import "./PopupEditor.css";
+import { useTriliumEvent } from "../react/hooks";
+import NoteTitleWidget from "../note_title";
+import NoteIcon from "../note_icon";
+
+export default function PopupEditor() {
+ const [ shown, setShown ] = useState(false);
+
+ useTriliumEvent("openInPopup", () => {
+ setShown(true);
+ });
+
+ return (
+
+
+
+
+ )}
+ className="popup-editor-dialog"
+ size="lg"
+ show={shown}
+ onHidden={() => setShown(false)}
+ >
+ Body goes here
+
+ )
+}
diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts
index 80f8f5915..bc862822e 100644
--- a/apps/client/src/widgets/dialogs/popup_editor.ts
+++ b/apps/client/src/widgets/dialogs/popup_editor.ts
@@ -4,82 +4,6 @@ import { openDialog } from "../../services/dialog.js";
import BasicWidget, { ReactWrappedWidget } from "../basic_widget.js";
import Container from "../containers/container.js";
-const TPL = /*html*/`\
-
-`;
-
export default class PopupEditorDialog extends Container {
private noteContext: NoteContext;
@@ -110,10 +34,6 @@ export default class PopupEditorDialog extends Container {
}
async openInPopupEvent({ noteIdOrPath }: EventData<"openInPopup">) {
- const $dialog = await openDialog(this.$widget, false, {
- focus: false
- });
-
await this.noteContext.setNote(noteIdOrPath, {
viewScope: {
readOnlyTemporarilyDisabled: true
diff --git a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
index e19032d46..789e0d006 100644
--- a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
+++ b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
@@ -41,6 +41,7 @@ export default function CKEditorWithWatchdog({ containerRef: externalContainerRe
const [ editor, setEditor ] = useState();
const { parentComponent, ntxId } = useNoteContext();
+ console.log("Register with ntxId", ntxId);
useKeyboardShortcuts("text-detail", containerRef, parentComponent, ntxId);
useImperativeHandle(editorApi, () => ({
From 29f049c4118d098fd297327c50b3b7c1855e7ca3 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 19:11:20 +0200
Subject: [PATCH 40/49] chore(quick_edit): inject note context
---
.../src/widgets/dialogs/PopupEditor.tsx | 21 +++++++++++++++++--
.../src/widgets/dialogs/popup_editor.ts | 9 ++------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 7969e3ac0..6b305fbb2 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -1,17 +1,34 @@
-import { useState } from "preact/hooks";
+import { useContext, useEffect, useState } from "preact/hooks";
import Modal from "../react/Modal";
import "./PopupEditor.css";
import { useTriliumEvent } from "../react/hooks";
import NoteTitleWidget from "../note_title";
import NoteIcon from "../note_icon";
+import NoteContext from "../../components/note_context";
+import { ParentComponent } from "../react/react_utils";
+
+const noteContext = new NoteContext("_popup-editor");
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
+ const parentComponent = useContext(ParentComponent);
+
+ useTriliumEvent("openInPopup", async ({ noteIdOrPath }) => {
+ await noteContext.setNote(noteIdOrPath, {
+ viewScope: {
+ readOnlyTemporarilyDisabled: true
+ }
+ });
- useTriliumEvent("openInPopup", () => {
setShown(true);
});
+ // Inject the note context
+ useEffect(() => {
+ if (!shown || !parentComponent) return;
+ parentComponent.handleEventInChildren("activeContextChanged", { noteContext });
+ }, [ shown ]);
+
return (
{
constructor() {
super();
- this.noteContext = new NoteContext("_popup-editor");
+ this.noteContext =
}
doRender() {
@@ -34,11 +34,7 @@ export default class PopupEditorDialog extends Container {
}
async openInPopupEvent({ noteIdOrPath }: EventData<"openInPopup">) {
- await this.noteContext.setNote(noteIdOrPath, {
- viewScope: {
- readOnlyTemporarilyDisabled: true
- }
- });
+
const colorClass = this.noteContext.note?.getColorClass();
const wrapperElement = this.$wrapper.get(0)!;
@@ -61,7 +57,6 @@ export default class PopupEditorDialog extends Container {
}
$dialog.on("shown.bs.modal", async () => {
- await this.handleEventInChildren("activeContextChanged", { noteContext: this.noteContext });
this.setVisibility(true);
await this.handleEventInChildren("focusOnDetail", { ntxId: this.noteContext.ntxId });
});
From 5531c15126b18857eae3f78233f07307c9fd71ee Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 19:17:50 +0200
Subject: [PATCH 41/49] chore(quick_edit): get note content to render
---
apps/client/src/stylesheets/style.css | 2 +-
.../src/widgets/dialogs/PopupEditor.css | 2 ++
.../src/widgets/dialogs/PopupEditor.tsx | 19 ++++++++++++-------
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css
index 9ef1c5e2d..36805a3d4 100644
--- a/apps/client/src/stylesheets/style.css
+++ b/apps/client/src/stylesheets/style.css
@@ -2591,7 +2591,7 @@ iframe.print-iframe {
flex-direction: column;
}
-.scrolling-container > .note-detail.full-height,
+.note-detail.full-height,
.scrolling-container > .note-list-widget.full-height {
position: relative;
flex-grow: 1;
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.css b/apps/client/src/widgets/dialogs/PopupEditor.css
index ce6494f33..325d9ea47 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.css
+++ b/apps/client/src/widgets/dialogs/PopupEditor.css
@@ -25,6 +25,8 @@ body.desktop .modal.popup-editor-dialog .modal-dialog {
padding: 0;
height: 75vh;
overflow: auto;
+ display: flex;
+ flex-direction: column;
}
.modal.popup-editor-dialog .note-detail-editable-text {
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 6b305fbb2..d28e7d6d8 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -6,6 +6,7 @@ import NoteTitleWidget from "../note_title";
import NoteIcon from "../note_icon";
import NoteContext from "../../components/note_context";
import { ParentComponent } from "../react/react_utils";
+import NoteDetail from "../NoteDetail";
const noteContext = new NoteContext("_popup-editor");
@@ -31,18 +32,22 @@ export default function PopupEditor() {
return (
-
-
-
- )}
+ title={}
className="popup-editor-dialog"
size="lg"
show={shown}
onHidden={() => setShown(false)}
>
- Body goes here
+
)
}
+
+export function TitleRow() {
+ return (
+
+
+
+
+ )
+}
From bb9cb2fb75e3fbde1835c82881804ead43c33e8a Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 19:25:27 +0200
Subject: [PATCH 42/49] fix(quick_edit): note context not injected on first
render
---
.../src/widgets/dialogs/PopupEditor.tsx | 29 ++++++++-----------
apps/client/src/widgets/react/hooks.tsx | 5 ++--
apps/client/src/widgets/react/react_utils.tsx | 3 ++
3 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index d28e7d6d8..b19851bb9 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -5,14 +5,13 @@ import { useTriliumEvent } from "../react/hooks";
import NoteTitleWidget from "../note_title";
import NoteIcon from "../note_icon";
import NoteContext from "../../components/note_context";
-import { ParentComponent } from "../react/react_utils";
+import { NoteContextContext, ParentComponent } from "../react/react_utils";
import NoteDetail from "../NoteDetail";
const noteContext = new NoteContext("_popup-editor");
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
- const parentComponent = useContext(ParentComponent);
useTriliumEvent("openInPopup", async ({ noteIdOrPath }) => {
await noteContext.setNote(noteIdOrPath, {
@@ -24,22 +23,18 @@ export default function PopupEditor() {
setShown(true);
});
- // Inject the note context
- useEffect(() => {
- if (!shown || !parentComponent) return;
- parentComponent.handleEventInChildren("activeContextChanged", { noteContext });
- }, [ shown ]);
-
return (
- }
- className="popup-editor-dialog"
- size="lg"
- show={shown}
- onHidden={() => setShown(false)}
- >
-
-
+
+ }
+ className="popup-editor-dialog"
+ size="lg"
+ show={shown}
+ onHidden={() => setShown(false)}
+ >
+
+
+
)
}
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index 856896f2c..63fa4fff1 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -2,7 +2,7 @@ import { CSSProperties } from "preact/compat";
import { DragData } from "../note_tree";
import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons";
import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
-import { ParentComponent, refToJQuerySelector } from "./react_utils";
+import { NoteContextContext, ParentComponent, refToJQuerySelector } from "./react_utils";
import { RefObject, VNode } from "preact";
import { Tooltip } from "bootstrap";
import { ViewMode, ViewScope } from "../../services/link";
@@ -257,7 +257,8 @@ export function useUniqueName(prefix?: string) {
}
export function useNoteContext() {
- const [ noteContext, setNoteContext ] = useState();
+ const noteContextContext = useContext(NoteContextContext);
+ const [ noteContext, setNoteContext ] = useState(noteContextContext);
const [ notePath, setNotePath ] = useState();
const [ note, setNote ] = useState();
const [ , setViewScope ] = useState();
diff --git a/apps/client/src/widgets/react/react_utils.tsx b/apps/client/src/widgets/react/react_utils.tsx
index d752662f5..468a0e73e 100644
--- a/apps/client/src/widgets/react/react_utils.tsx
+++ b/apps/client/src/widgets/react/react_utils.tsx
@@ -1,8 +1,11 @@
import { ComponentChild, createContext, render, type JSX, type RefObject } from "preact";
import Component from "../../components/component";
+import NoteContext from "../../components/note_context";
export const ParentComponent = createContext(null);
+export const NoteContextContext = createContext(null);
+
/**
* Takes in a React ref and returns a corresponding JQuery selector.
*
From 2f440eba37f62b1ca098a57b882ef50f6c7e19a0 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 19:34:14 +0200
Subject: [PATCH 43/49] chore(quick_edit): bring back focus
---
apps/client/src/widgets/dialogs/PopupEditor.tsx | 4 ++++
apps/client/src/widgets/dialogs/popup_editor.ts | 1 -
.../src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx | 1 -
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index b19851bb9..070244b56 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -12,6 +12,7 @@ const noteContext = new NoteContext("_popup-editor");
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
+ const parentComponent = useContext(ParentComponent);
useTriliumEvent("openInPopup", async ({ noteIdOrPath }) => {
await noteContext.setNote(noteIdOrPath, {
@@ -30,6 +31,9 @@ export default function PopupEditor() {
className="popup-editor-dialog"
size="lg"
show={shown}
+ onShown={() => {
+ parentComponent?.handleEvent("focusOnDetail", { ntxId: noteContext.ntxId });
+ }}
onHidden={() => setShown(false)}
>
diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts
index 9899ad163..1cadb3ab6 100644
--- a/apps/client/src/widgets/dialogs/popup_editor.ts
+++ b/apps/client/src/widgets/dialogs/popup_editor.ts
@@ -58,7 +58,6 @@ export default class PopupEditorDialog extends Container {
$dialog.on("shown.bs.modal", async () => {
this.setVisibility(true);
- await this.handleEventInChildren("focusOnDetail", { ntxId: this.noteContext.ntxId });
});
$dialog.on("hidden.bs.modal", () => {
const $typeWidgetEl = $dialog.find(".note-detail-printable");
diff --git a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
index 789e0d006..e19032d46 100644
--- a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
+++ b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx
@@ -41,7 +41,6 @@ export default function CKEditorWithWatchdog({ containerRef: externalContainerRe
const [ editor, setEditor ] = useState();
const { parentComponent, ntxId } = useNoteContext();
- console.log("Register with ntxId", ntxId);
useKeyboardShortcuts("text-detail", containerRef, parentComponent, ntxId);
useImperativeHandle(editorApi, () => ({
From 8001d940eb5cd39be6d8a77eafd797da419883b8 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 20:08:37 +0200
Subject: [PATCH 44/49] chore(quick_edit): bring back coloring
---
.../src/widgets/dialogs/PopupEditor.tsx | 56 +++++++---
.../src/widgets/dialogs/popup_editor.ts | 101 ------------------
apps/client/src/widgets/react/hooks.tsx | 9 ++
3 files changed, 49 insertions(+), 117 deletions(-)
delete mode 100644 apps/client/src/widgets/dialogs/popup_editor.ts
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 070244b56..583b13abd 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -1,47 +1,71 @@
-import { useContext, useEffect, useState } from "preact/hooks";
+import { useContext, useEffect, useRef, useState } from "preact/hooks";
import Modal from "../react/Modal";
import "./PopupEditor.css";
-import { useTriliumEvent } from "../react/hooks";
+import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks";
import NoteTitleWidget from "../note_title";
import NoteIcon from "../note_icon";
import NoteContext from "../../components/note_context";
import { NoteContextContext, ParentComponent } from "../react/react_utils";
import NoteDetail from "../NoteDetail";
-
-const noteContext = new NoteContext("_popup-editor");
+import { ComponentChildren } from "preact";
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
const parentComponent = useContext(ParentComponent);
+ const [ noteContext, setNoteContext ] = useState(new NoteContext("_popup-editor"));
useTriliumEvent("openInPopup", async ({ noteIdOrPath }) => {
+ const noteContext = new NoteContext("_popup-editor");
await noteContext.setNote(noteIdOrPath, {
viewScope: {
readOnlyTemporarilyDisabled: true
}
});
+ setNoteContext(noteContext);
setShown(true);
});
return (
- }
- className="popup-editor-dialog"
- size="lg"
- show={shown}
- onShown={() => {
- parentComponent?.handleEvent("focusOnDetail", { ntxId: noteContext.ntxId });
- }}
- onHidden={() => setShown(false)}
- >
-
-
+
+ }
+ className="popup-editor-dialog"
+ size="lg"
+ show={shown}
+ onShown={() => {
+ parentComponent?.handleEvent("focusOnDetail", { ntxId: noteContext.ntxId });
+ }}
+ onHidden={() => setShown(false)}
+ >
+
+
+
)
}
+export function DialogWrapper({ children }: { children: ComponentChildren }) {
+ const { note, ntxId } = useNoteContext();
+ const wrapperRef = useRef(null);
+ const colorClass = note?.getColorClass();
+ const [ hasTint, setHasTint ] = useState(false);
+
+ // Apply the tinted-dialog class only if the custom color CSS class specifies a hue
+ useEffect(() => {
+ if (!wrapperRef.current) return;
+ const customHue = getComputedStyle(wrapperRef.current).getPropertyValue("--custom-color-hue");
+ setHasTint(!!customHue);
+ }, [ note, colorClass ]);
+
+ return (
+
+ {children}
+
+ )
+}
+
export function TitleRow() {
return (
diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts
deleted file mode 100644
index 1cadb3ab6..000000000
--- a/apps/client/src/widgets/dialogs/popup_editor.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import type { EventNames, EventData } from "../../components/app_context.js";
-import NoteContext from "../../components/note_context.js";
-import { openDialog } from "../../services/dialog.js";
-import BasicWidget, { ReactWrappedWidget } from "../basic_widget.js";
-import Container from "../containers/container.js";
-
-export default class PopupEditorDialog extends Container
{
-
- private noteContext: NoteContext;
- private $modalHeader!: JQuery;
- private $modalBody!: JQuery;
- private $wrapper!: JQuery;
-
- constructor() {
- super();
- this.noteContext =
- }
-
- doRender() {
- // This will populate this.$widget with the content of the children.
- super.doRender();
-
- // Now we wrap it in the modal.
- const $newWidget = $(TPL);
- this.$modalHeader = $newWidget.find(".modal-title");
- this.$modalBody = $newWidget.find(".modal-body");
- this.$wrapper = $newWidget.find(".quick-edit-dialog-wrapper");
-
- const children = this.$widget.children();
- this.$modalHeader.append(children[0]);
- this.$modalBody.append(children.slice(1));
- this.$widget = $newWidget;
- this.setVisibility(false);
- }
-
- async openInPopupEvent({ noteIdOrPath }: EventData<"openInPopup">) {
-
-
- const colorClass = this.noteContext.note?.getColorClass();
- const wrapperElement = this.$wrapper.get(0)!;
-
- if (colorClass) {
- wrapperElement.className = "quick-edit-dialog-wrapper " + colorClass;
- } else {
- wrapperElement.className = "quick-edit-dialog-wrapper";
- }
-
- const customHue = getComputedStyle(wrapperElement).getPropertyValue("--custom-color-hue");
- if (customHue) {
- /* Apply the tinted-dialog class only if the custom color CSS class specifies a hue */
- wrapperElement.classList.add("tinted-quick-edit-dialog");
- }
-
- const activeEl = document.activeElement;
- if (activeEl && "blur" in activeEl) {
- (activeEl as HTMLElement).blur();
- }
-
- $dialog.on("shown.bs.modal", async () => {
- this.setVisibility(true);
- });
- $dialog.on("hidden.bs.modal", () => {
- const $typeWidgetEl = $dialog.find(".note-detail-printable");
- if ($typeWidgetEl.length) {
- const typeWidget = glob.getComponentByEl($typeWidgetEl[0]) as ReactWrappedWidget;
- typeWidget.cleanup();
- }
-
- this.setVisibility(false);
- });
- }
-
- setVisibility(visible: boolean) {
- const $bodyItems = this.$modalBody.find("> div");
- if (visible) {
- $bodyItems.fadeIn();
- this.$modalHeader.children().show();
- document.body.classList.add("popup-editor-open");
-
- } else {
- $bodyItems.hide();
- this.$modalHeader.children().hide();
- document.body.classList.remove("popup-editor-open");
- }
- }
-
- handleEventInChildren(name: T, data: EventData): Promise | null {
- // Avoid events related to the current tab interfere with our popup.
- if (["noteSwitched", "noteSwitchedAndActivated", "exportAsPdf", "printActiveNote"].includes(name)) {
- return Promise.resolve();
- }
-
- // Avoid not showing recent notes when creating a new empty tab.
- if ("noteContext" in data && data.noteContext.ntxId !== "_popup-editor") {
- return Promise.resolve();
- }
-
- return super.handleEventInChildren(name, data);
- }
-
-}
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index 63fa4fff1..82d01750c 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -265,11 +265,20 @@ export function useNoteContext() {
const [ isReadOnlyTemporarilyDisabled, setIsReadOnlyTemporarilyDisabled ] = useState(noteContext?.viewScope?.isReadOnly);
const [ refreshCounter, setRefreshCounter ] = useState(0);
+ useEffect(() => {
+ if (!noteContextContext) return;
+ setNoteContext(noteContextContext);
+ setNote(noteContextContext.note);
+ setNotePath(noteContextContext.notePath);
+ setViewScope(noteContextContext.viewScope);
+ }, [ noteContextContext ]);
+
useEffect(() => {
setNote(noteContext?.note);
}, [ notePath ]);
useTriliumEvents([ "setNoteContext", "activeContextChanged", "noteSwitchedAndActivated", "noteSwitched" ], ({ noteContext }) => {
+ if (noteContextContext) return;
setNoteContext(noteContext);
setNotePath(noteContext.notePath);
setViewScope(noteContext.viewScope);
From 2985c762e62afe7eb088ea06e318d3e2c4b87c15 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 21:00:55 +0200
Subject: [PATCH 45/49] chore(quick_edit): add back most of the components
---
apps/client/src/widgets/dialogs/PopupEditor.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 583b13abd..0d84e5ba5 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -1,13 +1,16 @@
import { useContext, useEffect, useRef, useState } from "preact/hooks";
import Modal from "../react/Modal";
import "./PopupEditor.css";
-import { useNoteContext, useNoteLabel, useTriliumEvent } from "../react/hooks";
+import { useNoteContext, useTriliumEvent } from "../react/hooks";
import NoteTitleWidget from "../note_title";
import NoteIcon from "../note_icon";
import NoteContext from "../../components/note_context";
import { NoteContextContext, ParentComponent } from "../react/react_utils";
import NoteDetail from "../NoteDetail";
import { ComponentChildren } from "preact";
+import NoteList from "../collections/NoteList";
+import StandaloneRibbonAdapter from "../ribbon/components/StandaloneRibbonAdapter";
+import FormattingToolbar from "../ribbon/FormattingToolbar";
export default function PopupEditor() {
const [ shown, setShown ] = useState(false);
@@ -39,7 +42,9 @@ export default function PopupEditor() {
}}
onHidden={() => setShown(false)}
>
+
+
From 6946da357185064c34896e6776a4c24774f9ec09 Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 21:07:17 +0200
Subject: [PATCH 46/49] chore(mermaid): avoid crash if "Matrix is not
invertible"
---
.../src/widgets/type_widgets/helpers/SvgSplitEditor.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/type_widgets/helpers/SvgSplitEditor.tsx b/apps/client/src/widgets/type_widgets/helpers/SvgSplitEditor.tsx
index 8a9e64a24..7f95bfb1b 100644
--- a/apps/client/src/widgets/type_widgets/helpers/SvgSplitEditor.tsx
+++ b/apps/client/src/widgets/type_widgets/helpers/SvgSplitEditor.tsx
@@ -163,7 +163,12 @@ function useResizer(containerRef: RefObject, noteId: string, svg
pan: zoomInstance.getPan(),
zoom: zoomInstance.getZoom()
}
- zoomInstance.destroy();
+ try {
+ zoomInstance.destroy();
+ } catch (e) {
+ // Sometimes crashes with "Matrix is not invertible" which can cause havoc such as breaking the popup editor from ever showing up again.
+ console.warn(e);
+ }
};
}, [ svg ]);
From 56c82d7f0fc255cc3015b39183ff90de6fcab48e Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 21:20:24 +0200
Subject: [PATCH 47/49] chore(quick_edit): address requested changes
---
apps/client/src/widgets/dialogs/PopupEditor.tsx | 4 ++--
apps/client/src/widgets/react/hooks.tsx | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 0d84e5ba5..4950a4103 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -62,10 +62,10 @@ export function DialogWrapper({ children }: { children: ComponentChildren }) {
if (!wrapperRef.current) return;
const customHue = getComputedStyle(wrapperRef.current).getPropertyValue("--custom-color-hue");
setHasTint(!!customHue);
- }, [ note, colorClass ]);
+ }, [ note ]);
return (
-
+
{children}
)
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index 82d01750c..f30957bef 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -271,6 +271,7 @@ export function useNoteContext() {
setNote(noteContextContext.note);
setNotePath(noteContextContext.notePath);
setViewScope(noteContextContext.viewScope);
+ setIsReadOnlyTemporarilyDisabled(noteContextContext?.viewScope?.readOnlyTemporarilyDisabled);
}, [ noteContextContext ]);
useEffect(() => {
@@ -292,6 +293,7 @@ export function useNoteContext() {
}
});
useTriliumEvent("readOnlyTemporarilyDisabled", ({ noteContext: eventNoteContext }) => {
+ if (noteContextContext) return;
if (eventNoteContext.ntxId === noteContext?.ntxId) {
setIsReadOnlyTemporarilyDisabled(eventNoteContext?.viewScope?.readOnlyTemporarilyDisabled);
}
From 26f7264f3cb93f658f41bb67c30a259b0e1d163b Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 21:37:37 +0200
Subject: [PATCH 48/49] chore(client): fix typecheck
---
apps/client/src/widgets/react/hooks.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index f30957bef..34a7c9ed8 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -258,7 +258,7 @@ export function useUniqueName(prefix?: string) {
export function useNoteContext() {
const noteContextContext = useContext(NoteContextContext);
- const [ noteContext, setNoteContext ] = useState(noteContextContext);
+ const [ noteContext, setNoteContext ] = useState(noteContextContext ?? undefined);
const [ notePath, setNotePath ] = useState();
const [ note, setNote ] = useState();
const [ , setViewScope ] = useState();
From 5edc4abfb42d8fe1ef71bb2fbca5d882832bfc3a Mon Sep 17 00:00:00 2001
From: Elian Doran
Date: Sat, 22 Nov 2025 21:37:41 +0200
Subject: [PATCH 49/49] chore(quick_edit): address requested changes
---
apps/client/src/widgets/dialogs/PopupEditor.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx
index 4950a4103..c2d98b544 100644
--- a/apps/client/src/widgets/dialogs/PopupEditor.tsx
+++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx
@@ -29,6 +29,11 @@ export default function PopupEditor() {
setShown(true);
});
+ // Add a global class to be able to handle issues with z-index due to rendering in a popup.
+ useEffect(() => {
+ document.body.classList.toggle("popup-editor-open", shown);
+ }, [shown]);
+
return (
@@ -52,9 +57,8 @@ export default function PopupEditor() {
}
export function DialogWrapper({ children }: { children: ComponentChildren }) {
- const { note, ntxId } = useNoteContext();
+ const { note } = useNoteContext();
const wrapperRef = useRef(null);
- const colorClass = note?.getColorClass();
const [ hasTint, setHasTint ] = useState(false);
// Apply the tinted-dialog class only if the custom color CSS class specifies a hue