You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					84 lines
				
				2.3 KiB
			
		
		
			
		
	
	
					84 lines
				
				2.3 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @author Yosuke Ota
							 | 
						||
| 
								 | 
							
								 * See LICENSE file in root directory for full license.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								module.exports = {
							 | 
						||
| 
								 | 
							
								  supported: '2.6.0',
							 | 
						||
| 
								 | 
							
								  createTemplateBodyVisitor (context) {
							 | 
						||
| 
								 | 
							
								    const sourceCode = context.getSourceCode()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Checks whether the given node can convert to the `slot`.
							 | 
						||
| 
								 | 
							
								     * @param {VAttribute} vSlotAttr node of `v-slot`
							 | 
						||
| 
								 | 
							
								     * @returns {boolean} `true` if the given node can convert to the `slot`
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function canConvertToSlot (vSlotAttr) {
							 | 
						||
| 
								 | 
							
								      if (vSlotAttr.parent.parent.name !== 'template') {
							 | 
						||
| 
								 | 
							
								        return false
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return true
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Convert to `slot` and `slot-scope`.
							 | 
						||
| 
								 | 
							
								     * @param {object} fixer fixer
							 | 
						||
| 
								 | 
							
								     * @param {VAttribute} vSlotAttr node of `v-slot`
							 | 
						||
| 
								 | 
							
								     * @returns {*} fix data
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function fixVSlotToSlot (fixer, vSlotAttr) {
							 | 
						||
| 
								 | 
							
								      const key = vSlotAttr.key
							 | 
						||
| 
								 | 
							
								      if (key.modifiers.length) {
							 | 
						||
| 
								 | 
							
								        // unknown modifiers
							 | 
						||
| 
								 | 
							
								        return null
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const attrs = []
							 | 
						||
| 
								 | 
							
								      const argument = key.argument
							 | 
						||
| 
								 | 
							
								      if (argument) {
							 | 
						||
| 
								 | 
							
								        if (argument.type === 'VIdentifier') {
							 | 
						||
| 
								 | 
							
								          const name = argument.rawName
							 | 
						||
| 
								 | 
							
								          attrs.push(`slot="${name}"`)
							 | 
						||
| 
								 | 
							
								        } else if (argument.type === 'VExpressionContainer' && argument.expression) {
							 | 
						||
| 
								 | 
							
								          const expression = sourceCode.getText(argument.expression)
							 | 
						||
| 
								 | 
							
								          attrs.push(`:slot="${expression}"`)
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          // unknown or syntax error
							 | 
						||
| 
								 | 
							
								          return null
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      const scopedValueNode = vSlotAttr.value
							 | 
						||
| 
								 | 
							
								      if (scopedValueNode) {
							 | 
						||
| 
								 | 
							
								        attrs.push(
							 | 
						||
| 
								 | 
							
								          `slot-scope=${sourceCode.getText(scopedValueNode)}`
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (!attrs.length) {
							 | 
						||
| 
								 | 
							
								        attrs.push('slot') // useless
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return fixer.replaceText(vSlotAttr, attrs.join(' '))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Reports `v-slot` node
							 | 
						||
| 
								 | 
							
								     * @param {VAttribute} vSlotAttr node of `v-slot`
							 | 
						||
| 
								 | 
							
								     * @returns {void}
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function reportVSlot (vSlotAttr) {
							 | 
						||
| 
								 | 
							
								      context.report({
							 | 
						||
| 
								 | 
							
								        node: vSlotAttr.key,
							 | 
						||
| 
								 | 
							
								        messageId: 'forbiddenVSlot',
							 | 
						||
| 
								 | 
							
								        // fix to use `slot` (downgrade)
							 | 
						||
| 
								 | 
							
								        fix: fixer => {
							 | 
						||
| 
								 | 
							
								          if (!canConvertToSlot(vSlotAttr)) {
							 | 
						||
| 
								 | 
							
								            return null
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          return fixVSlotToSlot(fixer, vSlotAttr)
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      "VAttribute[directive=true][key.name.name='slot']": reportVSlot
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |