eslint-plugin-vue
Version:
Official ESLint plugin for Vue.js
183 lines (181 loc) • 7.13 kB
JavaScript
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
const require_index = require('./index.js');
//#region lib/utils/html-comments.js
var require_html_comments = /* @__PURE__ */ require_rolldown_runtime.__commonJSMin(((exports, module) => {
/**
* @typedef { { exceptions?: string[] } } CommentParserConfig
* @typedef { (comment: ParsedHTMLComment) => void } HTMLCommentVisitor
* @typedef { { includeDirectives?: boolean } } CommentVisitorOption
*
* @typedef { Token & { type: 'HTMLCommentOpen' } } HTMLCommentOpen
* @typedef { Token & { type: 'HTMLCommentOpenDecoration' } } HTMLCommentOpenDecoration
* @typedef { Token & { type: 'HTMLCommentValue' } } HTMLCommentValue
* @typedef { Token & { type: 'HTMLCommentClose' } } HTMLCommentClose
* @typedef { Token & { type: 'HTMLCommentCloseDecoration' } } HTMLCommentCloseDecoration
* @typedef { { open: HTMLCommentOpen, openDecoration: HTMLCommentOpenDecoration | null, value: HTMLCommentValue | null, closeDecoration: HTMLCommentCloseDecoration | null, close: HTMLCommentClose } } ParsedHTMLComment
*/
const utils = require_index.default;
const COMMENT_DIRECTIVE = /^\s*eslint-(?:en|dis)able/;
const IE_CONDITIONAL_IF = /^\[if\s+/;
const IE_CONDITIONAL_ENDIF = /\[endif]$/;
/** @type { 'HTMLCommentOpen' } */
const TYPE_HTML_COMMENT_OPEN = "HTMLCommentOpen";
/** @type { 'HTMLCommentOpenDecoration' } */
const TYPE_HTML_COMMENT_OPEN_DECORATION = "HTMLCommentOpenDecoration";
/** @type { 'HTMLCommentValue' } */
const TYPE_HTML_COMMENT_VALUE = "HTMLCommentValue";
/** @type { 'HTMLCommentClose' } */
const TYPE_HTML_COMMENT_CLOSE = "HTMLCommentClose";
/** @type { 'HTMLCommentCloseDecoration' } */
const TYPE_HTML_COMMENT_CLOSE_DECORATION = "HTMLCommentCloseDecoration";
/**
* @param {HTMLComment} comment
* @returns {boolean}
*/
function isCommentDirective(comment) {
return COMMENT_DIRECTIVE.test(comment.value);
}
/**
* @param {HTMLComment} comment
* @returns {boolean}
*/
function isIEConditionalComment(comment) {
return IE_CONDITIONAL_IF.test(comment.value) || IE_CONDITIONAL_ENDIF.test(comment.value);
}
/**
* Define HTML comment parser
*
* @param {SourceCode} sourceCode The source code instance.
* @param {CommentParserConfig | null} config The config.
* @returns { (node: Token) => (ParsedHTMLComment | null) } HTML comment parser.
*/
function defineParser(sourceCode, config) {
config = config || {};
const exceptions = config.exceptions || [];
/**
* Get a open decoration string from comment contents.
* @param {string} contents comment contents
* @returns {string} decoration string
*/
function getOpenDecoration(contents) {
let decoration = "";
for (const exception of exceptions) {
const length = exception.length;
let index = 0;
while (contents.startsWith(exception, index)) index += length;
const exceptionLength = index;
if (decoration.length < exceptionLength) decoration = contents.slice(0, exceptionLength);
}
return decoration;
}
/**
* Get a close decoration string from comment contents.
* @param {string} contents comment contents
* @returns {string} decoration string
*/
function getCloseDecoration(contents) {
let decoration = "";
for (const exception of exceptions) {
const length = exception.length;
let index = contents.length;
while (contents.endsWith(exception, index)) index -= length;
const exceptionLength = contents.length - index;
if (decoration.length < exceptionLength) decoration = contents.slice(index);
}
return decoration;
}
/**
* Parse HTMLComment.
* @param {Token} node a comment token
* @returns {ParsedHTMLComment | null} the result of HTMLComment tokens.
*/
return function parseHTMLComment(node) {
if (node.type !== "HTMLComment") return null;
const htmlCommentText = sourceCode.getText(node);
if (!htmlCommentText.startsWith("<!--") || !htmlCommentText.endsWith("-->")) return null;
let valueText = htmlCommentText.slice(4, -3);
const openDecorationText = getOpenDecoration(valueText);
valueText = valueText.slice(openDecorationText.length);
const firstCharIndex = valueText.search(/\S/);
const beforeSpace = firstCharIndex >= 0 ? valueText.slice(0, firstCharIndex) : valueText;
valueText = valueText.slice(beforeSpace.length);
const closeDecorationText = getCloseDecoration(valueText);
if (closeDecorationText) valueText = valueText.slice(0, -closeDecorationText.length);
const lastCharIndex = valueText.search(/\S\s*$/);
const afterSpace = lastCharIndex >= 0 ? valueText.slice(lastCharIndex + 1) : valueText;
if (afterSpace) valueText = valueText.slice(0, -afterSpace.length);
let tokenIndex = node.range[0];
/**
* @param {string} type
* @param {string} value
* @returns {any}
*/
const createToken = (type, value$1) => {
/** @type {Range} */
const range = [tokenIndex, tokenIndex + value$1.length];
tokenIndex = range[1];
/** @type {SourceLocation} */
let loc;
return {
type,
value: value$1,
range,
get loc() {
if (loc) return loc;
return loc = {
start: sourceCode.getLocFromIndex(range[0]),
end: sourceCode.getLocFromIndex(range[1])
};
}
};
};
/** @type {HTMLCommentOpen} */
const open = createToken(TYPE_HTML_COMMENT_OPEN, "<!--");
/** @type {HTMLCommentOpenDecoration | null} */
const openDecoration = openDecorationText ? createToken(TYPE_HTML_COMMENT_OPEN_DECORATION, openDecorationText) : null;
tokenIndex += beforeSpace.length;
/** @type {HTMLCommentValue | null} */
const value = valueText ? createToken(TYPE_HTML_COMMENT_VALUE, valueText) : null;
tokenIndex += afterSpace.length;
return {
open,
openDecoration,
value,
closeDecoration: closeDecorationText ? createToken(TYPE_HTML_COMMENT_CLOSE_DECORATION, closeDecorationText) : null,
close: createToken(TYPE_HTML_COMMENT_CLOSE, "-->")
};
};
}
/**
* Define HTML comment visitor
*
* @param {RuleContext} context The rule context.
* @param {CommentParserConfig | null} config The config.
* @param {HTMLCommentVisitor} visitHTMLComment The HTML comment visitor.
* @param {CommentVisitorOption} [visitorOption] The option for visitor.
* @returns {RuleListener} HTML comment visitor.
*/
function defineVisitor(context, config, visitHTMLComment, visitorOption) {
return { Program(node) {
visitorOption = visitorOption || {};
if (utils.hasInvalidEOF(node)) return;
if (!node.templateBody) return;
const parse = defineParser(context.sourceCode, config);
for (const comment of node.templateBody.comments) {
if (comment.type !== "HTMLComment") continue;
if (!visitorOption.includeDirectives && isCommentDirective(comment)) continue;
if (isIEConditionalComment(comment)) continue;
const tokens = parse(comment);
if (tokens) visitHTMLComment(tokens);
}
} };
}
module.exports = { defineVisitor };
}));
//#endregion
Object.defineProperty(exports, 'default', {
enumerable: true,
get: function () {
return require_html_comments();
}
});