domql 1.4.22 → 1.5.0
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/README.md +9 -9
- package/package.json +1 -1
- package/packages/router/index.js +1 -1
- package/src/element/create.js +10 -10
- package/src/element/extend.js +55 -0
- package/src/element/mixins/registry.js +3 -3
- package/src/element/props.js +4 -4
- package/src/element/set.js +3 -3
- package/src/utils/extendUtils.js +116 -0
- package/src/utils/index.js +1 -1
- package/src/utils/node.js +1 -1
- package/src/utils/object.js +11 -11
- package/src/element/proto.js +0 -55
- package/src/utils/protoUtils.js +0 -116
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ var Link = {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
var ListItem = {
|
|
43
|
-
|
|
43
|
+
extend: Link,
|
|
44
44
|
class: 'ui link',
|
|
45
45
|
attr: {
|
|
46
46
|
href: '#'
|
|
@@ -48,7 +48,7 @@ var ListItem = {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
var menu = {
|
|
51
|
-
|
|
51
|
+
childExtend: ListItem,
|
|
52
52
|
home: 'Home',
|
|
53
53
|
text: 'About'
|
|
54
54
|
}
|
|
@@ -62,7 +62,7 @@ var header = {
|
|
|
62
62
|
var navItems = ['Home', 'About', 'FAQ', 'Contact']
|
|
63
63
|
|
|
64
64
|
var menu = {
|
|
65
|
-
|
|
65
|
+
extend: ListItem,
|
|
66
66
|
...navItems
|
|
67
67
|
}
|
|
68
68
|
```
|
|
@@ -89,8 +89,8 @@ var Increment = {
|
|
|
89
89
|
| Property | Type | Description | Default |
|
|
90
90
|
| --- | --- | --- | --- |
|
|
91
91
|
| `key` | `Number` `String` | Defines the key of the Element | The key of the object, or randomly generated name |
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
92
|
+
| `extend` | `Object` `Array` | Clones the other element | `undefined` |
|
|
93
|
+
| `childExtend` | `Object` `Array` | Specifies the `extend` for all child elements | `undefined` |
|
|
94
94
|
| `tag` | `String` | Specifis the HTML tag | `div` or related HTML tag if the key matches |
|
|
95
95
|
| `class` | `Any` | Specifies the HTML class | `undefined` |
|
|
96
96
|
| `attr` | `Object` | Specifies the set of HTML attributes | `{}` |
|
|
@@ -108,7 +108,7 @@ var User = {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
var Contact = {
|
|
111
|
-
|
|
111
|
+
extend: User,
|
|
112
112
|
username: 'nikoloza'
|
|
113
113
|
}
|
|
114
114
|
```
|
|
@@ -131,7 +131,7 @@ All native DOM events are supported and can be specified inside `on` parameter.
|
|
|
131
131
|
key
|
|
132
132
|
tag
|
|
133
133
|
node
|
|
134
|
-
|
|
134
|
+
extend
|
|
135
135
|
on
|
|
136
136
|
class
|
|
137
137
|
text
|
|
@@ -143,14 +143,14 @@ set
|
|
|
143
143
|
define
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
Anything except these keywords will create a new nested child element. The easier method to specify HTML tag is to use related nodeName as a key, for example:
|
|
146
|
+
Anything except these keywords will create a new nested child element. The easier method to specify HTML tag is to use related nodeName as a key, for example:
|
|
147
147
|
|
|
148
148
|
```javascript
|
|
149
149
|
var layout = { // this will be <div>
|
|
150
150
|
header: {}, // will create <header>
|
|
151
151
|
aside: {}, // will create <aside>
|
|
152
152
|
main: { // will create <main>
|
|
153
|
-
|
|
153
|
+
childExtend: {
|
|
154
154
|
article: { // will create <article>
|
|
155
155
|
title: {}, // will create <div>
|
|
156
156
|
description: {}, // will create <div>
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "DOM rendering Javascript framework at early stage.",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "rackai",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.5.0",
|
|
7
7
|
"repository": "https://github.com/rackai/domql",
|
|
8
8
|
"publishConfig": {
|
|
9
9
|
"registry": "https://registry.npmjs.org"
|
package/packages/router/index.js
CHANGED
|
@@ -10,7 +10,7 @@ export default (rootElement, path, state = {}, level = 0, pushState = true) => {
|
|
|
10
10
|
|
|
11
11
|
if (content) {
|
|
12
12
|
if (pushState) window.history.pushState(state, null, route)
|
|
13
|
-
rootElement.set({
|
|
13
|
+
rootElement.set({ extend: content })
|
|
14
14
|
.node.scrollIntoView({ behavior: 'smooth' })
|
|
15
15
|
}
|
|
16
16
|
|
package/src/element/create.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import root from './root'
|
|
4
4
|
import createNode from './node'
|
|
5
5
|
import { appendNode, assignNode } from './assign'
|
|
6
|
-
import {
|
|
6
|
+
import { applyExtendtype } from './extend'
|
|
7
7
|
import nodes from './nodes'
|
|
8
8
|
import set from './set'
|
|
9
9
|
import createState from './state'
|
|
@@ -27,17 +27,17 @@ const create = (element, parent, key, options = {}) => {
|
|
|
27
27
|
if (element === undefined) element = {}
|
|
28
28
|
if (element === null) return
|
|
29
29
|
|
|
30
|
-
// if element is
|
|
30
|
+
// if element is extend
|
|
31
31
|
if (element.__hash) {
|
|
32
|
-
element = {
|
|
32
|
+
element = { extend: element }
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
if (options.components) {
|
|
36
36
|
const { components } = options
|
|
37
|
-
const {
|
|
38
|
-
if (isString(
|
|
39
|
-
if (components[
|
|
40
|
-
else console.warn(
|
|
37
|
+
const { extend, component } = element
|
|
38
|
+
if (isString(extend))
|
|
39
|
+
if (components[extend]) element.extend = components[extend]
|
|
40
|
+
else console.warn(extend, 'is not in library', components, element)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// define KEY
|
|
@@ -51,18 +51,18 @@ const create = (element, parent, key, options = {}) => {
|
|
|
51
51
|
if (isString(element) || isNumber(element)) {
|
|
52
52
|
element = {
|
|
53
53
|
text: element,
|
|
54
|
-
tag: (!element.
|
|
54
|
+
tag: (!element.extend && parent.childExtend && parent.childExtend.tag) ||
|
|
55
55
|
((nodes.body.indexOf(key) > -1) && key) || 'string'
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// create PROTOtypal inheritance
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
applyExtendtype(element, parent, options)
|
|
62
62
|
|
|
63
63
|
if (Object.keys(options).length) {
|
|
64
64
|
registry.defaultOptions = options
|
|
65
|
-
if (options.
|
|
65
|
+
if (options.ignoreChildExtend) delete options.ignoreChildExtend
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// enable STATE
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isFunction, exec, getExtendStack, jointStacks, cloneAndMergeArrayExtend, deepMergeExtend } from '../utils'
|
|
4
|
+
|
|
5
|
+
const ENV = process.env.NODE_ENV
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checks whether element has `extend` or is a part
|
|
9
|
+
* of parent's `childExtend` extend
|
|
10
|
+
*/
|
|
11
|
+
export const applyExtendtype = (element, parent, options = {}) => {
|
|
12
|
+
if (isFunction(element)) element = exec(element, parent)
|
|
13
|
+
|
|
14
|
+
const { extend } = element
|
|
15
|
+
const extendStack = getExtendStack(extend)
|
|
16
|
+
|
|
17
|
+
if (ENV !== 'test' || ENV !== 'development') delete element.extend
|
|
18
|
+
|
|
19
|
+
let childExtendStack = []
|
|
20
|
+
if (parent) {
|
|
21
|
+
// Assign parent attr to the element
|
|
22
|
+
element.parent = parent
|
|
23
|
+
if (!options.ignoreChildExtend) {
|
|
24
|
+
childExtendStack = getExtendStack(parent.childExtend)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const extendLength = extendStack.length
|
|
29
|
+
const childExtendLength = childExtendStack.length
|
|
30
|
+
|
|
31
|
+
let stack = []
|
|
32
|
+
if (extendLength && childExtendLength) {
|
|
33
|
+
stack = jointStacks(extendStack, childExtendStack)
|
|
34
|
+
} else if (extendLength) {
|
|
35
|
+
stack = extendStack
|
|
36
|
+
} else if (childExtendLength) {
|
|
37
|
+
stack = childExtendStack
|
|
38
|
+
} else if (!options.extend) return element
|
|
39
|
+
|
|
40
|
+
if (options.extend) {
|
|
41
|
+
const defaultOptionsExtend = getExtendStack(options.extend)
|
|
42
|
+
stack = [].concat(stack, defaultOptionsExtend)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
element.__extend = stack
|
|
46
|
+
let mergedExtend = cloneAndMergeArrayExtend(stack)
|
|
47
|
+
|
|
48
|
+
const component = exec(element.component || mergedExtend.component, element)
|
|
49
|
+
if (component && options.components && options.components[component]) {
|
|
50
|
+
const componentExtend = cloneAndMergeArrayExtend(getExtendStack(options.components[component]))
|
|
51
|
+
mergedExtend = deepMergeExtend(componentExtend, mergedExtend)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return deepMergeExtend(element, mergedExtend)
|
|
55
|
+
}
|
|
@@ -21,10 +21,10 @@ export default {
|
|
|
21
21
|
class: classList,
|
|
22
22
|
state,
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
extend: {},
|
|
25
25
|
props: {},
|
|
26
26
|
path: {},
|
|
27
|
-
|
|
27
|
+
childExtend: {},
|
|
28
28
|
if: {},
|
|
29
29
|
define: {},
|
|
30
30
|
transform: {},
|
|
@@ -36,7 +36,7 @@ export default {
|
|
|
36
36
|
__trash: {},
|
|
37
37
|
__root: {},
|
|
38
38
|
__props: {},
|
|
39
|
-
|
|
39
|
+
__extend: {},
|
|
40
40
|
__ifFragment: {},
|
|
41
41
|
__ifFalsy: {},
|
|
42
42
|
__text: {},
|
package/src/element/props.js
CHANGED
|
@@ -37,10 +37,10 @@ const initProps = (element, parent) => {
|
|
|
37
37
|
propsStack.push(matchParentValue)
|
|
38
38
|
} else if (props) propsStack.push(props)
|
|
39
39
|
|
|
40
|
-
if (isArray(element.
|
|
41
|
-
element.
|
|
42
|
-
if (
|
|
43
|
-
return
|
|
40
|
+
if (isArray(element.__extend)) {
|
|
41
|
+
element.__extend.map(extend => {
|
|
42
|
+
if (extend.props) propsStack.push(extend.props)
|
|
43
|
+
return extend.props
|
|
44
44
|
})
|
|
45
45
|
}
|
|
46
46
|
|
package/src/element/set.js
CHANGED
|
@@ -25,10 +25,10 @@ const set = function (params, options) {
|
|
|
25
25
|
removeContentElement(params, element)
|
|
26
26
|
|
|
27
27
|
if (params) {
|
|
28
|
-
const {
|
|
29
|
-
if (!
|
|
28
|
+
const { childExtend } = params
|
|
29
|
+
if (!childExtend && element.childExtend) params.childExtend = element.childExtend
|
|
30
30
|
create(params, element, 'content', {
|
|
31
|
-
|
|
31
|
+
ignoreChildExtend: true,
|
|
32
32
|
...registry.defaultOptions
|
|
33
33
|
})
|
|
34
34
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec, isArray, isFunction, isObject } from './object'
|
|
4
|
+
|
|
5
|
+
export const generateHash = () => Math.random().toString(36).substring(2)
|
|
6
|
+
|
|
7
|
+
// hashing
|
|
8
|
+
export const extendStackRegistry = {}
|
|
9
|
+
export const extendCachedRegistry = {}
|
|
10
|
+
|
|
11
|
+
window.extendStackRegistry = extendStackRegistry
|
|
12
|
+
window.extendCachedRegistry = extendCachedRegistry
|
|
13
|
+
|
|
14
|
+
export const getHashedExtend = extend => {
|
|
15
|
+
return extendStackRegistry[extend.__hash]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const setHashedExtend = (extend, stack) => {
|
|
19
|
+
const hash = generateHash()
|
|
20
|
+
extend.__hash = hash
|
|
21
|
+
extendStackRegistry[hash] = stack
|
|
22
|
+
return stack
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const getExtendStackRegistry = (extend, stack) => {
|
|
26
|
+
if (extend.__hash)
|
|
27
|
+
return stack.concat(getHashedExtend(extend))
|
|
28
|
+
return setHashedExtend(extend, stack) // stack .concat(hashedExtend)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// stacking
|
|
32
|
+
export const extractArrayExtend = (extend, stack) => {
|
|
33
|
+
extend.forEach(each => flattenExtend(each, stack))
|
|
34
|
+
return stack
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const deepExtend = (extend, stack) => {
|
|
38
|
+
const extendOflattenExtend = extend.extend
|
|
39
|
+
if (extendOflattenExtend) {
|
|
40
|
+
flattenExtend(extendOflattenExtend, stack)
|
|
41
|
+
}
|
|
42
|
+
return stack
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const flattenExtend = (extend, stack) => {
|
|
46
|
+
if (!extend) return stack
|
|
47
|
+
if (isArray(extend)) return extractArrayExtend(extend, stack)
|
|
48
|
+
stack.push(extend)
|
|
49
|
+
if (extend.extend) deepExtend(extend, stack)
|
|
50
|
+
return stack
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// merging
|
|
54
|
+
export const deepCloneExtend = obj => {
|
|
55
|
+
const o = {}
|
|
56
|
+
for (const prop in obj) {
|
|
57
|
+
if (['parent', 'node', '__element', '__root', '__key'].indexOf(prop) > -1) continue
|
|
58
|
+
const objProp = obj[prop]
|
|
59
|
+
if (isObject(objProp)) {
|
|
60
|
+
o[prop] = deepCloneExtend(objProp)
|
|
61
|
+
} else if (isArray(objProp)) {
|
|
62
|
+
o[prop] = objProp.map(x => x)
|
|
63
|
+
} else o[prop] = objProp
|
|
64
|
+
}
|
|
65
|
+
return o
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const deepMergeExtend = (element, extend) => {
|
|
69
|
+
for (const e in extend) {
|
|
70
|
+
if (['parent', 'node', '__element', '__root'].indexOf(e) > -1) continue
|
|
71
|
+
const elementProp = element[e]
|
|
72
|
+
const extendProp = extend[e]
|
|
73
|
+
if (elementProp === undefined) {
|
|
74
|
+
element[e] = extendProp
|
|
75
|
+
} else if (isObject(elementProp) && isObject(extendProp)) {
|
|
76
|
+
deepMergeExtend(elementProp, extendProp)
|
|
77
|
+
} else if (isArray(elementProp) && isArray(extendProp)) {
|
|
78
|
+
element[e] = elementProp.concat(extendProp)
|
|
79
|
+
} else if (isArray(elementProp) && isObject(extendProp)) {
|
|
80
|
+
const obj = deepMergeExtend({}, elementProp)
|
|
81
|
+
element[e] = deepMergeExtend(obj, extendProp)
|
|
82
|
+
} else if (elementProp === undefined && isFunction(extendProp)) {
|
|
83
|
+
element[e] = extendProp
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return element
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const cloneAndMergeArrayExtend = stack => {
|
|
90
|
+
return stack.reduce((a, c) => {
|
|
91
|
+
return deepMergeExtend(a, deepCloneExtend(c))
|
|
92
|
+
}, {})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// joint stacks
|
|
96
|
+
export const jointStacks = (extendStack, childExtendStack) => {
|
|
97
|
+
return []
|
|
98
|
+
.concat(extendStack.slice(0, 1))
|
|
99
|
+
.concat(childExtendStack.slice(0, 1))
|
|
100
|
+
.concat(extendStack.slice(1))
|
|
101
|
+
.concat(childExtendStack.slice(1))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// init
|
|
105
|
+
export const getExtendStack = extend => {
|
|
106
|
+
if (!extend) return []
|
|
107
|
+
if (extend.__hash) return getHashedExtend(extend)
|
|
108
|
+
const stack = flattenExtend(extend, [])
|
|
109
|
+
// console.log(stack)
|
|
110
|
+
return getExtendStackRegistry(extend, stack)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const getExtendMerged = extend => {
|
|
114
|
+
const stack = getExtendStack(extend)
|
|
115
|
+
return cloneAndMergeArrayExtend(stack)
|
|
116
|
+
}
|
package/src/utils/index.js
CHANGED
package/src/utils/node.js
CHANGED
package/src/utils/object.js
CHANGED
|
@@ -71,17 +71,17 @@ export const merge = (element, obj) => {
|
|
|
71
71
|
return element
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export const deepMerge = (element,
|
|
74
|
+
export const deepMerge = (element, extend) => {
|
|
75
75
|
// console.groupCollapsed('deepMerge:')
|
|
76
|
-
for (const e in
|
|
76
|
+
for (const e in extend) {
|
|
77
77
|
const elementProp = element[e]
|
|
78
|
-
const
|
|
78
|
+
const extendProp = extend[e]
|
|
79
79
|
// const cachedProps = cache.props
|
|
80
80
|
if (e === 'parent' || e === 'props' || e === 'state') continue
|
|
81
81
|
if (elementProp === undefined) {
|
|
82
|
-
element[e] =
|
|
83
|
-
} else if (isObjectLike(elementProp) && isObject(
|
|
84
|
-
deepMerge(elementProp,
|
|
82
|
+
element[e] = extendProp
|
|
83
|
+
} else if (isObjectLike(elementProp) && isObject(extendProp)) {
|
|
84
|
+
deepMerge(elementProp, extendProp)
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
// console.groupEnd('deepMerge:')
|
|
@@ -105,7 +105,7 @@ export const deepClone = (obj, excluding = ['parent', 'node', '__element', '__ro
|
|
|
105
105
|
for (const prop in obj) {
|
|
106
106
|
if (excluding.indexOf(prop) > -1) continue
|
|
107
107
|
let objProp = obj[prop]
|
|
108
|
-
if (prop === '
|
|
108
|
+
if (prop === 'extend' && isArray(objProp)) {
|
|
109
109
|
objProp = mergeArray(objProp)
|
|
110
110
|
}
|
|
111
111
|
if (isObjectLike(objProp)) {
|
|
@@ -164,14 +164,14 @@ export const mergeIfExisted = (a, b) => {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
|
-
* Merges array
|
|
167
|
+
* Merges array extends
|
|
168
168
|
*/
|
|
169
169
|
export const mergeArray = (arr) => {
|
|
170
170
|
return arr.reduce((a, c) => deepMerge(a, deepClone(c)), {})
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
|
-
* Merges array
|
|
174
|
+
* Merges array extends
|
|
175
175
|
*/
|
|
176
176
|
export const mergeAndCloneIfArray = obj => {
|
|
177
177
|
return isArray(obj) ? mergeArray(obj) : deepClone(obj)
|
|
@@ -184,8 +184,8 @@ export const flattenRecursive = (param, prop, stack = []) => {
|
|
|
184
184
|
const objectized = mergeAndCloneIfArray(param)
|
|
185
185
|
stack.push(objectized)
|
|
186
186
|
|
|
187
|
-
const
|
|
188
|
-
if (
|
|
187
|
+
const extendOfExtend = objectized[prop]
|
|
188
|
+
if (extendOfExtend) flattenRecursive(extendOfExtend, prop, stack)
|
|
189
189
|
|
|
190
190
|
delete objectized[prop]
|
|
191
191
|
|
package/src/element/proto.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
import { isFunction, exec, getProtoStack, jointStacks, cloneAndMergeArrayProto, deepMergeProto } from '../utils'
|
|
4
|
-
|
|
5
|
-
const ENV = process.env.NODE_ENV
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Checks whether element has `proto` or is a part
|
|
9
|
-
* of parent's `childProto` prototype
|
|
10
|
-
*/
|
|
11
|
-
export const applyPrototype = (element, parent, options = {}) => {
|
|
12
|
-
if (isFunction(element)) element = exec(element, parent)
|
|
13
|
-
|
|
14
|
-
const { proto } = element
|
|
15
|
-
const protoStack = getProtoStack(proto)
|
|
16
|
-
|
|
17
|
-
if (ENV !== 'test' || ENV !== 'development') delete element.proto
|
|
18
|
-
|
|
19
|
-
let childProtoStack = []
|
|
20
|
-
if (parent) {
|
|
21
|
-
// Assign parent attr to the element
|
|
22
|
-
element.parent = parent
|
|
23
|
-
if (!options.ignoreChildProto) {
|
|
24
|
-
childProtoStack = getProtoStack(parent.childProto)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const protoLength = protoStack.length
|
|
29
|
-
const childProtoLength = childProtoStack.length
|
|
30
|
-
|
|
31
|
-
let stack = []
|
|
32
|
-
if (protoLength && childProtoLength) {
|
|
33
|
-
stack = jointStacks(protoStack, childProtoStack)
|
|
34
|
-
} else if (protoLength) {
|
|
35
|
-
stack = protoStack
|
|
36
|
-
} else if (childProtoLength) {
|
|
37
|
-
stack = childProtoStack
|
|
38
|
-
} else if (!options.proto) return element
|
|
39
|
-
|
|
40
|
-
if (options.proto) {
|
|
41
|
-
const defaultOptionsProto = getProtoStack(options.proto)
|
|
42
|
-
stack = [].concat(stack, defaultOptionsProto)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
element.__proto = stack
|
|
46
|
-
let mergedProto = cloneAndMergeArrayProto(stack)
|
|
47
|
-
|
|
48
|
-
const component = exec(element.component || mergedProto.component, element)
|
|
49
|
-
if (component && options.components && options.components[component]) {
|
|
50
|
-
const componentProto = cloneAndMergeArrayProto(getProtoStack(options.components[component]))
|
|
51
|
-
mergedProto = deepMergeProto(componentProto, mergedProto)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return deepMergeProto(element, mergedProto)
|
|
55
|
-
}
|
package/src/utils/protoUtils.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
import { exec, isArray, isFunction, isObject } from './object'
|
|
4
|
-
|
|
5
|
-
export const generateHash = () => Math.random().toString(36).substring(2)
|
|
6
|
-
|
|
7
|
-
// hashing
|
|
8
|
-
export const protoStackRegistry = {}
|
|
9
|
-
export const protoCachedRegistry = {}
|
|
10
|
-
|
|
11
|
-
window.protoStackRegistry = protoStackRegistry
|
|
12
|
-
window.protoCachedRegistry = protoCachedRegistry
|
|
13
|
-
|
|
14
|
-
export const getHashedProto = proto => {
|
|
15
|
-
return protoStackRegistry[proto.__hash]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const setHashedProto = (proto, stack) => {
|
|
19
|
-
const hash = generateHash()
|
|
20
|
-
proto.__hash = hash
|
|
21
|
-
protoStackRegistry[hash] = stack
|
|
22
|
-
return stack
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const getProtoStackRegistry = (proto, stack) => {
|
|
26
|
-
if (proto.__hash)
|
|
27
|
-
return stack.concat(getHashedProto(proto))
|
|
28
|
-
return setHashedProto(proto, stack) // stack .concat(hashedProto)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// stacking
|
|
32
|
-
export const extractArrayProto = (proto, stack) => {
|
|
33
|
-
proto.forEach(each => flattenProto(each, stack))
|
|
34
|
-
return stack
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const deepProto = (proto, stack) => {
|
|
38
|
-
const protoOflattenProto = proto.proto
|
|
39
|
-
if (protoOflattenProto) {
|
|
40
|
-
flattenProto(protoOflattenProto, stack)
|
|
41
|
-
}
|
|
42
|
-
return stack
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const flattenProto = (proto, stack) => {
|
|
46
|
-
if (!proto) return stack
|
|
47
|
-
if (isArray(proto)) return extractArrayProto(proto, stack)
|
|
48
|
-
stack.push(proto)
|
|
49
|
-
if (proto.proto) deepProto(proto, stack)
|
|
50
|
-
return stack
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// merging
|
|
54
|
-
export const deepCloneProto = obj => {
|
|
55
|
-
const o = {}
|
|
56
|
-
for (const prop in obj) {
|
|
57
|
-
if (['parent', 'node', '__element', '__root', '__key'].indexOf(prop) > -1) continue
|
|
58
|
-
const objProp = obj[prop]
|
|
59
|
-
if (isObject(objProp)) {
|
|
60
|
-
o[prop] = deepCloneProto(objProp)
|
|
61
|
-
} else if (isArray(objProp)) {
|
|
62
|
-
o[prop] = objProp.map(x => x)
|
|
63
|
-
} else o[prop] = objProp
|
|
64
|
-
}
|
|
65
|
-
return o
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export const deepMergeProto = (element, proto) => {
|
|
69
|
-
for (const e in proto) {
|
|
70
|
-
if (['parent', 'node', '__element', '__root'].indexOf(e) > -1) continue
|
|
71
|
-
const elementProp = element[e]
|
|
72
|
-
const protoProp = proto[e]
|
|
73
|
-
if (elementProp === undefined) {
|
|
74
|
-
element[e] = protoProp
|
|
75
|
-
} else if (isObject(elementProp) && isObject(protoProp)) {
|
|
76
|
-
deepMergeProto(elementProp, protoProp)
|
|
77
|
-
} else if (isArray(elementProp) && isArray(protoProp)) {
|
|
78
|
-
element[e] = elementProp.concat(protoProp)
|
|
79
|
-
} else if (isArray(elementProp) && isObject(protoProp)) {
|
|
80
|
-
const obj = deepMergeProto({}, elementProp)
|
|
81
|
-
element[e] = deepMergeProto(obj, protoProp)
|
|
82
|
-
} else if (elementProp === undefined && isFunction(protoProp)) {
|
|
83
|
-
element[e] = protoProp
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return element
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export const cloneAndMergeArrayProto = stack => {
|
|
90
|
-
return stack.reduce((a, c) => {
|
|
91
|
-
return deepMergeProto(a, deepCloneProto(c))
|
|
92
|
-
}, {})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// joint stacks
|
|
96
|
-
export const jointStacks = (protoStack, childProtoStack) => {
|
|
97
|
-
return []
|
|
98
|
-
.concat(protoStack.slice(0, 1))
|
|
99
|
-
.concat(childProtoStack.slice(0, 1))
|
|
100
|
-
.concat(protoStack.slice(1))
|
|
101
|
-
.concat(childProtoStack.slice(1))
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// init
|
|
105
|
-
export const getProtoStack = proto => {
|
|
106
|
-
if (!proto) return []
|
|
107
|
-
if (proto.__hash) return getHashedProto(proto)
|
|
108
|
-
const stack = flattenProto(proto, [])
|
|
109
|
-
// console.log(stack)
|
|
110
|
-
return getProtoStackRegistry(proto, stack)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export const getProtoMerged = proto => {
|
|
114
|
-
const stack = getProtoStack(proto)
|
|
115
|
-
return cloneAndMergeArrayProto(stack)
|
|
116
|
-
}
|