first commit
This commit is contained in:
224
app_vue/node_modules/eslint-plugin-vue/lib/rules/block-lang.js
generated
vendored
Normal file
224
app_vue/node_modules/eslint-plugin-vue/lib/rules/block-lang.js
generated
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @fileoverview Disallow use other than available `lang`
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {object} BlockOptions
|
||||
* @property {Set<string>} lang
|
||||
* @property {boolean} allowNoLang
|
||||
*/
|
||||
/**
|
||||
* @typedef { { [element: string]: BlockOptions | undefined } } Options
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} UserBlockOptions
|
||||
* @property {string[] | string} [lang]
|
||||
* @property {boolean} [allowNoLang]
|
||||
*/
|
||||
/**
|
||||
* @typedef { { [element: string]: UserBlockOptions | undefined } } UserOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* https://vuejs.github.io/vetur/guide/highlighting.html
|
||||
* <template lang="html"></template>
|
||||
* <style lang="css"></style>
|
||||
* <script lang="js"></script>
|
||||
* <script lang="javascript"></script>
|
||||
* @type {Record<string, string[] | undefined>}
|
||||
*/
|
||||
const DEFAULT_LANGUAGES = {
|
||||
template: ['html'],
|
||||
style: ['css'],
|
||||
script: ['js', 'javascript']
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NonNullable<BlockOptions['lang']>} lang
|
||||
*/
|
||||
function getAllowsLangPhrase(lang) {
|
||||
const langs = [...lang].map((s) => `"${s}"`)
|
||||
switch (langs.length) {
|
||||
case 1:
|
||||
return langs[0]
|
||||
default:
|
||||
return `${langs.slice(0, -1).join(', ')}, and ${langs[langs.length - 1]}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a given option.
|
||||
* @param {string} blockName The block name.
|
||||
* @param { UserBlockOptions } option An option to parse.
|
||||
* @returns {BlockOptions} Normalized option.
|
||||
*/
|
||||
function normalizeOption(blockName, option) {
|
||||
const lang = new Set(
|
||||
Array.isArray(option.lang) ? option.lang : option.lang ? [option.lang] : []
|
||||
)
|
||||
let hasDefault = false
|
||||
for (const def of DEFAULT_LANGUAGES[blockName] || []) {
|
||||
if (lang.has(def)) {
|
||||
lang.delete(def)
|
||||
hasDefault = true
|
||||
}
|
||||
}
|
||||
if (lang.size === 0) {
|
||||
return {
|
||||
lang,
|
||||
allowNoLang: true
|
||||
}
|
||||
}
|
||||
return {
|
||||
lang,
|
||||
allowNoLang: hasDefault || Boolean(option.allowNoLang)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Normalizes a given options.
|
||||
* @param { UserOptions } options An option to parse.
|
||||
* @returns {Options} Normalized option.
|
||||
*/
|
||||
function normalizeOptions(options) {
|
||||
if (!options) {
|
||||
return {}
|
||||
}
|
||||
|
||||
/** @type {Options} */
|
||||
const normalized = {}
|
||||
|
||||
for (const blockName of Object.keys(options)) {
|
||||
const value = options[blockName]
|
||||
if (value) {
|
||||
normalized[blockName] = normalizeOption(blockName, value)
|
||||
}
|
||||
}
|
||||
|
||||
return normalized
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow use other than available `lang`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/block-lang.html'
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
'^(?:\\S+)$': {
|
||||
oneOf: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
lang: {
|
||||
anyOf: [
|
||||
{ type: 'string' },
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
]
|
||||
},
|
||||
allowNoLang: { type: 'boolean' }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
minProperties: 1,
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expected:
|
||||
"Only {{allows}} can be used for the 'lang' attribute of '<{{tag}}>'.",
|
||||
missing: "The 'lang' attribute of '<{{tag}}>' is missing.",
|
||||
unexpected: "Do not specify the 'lang' attribute of '<{{tag}}>'.",
|
||||
useOrNot:
|
||||
"Only {{allows}} can be used for the 'lang' attribute of '<{{tag}}>'. Or, not specifying the `lang` attribute is allowed.",
|
||||
unexpectedDefault:
|
||||
"Do not explicitly specify the default language for the 'lang' attribute of '<{{tag}}>'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = normalizeOptions(
|
||||
context.options[0] || {
|
||||
script: { allowNoLang: true },
|
||||
template: { allowNoLang: true },
|
||||
style: { allowNoLang: true }
|
||||
}
|
||||
)
|
||||
if (!Object.keys(options).length) {
|
||||
// empty
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VElement} element
|
||||
* @returns {void}
|
||||
*/
|
||||
function verify(element) {
|
||||
const tag = element.name
|
||||
const option = options[tag]
|
||||
if (!option) {
|
||||
return
|
||||
}
|
||||
const lang = utils.getAttribute(element, 'lang')
|
||||
if (lang == null || lang.value == null) {
|
||||
if (!option.allowNoLang) {
|
||||
context.report({
|
||||
node: element.startTag,
|
||||
messageId: 'missing',
|
||||
data: {
|
||||
tag
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
if (!option.lang.has(lang.value.value)) {
|
||||
let messageId
|
||||
if (!option.allowNoLang) {
|
||||
messageId = 'expected'
|
||||
} else if (option.lang.size === 0) {
|
||||
if ((DEFAULT_LANGUAGES[tag] || []).includes(lang.value.value)) {
|
||||
messageId = 'unexpectedDefault'
|
||||
} else {
|
||||
messageId = 'unexpected'
|
||||
}
|
||||
} else {
|
||||
messageId = 'useOrNot'
|
||||
}
|
||||
context.report({
|
||||
node: lang,
|
||||
messageId,
|
||||
data: {
|
||||
tag,
|
||||
allows: getAllowsLangPhrase(option.lang)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.defineDocumentVisitor(context, {
|
||||
'VDocumentFragment > VElement': verify
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user