123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- const utils = require('./')
- const COMMENT_DIRECTIVE = /^\s*eslint-(?:en|dis)able/
- const IE_CONDITIONAL_IF = /^\[if\s+/
- const IE_CONDITIONAL_ENDIF = /\[endif\]$/
- const TYPE_HTML_COMMENT_OPEN = 'HTMLCommentOpen'
- const TYPE_HTML_COMMENT_OPEN_DECORATION = 'HTMLCommentOpenDecoration'
- const TYPE_HTML_COMMENT_VALUE = 'HTMLCommentValue'
- const TYPE_HTML_COMMENT_CLOSE = 'HTMLCommentClose'
- const TYPE_HTML_COMMENT_CLOSE_DECORATION = 'HTMLCommentCloseDecoration'
- function isCommentDirective(comment) {
- return COMMENT_DIRECTIVE.test(comment.value)
- }
- function isIEConditionalComment(comment) {
- return (
- IE_CONDITIONAL_IF.test(comment.value) ||
- IE_CONDITIONAL_ENDIF.test(comment.value)
- )
- }
- function defineParser(sourceCode, config) {
- config = config || {}
- const exceptions = config.exceptions || []
-
- 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
- }
-
- 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
- }
-
- 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]
-
- const createToken = (type, value) => {
-
- const range = [tokenIndex, tokenIndex + value.length]
- tokenIndex = range[1]
-
- let loc
- return {
- type,
- value,
- range,
- get loc() {
- if (loc) {
- return loc
- }
- return (loc = {
- start: sourceCode.getLocFromIndex(range[0]),
- end: sourceCode.getLocFromIndex(range[1])
- })
- }
- }
- }
-
- const open = createToken(TYPE_HTML_COMMENT_OPEN, '<!--')
-
- const openDecoration = openDecorationText
- ? createToken(TYPE_HTML_COMMENT_OPEN_DECORATION, openDecorationText)
- : null
- tokenIndex += beforeSpace.length
-
- const value = valueText
- ? createToken(TYPE_HTML_COMMENT_VALUE, valueText)
- : null
- tokenIndex += afterSpace.length
-
- const closeDecoration = closeDecorationText
- ? createToken(TYPE_HTML_COMMENT_CLOSE_DECORATION, closeDecorationText)
- : null
-
- const close = createToken(TYPE_HTML_COMMENT_CLOSE, '-->')
- return {
-
- open,
-
- openDecoration,
-
- value,
-
- closeDecoration,
-
- close
- }
- }
- }
- function defineVisitor(context, config, visitHTMLComment, visitorOption) {
- return {
- Program(node) {
- visitorOption = visitorOption || {}
- if (utils.hasInvalidEOF(node)) {
- return
- }
- if (!node.templateBody) {
- return
- }
- const parse = defineParser(context.getSourceCode(), 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
- }
|