chore(highlights_list): read highlights from CK

This commit is contained in:
Elian Doran 2025-12-18 12:52:14 +02:00
parent dbf29ed23f
commit 73f2f56932
No known key found for this signature in database
3 changed files with 77 additions and 4 deletions

View File

@ -1,7 +1,16 @@
import { CKTextEditor, ModelTextProxy } from "@triliumnext/ckeditor5";
import { useEffect, useState } from "preact/hooks";
import { t } from "../../services/i18n"; import { t } from "../../services/i18n";
import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty } from "../react/hooks"; import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor } from "../react/hooks";
import RightPanelWidget from "./RightPanelWidget"; import RightPanelWidget from "./RightPanelWidget";
interface RawHighlight {
id: string;
text: string;
attrs: Record<string, any>;
}
export default function HighlightsList() { export default function HighlightsList() {
const { note, noteContext } = useActiveNoteContext(); const { note, noteContext } = useActiveNoteContext();
const noteType = useNoteProperty(note, "type"); const noteType = useNoteProperty(note, "type");
@ -15,9 +24,73 @@ export default function HighlightsList() {
); );
} }
function AbstractHighlightsList({ highlights }: {
highlights: RawHighlight[]
}) {
return (
<span className="highlights-list">
<ol>
{highlights.map(highlight => (
<li>
<span>{highlight.text}</span>
</li>
))}
</ol>
</span>
);
}
//#region Editable text (CKEditor) //#region Editable text (CKEditor)
interface CKHighlight extends RawHighlight {
element: ModelTextProxy;
}
function EditableTextHighlightsList() { function EditableTextHighlightsList() {
return "Editable"; const { note, noteContext } = useActiveNoteContext();
const textEditor = useTextEditor(noteContext);
const [ highlights, setHighlights ] = useState<CKHighlight[]>([]);
useEffect(() => {
if (!textEditor) return;
const highlights = extractHighlightsFromTextEditor(textEditor);
setHighlights(highlights);
}, [ textEditor, note ]);
return <AbstractHighlightsList
highlights={highlights}
/>;
}
function extractHighlightsFromTextEditor(editor: CKTextEditor) {
const result: CKHighlight[] = [];
const root = editor.model.document.getRoot();
if (!root) return [];
for (const { item } of editor.model.createRangeIn(root).getWalker({ ignoreElementEnd: true })) {
if (!item.is('$textProxy')) continue;
console.log("Got ", item);
const attrs = {
bold: item.hasAttribute('bold'),
italic: item.hasAttribute('italic'),
underline: item.hasAttribute('underline'),
color: item.getAttribute('fontColor'),
background: item.getAttribute('fontBackgroundColor')
};
console.log("Got ", attrs);
if (Object.values(attrs).some(Boolean)) {
result.push({
id: crypto.randomUUID(),
text: item.data,
attrs,
element: item
});
}
}
return result;
} }
//#endregion //#endregion

View File

@ -114,6 +114,7 @@ function EditableTextTableOfContents() {
useEffect(() => { useEffect(() => {
if (!textEditor) return; if (!textEditor) return;
const headings = extractTocFromTextEditor(textEditor); const headings = extractTocFromTextEditor(textEditor);
setHeadings(headings);
// React to changes. // React to changes.
const changeCallback = () => { const changeCallback = () => {
@ -130,7 +131,6 @@ function EditableTextTableOfContents() {
}; };
textEditor.model.document.on("change:data", changeCallback); textEditor.model.document.on("change:data", changeCallback);
setHeadings(headings);
return () => textEditor.model.document.off("change:data", changeCallback); return () => textEditor.model.document.off("change:data", changeCallback);
}, [ textEditor, note ]); }, [ textEditor, note ]);

View File

@ -6,7 +6,7 @@ import { BalloonEditor, DecoupledEditor, FindAndReplaceEditing, FindCommand } fr
import "./translation_overrides.js"; import "./translation_overrides.js";
export { default as EditorWatchdog } from "./custom_watchdog"; export { default as EditorWatchdog } from "./custom_watchdog";
export { PREMIUM_PLUGINS } from "./plugins.js"; export { PREMIUM_PLUGINS } from "./plugins.js";
export type { EditorConfig, MentionFeed, MentionFeedObjectItem, ModelNode, ModelPosition, ModelElement, WatchdogConfig, WatchdogState } from "ckeditor5"; export type { EditorConfig, MentionFeed, MentionFeedObjectItem, ModelNode, ModelPosition, ModelElement, ModelTextProxy, WatchdogConfig, WatchdogState } from "ckeditor5";
export type { TemplateDefinition } from "ckeditor5-premium-features"; export type { TemplateDefinition } from "ckeditor5-premium-features";
export { default as buildExtraCommands } from "./extra_slash_commands.js"; export { default as buildExtraCommands } from "./extra_slash_commands.js";
export { default as getCkLocale } from "./i18n.js"; export { default as getCkLocale } from "./i18n.js";