mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
refactor(client): fix type errors related to CKEditor
This commit is contained in:
parent
3bad43c50d
commit
aab762911b
@ -3,6 +3,7 @@ import appContext from "../components/app_context.js";
|
|||||||
import noteCreateService from "./note_create.js";
|
import noteCreateService from "./note_create.js";
|
||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import { t } from "./i18n.js";
|
import { t } from "./i18n.js";
|
||||||
|
import type { MentionFeedObjectItem } from "@triliumnext/ckeditor5";
|
||||||
|
|
||||||
// this key needs to have this value, so it's hit by the tooltip
|
// this key needs to have this value, so it's hit by the tooltip
|
||||||
const SELECTED_NOTE_PATH_KEY = "data-note-path";
|
const SELECTED_NOTE_PATH_KEY = "data-note-path";
|
||||||
@ -43,7 +44,7 @@ interface Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function autocompleteSourceForCKEditor(queryText: string) {
|
async function autocompleteSourceForCKEditor(queryText: string) {
|
||||||
return await new Promise<MentionItem[]>((res, rej) => {
|
return await new Promise<MentionFeedObjectItem[]>((res, rej) => {
|
||||||
autocompleteSource(
|
autocompleteSource(
|
||||||
queryText,
|
queryText,
|
||||||
(rows) => {
|
(rows) => {
|
||||||
|
113
apps/client/src/types.d.ts
vendored
113
apps/client/src/types.d.ts
vendored
@ -209,119 +209,6 @@ declare global {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Range {
|
|
||||||
toJSON(): object;
|
|
||||||
getItems(): TextNode[];
|
|
||||||
}
|
|
||||||
interface Writer {
|
|
||||||
setAttribute(name: string, value: string, el: CKNode);
|
|
||||||
createPositionAt(el: CKNode, opt?: "end" | number);
|
|
||||||
setSelection(pos: number, pos2?: number);
|
|
||||||
insertText(text: string, opts: Record<string, unknown> | undefined | TextPosition, position?: TextPosition);
|
|
||||||
addMarker(name: string, opts: {
|
|
||||||
range: Range;
|
|
||||||
usingOperation: boolean;
|
|
||||||
});
|
|
||||||
removeMarker(name: string);
|
|
||||||
createRange(start: number, end: number): Range;
|
|
||||||
createElement(type: string, opts: Record<string, string | null | undefined>);
|
|
||||||
}
|
|
||||||
interface TextNode {
|
|
||||||
previousSibling?: TextNode;
|
|
||||||
name: string;
|
|
||||||
data: string;
|
|
||||||
startOffset: number;
|
|
||||||
_attrs: {
|
|
||||||
get(key: string): {
|
|
||||||
length: number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interface TextPosition {
|
|
||||||
textNode: TextNode;
|
|
||||||
offset: number;
|
|
||||||
compareWith(pos: TextPosition): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TextRange {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Marker {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CKNode {
|
|
||||||
_children: CKNode[];
|
|
||||||
name: string;
|
|
||||||
childCount: number;
|
|
||||||
isEmpty: boolean;
|
|
||||||
toJSON(): object;
|
|
||||||
is(type: string, name?: string);
|
|
||||||
getAttribute(name: string): string;
|
|
||||||
getChild(index: number): CKNode;
|
|
||||||
data: string;
|
|
||||||
startOffset: number;
|
|
||||||
root: {
|
|
||||||
document: {
|
|
||||||
model: {
|
|
||||||
createRangeIn(el: CKNode): TextRange;
|
|
||||||
markers: {
|
|
||||||
getMarkersIntersectingRange(range: TextRange): Marker[];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CKEvent {
|
|
||||||
stop(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PluginEventData {
|
|
||||||
title: string;
|
|
||||||
message: {
|
|
||||||
message: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EditingState {
|
|
||||||
highlightedResult: string;
|
|
||||||
results: unknown[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CKFindResult {
|
|
||||||
results: {
|
|
||||||
get(number): {
|
|
||||||
marker: {
|
|
||||||
getStart(): TextPosition;
|
|
||||||
getRange(): number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} & [];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MentionItem {
|
|
||||||
action?: string;
|
|
||||||
noteTitle?: string;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
link?: string;
|
|
||||||
notePath?: string;
|
|
||||||
highlightedNotePathTitle?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MentionConfig {
|
|
||||||
feeds: {
|
|
||||||
marker: string;
|
|
||||||
feed: (queryText: string) => MentionItem[] | Promise<MentionItem[]>;
|
|
||||||
itemRenderer?: (item: {
|
|
||||||
highlightedNotePathTitle: string
|
|
||||||
}) => void;
|
|
||||||
minimumCharacters: number;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Panzoom
|
* Panzoom
|
||||||
*/
|
*/
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { t } from "../../services/i18n.js";
|
import { t } from "../../services/i18n.js";
|
||||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
import noteAutocompleteService, { type Suggestion } from "../../services/note_autocomplete.js";
|
||||||
import server from "../../services/server.js";
|
import server from "../../services/server.js";
|
||||||
import contextMenuService from "../../menus/context_menu.js";
|
import contextMenuService from "../../menus/context_menu.js";
|
||||||
import attributeParser, { type Attribute } from "../../services/attribute_parser.js";
|
import attributeParser, { type Attribute } from "../../services/attribute_parser.js";
|
||||||
import { AttributeEditor } from "@triliumnext/ckeditor5";
|
import { AttributeEditor, type EditorConfig, type Element, type MentionFeed, type Node, type Position } from "@triliumnext/ckeditor5";
|
||||||
import froca from "../../services/froca.js";
|
import froca from "../../services/froca.js";
|
||||||
import attributeRenderer from "../../services/attribute_renderer.js";
|
import attributeRenderer from "../../services/attribute_renderer.js";
|
||||||
import noteCreateService from "../../services/note_create.js";
|
import noteCreateService from "../../services/note_create.js";
|
||||||
@ -84,57 +84,58 @@ const TPL = /*html*/`
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const mentionSetup: MentionConfig = {
|
const mentionSetup: MentionFeed[] = [
|
||||||
feeds: [
|
{
|
||||||
{
|
marker: "@",
|
||||||
marker: "@",
|
feed: (queryText) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
||||||
feed: (queryText) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
itemRenderer: (_item) => {
|
||||||
itemRenderer: (item) => {
|
const item = _item as Suggestion;
|
||||||
const itemElement = document.createElement("button");
|
const itemElement = document.createElement("button");
|
||||||
|
|
||||||
itemElement.innerHTML = `${item.highlightedNotePathTitle} `;
|
itemElement.innerHTML = `${item.highlightedNotePathTitle} `;
|
||||||
|
|
||||||
return itemElement;
|
return itemElement;
|
||||||
},
|
|
||||||
minimumCharacters: 0
|
|
||||||
},
|
},
|
||||||
{
|
minimumCharacters: 0
|
||||||
marker: "#",
|
},
|
||||||
feed: async (queryText) => {
|
{
|
||||||
const names = await server.get<string[]>(`attribute-names/?type=label&query=${encodeURIComponent(queryText)}`);
|
marker: "#",
|
||||||
|
feed: async (queryText) => {
|
||||||
|
const names = await server.get<string[]>(`attribute-names/?type=label&query=${encodeURIComponent(queryText)}`);
|
||||||
|
|
||||||
return names.map((name) => {
|
return names.map((name) => {
|
||||||
return {
|
return {
|
||||||
id: `#${name}`,
|
id: `#${name}`,
|
||||||
name: name
|
name: name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
|
||||||
minimumCharacters: 0
|
|
||||||
},
|
},
|
||||||
{
|
minimumCharacters: 0
|
||||||
marker: "~",
|
},
|
||||||
feed: async (queryText) => {
|
{
|
||||||
const names = await server.get<string[]>(`attribute-names/?type=relation&query=${encodeURIComponent(queryText)}`);
|
marker: "~",
|
||||||
|
feed: async (queryText) => {
|
||||||
|
const names = await server.get<string[]>(`attribute-names/?type=relation&query=${encodeURIComponent(queryText)}`);
|
||||||
|
|
||||||
return names.map((name) => {
|
return names.map((name) => {
|
||||||
return {
|
return {
|
||||||
id: `~${name}`,
|
id: `~${name}`,
|
||||||
name: name
|
name: name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
minimumCharacters: 0
|
minimumCharacters: 0
|
||||||
}
|
}
|
||||||
]
|
];
|
||||||
};
|
|
||||||
|
|
||||||
const editorConfig = {
|
const editorConfig: EditorConfig = {
|
||||||
toolbar: {
|
toolbar: {
|
||||||
items: []
|
items: []
|
||||||
},
|
},
|
||||||
placeholder: t("attribute_editor.placeholder"),
|
placeholder: t("attribute_editor.placeholder"),
|
||||||
mention: mentionSetup,
|
mention: {
|
||||||
|
feeds: mentionSetup
|
||||||
|
},
|
||||||
licenseKey: "GPL"
|
licenseKey: "GPL"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -334,7 +335,10 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem
|
|||||||
);
|
);
|
||||||
|
|
||||||
// disable spellcheck for attribute editor
|
// disable spellcheck for attribute editor
|
||||||
this.textEditor.editing.view.change((writer) => writer.setAttribute("spellcheck", "false", this.textEditor.editing.view.document.getRoot()));
|
const documentRoot = this.textEditor.editing.view.document.getRoot();
|
||||||
|
if (documentRoot) {
|
||||||
|
this.textEditor.editing.view.change((writer) => writer.setAttribute("spellcheck", "false", documentRoot));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataChanged() {
|
dataChanged() {
|
||||||
@ -411,18 +415,18 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem
|
|||||||
this.$editor.tooltip("show");
|
this.$editor.tooltip("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
getClickIndex(pos: TextPosition) {
|
getClickIndex(pos: Position) {
|
||||||
let clickIndex = pos.offset - pos.textNode.startOffset;
|
let clickIndex = pos.offset - (pos.textNode?.startOffset ?? 0);
|
||||||
|
|
||||||
let curNode = pos.textNode;
|
let curNode: Node | Text | Element | null = pos.textNode;
|
||||||
|
|
||||||
while (curNode.previousSibling) {
|
while (curNode?.previousSibling) {
|
||||||
curNode = curNode.previousSibling;
|
curNode = curNode.previousSibling;
|
||||||
|
|
||||||
if (curNode.name === "reference") {
|
if ((curNode as Element).name === "reference") {
|
||||||
clickIndex += curNode._attrs.get("notePath").length + 1;
|
clickIndex += (curNode.getAttribute("notePath") as string).length + 1;
|
||||||
} else {
|
} else if ("data" in curNode) {
|
||||||
clickIndex += curNode.data.length;
|
clickIndex += (curNode.data as string).length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,8 +484,12 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem
|
|||||||
this.$editor.trigger("focus");
|
this.$editor.trigger("focus");
|
||||||
|
|
||||||
this.textEditor.model.change((writer) => {
|
this.textEditor.model.change((writer) => {
|
||||||
const positionAt = writer.createPositionAt(this.textEditor.model.document.getRoot(), "end");
|
const documentRoot = this.textEditor.editing.model.document.getRoot();
|
||||||
|
if (!documentRoot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const positionAt = writer.createPositionAt(documentRoot, "end");
|
||||||
writer.setSelection(positionAt);
|
writer.setSelection(positionAt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { FindAndReplaceState, FindCommandResult } from "@triliumnext/ckeditor5";
|
||||||
import type { FindResult } from "./find.js";
|
import type { FindResult } from "./find.js";
|
||||||
import type FindWidget from "./find.js";
|
import type FindWidget from "./find.js";
|
||||||
|
|
||||||
@ -14,8 +15,8 @@ interface Match {
|
|||||||
export default class FindInText {
|
export default class FindInText {
|
||||||
|
|
||||||
private parent: FindWidget;
|
private parent: FindWidget;
|
||||||
private findResult?: CKFindResult | null;
|
private findResult?: FindCommandResult | null;
|
||||||
private editingState?: EditingState;
|
private editingState?: FindAndReplaceState;
|
||||||
|
|
||||||
constructor(parent: FindWidget) {
|
constructor(parent: FindWidget) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
@ -40,7 +41,7 @@ export default class FindInText {
|
|||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
const findAndReplaceEditing = textEditor.plugins.get("FindAndReplaceEditing");
|
const findAndReplaceEditing = textEditor.plugins.get("FindAndReplaceEditing");
|
||||||
findAndReplaceEditing.state.clear(model);
|
findAndReplaceEditing.state?.clear(model);
|
||||||
findAndReplaceEditing.stop();
|
findAndReplaceEditing.stop();
|
||||||
this.editingState = findAndReplaceEditing.state;
|
this.editingState = findAndReplaceEditing.state;
|
||||||
if (searchTerm !== "") {
|
if (searchTerm !== "") {
|
||||||
@ -52,14 +53,14 @@ export default class FindInText {
|
|||||||
// let m = text.match(re);
|
// let m = text.match(re);
|
||||||
// totalFound = m ? m.length : 0;
|
// totalFound = m ? m.length : 0;
|
||||||
const options = { matchCase: matchCase, wholeWords: wholeWord };
|
const options = { matchCase: matchCase, wholeWords: wholeWord };
|
||||||
findResult = textEditor.execute<CKFindResult>("find", searchTerm, options);
|
findResult = textEditor.execute("find", searchTerm, options);
|
||||||
totalFound = findResult.results.length;
|
totalFound = findResult.results.length;
|
||||||
// Find the result beyond the cursor
|
// Find the result beyond the cursor
|
||||||
const cursorPos = model.document.selection.getLastPosition();
|
const cursorPos = model.document.selection.getLastPosition();
|
||||||
for (let i = 0; i < findResult.results.length; ++i) {
|
for (let i = 0; i < findResult.results.length; ++i) {
|
||||||
const marker = findResult.results.get(i).marker;
|
const marker = findResult.results.get(i)?.marker;
|
||||||
const fromPos = marker.getStart();
|
const fromPos = marker?.getStart();
|
||||||
if (cursorPos && fromPos.compareWith(cursorPos) !== "before") {
|
if (cursorPos && fromPos && fromPos.compareWith(cursorPos) !== "before") {
|
||||||
currentFound = i;
|
currentFound = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ export default class FindInText {
|
|||||||
// XXX Do this accessing the private data?
|
// XXX Do this accessing the private data?
|
||||||
// See https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findnextcommand.js
|
// See https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findnextcommand.js
|
||||||
for (let i = 0; i < currentFound; ++i) {
|
for (let i = 0; i < currentFound; ++i) {
|
||||||
textEditor?.execute("findNext", searchTerm);
|
textEditor?.execute("findNext");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,17 +110,17 @@ export default class FindInText {
|
|||||||
// Clear the markers and set the caret to the
|
// Clear the markers and set the caret to the
|
||||||
// current occurrence
|
// current occurrence
|
||||||
const model = textEditor.model;
|
const model = textEditor.model;
|
||||||
const range = this.findResult?.results?.get(currentFound).marker.getRange();
|
const range = this.findResult?.results?.get(currentFound)?.marker?.getRange();
|
||||||
// From
|
// From
|
||||||
// https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findandreplace.js#L92
|
// https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findandreplace.js#L92
|
||||||
// XXX Roll our own since already done for codeEditor and
|
// XXX Roll our own since already done for codeEditor and
|
||||||
// will probably allow more refactoring?
|
// will probably allow more refactoring?
|
||||||
let findAndReplaceEditing = textEditor.plugins.get("FindAndReplaceEditing");
|
let findAndReplaceEditing = textEditor.plugins.get("FindAndReplaceEditing");
|
||||||
findAndReplaceEditing.state.clear(model);
|
findAndReplaceEditing.state?.clear(model);
|
||||||
findAndReplaceEditing.stop();
|
findAndReplaceEditing.stop();
|
||||||
if (range) {
|
if (range) {
|
||||||
model.change((writer) => {
|
model.change((writer) => {
|
||||||
writer.setSelection(range, 0);
|
writer.setSelection(range);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
textEditor.editing.view.scrollToTheSelection();
|
textEditor.editing.view.scrollToTheSelection();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { t } from "../../services/i18n.js";
|
import { t } from "../../services/i18n.js";
|
||||||
import libraryLoader from "../../services/library_loader.js";
|
import libraryLoader from "../../services/library_loader.js";
|
||||||
import noteAutocompleteService from "../../services/note_autocomplete.js";
|
import noteAutocompleteService, { type Suggestion } from "../../services/note_autocomplete.js";
|
||||||
import mimeTypesService from "../../services/mime_types.js";
|
import mimeTypesService from "../../services/mime_types.js";
|
||||||
import utils, { hasTouchBar } from "../../services/utils.js";
|
import utils, { hasTouchBar } from "../../services/utils.js";
|
||||||
import keyboardActionService from "../../services/keyboard_actions.js";
|
import keyboardActionService from "../../services/keyboard_actions.js";
|
||||||
@ -17,27 +17,25 @@ import { buildSelectedBackgroundColor } from "../../components/touch_bar.js";
|
|||||||
import { buildConfig, buildToolbarConfig } from "./ckeditor/config.js";
|
import { buildConfig, buildToolbarConfig } from "./ckeditor/config.js";
|
||||||
import type FNote from "../../entities/fnote.js";
|
import type FNote from "../../entities/fnote.js";
|
||||||
import { getMermaidConfig } from "../../services/mermaid.js";
|
import { getMermaidConfig } from "../../services/mermaid.js";
|
||||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor } from "@triliumnext/ckeditor5";
|
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor, type MentionFeed, type WatchdogConfig } from "@triliumnext/ckeditor5";
|
||||||
import "@triliumnext/ckeditor5/index.css";
|
import "@triliumnext/ckeditor5/index.css";
|
||||||
|
|
||||||
const ENABLE_INSPECTOR = false;
|
const ENABLE_INSPECTOR = false;
|
||||||
|
|
||||||
const mentionSetup: MentionConfig = {
|
const mentionSetup: MentionFeed[] = [
|
||||||
feeds: [
|
{
|
||||||
{
|
marker: "@",
|
||||||
marker: "@",
|
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
||||||
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
|
itemRenderer: (item) => {
|
||||||
itemRenderer: (item) => {
|
const itemElement = document.createElement("button");
|
||||||
const itemElement = document.createElement("button");
|
|
||||||
|
|
||||||
itemElement.innerHTML = `${item.highlightedNotePathTitle} `;
|
itemElement.innerHTML = `${(item as Suggestion).highlightedNotePathTitle} `;
|
||||||
|
|
||||||
return itemElement;
|
return itemElement;
|
||||||
},
|
},
|
||||||
minimumCharacters: 0
|
minimumCharacters: 0
|
||||||
}
|
}
|
||||||
]
|
];
|
||||||
};
|
|
||||||
|
|
||||||
const TPL = /*html*/`
|
const TPL = /*html*/`
|
||||||
<div class="note-detail-editable-text note-detail-printable">
|
<div class="note-detail-editable-text note-detail-printable">
|
||||||
@ -128,7 +126,7 @@ function buildListOfLanguages() {
|
|||||||
export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||||
|
|
||||||
private contentLanguage?: string | null;
|
private contentLanguage?: string | null;
|
||||||
private watchdog!: EditorWatchdog<CKTextEditor>;
|
private watchdog!: EditorWatchdog<ClassicEditor | PopupEditor>;
|
||||||
|
|
||||||
private $editor!: JQuery<HTMLElement>;
|
private $editor!: JQuery<HTMLElement>;
|
||||||
|
|
||||||
@ -158,7 +156,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
// display of $widget in both branches.
|
// display of $widget in both branches.
|
||||||
this.$widget.show();
|
this.$widget.show();
|
||||||
|
|
||||||
this.watchdog = new EditorWatchdog<CKTextEditor>(editorClass, {
|
const config: WatchdogConfig = {
|
||||||
// An average number of milliseconds between the last editor errors (defaults to 5000).
|
// An average number of milliseconds between the last editor errors (defaults to 5000).
|
||||||
// When the period of time between errors is lower than that and the crashNumberLimit
|
// When the period of time between errors is lower than that and the crashNumberLimit
|
||||||
// is also reached, the watchdog changes its state to crashedPermanently, and it stops
|
// is also reached, the watchdog changes its state to crashedPermanently, and it stops
|
||||||
@ -173,7 +171,8 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
// A minimum number of milliseconds between saving the editor data internally (defaults to 5000).
|
// A minimum number of milliseconds between saving the editor data internally (defaults to 5000).
|
||||||
// Note that for large documents, this might impact the editor performance.
|
// Note that for large documents, this might impact the editor performance.
|
||||||
saveInterval: 5000
|
saveInterval: 5000
|
||||||
});
|
};
|
||||||
|
this.watchdog = isClassicEditor ? new EditorWatchdog(ClassicEditor, config) : new EditorWatchdog(PopupEditor, config);
|
||||||
|
|
||||||
this.watchdog.on("stateChange", () => {
|
this.watchdog.on("stateChange", () => {
|
||||||
const currentState = this.watchdog.state;
|
const currentState = this.watchdog.state;
|
||||||
@ -226,7 +225,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
const editor = await editorClass.create(elementOrData, finalConfig);
|
const editor = await editorClass.create(elementOrData, finalConfig);
|
||||||
|
|
||||||
const notificationsPlugin = editor.plugins.get("Notification");
|
const notificationsPlugin = editor.plugins.get("Notification");
|
||||||
notificationsPlugin.on("show:warning", (evt: CKEvent, data: PluginEventData) => {
|
notificationsPlugin.on("show:warning", (evt, data) => {
|
||||||
const title = data.title;
|
const title = data.title;
|
||||||
const message = data.message.message;
|
const message = data.message.message;
|
||||||
|
|
||||||
@ -447,10 +446,10 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(this.watchdog.editor);
|
callback(this.watchdog.editor as CKTextEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(this.watchdog.editor);
|
resolve(this.watchdog.editor as CKTextEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
addLinkToTextCommand() {
|
addLinkToTextCommand() {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import "ckeditor5/ckeditor5.css";
|
import "ckeditor5/ckeditor5.css";
|
||||||
import { COMMON_PLUGINS, CORE_PLUGINS, POPUP_EDITOR_PLUGINS } from "./plugins";
|
import { COMMON_PLUGINS, CORE_PLUGINS, POPUP_EDITOR_PLUGINS } from "./plugins";
|
||||||
import { BalloonEditor, DecoupledEditor } from "ckeditor5";
|
import { BalloonEditor, DecoupledEditor, FindAndReplaceEditing, FindCommand } from "ckeditor5";
|
||||||
export { EditorWatchdog } from "ckeditor5";
|
export { EditorWatchdog } from "ckeditor5";
|
||||||
|
export type { EditorConfig, MentionFeed, MentionFeedObjectItem, Node, Position, Element, WatchdogConfig } from "ckeditor5";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Short-hand for the CKEditor classes supported by Trilium for text editing.
|
* Short-hand for the CKEditor classes supported by Trilium for text editing.
|
||||||
@ -12,6 +13,9 @@ export type CKTextEditor = (ClassicEditor | PopupEditor) & {
|
|||||||
removeSelection(): Promise<void>;
|
removeSelection(): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FindAndReplaceState = FindAndReplaceEditing["state"];
|
||||||
|
export type FindCommandResult = ReturnType<FindCommand["execute"]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text editor that can be used for editing attributes and relations.
|
* The text editor that can be used for editing attributes and relations.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user