jails-js 4.2.2 → 5.0.0-beta.3
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/.github/FUNDING.yml +2 -0
- package/dist/jails.js +2 -1
- package/dist/jails.js.map +1 -0
- package/package.json +4 -3
- package/src/Component.ts +124 -0
- package/src/Element.ts +117 -0
- package/src/Scanner.ts +26 -0
- package/src/index.ts +60 -0
- package/src/{repeat.js → soda-config.js} +10 -17
- package/src/utils/index.js +22 -58
- package/tsconfig.json +6 -0
- package/webpack.config.js +35 -0
- package/.babelrc +0 -16
- package/.eslintignore +0 -2
- package/.eslintrc +0 -20
- package/.eslintrc.js +0 -28
- package/src/animation.js +0 -94
- package/src/component.js +0 -143
- package/src/element.js +0 -57
- package/src/index.js +0 -51
- package/src/view.js +0 -126
- package/webpack.config.babel.js +0 -16
package/src/Element.ts
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
import { stripTemplateTag, dup, rAF, createTemplate, uuid } from './utils'
|
2
|
+
import morphdom from 'morphdom'
|
3
|
+
import { setSodaConfig } from './soda-config'
|
4
|
+
|
5
|
+
const sodajs = setSodaConfig()
|
6
|
+
const templates = {}
|
7
|
+
|
8
|
+
export const Element = ( el:HTMLElement ) => {
|
9
|
+
|
10
|
+
stripTemplateTag( el )
|
11
|
+
|
12
|
+
let updates = []
|
13
|
+
|
14
|
+
const model = Object.assign({}, JSON.parse(el.dataset.initialState || '{}'))
|
15
|
+
const morphdomOptions = lifecycle(el)
|
16
|
+
const { template, tplid } = getTemplateData(el)
|
17
|
+
|
18
|
+
const api = {
|
19
|
+
|
20
|
+
tplid,
|
21
|
+
el,
|
22
|
+
template,
|
23
|
+
model,
|
24
|
+
parent: {},
|
25
|
+
view : _ => _,
|
26
|
+
instances:{},
|
27
|
+
destroyers:[],
|
28
|
+
promises: [],
|
29
|
+
parentUpdate: data => null,
|
30
|
+
|
31
|
+
dispose(){
|
32
|
+
if( api.promises.length ){
|
33
|
+
Promise.all(api.promises)
|
34
|
+
.then(_ => api.destroyers.forEach( destroy => destroy(api) ))
|
35
|
+
}else {
|
36
|
+
api.destroyers.forEach( destroy => destroy(api) )
|
37
|
+
}
|
38
|
+
},
|
39
|
+
|
40
|
+
update( data = {}, isParentUpdate ) {
|
41
|
+
|
42
|
+
if( !document.body.contains(el) )
|
43
|
+
return
|
44
|
+
|
45
|
+
updates.push( data )
|
46
|
+
|
47
|
+
rAF( _ => {
|
48
|
+
|
49
|
+
if( updates.length ) {
|
50
|
+
|
51
|
+
const newdata = {}
|
52
|
+
updates.forEach( d => Object.assign(newdata, d ) )
|
53
|
+
updates = []
|
54
|
+
|
55
|
+
api.model = Object.assign( api.model, newdata )
|
56
|
+
|
57
|
+
if( isParentUpdate ) {
|
58
|
+
api.parentUpdate( api.model )
|
59
|
+
}
|
60
|
+
|
61
|
+
const newhtml = sodajs(template, api.view(dup(api.model)))
|
62
|
+
morphdom( el, newhtml, morphdomOptions )
|
63
|
+
|
64
|
+
Array
|
65
|
+
.from( el.querySelectorAll('[data-component]') )
|
66
|
+
.forEach( node => {
|
67
|
+
if( !node.__instance__ ) return
|
68
|
+
const { parent, ...model } = api.model
|
69
|
+
const initialState = node.dataset.initialState? JSON.parse(node.dataset.initialState): {}
|
70
|
+
const newmodel = Object.assign(initialState, { parent:model })
|
71
|
+
node.__instance__.update( newmodel, true )
|
72
|
+
})
|
73
|
+
}
|
74
|
+
})
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
el.__instance__ = api
|
79
|
+
|
80
|
+
return api
|
81
|
+
}
|
82
|
+
|
83
|
+
const lifecycle = ( element: HTMLElement ) => {
|
84
|
+
return {
|
85
|
+
onBeforeElUpdated: update(element),
|
86
|
+
onBeforeElChildrenUpdated: update(element),
|
87
|
+
getNodeKey(node) {
|
88
|
+
if( node.nodeType === 1 && node.dataset.tplid )
|
89
|
+
return node.dataset.key || node.dataset.tplid
|
90
|
+
return false
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
const update = ( element: HTMLElement ) => ( node: HTMLElement, toEl: HTMLElement ) => {
|
96
|
+
if ( node.isEqualNode(toEl) )
|
97
|
+
return false
|
98
|
+
if( node.nodeType == 1 ) {
|
99
|
+
if( 'static' in node.dataset )
|
100
|
+
return false
|
101
|
+
}
|
102
|
+
return true
|
103
|
+
}
|
104
|
+
|
105
|
+
const getTemplateData = ( element: HTMLElement ) => {
|
106
|
+
if( element.getAttribute('tplid') ) {
|
107
|
+
const tplid = element.getAttribute('tplid')
|
108
|
+
const template = templates[tplid]
|
109
|
+
return { tplid, template }
|
110
|
+
}else {
|
111
|
+
const tplid = uuid()
|
112
|
+
element.setAttribute('tplid', tplid)
|
113
|
+
templates[tplid] = createTemplate(element.outerHTML, templates)
|
114
|
+
const template = templates[tplid]
|
115
|
+
return { tplid, template }
|
116
|
+
}
|
117
|
+
}
|
package/src/Scanner.ts
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
export const Scanner = {
|
3
|
+
|
4
|
+
scan( node: HTMLElement, callback ) {
|
5
|
+
if( node.nodeType === 1 ) {
|
6
|
+
const list : Array<HTMLElement> = Array.from( node.querySelectorAll('[data-component]') )
|
7
|
+
const elements : Array<HTMLElement> = node.dataset.component? [node].concat(list) : list
|
8
|
+
if( elements.length ) {
|
9
|
+
elements.reverse().forEach( callback )
|
10
|
+
}
|
11
|
+
}
|
12
|
+
},
|
13
|
+
|
14
|
+
observe( target: HTMLElement, onAdd, onRemove ) {
|
15
|
+
const observer = new MutationObserver(mutations => mutations.forEach( mutation => {
|
16
|
+
if (mutation.type === 'childList') {
|
17
|
+
if (mutation.addedNodes.length) {
|
18
|
+
Array.from( mutation.addedNodes ).forEach( node => Scanner.scan(node, onAdd) )
|
19
|
+
} else if (mutation.removedNodes.length) {
|
20
|
+
Array.from( mutation.removedNodes ).forEach( node => Scanner.scan(node, onRemove) )
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}))
|
24
|
+
observer.observe(target, { childList: true, subtree: true })
|
25
|
+
}
|
26
|
+
}
|
package/src/index.ts
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
import { Element } from './Element'
|
2
|
+
import { Scanner } from './Scanner'
|
3
|
+
import { Component } from './Component'
|
4
|
+
import { stripTemplateTag } from './utils'
|
5
|
+
|
6
|
+
const components = {}
|
7
|
+
|
8
|
+
export default {
|
9
|
+
|
10
|
+
start() {
|
11
|
+
|
12
|
+
const body: HTMLElement = document.body
|
13
|
+
|
14
|
+
stripTemplateTag( body )
|
15
|
+
|
16
|
+
Scanner.scan( body, createElement )
|
17
|
+
Scanner.observe( body, createElement, disposeElement )
|
18
|
+
},
|
19
|
+
|
20
|
+
register( name, module, dependencies = {} ) {
|
21
|
+
components[name] = { name, module, dependencies }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
const createElement = ( element: HTMLElement ) => {
|
26
|
+
|
27
|
+
const ElementInterface = Element( element )
|
28
|
+
const names = element.dataset.component.split(/\s/)
|
29
|
+
|
30
|
+
names.forEach( name => {
|
31
|
+
|
32
|
+
const C = components[name]
|
33
|
+
|
34
|
+
if( !C ) {
|
35
|
+
console.warn(`Jails - Module ${name} not registered`)
|
36
|
+
return
|
37
|
+
}
|
38
|
+
|
39
|
+
const { module, dependencies } = C
|
40
|
+
ElementInterface.model = Object.assign({}, module.model, ElementInterface.model )
|
41
|
+
|
42
|
+
const base = Component({ name, element, dependencies, ElementInterface })
|
43
|
+
const promise = module.default(base)
|
44
|
+
|
45
|
+
if( promise && promise.then ) {
|
46
|
+
ElementInterface.promises.push(promise)
|
47
|
+
}
|
48
|
+
|
49
|
+
base.__initialize()
|
50
|
+
ElementInterface.view = module.view || ElementInterface.view
|
51
|
+
ElementInterface.instances[name] = { methods: {} }
|
52
|
+
})
|
53
|
+
|
54
|
+
ElementInterface.update()
|
55
|
+
}
|
56
|
+
|
57
|
+
const disposeElement = ( node ) => {
|
58
|
+
if( node.__instance__)
|
59
|
+
node.__instance__.dispose()
|
60
|
+
}
|
@@ -1,8 +1,10 @@
|
|
1
|
-
import
|
1
|
+
import sodajs from 'sodajs'
|
2
2
|
|
3
|
-
export
|
3
|
+
export const setSodaConfig = () => {
|
4
4
|
|
5
|
-
|
5
|
+
sodajs.prefix('v-')
|
6
|
+
|
7
|
+
sodajs.directive('repeat', {
|
6
8
|
|
7
9
|
priority: 10,
|
8
10
|
|
@@ -52,17 +54,13 @@ export default ({ sodajs: soda, models }) => {
|
|
52
54
|
itemScope[trackName] = i
|
53
55
|
itemScope[itemName] = repeatObj[i]
|
54
56
|
|
55
|
-
const components = findComponents(itemNode)
|
56
|
-
|
57
|
-
components.forEach(node => {
|
58
|
-
const ID = uuid()
|
59
|
-
node.setAttribute('data-model-id', ID)
|
60
|
-
models[ID] = itemScope
|
61
|
-
})
|
62
|
-
|
63
57
|
itemNode.removeAttribute(`${this._prefix}repeat`)
|
58
|
+
|
64
59
|
el.parentNode.insertBefore(itemNode, el)
|
65
60
|
|
61
|
+
Array.from(itemNode.querySelectorAll('[data-component]'))
|
62
|
+
.forEach( node => node.setAttribute('data-initial-state', JSON.stringify(itemScope)) )
|
63
|
+
|
66
64
|
compileNode(itemNode, itemScope)
|
67
65
|
}
|
68
66
|
|
@@ -84,11 +82,6 @@ export default ({ sodajs: soda, models }) => {
|
|
84
82
|
el.innerHTML = ''
|
85
83
|
}
|
86
84
|
})
|
87
|
-
}
|
88
85
|
|
89
|
-
|
90
|
-
const isComponent = el.getAttribute('data-component')
|
91
|
-
const component = isComponent ? [el] : []
|
92
|
-
const childComponents = Array.prototype.slice.call(el.querySelectorAll('[data-component]'))
|
93
|
-
return component.concat(childComponents)
|
86
|
+
return sodajs
|
94
87
|
}
|
package/src/utils/index.js
CHANGED
@@ -3,38 +3,6 @@ export const rAF = (fn) => {
|
|
3
3
|
(requestAnimationFrame || setTimeout)(fn, 1000 / 60)
|
4
4
|
}
|
5
5
|
|
6
|
-
export const nextFrame = (fn) => {
|
7
|
-
rAF(() => rAF(fn))
|
8
|
-
}
|
9
|
-
|
10
|
-
export const addClass = (element) => (string) => {
|
11
|
-
string.split(/\s/).map(item => element.classList.add(item))
|
12
|
-
}
|
13
|
-
|
14
|
-
export const removeClass = (element) => (string) => {
|
15
|
-
string.split(/\s/).map(item => element.classList.remove(item))
|
16
|
-
}
|
17
|
-
|
18
|
-
export const getPrefix = (object) => {
|
19
|
-
for (let key in object)
|
20
|
-
if (key in document.body.style)
|
21
|
-
return object[key]
|
22
|
-
}
|
23
|
-
|
24
|
-
export const animationEnd = getPrefix({
|
25
|
-
animation: 'animationend',
|
26
|
-
OAnimation: 'oAnimationEnd',
|
27
|
-
MozAnimation: 'animationend',
|
28
|
-
WebkitAnimation: 'webkitAnimationEnd'
|
29
|
-
})
|
30
|
-
|
31
|
-
export const transitionEnd = getPrefix({
|
32
|
-
transition: 'transitionend',
|
33
|
-
OTransition: 'oTransitionEnd',
|
34
|
-
MozTransition: 'transitionend',
|
35
|
-
WebkitTransition: 'webkitTransitionEnd'
|
36
|
-
})
|
37
|
-
|
38
6
|
export const uuid = () => {
|
39
7
|
return 'xxxxxxxx'.replace(/[xy]/g, (c) => {
|
40
8
|
const r = Math.random() * 8 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
|
@@ -42,36 +10,32 @@ export const uuid = () => {
|
|
42
10
|
})
|
43
11
|
}
|
44
12
|
|
45
|
-
export const
|
46
|
-
const
|
47
|
-
|
48
|
-
|
49
|
-
|
13
|
+
export const stripTemplateTag = ( element ) => {
|
14
|
+
const templates = Array.from(element.querySelectorAll('template'))
|
15
|
+
// https://gist.github.com/harmenjanssen/07e425248779c65bc5d11b02fb913274
|
16
|
+
templates.forEach( template => {
|
17
|
+
template.parentNode.replaceChild(template.content, template )
|
18
|
+
})
|
50
19
|
}
|
51
20
|
|
52
|
-
export const
|
53
|
-
|
54
|
-
|
55
|
-
const virtual = document.createElement(type)
|
56
|
-
virtual.innerHTML = html.replace(/<template*.>/g, '<x-template>').replace(/<\/template>/g, '</x-template>')
|
21
|
+
export const dup = (o) => {
|
22
|
+
return JSON.parse( JSON.stringify(o) )
|
23
|
+
}
|
57
24
|
|
58
|
-
|
59
|
-
const templates = elements.reverse().reduce(setIds, {})
|
25
|
+
export const createTemplate = ( html, templates ) => {
|
60
26
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
}
|
65
|
-
}
|
27
|
+
const vroot = document.createElement('div')
|
28
|
+
vroot.innerHTML = html
|
29
|
+
stripTemplateTag( vroot )
|
66
30
|
|
67
|
-
|
68
|
-
|
69
|
-
|
31
|
+
Array
|
32
|
+
.from(vroot.querySelectorAll('[data-component]'))
|
33
|
+
.forEach( c => {
|
34
|
+
const tplid = c.getAttribute('tplid')
|
35
|
+
const cache = templates[tplid]
|
36
|
+
if( cache )
|
37
|
+
c.outerHTML = cache
|
38
|
+
})
|
70
39
|
|
71
|
-
|
72
|
-
let elem = el.parentNode
|
73
|
-
for ( ; elem && elem !== document; elem = elem.parentNode ) {
|
74
|
-
if ( elem.matches( selector ) ) return elem
|
75
|
-
}
|
76
|
-
return null
|
40
|
+
return vroot.innerHTML
|
77
41
|
}
|
package/tsconfig.json
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
const path = require('path')
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
|
5
|
+
devtool: 'source-map',
|
6
|
+
|
7
|
+
resolve: {
|
8
|
+
extensions: ['.ts', '.js', '.json']
|
9
|
+
},
|
10
|
+
|
11
|
+
entry: {
|
12
|
+
jails: './src/index.ts'
|
13
|
+
},
|
14
|
+
|
15
|
+
module: {
|
16
|
+
rules: [
|
17
|
+
{
|
18
|
+
test: /\.ts$/,
|
19
|
+
exclude: [/node_modules/],
|
20
|
+
loader: 'ts-loader',
|
21
|
+
options: {
|
22
|
+
transpileOnly: true
|
23
|
+
}
|
24
|
+
}
|
25
|
+
]
|
26
|
+
},
|
27
|
+
|
28
|
+
output: {
|
29
|
+
path : path.resolve(__dirname, './dist'),
|
30
|
+
filename : '[name].js',
|
31
|
+
libraryTarget : 'umd',
|
32
|
+
library : 'jails',
|
33
|
+
umdNamedDefine: true
|
34
|
+
}
|
35
|
+
}
|
package/.babelrc
DELETED
package/.eslintignore
DELETED
package/.eslintrc
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"rules": {
|
3
|
-
"indent": [2,"tab", {"SwitchCase":1}],
|
4
|
-
"quotes": [2,"single"],
|
5
|
-
"semi": [2,"never"],
|
6
|
-
"no-unused-vars": ["warn", { "vars": "all", "args": "none" }],
|
7
|
-
"no-console": 0
|
8
|
-
},
|
9
|
-
"env": {
|
10
|
-
"es6": true,
|
11
|
-
"browser": true,
|
12
|
-
"node" : true,
|
13
|
-
"jquery": true,
|
14
|
-
},
|
15
|
-
"extends": "eslint:recommended",
|
16
|
-
"parserOptions": {
|
17
|
-
"sourceType": "module"
|
18
|
-
},
|
19
|
-
"globals":{}
|
20
|
-
}
|
package/.eslintrc.js
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module.exports = {
|
2
|
-
"parser":"babel-eslint",
|
3
|
-
"rules": {
|
4
|
-
"indent": [2,"tab", {"SwitchCase":1}],
|
5
|
-
"quotes": [2,"single"],
|
6
|
-
"semi": [2,"never"],
|
7
|
-
"no-unused-vars": ["warn", { "vars": "all", "args": "none" }],
|
8
|
-
"no-console": 0
|
9
|
-
},
|
10
|
-
"env": {
|
11
|
-
"es6": true,
|
12
|
-
"browser": true,
|
13
|
-
"node" : true,
|
14
|
-
"jquery": true,
|
15
|
-
},
|
16
|
-
"extends": "eslint:recommended",
|
17
|
-
"parserOptions": {
|
18
|
-
"sourceType": "module",
|
19
|
-
"ecmaVersion": 2017,
|
20
|
-
"ecmaFeatures": {
|
21
|
-
"experimentalObjectRestSpread": true
|
22
|
-
}
|
23
|
-
},
|
24
|
-
"globals":{
|
25
|
-
"APPCONFIG":true,
|
26
|
-
"webcomponents":true
|
27
|
-
}
|
28
|
-
}
|
package/src/animation.js
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
addClass,
|
3
|
-
removeClass,
|
4
|
-
animationEnd,
|
5
|
-
transitionEnd,
|
6
|
-
nextFrame
|
7
|
-
} from './utils'
|
8
|
-
|
9
|
-
export const onBeforeAdd = (node, animation) => {
|
10
|
-
|
11
|
-
const enter = `${animation}-enter`
|
12
|
-
const enterActive = `${animation}-enter-active`
|
13
|
-
const addClassNames = addClass(node)
|
14
|
-
|
15
|
-
addClassNames(`${enter} ${enterActive}`)
|
16
|
-
}
|
17
|
-
|
18
|
-
export const onAdd = (node, animation) => {
|
19
|
-
|
20
|
-
const enter = `${animation}-enter`
|
21
|
-
const enterActive = `${animation}-enter-active`
|
22
|
-
const enterTo = `${animation}-enter-to`
|
23
|
-
const removeClassNames = removeClass(node)
|
24
|
-
const addClassNames = addClass(node)
|
25
|
-
|
26
|
-
const remove = () => {
|
27
|
-
removeClassNames(`${enter} ${enterActive} ${enterTo}`)
|
28
|
-
node.removeEventListener(transitionEnd, remove)
|
29
|
-
node.removeEventListener(animationEnd, remove)
|
30
|
-
}
|
31
|
-
|
32
|
-
node.addEventListener(transitionEnd, remove)
|
33
|
-
node.addEventListener(animationEnd, remove)
|
34
|
-
|
35
|
-
nextFrame(() => {
|
36
|
-
addClassNames(enterTo)
|
37
|
-
removeClassNames(enter)
|
38
|
-
})
|
39
|
-
}
|
40
|
-
|
41
|
-
export const onRemove = (node, animation) => {
|
42
|
-
|
43
|
-
const leave = `${animation}-leave`
|
44
|
-
const leaveActive = `${animation}-leave-active`
|
45
|
-
const leaveTo = `${animation}-leave-to`
|
46
|
-
const removeClassNames = removeClass(node)
|
47
|
-
const addClassNames = addClass(node)
|
48
|
-
const style = window.getComputedStyle(node)
|
49
|
-
|
50
|
-
let transitionsLength = style.transitionProperty.split(',').length
|
51
|
-
|
52
|
-
const remove = (e) => {
|
53
|
-
if (e.type == 'transitionend') {
|
54
|
-
if (e.target == node) {
|
55
|
-
transitionsLength -= 1
|
56
|
-
if (transitionsLength <= 1) {
|
57
|
-
removeClassNames(`${leaveActive} ${leaveTo}`)
|
58
|
-
node.removeEventListener(transitionEnd, remove)
|
59
|
-
node.parentNode ? node.parentNode.removeChild(node) : null
|
60
|
-
}
|
61
|
-
}
|
62
|
-
}
|
63
|
-
else {
|
64
|
-
removeClassNames(`${leaveActive} ${leaveTo}`)
|
65
|
-
node.removeEventListener(animationEnd, remove)
|
66
|
-
node.parentNode ? node.parentNode.removeChild(node) : null
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
node.addEventListener(transitionEnd, remove)
|
71
|
-
node.addEventListener(animationEnd, remove)
|
72
|
-
|
73
|
-
addClassNames(`${leave} ${leaveActive}`)
|
74
|
-
|
75
|
-
nextFrame(() => {
|
76
|
-
removeClassNames(leave)
|
77
|
-
addClassNames(leaveTo)
|
78
|
-
})
|
79
|
-
}
|
80
|
-
|
81
|
-
export const animateNodes = (node, callback) => {
|
82
|
-
|
83
|
-
const childnodes = node.nodeType == 1
|
84
|
-
? Array.prototype.slice.call(node.querySelectorAll('[data-animation]'))
|
85
|
-
: []
|
86
|
-
|
87
|
-
const list = node.dataset && node.dataset.animation
|
88
|
-
? [node].concat(childnodes)
|
89
|
-
: childnodes
|
90
|
-
|
91
|
-
list.forEach(n => callback(n, n.dataset.animation))
|
92
|
-
|
93
|
-
return list.length > 0
|
94
|
-
}
|
package/src/component.js
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
import { pandora, log } from 'jails.packages/pandora'
|
2
|
-
import { on, off, trigger } from './utils/events'
|
3
|
-
import * as Pubsub from './utils/pubsub'
|
4
|
-
import { getParent } from './utils'
|
5
|
-
|
6
|
-
export default function Component ({ name, element, view, component }) {
|
7
|
-
|
8
|
-
const module = component.module
|
9
|
-
const store = Store({ name, element, module, view })
|
10
|
-
const subscriptions = []
|
11
|
-
const destroyers = []
|
12
|
-
|
13
|
-
let resolver
|
14
|
-
let promise = new Promise(resolve => resolver = resolve)
|
15
|
-
let updater = () => null
|
16
|
-
|
17
|
-
const base = {
|
18
|
-
|
19
|
-
name,
|
20
|
-
injection: component.dependencies,
|
21
|
-
elm: element,
|
22
|
-
msg: store,
|
23
|
-
publish: Pubsub.publish,
|
24
|
-
unsubscribe: Pubsub.unsubscribe,
|
25
|
-
|
26
|
-
__initialize(base) {
|
27
|
-
resolver(base)
|
28
|
-
base.destroy( _ => {
|
29
|
-
subscriptions.forEach(topic => Pubsub.unsubscribe(topic))
|
30
|
-
destroyers.forEach(fn => element.removeEventListener(':destroy', fn))
|
31
|
-
})
|
32
|
-
},
|
33
|
-
|
34
|
-
main(fn) {
|
35
|
-
promise.then(() => fn().forEach(lambda => lambda(base)))
|
36
|
-
},
|
37
|
-
|
38
|
-
render(data) {
|
39
|
-
view.update(element, data)
|
40
|
-
},
|
41
|
-
|
42
|
-
expose(methods) {
|
43
|
-
element.__instances__[name].methods = methods
|
44
|
-
},
|
45
|
-
|
46
|
-
update(data) {
|
47
|
-
if( data.apply ){
|
48
|
-
const _parent = getParent(element, '[data-component]')
|
49
|
-
updater = data
|
50
|
-
updater( _parent.__model__ )
|
51
|
-
}else {
|
52
|
-
updater( data )
|
53
|
-
}
|
54
|
-
},
|
55
|
-
|
56
|
-
destroy(callback) {
|
57
|
-
destroyers.push(callback)
|
58
|
-
element.addEventListener(':destroy', callback)
|
59
|
-
},
|
60
|
-
|
61
|
-
on(name, selectorOrCallback, callback) {
|
62
|
-
on(element, name, selectorOrCallback, callback)
|
63
|
-
},
|
64
|
-
|
65
|
-
off(name, callback) {
|
66
|
-
off(element, name, callback)
|
67
|
-
},
|
68
|
-
|
69
|
-
trigger(ev, target, args) {
|
70
|
-
if (target.constructor === String)
|
71
|
-
trigger(element.querySelector(target), ev, { args: args })
|
72
|
-
else trigger(element, ev, { args: target })
|
73
|
-
},
|
74
|
-
|
75
|
-
emit(n, params) {
|
76
|
-
const args = Array.prototype.slice.call(arguments)
|
77
|
-
trigger(element, args.shift(), { args: args })
|
78
|
-
},
|
79
|
-
|
80
|
-
get(name, query) {
|
81
|
-
|
82
|
-
return function () {
|
83
|
-
|
84
|
-
const args = Array.prototype.slice.call(arguments),
|
85
|
-
method = args.shift(),
|
86
|
-
selector = `[data-component*=${name}]`
|
87
|
-
|
88
|
-
query = query ? selector + query : selector
|
89
|
-
|
90
|
-
Array.from(element.querySelectorAll(query))
|
91
|
-
.forEach(el => {
|
92
|
-
const instance = el.__instances__[name]
|
93
|
-
if (instance && (method in instance.methods))
|
94
|
-
instance.methods[method].apply(null, args)
|
95
|
-
})
|
96
|
-
|
97
|
-
if (element.matches(query)) {
|
98
|
-
const instance = element.__instances__[name]
|
99
|
-
if (instance && method in instance.methods)
|
100
|
-
instance.methods[method].apply(null, args)
|
101
|
-
}
|
102
|
-
}
|
103
|
-
},
|
104
|
-
|
105
|
-
subscribe(name, method) {
|
106
|
-
subscriptions.push({ name, method })
|
107
|
-
Pubsub.subscribe(name, method)
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
return base
|
112
|
-
|
113
|
-
}
|
114
|
-
|
115
|
-
const Store = ({ element, name, module, view:View }) => {
|
116
|
-
|
117
|
-
const view = module.view ? module.view : state => state
|
118
|
-
const initialState = View.models[element.dataset.modelId]
|
119
|
-
const model = Object.assign({}, module.model, initialState)
|
120
|
-
const title = name.charAt(0).toUpperCase() + name.substring(1)
|
121
|
-
|
122
|
-
const middlewares = View.mode === 'development'
|
123
|
-
? [log(`Component ${title}`)]
|
124
|
-
: []
|
125
|
-
|
126
|
-
const actions = module.actions || {}
|
127
|
-
|
128
|
-
const store = pandora({
|
129
|
-
model,
|
130
|
-
actions,
|
131
|
-
middlewares,
|
132
|
-
autostart: false,
|
133
|
-
callback(state) {
|
134
|
-
View.update(element, view(state))
|
135
|
-
}
|
136
|
-
})
|
137
|
-
|
138
|
-
if (module.model && Object.keys(module.model).length) {
|
139
|
-
View.update(element, view(model))
|
140
|
-
}
|
141
|
-
|
142
|
-
return store
|
143
|
-
}
|