forked from vuejs/vue-test-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind-vnodes.js
76 lines (65 loc) · 2.01 KB
/
find-vnodes.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
// @flow
import {
REF_SELECTOR
} from './consts'
import {
throwError
} from 'shared/util'
function findAllVNodes (vnode: VNode, nodes: Array<VNode> = []): Array<VNode> {
nodes.push(vnode)
if (Array.isArray(vnode.children)) {
vnode.children.forEach((childVNode) => {
findAllVNodes(childVNode, nodes)
})
}
if (vnode.child) {
findAllVNodes(vnode.child._vnode, nodes)
}
return nodes
}
function removeDuplicateNodes (vNodes: Array<VNode>): Array<VNode> {
const vNodeElms = vNodes.map(vNode => vNode.elm)
return vNodes.filter((vNode, index) => index === vNodeElms.indexOf(vNode.elm))
}
function nodeMatchesRef (node: VNode, refName: string): boolean {
return node.data && node.data.ref === refName
}
function findVNodesByRef (vNode: VNode, refName: string): Array<VNode> {
const nodes = findAllVNodes(vNode)
const refFilteredNodes = nodes.filter(node => nodeMatchesRef(node, refName))
// Only return refs defined on top-level VNode to provide the same
// behavior as selecting via vm.$ref.{someRefName}
const mainVNodeFilteredNodes = refFilteredNodes.filter(node => (
!!vNode.context.$refs[node.data.ref]
))
return removeDuplicateNodes(mainVNodeFilteredNodes)
}
function nodeMatchesSelector (node: VNode, selector: string): boolean {
return node.elm && node.elm.getAttribute && node.elm.matches(selector)
}
function findVNodesBySelector (
vNode: VNode,
selector: string
): Array<VNode> {
const nodes = findAllVNodes(vNode)
const filteredNodes = nodes.filter(node => (
nodeMatchesSelector(node, selector)
))
return removeDuplicateNodes(filteredNodes)
}
export default function findVnodes (
vnode: VNode,
vm: Component | null,
selectorType: ?string,
selector: Object | string
): Array<VNode> {
if (selectorType === REF_SELECTOR) {
if (!vm) {
throwError('$ref selectors can only be used on Vue component wrappers')
}
// $FlowIgnore
return findVNodesByRef(vnode, selector.ref)
}
// $FlowIgnore
return findVNodesBySelector(vnode, selector)
}