-
Notifications
You must be signed in to change notification settings - Fork 0
/
component.js
72 lines (65 loc) · 2.09 KB
/
component.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
import _ from 'lodash'
import 'element-qsa-scope'
if (!Element.prototype.matches) {
Element.prototype.matches = Element.prototype.msMatchesSelector
}
let getComponentsFromNodes = (node, nodes = []) => {
nodes = [].slice.call(nodes)
if (nodes.indexOf(node) > -1) {
nodes.splice(nodes.indexOf(node), 1)
}
let components = []
_.each(nodes, (node) => {
if (node.$component) {
components.push(node.$component)
}
})
return components
}
let getPropertiesFromPrototypesChain = (obj, parentProperties = []) => {
if (obj == null || (typeof obj !== 'object') || !obj.__proto__) {
return parentProperties
}
var properties = Object.getOwnPropertyNames(obj.__proto__).concat(parentProperties)
if (obj.__proto__.constructor && obj.__proto__.constructor.name !== '_class') {
properties = getPropertiesFromPrototypesChain(obj.__proto__, properties)
}
return properties
}
export default class {
constructor(node) {
this.$node = node
this.init()
_.each(getPropertiesFromPrototypesChain(this), (property) => {
if (property.charAt(0) === '@') {
this.$node.addEventListener(property.substring(1), this[property].bind(this))
}
})
}
init() { }
$findSiblings(componentName) {
let query = componentName ? `:scope > [data-component='${componentName}']` : ':scope > [data-component]'
return getComponentsFromNodes(this.$node, this.$node.parentNode.querySelectorAll(query))
}
get $siblings() {
return this.$findSiblings()
}
$findChildren(componentName) {
let query = componentName ? `:scope [data-component='${componentName}']` : ':scope [data-component]'
return getComponentsFromNodes(this.$node, this.$node.querySelectorAll(query))
}
get $children() {
return this.$findChildren()
}
$findParent(componentName) {
let query = componentName ? `[data-component='${componentName}']` : '[data-component]'
let node = this.$node.parentElement
while (node && !node.matches(query)) {
node = node.parentElement
}
return node ? node.$component : undefined
}
get $parent() {
return this.$findParent()
}
}