From 038da916c3fb7075f478b2bd37228227dfffb115 Mon Sep 17 00:00:00 2001 From: chouchouji <1305974212@qq.com> Date: 2025年2月14日 22:33:20 +0800 Subject: [PATCH 1/6] feat(no-multiple-template-root): support disallowComments property --- lib/rules/no-multiple-template-root.js | 45 +++++++++++- tests/lib/rules/no-multiple-template-root.js | 76 ++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-multiple-template-root.js b/lib/rules/no-multiple-template-root.js index 45c22389f..7d89c696f 100644 --- a/lib/rules/no-multiple-template-root.js +++ b/lib/rules/no-multiple-template-root.js @@ -15,8 +15,19 @@ module.exports = { url: 'https://eslint.vuejs.org/rules/no-multiple-template-root.html' }, fixable: null, - schema: [], + schema: [ + { + type: 'object', + properties: { + disallowComments: { + type: 'boolean' + } + }, + additionalProperties: false + } + ], messages: { + commentRoot: 'The template root disallows comments.', multipleRoot: 'The template root requires exactly one element.', textRoot: 'The template root requires an element rather than texts.', disallowedElement: "The template root disallows '<{{name}}>' elements.", @@ -28,6 +39,8 @@ module.exports = { * @returns {RuleListener} AST event handlers. */ create(context) { + const options = context.options[0] || {} + const disallowComments = options.disallowComments const sourceCode = context.getSourceCode() return { @@ -37,6 +50,36 @@ module.exports = { return } + const commentRangesMap = new Map() + const comments = element.comments + if (disallowComments && comments.length> 0) { + for (const comment of comments) { + const [start, end] = comment.range + commentRangesMap.set(`${start}-${end}`, comment) + } + + for (const child of element.children) { + if (child.type === 'VElement') { + for (const range of commentRangesMap.keys()) { + const ranges = range.split('-') + if (ranges[0]> child.range[0] && ranges[1] < child.range[1]) { + commentRangesMap.delete(range) + } + } + } + } + + if (commentRangesMap.size> 0) { + for (const node of commentRangesMap.values()) { + context.report({ + node, + loc: node.loc, + messageId: 'commentRoot' + }) + } + } + } + const rootElements = [] let extraText = null let extraElement = null diff --git a/tests/lib/rules/no-multiple-template-root.js b/tests/lib/rules/no-multiple-template-root.js index 7ab80af7e..c452ebe45 100644 --- a/tests/lib/rules/no-multiple-template-root.js +++ b/tests/lib/rules/no-multiple-template-root.js @@ -62,6 +62,30 @@ ruleTester.run('no-multiple-template-root', rule, { ` + }, + { + filename: 'test.vue', + code: ` + + + 12333 + + + `, + options: [{ disallowComments: false }] + }, + { + filename: 'test.vue', + code: ` + + + + + 12333 + + + `, + options: [{ disallowComments: false }] } ], invalid: [ @@ -104,6 +128,58 @@ ruleTester.run('no-multiple-template-root', rule, { filename: 'test.vue', code: '', errors: ["The template root disallows '' elements."] + }, + { + code: ` + + + 12333 + + + `, + options: [{ disallowComments: true }], + errors: [ + { + message: 'The template root disallows comments.', + line: 3 + }, + { + message: 'The template root disallows comments.', + line: 5 + } + ] + }, + { + code: ` + + + + 12333 + + + + `, + options: [{ disallowComments: true }], + errors: [ + { + message: 'The template root disallows comments.', + line: 3 + } + ] + }, + { + code: ` + + + + 12333 + + + + `, + options: [{ disallowComments: true }], + errors: ['The template root disallows comments.'] } ] }) From 5601d918d88df53737d49050e3dc9155ef52b0d7 Mon Sep 17 00:00:00 2001 From: chouchouji <1305974212@qq.com> Date: 2025年2月15日 14:13:49 +0800 Subject: [PATCH 2/6] refactor(no-multiple-template-root): optimize code --- lib/rules/no-multiple-template-root.js | 59 ++++++++++++++------ tests/lib/rules/no-multiple-template-root.js | 36 ++++++++++++ 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/lib/rules/no-multiple-template-root.js b/lib/rules/no-multiple-template-root.js index 7d89c696f..e25f0b94f 100644 --- a/lib/rules/no-multiple-template-root.js +++ b/lib/rules/no-multiple-template-root.js @@ -50,30 +50,55 @@ module.exports = { return } - const commentRangesMap = new Map() const comments = element.comments if (disallowComments && comments.length> 0) { - for (const comment of comments) { - const [start, end] = comment.range - commentRangesMap.set(`${start}-${end}`, comment) - } + const commentRanges = comments.map((comment) => comment.range) + const elementRanges = element.children + .filter((child) => child.type === 'VElement') + .map((child) => child.range) + + let commentIndex = 0 + let elementIndex = 0 + + const needReportComments = elementRanges.length === 0 ? comments : [] + while ( + commentIndex < commentRanges.length && + elementRanges.length> 0 + ) { + const [commentStart, commentEnd] = commentRanges[commentIndex] + const [elementStart, elementEnd] = elementRanges[elementIndex] + if (commentStart> elementStart && commentEnd < elementEnd) { + commentIndex += 1 + continue + } + + if (commentEnd < elementStart) { + needReportComments.push(comments[commentIndex]) + commentIndex += 1 + } + + // the element array has no any element, but comment still has some elements + if ( + elementIndex === elementRanges.length - 1 && + commentStart> elementEnd + ) { + needReportComments.push(comments[commentIndex]) + commentIndex += 1 + } - for (const child of element.children) { - if (child.type === 'VElement') { - for (const range of commentRangesMap.keys()) { - const ranges = range.split('-') - if (ranges[0]> child.range[0] && ranges[1] < child.range[1]) { - commentRangesMap.delete(range) - } - } + if ( + elementIndex < elementRanges.length - 1 && + commentStart> elementEnd + ) { + elementIndex += 1 } } - if (commentRangesMap.size> 0) { - for (const node of commentRangesMap.values()) { + if (needReportComments.length> 0) { + for (const comment of needReportComments) { context.report({ - node, - loc: node.loc, + node: comment, + loc: comment.loc, messageId: 'commentRoot' }) } diff --git a/tests/lib/rules/no-multiple-template-root.js b/tests/lib/rules/no-multiple-template-root.js index c452ebe45..517fdeccd 100644 --- a/tests/lib/rules/no-multiple-template-root.js +++ b/tests/lib/rules/no-multiple-template-root.js @@ -86,6 +86,42 @@ ruleTester.run('no-multiple-template-root', rule, { `, options: [{ disallowComments: false }] + }, + { + filename: 'test.vue', + code: ` + + + + 12333 + + + 12333 + + + + `, + options: [{ disallowComments: true }] + }, + { + filename: 'test.vue', + code: ` + + + + 12333 + + + 12333 + + + + + 12333 + + + `, + options: [{ disallowComments: true }] } ], invalid: [ From f802a5fc4fa40a27f7fc321a696179e20337fd13 Mon Sep 17 00:00:00 2001 From: chouchouji <1305974212@qq.com> Date: 2025年2月15日 15:58:35 +0800 Subject: [PATCH 3/6] refactor(no-multiple-template-root): optimize code --- lib/rules/no-multiple-template-root.js | 95 +++++++++++--------- tests/lib/rules/no-multiple-template-root.js | 54 +++++++++++ 2 files changed, 107 insertions(+), 42 deletions(-) diff --git a/lib/rules/no-multiple-template-root.js b/lib/rules/no-multiple-template-root.js index e25f0b94f..1d728b1f5 100644 --- a/lib/rules/no-multiple-template-root.js +++ b/lib/rules/no-multiple-template-root.js @@ -6,6 +6,58 @@ const utils = require('../utils') +/** + * Get all comments that need to be reported + * @param {(HTMLComment | HTMLBogusComment | Comment)[]} comments + * @param {VRootElement} element + * @returns {(HTMLComment | HTMLBogusComment | Comment)[]} + */ +function getReportComments(comments, element) { + const commentRanges = comments.map((comment) => comment.range) + const elementRanges = element.children + .filter((child) => child.type === 'VElement') + .map((child) => child.range) + + // should return comment directly when no any elements + if (elementRanges.length === 0) { + return comments + } + + let commentIndex = 0 + let elementIndex = 0 + + const needReportComments = [] + while (commentIndex < commentRanges.length) { + const [commentStart, commentEnd] = commentRanges[commentIndex] + const [elementStart, elementEnd] = elementRanges[elementIndex] + // if the comment is in the range of element, should skip + if (commentStart> elementStart && commentEnd < elementEnd) { + commentIndex += 1 + continue + } + + if (commentEnd < elementStart) { + needReportComments.push(comments[commentIndex]) + commentIndex += 1 + } + + // the element array has no any element, but comment still has some elements + if ( + elementIndex === elementRanges.length - 1 && + commentStart> elementEnd + ) { + needReportComments.push(comments[commentIndex]) + commentIndex += 1 + } + + if (elementIndex < elementRanges.length - 1 && commentStart> elementEnd) { + elementIndex += 1 + } + } + + return needReportComments +} + module.exports = { meta: { type: 'problem', @@ -52,48 +104,7 @@ module.exports = { const comments = element.comments if (disallowComments && comments.length> 0) { - const commentRanges = comments.map((comment) => comment.range) - const elementRanges = element.children - .filter((child) => child.type === 'VElement') - .map((child) => child.range) - - let commentIndex = 0 - let elementIndex = 0 - - const needReportComments = elementRanges.length === 0 ? comments : [] - while ( - commentIndex < commentRanges.length && - elementRanges.length> 0 - ) { - const [commentStart, commentEnd] = commentRanges[commentIndex] - const [elementStart, elementEnd] = elementRanges[elementIndex] - if (commentStart> elementStart && commentEnd < elementEnd) { - commentIndex += 1 - continue - } - - if (commentEnd < elementStart) { - needReportComments.push(comments[commentIndex]) - commentIndex += 1 - } - - // the element array has no any element, but comment still has some elements - if ( - elementIndex === elementRanges.length - 1 && - commentStart> elementEnd - ) { - needReportComments.push(comments[commentIndex]) - commentIndex += 1 - } - - if ( - elementIndex < elementRanges.length - 1 && - commentStart> elementEnd - ) { - elementIndex += 1 - } - } - + const needReportComments = getReportComments(comments, element) if (needReportComments.length> 0) { for (const comment of needReportComments) { context.report({ diff --git a/tests/lib/rules/no-multiple-template-root.js b/tests/lib/rules/no-multiple-template-root.js index 517fdeccd..0bc425e93 100644 --- a/tests/lib/rules/no-multiple-template-root.js +++ b/tests/lib/rules/no-multiple-template-root.js @@ -203,6 +203,60 @@ ruleTester.run('no-multiple-template-root', rule, { } ] }, + { + code: ` + + + + + 12333 + + + 12333 + + + + + + 12333 + + + + `, + options: [{ disallowComments: true }], + errors: [ + { + message: 'The template root disallows comments.', + line: 3 + }, + { + message: 'The template root disallows comments.', + line: 12 + }, + { + message: 'The template root disallows comments.', + line: 17 + } + ] + }, + { + code: ` + + + 12333 + + + + + `, + options: [{ disallowComments: true }], + errors: [ + { + message: 'The template root disallows comments.', + line: 7 + } + ] + }, { code: ` From b33de2808c1ff616b095ec986bc45e74af6fddad Mon Sep 17 00:00:00 2001 From: chouchouji <70570907+chouchouji@users.noreply.github.com> Date: Wed, 5 Mar 2025 06:47:17 +0000 Subject: [PATCH 4/6] docs(no-multiple-template-root): update docs --- docs/rules/no-multiple-template-root.md | 27 ++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-multiple-template-root.md b/docs/rules/no-multiple-template-root.md index 90b5488fc..8a85c9201 100644 --- a/docs/rules/no-multiple-template-root.md +++ b/docs/rules/no-multiple-template-root.md @@ -61,7 +61,32 @@ This rule checks whether template contains single root element valid for Vue 2. ## :wrench: Options -Nothing. +```json +{ + "vue/no-multiple-template-root": ["error", { + "disallowComments": false + }] +} +``` + +- "disallowComments" (`boolean`) Enables there should not be any comments in the template root. Default is `false`. + +### "disallowComments": true + + + +```vue +/* ✗ BAD */ + + + + vue eslint plugin + + + +``` + + ## :rocket: Version From 0d774c76ee04757b428bcd1ac7fe63724b8919cc Mon Sep 17 00:00:00 2001 From: chouchouji <70570907+chouchouji@users.noreply.github.com> Date: Wed, 5 Mar 2025 08:22:30 +0000 Subject: [PATCH 5/6] refactor(no-multiple-template-root): optimize code --- lib/rules/no-multiple-template-root.js | 69 +++++--------------- tests/lib/rules/no-multiple-template-root.js | 20 ++++++ 2 files changed, 35 insertions(+), 54 deletions(-) diff --git a/lib/rules/no-multiple-template-root.js b/lib/rules/no-multiple-template-root.js index 1d728b1f5..84610eb5f 100644 --- a/lib/rules/no-multiple-template-root.js +++ b/lib/rules/no-multiple-template-root.js @@ -9,53 +9,16 @@ const utils = require('../utils') /** * Get all comments that need to be reported * @param {(HTMLComment | HTMLBogusComment | Comment)[]} comments - * @param {VRootElement} element + * @param {Range[]} elementRanges * @returns {(HTMLComment | HTMLBogusComment | Comment)[]} */ -function getReportComments(comments, element) { - const commentRanges = comments.map((comment) => comment.range) - const elementRanges = element.children - .filter((child) => child.type === 'VElement') - .map((child) => child.range) - - // should return comment directly when no any elements - if (elementRanges.length === 0) { - return comments - } - - let commentIndex = 0 - let elementIndex = 0 - - const needReportComments = [] - while (commentIndex < commentRanges.length) { - const [commentStart, commentEnd] = commentRanges[commentIndex] - const [elementStart, elementEnd] = elementRanges[elementIndex] - // if the comment is in the range of element, should skip - if (commentStart> elementStart && commentEnd < elementEnd) { - commentIndex += 1 - continue - } - - if (commentEnd < elementStart) { - needReportComments.push(comments[commentIndex]) - commentIndex += 1 - } - - // the element array has no any element, but comment still has some elements - if ( - elementIndex === elementRanges.length - 1 && - commentStart> elementEnd - ) { - needReportComments.push(comments[commentIndex]) - commentIndex += 1 - } - - if (elementIndex < elementRanges.length - 1 && commentStart> elementEnd) { - elementIndex += 1 - } - } - - return needReportComments +function getReportComments(comments, elementRanges) { + return comments.filter( + (comment) => + !elementRanges.some( + (range) => range[0] <= comment.range[0] && comment.range[1] <= range[1] + ) + ) } module.exports = { @@ -103,16 +66,14 @@ module.exports = { } const comments = element.comments + const elementRanges = element.children.map((child) => child.range) if (disallowComments && comments.length> 0) { - const needReportComments = getReportComments(comments, element) - if (needReportComments.length> 0) { - for (const comment of needReportComments) { - context.report({ - node: comment, - loc: comment.loc, - messageId: 'commentRoot' - }) - } + for (const comment of getReportComments(comments, elementRanges)) { + context.report({ + node: comment, + loc: comment.loc, + messageId: 'commentRoot' + }) } } diff --git a/tests/lib/rules/no-multiple-template-root.js b/tests/lib/rules/no-multiple-template-root.js index 0bc425e93..c52c1c202 100644 --- a/tests/lib/rules/no-multiple-template-root.js +++ b/tests/lib/rules/no-multiple-template-root.js @@ -257,6 +257,26 @@ ruleTester.run('no-multiple-template-root', rule, { } ] }, + { + code: ` + + + + + + `, + options: [{ disallowComments: true }], + errors: [ + { + message: 'The template root disallows comments.', + line: 4 + }, + { + message: 'The template root requires exactly one element.', + line: 5 + } + ] + }, { code: ` From 7dcd6833cdccfc818f050671fc39c909d3fada32 Mon Sep 17 00:00:00 2001 From: chouchouji <70570907+chouchouji@users.noreply.github.com> Date: Wed, 5 Mar 2025 08:24:55 +0000 Subject: [PATCH 6/6] style: format code --- lib/rules/no-multiple-template-root.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-multiple-template-root.js b/lib/rules/no-multiple-template-root.js index 84610eb5f..524b7a2b1 100644 --- a/lib/rules/no-multiple-template-root.js +++ b/lib/rules/no-multiple-template-root.js @@ -13,12 +13,12 @@ const utils = require('../utils') * @returns {(HTMLComment | HTMLBogusComment | Comment)[]} */ function getReportComments(comments, elementRanges) { - return comments.filter( - (comment) => - !elementRanges.some( - (range) => range[0] <= comment.range[0] && comment.range[1] <= range[1] - ) - ) + return comments.filter( + (comment) => + !elementRanges.some( + (range) => range[0] <= comment.range[0] && comment.range[1] <= range[1] + ) + ) } module.exports = { AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル