Skip to content

Commit 7f22532

Browse files
authored
fix: import markdown to text note (#7538)
2 parents c7beb87 + 8f8ea7a commit 7f22532

File tree

7 files changed

+51
-38
lines changed

7 files changed

+51
-38
lines changed

apps/client/src/components/app_context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,12 @@ export type CommandMappings = {
218218
/** Works only in the electron context menu. */
219219
replaceMisspelling: CommandData;
220220

221-
importMarkdownInline: CommandData;
222221
showPasswordNotSet: CommandData;
223222
showProtectedSessionPasswordDialog: CommandData;
224223
showUploadAttachmentsDialog: CommandData & { noteId: string };
225224
showIncludeNoteDialog: CommandData & { textTypeWidget: EditableTextTypeWidget };
226225
showAddLinkDialog: CommandData & { textTypeWidget: EditableTextTypeWidget, text: string };
226+
showPasteMarkdownDialog: CommandData & { textTypeWidget: EditableTextTypeWidget };
227227
closeProtectedSessionPasswordDialog: CommandData;
228228
copyImageReferenceToClipboard: CommandData;
229229
copyImageToClipboard: CommandData;

apps/client/src/services/glob.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ function setupGlobs() {
2020
window.glob.froca = froca;
2121
window.glob.treeCache = froca; // compatibility for CKEditor builds for a while
2222

23-
// for CKEditor integration (button on block toolbar)
24-
window.glob.importMarkdownInline = async () => appContext.triggerCommand("importMarkdownInline");
25-
2623
window.onerror = function (msg, url, lineNo, columnNo, error) {
2724
const string = String(msg).toLowerCase();
2825

apps/client/src/types.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ interface CustomGlobals {
2626
appContext: AppContext;
2727
froca: Froca;
2828
treeCache: Froca;
29-
importMarkdownInline: () => Promise<unknown>;
3029
SEARCH_HELP_TEXT: string;
3130
activeDialog: JQuery<HTMLElement> | null;
3231
componentId: string;

apps/client/src/widgets/dialogs/markdown_import.tsx

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,42 @@ import utils from "../../services/utils";
77
import Modal from "../react/Modal";
88
import Button from "../react/Button";
99
import { useTriliumEvent } from "../react/hooks";
10+
import EditableTextTypeWidget from "../type_widgets/editable_text";
1011

1112
interface RenderMarkdownResponse {
1213
htmlContent: string;
1314
}
1415

1516
export default function MarkdownImportDialog() {
1617
const markdownImportTextArea = useRef<HTMLTextAreaElement>(null);
18+
const [textTypeWidget, setTextTypeWidget] = useState<EditableTextTypeWidget>();
1719
const [ text, setText ] = useState("");
1820
const [ shown, setShown ] = useState(false);
1921

20-
const triggerImport = useCallback(() => {
21-
if (appContext.tabManager.getActiveContextNoteType() !== "text") {
22-
return;
23-
}
24-
22+
useTriliumEvent("showPasteMarkdownDialog", ({ textTypeWidget }) => {
23+
setTextTypeWidget(textTypeWidget);
2524
if (utils.isElectron()) {
2625
const { clipboard } = utils.dynamicRequire("electron");
2726
const text = clipboard.readText();
2827

29-
convertMarkdownToHtml(text);
28+
convertMarkdownToHtml(text, textTypeWidget);
3029
} else {
3130
setShown(true);
3231
}
33-
}, []);
34-
35-
useTriliumEvent("importMarkdownInline", triggerImport);
36-
useTriliumEvent("pasteMarkdownIntoText", triggerImport);
37-
38-
async function sendForm() {
39-
await convertMarkdownToHtml(text);
40-
setText("");
41-
setShown(false);
42-
}
32+
});
4333

4434
return (
4535
<Modal
4636
className="markdown-import-dialog" title={t("markdown_import.dialog_title")} size="lg"
47-
footer={<Button className="markdown-import-button" text={t("markdown_import.import_button")} onClick={sendForm} keyboardShortcut="Ctrl+Space" />}
37+
footer={<Button className="markdown-import-button" text={t("markdown_import.import_button")} onClick={() => setShown(false)} keyboardShortcut="Ctrl+Enter" />}
4838
onShown={() => markdownImportTextArea.current?.focus()}
49-
onHidden={() => setShown(false) }
39+
onHidden={async () => {
40+
if (textTypeWidget) {
41+
await convertMarkdownToHtml(text, textTypeWidget);
42+
}
43+
setShown(false);
44+
setText("");
45+
}}
5046
show={shown}
5147
>
5248
<p>{t("markdown_import.modal_body_text")}</p>
@@ -56,26 +52,17 @@ export default function MarkdownImportDialog() {
5652
onKeyDown={(e) => {
5753
if (e.key === "Enter" && e.ctrlKey) {
5854
e.preventDefault();
59-
sendForm();
55+
setShown(false);
6056
}
6157
}}></textarea>
6258
</Modal>
6359
)
6460
}
6561

66-
async function convertMarkdownToHtml(markdownContent: string) {
62+
async function convertMarkdownToHtml(markdownContent: string, textTypeWidget: EditableTextTypeWidget) {
6763
const { htmlContent } = await server.post<RenderMarkdownResponse>("other/render-markdown", { markdownContent });
6864

69-
const textEditor = await appContext.tabManager.getActiveContext()?.getTextEditor();
70-
if (!textEditor) {
71-
return;
72-
}
73-
74-
const viewFragment = textEditor.data.processor.toView(htmlContent);
75-
const modelFragment = textEditor.data.toModel(viewFragment);
76-
77-
textEditor.model.insertContent(modelFragment, textEditor.model.document.selection);
78-
textEditor.editing.view.focus();
79-
65+
await textTypeWidget.addHtmlToEditor(htmlContent);
66+
8067
toast.showMessage(t("markdown_import.import_success"));
8168
}

apps/client/src/widgets/type_widgets/editable_text.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,30 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
329329
});
330330
}
331331

332+
async addHtmlToEditor(html: string) {
333+
await this.initialized;
334+
335+
const editor = this.watchdog.editor;
336+
if (!editor) return;
337+
338+
editor.model.change((writer) => {
339+
const viewFragment = editor.data.processor.toView(html);
340+
const modelFragment = editor.data.toModel(viewFragment);
341+
const insertPosition = editor.model.document.selection.getLastPosition();
342+
343+
if (insertPosition) {
344+
const range = editor.model.insertContent(modelFragment, insertPosition);
345+
346+
if (range) {
347+
writer.setSelection(range.end);
348+
}
349+
}
350+
351+
});
352+
353+
editor.editing.view.focus();
354+
}
355+
332356
addTextToActiveEditorEvent({ text }: EventData<"addTextToActiveEditor">) {
333357
if (!this.isActive()) {
334358
return;
@@ -385,6 +409,10 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
385409
this.triggerCommand("showAddLinkDialog", { textTypeWidget: this, text: selectedText });
386410
}
387411

412+
pasteMarkdownIntoTextCommand() {
413+
this.triggerCommand("showPasteMarkdownDialog", { textTypeWidget: this });
414+
}
415+
388416
getSelectedText() {
389417
const range = this.watchdog.editor?.model.document.selection.getFirstRange();
390418
let text = "";

packages/ckeditor5/src/augmentation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@ declare global {
1919
getHeaders(): Promise<Record<string, string>>;
2020
getReferenceLinkTitle(href: string): Promise<string>;
2121
getReferenceLinkTitleSync(href: string): string;
22-
importMarkdownInline(): void;
2322
}
2423
}

packages/ckeditor5/src/plugins/markdownimport.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ export default class MarkdownImportPlugin extends Plugin {
3131
class ImportMarkdownCommand extends Command {
3232

3333
execute() {
34-
glob.importMarkdownInline();
34+
const editorEl = this.editor.editing.view.getDomRoot();
35+
const component = glob.getComponentByEl(editorEl);
36+
37+
component.triggerCommand('pasteMarkdownIntoText');
3538
}
3639

3740
}

0 commit comments

Comments
 (0)