@domql/element 2.3.117 → 2.3.154

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/applyParam.js ADDED
@@ -0,0 +1,25 @@
1
+ 'use strict'
2
+
3
+ import { isFunction } from '@domql/utils'
4
+ import { registry } from './mixins'
5
+
6
+ export const applyParam = (param, element, options) => {
7
+ const { node, context } = element
8
+ const prop = element[param]
9
+
10
+ const DOMQLProperty = registry[param]
11
+ const DOMQLPropertyFromContext = context && context.registry && context.registry[param]
12
+ const isGlobalTransformer = DOMQLPropertyFromContext || DOMQLProperty
13
+
14
+ const hasDefine = element.define && element.define[param]
15
+ const hasContextDefine = context && context.define && context.define[param]
16
+
17
+ if (isGlobalTransformer && !hasContextDefine) {
18
+ if (isFunction(isGlobalTransformer)) {
19
+ isGlobalTransformer(prop, element, node, options)
20
+ return
21
+ }
22
+ }
23
+
24
+ return { hasDefine, hasContextDefine }
25
+ }
package/create.js ADDED
@@ -0,0 +1,328 @@
1
+ 'use strict'
2
+
3
+ import { isObject, isFunction, isString, exec, is, isNode, isUndefined } from '@domql/utils'
4
+ import { ROOT } from '@domql/tree'
5
+ import { createKey } from '@domql/key'
6
+ import { TAGS } from '@domql/registry'
7
+ import { triggerEventOn } from '@domql/event'
8
+ import { appendNode, assignNode } from '@domql/render'
9
+ import { isMethod, lookup, setProps, remove, spotByPath } from '@domql/methods'
10
+ import { assignClass } from '@domql/classlist'
11
+ import { cacheNode, detectTag } from '@domql/node'
12
+ import { createState } from '@domql/state'
13
+ import { createProps } from '@domql/props'
14
+
15
+ import createNode from './node'
16
+ import { applyExtend } from './extend'
17
+ import set from './set'
18
+ import update from './update'
19
+ import { log, keys, parse, parseDeep, nextElement, previousElement } from './methods'
20
+ import { registry } from './mixins'
21
+ import { throughInitialExec } from './iterate'
22
+ import OPTIONS from './options'
23
+
24
+ import {
25
+ applyComponentFromContext,
26
+ applyKeyComponentAsExtend,
27
+ applyVariant,
28
+ checkIfKeyIsComponent,
29
+ isVariant
30
+ } from './utils/component'
31
+ import { removeContentElement, updateContentElement } from './remove'
32
+
33
+ const ENV = process.env.NODE_ENV
34
+
35
+ /**
36
+ * Creating a domQL element using passed parameters
37
+ */
38
+ const create = (element, parent, key, options = OPTIONS.create || {}) => {
39
+ if (options && !OPTIONS.create) {
40
+ OPTIONS.create = options
41
+ OPTIONS.create.context = element.context || options.context
42
+ }
43
+
44
+ // if ELEMENT is not given
45
+ if (element === undefined) {
46
+ if (ENV === 'test' || ENV === 'development') {
47
+ console.warn(key, 'element is undefined in', parent && parent.__ref && parent.__ref.path)
48
+ }
49
+ element = {}
50
+ }
51
+ if (isString(key) && key.slice(0, 2 === '__')) {
52
+ if (ENV === 'test' || ENV === 'development') {
53
+ console.warn(key, 'seems like to be in __ref')
54
+ }
55
+ }
56
+ if (element === null) return
57
+ if (element === true) element = { text: true }
58
+
59
+ // if element is extend
60
+ if (element.__hash) {
61
+ element = { extend: element }
62
+ }
63
+
64
+ // if PARENT is not given
65
+ if (!parent) parent = ROOT
66
+ if (isNode(parent)) {
67
+ parent = ROOT[`${key}_parent`] = { key: ':root', node: parent }
68
+ }
69
+
70
+ // if element is STRING
71
+ if (checkIfPrimitive(element)) {
72
+ element = applyValueAsText(element, parent, key)
73
+ }
74
+
75
+ // define KEY
76
+ const assignedKey = (element.key || key || createKey()).toString()
77
+
78
+ if (checkIfKeyIsComponent(assignedKey)) {
79
+ element = applyKeyComponentAsExtend(element, parent, assignedKey)
80
+ }
81
+
82
+ // TODO: move as define plugins
83
+ // Responsive rendering
84
+ if (checkIfMedia(assignedKey)) {
85
+ element = applyMediaProps(element, parent, assignedKey)
86
+ }
87
+
88
+ if (element.__ref) element.__ref.origin = element
89
+ else element.__ref = { origin: element } // eslint-disable-line
90
+ const __ref = element.__ref
91
+
92
+ // assign context
93
+ applyContext(element, parent, options)
94
+ const { context } = element
95
+
96
+ if (context && context.components) {
97
+ applyComponentFromContext(element, parent, options)
98
+ }
99
+
100
+ // create EXTEND inheritance
101
+ applyExtend(element, parent, options)
102
+
103
+ // create and assign a KEY
104
+ element.key = assignedKey
105
+
106
+ // Only resolve extends, skip everything else
107
+ if (options.onlyResolveExtends) {
108
+ return resolveExtends(element, parent, options)
109
+ }
110
+
111
+ if (Object.keys(options).length) {
112
+ registry.defaultOptions = options
113
+ if (options.ignoreChildExtend) delete options.ignoreChildExtend
114
+ }
115
+
116
+ addCaching(element, parent)
117
+
118
+ addMethods(element, parent)
119
+
120
+ // enable STATE
121
+ element.state = createState(element, parent)
122
+
123
+ // don't render IF in condition
124
+ checkIf(element, parent)
125
+
126
+ // if it already HAS a NODE
127
+ if (element.node && __ref.__if) { // TODO: check on if
128
+ return assignNode(element, parent, assignedKey)
129
+ }
130
+
131
+ // apply props settings
132
+ if (__ref.__if) createProps(element, parent)
133
+
134
+ // apply variants
135
+ applyVariant(element, parent)
136
+
137
+ // run `on.init`
138
+ const initReturns = triggerEventOn('init', element, options)
139
+ if (initReturns === false) return element
140
+
141
+ // run `on.beforeClassAssign`
142
+ triggerEventOn('beforeClassAssign', element, options)
143
+
144
+ // generate a CLASS name
145
+ assignClass(element)
146
+
147
+ // CREATE a real NODE
148
+ createNode(element, options)
149
+
150
+ if (!__ref.__if) return element
151
+
152
+ // assign NODE
153
+ assignNode(element, parent, key)
154
+
155
+ // run `on.renderRouter`
156
+ triggerEventOn('renderRouter', element, options)
157
+
158
+ // run `on.render`
159
+ triggerEventOn('render', element, options)
160
+
161
+ if (parent.__ref && parent.__ref.__children) parent.__ref.__children.push(element.key)
162
+
163
+ return element
164
+ }
165
+
166
+ const checkIfPrimitive = (element) => {
167
+ return is(element)('string', 'number')
168
+ }
169
+
170
+ const applyValueAsText = (element, parent, key) => {
171
+ const extendTag = element.extend && element.extend.tag
172
+ const childExtendTag = parent.childExtend && parent.childExtend.tag
173
+ const isKeyValidHTMLTag = ((TAGS.body.indexOf(key) > -1) && key)
174
+ return {
175
+ text: element,
176
+ tag: extendTag || childExtendTag || isKeyValidHTMLTag || 'string'
177
+ }
178
+ }
179
+
180
+ const addMethods = (element, parent) => {
181
+ const proto = {
182
+ set: set.bind(element),
183
+ update: update.bind(element),
184
+ remove: remove.bind(element),
185
+ updateContent: updateContentElement.bind(element),
186
+ removeContent: removeContentElement.bind(element),
187
+ setProps: setProps.bind(element),
188
+ lookup: lookup.bind(element),
189
+ spotByPath: spotByPath.bind(element),
190
+ parse: parse.bind(element),
191
+ parseDeep: parseDeep.bind(element),
192
+ keys: keys.bind(element),
193
+ nextElement: nextElement.bind(element),
194
+ previousElement: previousElement.bind(element)
195
+ }
196
+ if (ENV === 'test' || ENV === 'development') proto.log = log.bind(element)
197
+ Object.setPrototypeOf(element, proto)
198
+ }
199
+
200
+ const applyContext = (element, parent, options) => {
201
+ if (options.context && !ROOT.context && !element.context) ROOT.context = options.context
202
+ if (!element.context) element.context = parent.context || options.context || ROOT.context
203
+ }
204
+
205
+ const checkIf = (element, parent) => {
206
+ const { __ref: ref } = element
207
+
208
+ if (isFunction(element.if)) {
209
+ // TODO: move as fragment
210
+ const ifPassed = element.if(element, element.state)
211
+ if (!ifPassed) {
212
+ const ifFragment = cacheNode({ tag: 'fragment' })
213
+ ref.__ifFragment = appendNode(ifFragment, parent.node)
214
+ delete ref.__if
215
+ } else ref.__if = true
216
+ } else ref.__if = true
217
+ }
218
+
219
+ const addCaching = (element, parent) => {
220
+ const { __ref: ref } = element
221
+ let { __ref: parentRef } = parent
222
+
223
+ // enable TRANSFORM in data
224
+ if (!element.transform) element.transform = {}
225
+
226
+ // enable CACHING
227
+ if (!ref.__cached) ref.__cached = {}
228
+ if (!ref.__defineCache) ref.__defineCache = {}
229
+
230
+ // enable EXEC
231
+ if (!ref.__exec) ref.__exec = {}
232
+
233
+ // enable CLASS CACHING
234
+ if (!ref.__class) ref.__class = {}
235
+ if (!ref.__classNames) ref.__classNames = {}
236
+
237
+ // enable CLASS CACHING
238
+ if (!ref.__attr) ref.__attr = {}
239
+
240
+ // enable CHANGES storing
241
+ if (!ref.__changes) ref.__changes = []
242
+
243
+ // enable CHANGES storing
244
+ if (!ref.__children) ref.__children = []
245
+
246
+ // Add _root element property
247
+ const hasRoot = parent && parent.key === ':root'
248
+ if (!ref.__root) ref.__root = hasRoot ? element : parentRef.__root
249
+
250
+ // set the PATH array
251
+ if (ENV === 'test' || ENV === 'development') {
252
+ if (!parentRef) parentRef = parent.ref = {}
253
+ if (!parentRef.__path) parentRef.__path = []
254
+ ref.__path = parentRef.__path.concat(element.key)
255
+ }
256
+ }
257
+
258
+ const resolveExtends = (element, parent, options) => {
259
+ const { __ref } = element
260
+ element.tag = detectTag(element)
261
+
262
+ if (!__ref.__exec) __ref.__exec = {}
263
+ if (!__ref.__attr) __ref.__attr = {}
264
+
265
+ if (!element.props) element.props = {}
266
+ if (!element.state) element.state = {}
267
+
268
+ createState(element, parent, { skipApplyMethods: true })
269
+ createProps(element, parent)
270
+ applyVariant(element, parent)
271
+
272
+ throughInitialExec(element, options.propsExcludedFromExec)
273
+
274
+ for (const param in element) {
275
+ const prop = element[param]
276
+ if (
277
+ isUndefined(prop) ||
278
+ isMethod(param) ||
279
+ isObject(registry[param]) ||
280
+ isVariant(param)
281
+ ) continue
282
+
283
+ const hasDefined = element.define && element.define[param]
284
+ const ourParam = registry[param]
285
+ const hasOptionsDefine = options.define && options.define[param]
286
+ if (ourParam && !hasOptionsDefine) continue
287
+ else if (element[param] && !hasDefined && !hasOptionsDefine) {
288
+ create(exec(prop, element), element, param, options)
289
+ }
290
+ }
291
+
292
+ delete element.parent
293
+ delete element.update
294
+ delete element.__element
295
+
296
+ // added by createProps
297
+ delete element.props.update
298
+ delete element.props.__element
299
+
300
+ // added by createState
301
+ delete element.state.__element
302
+ delete element.state.__element
303
+ if (!options.keepRef) delete element.__ref
304
+
305
+ return element
306
+ }
307
+
308
+ const checkIfMedia = (key) => key.slice(0, 1) === '@'
309
+
310
+ const applyMediaProps = (element, parent, key) => {
311
+ const { props } = element
312
+ if (props) {
313
+ props.display = 'none'
314
+ if (props[key]) props[key].display = props.display
315
+ else props[key] = { display: props.display || 'block' }
316
+ return element
317
+ } else {
318
+ return {
319
+ ...element,
320
+ props: {
321
+ display: 'none',
322
+ [key]: { display: 'block' }
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ export default create
package/define.js ADDED
@@ -0,0 +1,13 @@
1
+ 'use strict'
2
+
3
+ import { report } from '@domql/report'
4
+ import { registry } from './mixins'
5
+
6
+ export default (params, options = {}) => {
7
+ const { overwrite } = options
8
+ for (const param in params) {
9
+ if (registry[param] && !overwrite) {
10
+ report('OverwriteToBuiltin', param)
11
+ } else registry[param] = params[param]
12
+ }
13
+ }
package/extend.js ADDED
@@ -0,0 +1,87 @@
1
+ 'use strict'
2
+
3
+ import { isFunction, exec, isString } from '@domql/utils'
4
+ import {
5
+ getExtendStack,
6
+ jointStacks,
7
+ cloneAndMergeArrayExtend,
8
+ deepMergeExtend,
9
+ replaceStringsWithComponents
10
+ } from './utils'
11
+
12
+ const ENV = process.env.NODE_ENV
13
+
14
+ /**
15
+ * Checks whether element has `extend` or is a part
16
+ * of parent's `childExtend` extend
17
+ */
18
+ export const applyExtend = (element, parent, options = {}) => {
19
+ if (isFunction(element)) element = exec(element, parent)
20
+
21
+ let { extend, props, context, __ref } = element
22
+
23
+ const COMPONENTS = (context && context.components) || options.components
24
+ if (isString(extend)) {
25
+ if (COMPONENTS && COMPONENTS[extend]) extend = COMPONENTS[extend]
26
+ else {
27
+ if (ENV !== 'test' || ENV !== 'development') {
28
+ console.warn('Extend is string but component was not found:', extend)
29
+ } extend = {}
30
+ }
31
+ }
32
+
33
+ const extendStack = getExtendStack(extend)
34
+
35
+ if (ENV !== 'test' || ENV !== 'development') delete element.extend
36
+
37
+ let childExtendStack = []
38
+ if (parent) {
39
+ element.parent = parent
40
+ // Assign parent attr to the element
41
+ if (!options.ignoreChildExtend) {
42
+ if (props && props.ignoreChildExtend) return
43
+
44
+ childExtendStack = getExtendStack(parent.childExtend)
45
+
46
+ // if (parent.childExtendRecursive && (props && !props.ignoreChildExtendRecursive)) {
47
+ if (parent.childExtendRecursive) {
48
+ const canExtendRecursive = !props?.ignoreChildExtendRecursive && element.key !== '__text'
49
+ if (canExtendRecursive) {
50
+ const childExtendRecursiveStack = getExtendStack(parent.childExtendRecursive)
51
+ // add error if childExtendRecursive contains element which goes to infinite loop
52
+ childExtendStack = childExtendStack.concat(childExtendRecursiveStack)
53
+ element.childExtendRecursive = parent.childExtendRecursive
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ const extendLength = extendStack.length
60
+ const childExtendLength = childExtendStack.length
61
+
62
+ let stack = []
63
+ if (extendLength && childExtendLength) {
64
+ stack = jointStacks(extendStack, childExtendStack)
65
+ } else if (extendLength) {
66
+ stack = extendStack
67
+ } else if (childExtendLength) {
68
+ stack = childExtendStack
69
+ } else if (!options.extend) return element
70
+
71
+ if (options.extend) {
72
+ const defaultOptionsExtend = getExtendStack(options.extend)
73
+ stack = [].concat(stack, defaultOptionsExtend)
74
+ }
75
+
76
+ if (__ref) __ref.__extend = stack
77
+ const findAndReplaceStrings = replaceStringsWithComponents(stack, COMPONENTS)
78
+ let mergedExtend = cloneAndMergeArrayExtend(findAndReplaceStrings)
79
+
80
+ const component = exec(element.component || mergedExtend.component, element)
81
+ if (component && COMPONENTS && COMPONENTS[component]) {
82
+ const componentExtend = cloneAndMergeArrayExtend(getExtendStack(COMPONENTS[component]))
83
+ mergedExtend = deepMergeExtend(componentExtend, mergedExtend)
84
+ }
85
+
86
+ return deepMergeExtend(element, mergedExtend)
87
+ }
package/index.js CHANGED
@@ -1,7 +1,27 @@
1
1
  'use strict'
2
2
 
3
- export * from '@domql/methods'
4
- export * from '@domql/iterate'
5
- export * from '@domql/update'
6
- export * from '@domql/create'
7
- export * from '@domql/set'
3
+ import { TREE } from '@domql/tree'
4
+ import create from './create'
5
+ import createNode from './node'
6
+ import define from './define'
7
+ import update from './update'
8
+ import parse from './parse'
9
+ import set from './set'
10
+
11
+ import { log, keys } from './methods'
12
+ import { get, remove, lookup } from '@domql/methods'
13
+
14
+ export {
15
+ TREE,
16
+ create,
17
+ createNode,
18
+ define,
19
+ remove,
20
+ update,
21
+ parse,
22
+ lookup,
23
+ set,
24
+ get,
25
+ log,
26
+ keys
27
+ }
package/iterate.js ADDED
@@ -0,0 +1,94 @@
1
+ 'use strict'
2
+
3
+ import { isObject, exec, isFunction, isNumber, isString } from '@domql/utils'
4
+ import { METHODS_EXL, checkIfKeyIsComponent, extendizeByKey, isVariant, overwrite } from './utils'
5
+ import { isMethod } from '@domql/methods'
6
+
7
+ export const throughInitialExec = (element, exclude = {}) => {
8
+ const { __ref: ref } = element
9
+ for (const param in element) {
10
+ if (exclude[param]) continue
11
+ const prop = element[param]
12
+ if (isFunction(prop) && !isMethod(param) && !isVariant(param)) {
13
+ ref.__exec[param] = prop
14
+ element[param] = prop(element, element.state)
15
+ // if (isComponent)
16
+ }
17
+ }
18
+ }
19
+
20
+ export const throughUpdatedExec = (element, options = { excludes: METHODS_EXL }) => {
21
+ const { __ref: ref } = element
22
+ const changes = {}
23
+
24
+ for (const param in ref.__exec) {
25
+ const prop = element[param]
26
+
27
+ const isDefinedParam = ref.__defineCache[param]
28
+ if (isDefinedParam) continue
29
+
30
+ const newExec = ref.__exec[param](element, element.state, element.context)
31
+ const execReturnsString = isString(newExec) || isNumber(newExec)
32
+ // if (prop && prop.node && execReturnsString) {
33
+ if (prop && prop.node && execReturnsString) {
34
+ overwrite(prop, { text: newExec }, options)
35
+ } else if (newExec !== prop) {
36
+ if (checkIfKeyIsComponent(param)) {
37
+ const { extend, ...newElem } = extendizeByKey(newExec, element, param)
38
+ overwrite(prop, newElem, options)
39
+ // } else {
40
+ // overwrite(prop, newExec, options)
41
+ } else {
42
+ ref.__cached[param] = changes[param] = prop
43
+ element[param] = newExec
44
+ }
45
+ }
46
+ }
47
+
48
+ return changes
49
+ }
50
+
51
+ export const throughInitialDefine = (element) => {
52
+ const { define, context, __ref: ref } = element
53
+
54
+ let defineObj = {}
55
+ const hasGlobalDefine = context && isObject(context.define)
56
+ if (isObject(define)) defineObj = { ...define }
57
+ if (hasGlobalDefine) defineObj = { ...defineObj, ...context.define }
58
+
59
+ for (const param in defineObj) {
60
+ let elementProp = element[param]
61
+
62
+ if (isFunction(elementProp) && !isMethod(param) && !isVariant(param)) {
63
+ ref.__exec[param] = elementProp
64
+ const execParam = elementProp = exec(elementProp, element)
65
+
66
+ if (execParam) {
67
+ elementProp = element[param] = execParam.parse ? execParam.parse() : execParam
68
+ ref.__defineCache[param] = elementProp
69
+ }
70
+ }
71
+
72
+ const execParam = defineObj[param](elementProp, element, element.state, element.context)
73
+ if (execParam) element[param] = execParam
74
+ }
75
+ return element
76
+ }
77
+
78
+ export const throughUpdatedDefine = (element) => {
79
+ const { context, define, __ref: ref } = element
80
+ const changes = {}
81
+
82
+ let obj = {}
83
+ if (isObject(define)) obj = { ...define }
84
+ if (isObject(context && context.define)) obj = { ...obj, ...context.define }
85
+
86
+ for (const param in obj) {
87
+ const execParam = ref.__exec[param]
88
+ if (execParam) ref.__defineCache[param] = execParam(element, element.state, element.context)
89
+ const cached = exec(ref.__defineCache[param], element)
90
+ const newExecParam = obj[param](cached, element, element.state, element.context)
91
+ if (newExecParam) element[param] = newExecParam
92
+ }
93
+ return changes
94
+ }
package/methods.js ADDED
@@ -0,0 +1,88 @@
1
+ 'use strict'
2
+
3
+ import { isDefined, isFunction, isObjectLike } from '@domql/utils'
4
+ import { parseFilters, registry } from './mixins'
5
+
6
+ export const set = function () {
7
+ }
8
+
9
+ export const update = function () {
10
+ }
11
+
12
+ export const defineSetter = (element, key, get, set) =>
13
+ Object.defineProperty(element, key, { get, set })
14
+
15
+ export const keys = function () {
16
+ const element = this
17
+ const keys = []
18
+ for (const param in element) {
19
+ if (registry[param] && !parseFilters.elementKeys.includes(param)) { continue }
20
+ keys.push(param)
21
+ }
22
+ return keys
23
+ }
24
+
25
+ export const parse = function (excl = []) {
26
+ const element = this
27
+ const obj = {}
28
+ const keyList = keys.call(element)
29
+ keyList.forEach(v => {
30
+ if (excl.includes(v)) return
31
+ let val = element[v]
32
+ if (v === 'state') {
33
+ if (element.__ref && element.__ref.__hasRootState) return
34
+ if (isFunction(val && val.parse)) val = val.parse()
35
+ } else if (v === 'props') {
36
+ const { __element, update, ...props } = element[v]
37
+ obj[v] = props
38
+ } else if (isDefined(val)) obj[v] = val
39
+ })
40
+ return obj
41
+ }
42
+
43
+ export const parseDeep = function (excl = []) {
44
+ const element = this
45
+ const obj = parse.call(element, excl)
46
+ for (const v in obj) {
47
+ if (excl.includes(v)) return
48
+ if (isObjectLike(obj[v])) { obj[v] = parseDeep.call(obj[v], excl) }
49
+ }
50
+ return obj
51
+ }
52
+
53
+ export const log = function (...args) {
54
+ const element = this
55
+ const { __ref } = element
56
+ console.group(element.key)
57
+ if (args.length) {
58
+ args.forEach(v => console.log(`%c${v}:\n`, 'font-weight: bold', element[v]))
59
+ } else {
60
+ console.log(__ref.path)
61
+ const keys = element.keys()
62
+ keys.forEach(v => console.log(`%c${v}:\n`, 'font-weight: bold', element[v]))
63
+ }
64
+ console.groupEnd(element.key)
65
+ return element
66
+ }
67
+
68
+ export const nextElement = function () {
69
+ const element = this
70
+ const { key, parent } = element
71
+ const { __children } = parent.__ref
72
+
73
+ const currentIndex = __children.indexOf(key)
74
+ const nextChild = __children[currentIndex + 1]
75
+
76
+ return parent[nextChild]
77
+ }
78
+
79
+ export const previousElement = function (el) {
80
+ const element = el || this
81
+ const { key, parent } = element
82
+ const { __children } = parent.__ref
83
+
84
+ if (!__children) return
85
+
86
+ const currentIndex = __children.indexOf(key)
87
+ return parent[__children[currentIndex - 1]]
88
+ }
package/node.js ADDED
@@ -0,0 +1,84 @@
1
+ 'use strict'
2
+
3
+ import { exec, isFunction, isObject, isUndefined } from '@domql/utils'
4
+ import { applyEventsOnNode, triggerEventOn } from '@domql/event'
5
+ import { isMethod } from '@domql/methods'
6
+ import { cacheNode } from '@domql/node'
7
+
8
+ import create from './create'
9
+
10
+ import {
11
+ throughInitialDefine,
12
+ throughInitialExec
13
+ } from './iterate'
14
+ import { registry } from './mixins'
15
+ import { applyParam } from './applyParam'
16
+ import { isVariant } from './utils'
17
+ // import { defineSetter } from './methods'
18
+
19
+ const ENV = process.env.NODE_ENV
20
+
21
+ export const createNode = (element, options) => {
22
+ // create and assign a node
23
+ let { node, tag, __ref: ref } = element
24
+
25
+ let isNewNode
26
+
27
+ if (!node) {
28
+ isNewNode = true
29
+
30
+ if (!ref.__if) return element
31
+
32
+ if (tag === 'shadow') {
33
+ node = element.node = element.parent.node.attachShadow({ mode: 'open' })
34
+ } else node = element.node = cacheNode(element)
35
+
36
+ // trigger `on.attachNode`
37
+ triggerEventOn('attachNode', element, options)
38
+ }
39
+
40
+ // node.dataset // .key = element.key
41
+
42
+ if (ENV === 'test' || ENV === 'development' || options.alowRefReference) {
43
+ node.ref = element
44
+ if (isFunction(node.setAttribute)) node.setAttribute('key', element.key)
45
+ }
46
+
47
+ if (!ref.__if) return element
48
+
49
+ // iterate through all given params
50
+ if (element.tag !== 'string' || element.tag !== 'fragment') {
51
+ // iterate through define
52
+ throughInitialDefine(element)
53
+
54
+ // iterate through exec
55
+ throughInitialExec(element)
56
+
57
+ // apply events
58
+ if (isNewNode && isObject(element.on)) applyEventsOnNode(element)
59
+
60
+ for (const param in element) {
61
+ const prop = element[param]
62
+
63
+ if (
64
+ isUndefined(prop) ||
65
+ isMethod(param) ||
66
+ isVariant(param) ||
67
+ isObject(registry[param])
68
+ ) continue
69
+
70
+ const isElement = applyParam(param, element, options)
71
+ if (isElement) {
72
+ const { hasDefine, hasContextDefine } = isElement
73
+ if (element[param] && !hasDefine && !hasContextDefine) {
74
+ create(exec(prop, element), element, param, options)
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ // node.dataset.key = key
81
+ return element
82
+ }
83
+
84
+ export default createNode
package/options.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ export default {}
package/package.json CHANGED
@@ -1,15 +1,30 @@
1
1
  {
2
2
  "name": "@domql/element",
3
- "version": "2.3.117",
4
- "main": "index.js",
3
+ "version": "2.3.154",
5
4
  "license": "MIT",
5
+ "type": "module",
6
+ "module": "index.js",
7
+ "main": "index.js",
8
+ "exports": "./dist/cjs/index.js",
9
+ "source": "index.js",
10
+ "files": [
11
+ "*.js",
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "copy:package:cjs": "cp ../../build/package-cjs.json dist/cjs/package.json",
16
+ "build:esm": "npx esbuild *.js --target=es2019 --format=esm --outdir=dist/esm",
17
+ "build:cjs": "npx esbuild *.js --target=node16 --format=cjs --outdir=dist/cjs",
18
+ "build": "yarn build:cjs",
19
+ "prepublish": "rimraf -I dist && yarn build && yarn copy:package:cjs"
20
+ },
6
21
  "dependencies": {
7
- "@domql/create": "latest",
8
- "@domql/iterate": "latest",
9
- "@domql/methods": "latest",
10
- "@domql/set": "latest",
11
- "@domql/update": "latest"
22
+ "@domql/globals": "latest",
23
+ "@domql/key": "latest",
24
+ "@domql/tags": "latest"
12
25
  },
13
- "gitHead": "a6da9bf1846e4a1e26017978cf52112b9d61d484",
14
- "source": "index.js"
26
+ "gitHead": "86251c1d94b9e87288cc9e84fd9badb6461b2973",
27
+ "devDependencies": {
28
+ "@babel/core": "^7.12.0"
29
+ }
15
30
  }
package/parse.js ADDED
@@ -0,0 +1,17 @@
1
+ 'use strict'
2
+
3
+ import { assignNode } from '@domql/render'
4
+ import create from './create'
5
+
6
+ const parse = (element) => {
7
+ const virtualTree = {
8
+ node: document.createElement('div')
9
+ }
10
+
11
+ if (element && element.node) assignNode(element, virtualTree)
12
+ else create(element, virtualTree)
13
+
14
+ return virtualTree.node.innerHTML
15
+ }
16
+
17
+ export default parse
package/remove.js ADDED
@@ -0,0 +1,30 @@
1
+ 'use strict'
2
+
3
+ import { isFunction } from '@domql/utils'
4
+
5
+ export const updateContentElement = function (params, options) {
6
+ const element = this
7
+
8
+ if (!element.content) return
9
+ if (element.content.update) element.content.update(params, options)
10
+ }
11
+
12
+ export const removeContentElement = function (el) {
13
+ const element = el || this
14
+ const { __ref } = element
15
+
16
+ if (element.content) {
17
+ if (element.content.node) {
18
+ if (element.content.tag === 'fragment') element.node.innerHTML = ''
19
+ else element.node.removeChild(element.content.node)
20
+ }
21
+
22
+ const { __cached } = __ref
23
+ if (__cached && __cached.content) {
24
+ if (__cached.content.tag === 'fragment') __cached.content.parent.node.innerHTML = ''
25
+ else if (__cached.content && isFunction(__cached.content.remove)) __cached.content.remove()
26
+ }
27
+
28
+ delete element.content
29
+ }
30
+ }
package/set.js ADDED
@@ -0,0 +1,33 @@
1
+ 'use strict'
2
+
3
+ import { isEqualDeep } from '@domql/utils'
4
+ import { removeContentElement } from './remove'
5
+
6
+ import create from './create'
7
+ import { registry } from './mixins'
8
+ import OPTIONS from './options'
9
+
10
+ const set = function (params, options = {}, el) {
11
+ const element = el || this
12
+ const __contentRef = element.content && element.content.__ref
13
+
14
+ const isEqual = isEqualDeep(params, element.content)
15
+ // console.error(params)
16
+ if (isEqual && __contentRef && __contentRef.__cached) return element
17
+ removeContentElement(element)
18
+
19
+ if (params) {
20
+ const { childExtend } = params
21
+ if (!childExtend && element.childExtend) params.childExtend = element.childExtend
22
+ create(params, element, 'content', {
23
+ ignoreChildExtend: true,
24
+ ...registry.defaultOptions,
25
+ ...OPTIONS.create,
26
+ ...options
27
+ })
28
+ }
29
+
30
+ return element
31
+ }
32
+
33
+ export default set
package/update.js ADDED
@@ -0,0 +1,227 @@
1
+ 'use strict'
2
+
3
+ import { window } from '@domql/globals'
4
+ import { exec, isArray, isFunction, isNumber, isObject, isString, isUndefined, merge, overwriteDeep } from '@domql/utils'
5
+ import { applyEvent, triggerEventOn, triggerEventOnUpdate } from '@domql/event'
6
+ import { isMethod } from '@domql/methods'
7
+ import { createSnapshotId } from '@domql/key'
8
+ import { updateProps } from '@domql/props'
9
+ import { createState } from '@domql/state'
10
+
11
+ import { METHODS_EXL, isVariant } from './utils'
12
+ import create from './create'
13
+ import { throughUpdatedDefine, throughUpdatedExec } from './iterate'
14
+ import { registry } from './mixins'
15
+ import { applyParam } from './applyParam'
16
+ import OPTIONS from './options'
17
+
18
+ const snapshot = {
19
+ snapshotId: createSnapshotId
20
+ }
21
+
22
+ const UPDATE_DEFAULT_OPTIONS = {
23
+ stackChanges: false,
24
+ cleanExec: true,
25
+ preventRecursive: false,
26
+ currentSnapshot: false,
27
+ calleeElement: false,
28
+ excludes: METHODS_EXL
29
+ }
30
+
31
+ const update = function (params = {}, options = UPDATE_DEFAULT_OPTIONS) {
32
+ const element = this
33
+ const { parent, node, key } = element
34
+ const { excludes, preventInheritAtCurrentState } = options
35
+
36
+ if (preventInheritAtCurrentState && preventInheritAtCurrentState.__element === element) return
37
+ if (!excludes) merge(options, UPDATE_DEFAULT_OPTIONS)
38
+
39
+ let ref = element.__ref
40
+ if (!ref) ref = element.__ref = {}
41
+
42
+ const [snapshotOnCallee, calleeElement, snapshotHasUpdated] = captureSnapshot(element, options)
43
+ if (snapshotHasUpdated) return
44
+
45
+ if (isString(params) || isNumber(params)) {
46
+ params = { text: params }
47
+ }
48
+
49
+ const ifFails = checkIfOnUpdate(element, parent, options)
50
+ if (ifFails) return
51
+
52
+ const inheritState = inheritStateUpdates(element, options)
53
+ if (inheritState === false) return
54
+
55
+ if (ref.__if && !options.preventPropsUpdate) {
56
+ const hasParentProps = parent.props && (parent.props[key] || parent.props.childProps)
57
+ const hasFunctionInProps = ref.__props.filter(v => isFunction(v))
58
+ const props = params.props || hasParentProps || hasFunctionInProps.length
59
+ if (props) updateProps(props, element, parent)
60
+ }
61
+
62
+ if (!options.isForced) {
63
+ triggerEventOn('beforeClassAssign', element, options)
64
+ }
65
+
66
+ if (!options.preventInitUpdateListener) {
67
+ const initUpdateReturns = triggerEventOnUpdate('initUpdate', params, element, options)
68
+ if (initUpdateReturns === false) return element
69
+ }
70
+
71
+ const overwriteChanges = overwriteDeep(element, params, METHODS_EXL)
72
+ const execChanges = throughUpdatedExec(element, { ignore: UPDATE_DEFAULT_OPTIONS })
73
+ const definedChanges = throughUpdatedDefine(element)
74
+
75
+ if (options.stackChanges && element.__stackChanges) {
76
+ const stackChanges = merge(definedChanges, merge(execChanges, overwriteChanges))
77
+ element.__stackChanges.push(stackChanges)
78
+ }
79
+
80
+ if (!ref.__if) return false
81
+ if (!node) {
82
+ // return createNode(element, options)
83
+ return
84
+ }
85
+
86
+ for (const param in element) {
87
+ const prop = element[param]
88
+ const hasOnlyUpdateFalsy = options.onlyUpdate && (options.onlyUpdate !== param || !element.lookup(options.onlyUpdate))
89
+ const isInPreventUpdate = isArray(options.preventUpdate) && options.preventUpdate.includes(param)
90
+ const isInPreventDefineUpdate = isArray(options.preventDefineUpdate) && options.preventDefineUpdate.includes(param)
91
+
92
+ if (
93
+ isUndefined(prop) ||
94
+ hasOnlyUpdateFalsy ||
95
+ isInPreventUpdate ||
96
+ isInPreventDefineUpdate ||
97
+ options.preventDefineUpdate === true ||
98
+ options.preventDefineUpdate === param ||
99
+ (options.preventContentUpdate && param === 'content') ||
100
+ (options.preventStateUpdate && param) === 'state' ||
101
+ isMethod(param) || isObject(registry[param]) || isVariant(param)
102
+ ) continue
103
+ if (options.preventStateUpdate === 'once') options.preventStateUpdate = false
104
+
105
+ const isElement = applyParam(param, element, options)
106
+ if (isElement) {
107
+ const { hasDefine, hasContextDefine } = isElement
108
+ const canUpdate = isObject(prop) && !hasDefine && !hasContextDefine && !options.preventRecursive
109
+ if (!canUpdate) continue
110
+
111
+ const childUpdateCall = () => update.call(prop, params[prop], {
112
+ ...options,
113
+ currentSnapshot: snapshotOnCallee,
114
+ calleeElement: calleeElement
115
+ })
116
+
117
+ if ((element.props && element.props.lazyLoad) || options.lazyLoad) {
118
+ window.requestAnimationFrame(() => childUpdateCall())
119
+ } else childUpdateCall()
120
+ }
121
+ }
122
+
123
+ if (!options.preventUpdateListener) triggerEventOn('update', element, options)
124
+ }
125
+
126
+ const captureSnapshot = (element, options) => {
127
+ const ref = element.__ref
128
+
129
+ const { currentSnapshot, calleeElement } = options
130
+ const isCallee = calleeElement === element
131
+ if (!calleeElement || isCallee) {
132
+ const createdStanpshot = snapshot.snapshotId()
133
+ ref.__currentSnapshot = createdStanpshot
134
+ return [createdStanpshot, element]
135
+ }
136
+
137
+ const snapshotOnCallee = ref.__currentSnapshot
138
+ if (currentSnapshot < snapshotOnCallee) {
139
+ return [snapshotOnCallee, calleeElement, true]
140
+ }
141
+
142
+ return [snapshotOnCallee, calleeElement]
143
+ }
144
+
145
+ const checkIfOnUpdate = (element, parent, options) => {
146
+ if (!isFunction(element.if) || !element.state || !parent) return
147
+
148
+ const ref = element.__ref
149
+ const ifPassed = element.if(element, element.state, element.context, options)
150
+ const itWasFalse = ref.__if !== true
151
+
152
+ if (ifPassed) {
153
+ ref.__if = true
154
+ if (itWasFalse) {
155
+ delete element.__hash
156
+ delete element.extend
157
+ if (!ref.__hasRootState) {
158
+ delete element.state
159
+ }
160
+ if (ref.__state) {
161
+ element.state = ref.__state
162
+ }
163
+ const created = create(element, parent, element.key, OPTIONS.create)
164
+ if (options.preventUpdate !== true && element.on && isFunction(element.on.update)) {
165
+ applyEvent(element.on.update, created, created.state)
166
+ }
167
+ return created
168
+ }
169
+ } else if (element.node && !ifPassed) {
170
+ element.node.remove()
171
+ delete ref.__if
172
+ }
173
+ }
174
+
175
+ const inheritStateUpdates = (element, options) => {
176
+ const { __ref: ref } = element
177
+ const stateKey = ref.__state
178
+ const { parent, state } = element
179
+
180
+ if (options.preventpdateTriggerStateUpdate) return
181
+
182
+ if (!stateKey && !ref.__hasRootState) {
183
+ element.state = (parent && parent.state) || {}
184
+ return
185
+ }
186
+
187
+ const { isHoisted, execStateFunction, stateFunctionOverwrite } = options
188
+ const shouldForceStateUpdate = isFunction(stateKey) && (!isHoisted && execStateFunction && stateFunctionOverwrite)
189
+ if (shouldForceStateUpdate) {
190
+ const execState = exec(stateKey, element)
191
+ state.set(execState, {
192
+ ...options,
193
+ preventUpdate: true
194
+ })
195
+ return
196
+ }
197
+
198
+ const parentState = (parent && parent.state) || {}
199
+ const keyInParentState = parentState[stateKey]
200
+
201
+ if (!keyInParentState || options.preventInheritedStateUpdate) return
202
+
203
+ if (!options.preventInitStateUpdateListener) {
204
+ const initStateReturns = triggerEventOnUpdate('initStateUpdated', keyInParentState, element, options)
205
+ if (initStateReturns === false) return element
206
+ }
207
+
208
+ const newState = createStateUpdate(element, parent, options)
209
+
210
+ if (!options.preventStateUpdateListener) {
211
+ triggerEventOnUpdate('stateUpdated', newState.parse(), element, options)
212
+ }
213
+ }
214
+
215
+ const createStateUpdate = (element, parent, options) => {
216
+ const __stateChildren = element.state.__children
217
+ const newState = createState(element, parent)
218
+ element.state = newState
219
+ for (const child in __stateChildren) {
220
+ // check this for inherited states
221
+ if (newState[child]) newState.__children[child] = __stateChildren[child]
222
+ __stateChildren[child].parent = newState
223
+ }
224
+ return newState
225
+ }
226
+
227
+ export default update
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2016 symbo.ls
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.