jails-js 4.2.2 → 5.0.0-beta.10
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 +3 -13
- package/.github/FUNDING.yml +2 -0
- package/README.md +7 -37
- package/dist/jails.js +2 -1
- package/dist/jails.js.map +1 -0
- package/package.json +41 -38
- package/src/component.ts +149 -0
- package/src/element.ts +35 -0
- package/src/index.ts +27 -0
- package/src/template-system.ts +89 -0
- package/src/utils/{events.js → events.ts} +0 -0
- package/src/utils/index.ts +57 -0
- package/src/utils/{pubsub.js → pubsub.ts} +2 -2
- package/tsconfig.json +16 -0
- package/webpack.config.js +35 -0
- 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/repeat.js +0 -94
- package/src/utils/index.js +0 -77
- package/src/view.js +0 -126
- package/webpack.config.babel.js +0 -16
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
|
-
}
|
package/src/element.js
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
import Component from './component'
|
2
|
-
import { trigger } from './utils/events'
|
3
|
-
import { nextFrame } from './utils'
|
4
|
-
|
5
|
-
export const create = ({ element, view, modules }) => {
|
6
|
-
|
7
|
-
element.__instances__ = {}
|
8
|
-
element.__model__ = {}
|
9
|
-
|
10
|
-
const names = element.dataset.component.split(/\s/)
|
11
|
-
|
12
|
-
if(!element.dataset.reactorId){
|
13
|
-
view.setNewElement(element)
|
14
|
-
}
|
15
|
-
|
16
|
-
names.forEach( name => {
|
17
|
-
|
18
|
-
if( name in modules && (!element.__instances__[name]) ){
|
19
|
-
|
20
|
-
const component = modules[name]
|
21
|
-
|
22
|
-
nextFrame(_ => {
|
23
|
-
if( element.__instances__ ) {
|
24
|
-
const base = Component({ name, element, view, component })
|
25
|
-
|
26
|
-
element.__instances__[name] = { base, methods: {} }
|
27
|
-
|
28
|
-
element.__update__ = (state) => {
|
29
|
-
for ( let name in element.__instances__ )
|
30
|
-
element.__instances__[name].base.update(state)
|
31
|
-
}
|
32
|
-
|
33
|
-
component.module.default(base)
|
34
|
-
base.__initialize(base)
|
35
|
-
delete base.__initialize
|
36
|
-
}
|
37
|
-
})
|
38
|
-
}
|
39
|
-
})
|
40
|
-
|
41
|
-
}
|
42
|
-
|
43
|
-
export const ismounted = (element) => {
|
44
|
-
return Boolean( element.__instances__ )
|
45
|
-
}
|
46
|
-
|
47
|
-
export const destroy = ({ element }) => {
|
48
|
-
|
49
|
-
trigger(element, ':destroy')
|
50
|
-
|
51
|
-
for (let ev in element.__events)
|
52
|
-
element.removeEventListener(ev, element.__events[ev].listener)
|
53
|
-
|
54
|
-
delete element.__events
|
55
|
-
delete element.__instances__
|
56
|
-
delete element.__model__
|
57
|
-
}
|
package/src/index.js
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
import View from './view'
|
2
|
-
import { ismounted, create, destroy } from './element'
|
3
|
-
|
4
|
-
const modules = {}
|
5
|
-
|
6
|
-
export default {
|
7
|
-
|
8
|
-
register( name, module, dependencies ){
|
9
|
-
modules[ name ] = { name, module, dependencies }
|
10
|
-
},
|
11
|
-
|
12
|
-
start(){
|
13
|
-
const view = getView()
|
14
|
-
view.mode = 'production'
|
15
|
-
view.observe()
|
16
|
-
},
|
17
|
-
|
18
|
-
devStart(){
|
19
|
-
console.time('jails')
|
20
|
-
const view = getView()
|
21
|
-
view.mode = 'development'
|
22
|
-
view.observe()
|
23
|
-
console.timeEnd('jails')
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
const getView = () => {
|
28
|
-
|
29
|
-
const view = View({
|
30
|
-
|
31
|
-
onAdd(elements) {
|
32
|
-
elements
|
33
|
-
.filter(el => !ismounted(el))
|
34
|
-
.forEach(element => create({ element, view, modules }))
|
35
|
-
},
|
36
|
-
|
37
|
-
onRemove(removedNodes) {
|
38
|
-
removedNodes.forEach(removedNode => {
|
39
|
-
if (removedNode.nodeType === 1) {
|
40
|
-
const children = Array.from(removedNode.querySelectorAll('[data-component]'))
|
41
|
-
children
|
42
|
-
.concat(removedNode.dataset.component ? removedNode : [])
|
43
|
-
.filter(element => !document.body.contains(element))
|
44
|
-
.forEach(element => destroy({ element }))
|
45
|
-
}
|
46
|
-
})
|
47
|
-
}
|
48
|
-
})
|
49
|
-
|
50
|
-
return view
|
51
|
-
}
|
package/src/repeat.js
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
import { uuid } from './utils'
|
2
|
-
|
3
|
-
export default ({ sodajs: soda, models }) => {
|
4
|
-
|
5
|
-
soda.directive('repeat', {
|
6
|
-
|
7
|
-
priority: 10,
|
8
|
-
|
9
|
-
link({ scope, el, expression, getValue, compileNode }) {
|
10
|
-
|
11
|
-
let itemName
|
12
|
-
let valueName
|
13
|
-
let trackName
|
14
|
-
|
15
|
-
const trackReg = /\s+by\s+([^\s]+)$/
|
16
|
-
const inReg = /([^\s]+)\s+in\s+([^\s]+)|\(([^,]+)\s*,\s*([^)]+)\)\s+in\s+([^\s]+)/
|
17
|
-
|
18
|
-
const opt = expression.replace(trackReg, (item, $1) => {
|
19
|
-
if ($1)
|
20
|
-
trackName = ($1 || '').trim()
|
21
|
-
return ''
|
22
|
-
})
|
23
|
-
|
24
|
-
const r = inReg.exec(opt)
|
25
|
-
|
26
|
-
if (r) {
|
27
|
-
if (r[1] && r[2]) {
|
28
|
-
itemName = (r[1] || '').trim()
|
29
|
-
valueName = (r[2] || '').trim()
|
30
|
-
|
31
|
-
if (!(itemName && valueName)) {
|
32
|
-
return
|
33
|
-
}
|
34
|
-
} else if (r[3] && r[4] && r[5]) {
|
35
|
-
trackName = (r[3] || '').trim()
|
36
|
-
itemName = (r[4] || '').trim()
|
37
|
-
valueName = (r[5] || '').trim()
|
38
|
-
}
|
39
|
-
} else {
|
40
|
-
return
|
41
|
-
}
|
42
|
-
|
43
|
-
trackName = trackName || '$index'
|
44
|
-
|
45
|
-
const repeatObj = getValue(scope, valueName) || []
|
46
|
-
|
47
|
-
const repeatFunc = (i) => {
|
48
|
-
|
49
|
-
const itemNode = el.cloneNode(true)
|
50
|
-
const itemScope = Object.create(scope)
|
51
|
-
|
52
|
-
itemScope[trackName] = i
|
53
|
-
itemScope[itemName] = repeatObj[i]
|
54
|
-
|
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
|
-
itemNode.removeAttribute(`${this._prefix}repeat`)
|
64
|
-
el.parentNode.insertBefore(itemNode, el)
|
65
|
-
|
66
|
-
compileNode(itemNode, itemScope)
|
67
|
-
}
|
68
|
-
|
69
|
-
if ('length' in repeatObj) {
|
70
|
-
for (var i = 0; i < repeatObj.length; i++) {
|
71
|
-
repeatFunc(i)
|
72
|
-
}
|
73
|
-
} else {
|
74
|
-
for (var i in repeatObj) {
|
75
|
-
if (repeatObj.hasOwnProperty(i)) {
|
76
|
-
repeatFunc(i)
|
77
|
-
}
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
el.parentNode.removeChild(el)
|
82
|
-
|
83
|
-
if (el.childNodes && el.childNodes.length)
|
84
|
-
el.innerHTML = ''
|
85
|
-
}
|
86
|
-
})
|
87
|
-
}
|
88
|
-
|
89
|
-
function findComponents(el) {
|
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)
|
94
|
-
}
|
package/src/utils/index.js
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
|
2
|
-
export const rAF = (fn) => {
|
3
|
-
(requestAnimationFrame || setTimeout)(fn, 1000 / 60)
|
4
|
-
}
|
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
|
-
export const uuid = () => {
|
39
|
-
return 'xxxxxxxx'.replace(/[xy]/g, (c) => {
|
40
|
-
const r = Math.random() * 8 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
|
41
|
-
return v.toString(8)
|
42
|
-
})
|
43
|
-
}
|
44
|
-
|
45
|
-
export const setIds = (acc, element) => {
|
46
|
-
const id = uuid()
|
47
|
-
element.setAttribute('data-reactor-id', id)
|
48
|
-
acc[id] = element.outerHTML.replace(/<(x-)?template*.>|<\/(x-)?template>/g, '')
|
49
|
-
return acc
|
50
|
-
}
|
51
|
-
|
52
|
-
export const createTemplates = ( html, type = 'div' ) => {
|
53
|
-
|
54
|
-
const SELECTOR = '[data-component]:not([data-reactor-id])'
|
55
|
-
const virtual = document.createElement(type)
|
56
|
-
virtual.innerHTML = html.replace(/<template*.>/g, '<x-template>').replace(/<\/template>/g, '</x-template>')
|
57
|
-
|
58
|
-
const elements = Array.from(virtual.querySelectorAll(SELECTOR))
|
59
|
-
const templates = elements.reverse().reduce(setIds, {})
|
60
|
-
|
61
|
-
return {
|
62
|
-
templates,
|
63
|
-
html: virtual.innerHTML.replace(/<x-template*.>/g, '<template>').replace(/<\/x-template>/g, '</template>')
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
export const dup = (object) => {
|
68
|
-
return JSON.parse(JSON.stringify(object))
|
69
|
-
}
|
70
|
-
|
71
|
-
export const getParent = (el, selector) => {
|
72
|
-
let elem = el.parentNode
|
73
|
-
for ( ; elem && elem !== document; elem = elem.parentNode ) {
|
74
|
-
if ( elem.matches( selector ) ) return elem
|
75
|
-
}
|
76
|
-
return null
|
77
|
-
}
|
package/src/view.js
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
import morphdom from 'morphdom'
|
2
|
-
import sodajs from 'sodajs'
|
3
|
-
|
4
|
-
import * as animation from './animation'
|
5
|
-
import { dup, createTemplates, setIds } from './utils'
|
6
|
-
import repeatDirective from './repeat'
|
7
|
-
|
8
|
-
const STATIC = 'static'
|
9
|
-
const COMPONENT = '[data-component]'
|
10
|
-
|
11
|
-
export default function View( callback ) {
|
12
|
-
|
13
|
-
const root = document.body
|
14
|
-
const { templates, html } = createTemplates(root.innerHTML, 'html')
|
15
|
-
const models = {}
|
16
|
-
const SST = {}
|
17
|
-
|
18
|
-
sodajs.prefix('v-')
|
19
|
-
repeatDirective({ sodajs, models })
|
20
|
-
|
21
|
-
return {
|
22
|
-
|
23
|
-
mode : 'production',
|
24
|
-
templates,
|
25
|
-
models,
|
26
|
-
SST,
|
27
|
-
|
28
|
-
update( element, data ){
|
29
|
-
if (element) {
|
30
|
-
const id = element.dataset.reactorId
|
31
|
-
const template = templates[id]
|
32
|
-
const newstate = Object.assign({}, element.__model__, dup(data))
|
33
|
-
const newhtml = sodajs(template, newstate)
|
34
|
-
morphdom( element, newhtml, lifecycle(element, data, SST))
|
35
|
-
if( element.__model__ ){
|
36
|
-
Object.assign( element.__model__, newstate )
|
37
|
-
}
|
38
|
-
}
|
39
|
-
},
|
40
|
-
|
41
|
-
observe() {
|
42
|
-
const observer = observe( callback )
|
43
|
-
root.innerHTML = sodajs(html, {})
|
44
|
-
return observer
|
45
|
-
},
|
46
|
-
|
47
|
-
setNewElement(element){
|
48
|
-
setIds(templates, element)
|
49
|
-
}
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
const observe = ( callback ) => {
|
54
|
-
const observer = new MutationObserver(mutations => mutations.forEach(onMutation(callback)))
|
55
|
-
observer.observe(document.body, { childList: true, subtree: true })
|
56
|
-
return observer;
|
57
|
-
}
|
58
|
-
|
59
|
-
const onMutation = (callback) => (mutation) => {
|
60
|
-
if (mutation.type === 'childList') {
|
61
|
-
if (mutation.addedNodes.length) {
|
62
|
-
callback.onAdd(scan())
|
63
|
-
} else if (mutation.removedNodes.length) {
|
64
|
-
callback.onRemove(mutation.removedNodes)
|
65
|
-
}
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
const scan = () => {
|
70
|
-
return Array
|
71
|
-
.from( document.querySelectorAll(COMPONENT) )
|
72
|
-
.reverse()
|
73
|
-
}
|
74
|
-
|
75
|
-
const lifecycle = (elm, data, SST) => ({
|
76
|
-
|
77
|
-
getNodeKey(node) {
|
78
|
-
if (node.nodeType === 1) {
|
79
|
-
return node.dataset.key || node.dataset.reactorId
|
80
|
-
}
|
81
|
-
return false
|
82
|
-
},
|
83
|
-
|
84
|
-
onBeforeElUpdated(node) {
|
85
|
-
return update( elm, data, SST, node )
|
86
|
-
},
|
87
|
-
|
88
|
-
onBeforeElChildrenUpdated(node, tonode) {
|
89
|
-
return update( elm, data, SST, node )
|
90
|
-
},
|
91
|
-
|
92
|
-
onNodeAdded(node) {
|
93
|
-
animation.animateNodes(node, animation.onAdd)
|
94
|
-
},
|
95
|
-
|
96
|
-
onBeforeNodeAdded(node) {
|
97
|
-
animation.animateNodes(node, animation.onBeforeAdd)
|
98
|
-
},
|
99
|
-
|
100
|
-
onBeforeNodeDiscarded(node) {
|
101
|
-
return !animation.animateNodes(node, animation.onRemove)
|
102
|
-
}
|
103
|
-
})
|
104
|
-
|
105
|
-
const update = (elm, data, SST, node) => {
|
106
|
-
|
107
|
-
if (node.nodeType === 1) {
|
108
|
-
// If element has static property, don't update
|
109
|
-
if ( STATIC in node.dataset )
|
110
|
-
return false
|
111
|
-
|
112
|
-
// If element is child and a component, don't update
|
113
|
-
if (node !== elm && node.dataset.component && node.__update__) {
|
114
|
-
|
115
|
-
const newdata = Object.assign(SST, data)
|
116
|
-
node.__update__(newdata)
|
117
|
-
|
118
|
-
Array.from(node.querySelectorAll(COMPONENT)).forEach(el => {
|
119
|
-
if (el.dataset.component && el.__update__)
|
120
|
-
el.__update__(newdata)
|
121
|
-
})
|
122
|
-
|
123
|
-
return false
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
package/webpack.config.babel.js
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
const path = require('path')
|
2
|
-
|
3
|
-
module.exports = {
|
4
|
-
|
5
|
-
entry: {
|
6
|
-
'jails': './src/index.js'
|
7
|
-
},
|
8
|
-
|
9
|
-
output: {
|
10
|
-
path : path.resolve(__dirname, './dist'),
|
11
|
-
filename : '[name].js',
|
12
|
-
libraryTarget : 'umd',
|
13
|
-
library : 'jails',
|
14
|
-
umdNamedDefine: true
|
15
|
-
}
|
16
|
-
}
|