diff --git a/web/markdown/markdown-spoiler.react.js b/web/markdown/markdown-spoiler.react.js
new file mode 100644
index 000000000..1a3016957
--- /dev/null
+++ b/web/markdown/markdown-spoiler.react.js
@@ -0,0 +1,21 @@
+// @flow
+
+import * as React from 'react';
+
+import type { ReactElement } from 'lib/shared/markdown';
+
+type MarkdownSpoilerProps = {
+ +text: ReactElement,
+};
+
+function MarkdownSpoiler(props: MarkdownSpoilerProps): React.Node {
+ const { text } = props;
+
+ return {text};
+}
+
+const MemoizedMarkdownSpoiler: React.ComponentType = React.memo(
+ MarkdownSpoiler,
+);
+
+export default MemoizedMarkdownSpoiler;
diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js
index 7a668ac59..a27a84bee 100644
--- a/web/markdown/rules.react.js
+++ b/web/markdown/rules.react.js
@@ -1,210 +1,213 @@
// @flow
import _memoize from 'lodash/memoize';
import * as React from 'react';
import * as SimpleMarkdown from 'simple-markdown';
import { relativeMemberInfoSelectorForMembersOfThread } from 'lib/selectors/user-selectors';
import * as SharedMarkdown from 'lib/shared/markdown';
import type { RelativeMemberInfo } from 'lib/types/thread-types';
import { useSelector } from '../redux/redux-utils';
+import MarkdownSpoiler from './markdown-spoiler.react';
export type MarkdownRules = {
+simpleMarkdownRules: SharedMarkdown.ParserRules,
+useDarkStyle: boolean,
};
const linkRules: boolean => MarkdownRules = _memoize(useDarkStyle => {
const simpleMarkdownRules = {
// We are using default simple-markdown rules
// For more details, look at native/markdown/rules.react
link: {
...SimpleMarkdown.defaultRules.link,
match: () => null,
// eslint-disable-next-line react/display-name
react: (
node: SharedMarkdown.SingleASTNode,
output: SharedMarkdown.Output,
state: SharedMarkdown.State,
) => (
{output(node.content, state)}
),
},
paragraph: {
...SimpleMarkdown.defaultRules.paragraph,
match: SimpleMarkdown.blockRegex(SharedMarkdown.paragraphRegex),
// eslint-disable-next-line react/display-name
react: (
node: SharedMarkdown.SingleASTNode,
output: SharedMarkdown.Output,
state: SharedMarkdown.State,
) => (
{output(node.content, state)}
),
},
text: SimpleMarkdown.defaultRules.text,
url: {
...SimpleMarkdown.defaultRules.url,
match: SimpleMarkdown.inlineRegex(SharedMarkdown.urlRegex),
},
};
return {
simpleMarkdownRules: simpleMarkdownRules,
useDarkStyle,
};
});
const markdownRules: boolean => MarkdownRules = _memoize(useDarkStyle => {
const linkMarkdownRules = linkRules(useDarkStyle);
const simpleMarkdownRules = {
...linkMarkdownRules.simpleMarkdownRules,
autolink: SimpleMarkdown.defaultRules.autolink,
link: {
...linkMarkdownRules.simpleMarkdownRules.link,
match: SimpleMarkdown.defaultRules.link.match,
},
blockQuote: {
...SimpleMarkdown.defaultRules.blockQuote,
// match end of blockQuote by either \n\n or end of string
match: SharedMarkdown.matchBlockQuote(SharedMarkdown.blockQuoteRegex),
parse: SharedMarkdown.parseBlockQuote,
},
spoiler: {
order: SimpleMarkdown.defaultRules.paragraph.order - 1,
match: SimpleMarkdown.inlineRegex(SharedMarkdown.spoilerRegex),
parse(
capture: SharedMarkdown.Capture,
parse: SharedMarkdown.Parser,
state: SharedMarkdown.State,
) {
const content = capture[1];
return {
content: SimpleMarkdown.parseInline(parse, content, state),
};
},
// eslint-disable-next-line react/display-name
react: (
node: SharedMarkdown.SingleASTNode,
output: SharedMarkdown.Output,
state: SharedMarkdown.State,
- ) => {output(node.content, state)},
+ ) => (
+
+ ),
},
inlineCode: SimpleMarkdown.defaultRules.inlineCode,
em: SimpleMarkdown.defaultRules.em,
strong: SimpleMarkdown.defaultRules.strong,
del: SimpleMarkdown.defaultRules.del,
u: SimpleMarkdown.defaultRules.u,
heading: {
...SimpleMarkdown.defaultRules.heading,
match: SimpleMarkdown.blockRegex(SharedMarkdown.headingRegex),
},
mailto: SimpleMarkdown.defaultRules.mailto,
codeBlock: {
...SimpleMarkdown.defaultRules.codeBlock,
match: SimpleMarkdown.blockRegex(SharedMarkdown.codeBlockRegex),
parse: (capture: SharedMarkdown.Capture) => ({
content: capture[0].replace(/^ {4}/gm, ''),
}),
},
fence: {
...SimpleMarkdown.defaultRules.fence,
match: SimpleMarkdown.blockRegex(SharedMarkdown.fenceRegex),
parse: (capture: SharedMarkdown.Capture) => ({
type: 'codeBlock',
content: capture[2],
}),
},
json: {
order: SimpleMarkdown.defaultRules.paragraph.order - 1,
match: (source: string, state: SharedMarkdown.State) => {
if (state.inline) {
return null;
}
return SharedMarkdown.jsonMatch(source);
},
parse: (capture: SharedMarkdown.Capture) => {
const jsonCapture: SharedMarkdown.JSONCapture = (capture: any);
return {
type: 'codeBlock',
content: SharedMarkdown.jsonPrint(jsonCapture),
};
},
},
list: {
...SimpleMarkdown.defaultRules.list,
match: SharedMarkdown.matchList,
parse: SharedMarkdown.parseList,
},
escape: SimpleMarkdown.defaultRules.escape,
};
return {
...linkMarkdownRules,
simpleMarkdownRules,
useDarkStyle,
};
});
function useTextMessageRulesFunc(
threadID: ?string,
): ?(boolean) => MarkdownRules {
const threadMembers = useSelector(
relativeMemberInfoSelectorForMembersOfThread(threadID),
);
return React.useMemo(() => {
if (!threadMembers) {
return undefined;
}
return _memoize<[boolean], MarkdownRules>((useDarkStyle: boolean) =>
textMessageRules(threadMembers, useDarkStyle),
);
}, [threadMembers]);
}
function textMessageRules(
members: $ReadOnlyArray,
useDarkStyle: boolean,
): MarkdownRules {
const baseRules = markdownRules(useDarkStyle);
return {
...baseRules,
simpleMarkdownRules: {
...baseRules.simpleMarkdownRules,
mention: {
...SimpleMarkdown.defaultRules.strong,
match: SharedMarkdown.matchMentions(members),
parse: (capture: SharedMarkdown.Capture) => ({
content: capture[0],
}),
// eslint-disable-next-line react/display-name
react: (
node: SharedMarkdown.SingleASTNode,
output: SharedMarkdown.Output,
state: SharedMarkdown.State,
) => {node.content},
},
},
};
}
let defaultTextMessageRules = null;
function getDefaultTextMessageRules(): MarkdownRules {
if (!defaultTextMessageRules) {
defaultTextMessageRules = textMessageRules([], false);
}
return defaultTextMessageRules;
}
export { linkRules, useTextMessageRulesFunc, getDefaultTextMessageRules };