Skip to content

Commit ce9e1bf

Browse files
lusarzeddyerburgh
authored andcommitted
refactor: refactor add-slots.js (#556)
1 parent 807d3c8 commit ce9e1bf

File tree

3 files changed

+53
-59
lines changed

3 files changed

+53
-59
lines changed

packages/create-instance/add-slots.js

+27-44
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,43 @@
11
// @flow
22

33
import { compileToFunctions } from 'vue-template-compiler'
4-
import { throwError } from 'shared/util'
54
import { validateSlots } from './validate-slots'
5+
import { toArray } from 'shared/util'
66

7-
function addSlotToVm (vm: Component, slotName: string, slotValue: Component | string | Array<Component> | Array<string>): void {
8-
let elem
9-
if (typeof slotValue === 'string') {
10-
if (!compileToFunctions) {
11-
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined')
12-
}
13-
if (typeof window === 'undefined') {
14-
throwError('the slots string option does not support strings in server-test-uitls.')
15-
}
16-
if (window.navigator.userAgent.match(/PhantomJS/i)) {
17-
throwError('the slots option does not support strings in PhantomJS. Please use Puppeteer, or pass a component.')
18-
}
19-
const domParser = new window.DOMParser()
20-
const _document = domParser.parseFromString(slotValue, 'text/html')
21-
const _slotValue = slotValue.trim()
22-
if (_slotValue[0] === '<' && _slotValue[_slotValue.length - 1] === '>' && _document.body.childElementCount === 1) {
23-
elem = vm.$createElement(compileToFunctions(slotValue))
24-
} else {
25-
const compiledResult = compileToFunctions(`<div>${slotValue}{{ }}</div>`)
26-
const _staticRenderFns = vm._renderProxy.$options.staticRenderFns
27-
vm._renderProxy.$options.staticRenderFns = compiledResult.staticRenderFns
28-
elem = compiledResult.render.call(vm._renderProxy, vm.$createElement).children
29-
vm._renderProxy.$options.staticRenderFns = _staticRenderFns
30-
}
31-
} else {
32-
elem = vm.$createElement(slotValue)
7+
function isSingleHTMLTag (template: string) {
8+
if (!template.startsWith('<') || !template.endsWith('>')) {
9+
return false
3310
}
34-
if (Array.isArray(elem)) {
35-
if (Array.isArray(vm.$slots[slotName])) {
36-
vm.$slots[slotName] = [...vm.$slots[slotName], ...elem]
11+
const _document = new window.DOMParser().parseFromString(template, 'text/html')
12+
return _document.body.childElementCount === 1
13+
}
14+
15+
function createElementFromAdvancedString (slotValue, vm) {
16+
const compiledResult = compileToFunctions(`<div>${slotValue}{{ }}</div>`)
17+
const _staticRenderFns = vm._renderProxy.$options.staticRenderFns
18+
vm._renderProxy.$options.staticRenderFns = compiledResult.staticRenderFns
19+
const elem = compiledResult.render.call(vm._renderProxy, vm.$createElement).children
20+
vm._renderProxy.$options.staticRenderFns = _staticRenderFns
21+
return elem
22+
}
23+
24+
function createElement (slotValue: string | Object, vm) {
25+
if (typeof slotValue === 'string') {
26+
slotValue = slotValue.trim()
27+
if (isSingleHTMLTag(slotValue)) {
28+
return vm.$createElement(compileToFunctions(slotValue))
3729
} else {
38-
vm.$slots[slotName] = [...elem]
30+
return createElementFromAdvancedString(slotValue, vm)
3931
}
4032
} else {
41-
if (Array.isArray(vm.$slots[slotName])) {
42-
vm.$slots[slotName].push(elem)
43-
} else {
44-
vm.$slots[slotName] = [elem]
45-
}
33+
return vm.$createElement(slotValue)
4634
}
4735
}
4836

4937
export function addSlots (vm: Component, slots: Object): void {
5038
validateSlots(slots)
51-
Object.keys(slots).forEach((key) => {
52-
if (Array.isArray(slots[key])) {
53-
slots[key].forEach((slotValue) => {
54-
addSlotToVm(vm, key, slotValue)
55-
})
56-
} else {
57-
addSlotToVm(vm, key, slots[key])
58-
}
39+
Object.keys(slots).forEach(name => {
40+
vm.$slots[name] = toArray(slots[name])
41+
.map(slotValue => createElement(slotValue, vm))
5942
})
6043
}
+18-15
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
// @flow
22

3-
import { throwError } from 'shared/util'
4-
5-
function isValidSlot (slot: any): boolean {
6-
return Array.isArray(slot) || (slot !== null && typeof slot === 'object') || typeof slot === 'string'
7-
}
3+
import { throwError, toArray, isObject } from 'shared/util'
4+
import { compileToFunctions } from 'vue-template-compiler'
85

96
export function validateSlots (slots: Object): void {
10-
slots && Object.keys(slots).forEach((key) => {
11-
if (!isValidSlot(slots[key])) {
12-
throwError('slots[key] must be a Component, string or an array of Components')
13-
}
7+
Object.keys(slots).forEach(key => {
8+
toArray(slots[key]).forEach(slotValue => {
9+
if (!isObject(slotValue) && typeof slotValue !== 'string') {
10+
throwError('slots[key] must be a Component, string or an array of Components')
11+
}
1412

15-
if (Array.isArray(slots[key])) {
16-
slots[key].forEach((slotValue) => {
17-
if (!isValidSlot(slotValue)) {
18-
throwError('slots[key] must be a Component, string or an array of Components')
13+
if (typeof slotValue === 'string') {
14+
if (!compileToFunctions) {
15+
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined')
16+
}
17+
if (typeof window === 'undefined') {
18+
throwError('the slots string option does not support strings in server-test-uitls.')
19+
}
20+
if (window.navigator.userAgent.match(/PhantomJS/i)) {
21+
throwError('the slots option does not support strings in PhantomJS. Please use Puppeteer, or pass a component.')
1922
}
20-
})
21-
}
23+
}
24+
})
2225
})
2326
}

packages/shared/util.js

+8
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@ export const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.sli
2121
*/
2222
const hyphenateRE = /\B([A-Z])/g
2323
export const hyphenate = (str: string) => str.replace(hyphenateRE, '-$1').toLowerCase()
24+
25+
export function toArray (value: any) {
26+
return Array.isArray(value) ? value : [value]
27+
}
28+
29+
export function isObject (obj: mixed): boolean %checks {
30+
return obj !== null && typeof obj === 'object'
31+
}

0 commit comments

Comments
 (0)