quote-props.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * @author Yosuke Ota
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. const { wrapStylisticOrCoreRule, flatten } = require('../utils')
  7. // eslint-disable-next-line internal/no-invalid-meta
  8. module.exports = wrapStylisticOrCoreRule('quote-props', {
  9. skipDynamicArguments: true,
  10. preprocess(context, { wrapContextToOverrideProperties, defineVisitor }) {
  11. const sourceCode = context.getSourceCode()
  12. /**
  13. * @type {'"' | "'" | null}
  14. */
  15. let htmlQuote = null
  16. defineVisitor({
  17. /** @param {VExpressionContainer} node */
  18. 'VAttribute > VExpressionContainer.value'(node) {
  19. const text = sourceCode.getText(node)
  20. const firstChar = text[0]
  21. htmlQuote = firstChar === "'" || firstChar === '"' ? firstChar : null
  22. },
  23. 'VAttribute > VExpressionContainer.value:exit'() {
  24. htmlQuote = null
  25. }
  26. })
  27. wrapContextToOverrideProperties({
  28. // Override the report method and replace the quotes in the fixed text with safe quotes.
  29. report(descriptor) {
  30. if (htmlQuote) {
  31. const expectedQuote = htmlQuote === '"' ? "'" : '"'
  32. context.report({
  33. ...descriptor,
  34. *fix(fixer) {
  35. for (const fix of flatten(
  36. descriptor.fix && descriptor.fix(fixer)
  37. )) {
  38. yield fixer.replaceTextRange(
  39. fix.range,
  40. fix.text.replace(/["']/gu, expectedQuote)
  41. )
  42. }
  43. }
  44. })
  45. } else {
  46. context.report(descriptor)
  47. }
  48. }
  49. })
  50. }
  51. })