jails-js 5.0.0-beta.6 → 5.0.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +6 -0
- package/README.md +7 -37
- package/dist/jails.js +1 -1
- package/dist/jails.js.map +1 -1
- package/package.json +41 -39
- package/src/component.ts +158 -0
- package/src/element.ts +35 -0
- package/src/index.ts +18 -52
- package/src/template-system.ts +89 -0
- package/src/utils/{events.js → events.ts} +0 -0
- package/src/utils/index.ts +58 -0
- package/src/utils/{pubsub.js → pubsub.ts} +2 -2
- package/tsconfig.json +13 -3
- package/src/Component.ts +0 -123
- package/src/Element.ts +0 -128
- package/src/Instances.ts +0 -1
- package/src/Scanner.ts +0 -26
- package/src/soda-config.js +0 -87
- package/src/utils/index.js +0 -41
package/package.json
CHANGED
@@ -1,41 +1,43 @@
|
|
1
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
|
-
|
2
|
+
"name": "jails-js",
|
3
|
+
"version": "5.0.0-beta.9",
|
4
|
+
"description": "A Modern Javascript Library",
|
5
|
+
"main": "dist/jails.js",
|
6
|
+
"scripts": {
|
7
|
+
"start": "webpack --watch --mode=development",
|
8
|
+
"build": "webpack --mode=production",
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
10
|
+
},
|
11
|
+
"repository": {
|
12
|
+
"type": "git",
|
13
|
+
"url": "https://github.com/jails-org/Jails.git"
|
14
|
+
},
|
15
|
+
"keywords": [
|
16
|
+
"Jails",
|
17
|
+
"Javascript",
|
18
|
+
"Component",
|
19
|
+
"Micro-Library"
|
20
|
+
],
|
21
|
+
"author": "javiani",
|
22
|
+
"license": "MIT",
|
23
|
+
"bugs": {
|
24
|
+
"url": "https://github.com/jails-org/Jails/issues"
|
25
|
+
},
|
26
|
+
"homepage": "https://github.com/jails-org/Jails",
|
27
|
+
"devDependencies": {
|
28
|
+
"@babel/core": "^7.2.2",
|
29
|
+
"@babel/preset-env": "^7.2.3",
|
30
|
+
"babel-loader": "^8.0.5",
|
31
|
+
"babel-plugin-transform-custom-element-classes": "^0.1.0",
|
32
|
+
"babel-preset-env": "^1.7.0",
|
33
|
+
"ts-loader": "^9.2.6",
|
34
|
+
"typescript": "^4.5.4",
|
35
|
+
"webpack": "^5.59.1",
|
36
|
+
"webpack-cli": "^3.2.1"
|
37
|
+
},
|
38
|
+
"dependencies": {
|
39
|
+
"morphdom": "^2.6.1",
|
40
|
+
"squirrelly": "^8.0.8",
|
41
|
+
"template7": "^1.4.2"
|
42
|
+
}
|
41
43
|
}
|
package/src/component.ts
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
import morphdom from 'morphdom'
|
2
|
+
|
3
|
+
import { rAF, dup, buildtemplates } from './utils'
|
4
|
+
import { on, off, trigger } from './utils/events'
|
5
|
+
import { publish, subscribe, unsubscribe } from './utils/pubsub'
|
6
|
+
|
7
|
+
type MainArgs = () => Array<Function>
|
8
|
+
|
9
|
+
export default function Component(elm, { module, dependencies, templates, components }) {
|
10
|
+
|
11
|
+
const options = getOptions(module)
|
12
|
+
|
13
|
+
buildtemplates(elm, components, templates)
|
14
|
+
|
15
|
+
const tplid = elm.getAttribute('tplid')
|
16
|
+
const template = templates[tplid]
|
17
|
+
const state = { data: module.model ? dup(module.model) : {} }
|
18
|
+
|
19
|
+
let batchUpdates = []
|
20
|
+
|
21
|
+
const base = {
|
22
|
+
template,
|
23
|
+
elm,
|
24
|
+
dependencies,
|
25
|
+
publish,
|
26
|
+
subscribe,
|
27
|
+
unsubscribe,
|
28
|
+
|
29
|
+
main(fn: MainArgs) {
|
30
|
+
options.main = fn
|
31
|
+
},
|
32
|
+
|
33
|
+
unmount(fn) {
|
34
|
+
options.unmount = fn
|
35
|
+
},
|
36
|
+
|
37
|
+
onupdate(fn) {
|
38
|
+
options.onupdate = fn
|
39
|
+
},
|
40
|
+
|
41
|
+
on(eventName: string, selectorOrCallback: object | Function, callback: Function) {
|
42
|
+
on(elm, eventName, selectorOrCallback, callback)
|
43
|
+
},
|
44
|
+
|
45
|
+
off(eventName: string, callback: Function) {
|
46
|
+
off(elm, eventName, callback)
|
47
|
+
},
|
48
|
+
|
49
|
+
trigger(eventName: string, target: string, args: any) {
|
50
|
+
if (target.constructor === String)
|
51
|
+
trigger(elm.querySelector(target), eventName, { args: args })
|
52
|
+
else trigger(elm, eventName, { args: target })
|
53
|
+
},
|
54
|
+
|
55
|
+
emit: (...args) => {
|
56
|
+
trigger(elm, args.shift(), { args: args })
|
57
|
+
},
|
58
|
+
|
59
|
+
state: {
|
60
|
+
set(data: any) {
|
61
|
+
if (data.constructor === Function) {
|
62
|
+
const newstate = dup(state.data)
|
63
|
+
data(newstate)
|
64
|
+
base.render(newstate)
|
65
|
+
} else {
|
66
|
+
base.render(data)
|
67
|
+
}
|
68
|
+
return new Promise((resolve) => rAF(_ => rAF(resolve)))
|
69
|
+
},
|
70
|
+
get() {
|
71
|
+
return dup(state.data)
|
72
|
+
}
|
73
|
+
},
|
74
|
+
|
75
|
+
render(data: object = state.data) {
|
76
|
+
|
77
|
+
if (!document.body.contains(elm))
|
78
|
+
return
|
79
|
+
|
80
|
+
batchUpdates.push(data)
|
81
|
+
|
82
|
+
rAF(() => {
|
83
|
+
rAF(() => {
|
84
|
+
if (batchUpdates.length) {
|
85
|
+
|
86
|
+
const batchData = {}
|
87
|
+
batchUpdates.forEach(d => Object.assign(batchData, d))
|
88
|
+
batchUpdates = []
|
89
|
+
|
90
|
+
state.data = Object.assign(state.data, batchData)
|
91
|
+
|
92
|
+
const newdata = dup(state.data)
|
93
|
+
const newhtml = base.template(options.view(newdata))
|
94
|
+
|
95
|
+
morphdom(elm, newhtml, morphdomOptions(elm, options))
|
96
|
+
|
97
|
+
Array
|
98
|
+
.from(elm.querySelectorAll('[tplid]'))
|
99
|
+
.map(child => {
|
100
|
+
child.options.onupdate(newdata)
|
101
|
+
child.base.render(newdata)
|
102
|
+
return child
|
103
|
+
})
|
104
|
+
}
|
105
|
+
})
|
106
|
+
})
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
return { base, options }
|
111
|
+
}
|
112
|
+
|
113
|
+
const getOptions = (module) => ({
|
114
|
+
main: _ => _,
|
115
|
+
unmount: _ => _,
|
116
|
+
onupdate: _ => _,
|
117
|
+
view: module.view ? module.view : _ => _
|
118
|
+
})
|
119
|
+
|
120
|
+
const morphdomOptions = (_parent, options) => ({
|
121
|
+
|
122
|
+
onNodeAdded: onUpdates(_parent, options),
|
123
|
+
onElUpdated: onUpdates(_parent, options),
|
124
|
+
onBeforeElChildrenUpdated: checkStatic,
|
125
|
+
onBeforeElUpdated: checkStatic,
|
126
|
+
|
127
|
+
getNodeKey(node) {
|
128
|
+
if (node.nodeType === 1 && node.getAttribute('tplid'))
|
129
|
+
return node.dataset.key || node.getAttribute('tplid')
|
130
|
+
return false
|
131
|
+
}
|
132
|
+
})
|
133
|
+
|
134
|
+
const checkStatic = (node) => {
|
135
|
+
if ('static' in node.dataset) {
|
136
|
+
return false
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
const onUpdates = (_parent, options) => (node) => {
|
141
|
+
|
142
|
+
if (node.nodeType === 1) {
|
143
|
+
|
144
|
+
if (node.getAttribute && node.getAttribute('scope')) {
|
145
|
+
|
146
|
+
const scope = JSON.parse(node.getAttribute('scope').replace(/\'/g, '\"'))
|
147
|
+
|
148
|
+
Array.from(node.querySelectorAll('[tplid]'))
|
149
|
+
.map(el => {
|
150
|
+
const data = Object.assign({}, _parent.base.state.get(), scope)
|
151
|
+
options.onupdate(data)
|
152
|
+
el.base.render(data)
|
153
|
+
})
|
154
|
+
|
155
|
+
node.removeAttribute('scope')
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
package/src/element.ts
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
import Component from './component'
|
2
|
+
|
3
|
+
export default function Element(module, dependencies, templates, components) {
|
4
|
+
|
5
|
+
return class extends HTMLElement {
|
6
|
+
|
7
|
+
constructor() {
|
8
|
+
|
9
|
+
super()
|
10
|
+
|
11
|
+
const { base, options } = Component(this, { module, dependencies, templates, components })
|
12
|
+
|
13
|
+
this.base = base
|
14
|
+
this.options = options
|
15
|
+
|
16
|
+
module.default(base)
|
17
|
+
}
|
18
|
+
|
19
|
+
connectedCallback() {
|
20
|
+
this.base.render()
|
21
|
+
this.options.main().forEach(f => f(this.base))
|
22
|
+
}
|
23
|
+
|
24
|
+
disconnectedCallback() {
|
25
|
+
this.options.unmount(this.base)
|
26
|
+
delete this.options
|
27
|
+
delete this.base
|
28
|
+
delete this.__events
|
29
|
+
}
|
30
|
+
|
31
|
+
attributeChangedCallback() {
|
32
|
+
//TODO
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
package/src/index.ts
CHANGED
@@ -1,62 +1,28 @@
|
|
1
|
-
import {
|
2
|
-
import
|
3
|
-
import { Component } from './Component'
|
4
|
-
import { Instances } from './Instances'
|
5
|
-
import { stripTemplateTag, dup } from './utils'
|
1
|
+
import { buildtemplates, stripTemplateTag } from './utils'
|
2
|
+
import Element from './element'
|
6
3
|
|
7
|
-
const
|
4
|
+
export const templates = {}
|
5
|
+
export const components = {}
|
8
6
|
|
9
7
|
export default {
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
const body: HTMLElement = document.body
|
14
|
-
|
15
|
-
stripTemplateTag( body )
|
16
|
-
|
17
|
-
Scanner.observe( body, createElement, disposeElement )
|
18
|
-
Scanner.scan( body, createElement )
|
9
|
+
register(name: string, module: any, dependencies: object = {}) {
|
10
|
+
components[name] = { name, module, dependencies }
|
19
11
|
},
|
20
12
|
|
21
|
-
|
22
|
-
|
13
|
+
start() {
|
14
|
+
const body = document.body
|
15
|
+
stripTemplateTag(body)
|
16
|
+
buildtemplates(body, components, templates)
|
17
|
+
registerComponents()
|
23
18
|
}
|
24
19
|
}
|
25
20
|
|
26
|
-
const
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
const C = components[name]
|
34
|
-
|
35
|
-
if( !C ) {
|
36
|
-
console.warn(`Jails - Module ${name} not registered`)
|
37
|
-
return
|
38
|
-
}
|
39
|
-
|
40
|
-
const { module, dependencies } = C
|
41
|
-
ElementInterface.model = Object.assign({}, module.model? dup(module.model) : null, ElementInterface.model )
|
42
|
-
|
43
|
-
const base = Component({ name, element, dependencies, ElementInterface })
|
44
|
-
const promise = module.default(base)
|
45
|
-
|
46
|
-
if( promise && promise.then ) {
|
47
|
-
ElementInterface.promises.push(promise)
|
48
|
-
}
|
49
|
-
|
50
|
-
base.__initialize()
|
51
|
-
ElementInterface.view = module.view || ElementInterface.view
|
52
|
-
ElementInterface.instances[name] = { methods: {} }
|
53
|
-
})
|
54
|
-
|
55
|
-
ElementInterface.update()
|
56
|
-
}
|
57
|
-
|
58
|
-
const disposeElement = ( node ) => {
|
59
|
-
const instance = Instances.get(node)
|
60
|
-
if( Instances.get(node) )
|
61
|
-
instance.dispose()
|
21
|
+
const registerComponents = () => {
|
22
|
+
Object
|
23
|
+
.values(components)
|
24
|
+
.forEach(({ name, module, dependencies }) => {
|
25
|
+
const Base = Element(module, dependencies, templates, components)
|
26
|
+
customElements.define(name, Base)
|
27
|
+
})
|
62
28
|
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import { compile, defaultConfig, filters } from 'squirrelly'
|
2
|
+
import { stripTemplateTag, decodeHtmlEntities } from './utils'
|
3
|
+
|
4
|
+
const defaultOptions = {
|
5
|
+
...defaultConfig,
|
6
|
+
tags: ['{', '}'],
|
7
|
+
useWith: true
|
8
|
+
}
|
9
|
+
|
10
|
+
export default function templateSystem(element) {
|
11
|
+
|
12
|
+
const vdom = element.cloneNode(true)
|
13
|
+
|
14
|
+
stripTemplateTag(vdom)
|
15
|
+
|
16
|
+
const newvdom = directives(vdom)
|
17
|
+
|
18
|
+
const html = decodeHtmlEntities(
|
19
|
+
newvdom.outerHTML
|
20
|
+
.replace(/html-(selected|checked|readonly|disabled|autoplay)=\"(.*)\"/g, `{@if ($2) }$1{/if}`)
|
21
|
+
.replace(/html-/g, '')
|
22
|
+
)
|
23
|
+
|
24
|
+
const template = compile(html, defaultOptions)
|
25
|
+
|
26
|
+
return (data) => {
|
27
|
+
return template(data, defaultOptions)
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
/**@Directives */
|
32
|
+
|
33
|
+
const directives = (vdom) => {
|
34
|
+
|
35
|
+
const nodes = Array
|
36
|
+
.from(vdom.querySelectorAll('[html-for],[html-if],[html-foreach]'))
|
37
|
+
.reverse()
|
38
|
+
|
39
|
+
if (nodes.length) {
|
40
|
+
|
41
|
+
nodes.forEach(node => {
|
42
|
+
if (node.getAttribute('html-foreach')) {
|
43
|
+
const instruction = node.getAttribute('html-foreach')
|
44
|
+
const split = instruction.match(/(.*)\sin\s(.*)/)
|
45
|
+
const varname = split[1]
|
46
|
+
const object = split[2]
|
47
|
+
node.removeAttribute('html-foreach')
|
48
|
+
node.setAttribute('scope', `{${varname} | JSON($key, '${varname}')}`)
|
49
|
+
const open = document.createTextNode(`{@foreach(${object}) => $key, ${varname}}`)
|
50
|
+
const close = document.createTextNode('{/foreach}')
|
51
|
+
wrap(open, node, close)
|
52
|
+
} else if (node.getAttribute('html-for')) {
|
53
|
+
const instruction = node.getAttribute('html-for')
|
54
|
+
const split = instruction.match(/(.*)\sin\s(.*)/)
|
55
|
+
const varname = split[1]
|
56
|
+
const object = split[2]
|
57
|
+
node.removeAttribute('html-for')
|
58
|
+
node.setAttribute('scope', `{${varname} | JSON($index, '${varname}')}`)
|
59
|
+
const open = document.createTextNode(`{@each(${object}) => ${varname}, $index}`)
|
60
|
+
const close = document.createTextNode('{/each}')
|
61
|
+
wrap(open, node, close)
|
62
|
+
} else if (node.getAttribute('html-if')) {
|
63
|
+
const instruction = node.getAttribute('html-if')
|
64
|
+
node.removeAttribute('html-if')
|
65
|
+
const open = document.createTextNode(`{@if (${instruction}) }`)
|
66
|
+
const close = document.createTextNode('{/if}')
|
67
|
+
wrap(open, node, close)
|
68
|
+
}
|
69
|
+
})
|
70
|
+
}
|
71
|
+
|
72
|
+
return vdom
|
73
|
+
}
|
74
|
+
|
75
|
+
filters.define('JSON', (scope, index, varname) => {
|
76
|
+
|
77
|
+
const key = index.constructor == String ? '$key' : '$index'
|
78
|
+
const newobject = { $index: index }
|
79
|
+
|
80
|
+
newobject[varname] = scope
|
81
|
+
newobject[key] = index
|
82
|
+
|
83
|
+
return JSON.stringify(newobject)
|
84
|
+
})
|
85
|
+
|
86
|
+
const wrap = (open, node, close) => {
|
87
|
+
node.parentNode.insertBefore(open, node)
|
88
|
+
node.parentNode.insertBefore(close, node.nextSibling)
|
89
|
+
}
|
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import templateSystem from '../template-system'
|
2
|
+
|
3
|
+
const textarea = document.createElement('textarea')
|
4
|
+
|
5
|
+
export const rAF = (fn) => {
|
6
|
+
(requestAnimationFrame || setTimeout)(fn, 1000 / 60)
|
7
|
+
}
|
8
|
+
|
9
|
+
export const uuid = () => {
|
10
|
+
return 'xxxxxxxx'.replace(/[xy]/g, (c) => {
|
11
|
+
const r = Math.random() * 8 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
|
12
|
+
return v.toString(8)
|
13
|
+
})
|
14
|
+
}
|
15
|
+
|
16
|
+
export const stripTemplateTag = (element) => {
|
17
|
+
const templates = Array.from(element.querySelectorAll('template'))
|
18
|
+
// https://gist.github.com/harmenjanssen/07e425248779c65bc5d11b02fb913274
|
19
|
+
templates.forEach(template => {
|
20
|
+
template.parentNode.replaceChild(template.content, template)
|
21
|
+
stripTemplateTag(template.content)
|
22
|
+
})
|
23
|
+
}
|
24
|
+
|
25
|
+
export const dup = (o) => {
|
26
|
+
return JSON.parse(JSON.stringify(o))
|
27
|
+
}
|
28
|
+
|
29
|
+
export const createTemplateId = (element, templates) => {
|
30
|
+
|
31
|
+
const tplid = element.getAttribute('tplid')
|
32
|
+
|
33
|
+
if (!tplid) {
|
34
|
+
const id = uuid()
|
35
|
+
element.setAttribute('tplid', id)
|
36
|
+
templates[id] = templateSystem(element)
|
37
|
+
return templates[id]
|
38
|
+
}
|
39
|
+
|
40
|
+
return templates[tplid]
|
41
|
+
}
|
42
|
+
|
43
|
+
export const buildtemplates = (target, components, templates) => {
|
44
|
+
|
45
|
+
return Array
|
46
|
+
.from(target.querySelectorAll('*'))
|
47
|
+
.filter(node => node.tagName.toLocaleLowerCase() in components)
|
48
|
+
.reverse()
|
49
|
+
.map(node => {
|
50
|
+
createTemplateId(node, templates)
|
51
|
+
return node
|
52
|
+
})
|
53
|
+
}
|
54
|
+
|
55
|
+
export const decodeHtmlEntities = (str) => {
|
56
|
+
textarea.innerHTML = str
|
57
|
+
return textarea.value
|
58
|
+
}
|
@@ -3,14 +3,14 @@ const _async = {}
|
|
3
3
|
|
4
4
|
export const publish = (name, params) => {
|
5
5
|
_async[name] = Object.assign({}, _async[name], params)
|
6
|
-
if(
|
6
|
+
if (topics[name])
|
7
7
|
topics[name].forEach(topic => topic(params))
|
8
8
|
}
|
9
9
|
|
10
10
|
export const subscribe = (name, method) => {
|
11
11
|
topics[name] = topics[name] || []
|
12
12
|
topics[name].push(method)
|
13
|
-
if (
|
13
|
+
if (name in _async) {
|
14
14
|
method(_async[name])
|
15
15
|
}
|
16
16
|
}
|
package/tsconfig.json
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
{
|
2
2
|
"compilerOptions": {
|
3
|
-
"
|
4
|
-
"
|
5
|
-
|
3
|
+
"baseUrl": "./src",
|
4
|
+
"outDir": "./dist/",
|
5
|
+
"target": "es6",
|
6
|
+
"allowJs": true,
|
7
|
+
"moduleResolution": "node",
|
8
|
+
"allowSyntheticDefaultImports": true,
|
9
|
+
"lib": [
|
10
|
+
"dom"
|
11
|
+
]
|
12
|
+
},
|
13
|
+
"exclude": [
|
14
|
+
"./node_modules"
|
15
|
+
]
|
6
16
|
}
|
package/src/Component.ts
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
import * as Pubsub from './utils/pubsub'
|
2
|
-
import { on, off, trigger } from './utils/events'
|
3
|
-
import { rAF } from './utils'
|
4
|
-
import { Instances } from './Instances'
|
5
|
-
|
6
|
-
export const Component = ({
|
7
|
-
|
8
|
-
name,
|
9
|
-
element,
|
10
|
-
dependencies,
|
11
|
-
ElementInterface
|
12
|
-
|
13
|
-
}) => {
|
14
|
-
|
15
|
-
const subscriptions = []
|
16
|
-
|
17
|
-
let stateSubscriptions = []
|
18
|
-
let resolver
|
19
|
-
let promise = new Promise(resolve => resolver = resolve)
|
20
|
-
|
21
|
-
const base = {
|
22
|
-
|
23
|
-
name,
|
24
|
-
dependencies,
|
25
|
-
elm: element,
|
26
|
-
publish: Pubsub.publish,
|
27
|
-
unsubscribe: Pubsub.unsubscribe,
|
28
|
-
|
29
|
-
__initialize() {
|
30
|
-
resolver(base)
|
31
|
-
},
|
32
|
-
|
33
|
-
main(fn) {
|
34
|
-
promise
|
35
|
-
.then( _ => fn().forEach(lambda => lambda(base)))
|
36
|
-
.catch( err => console.error( err) )
|
37
|
-
},
|
38
|
-
|
39
|
-
expose(methods) {
|
40
|
-
ElementInterface.instances[name].methods = methods
|
41
|
-
},
|
42
|
-
|
43
|
-
state: {
|
44
|
-
set( state ) {
|
45
|
-
if( state.constructor === Function ){
|
46
|
-
const model = ElementInterface.model
|
47
|
-
state(model)
|
48
|
-
ElementInterface.update(model)
|
49
|
-
} else {
|
50
|
-
ElementInterface.update(state)
|
51
|
-
}
|
52
|
-
stateSubscriptions.forEach( fn => fn(ElementInterface.model) )
|
53
|
-
return new Promise((resolve) => rAF(_ => rAF(resolve) ))
|
54
|
-
},
|
55
|
-
get() {
|
56
|
-
return ElementInterface.model
|
57
|
-
},
|
58
|
-
subscribe(fn){
|
59
|
-
stateSubscriptions.push(fn)
|
60
|
-
},
|
61
|
-
unsubscribe(fn){
|
62
|
-
stateSubscriptions = stateSubscriptions.filter( item => item !== fn )
|
63
|
-
}
|
64
|
-
},
|
65
|
-
|
66
|
-
destroy(callback) {
|
67
|
-
ElementInterface.destroyers.push(callback)
|
68
|
-
},
|
69
|
-
|
70
|
-
on(name, selectorOrCallback, callback) {
|
71
|
-
on(element, name, selectorOrCallback, callback)
|
72
|
-
},
|
73
|
-
|
74
|
-
off(name, callback) {
|
75
|
-
off(element, name, callback)
|
76
|
-
},
|
77
|
-
|
78
|
-
trigger(ev, target, args) {
|
79
|
-
if (target.constructor === String)
|
80
|
-
trigger(element.querySelector(target), ev, { args: args })
|
81
|
-
else trigger(element, ev, { args: target })
|
82
|
-
},
|
83
|
-
|
84
|
-
emit(n, params) {
|
85
|
-
const args = Array.prototype.slice.call(arguments)
|
86
|
-
trigger(element, args.shift(), { args: args })
|
87
|
-
},
|
88
|
-
|
89
|
-
update(fn) {
|
90
|
-
ElementInterface.parentUpdate = fn
|
91
|
-
},
|
92
|
-
|
93
|
-
get(name, query) {
|
94
|
-
|
95
|
-
return function () {
|
96
|
-
const args = Array.prototype.slice.call(arguments),
|
97
|
-
method = args.shift(),
|
98
|
-
selector = `[data-component*=${name}]`
|
99
|
-
query = query ? selector + query : selector
|
100
|
-
|
101
|
-
Array.from(element.querySelectorAll(query))
|
102
|
-
.forEach(el => {
|
103
|
-
const instance = Instances.get(el).instances[name]
|
104
|
-
if (instance && (method in instance.methods))
|
105
|
-
instance.methods[method].apply(null, args)
|
106
|
-
})
|
107
|
-
|
108
|
-
if (element.matches(query)) {
|
109
|
-
const instance = Instances.get(element).instances[name]
|
110
|
-
if (instance && method in instance.methods)
|
111
|
-
instance.methods[method].apply(null, args)
|
112
|
-
}
|
113
|
-
}
|
114
|
-
},
|
115
|
-
|
116
|
-
subscribe(name, method) {
|
117
|
-
subscriptions.push({ name, method })
|
118
|
-
Pubsub.subscribe(name, method)
|
119
|
-
}
|
120
|
-
}
|
121
|
-
|
122
|
-
return base
|
123
|
-
}
|