-
-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
611af52
commit 6674f2a
Showing
8 changed files
with
190 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<template> | ||
<div> | ||
<!-- default slot --> | ||
<slot> | ||
<!-- Default Slot Content --> | ||
<p></p> | ||
</slot> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
} | ||
</script> | ||
|
||
<style> | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<template> | ||
<div> | ||
<!-- head slot --> | ||
<slot name="header"> | ||
<!-- Default Slot Content --> | ||
<p></p> | ||
</slot> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
} | ||
</script> | ||
|
||
<style> | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<template> | ||
<div> | ||
<!-- Named slot --> | ||
<slot name="header" :a="someData" b="str"> | ||
<!-- Default Slot Content --> | ||
<p></p> | ||
</slot> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
} | ||
</script> | ||
|
||
<style> | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import * as path from 'path' | ||
import * as fs from 'fs' | ||
import sfcToAST, { AstResult } from '../sfcToAST' | ||
import parseTemplate, { SlotResult } from '../parseTemplate' | ||
|
||
function getAST(fileName: string): object { | ||
const p = path.resolve(__dirname, `../../../__fixtures__/${fileName}`) | ||
const source = fs.readFileSync(p, 'utf-8') | ||
return sfcToAST(source) | ||
} | ||
|
||
test('Default slot with slot description', () => { | ||
const sfc: AstResult = getAST('defaultSlot.vue') | ||
const slotRes: SlotResult[] = parseTemplate(sfc.templateAst) | ||
expect(slotRes.length).toBe(1) | ||
expect(slotRes[0].name).toBe('default') | ||
expect(slotRes[0].describe).toBe('default slot') | ||
expect(slotRes[0].backerDesc).toBe('Default Slot Content') | ||
expect(slotRes[0].bindings).toEqual({}) | ||
}) | ||
|
||
test('Named slot with slot description', () => { | ||
const sfc: AstResult = getAST('namedSlot.vue') | ||
const slotRes: SlotResult[] = parseTemplate(sfc.templateAst) | ||
expect(slotRes.length).toBe(1) | ||
expect(slotRes[0].name).toBe('header') | ||
expect(slotRes[0].describe).toBe('head slot') | ||
expect(slotRes[0].backerDesc).toBe('Default Slot Content') | ||
expect(slotRes[0].bindings).toEqual({}) | ||
}) | ||
|
||
test('Named slot with slot description and bingdings', () => { | ||
const sfc: AstResult = getAST('slotWithBindings.vue') | ||
const slotRes: SlotResult[] = parseTemplate(sfc.templateAst) | ||
expect(slotRes.length).toBe(1) | ||
expect(slotRes[0].name).toBe('header') | ||
expect(slotRes[0].describe).toBe('Named slot') | ||
expect(slotRes[0].backerDesc).toBe('Default Slot Content') | ||
expect(slotRes[0].bindings).toEqual({ | ||
a: 'someData', | ||
b: 'str' | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,86 @@ | ||
import { parse } from 'vue-template-compiler' | ||
export interface SlotResult { | ||
name: string | ||
describe: string | ||
backerDesc: string | ||
bindings: AttrsMap | ||
} | ||
|
||
export default function() {} | ||
export default function traverse(templateAst: any): SlotResult[] { | ||
const parent = templateAst.parent | ||
let res: SlotResult[] = [] | ||
if (templateAst.type === 1) { | ||
if (templateAst.tag === 'slot') { | ||
const slot: SlotResult = { | ||
name: 'default', | ||
describe: '', | ||
backerDesc: '', | ||
bindings: {} | ||
} | ||
slot.bindings = extractAndFilterAttr(templateAst.attrsMap) | ||
if (slot.bindings.name) { | ||
slot.name = slot.bindings.name | ||
delete slot.bindings.name | ||
} | ||
if (parent) { | ||
const list: [] = parent.children | ||
let currentSlotIndex = 0 | ||
for (let i = 0; i < list.length; i++) { | ||
let el = list[i] | ||
if (el === templateAst) { | ||
currentSlotIndex = i | ||
break | ||
} | ||
} | ||
|
||
// Find the first leading comment node as a description of the slot | ||
const copies = list.slice(0, currentSlotIndex).reverse() | ||
for (let i = 0; i < copies.length; i++) { | ||
let el: any = copies[i] | ||
if (el.type !== 3 || (!el.isComment && el.text.trim())) break | ||
if ( | ||
el.isComment && | ||
!(parent.tag === 'slot' && parent.children[0] === el) | ||
) { | ||
slot.describe = el.text.trim() | ||
break | ||
} | ||
} | ||
|
||
// Find the first child comment node as a description of the default slot content | ||
if (templateAst.children.length) { | ||
for (let i = 0; i < templateAst.children.length; i++) { | ||
let el: any = templateAst.children[i] | ||
if (el.type !== 3 || (!el.isComment && el.text.trim())) break | ||
if (el.isComment) { | ||
slot.backerDesc = el.text.trim() | ||
break | ||
} | ||
} | ||
} | ||
} | ||
res.push(slot) | ||
} | ||
for (let i = 0; i < templateAst.children.length; i++) { | ||
res = res.concat(traverse(templateAst.children[i])) | ||
} | ||
} | ||
|
||
return res | ||
} | ||
|
||
type AttrsMap = { | ||
[key: string]: string | ||
} | ||
const dirRE = /^(v-|:|@)/ | ||
const allowRE = /^(v-bind|:)/ | ||
function extractAndFilterAttr(attrsMap: AttrsMap): AttrsMap { | ||
const res: AttrsMap = {} | ||
const keys = Object.keys(attrsMap) | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
if (!dirRE.test(key) || allowRE.test(key)) { | ||
res[key.replace(allowRE, '')] = attrsMap[key] | ||
} | ||
} | ||
return res | ||
} |