diff --git a/CHANGELOG.md b/CHANGELOG.md index 28b605f..2ee588f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `inputStyle` and `nativeSpellcheck` options to manage the native language of the browser (Thanks to [@firm1], [#143]). - Group buttons in drop-down lists by adding a sub-option `children` for the items in the toolbar (Thanks to [@firm1], [#141]). +- `sanitizerFunction` option to allow custom HTML sanitizing in the markdown preview (Thanks to [@adamb70], [#147]). ### Changed - Delay before assuming that submit of the form as failed is `autosave.submit_delay` instead of `autosave.delay` (Thanks to [@Situphen], [#139]). - +- Add `watch` task for gulp. ## [2.9.0] - 2020-01-13 ### Added @@ -147,7 +148,7 @@ Project forked from [SimpleMDE](https://github.com/sparksuite/simplemde-markdown [#9]: https://github.com/Ionaru/easy-markdown-editor/issues/9 -[#143]: https://github.com/Ionaru/easy-markdown-editor/pull/132 +[#143]: https://github.com/Ionaru/easy-markdown-editor/pull/143 [#139]: https://github.com/Ionaru/easy-markdown-editor/pull/139 [#132]: https://github.com/Ionaru/easy-markdown-editor/pull/132 [#123]: https://github.com/Ionaru/easy-markdown-editor/pull/123 diff --git a/README.md b/README.md index 87938be..44b4fd9 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ easyMDE.value('New input for **EasyMDE**'); - **hljs**: An injectible instance of [highlight.js](https://github.com/isagalaev/highlight.js). If you don't want to rely on the global namespace (`window.hljs`), you can provide an instance here. Defaults to `undefined`. - **markedOptions**: Set the internal Markdown renderer's [options](https://marked.js.org/#/USING_ADVANCED.md#options). Other `renderingConfig` options will take precedence. - **singleLineBreaks**: If set to `false`, disable parsing GFM single line breaks. Defaults to `true`. + - **sanitizerFunction**: Custom function for sanitizing the HTML output of markdown renderer. - **shortcuts**: Keyboard shortcuts associated with this instance. Defaults to the [array of shortcuts](#keyboard-shortcuts). - **showIcons**: An array of icon names to show. Can be used to show specific icons hidden by default without completely customizing the toolbar. - **spellChecker**: If set to `false`, disable the spell checker. Defaults to `true`. @@ -251,6 +252,10 @@ var editor = new EasyMDE({ renderingConfig: { singleLineBreaks: false, codeSyntaxHighlighting: true, + sanitizerFunction: function(renderedHTML) { + // Using DOMPurify and only allowing tags + return DOMPurify.sanitize(renderedHTML, {ALLOWED_TAGS: ['b']}) + }, }, shortcuts: { drawTable: "Cmd-Alt-T" diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..d4ddd1e --- /dev/null +++ b/example/index.html @@ -0,0 +1,20 @@ + + + + + + + + Example / Preview + + + + + + + + + + \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 6f3faea..60acdab 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -20,6 +20,13 @@ var banner = ['/**', ' */', ''].join('\n'); + +var css_files = [ + './node_modules/codemirror/lib/codemirror.css', + './src/css/*.css', + './node_modules/codemirror-spell-checker/src/css/spell-checker.css', +]; + function lint() { return gulp.src('./src/js/**/*.js') .pipe(eslint()) @@ -37,12 +44,6 @@ function scripts() { } function styles() { - var css_files = [ - './node_modules/codemirror/lib/codemirror.css', - './src/css/*.css', - './node_modules/codemirror-spell-checker/src/css/spell-checker.css', - ]; - return gulp.src(css_files) .pipe(concat('easymde.css')) .pipe(cleanCSS()) @@ -52,7 +53,14 @@ function styles() { .pipe(gulp.dest('./dist/')); } +// Watch for file changes +function watch() { + gulp.watch('./src/js/**/*.js', scripts) + gulp.watch(css_files, styles) +} + var build = gulp.parallel(gulp.series(lint, scripts), styles); gulp.task('default', build); +gulp.task('watch', gulp.series(build, watch)); gulp.task('lint', lint); diff --git a/package-lock.json b/package-lock.json index c135596..7914dd3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,9 +25,9 @@ } }, "@types/codemirror": { - "version": "0.0.82", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.82.tgz", - "integrity": "sha512-EVlPrt1rB256CRTlhNCXXLYaN24n3qZNStM6dRWaV6sUYyJA1SC5hvDSCHEHDg1SB93X8TwAGWRjEVdmUWPHmQ==", + "version": "0.0.85", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.85.tgz", + "integrity": "sha512-ZAVyNzXAHu/mkvvZlq2IYPBjm4X3mEno27epXpBRXwWbX75zAAeGZfubXxft1kWNqBSI2f50kvuJTG+fRwHaNg==", "dev": true, "requires": { "@types/tern": "*" @@ -1035,9 +1035,9 @@ "dev": true }, "codemirror": { - "version": "5.50.2", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.50.2.tgz", - "integrity": "sha512-PPjUsC1oXSM86lunKrw609P1oM0Wu8z9rqzjbeyBYCcx44VL41aUpccdOf1PfAZtTONlmN3sT3p2etLNYa1OGg==" + "version": "5.51.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.51.0.tgz", + "integrity": "sha512-vyuYYRv3eXL0SCuZA4spRFlKNzQAewHcipRQCOKgRy7VNAvZxTKzbItdbCl4S5AgPZ5g3WkHp+ibWQwv9TLG7Q==" }, "codemirror-spell-checker": { "version": "1.1.2", @@ -5907,9 +5907,9 @@ "dev": true }, "typescript": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", - "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==", + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", "dev": true }, "typo-js": { diff --git a/package.json b/package.json index 03a9a95..9884d1e 100644 --- a/package.json +++ b/package.json @@ -19,12 +19,12 @@ "license": "MIT", "author": "Jeroen Akkerman", "dependencies": { - "codemirror": "^5.50.2", + "codemirror": "^5.51.0", "codemirror-spell-checker": "1.1.2", "marked": "^0.8.0" }, "devDependencies": { - "@types/codemirror": "0.0.82", + "@types/codemirror": "0.0.85", "@types/marked": "^0.7.2", "browserify": "^16.5.0", "gulp": "^4.0.2", @@ -35,7 +35,7 @@ "gulp-rename": "^2.0.0", "gulp-terser": "^1.2.0", "gulp-uglify": "^3.0.2", - "typescript": "^3.7.4", + "typescript": "^3.7.5", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^2.0.0" }, diff --git a/src/js/easymde.js b/src/js/easymde.js index c93786e..642dcb5 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -1791,6 +1791,11 @@ EasyMDE.prototype.markdown = function (text) { // Convert the markdown to HTML var htmlText = marked(text); + + // Sanitize HTML + if (this.options.renderingConfig && typeof this.options.renderingConfig.sanitizerFunction === 'function') { + htmlText = this.options.renderingConfig.sanitizerFunction.call(this, htmlText); + } // Edit the HTML anchors to add 'target="_blank"' by default. htmlText = addAnchorTargetBlank(htmlText); diff --git a/types/easymde.d.ts b/types/easymde.d.ts index 8fef851..9391416 100644 --- a/types/easymde.d.ts +++ b/types/easymde.d.ts @@ -58,6 +58,7 @@ declare namespace EasyMDE { codeSyntaxHighlighting?: boolean; hljs?: any; markedOptions?: marked.MarkedOptions; + sanitizerFunction?: (html: string) => string; singleLineBreaks?: boolean; }