mirror of
https://github.com/kou029w/quot.git
synced 2025-01-31 06:18:01 +00:00
auto link (experimental)
This commit is contained in:
parent
b569dac9ce
commit
b725b250d3
3 changed files with 57 additions and 8 deletions
20
app/package-lock.json
generated
20
app/package-lock.json
generated
|
@ -11,6 +11,7 @@
|
|||
"@exampledev/new.css": "^1.1.3",
|
||||
"@fastify/http-proxy": "^8.2.2",
|
||||
"@lexical/history": "^0.4.1",
|
||||
"@lexical/link": "^0.4.1",
|
||||
"@lexical/rich-text": "^0.4.1",
|
||||
"@tsconfig/node18-strictest-esm": "^1.0.1",
|
||||
"esbuild": "^0.15.7",
|
||||
|
@ -138,6 +139,17 @@
|
|||
"lexical": "0.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@lexical/link": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.4.1.tgz",
|
||||
"integrity": "sha512-566lQymmuBe3Y7UDyaaTs+VDlElbu1WhnjT9lVDk0BXag7MA8tv/f60XptWnTK1pv/Dobm/CyLmyLae55OuflQ==",
|
||||
"dependencies": {
|
||||
"@lexical/utils": "0.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"lexical": "0.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@lexical/list": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.4.1.tgz",
|
||||
|
@ -1199,6 +1211,14 @@
|
|||
"@lexical/selection": "0.4.1"
|
||||
}
|
||||
},
|
||||
"@lexical/link": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.4.1.tgz",
|
||||
"integrity": "sha512-566lQymmuBe3Y7UDyaaTs+VDlElbu1WhnjT9lVDk0BXag7MA8tv/f60XptWnTK1pv/Dobm/CyLmyLae55OuflQ==",
|
||||
"requires": {
|
||||
"@lexical/utils": "0.4.1"
|
||||
}
|
||||
},
|
||||
"@lexical/list": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.4.1.tgz",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"@exampledev/new.css": "^1.1.3",
|
||||
"@fastify/http-proxy": "^8.2.2",
|
||||
"@lexical/history": "^0.4.1",
|
||||
"@lexical/link": "^0.4.1",
|
||||
"@lexical/rich-text": "^0.4.1",
|
||||
"@tsconfig/node18-strictest-esm": "^1.0.1",
|
||||
"esbuild": "^0.15.7",
|
||||
|
|
|
@ -11,11 +11,13 @@ import {
|
|||
HeadingNode,
|
||||
registerRichText,
|
||||
} from "@lexical/rich-text";
|
||||
import { $createAutoLinkNode, AutoLinkNode } from "@lexical/link";
|
||||
import { onCleanup, onMount } from "solid-js";
|
||||
import type Pages from "../../protocol/pages";
|
||||
import "./editor.css";
|
||||
|
||||
const editor = createEditor({ nodes: [HeadingNode] });
|
||||
const urlMatcher = /https?:\/\/[^\s]+/;
|
||||
const editor = createEditor({ nodes: [HeadingNode, AutoLinkNode] });
|
||||
|
||||
function ref(el: HTMLElement) {
|
||||
editor.setRootElement(el);
|
||||
|
@ -29,12 +31,26 @@ export default (props: {
|
|||
}) => {
|
||||
const initialEditorState = () => {
|
||||
const root = $getRoot();
|
||||
for (const [i, text] of props.text.split("\n").entries()) {
|
||||
const line = i === 0 ? $createHeadingNode("h2") : $createParagraphNode();
|
||||
const indent = text.match(/^\s*/)?.[0]?.length ?? 0;
|
||||
line.setIndent(indent);
|
||||
line.append($createTextNode(text.slice(indent)));
|
||||
root.append(line);
|
||||
const [title, ...lines] = props.text.split("\n");
|
||||
const titleNode = $createHeadingNode("h2");
|
||||
titleNode.append($createTextNode(title));
|
||||
root.append(titleNode);
|
||||
for (const line of lines) {
|
||||
const lineNode = $createParagraphNode();
|
||||
const indent = line.match(/^\s*/)?.[0]?.length ?? 0;
|
||||
lineNode.setIndent(indent);
|
||||
let text = line.slice(indent);
|
||||
let match: RegExpMatchArray | null = null;
|
||||
while ((match = text.match(urlMatcher))) {
|
||||
const offset = text.slice(0, match.index!);
|
||||
const input = match[0]!;
|
||||
const link = $createAutoLinkNode(input);
|
||||
link.append($createTextNode(match[0]));
|
||||
lineNode.append($createTextNode(offset), link);
|
||||
text = text.slice(offset.length + input.length);
|
||||
}
|
||||
lineNode.append($createTextNode(text));
|
||||
root.append(lineNode);
|
||||
}
|
||||
};
|
||||
onCleanup(registerRichText(editor, initialEditorState));
|
||||
|
@ -64,5 +80,17 @@ export default (props: {
|
|||
)
|
||||
);
|
||||
onMount(() => editor.focus());
|
||||
return <article ref={ref} class="editor" contenteditable />;
|
||||
return (
|
||||
<article
|
||||
ref={ref}
|
||||
onclick={(e) => {
|
||||
const el = e.target.parentElement;
|
||||
if (el instanceof HTMLAnchorElement) {
|
||||
window.open(el.href, "_blank", "noreferrer");
|
||||
}
|
||||
}}
|
||||
class="editor"
|
||||
contenteditable
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue