|
1 | 1 | // @flow
|
2 | 2 |
|
3 | 3 | import { compileToFunctions } from 'vue-template-compiler'
|
4 |
| -import { throwError } from 'shared/util' |
5 | 4 | import { validateSlots } from './validate-slots'
|
| 5 | +import { toArray } from 'shared/util' |
6 | 6 |
|
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 |
33 | 10 | }
|
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)) |
37 | 29 | } else {
|
38 |
| - vm.$slots[slotName] = [...elem] |
| 30 | + return createElementFromAdvancedString(slotValue, vm) |
39 | 31 | }
|
40 | 32 | } 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) |
46 | 34 | }
|
47 | 35 | }
|
48 | 36 |
|
49 | 37 | export function addSlots (vm: Component, slots: Object): void {
|
50 | 38 | 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)) |
59 | 42 | })
|
60 | 43 | }
|
0 commit comments