Skip to content
This repository was archived by the owner on Mar 8, 2019. It is now read-only.

Commit 5afc17d

Browse files
authored
feat: handle slots in render functions (#78)
* fix: describe typo * feat: handle slots in render functions
1 parent 44ed97e commit 5afc17d

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

src/script-handlers/__tests__/eventHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function parse(src: string): NodePath[] {
1111
return resolveExportedComponent(ast)
1212
}
1313

14-
describe('displayNameHandler', () => {
14+
describe('eventHandler', () => {
1515
let documentation: Documentation
1616
let mockEventDescriptor: EventDescriptor
1717

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { NodePath } from 'ast-types'
2+
import babylon from '../../babel-parser'
3+
import { Documentation, SlotDescriptor } from '../../Documentation'
4+
import resolveExportedComponent from '../../utils/resolveExportedComponent'
5+
import slotHandler from '../slotHandler'
6+
7+
jest.mock('../../Documentation')
8+
9+
function parse(src: string): NodePath[] {
10+
const ast = babylon().parse(src)
11+
return resolveExportedComponent(ast)
12+
}
13+
14+
describe('render function slotHandler', () => {
15+
let documentation: Documentation
16+
let mockSlotDescriptor: SlotDescriptor
17+
18+
beforeEach(() => {
19+
mockSlotDescriptor = { description: '' }
20+
documentation = new (require('../../Documentation')).Documentation()
21+
const mockGetSlotDescriptor = documentation.getSlotDescriptor as jest.Mock
22+
mockGetSlotDescriptor.mockReturnValue(mockSlotDescriptor)
23+
})
24+
25+
it('should find slots in render function', () => {
26+
const src = `
27+
export default {
28+
render: function (createElement) {
29+
return createElement('div', this.$slots.mySlot)
30+
}
31+
}
32+
`
33+
const def = parse(src)
34+
slotHandler(documentation, def[0])
35+
expect(documentation.getSlotDescriptor).toHaveBeenCalledWith('mySlot')
36+
})
37+
38+
it('should find scoped slots in render function', () => {
39+
const src = `
40+
export default {
41+
render: function (createElement) {
42+
return createElement('div', [
43+
this.$scopedSlots.myScopedSlot({
44+
text: this.message
45+
})
46+
])
47+
}
48+
}
49+
`
50+
const def = parse(src)
51+
slotHandler(documentation, def[0])
52+
expect(documentation.getSlotDescriptor).toHaveBeenCalledWith('myScopedSlot')
53+
})
54+
})

src/script-handlers/slotHandler.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as bt from '@babel/types'
2+
import { NodePath } from 'ast-types'
3+
import { Documentation, ParamTag, ParamType } from '../Documentation'
4+
5+
export interface TypedParamTag extends ParamTag {
6+
type: ParamType
7+
}
8+
9+
// tslint:disable-next-line:no-var-requires
10+
import recast = require('recast')
11+
12+
export default function eventHandler(documentation: Documentation, path: NodePath) {
13+
if (bt.isObjectExpression(path.node)) {
14+
const renderPath = path
15+
.get('properties')
16+
.filter((p: NodePath) => bt.isObjectProperty(p.node) && p.node.key.name === 'render')
17+
18+
// if no prop return
19+
if (!renderPath.length) {
20+
return
21+
}
22+
23+
const renderValuePath = renderPath[0].get('value')
24+
recast.visit(renderValuePath, {
25+
visitCallExpression(pathCall: NodePath<bt.CallExpression>) {
26+
if (
27+
bt.isMemberExpression(pathCall.node.callee) &&
28+
bt.isMemberExpression(pathCall.node.callee.object) &&
29+
bt.isThisExpression(pathCall.node.callee.object.object) &&
30+
bt.isIdentifier(pathCall.node.callee.property) &&
31+
pathCall.node.callee.object.property.name === '$scopedSlots'
32+
) {
33+
documentation.getSlotDescriptor(pathCall.node.callee.property.name)
34+
return false
35+
}
36+
this.traverse(pathCall)
37+
},
38+
visitMemberExpression(pathMember: NodePath<bt.MemberExpression>) {
39+
if (
40+
bt.isMemberExpression(pathMember.node.object) &&
41+
bt.isThisExpression(pathMember.node.object.object) &&
42+
bt.isIdentifier(pathMember.node.object.property) &&
43+
pathMember.node.object.property.name === '$slots' &&
44+
bt.isIdentifier(pathMember.node.property)
45+
) {
46+
documentation.getSlotDescriptor(pathMember.node.property.name)
47+
return false
48+
}
49+
this.traverse(pathMember)
50+
},
51+
})
52+
}
53+
}

0 commit comments

Comments
 (0)