Skip to content

Commit

Permalink
close: #11 fix link
Browse files Browse the repository at this point in the history
  • Loading branch information
nasum committed Apr 6, 2024
1 parent be486f3 commit 7ff7491
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 1 deletion.
15 changes: 14 additions & 1 deletion frontend/src/components/common/editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
Expand All @@ -26,7 +25,9 @@ import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
import { EditorState } from "lexical";

import CodeHighlightPlugin from "./plugins/CodeHighlight";
import LinkPlugin from "./plugins/LinkPlugin";
import { Theme } from "./theme/Theme";

import "github-markdown-css";
Expand All @@ -47,6 +48,18 @@ const EditorContainer = styled.div`
:where(ol) {
list-style: decimal;
}
li[role="checkbox"] {
cursor: pointer;
span {
cursor: auto;
}
}
a {
text-decoration: none;
cursor: pointer;
}
`;

const EditorActions = styled.div`
Expand Down
82 changes: 82 additions & 0 deletions frontend/src/components/common/editor/plugins/LinkPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useEffect } from "react";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { $isLinkNode } from "@lexical/link";
import type { LexicalEditor } from "lexical";
import { $getNearestNodeFromDOMNode } from "lexical";
import { BrowserOpenURL } from "../../../../../wailsjs/runtime";

export default function LinkPlugin() {
const [editor] = useLexicalComposerContext();

useEffect(() => {
const onClick = (e: MouseEvent) => {
const linkDomNode = getLinkDomNode(e, editor);

if (linkDomNode === null) {
return;
}

const href = linkDomNode.getAttribute("href");

let linkNode = null;
editor.update(() => {
const maybeLinkNode = $getNearestNodeFromDOMNode(linkDomNode);

if ($isLinkNode(maybeLinkNode)) {
linkNode = maybeLinkNode;
}
});

try {
if (href !== null) {
BrowserOpenURL(href);
e.preventDefault();
}
} catch (e) {
console.error(e);
}
};

return editor.registerRootListener(
(
rootElement: null | HTMLElement,
prevRootElement: null | HTMLElement,
) => {
if (prevRootElement !== null) {
prevRootElement.removeEventListener("click", onClick);
prevRootElement.removeEventListener("auxclick", onClick);
}

if (rootElement !== null) {
rootElement.addEventListener("click", onClick);
rootElement.addEventListener("auxclick", onClick);
}
},
);
}, [editor]);

return null;
}

function isLinkDomNode(domNode: Node): boolean {
return domNode.nodeName.toLowerCase() === "a";
}

function getLinkDomNode(
event: MouseEvent | PointerEvent,
editor: LexicalEditor,
): HTMLAnchorElement | null {
return editor.getEditorState().read(() => {
const domNode = event.target as Node;

if (isLinkDomNode(domNode)) {
return domNode as HTMLAnchorElement;
}

if (domNode.parentNode && isLinkDomNode(domNode.parentNode)) {
return domNode.parentNode as HTMLAnchorElement;
}

return null;
});
}

0 comments on commit 7ff7491

Please sign in to comment.