diff --git a/src/main/preferences/schema.json b/src/main/preferences/schema.json
index ddf2fff2..f0010599 100644
--- a/src/main/preferences/schema.json
+++ b/src/main/preferences/schema.json
@@ -289,6 +289,11 @@
"type": "boolean",
"default": false
},
+ "isHtmlEnabled": {
+ "description": "Markdown-Enable HTML rendering",
+ "type": "boolean",
+ "default": true
+ },
"isGitlabCompatibilityEnabled": {
"description": "Markdown-Enable GitLab compatibility mode.",
"type": "boolean",
diff --git a/src/muya/lib/config/index.js b/src/muya/lib/config/index.js
index 18e576fb..ba4a8326 100644
--- a/src/muya/lib/config/index.js
+++ b/src/muya/lib/config/index.js
@@ -283,7 +283,10 @@ export const MUYA_DEFAULT_OPTION = Object.freeze({
// Markdown extensions
superSubScript: false,
footnote: false,
- isGitlabCompatibilityEnabled: false
+ isGitlabCompatibilityEnabled: false,
+
+ // Whether HTML rendering is disabled or not.
+ disableHtml: true
})
// export const DIAGRAM_TEMPLATE = Object.freeze({
diff --git a/src/muya/lib/contentState/pasteCtrl.js b/src/muya/lib/contentState/pasteCtrl.js
index 5fe883ee..e7753771 100644
--- a/src/muya/lib/contentState/pasteCtrl.js
+++ b/src/muya/lib/contentState/pasteCtrl.js
@@ -74,7 +74,8 @@ const pasteCtrl = ContentState => {
}
// Prevent XSS and sanitize HTML.
- const sanitizedHtml = sanitize(html, PREVIEW_DOMPURIFY_CONFIG)
+ const { disableHtml } = this.muya.options
+ const sanitizedHtml = sanitize(html, PREVIEW_DOMPURIFY_CONFIG, disableHtml)
const tempWrapper = document.createElement('div')
tempWrapper.innerHTML = sanitizedHtml
diff --git a/src/muya/lib/parser/marked/options.js b/src/muya/lib/parser/marked/options.js
index 4c1399cd..8a8db848 100644
--- a/src/muya/lib/parser/marked/options.js
+++ b/src/muya/lib/parser/marked/options.js
@@ -30,5 +30,7 @@ export default {
frontMatter: true,
superSubScript: false,
footnote: false,
- isGitlabCompatibilityEnabled: false
+ isGitlabCompatibilityEnabled: false,
+
+ isHtmlEnabled: true
}
diff --git a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js
index 58f51774..4cf27c4d 100644
--- a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js
+++ b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js
@@ -132,7 +132,8 @@ export default function renderLeafBlock (parent, block, activeBlocks, matches, u
selector += `.${CLASS_OR_ID.AG_HTML_PREVIEW}`
Object.assign(data.attrs, { spellcheck: 'false' })
- const htmlContent = sanitize(code, PREVIEW_DOMPURIFY_CONFIG)
+ const { disableHtml } = this.muya.options
+ const htmlContent = sanitize(code, PREVIEW_DOMPURIFY_CONFIG, disableHtml)
// handle empty html bock
if (/^<([a-z][a-z\d]*)[^>]*?>(\s*)<\/\1>$/.test(htmlContent.trim())) {
diff --git a/src/muya/lib/utils/exportHtml.js b/src/muya/lib/utils/exportHtml.js
index 02ee4412..a4a91889 100644
--- a/src/muya/lib/utils/exportHtml.js
+++ b/src/muya/lib/utils/exportHtml.js
@@ -13,7 +13,7 @@ import { validEmoji } from '../ui/emojis'
export const getSanitizeHtml = (markdown, options) => {
const html = marked(markdown, options)
- return sanitize(html, EXPORT_DOMPURIFY_CONFIG)
+ return sanitize(html, EXPORT_DOMPURIFY_CONFIG, false)
}
const DIAGRAM_TYPE = [
@@ -143,7 +143,7 @@ class ExportHtml {
mathRenderer: this.mathRenderer
})
- html = sanitize(html, EXPORT_DOMPURIFY_CONFIG)
+ html = sanitize(html, EXPORT_DOMPURIFY_CONFIG, false)
const exportContainer = this.exportContainer = document.createElement('div')
exportContainer.classList.add('ag-render-container')
@@ -192,7 +192,7 @@ class ExportHtml {
- ${sanitize(title, EXPORT_DOMPURIFY_CONFIG)}
+ ${sanitize(title, EXPORT_DOMPURIFY_CONFIG, true)}
@@ -304,7 +304,7 @@ class ExportHtml {
}
output = output + createTableBody(html) + HF_TABLE_END
- return sanitize(output, EXPORT_DOMPURIFY_CONFIG)
+ return sanitize(output, EXPORT_DOMPURIFY_CONFIG, false)
}
}
diff --git a/src/muya/lib/utils/index.js b/src/muya/lib/utils/index.js
index 98392db2..98ce56a9 100644
--- a/src/muya/lib/utils/index.js
+++ b/src/muya/lib/utils/index.js
@@ -6,6 +6,14 @@ let id = 0
const TIMEOUT = 1500
+const HTML_TAG_REPLACEMENTS = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
+}
+
export const getUniqueId = () => `${ID_PREFIX}${id++}`
export const getLongUniqueId = () => `${getUniqueId()}-${(+new Date()).toString(32)}`
@@ -322,6 +330,10 @@ export const escapeInBlockHtml = html => {
})
}
+export const escapeHtmlTags = html => {
+ return html.replace(/[&<>"']/g, x => { return HTML_TAG_REPLACEMENTS[x] })
+}
+
export const wordCount = markdown => {
const paragraph = markdown.split(/\n{2,}/).filter(line => line).length
let word = 0
@@ -363,8 +375,12 @@ export const mixins = (constructor, ...object) => {
return Object.assign(constructor.prototype, ...object)
}
-export const sanitize = (html, options) => {
- return runSanitize(escapeInBlockHtml(html), options)
+export const sanitize = (html, purifyOptions, disableHtml) => {
+ if (disableHtml) {
+ return runSanitize(escapeHtmlTags(html), purifyOptions)
+ } else {
+ return runSanitize(escapeInBlockHtml(html), purifyOptions)
+ }
}
export const getParagraphReference = (ele, id) => {
diff --git a/src/renderer/components/editorWithTabs/editor.vue b/src/renderer/components/editorWithTabs/editor.vue
index febd64a0..8cc7bc01 100644
--- a/src/renderer/components/editorWithTabs/editor.vue
+++ b/src/renderer/components/editorWithTabs/editor.vue
@@ -140,6 +140,7 @@ export default {
frontmatterType: state => state.preferences.frontmatterType,
superSubScript: state => state.preferences.superSubScript,
footnote: state => state.preferences.footnote,
+ isHtmlEnabled: state => state.preferences.isHtmlEnabled,
isGitlabCompatibilityEnabled: state => state.preferences.isGitlabCompatibilityEnabled,
lineHeight: state => state.preferences.lineHeight,
fontSize: state => state.preferences.fontSize,
@@ -285,6 +286,13 @@ export default {
}
},
+ isHtmlEnabled: function (value, oldValue) {
+ const { editor } = this
+ if (value !== oldValue && editor) {
+ editor.setOptions({ disableHtml: !value }, true)
+ }
+ },
+
isGitlabCompatibilityEnabled: function (value, oldValue) {
const { editor } = this
if (value !== oldValue && editor) {
@@ -525,6 +533,7 @@ export default {
frontmatterType,
superSubScript,
footnote,
+ isHtmlEnabled,
isGitlabCompatibilityEnabled,
hideQuickInsertHint,
editorLineWidth,
@@ -573,6 +582,7 @@ export default {
frontmatterType,
superSubScript,
footnote,
+ disableHtml: !isHtmlEnabled,
isGitlabCompatibilityEnabled,
hideQuickInsertHint,
hideLinkPopup,
diff --git a/src/renderer/prefComponents/markdown/index.vue b/src/renderer/prefComponents/markdown/index.vue
index e7855e44..dadc74c0 100644
--- a/src/renderer/prefComponents/markdown/index.vue
+++ b/src/renderer/prefComponents/markdown/index.vue
@@ -62,6 +62,11 @@
>
Compatibility
+
state.preferences.frontmatterType,
superSubScript: state => state.preferences.superSubScript,
footnote: state => state.preferences.footnote,
+ isHtmlEnabled: state => state.preferences.isHtmlEnabled,
isGitlabCompatibilityEnabled: state => state.preferences.isGitlabCompatibilityEnabled,
sequenceTheme: state => state.preferences.sequenceTheme
})
diff --git a/src/renderer/store/preferences.js b/src/renderer/store/preferences.js
index 2c0e13b6..82489c5d 100644
--- a/src/renderer/store/preferences.js
+++ b/src/renderer/store/preferences.js
@@ -47,6 +47,7 @@ const state = {
frontmatterType: '-',
superSubScript: false,
footnote: false,
+ isHtmlEnabled: true,
isGitlabCompatibilityEnabled: false,
sequenceTheme: 'hand',
diff --git a/static/preference.json b/static/preference.json
index 5f687534..6e64f7fc 100644
--- a/static/preference.json
+++ b/static/preference.json
@@ -43,6 +43,7 @@
"frontmatterType": "-",
"superSubScript": false,
"footnote": false,
+ "isHtmlEnabled": true,
"isGitlabCompatibilityEnabled": false,
"sequenceTheme": "hand",