@symbo.ls/utils 3.2.3 → 3.14.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/LICENSE +25 -12
- package/README.md +106 -0
- package/array.js +162 -0
- package/cache.js +7 -0
- package/cdn.js +83 -0
- package/component.js +25 -0
- package/cookie.js +71 -0
- package/{src/detectHeight.js → detectHeight.js} +3 -3
- package/dist/cjs/array.js +168 -0
- package/dist/cjs/browser.js +0 -2
- package/dist/cjs/cache.js +26 -0
- package/dist/cjs/cdn.js +85 -0
- package/dist/cjs/component.js +45 -0
- package/dist/cjs/cookie.js +75 -0
- package/dist/cjs/date.js +1 -3
- package/dist/cjs/detectHeight.js +4 -6
- package/dist/cjs/element.js +136 -0
- package/dist/cjs/env.js +43 -0
- package/dist/cjs/events.js +39 -0
- package/dist/cjs/extends.js +434 -0
- package/dist/cjs/fibonacci.js +1 -3
- package/dist/cjs/files.js +1 -3
- package/dist/cjs/function.js +114 -0
- package/dist/cjs/globals.js +30 -0
- package/dist/cjs/if.js +48 -0
- package/dist/cjs/index.js +38 -425
- package/dist/cjs/key.js +38 -0
- package/dist/cjs/keys.js +201 -0
- package/dist/cjs/load.js +5 -7
- package/dist/cjs/log.js +34 -0
- package/dist/cjs/metadata.js +310 -0
- package/dist/cjs/methods.js +599 -0
- package/dist/cjs/node.js +35 -0
- package/dist/cjs/object.js +634 -0
- package/dist/cjs/projectKeys.js +35 -0
- package/dist/cjs/props.js +282 -0
- package/dist/cjs/scaling.js +5 -169
- package/dist/cjs/scope.js +44 -0
- package/dist/cjs/sharedLibraries.js +146 -0
- package/dist/cjs/state.js +173 -0
- package/dist/cjs/string-extra.js +72 -0
- package/dist/cjs/string.js +183 -0
- package/dist/cjs/style.js +1 -3
- package/dist/cjs/tags.js +220 -0
- package/dist/cjs/triggerEvent.js +112 -0
- package/dist/cjs/types.js +74 -0
- package/dist/cjs/update.js +42 -0
- package/dist/esm/array.js +148 -0
- package/dist/esm/browser.js +14 -0
- package/dist/esm/cache.js +6 -0
- package/dist/esm/cdn.js +65 -0
- package/dist/esm/component.js +25 -0
- package/dist/esm/cookie.js +55 -0
- package/dist/esm/date.js +11 -0
- package/dist/esm/detectHeight.js +42 -0
- package/dist/esm/element.js +116 -0
- package/dist/esm/env.js +23 -0
- package/dist/esm/events.js +19 -0
- package/dist/esm/extends.js +414 -0
- package/dist/esm/fibonacci.js +10 -0
- package/dist/esm/files.js +4 -0
- package/dist/esm/function.js +94 -0
- package/dist/esm/globals.js +10 -0
- package/dist/esm/if.js +28 -0
- package/dist/esm/index.js +37 -0
- package/dist/esm/key.js +18 -0
- package/dist/esm/keys.js +181 -0
- package/dist/esm/load.js +151 -0
- package/dist/esm/log.js +14 -0
- package/dist/esm/metadata.js +290 -0
- package/dist/esm/methods.js +569 -0
- package/dist/esm/node.js +15 -0
- package/dist/esm/object.js +621 -0
- package/dist/esm/projectKeys.js +16 -0
- package/dist/esm/props.js +262 -0
- package/dist/esm/scaling.js +15 -0
- package/dist/esm/scope.js +24 -0
- package/dist/esm/sharedLibraries.js +126 -0
- package/dist/esm/state.js +163 -0
- package/dist/esm/string-extra.js +52 -0
- package/dist/esm/string.js +163 -0
- package/dist/esm/style.js +20 -0
- package/dist/esm/tags.js +200 -0
- package/dist/esm/triggerEvent.js +92 -0
- package/dist/esm/types.js +54 -0
- package/dist/esm/update.js +22 -0
- package/dist/iife/index.js +5818 -0
- package/element.js +148 -0
- package/env.js +15 -0
- package/events.js +19 -0
- package/extends.js +519 -0
- package/function.js +145 -0
- package/globals.js +8 -0
- package/if.js +30 -0
- package/index.js +41 -0
- package/key.js +20 -0
- package/keys.js +176 -0
- package/log.js +12 -0
- package/metadata.js +392 -0
- package/methods.js +636 -0
- package/node.js +37 -0
- package/object.js +803 -0
- package/package.json +38 -22
- package/projectKeys.js +30 -0
- package/props.js +327 -0
- package/{src/scaling.js → scaling.js} +1 -1
- package/scope.js +32 -0
- package/sharedLibraries.js +184 -0
- package/state.js +203 -0
- package/{src/index.js → string-extra.js} +11 -17
- package/string.js +206 -0
- package/tags.js +176 -0
- package/triggerEvent.js +102 -0
- package/types.js +55 -0
- package/update.js +27 -0
- package/dist/cjs/package.json +0 -4
- /package/{src/browser.js → browser.js} +0 -0
- /package/{src/date.js → date.js} +0 -0
- /package/{src/fibonacci.js → fibonacci.js} +0 -0
- /package/{src/files.js → files.js} +0 -0
- /package/{src/load.js → load.js} +0 -0
- /package/{src/style.js → style.js} +0 -0
package/element.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { createExtends } from './extends.js'
|
|
4
|
+
import { createKey } from './key.js'
|
|
5
|
+
import { isNode } from './node.js'
|
|
6
|
+
import { createProps } from './props.js'
|
|
7
|
+
import { HTML_TAGS } from './tags.js'
|
|
8
|
+
import { is, isFunction } from './types.js'
|
|
9
|
+
|
|
10
|
+
const ENV = process.env.NODE_ENV
|
|
11
|
+
|
|
12
|
+
export const returnValueAsText = (element, parent, key) => {
|
|
13
|
+
const childExtendsTag = parent.childExtends && parent.childExtends.tag
|
|
14
|
+
const childPropsTag = parent.childProps && parent.childProps.tag
|
|
15
|
+
const isKeyValidHTMLTag = HTML_TAGS.body.has(key) && key
|
|
16
|
+
return {
|
|
17
|
+
text: element,
|
|
18
|
+
tag: childExtendsTag || childPropsTag || isKeyValidHTMLTag || 'string'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const createBasedOnType = (element, parent, key) => {
|
|
23
|
+
// if ELEMENT is not given
|
|
24
|
+
if (element === undefined) {
|
|
25
|
+
if (ENV === 'test' || ENV === 'development') {
|
|
26
|
+
console.warn(
|
|
27
|
+
key,
|
|
28
|
+
'element is undefined in',
|
|
29
|
+
parent?.__ref?.path
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
return {}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (element === null) return
|
|
36
|
+
if (element === true) return {}
|
|
37
|
+
|
|
38
|
+
if (is(element)('string', 'number')) {
|
|
39
|
+
return returnValueAsText(element, parent, key)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (isFunction(element)) {
|
|
43
|
+
return { props: element }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return element
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const addRef = (element, parent) => {
|
|
50
|
+
const ref = {}
|
|
51
|
+
ref.origin = element
|
|
52
|
+
ref.parent = parent
|
|
53
|
+
return ref
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const createParent = (element, parent, key, options, root) => {
|
|
57
|
+
if (!parent) return root
|
|
58
|
+
if (isNode(parent)) {
|
|
59
|
+
const parentNodeWrapper = { key: ':root', node: parent }
|
|
60
|
+
root[`${key}_parent`] = parentNodeWrapper
|
|
61
|
+
return parentNodeWrapper
|
|
62
|
+
}
|
|
63
|
+
return parent
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const createRoot = (element, parent) => {
|
|
67
|
+
const { __ref: ref } = element
|
|
68
|
+
const { __ref: parentRef } = parent
|
|
69
|
+
|
|
70
|
+
const hasRoot = parent && parent.key === ':root'
|
|
71
|
+
if (!ref?.root) {
|
|
72
|
+
ref.root = hasRoot ? element : parentRef?.root
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const createPath = (element, parent, key) => {
|
|
77
|
+
let { __ref: parentRef } = parent
|
|
78
|
+
// set the PATH array
|
|
79
|
+
if (!parentRef) parentRef = parent.ref = {}
|
|
80
|
+
if (!parentRef.path) parentRef.path = []
|
|
81
|
+
return parentRef.path.concat(key)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const addContext = (element, parent, key, options, root) => {
|
|
85
|
+
const forcedOptionsContext =
|
|
86
|
+
options.context && !root.context && !element.context
|
|
87
|
+
if (forcedOptionsContext) root.context = options.context
|
|
88
|
+
|
|
89
|
+
// inherit from parent or root
|
|
90
|
+
return options.context || parent.context || root.context || element.context
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const addCaching = (element, parent, key) => {
|
|
94
|
+
const ref = addRef(element, parent)
|
|
95
|
+
|
|
96
|
+
element.__ref = ref
|
|
97
|
+
|
|
98
|
+
// enable CACHING
|
|
99
|
+
if (!ref.__defineCache) ref.__defineCache = {}
|
|
100
|
+
|
|
101
|
+
// enable EXEC
|
|
102
|
+
if (!ref.__exec) ref.__exec = {}
|
|
103
|
+
if (!ref.__execProps) ref.__execProps = {}
|
|
104
|
+
|
|
105
|
+
// enable CLASS CACHING
|
|
106
|
+
if (!ref.__class) ref.__class = {}
|
|
107
|
+
if (!ref.__classNames) ref.__classNames = {}
|
|
108
|
+
|
|
109
|
+
// enable CLASS CACHING
|
|
110
|
+
if (!ref.__attr) ref.__attr = {}
|
|
111
|
+
|
|
112
|
+
// enable CHANGES storing
|
|
113
|
+
if (!ref.__changes) ref.__changes = []
|
|
114
|
+
|
|
115
|
+
// enable CHANGES storing
|
|
116
|
+
if (!ref.__children) ref.__children = []
|
|
117
|
+
|
|
118
|
+
ref.__extends = createExtends(element, parent, key)
|
|
119
|
+
ref.path = createPath(element, parent, key)
|
|
120
|
+
|
|
121
|
+
return ref
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const createElement = (passedProps, parentEl, passedKey, opts, root) => {
|
|
125
|
+
const hashed = passedProps?.__hash
|
|
126
|
+
const element = hashed
|
|
127
|
+
? { extends: [passedProps] }
|
|
128
|
+
: createBasedOnType(passedProps, parentEl, passedKey)
|
|
129
|
+
if (!element) return
|
|
130
|
+
|
|
131
|
+
const parent = createParent(element, parentEl, passedKey, opts, root)
|
|
132
|
+
const key = createKey(element, parent, passedKey)
|
|
133
|
+
|
|
134
|
+
addCaching(element, parent, key)
|
|
135
|
+
|
|
136
|
+
const props = createProps(element, parent, key)
|
|
137
|
+
const context = addContext(element, parent, key, opts, root)
|
|
138
|
+
const on = element.on || {}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
...element,
|
|
142
|
+
key,
|
|
143
|
+
props,
|
|
144
|
+
parent,
|
|
145
|
+
context,
|
|
146
|
+
on
|
|
147
|
+
}
|
|
148
|
+
}
|
package/env.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// @preserve-env
|
|
4
|
+
export const NODE_ENV = process.env.NODE_ENV
|
|
5
|
+
export const ENV = NODE_ENV
|
|
6
|
+
|
|
7
|
+
export const isProduction = (env = NODE_ENV) => env === 'production'
|
|
8
|
+
export const isTest = (env = NODE_ENV) => env === 'testing' || env === 'test'
|
|
9
|
+
export const isTesting = isTest
|
|
10
|
+
export const isStaging = (env = NODE_ENV) => env === 'staging'
|
|
11
|
+
export const isLocal = (env = NODE_ENV) => env === 'local'
|
|
12
|
+
export const isDevelopment = (env = NODE_ENV) =>
|
|
13
|
+
env === 'development' || env === 'dev' || env === 'local'
|
|
14
|
+
export const getNev = (key, env = NODE_ENV) => env[key]
|
|
15
|
+
export const isNotProduction = (env = NODE_ENV) => !isProduction(env)
|
package/events.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { lowercaseFirstLetter } from './string.js'
|
|
4
|
+
import { isFunction } from './types.js'
|
|
5
|
+
|
|
6
|
+
export function addEventFromProps (key, obj) {
|
|
7
|
+
const { props, on } = obj
|
|
8
|
+
const eventName = lowercaseFirstLetter(key.split('on')[1])
|
|
9
|
+
const origEvent = on[eventName]
|
|
10
|
+
const funcFromProps = props[key]
|
|
11
|
+
if (isFunction(origEvent)) {
|
|
12
|
+
on[eventName] = (...args) => {
|
|
13
|
+
const originalEventRetunrs = origEvent(...args)
|
|
14
|
+
if (originalEventRetunrs !== false) {
|
|
15
|
+
if (isFunction(funcFromProps)) return funcFromProps(...args)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} else on[eventName] = funcFromProps
|
|
19
|
+
}
|
package/extends.js
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { joinArrays, removeDuplicatesInArray } from './array.js'
|
|
4
|
+
import { matchesComponentNaming } from './component.js'
|
|
5
|
+
import { deepClone, exec } from './object.js'
|
|
6
|
+
import { isArray, isObject, isString } from './types.js'
|
|
7
|
+
const ENV = process.env.NODE_ENV
|
|
8
|
+
const isSourcemapEnabled = (options) => options.sourcemap !== false && ENV !== 'production'
|
|
9
|
+
|
|
10
|
+
export const createExtendsFromKeys = key => {
|
|
11
|
+
if (key.includes('+')) {
|
|
12
|
+
return key.split('+').filter(matchesComponentNaming)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (key.includes('_')) {
|
|
16
|
+
const [first] = key.split('_')
|
|
17
|
+
return [first]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (key.includes('.') && !matchesComponentNaming(key.split('.')[1])) {
|
|
21
|
+
const [first] = key.split('.')
|
|
22
|
+
return [first]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return [key]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Initial extend creation
|
|
29
|
+
export const createExtends = (element, parent, key) => {
|
|
30
|
+
let __extends = []
|
|
31
|
+
const keyExtends = createExtendsFromKeys(key)
|
|
32
|
+
if (keyExtends) __extends = [...keyExtends]
|
|
33
|
+
const elementExtends = element.extends
|
|
34
|
+
if (elementExtends) {
|
|
35
|
+
__extends = isArray(elementExtends)
|
|
36
|
+
? [...__extends, ...elementExtends]
|
|
37
|
+
: [...__extends, elementExtends]
|
|
38
|
+
}
|
|
39
|
+
return __extends
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const addExtends = (newExtends, element) => {
|
|
43
|
+
const { __ref: ref } = element
|
|
44
|
+
let { __extends } = ref
|
|
45
|
+
|
|
46
|
+
if (!newExtends) return __extends
|
|
47
|
+
|
|
48
|
+
// Check if the first extend has a variant in components
|
|
49
|
+
const variant = element.variant
|
|
50
|
+
const context = element.context
|
|
51
|
+
if (
|
|
52
|
+
variant &&
|
|
53
|
+
context?.components &&
|
|
54
|
+
!Array.isArray(newExtends) &&
|
|
55
|
+
typeof newExtends === 'string'
|
|
56
|
+
) {
|
|
57
|
+
const variantKey = `${newExtends}.${variant}`
|
|
58
|
+
if (context.components[variantKey]) {
|
|
59
|
+
newExtends = variantKey
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!__extends.includes(newExtends)) {
|
|
64
|
+
__extends = Array.isArray(newExtends)
|
|
65
|
+
? [...__extends, ...newExtends]
|
|
66
|
+
: [...__extends, newExtends]
|
|
67
|
+
ref.__extends = __extends
|
|
68
|
+
}
|
|
69
|
+
return __extends
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const concatAddExtends = (newExtend, element) => {
|
|
73
|
+
if (!newExtend) return element
|
|
74
|
+
const { extends: elementExtend } = element
|
|
75
|
+
const originalArray = isArray(elementExtend) ? elementExtend : [elementExtend]
|
|
76
|
+
const receivedArray = isArray(newExtend) ? newExtend : [newExtend]
|
|
77
|
+
return {
|
|
78
|
+
...element,
|
|
79
|
+
extends: joinArrays(receivedArray, originalArray)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const generateHash = () => Math.random().toString(36).substring(2)
|
|
84
|
+
|
|
85
|
+
// hashing
|
|
86
|
+
export const extendStackRegistry = {}
|
|
87
|
+
export const extendCachedRegistry = {}
|
|
88
|
+
|
|
89
|
+
export const getHashedExtend = extend => {
|
|
90
|
+
return extendStackRegistry[extend.__hash]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const setHashedExtend = (extend, stack) => {
|
|
94
|
+
const hash = generateHash()
|
|
95
|
+
if (!isString(extend)) {
|
|
96
|
+
extend.__hash = hash
|
|
97
|
+
}
|
|
98
|
+
if (hash !== '__proto__' && hash !== 'constructor' && hash !== 'prototype') {
|
|
99
|
+
extendStackRegistry[hash] = stack
|
|
100
|
+
}
|
|
101
|
+
return stack
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const getExtendsStackRegistry = (extend, stack) => {
|
|
105
|
+
if (extend.__hash) {
|
|
106
|
+
return stack.concat(getHashedExtend(extend))
|
|
107
|
+
}
|
|
108
|
+
return setHashedExtend(extend, stack) // stack .concat(hashedExtend)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// stacking
|
|
112
|
+
export const extractArrayExtend = (
|
|
113
|
+
extend,
|
|
114
|
+
stack,
|
|
115
|
+
context,
|
|
116
|
+
processed = new Set(),
|
|
117
|
+
nameStack,
|
|
118
|
+
componentNameMap
|
|
119
|
+
) => {
|
|
120
|
+
for (const each of extend) {
|
|
121
|
+
if (isArray(each)) {
|
|
122
|
+
extractArrayExtend(each, stack, context, processed, nameStack, componentNameMap)
|
|
123
|
+
} else {
|
|
124
|
+
flattenExtend(each, stack, context, processed, nameStack, undefined, componentNameMap)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return stack
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const deepExtend = (extend, stack, context, processed = new Set(), nameStack, currentName, componentNameMap) => {
|
|
131
|
+
const extendOflattenExtend = extend.extends
|
|
132
|
+
const cleanExtend = { ...extend }
|
|
133
|
+
delete cleanExtend.extends
|
|
134
|
+
let hasKeys = false
|
|
135
|
+
for (const _k in cleanExtend) { hasKeys = true; break } // eslint-disable-line
|
|
136
|
+
if (hasKeys) {
|
|
137
|
+
stack.push(cleanExtend)
|
|
138
|
+
if (nameStack) nameStack.push(currentName)
|
|
139
|
+
}
|
|
140
|
+
if (extendOflattenExtend) {
|
|
141
|
+
flattenExtend(extendOflattenExtend, stack, context, processed, nameStack, currentName, componentNameMap)
|
|
142
|
+
}
|
|
143
|
+
return stack
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export const flattenExtend = (
|
|
147
|
+
extend,
|
|
148
|
+
stack,
|
|
149
|
+
context,
|
|
150
|
+
processed = new Set(),
|
|
151
|
+
nameStack,
|
|
152
|
+
parentName,
|
|
153
|
+
componentNameMap
|
|
154
|
+
) => {
|
|
155
|
+
if (!extend) return stack
|
|
156
|
+
if (processed.has(extend)) return stack
|
|
157
|
+
|
|
158
|
+
if (isArray(extend)) {
|
|
159
|
+
return extractArrayExtend(extend, stack, context, processed, nameStack, componentNameMap)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let currentName = parentName
|
|
163
|
+
if (isString(extend)) {
|
|
164
|
+
currentName = extend
|
|
165
|
+
extend = mapStringsWithContextComponents(extend, context)
|
|
166
|
+
} else if (componentNameMap && isObject(extend) && componentNameMap.has(extend)) {
|
|
167
|
+
// Resolve name from pre-built map (top-level resolved extends)
|
|
168
|
+
currentName = componentNameMap.get(extend)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
processed.add(extend)
|
|
172
|
+
|
|
173
|
+
if (extend?.extends) {
|
|
174
|
+
deepExtend(extend, stack, context, processed, nameStack, currentName, componentNameMap)
|
|
175
|
+
} else if (extend) {
|
|
176
|
+
stack.push(extend)
|
|
177
|
+
if (nameStack) nameStack.push(currentName)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return stack
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const MERGE_EXTENDS_SKIP = new Set([
|
|
184
|
+
'parent', 'node', '__ref', '__proto__', 'extends', 'childExtends', 'childExtendsRecursive'
|
|
185
|
+
])
|
|
186
|
+
|
|
187
|
+
export const deepMergeExtends = (element, extend, sourcemap, sourceName, preBuiltSourcemap) => {
|
|
188
|
+
// Clone extend to prevent mutations
|
|
189
|
+
extend = deepClone(extend)
|
|
190
|
+
|
|
191
|
+
for (const e in extend) {
|
|
192
|
+
if (MERGE_EXTENDS_SKIP.has(e)) continue
|
|
193
|
+
|
|
194
|
+
const elementProp = element[e]
|
|
195
|
+
const extendProp = extend[e]
|
|
196
|
+
|
|
197
|
+
// Skip if the property is undefined in the extend object
|
|
198
|
+
if (extendProp === undefined) continue
|
|
199
|
+
|
|
200
|
+
// Handle only properties that exist in the extend object
|
|
201
|
+
if (
|
|
202
|
+
Object.prototype.hasOwnProperty.call(extend, e) &&
|
|
203
|
+
e !== '__proto__' && e !== 'constructor' && e !== 'prototype'
|
|
204
|
+
) {
|
|
205
|
+
if (elementProp === undefined) {
|
|
206
|
+
// For undefined properties in element, copy from extend
|
|
207
|
+
element[e] = extendProp
|
|
208
|
+
// Track sourcemap for this property
|
|
209
|
+
if (sourcemap && sourceName) {
|
|
210
|
+
if (isObject(extendProp) && !isArray(extendProp)) {
|
|
211
|
+
sourcemap[e] = sourcemap[e] || {}
|
|
212
|
+
trackSourcemapDeep(sourcemap[e], extendProp, sourceName)
|
|
213
|
+
} else {
|
|
214
|
+
sourcemap[e] = sourceName
|
|
215
|
+
}
|
|
216
|
+
} else if (sourcemap && preBuiltSourcemap?.[e]) {
|
|
217
|
+
// Copy sourcemap entry from pre-built sourcemap (used in finalizeExtends)
|
|
218
|
+
sourcemap[e] = preBuiltSourcemap[e]
|
|
219
|
+
}
|
|
220
|
+
} else if (isObject(elementProp) && isObject(extendProp)) {
|
|
221
|
+
// For objects, merge based on type
|
|
222
|
+
const nestedSourcemap = sourcemap ? (sourcemap[e] = sourcemap[e] || {}) : undefined
|
|
223
|
+
const nestedPreBuilt = preBuiltSourcemap?.[e]
|
|
224
|
+
if (matchesComponentNaming(e)) {
|
|
225
|
+
// For components, override base properties with extended ones
|
|
226
|
+
element[e] = deepMergeExtends(elementProp, extendProp, nestedSourcemap, sourceName, nestedPreBuilt)
|
|
227
|
+
} else {
|
|
228
|
+
// For other objects, merge normally
|
|
229
|
+
deepMergeExtends(elementProp, extendProp, nestedSourcemap, sourceName, nestedPreBuilt)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (
|
|
234
|
+
e === 'extends' ||
|
|
235
|
+
e === 'childExtends' ||
|
|
236
|
+
e === 'childExtendsRecursive'
|
|
237
|
+
) {
|
|
238
|
+
if (isArray(elementProp) && isArray(extendProp)) {
|
|
239
|
+
element[e] = elementProp.concat(extendProp)
|
|
240
|
+
} else if (isArray(elementProp) && isObject(extendProp)) {
|
|
241
|
+
const obj = deepMergeExtends({}, elementProp)
|
|
242
|
+
element[e] = deepMergeExtends(obj, extendProp)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// If elementProp is defined and not an object, keep it (don't override)
|
|
246
|
+
// This preserves properties from earlier in the extend chain
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return element
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const trackSourcemapDeep = (sourcemap, obj, sourceName, seen) => {
|
|
254
|
+
if (!seen) seen = new WeakSet()
|
|
255
|
+
if (seen.has(obj)) return
|
|
256
|
+
seen.add(obj)
|
|
257
|
+
for (const key in obj) {
|
|
258
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue
|
|
259
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
|
|
260
|
+
const val = obj[key]
|
|
261
|
+
if (isObject(val) && !isArray(val)) {
|
|
262
|
+
sourcemap[key] = sourcemap[key] || {}
|
|
263
|
+
trackSourcemapDeep(sourcemap[key], val, sourceName, seen)
|
|
264
|
+
} else {
|
|
265
|
+
sourcemap[key] = sourceName
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export const cloneAndMergeArrayExtend = (stack, sourcemap, extendNames) => {
|
|
271
|
+
return stack.reduce((acc, current, i) => {
|
|
272
|
+
// Clone current extend to avoid mutations
|
|
273
|
+
const cloned = deepClone(current)
|
|
274
|
+
const sourceName = extendNames ? extendNames[i] : undefined
|
|
275
|
+
// Merge into accumulator, giving priority to current extend
|
|
276
|
+
return deepMergeExtends(acc, cloned, sourcemap, sourceName)
|
|
277
|
+
}, {})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export const mapStringsWithContextComponents = (
|
|
281
|
+
extend,
|
|
282
|
+
context,
|
|
283
|
+
options = {},
|
|
284
|
+
variant
|
|
285
|
+
) => {
|
|
286
|
+
const COMPONENTS = context?.components || options.components
|
|
287
|
+
const PAGES = context?.pages || options.pages
|
|
288
|
+
if (isString(extend)) {
|
|
289
|
+
const componentExists =
|
|
290
|
+
COMPONENTS &&
|
|
291
|
+
(COMPONENTS[extend + '.' + variant] ||
|
|
292
|
+
COMPONENTS[extend] ||
|
|
293
|
+
COMPONENTS['smbls.' + extend])
|
|
294
|
+
const pageExists = PAGES && extend.charCodeAt(0) === 47 && PAGES[extend]
|
|
295
|
+
if (componentExists) return componentExists
|
|
296
|
+
else if (pageExists) return pageExists
|
|
297
|
+
else {
|
|
298
|
+
if (options.verbose && (ENV === 'test' || ENV === 'development')) {
|
|
299
|
+
console.warn('Extend is string but component was not found:', extend)
|
|
300
|
+
}
|
|
301
|
+
return
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return extend
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// joint stacks
|
|
308
|
+
export const jointStacks = (extendStack, childExtendsStack) => {
|
|
309
|
+
return []
|
|
310
|
+
.concat(extendStack.slice(0, 1))
|
|
311
|
+
.concat(childExtendsStack.slice(0, 1))
|
|
312
|
+
.concat(extendStack.slice(1))
|
|
313
|
+
.concat(childExtendsStack.slice(1))
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// init
|
|
317
|
+
export const getExtendsStack = (extend, context, nameStack, componentNameMap) => {
|
|
318
|
+
if (!extend) return []
|
|
319
|
+
if (extend.__hash) return getHashedExtend(extend) || []
|
|
320
|
+
const processed = new Set()
|
|
321
|
+
const stack = flattenExtend(extend, [], context, processed, nameStack, undefined, componentNameMap)
|
|
322
|
+
if (nameStack) return stack
|
|
323
|
+
return getExtendsStackRegistry(extend, stack)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export const addExtend = (newExtends, elementExtends) => {
|
|
327
|
+
if (!newExtends) return elementExtends
|
|
328
|
+
const receivedArray = isArray(newExtends) ? newExtends : [newExtends]
|
|
329
|
+
return joinArrays(receivedArray, elementExtends)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export const getExtendsInElement = obj => {
|
|
333
|
+
let result = []
|
|
334
|
+
|
|
335
|
+
function traverse (o) {
|
|
336
|
+
for (const key in o) {
|
|
337
|
+
if (Object.prototype.hasOwnProperty.call(o, key)) {
|
|
338
|
+
// Check if the key starts with a capital letter and exclude keys like @mobileL, $router
|
|
339
|
+
if (matchesComponentNaming(key)) {
|
|
340
|
+
result.push(key)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Check if the key is "extend" and it's either a string or an array
|
|
344
|
+
if (key === 'extends') {
|
|
345
|
+
// Add the value of the extend key to the result array
|
|
346
|
+
if (typeof o[key] === 'string') {
|
|
347
|
+
result.push(o[key])
|
|
348
|
+
} else if (Array.isArray(o[key])) {
|
|
349
|
+
result = result.concat(o[key])
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// If the property is an object, traverse it
|
|
354
|
+
if (typeof o[key] === 'object' && o[key] !== null) {
|
|
355
|
+
traverse(o[key])
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
traverse(obj)
|
|
362
|
+
return result
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export const createElementExtends = (element, parent, options = {}) => {
|
|
366
|
+
const { __ref: ref } = element
|
|
367
|
+
const context = element.context || parent.context
|
|
368
|
+
const variant = element.variant
|
|
369
|
+
|
|
370
|
+
if (element.extends) {
|
|
371
|
+
if (Array.isArray(element.extends) && element.extends.length > 0) {
|
|
372
|
+
// Handle first item in array specially for variant
|
|
373
|
+
const [firstExtend, ...restExtends] = element.extends
|
|
374
|
+
if (typeof firstExtend === 'string' && variant && context?.components) {
|
|
375
|
+
const variantKey = `${firstExtend}.${variant}`
|
|
376
|
+
if (context.components[variantKey]) {
|
|
377
|
+
addExtends([variantKey, ...restExtends], element)
|
|
378
|
+
} else {
|
|
379
|
+
addExtends(element.extends, element)
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
addExtends(element.extends, element)
|
|
383
|
+
}
|
|
384
|
+
} else if (
|
|
385
|
+
typeof element.extends === 'string' &&
|
|
386
|
+
variant &&
|
|
387
|
+
context?.components
|
|
388
|
+
) {
|
|
389
|
+
const variantKey = `${element.extends}.${variant}`
|
|
390
|
+
if (context.components[variantKey]) {
|
|
391
|
+
addExtends(variantKey, element)
|
|
392
|
+
} else {
|
|
393
|
+
addExtends(element.extends, element)
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
addExtends(element.extends, element)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
inheritChildPropsExtends(element, parent, options)
|
|
401
|
+
inheritChildExtends(element, parent, options)
|
|
402
|
+
inheritRecursiveChildExtends(element, parent, options)
|
|
403
|
+
|
|
404
|
+
if (element.component) {
|
|
405
|
+
addExtends(exec(element.component, element), element)
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (context.defaultExtends) {
|
|
409
|
+
addExtends(context.defaultExtends, element)
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return removeDuplicatesInArray(ref.__extends)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export const inheritChildPropsExtends = (element, parent, options = {}) => {
|
|
416
|
+
const { __ref: ref } = element
|
|
417
|
+
const ignoreChildExtends =
|
|
418
|
+
options.ignoreChildExtends || element.ignoreChildExtends
|
|
419
|
+
if (!ignoreChildExtends) {
|
|
420
|
+
if (parent.childProps?.extends) {
|
|
421
|
+
addExtends(parent.childProps.extends, element)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return ref.__extends
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export const inheritChildExtends = (element, parent, options = {}) => {
|
|
428
|
+
const { __ref: ref } = element
|
|
429
|
+
const ignoreChildExtends =
|
|
430
|
+
options.ignoreChildExtends || element.ignoreChildExtends
|
|
431
|
+
|
|
432
|
+
const childExtends = parent.childExtends
|
|
433
|
+
if (!ignoreChildExtends && childExtends) {
|
|
434
|
+
addExtends(childExtends, element)
|
|
435
|
+
}
|
|
436
|
+
return ref.__extends
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export const inheritRecursiveChildExtends = (element, parent, options = {}) => {
|
|
440
|
+
const { __ref: ref } = element
|
|
441
|
+
const childExtendsRecursive = parent.childExtendsRecursive
|
|
442
|
+
const ignoreChildExtendsRecursive =
|
|
443
|
+
options.ignoreChildExtendsRecursive || element.ignoreChildExtendsRecursive
|
|
444
|
+
const isText = element.key === '__text'
|
|
445
|
+
if (childExtendsRecursive && !isText && !ignoreChildExtendsRecursive) {
|
|
446
|
+
addExtends(childExtendsRecursive, element)
|
|
447
|
+
}
|
|
448
|
+
return ref.__extends
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export const createExtendsStack = (element, parent, options = {}) => {
|
|
452
|
+
const { __ref: ref } = element
|
|
453
|
+
const context = element.context || parent.context
|
|
454
|
+
|
|
455
|
+
const variant = element.variant
|
|
456
|
+
|
|
457
|
+
// Keep original string names before resolution for sourcemap tracking
|
|
458
|
+
const sourcemap = isSourcemapEnabled(options)
|
|
459
|
+
const originalExtendNames = sourcemap ? [...ref.__extends] : null
|
|
460
|
+
|
|
461
|
+
const __extends = removeDuplicatesInArray(
|
|
462
|
+
ref.__extends.map((val, i) => {
|
|
463
|
+
return mapStringsWithContextComponents(
|
|
464
|
+
val,
|
|
465
|
+
context,
|
|
466
|
+
options,
|
|
467
|
+
i === 0 && variant
|
|
468
|
+
)
|
|
469
|
+
})
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
if (sourcemap) {
|
|
473
|
+
// Build a map from resolved component objects to their original string names
|
|
474
|
+
const componentNameMap = new WeakMap()
|
|
475
|
+
for (let i = 0; i < __extends.length; i++) {
|
|
476
|
+
const resolved = __extends[i]
|
|
477
|
+
const originalName = originalExtendNames[i]
|
|
478
|
+
if (resolved && isObject(resolved) && isString(originalName)) {
|
|
479
|
+
componentNameMap.set(resolved, originalName)
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
const nameStack = []
|
|
483
|
+
const stack = getExtendsStack(__extends, context, nameStack, componentNameMap)
|
|
484
|
+
ref.__extendsStack = stack
|
|
485
|
+
ref.__extendsNames = nameStack
|
|
486
|
+
} else {
|
|
487
|
+
const stack = getExtendsStack(__extends, context)
|
|
488
|
+
ref.__extendsStack = stack
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return ref.__extendsStack
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export const finalizeExtends = (element, parent, options = {}) => {
|
|
495
|
+
const { __ref: ref } = element
|
|
496
|
+
const { __extendsStack } = ref
|
|
497
|
+
|
|
498
|
+
if (isSourcemapEnabled(options)) {
|
|
499
|
+
const sourcemapAcc = {}
|
|
500
|
+
const extendNames = ref.__extendsNames || []
|
|
501
|
+
const flattenExtends = cloneAndMergeArrayExtend(__extendsStack, sourcemapAcc, extendNames)
|
|
502
|
+
// Only keep sourcemap entries for properties actually merged into element
|
|
503
|
+
const appliedSourcemap = {}
|
|
504
|
+
deepMergeExtends(element, flattenExtends, appliedSourcemap, undefined, sourcemapAcc)
|
|
505
|
+
ref.__sourcemap = appliedSourcemap
|
|
506
|
+
} else {
|
|
507
|
+
const flattenExtends = cloneAndMergeArrayExtend(__extendsStack)
|
|
508
|
+
deepMergeExtends(element, flattenExtends)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return element
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export const applyExtends = (element, parent, options = {}) => {
|
|
515
|
+
createElementExtends(element, parent, options)
|
|
516
|
+
createExtendsStack(element, parent, options)
|
|
517
|
+
finalizeExtends(element, parent, options)
|
|
518
|
+
return element
|
|
519
|
+
}
|