forked from vuejs/vue-test-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind-vue-components.js
123 lines (112 loc) · 3.11 KB
/
find-vue-components.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// @flow
import { FUNCTIONAL_OPTIONS, VUE_VERSION } from './consts'
import { throwError } from 'shared/util'
export function findAllVueComponentsFromVm (
vm: Component,
components: Array<Component> = []
): Array<Component> {
components.push(vm)
vm.$children.forEach(child => {
findAllVueComponentsFromVm(child, components)
})
return components
}
function findAllVueComponentsFromVnode (
vnode: Component,
components: Array<Component> = []
): Array<Component> {
if (vnode.child) {
components.push(vnode.child)
}
if (vnode.children) {
vnode.children.forEach(child => {
findAllVueComponentsFromVnode(child, components)
})
}
return components
}
function findAllFunctionalComponentsFromVnode (
vnode: Component,
components: Array<Component> = []
): Array<Component> {
if (vnode[FUNCTIONAL_OPTIONS] || vnode.functionalContext) {
components.push(vnode)
}
if (vnode.children) {
vnode.children.forEach(child => {
findAllFunctionalComponentsFromVnode(child, components)
})
}
return components
}
export function vmCtorMatchesName (vm: Component, name: string): boolean {
return !!(
name && (
(vm._vnode &&
vm._vnode.functionalOptions &&
vm._vnode.functionalOptions.name === name) ||
(vm.$options && vm.$options.name === name) ||
(vm.options && vm.options.name === name)
))
}
export function vmCtorMatchesSelector (
component: Component,
selector: Object
): boolean {
const Ctor = selector._Ctor || (selector.options && selector.options._Ctor)
if (!Ctor) {
return false
}
const constructor = component.__proto__.constructor
return Object.keys(Ctor || {}).some(c => {
return Ctor[c] === constructor || Ctor[c] === constructor.super
})
}
export function vmFunctionalCtorMatchesSelector (
component: VNode,
Ctor: Object
): boolean {
if (VUE_VERSION < 2.3) {
throwError(
`find for functional components is not supported in ` + `Vue < 2.3`
)
}
if (!Ctor) {
return false
}
if (!component[FUNCTIONAL_OPTIONS]) {
return false
}
const Ctors = Object.keys(component[FUNCTIONAL_OPTIONS]._Ctor)
return Ctors.some(c => Ctor[c] === component[FUNCTIONAL_OPTIONS]._Ctor[c])
}
export default function findVueComponents (
root: Component,
selectorType: ?string,
selector: Object
): Array<Component> {
if (selector.functional) {
const nodes = root._vnode
? findAllFunctionalComponentsFromVnode(root._vnode)
: findAllFunctionalComponentsFromVnode(root)
return nodes.filter(
node =>
vmFunctionalCtorMatchesSelector(node, selector._Ctor) ||
node[FUNCTIONAL_OPTIONS].name === selector.name
)
}
const nameSelector =
typeof selector === 'function' ? selector.extendOptions.name : selector.name
const components = root._isVue
? findAllVueComponentsFromVm(root)
: findAllVueComponentsFromVnode(root)
return components.filter(component => {
if (!component.$vnode && !component.$options.extends) {
return false
}
return (
vmCtorMatchesSelector(component, selector) ||
vmCtorMatchesName(component, nameSelector)
)
})
}