mirror of
https://github.com/zadam/trilium.git
synced 2026-03-07 04:30:54 +01:00
Compare commits
5 Commits
feature/im
...
feature/to
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3337eab9c | ||
|
|
8128a8192a | ||
|
|
c80bb9657c | ||
|
|
65514a6fd7 | ||
|
|
93a7f8c711 |
@@ -1,6 +1,6 @@
|
||||
import "./TableOfContents.css";
|
||||
|
||||
import { CKTextEditor, ModelElement } from "@triliumnext/ckeditor5";
|
||||
import { attributeChangeAffectsHeading, CKTextEditor, ModelElement } from "@triliumnext/ckeditor5";
|
||||
import clsx from "clsx";
|
||||
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
|
||||
|
||||
@@ -170,11 +170,14 @@ function EditableTextTableOfContents() {
|
||||
|
||||
const affectsHeadings = changes.some( change => {
|
||||
return (
|
||||
change.type === 'insert' || change.type === 'remove' || (change.type === 'attribute' && change.attributeKey === 'headingLevel')
|
||||
change.type === 'insert' || change.type === 'remove' ||
|
||||
(change.type === 'attribute' && attributeChangeAffectsHeading(change, textEditor))
|
||||
);
|
||||
});
|
||||
if (affectsHeadings) {
|
||||
setHeadings(extractTocFromTextEditor(textEditor));
|
||||
requestAnimationFrame(() => {
|
||||
setHeadings(extractTocFromTextEditor(textEditor));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import "./MindMap.css";
|
||||
import nodeMenu from "@mind-elixir/node-menu";
|
||||
import { DISPLAYABLE_LOCALE_IDS } from "@triliumnext/commons";
|
||||
import { snapdom } from "@zumer/snapdom";
|
||||
import { default as VanillaMindElixir,MindElixirData, MindElixirInstance, Operation, Options, THEME as LIGHT_THEME, DARK_THEME } from "mind-elixir";
|
||||
import { DARK_THEME, default as VanillaMindElixir, MindElixirData, MindElixirInstance, Operation, Options, THEME as LIGHT_THEME } from "mind-elixir";
|
||||
import { HTMLAttributes, RefObject } from "preact";
|
||||
import { useCallback, useEffect, useRef } from "preact/hooks";
|
||||
|
||||
@@ -154,6 +154,7 @@ function MindElixir({ containerRef: externalContainerRef, containerProps, apiRef
|
||||
const apiRef = useRef<MindElixirInstance>(null);
|
||||
const [ locale ] = useTriliumOption("locale");
|
||||
const colorScheme = useColorScheme();
|
||||
const defaultColorScheme = useRef(colorScheme);
|
||||
|
||||
function reinitialize() {
|
||||
if (!containerRef.current) return;
|
||||
@@ -162,7 +163,7 @@ function MindElixir({ containerRef: externalContainerRef, containerProps, apiRef
|
||||
el: containerRef.current,
|
||||
locale: LOCALE_MAPPINGS[locale as DISPLAYABLE_LOCALE_IDS] ?? undefined,
|
||||
editable,
|
||||
theme: LIGHT_THEME
|
||||
theme: defaultColorScheme.current === "dark" ? DARK_THEME : LIGHT_THEME
|
||||
});
|
||||
|
||||
if (editable) {
|
||||
@@ -188,7 +189,11 @@ function MindElixir({ containerRef: externalContainerRef, containerProps, apiRef
|
||||
if (!apiRef.current) return;
|
||||
const newTheme = colorScheme === "dark" ? DARK_THEME : LIGHT_THEME;
|
||||
if (apiRef.current.theme === newTheme) return; // Avoid unnecessary theme changes, which can be expensive to render.
|
||||
apiRef.current.changeTheme(newTheme);
|
||||
try {
|
||||
apiRef.current.changeTheme(newTheme);
|
||||
} catch (e) {
|
||||
console.warn("Failed to change mind map theme:", e);
|
||||
}
|
||||
}, [ colorScheme ]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -11,6 +11,7 @@ export type { EditorConfig, MentionFeed, MentionFeedObjectItem, ModelNode, Model
|
||||
export type { TemplateDefinition } from "ckeditor5-premium-features";
|
||||
export { default as buildExtraCommands } from "./extra_slash_commands.js";
|
||||
export { default as getCkLocale } from "./i18n.js";
|
||||
export * from "./utils.js";
|
||||
|
||||
// Import with sideffects to ensure that type augmentations are present.
|
||||
import "@triliumnext/ckeditor5-math";
|
||||
|
||||
28
packages/ckeditor5/src/utils.ts
Normal file
28
packages/ckeditor5/src/utils.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { DifferItemAttribute, Editor, ModelDocumentFragment, ModelElement, ModelNode } from "ckeditor5";
|
||||
|
||||
function hasHeadingAncestor(node: ModelElement | ModelNode | ModelDocumentFragment | null): boolean {
|
||||
let current: ModelElement | ModelNode | ModelDocumentFragment | null = node;
|
||||
while (current) {
|
||||
if (!!current && current.is('element') && (current as ModelElement).name.startsWith("heading")) return true;
|
||||
current = current.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function attributeChangeAffectsHeading(change: DifferItemAttribute, editor: Editor): boolean {
|
||||
if (change.type !== "attribute") return false;
|
||||
|
||||
// Fast checks on range boundaries
|
||||
if (hasHeadingAncestor(change.range.start.parent) || hasHeadingAncestor(change.range.end.parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Robust check across the whole changed range
|
||||
const range = editor.model.createRange(change.range.start, change.range.end);
|
||||
for (const item of range.getItems()) {
|
||||
const baseNode = item.is("$textProxy") ? item.parent : item;
|
||||
if (hasHeadingAncestor(baseNode)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user