Skip to content

Commit 2a402c4

Browse files
committed
fix(deps): update dependency react-markdown to v5
1 parent ceb7297 commit 2a402c4

File tree

4 files changed

+119
-137
lines changed

4 files changed

+119
-137
lines changed

README.md

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -39,56 +39,68 @@ function Demo() {
3939
```typescript
4040
import { ReactMarkdownProps } from 'react-markdown';
4141

42-
interface IMarkdownPreviewProps extends Omit<ReactMarkdownProps, 'className'> {
43-
prefixCls?: string;
42+
type MarkdownPreviewProps = {
4443
className?: string;
44+
source?: string;
4545
style?: React.CSSProperties;
4646
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
4747
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;
48-
}
48+
} & ReactMarkdownProps;
4949
```
5050

51-
This [`ReactMarkdownProps`](https://github.com/rexxars/react-markdown/blob/2d991aa1097e95064f0209fc6d3a15b6300c07c7/index.d.ts#L76-L95) details.
52-
53-
- `source` or `children` - _string_ The Markdown source to parse (**required**)
54-
- `className` - _string_ Class name of the container element. If none is passed, a container will not be rendered.
55-
- `escapeHtml` - _boolean_ Setting to `false` will cause HTML to be rendered (see notes below about proper HTML support). Be aware that setting this to `false` might cause security issues if the
56-
input is user-generated. Use at your own risk. (default: `true`).
57-
- `skipHtml` - _boolean_ Setting to `true` will skip inlined and blocks of HTML (default: `false`).
58-
- `sourcePos` - _boolean_ Setting to `true` will add `data-sourcepos` attributes to all elements,
59-
indicating where in the markdown source they were rendered from (default: `false`).
60-
- `rawSourcePos` - _boolean_ Setting to `true` will pass a `sourcePosition` property to all renderers with structured source position information (default: `false`).
61-
- `includeNodeIndex` - _boolean_ Setting to `true` will pass `index` and `parentChildCount` props to all renderers (default: `false`).
62-
- `allowedTypes` - _array_ Defines which types of nodes should be allowed (rendered). (default: all
63-
types).
64-
- `disallowedTypes` - _array_ Defines which types of nodes should be disallowed (not rendered).
65-
(default: none).
66-
- `unwrapDisallowed` - _boolean_ Setting to `true` will try to extract/unwrap the children of
67-
disallowed nodes. For instance, if disallowing `Strong`, the default behaviour is to simply skip
68-
the text within the strong altogether, while the behaviour some might want is to simply have the
69-
text returned without the strong wrapping it. (default: `false`)
70-
- `allowNode` - _function_ Function execute if in order to determine if the node should be allowed.
71-
Ran prior to checking `allowedTypes`/`disallowedTypes`. Returning a truthy value will allow the
72-
node to be included. Note that if this function returns `true` and the type is not in
73-
`allowedTypes` (or specified as a `disallowedType`), it won't be included. The function will
74-
receive three arguments argument (`node`, `index`, `parent`), where `node` contains different
75-
properties depending on the node type.
76-
- `linkTarget` - _function|string_ Sets the default target attribute for links. If a function is
77-
provided, it will be called with `url`, `text`, and `title` and should return a string
78-
(e.g. `_blank` for a new tab). Default is `undefined` (no target attribute).
79-
- `transformLinkUri` - _function|null_ Function that gets called for each encountered link with a
80-
single argument - `uri`. The returned value is used in place of the original. The default link URI
81-
transformer acts as an XSS-filter, neutralizing things like `javascript:`, `vbscript:` and `file:`
82-
protocols. If you specify a custom function, this default filter won't be called, but you can
83-
access it as `require('react-markdown').uriTransformer`. If you want to disable the default
84-
transformer, pass `null` to this option.
85-
- `transformImageUri` - _function|null_ Function that gets called for each encountered image with a
86-
single argument - `uri`. The returned value is used in place of the original.
87-
- `renderers` - _object_ An object where the keys represent the node type and the value is a React
88-
component. The object is merged with the default renderers. The props passed to the component
89-
varies based on the type of node.
90-
91-
See [Options Props](https://github.com/rexxars/react-markdown/tree/2d991aa1097e95064f0209fc6d3a15b6300c07c7#options) for more details.
51+
This [`ReactMarkdownProps`](https://github.com/remarkjs/react-markdown/blob/22bb78747d768181cb9ea8711b5e13c3768921d8/index.d.ts#L32-L84) details.
52+
53+
- `source` (`string`, default: `''`)\
54+
Markdown to parse
55+
- `className` (`string?`)\
56+
Wrap the markdown in a `div` with this class name
57+
- `allowDangerousHtml` (`boolean`, default: `false`)\
58+
This project is safe by default and escapes HTML.
59+
Use `allowDangerousHtml: true` to allow dangerous html instead.
60+
See [security](https://github.com/remarkjs/react-markdown/tree/22bb78747d768181cb9ea8711b5e13c3768921d8#security)
61+
- `skipHtml` (`boolean`, default: `false`)\
62+
Ignore HTML in Markdown
63+
- `sourcePos` (`boolean`, default: `false`)\
64+
Pass a prop to all renderers with a serialized position
65+
(`data-sourcepos="3:1-3:13"`)
66+
- `rawSourcePos` (`boolean`, default: `false`)\
67+
Pass a prop to all renderers with their [position](https://github.com/syntax-tree/unist#position)
68+
(`sourcePosition: {start: {line: 3, column: 1}, end:…}`)
69+
- `includeNodeIndex` (`boolean`, default: `false`)\
70+
Pass [`index`](https://github.com/syntax-tree/unist#index) and `parentChildCount` in props to all renderers
71+
- `allowedTypes` (`Array.<string>`, default: list of all types)\
72+
Node types to allow (can’t combine w/ `disallowedTypes`).
73+
All types are available at `ReactMarkdown.types`
74+
- `disallowedTypes` (`Array.<string>`, default: `[]`)\
75+
Node types to disallow (can’t combine w/ `allowedTypes`)
76+
- `allowNode` (`(node, index, parent) => boolean?`, optional)\
77+
Function called to check if a node is allowed (when truthy) or not.
78+
`allowedTypes` / `disallowedTypes` is used first!
79+
- `unwrapDisallowed` (`boolean`, default: `false`)\
80+
Extract (unwrap) the children of not allowed nodes.
81+
By default, when `strong` is not allowed, it and it’s content is dropped,
82+
but with `unwrapDisallowed` the node itself is dropped but the content used
83+
- `linkTarget` (`string` or `(url, text, title) => string`, optional)\
84+
Target to use on links (such as `_blank` for `<a target="_blank"…`)
85+
- `transformLinkUri` (`(uri) => string`, default:
86+
[`./uri-transformer.js`][uri], optional)\
87+
URL to use for links.
88+
The default allows only `http`, `https`, `mailto`, and `tel`, and is
89+
available at `ReactMarkdown.uriTransformer`.
90+
Pass `null` to allow all URLs.
91+
See [security](https://github.com/remarkjs/react-markdown/tree/22bb78747d768181cb9ea8711b5e13c3768921d8#security)
92+
- `transformImageUri` (`(uri) => string`, default:
93+
[`./uri-transformer.js`][uri], optional)\
94+
Same as `transformLinkUri` but for images
95+
- `renderers` (`Object.<Component>`, default: `{}`)\
96+
Object mapping node types to React components.
97+
Merged with the default renderers (available at `ReactMarkdown.renderers`).
98+
Which props are passed varies based on the node
99+
- `plugins` (`Array.<Plugin>`, default: `[]`)\
100+
List of [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins) to use.
101+
See the next section for examples on how to pass options
102+
103+
See [Options Props](https://github.com/remarkjs/react-markdown/tree/22bb78747d768181cb9ea8711b5e13c3768921d8#props) for more details.
92104

93105
## Development
94106

package.json

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,25 @@
4343
"react-dom": ">=16.8.0"
4444
},
4545
"dependencies": {
46-
"@babel/runtime": "7.11.2",
47-
"@types/prismjs": "1.16.1",
48-
"prismjs": "1.21.0",
49-
"react-markdown": "4.3.1"
46+
"@babel/runtime": "7.12.5",
47+
"@types/prismjs": "1.16.2",
48+
"prismjs": "1.22.0",
49+
"remark-gfm": "1.0.0",
50+
"react-markdown": "5.0.2"
5051
},
5152
"devDependencies": {
52-
"@kkt/loader-less": "5.9.0",
53-
"@kkt/loader-raw": "5.9.0",
54-
"@types/react": "16.9.46",
55-
"@types/react-dom": "16.9.8",
53+
"@kkt/loader-less": "5.10.3",
54+
"@kkt/loader-raw": "5.10.3",
55+
"@types/react": "16.14.2",
56+
"@types/react-dom": "16.9.10",
5657
"@uiw/react-github-corners": "1.2.0",
5758
"@uiw/react-shields": "1.1.0",
5859
"@uiw/reset.css": "1.0.4",
5960
"compile-less-cli": "1.5.1",
60-
"kkt": "5.9.0",
61-
"react": "16.13.1",
62-
"react-dom": "16.13.1",
63-
"tsbb": "1.7.7"
61+
"kkt": "5.10.3",
62+
"react": "16.14.0",
63+
"react-dom": "16.14.0",
64+
"tsbb": "1.7.8"
6465
},
6566
"eslintConfig": {
6667
"extends": "react-app"

src/allowNode.tsx

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/index.tsx

Lines changed: 50 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,69 @@
1-
import React, { Component } from 'react';
1+
import React, { useEffect } from 'react';
2+
import ReactMarkdown, { ReactMarkdownProps } from 'react-markdown';
3+
import gfm from 'remark-gfm';
24
import Prism from 'prismjs';
35
import 'prismjs/components/prism-markup';
4-
import ReactMarkdown, { ReactMarkdownProps } from 'react-markdown';
5-
import allowNode from './allowNode';
66
import { loadLang } from './langs';
77
import './styles/markdown.less';
88
import './styles/markdowncolor.less';
99

10-
export type {
11-
ReactMarkdownProps,
12-
MarkdownAbstractSyntaxTree,
13-
NodeType,
14-
RemarkParseOptions,
15-
Position,
16-
Point,
17-
AlignType,
18-
ReferenceType,
19-
LinkTargetResolver,
20-
Renderers,
21-
} from 'react-markdown';
22-
23-
export interface IMarkdownPreviewProps extends Omit<ReactMarkdownProps, 'className'> {
24-
prefixCls?: string;
10+
export type MarkdownPreviewProps = {
2511
className?: string;
12+
source?: string;
2613
style?: React.CSSProperties;
2714
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
2815
onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;
29-
}
16+
} & ReactMarkdownProps;
3017

31-
export interface IMarkdownPreviewState {
32-
value?: string;
33-
}
18+
const MarkdownPreview: React.FC<MarkdownPreviewProps> = (props = {} as ReactMarkdownProps) => {
19+
const { className, source, style, onScroll, onMouseOver, ...other } = props;
20+
const mdp = React.createRef<HTMLDivElement>();
21+
const loadedLang = React.useRef<string[]>(['markup']);
22+
useEffect(() => {
23+
highlight();
24+
// eslint-disable-next-line react-hooks/exhaustive-deps
25+
}, [source]);
3426

35-
export default class MarkdownPreview extends Component<IMarkdownPreviewProps, IMarkdownPreviewState> {
36-
public mdp = React.createRef<HTMLDivElement>();
37-
public loadedLang: string[] = ['markup'];
38-
public static defaultProps: IMarkdownPreviewProps = {
39-
renderers: {},
40-
}
41-
public constructor(props: IMarkdownPreviewProps) {
42-
super(props);
43-
this.state = {
44-
value: '' || props.source,
45-
};
46-
}
47-
componentDidMount() {
48-
this.highlight();
49-
}
50-
componentDidUpdate(prevProps: IMarkdownPreviewProps) {
51-
if (this.props.source !== prevProps.source) {
52-
this.setState({ value: this.props.source }, () => {
53-
this.highlight();
54-
});
55-
}
56-
}
57-
public renderHTML(mdStr?: string) {
58-
this.setState({ value: mdStr }, () => {
59-
this.highlight();
60-
});
61-
}
62-
public async highlight() {
63-
if (!this.mdp.current) return;
64-
const codes = this.mdp.current.getElementsByTagName('code') as unknown as HTMLElement[];
65-
for (const value of codes) {
66-
const tag = value.parentNode as HTMLElement;
67-
if (tag && tag.tagName === 'PRE' && /^language-/.test(value.className.trim())) {
68-
const lang = value.className.trim().replace(/^language-/, '');
27+
async function highlight() {
28+
if (!mdp.current) return;
29+
const codes = mdp.current.getElementsByTagName('code') as unknown as HTMLElement[];
30+
for (const val of codes) {
31+
const tag = val.parentNode as HTMLElement;
32+
if (tag && tag.tagName === 'PRE' && /^language-/.test(val.className.trim())) {
33+
const lang = val.className.trim().replace(/^language-/, '');
6934
try {
70-
if (!this.loadedLang.includes(lang as never)) {
71-
this.loadedLang.push(lang);
35+
if (!loadedLang.current.includes(lang as never)) {
36+
loadedLang.current.push(lang);
7237
await loadLang(lang);
7338
}
74-
await Prism.highlightElement(value);
39+
await Prism.highlightElement(val);
7540
} catch (error) { }
7641
}
7742
}
7843
}
79-
render() {
80-
const { className, style, onScroll, onMouseOver, ...other } = this.props;
81-
const cls = `wmde-markdown wmde-markdown-color ${className || ''}`;
82-
return (
83-
<div ref={this.mdp} onScroll={onScroll} style={style} onMouseOver={onMouseOver} className={cls} >
84-
<ReactMarkdown escapeHtml={false} allowNode={allowNode} {...other} source={this.state.value} />
85-
</div>
86-
);
87-
}
88-
}
44+
45+
const cls = `wmde-markdown wmde-markdown-color ${className || ''}`;
46+
const reactMarkdownProps = {
47+
allowDangerousHtml: true,
48+
...other,
49+
plugins: [gfm, ...(other.plugins || [])],
50+
allowNode: (node, index, parent) => {
51+
const nodeany = node;
52+
if (nodeany.type === 'html' && reactMarkdownProps.allowDangerousHtml) {
53+
// filter style
54+
node.value = (node.value as string).replace(/<((style|script|link|input|form)|\/(style|script|link|input|form))(\s?[^>]*>)/gi, (a: string) => {
55+
return a.replace(/[<>]/g, (e: string) => (({ '<': '&lt;', '>': '&gt;' } as { [key: string]: string })[e]))
56+
});
57+
}
58+
return true;
59+
},
60+
source: source || '',
61+
} as ReactMarkdownProps;
62+
return (
63+
<div ref={mdp} onScroll={onScroll} onMouseOver={onMouseOver} className={cls} style={style}>
64+
<ReactMarkdown {...reactMarkdownProps} />
65+
</div>
66+
);
67+
}
68+
69+
export default MarkdownPreview;

0 commit comments

Comments
 (0)