From 56c93454be6f4167174f23f9207310d3e52b75f5 Mon Sep 17 00:00:00 2001 From: luozhangbiao Date: Mon, 1 Aug 2022 16:25:47 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E4=BA=BA=E5=B7=A5merge=20=E6=B3=A8?= =?UTF-8?q?=E5=85=A5HTML=E5=88=B0document=E5=89=8D=EF=BC=8C=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=AF=B9=E6=B8=B2=E6=9F=93=E6=88=90=E7=9A=84HTML?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E9=98=B2XSS=E8=BF=87=E6=BB=A4=E5=A4=84?= =?UTF-8?q?=E7=90=86=20#03cb80a980fb109a8512a7d7e99325dd39a4fc5c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 224 ++++++++++--- package.json | 1 + src/mavon-editor.vue | 728 +++++++++++++++++++++---------------------- 3 files changed, 546 insertions(+), 407 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 05e6e3bf2..82b3c13b4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,49 +1,199 @@ -// http://eslint.org/docs/user-guide/configuring - module.exports = { root: true, - parser: 'babel-eslint', parserOptions: { + parser: 'babel-eslint', sourceType: 'module' }, env: { browser: true, + node: true, + es6: true, }, - // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style - extends: 'standard', - // required to lint *.vue files - plugins: [ - 'html' - ], + extends: ['plugin:vue/recommended', 'eslint:recommended'], + // add your custom rules here - 'rules': { - // allow paren-less arrow functions - 'arrow-parens': 0, - // allow async-await - 'generator-star-spacing': 0, - // allow debugger during development - 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, - // 忽略; - 'semi':0, - // 忽略缩进 - 'indent':0, - // camel case - 'camelcase':0, - // 键值对:后强制空格 - 'key-spacing':0, - // ,前不允许空格 - 'comma-spacing':0, - // 函数空格 - 'space-before-function-paren':0, - // - 'no-unused-vars':0, - // else 强制换行 - 'brace-style':0, - 'no-unneeded-ternary': 0, - 'quotes': 0, + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline": "off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'always-multiline'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", { "null": "ignore" }], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1, + ignoredNodes: ["TemplateLiteral"] + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, 'no-useless-escape': 0, - 'no-eval': 0, - // 允许多个空格 - 'no-multi-spaces': 0 + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing' : "off", + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] } } diff --git a/package.json b/package.json index b847a05a3..c6ac04017 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.6.0", "eslint-plugin-standard": "^3.0.1", + "eslint-plugin-vue": "^9.3.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^1", "github-markdown-css": "^2.6.0", diff --git a/src/mavon-editor.vue b/src/mavon-editor.vue index 41d02cb9e..597f0fc2f 100644 --- a/src/mavon-editor.vue +++ b/src/mavon-editor.vue @@ -6,8 +6,8 @@ >
- - + + - - + +
@@ -56,7 +48,6 @@
+ />
+ v-html="d_render" + />
{{ d_words.navigation_title }} + @click="toolbar_right_click('navigation')" + />
+ />
@@ -146,20 +138,20 @@
-
+ @click.stop.prevent="toolbar_right_click('help')" + /> +
@@ -167,33 +159,33 @@
- none + none
+ />
From df66dcc4e2c6d81070431f85f9d5ec0dfcb9caaf Mon Sep 17 00:00:00 2001 From: 50 Date: Wed, 24 Nov 2021 10:43:19 +0800 Subject: [PATCH 05/17] Fix build warnings and optimize console output (cherry picked from commit 720c987a1bf345dbc5d4731fb1f371b9f97462c0) --- webpack/webpack.dev.js | 75 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/webpack/webpack.dev.js b/webpack/webpack.dev.js index 9ffbac28e..b0958d026 100644 --- a/webpack/webpack.dev.js +++ b/webpack/webpack.dev.js @@ -11,53 +11,52 @@ var merge = require('merges-utils') var base = require('./webpack.base.js') -var path = require('path'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); +var path = require('path') +var HtmlWebpackPlugin = require('html-webpack-plugin') var config = { - entry: { - index: './src/dev/index.js', - vue: ['vue'] + entry: { + index: './src/dev/index.js', + vue: ['vue'], + }, + output: { + path: path.resolve(__dirname, '../dist'), + // publicPath: '/dist/', + filename: 'js/[name].[chunkhash:8].js', + chunkFilename: 'js/[name].[chunkhash:8].js', + }, + resolve: { + alias: { + 'vue': '@vue/runtime-dom', + 'muse-components': 'muse-ui/src', }, - output: { - path: path.resolve(__dirname, '../dist'), - // publicPath: '/dist/', - filename: 'js/[name].[chunkhash:8].js', - chunkFilename: 'js/[name].[chunkhash:8].js' - }, - resolve: { - alias: { - 'vue': '@vue/runtime-dom', - 'muse-components': 'muse-ui/src' - }, - extensions: ['.js', '.vue', '.less'] - }, - devServer: { - historyApiFallback: true, - disableHostCheck: true, - host: 'localhost', - port: '9090' - // hot: true, - // noInfo: true - }, - devtool: 'source-map' + extensions: ['.js', '.vue', '.less'], + }, + devServer: { + historyApiFallback: true, + disableHostCheck: true, + host: 'localhost', + port: '9090', + stats: 'normal', + }, + devtool: 'source-map', } -var res = merge([base, config]); +var res = merge([base, config]) res.plugins = [ - new HtmlWebpackPlugin({ - filename: 'index.html', - template: 'src/dev/index.html', - inject: true, - hash: false, - chunks: ['common', 'vue', 'index'] - }) + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'src/dev/index.html', + inject: true, + hash: false, + chunks: ['common', 'vue', 'index'], + }), ].concat(res.plugins) res.optimization = { - splitChunks:{ - chunks: 'all' - } + splitChunks: { + chunks: 'all', + }, } module.exports = res From 897996aebaa109cbb302595ba61383bc10117c7a Mon Sep 17 00:00:00 2001 From: 50 Date: Wed, 24 Nov 2021 15:28:43 +0800 Subject: [PATCH 06/17] fix: Fix the content of code blocks to be displayed outside the pre container,issue #729 (cherry picked from commit c611bddbf9d5c3fb1fb254b625bfd0de5f7ca141) --- src/lib/css/md.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/css/md.css b/src/lib/css/md.css index adc009644..b6bde128c 100644 --- a/src/lib/css/md.css +++ b/src/lib/css/md.css @@ -22,3 +22,6 @@ .markdown-body .hljs-left { text-align: left; } +.markdown-body .hljs { + overflow: auto; +} \ No newline at end of file From b0bb40fde7bb217a1acb90df7340c2363e082a2f Mon Sep 17 00:00:00 2001 From: Zhexin Jin Date: Thu, 2 Dec 2021 02:31:54 -0500 Subject: [PATCH 07/17] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E5=9C=A8=E7=BC=96=E8=BE=91=E5=99=A8=E5=A4=96=E6=B8=B2?= =?UTF-8?q?=E6=9F=93markdown=E7=9A=84=E4=BE=8B=E5=AD=90=20(#612)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added an example about how to render markdown (cherry picked from commit bf97a96341d0b287700e8166cdf73debeb094331) --- doc/cn/markdown.md | 36 +++++++++++++++++++++++++++++++++++- doc/en/markdown.md | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/doc/cn/markdown.md b/doc/cn/markdown.md index cfe7016a8..9576417cf 100644 --- a/doc/cn/markdown.md +++ b/doc/cn/markdown.md @@ -34,4 +34,38 @@ markdownIt.set({ breaks: false }); ``` -> [更多设置参考markdown-it...](https://github.com/markdown-it/markdown-it) \ No newline at end of file +> [更多设置参考markdown-it...](https://github.com/markdown-it/markdown-it) + +### 简单示例 + +> 注意:`class="markdown-body"` 是必要的,否则CSS样式会于预览的不一样 + +```html + + + +``` diff --git a/doc/en/markdown.md b/doc/en/markdown.md index 2fd372dc1..aa16af983 100644 --- a/doc/en/markdown.md +++ b/doc/en/markdown.md @@ -34,4 +34,38 @@ markdownIt.set({ breaks: false }); ``` -> [markdown-it API](https://github.com/markdown-it/markdown-it) \ No newline at end of file +> [markdown-it API](https://github.com/markdown-it/markdown-it) + +### Simple example + +> Notice:`class="markdown-body"` is necessary, or the CSS style will be different from the preview + +```html + + + +``` From b462fe9d63a8992858ce30a61e0bb1866007e89a Mon Sep 17 00:00:00 2001 From: luozhangbiao Date: Mon, 1 Aug 2022 16:53:18 +0800 Subject: [PATCH 08/17] fix: image cannot be previewed (#738) * fix: image cannot be previewed,issue #737 * fix test * Update src/lib/core/rules.js Co-authored-by: ygj6 <7699524+ygj6@users.noreply.github.com> Co-authored-by: ygj6 <7699524+ygj6@users.noreply.github.com> (cherry picked from commit 99331191d19770c5731e336bbc290f752b0b2ef5) # Conflicts: # src/mavon-editor.vue --- src/lib/core/rules.js | 21 ++++++++++++++++++--- src/lib/mixins/markdown.js | 6 +++++- src/mavon-editor.vue | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/lib/core/rules.js b/src/lib/core/rules.js index 064756e16..504a9d4b3 100644 --- a/src/lib/core/rules.js +++ b/src/lib/core/rules.js @@ -1,8 +1,10 @@ export const HEADER_FLAG = ' _MD-HEADER_ '; +export const IMAGE_FLAG = ['_MD-HEADER_', true]; +const IMAGE_FLAG_STR = `${IMAGE_FLAG[0]}="${IMAGE_FLAG[1]}" `; -export function headRule(tocHeadRule) { +export function headRule(defaultTocHeadRule) { return function (tokens, index) { - let code = tocHeadRule(tokens, index); + let code = defaultTocHeadRule(tokens, index); var label = tokens[index + 1]; if (label.type === 'inline') { return code.replace(' Date: Mon, 1 Aug 2022 17:05:44 +0800 Subject: [PATCH 09/17] fix: Add sanitizer for filtering HTML tags (#744) * fix: Add sanitizer for filtering HTML tags * fix: Do not share `markdown-it` instances * chore: fix lint Co-authored-by: wangsongc (cherry picked from commit b9489a331baf65e856629814f68c6b74f495c863) # Conflicts: # src/mavon-editor.vue --- README-EN.md | 3 +- README.md | 3 +- src/dev/editor.vue | 9 ++- src/lib/core/rules.js | 34 ----------- src/lib/core/sanitizer.js | 31 ++++++++++ src/lib/mixins/markdown.js | 112 ++++++++++++++++++++----------------- src/mavon-editor.vue | 59 ++----------------- 7 files changed, 107 insertions(+), 144 deletions(-) delete mode 100644 src/lib/core/rules.js create mode 100644 src/lib/core/sanitizer.js diff --git a/README-EN.md b/README-EN.md index e44e17cdc..a2c445260 100644 --- a/README-EN.md +++ b/README-EN.md @@ -68,7 +68,8 @@ $ npm install mavon-editor@next --save | imageFilter | Function | null | Image file filter Function, params is a `File Object`, you should return `Boolean` about the test result | | imageClick | function | null | Image Click Function | | tabSize | Number | null | How many spaces equals one tab, default \t | -| xssOptions | Object | {} | xss rule configuration, enabled by default, set to false to turn off, custom rule reference [https://jsxss.com/zh/options.html](https://jsxss.com/zh/options.html) | +| html | Boolean | true | Enable HTML tags in source, for historical reasons this tag has always been true by default, but it is recommended to turn it off if you don't need this feature, as doing so it eliminates the security vulnerabilities altogether. | +| xssOptions | Object | {} | xss rules configuration, enabled by default, set to false to turn off, enabled will filter HTML tags, the default filter all HTML tag attributes, it is recommended to configure the whitelist on demand to reduce the possibility of being attacked.
- custom rule reference: [https://jsxss.com/zh/options.html](https://jsxss.com/zh/options.html)
- Demo: [dev-demo](./src/dev/editor.vue) | | toolbars | Object | As in the following example | toolbars | ```javascript diff --git a/README.md b/README.md index c44289d08..f1ec74b04 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,8 @@ $ npm install mavon-editor@next --save | imageFilter | function | null | 图片过滤函数,参数为一个`File Object`,要求返回一个`Boolean`, `true`表示文件合法,`false`表示文件不合法 | | imageClick | function | null | 图片点击事件,默认为预览,可覆盖 | | tabSize | Number | \t | tab转化为几个空格,默认为\t | -| xssOptions | Object | {} | xss规则配置, 默认开启,设置false可以关闭,自定义规则参考 [https://jsxss.com/zh/options.html](https://jsxss.com/zh/options.html) | +| html | Boolean | true | 启用HTML标签,因为历史原因这个标记一直默认为true,但建议不使用HTML标签就关闭它,它能彻底杜绝安全问题。 | +| xssOptions | Object | {} | xss规则配置, 默认开启,设置false可以关闭,开启后会对HTML标签进行过滤,默认过滤所有HTML标签属性,建议按需配置白名单减少被攻击的可能。
- 自定义规则参考: [https://jsxss.com/zh/options.html](https://jsxss.com/zh/options.html)
- 参考DEMO: [dev-demo](./src/dev/editor.vue) | | toolbars | Object | 如下例 | 工具栏 | ```javascript diff --git a/src/dev/editor.vue b/src/dev/editor.vue index c8b5c5734..57391f8e9 100644 --- a/src/dev/editor.vue +++ b/src/dev/editor.vue @@ -1,7 +1,7 @@