prefer-true-attribute-shorthand.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * @author Pig Fang
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. module.exports = {
  8. meta: {
  9. type: 'suggestion',
  10. docs: {
  11. description:
  12. 'require shorthand form attribute when `v-bind` value is `true`',
  13. categories: undefined,
  14. url: 'https://eslint.vuejs.org/rules/prefer-true-attribute-shorthand.html'
  15. },
  16. fixable: null,
  17. hasSuggestions: true,
  18. schema: [{ enum: ['always', 'never'] }],
  19. messages: {
  20. expectShort:
  21. "Boolean prop with 'true' value should be written in shorthand form.",
  22. expectLong:
  23. "Boolean prop with 'true' value should be written in long form.",
  24. rewriteIntoShort: 'Rewrite this prop into shorthand form.',
  25. rewriteIntoLongVueProp:
  26. 'Rewrite this prop into long-form Vue component prop.',
  27. rewriteIntoLongHtmlAttr:
  28. 'Rewrite this prop into long-form HTML attribute.'
  29. }
  30. },
  31. /** @param {RuleContext} context */
  32. create(context) {
  33. /** @type {'always' | 'never'} */
  34. const option = context.options[0] || 'always'
  35. return utils.defineTemplateBodyVisitor(context, {
  36. VAttribute(node) {
  37. if (!utils.isCustomComponent(node.parent.parent)) {
  38. return
  39. }
  40. if (option === 'never' && !node.directive && !node.value) {
  41. context.report({
  42. node,
  43. messageId: 'expectLong',
  44. suggest: [
  45. {
  46. messageId: 'rewriteIntoLongVueProp',
  47. fix: (fixer) =>
  48. fixer.replaceText(node, `:${node.key.rawName}="true"`)
  49. },
  50. {
  51. messageId: 'rewriteIntoLongHtmlAttr',
  52. fix: (fixer) =>
  53. fixer.replaceText(
  54. node,
  55. `${node.key.rawName}="${node.key.rawName}"`
  56. )
  57. }
  58. ]
  59. })
  60. return
  61. }
  62. if (option !== 'always') {
  63. return
  64. }
  65. if (
  66. !node.directive ||
  67. !node.value ||
  68. !node.value.expression ||
  69. node.value.expression.type !== 'Literal' ||
  70. node.value.expression.value !== true
  71. ) {
  72. return
  73. }
  74. const { argument } = node.key
  75. if (!argument) {
  76. return
  77. }
  78. context.report({
  79. node,
  80. messageId: 'expectShort',
  81. suggest: [
  82. {
  83. messageId: 'rewriteIntoShort',
  84. fix: (fixer) => {
  85. const sourceCode = context.getSourceCode()
  86. return fixer.replaceText(node, sourceCode.getText(argument))
  87. }
  88. }
  89. ]
  90. })
  91. }
  92. })
  93. }
  94. }