Breaks the application when try to edit the code snippet extension beside
While using code snippet syntax in editor and trying to edit extension text beside "```" I'm getting following error:
Cannot read properties of null (reading 'children')
./node_modules/rehype-prism-plus/dist/rehype-prism-plus.es.js:1
> 1 | import{visit as e}from"unist-util-visit";import{toString as t}from"hast-util-to-string";import{filter as r}from"unist-util-filter";import n from"parse-numeric-range";import{refractor as i}from"refractor/lib/common.js";import{refractor as o}from"refractor/lib/all.js";function a(){a=function(e,t){return new r(e,void 0,t)};var e=RegExp.prototype,t=new WeakMap;function r(e,n,i){var o=new RegExp(e,n);return t.set(o,i||t.get(e)),l(o,r.prototype)}function n(e,r){var n=t.get(r);return Object.keys(n).reduce(function(t,r){return t[r]=e[n[r]],t},Object.create(null))}return s(r,RegExp),r.prototype.exec=function(t){var r=e.exec.call(this,t);return r&&(r.groups=n(r,this)),r},r.prototype[Symbol.replace]=function(r,i){if("string"==typeof i){var o=t.get(this);return e[Symbol.replace].call(this,r,i.replace(/\$<([^>]+)>/g,function(e,t){return"$"+o[t]}))}if("function"==typeof i){var a=this;return e[Symbol.replace].call(this,r,function(){var e=arguments;return"object"!=typeof e[e.length-1]&&(e=[].slice.call(e)).push(n(e,a)),i.apply(this,e)})}return e[Symbol.replace].call(this,r,i)},a.apply(this,arguments)}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&l(e,t)}function l(e,t){return l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},l(e,t)}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function c(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return u(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?u(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var p=function e(t){return t.reduce(function(t,r){if("text"===r.type){if(-1===r.value.indexOf("\n"))return t.push(r),t;for(var n,i=r.value.split("\n"),o=c(i.entries());!(n=o()).done;){var a=n.value,s=a[0],l=a[1];t.push({type:"text",value:s===i.length-1?l:l+"\n",position:{start:{line:r.position.start.line+s},end:{line:r.position.start.line+s}}})}return t}return Object.prototype.hasOwnProperty.call(r,"children")?(r.children=e(r.children),t.push(r),t):(t.push(r),t)},[])},f=function(i){return function(o){return void 0===o&&(o={}),function(t){e(t,"element",s)};function s(e,s,l){if(l&&"pre"===l.tagName&&"code"===e.tagName){var u=e.data&&e.data.meta?e.data.meta:"";e.properties.className?"boolean"==typeof e.properties.className?e.properties.className=[]:Array.isArray(e.properties.className)||(e.properties.className=[e.properties.className]):e.properties.className=[],e.properties.className.push("code-highlight");var f,h=function(e){for(var t,r=c(e.properties.className);!(t=r()).done;){var n=t.value;if("language-"===n.slice(0,9))return n.slice(9).toLowerCase()}return null}(e);if(h)try{f=i.highlight(t(e),h),l.properties.className=(l.properties.className||[]).concat("language-"+h)}catch(t){if(!o.ignoreMissing||!/Unknown language/.test(t.message))throw t;f=e}else f=e;var m,d=(m=1,function e(t){return t.reduce(function(t,r){if("text"===r.type){var n=(r.value.match(/\n/g)||"").length;return r.position={start:{line:m,column:0},end:{line:m+n,column:0}},m+=n,t.push(r),t}if(Object.prototype.hasOwnProperty.call(r,"children")){var i=m;return r.children=e(r.children),t.push(r),r.position={start:{line:i,column:0},end:{line:m,column:0}},t}return t.push(r),t},[])})(f.children);f.children=p(d),f.children.length>0&&(f.position={start:{line:f.children[0].position.start.line,column:0},end:{line:f.children[f.children.length-1].position.end.line,column:0}});for(var g,y,v=function(e){var t=/{([\d,-]+)}/,r=e.split(",").map(function(e){return e.trim()}).join();if(t.test(r)){var i=t.exec(r)[1],o=n(i);return function(e){return o.includes(e+1)}}return function(){return!1}}(u),b=function(e){var t=/*#__PURE__*/a(/showLineNumbers=([0-9]+)/i,{lines:1});if(t.test(e)){var r=t.exec(e);return Number(r.groups.lines)}return 1}(u),N=(""===(g=t(e).split(/\n/))[g.length-1].trim()&&g.pop(),g.map(function(e){return{type:"element",tagName:"span",properties:{className:["code-line"]},children:[{type:"text",value:e}]}})),w=function(){var e=y.value,n=e[0],i=e[1];(u.toLowerCase().includes("showLineNumbers".toLowerCase())||o.showLineNumbers)&&(i.properties.line=[(n+b).toString()],i.properties.className.push("line-number")),v(n)&&i.properties.className.push("highlight-line"),"diff"===h&&"-"===t(i).substring(0,1)?i.properties.className.push("deleted"):"diff"===h&&"+"===t(i).substring(0,1)&&i.properties.className.push("inserted");var a=r(f,function(e){return e.position.start.line<=n+1&&e.position.end.line>=n+1});i.children=a.children},x=c(N.entries());!(y=x()).done;)w();e.children=N}}}},h=f(i),m=f(o);export{m as default,h as rehypePrismCommon,f as rehypePrismGenerator};
| ^
2 | //# sourceMappingURL=rehype-prism-plus.es.js.map
3 |
This happens when user try to edit "```jsx" part inside the editor:
// (Sometimes when I try to edit/remove `"```jsx"` in the following line it breaks the application and gives the above error)
```jsx
import React from "react";
import MDEditor from '@uiw/react-md-editor';
export default function App() {
const [value, setValue] = React.useState("**Hello world!!!**");
return (
<div className="container">
<MDEditor
value={value}
onChange={setValue}
/>
<MDEditor.Markdown source={value} style={{ whiteSpace: 'pre-wrap' }} />
</div>
);
}
Also the code snippets are not getting highlighted in my markdown preview.
NOTE: Your own website is also crashing due to the same issue.Kindly open https://uiwjs.github.io/react-md-editor/ and try to edit the following part:
https://user-images.githubusercontent.com/62889697/173334753-23d79d78-cdca-4d23-9c8b-eb2abe9220fe.mp4
@wajeshubham Fixed this, but not perfect.
Ok thanks @jaywcjlove
@jaywcjlove I'm still facing a highlighting issue for code

Please let me know if I'm missing something.
export const MdComp: React.FC<Props> = ({ source, className }) => {
return (
<MDEditor.Markdown
className={className}
source={source}
rehypePlugins={[[rehypeSanitize]]}
linkTarget="_blank"
/>
);
};
@wajeshubham https://codesandbox.io/embed/markdown-editor-for-react-uiwjs-react-md-editor-issues-406-44qb3y?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import ReactDOM from "react-dom";
import MDEditor from "@uiw/react-md-editor";
// No import is required in the WebPack.
// import "@uiw/react-md-editor/dist/markdown-editor.css";
const mkdStr = `# Markdown Editor for [React](https://facebook.github.io/react/)
**Hello world!!!**
[](https://avatars.githubusercontent.com/u/1680273?v=4)
\`\`\`javascript
import React from "react";
import ReactDOM from "react-dom";
import MEDitor from '@uiw/react-md-editor';
\`\`\`
\`\`\`jsx
export const MdComp: React.FC<Props> = ({ source, className }) => {
return (
<MDEditor.Markdown
className={className}
source={source}
rehypePlugins={[[rehypeSanitize]]}
linkTarget="_blank"
/>
);
};
\`\`\`
`;
function App() {
return (
<div className="container">
<MDEditor.Markdown
style={{ padding: 15 }}
source={mkdStr}
linkTarget="_blank"
// previewOptions={{
// linkTarget: "_blank"
// }}
/>
</div>
);
}
Removing rehypePlugins prop resolves the issue. But isn't it insecure? do you have any other secure way for the same?
https://codesandbox.io/embed/markdown-editor-for-react-uiwjs-react-md-editor-issues-406-44qb3y?fontsize=14&hidenavigation=1&theme=dark @wajeshubham
import React from "react";
import ReactDOM from "react-dom";
import MDEditor from "@uiw/react-md-editor";
import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
// No import is required in the WebPack.
// import "@uiw/react-md-editor/dist/markdown-editor.css";
const mkdStr = `# Markdown Editor for [React](https://facebook.github.io/react/)
**Hello world!!!**
[](https://avatars.githubusercontent.com/u/1680273?v=4)
\`\`\`javascript
import React from "react";
import ReactDOM from "react-dom";
import MEDitor from '@uiw/react-md-editor';
\`\`\`
\`\`\`jsx
export const MdComp: React.FC<Props> = ({ source, className }) => {
return (
<MDEditor.Markdown
className={className}
source={source}
rehypePlugins={[[rehypeSanitize]]}
linkTarget="_blank"
/>
);
};
\`\`\`
`;
function App() {
return (
<div className="container">
<MDEditor.Markdown
style={{ padding: 15 }}
source={mkdStr}
linkTarget="_blank"
// rehypePlugins={[[rehypeSanitize]]}
pluginsFilter={(type, plugin) => {
if (type === "rehype") {
// plugin.push(rehypeSanitize);
plugin.unshift([
rehypeSanitize,
{
...defaultSchema,
attributes: {
...defaultSchema.attributes,
code: [
...(defaultSchema.attributes.code || []),
// List of all allowed languages:
[
"className",
"language-jsx",
"language-javascript",
"language-jsx",
"language-js",
"language-css",
"language-md"
]
]
}
}
]);
console.log(plugin);
}
return plugin;
}}
// previewOptions={{
// linkTarget: "_blank"
// }}
/>
</div>
);
}
Thanks @jaywcjlove. Last question, how much secure is the rehypen plugin? Do we need to use something like dompurify to stay away from the XSS attacks? or rehypen plugin is alone secure to do so?
I'm not sure how safe it is, you can ask here: https://www.npmjs.com/package/rehype-sanitize
@wajeshubham