Skip to content

Commit 0f8ce3d

Browse files
authored
refactor: return jsx element instead of string in marked (#910)
* refactor: return jsx element instead of string in marked * chore: update
1 parent 491859b commit 0f8ce3d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+417
-637
lines changed

web/src/components/CreateTagDialog.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { TextField } from "@mui/joy";
22
import React, { useEffect, useState } from "react";
33
import { useTagStore } from "../store/module";
44
import { getTagSuggestionList } from "../helpers/api";
5+
import { matcher } from "../labs/marked/matcher";
56
import Tag from "../labs/marked/parser/Tag";
67
import Icon from "./Icon";
78
import toastHelper from "./Toast";
@@ -10,7 +11,7 @@ import { generateDialog } from "./Dialog";
1011
type Props = DialogProps;
1112

1213
const validateTagName = (tagName: string): boolean => {
13-
const matchResult = Tag.matcher(`#${tagName}`);
14+
const matchResult = matcher(`#${tagName}`, Tag.regexp);
1415
if (!matchResult || matchResult[1] !== tagName) {
1516
return false;
1617
}

web/src/components/Memo.tsx

+1-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import "../less/memo.less";
1515

1616
interface Props {
1717
memo: Memo;
18-
highlightWord?: string;
1918
}
2019

2120
export const getFormatedMemoTimeStr = (time: number, locale = "en"): string => {
@@ -27,7 +26,7 @@ export const getFormatedMemoTimeStr = (time: number, locale = "en"): string => {
2726
};
2827

2928
const Memo: React.FC<Props> = (props: Props) => {
30-
const { memo, highlightWord } = props;
29+
const { memo } = props;
3130
const { t, i18n } = useTranslation();
3231
const navigate = useNavigate();
3332
const editorStore = useEditorStore();
@@ -143,9 +142,6 @@ const Memo: React.FC<Props> = (props: Props) => {
143142
if (imgUrl) {
144143
showPreviewImageDialog([imgUrl], 0);
145144
}
146-
} else if (targetEl.tagName === "BUTTON" && targetEl.className === "codeblock-copy-btn") {
147-
copy(targetEl.parentElement?.children[1].textContent ?? "");
148-
toastHelper.success(t("message.succeed-copy-code"));
149145
}
150146
};
151147

@@ -228,7 +224,6 @@ const Memo: React.FC<Props> = (props: Props) => {
228224
</div>
229225
<MemoContent
230226
content={memo.content}
231-
highlightWord={highlightWord}
232227
onMemoContentClick={handleMemoContentClick}
233228
onMemoContentDoubleClick={handleMemoContentDoubleClick}
234229
/>

web/src/components/MemoContent.tsx

+7-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useEffect, useMemo, useRef, useState } from "react";
22
import { useTranslation } from "react-i18next";
33
import { useUserStore } from "../store/module";
44
import { marked } from "../labs/marked";
5-
import { highlightWithWord } from "../labs/highlighter";
65
import Icon from "./Icon";
76
import "../less/memo-content.less";
87

@@ -12,7 +11,6 @@ export interface DisplayConfig {
1211

1312
interface Props {
1413
content: string;
15-
highlightWord?: string;
1614
className?: string;
1715
displayConfig?: Partial<DisplayConfig>;
1816
onMemoContentClick?: (e: React.MouseEvent) => void;
@@ -30,14 +28,14 @@ const defaultDisplayConfig: DisplayConfig = {
3028
};
3129

3230
const MemoContent: React.FC<Props> = (props: Props) => {
33-
const { className, content, highlightWord, onMemoContentClick, onMemoContentDoubleClick } = props;
31+
const { className, content, onMemoContentClick, onMemoContentDoubleClick } = props;
32+
const { t } = useTranslation();
33+
const userStore = useUserStore();
34+
const user = userStore.state.user;
3435
const foldedContent = useMemo(() => {
3536
const firstHorizontalRuleIndex = content.search(/^---$|^\*\*\*$|^___$/m);
3637
return firstHorizontalRuleIndex !== -1 ? content.slice(0, firstHorizontalRuleIndex) : content;
3738
}, [content]);
38-
const { t } = useTranslation();
39-
const userStore = useUserStore();
40-
const user = userStore.state.user;
4139

4240
const [state, setState] = useState<State>({
4341
expandButtonStatus: -1,
@@ -97,10 +95,9 @@ const MemoContent: React.FC<Props> = (props: Props) => {
9795
className={`memo-content-text ${state.expandButtonStatus === 0 ? "expanded" : ""}`}
9896
onClick={handleMemoContentClick}
9997
onDoubleClick={handleMemoContentDoubleClick}
100-
dangerouslySetInnerHTML={{
101-
__html: highlightWithWord(marked(state.expandButtonStatus === 0 ? foldedContent : content), highlightWord),
102-
}}
103-
></div>
98+
>
99+
{marked(state.expandButtonStatus === 0 ? foldedContent : content)}
100+
</div>
104101
{state.expandButtonStatus !== -1 && (
105102
<div className="expand-btn-container">
106103
<span className={`btn ${state.expandButtonStatus === 0 ? "expand-btn" : "fold-btn"}`} onClick={handleExpandBtnClick}>

web/src/components/MemoList.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const MemoList = () => {
1919
const memoDisplayTsOption = userStore.state.user?.setting.memoDisplayTsOption;
2020
const { memos, isFetching } = memoStore.state;
2121
const [isComplete, setIsComplete] = useState<boolean>(false);
22-
const [highlightWord, setHighlightWord] = useState<string | undefined>("");
2322

2423
const { tag: tagQuery, duration, type: memoType, text: textQuery, shortcutId, visibility } = query ?? {};
2524
const shortcut = shortcutId ? shortcutStore.getShortcutById(shortcutId) : null;
@@ -107,7 +106,6 @@ const MemoList = () => {
107106
if (pageWrapper) {
108107
pageWrapper.scrollTo(0, 0);
109108
}
110-
setHighlightWord(query?.text);
111109
}, [query]);
112110

113111
useEffect(() => {
@@ -136,7 +134,7 @@ const MemoList = () => {
136134
return (
137135
<div className="memo-list-container">
138136
{sortedMemos.map((memo) => (
139-
<Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} highlightWord={highlightWord} />
137+
<Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} />
140138
))}
141139
{isFetching ? (
142140
<div className="status-text-container fetching-tip">

web/src/labs/highlighter/index.ts

-24
This file was deleted.

web/src/labs/marked/index.ts renamed to web/src/labs/marked/index.tsx

+33-11
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1+
import { matcher } from "./matcher";
12
import { blockElementParserList, inlineElementParserList } from "./parser";
23

3-
export const marked = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => {
4+
export const marked = (
5+
markdownStr: string,
6+
blockParsers = blockElementParserList,
7+
inlineParsers = inlineElementParserList
8+
): string | JSX.Element => {
49
for (const parser of blockParsers) {
5-
const matchResult = parser.matcher(markdownStr);
10+
const matchResult = matcher(markdownStr, parser.regexp);
611
if (!matchResult) {
712
continue;
813
}
914
const matchedStr = matchResult[0];
1015
const retainContent = markdownStr.slice(matchedStr.length);
1116

1217
if (parser.name === "br") {
13-
return parser.renderer(matchedStr) + marked(retainContent, blockParsers, inlineParsers);
18+
return (
19+
<>
20+
{parser.renderer(matchedStr)}
21+
{marked(retainContent, blockParsers, inlineParsers)}
22+
</>
23+
);
1424
} else {
1525
if (retainContent === "") {
1626
return parser.renderer(matchedStr);
1727
} else if (retainContent.startsWith("\n")) {
18-
return parser.renderer(matchedStr) + marked(retainContent.slice(1), blockParsers, inlineParsers);
28+
return (
29+
<>
30+
{parser.renderer(matchedStr)}
31+
{marked(retainContent.slice(1), blockParsers, inlineParsers)}
32+
</>
33+
);
1934
}
2035
}
2136
}
@@ -24,7 +39,7 @@ export const marked = (markdownStr: string, blockParsers = blockElementParserLis
2439
let matchedIndex = -1;
2540

2641
for (const parser of inlineParsers) {
27-
const matchResult = parser.matcher(markdownStr);
42+
const matchResult = matcher(markdownStr, parser.regexp);
2843
if (!matchResult) {
2944
continue;
3045
}
@@ -41,17 +56,23 @@ export const marked = (markdownStr: string, blockParsers = blockElementParserLis
4156
}
4257

4358
if (matchedInlineParser) {
44-
const matchResult = matchedInlineParser.matcher(markdownStr);
59+
const matchResult = matcher(markdownStr, matchedInlineParser.regexp);
4560
if (matchResult) {
4661
const matchedStr = matchResult[0];
4762
const matchedLength = matchedStr.length;
4863
const prefixStr = markdownStr.slice(0, matchedIndex);
4964
const suffixStr = markdownStr.slice(matchedIndex + matchedLength);
50-
return marked(prefixStr, [], inlineParsers) + matchedInlineParser.renderer(matchedStr) + marked(suffixStr, [], inlineParsers);
65+
return (
66+
<>
67+
{marked(prefixStr, [], inlineParsers)}
68+
{matchedInlineParser.renderer(matchedStr)}
69+
{marked(suffixStr, [], inlineParsers)}
70+
</>
71+
);
5172
}
5273
}
5374

54-
return markdownStr;
75+
return <>{markdownStr}</>;
5576
};
5677

5778
interface MatchedNode {
@@ -64,7 +85,7 @@ export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
6485

6586
const walkthough = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => {
6687
for (const parser of blockParsers) {
67-
const matchResult = parser.matcher(markdownStr);
88+
const matchResult = matcher(markdownStr, parser.regexp);
6889
if (!matchResult) {
6990
continue;
7091
}
@@ -79,6 +100,7 @@ export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
79100
return walkthough(retainContent, blockParsers, inlineParsers);
80101
} else {
81102
if (retainContent.startsWith("\n")) {
103+
walkthough(matchedStr, [], inlineParsers);
82104
return walkthough(retainContent.slice(1), blockParsers, inlineParsers);
83105
}
84106
}
@@ -88,7 +110,7 @@ export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
88110
let matchedIndex = -1;
89111

90112
for (const parser of inlineParsers) {
91-
const matchResult = parser.matcher(markdownStr);
113+
const matchResult = matcher(markdownStr, parser.regexp);
92114
if (!matchResult) {
93115
continue;
94116
}
@@ -105,7 +127,7 @@ export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
105127
}
106128

107129
if (matchedInlineParser) {
108-
const matchResult = matchedInlineParser.matcher(markdownStr);
130+
const matchResult = matcher(markdownStr, matchedInlineParser.regexp);
109131
if (matchResult) {
110132
const matchedStr = matchResult[0];
111133
const matchedLength = matchedStr.length;

0 commit comments

Comments
 (0)