@domql/element 3.4.5 → 3.4.9
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/event/__tests__/applyAnimationFrame.test.js +114 -0
- package/event/__tests__/applyEvent.test.js +159 -0
- package/event/__tests__/applyEventUpdate.test.js +198 -0
- package/event/__tests__/applyEventsOnNode.test.js +216 -0
- package/event/__tests__/canRenderTag.test.js +50 -0
- package/event/__tests__/index.test.js +39 -0
- package/event/__tests__/initAnimationFrame.test.js +156 -0
- package/event/__tests__/registerFrameListener.test.js +97 -0
- package/event/__tests__/store.test.js +93 -0
- package/event/__tests__/triggerEventOn.test.js +195 -0
- package/event/__tests__/triggerEventOnUpdate.test.js +207 -0
- package/event/animationFrame.js +92 -0
- package/event/can.js +8 -0
- package/event/index.js +5 -0
- package/event/on.js +71 -0
- package/event/store.js +6 -0
- package/methods/set.js +73 -0
- package/methods/v2.js +83 -0
- package/mixins/attr.js +32 -0
- package/mixins/classList.js +62 -0
- package/mixins/content.js +65 -0
- package/mixins/data.js +26 -0
- package/mixins/html.js +19 -0
- package/mixins/index.js +23 -0
- package/mixins/registry.js +46 -0
- package/mixins/scope.js +23 -0
- package/mixins/state.js +18 -0
- package/mixins/style.js +25 -0
- package/mixins/text.js +31 -0
- package/package.json +13 -8
- package/render/__tests__/appendNode.test.js +53 -0
- package/render/__tests__/assignNode.test.js +151 -0
- package/render/__tests__/cacheNode.test.js +168 -0
- package/render/__tests__/createHTMLNode.test.js +118 -0
- package/render/__tests__/createNode.test.js +9 -0
- package/render/__tests__/detectTag.test.js +99 -0
- package/render/__tests__/index.test.js +56 -0
- package/render/__tests__/insertNodeAfter.test.js +111 -0
- package/render/__tests__/insertNodeBefore.test.js +65 -0
- package/render/append.js +61 -0
- package/render/cache.js +68 -0
- package/render/create.js +3 -0
- package/render/index.js +5 -0
- package/utils/applyParam.js +33 -0
- package/utils/extendUtils.js +135 -0
- package/utils/index.js +4 -0
- package/utils/propEvents.js +36 -0
package/render/cache.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { report } from '@domql/report'
|
|
4
|
+
import { canRenderTag } from '../event/index.js'
|
|
5
|
+
import { exec, isObject, isString, isValidHtmlTag, SVG_TAGS, document } from '@domql/utils'
|
|
6
|
+
|
|
7
|
+
const SVG_NS = 'http://www.w3.org/2000/svg'
|
|
8
|
+
|
|
9
|
+
export const createHTMLNode = (element) => {
|
|
10
|
+
const { tag, context } = element
|
|
11
|
+
const doc = context.document || document
|
|
12
|
+
if (tag) {
|
|
13
|
+
if (tag === 'string') return doc.createTextNode(element.text)
|
|
14
|
+
else if (tag === 'fragment') {
|
|
15
|
+
return doc.createDocumentFragment()
|
|
16
|
+
} else if (SVG_TAGS.has(tag)) {
|
|
17
|
+
if (tag === 'svg' || element.parent?.node?.namespaceURI === SVG_NS) {
|
|
18
|
+
return doc.createElementNS(SVG_NS, tag)
|
|
19
|
+
}
|
|
20
|
+
return doc.createElement(tag)
|
|
21
|
+
} else return doc.createElement(tag)
|
|
22
|
+
} else {
|
|
23
|
+
return doc.createElement('div')
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const detectTag = element => {
|
|
28
|
+
let { tag, key, props } = element
|
|
29
|
+
tag = exec(tag, element)
|
|
30
|
+
|
|
31
|
+
if (tag === true) tag = key
|
|
32
|
+
|
|
33
|
+
if (isObject(props) && isString(props.tag)) {
|
|
34
|
+
const tagExists = isValidHtmlTag(props.tag)
|
|
35
|
+
if (tagExists) return props.tag
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isString(tag)) {
|
|
39
|
+
if (isValidHtmlTag(tag)) return tag
|
|
40
|
+
} else {
|
|
41
|
+
let keyAsTag = key.toLowerCase()
|
|
42
|
+
if (keyAsTag.includes('.')) keyAsTag = keyAsTag.split('.')[0]
|
|
43
|
+
if (keyAsTag.includes('_')) keyAsTag = keyAsTag.split('_')[0]
|
|
44
|
+
if (isValidHtmlTag(keyAsTag)) return keyAsTag
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return 'div'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const cacheNode = (element) => {
|
|
51
|
+
const { context } = element
|
|
52
|
+
const win = context.window || window
|
|
53
|
+
const tag = element.tag = detectTag(element)
|
|
54
|
+
|
|
55
|
+
if (!canRenderTag(tag)) {
|
|
56
|
+
return report('HTMLInvalidTag', element.tag, element)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!win.nodeCaches) win.nodeCaches = {}
|
|
60
|
+
const isSvgContext = SVG_TAGS.has(tag) && (tag === 'svg' || element.parent?.node?.namespaceURI === SVG_NS)
|
|
61
|
+
const cacheKey = isSvgContext ? 'svg:' + tag : tag
|
|
62
|
+
let cachedTag = win.nodeCaches[cacheKey]
|
|
63
|
+
if (!cachedTag) cachedTag = win.nodeCaches[cacheKey] = createHTMLNode(element)
|
|
64
|
+
|
|
65
|
+
const clonedNode = cachedTag.cloneNode(true)
|
|
66
|
+
if (tag === 'string') clonedNode.nodeValue = element.text
|
|
67
|
+
return clonedNode
|
|
68
|
+
}
|
package/render/create.js
ADDED
package/render/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec, isFunction } from '@domql/utils'
|
|
4
|
+
import { REGISTRY } from '../mixins/index.js'
|
|
5
|
+
|
|
6
|
+
export const applyParam = (param, element, options) => {
|
|
7
|
+
const { node, context, __ref: ref } = element
|
|
8
|
+
const prop = exec(element[param], element)
|
|
9
|
+
|
|
10
|
+
const { onlyUpdate } = options
|
|
11
|
+
|
|
12
|
+
const DOMQLProperty = REGISTRY[param]
|
|
13
|
+
const DOMQLPropertyFromContext = context?.registry?.[param]
|
|
14
|
+
const isGlobalTransformer = DOMQLPropertyFromContext || DOMQLProperty
|
|
15
|
+
|
|
16
|
+
const hasDefine = element.define?.[param]
|
|
17
|
+
const hasContextDefine = context?.define?.[param]
|
|
18
|
+
|
|
19
|
+
if (!ref.__if) return
|
|
20
|
+
|
|
21
|
+
const hasOnlyUpdate = onlyUpdate
|
|
22
|
+
? onlyUpdate === param || element.lookup(onlyUpdate)
|
|
23
|
+
: true
|
|
24
|
+
|
|
25
|
+
if (isGlobalTransformer && !hasContextDefine && hasOnlyUpdate) {
|
|
26
|
+
if (isFunction(isGlobalTransformer)) {
|
|
27
|
+
isGlobalTransformer(prop, element, node, options)
|
|
28
|
+
}
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return { hasDefine, hasContextDefine }
|
|
33
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
isArray,
|
|
5
|
+
isFunction,
|
|
6
|
+
isObject,
|
|
7
|
+
isString,
|
|
8
|
+
deepClone,
|
|
9
|
+
isNotProduction
|
|
10
|
+
} from '@domql/utils'
|
|
11
|
+
|
|
12
|
+
export const generateHash = () => Math.random().toString(36).substring(2)
|
|
13
|
+
|
|
14
|
+
// hashing
|
|
15
|
+
export const extendStackRegistry = {}
|
|
16
|
+
export const extendCachedRegistry = {}
|
|
17
|
+
|
|
18
|
+
export const getHashedExtend = extend => {
|
|
19
|
+
return extendStackRegistry[extend.__hash]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const setHashedExtend = (extend, stack) => {
|
|
23
|
+
const hash = generateHash()
|
|
24
|
+
if (!isString(extend)) {
|
|
25
|
+
extend.__hash = hash
|
|
26
|
+
}
|
|
27
|
+
extendStackRegistry[hash] = stack
|
|
28
|
+
return stack
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getExtendStackRegistry = (extend, stack) => {
|
|
32
|
+
if (extend.__hash) {
|
|
33
|
+
return stack.concat(getHashedExtend(extend))
|
|
34
|
+
}
|
|
35
|
+
return setHashedExtend(extend, stack) // stack .concat(hashedExtend)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// stacking
|
|
39
|
+
export const extractArrayExtend = (extend, stack, context) => {
|
|
40
|
+
for (let i = 0; i < extend.length; i++) flattenExtend(extend[i], stack, context)
|
|
41
|
+
return stack
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const deepExtend = (extend, stack, context) => {
|
|
45
|
+
const extendOflattenExtend = extend.extend
|
|
46
|
+
if (extendOflattenExtend) {
|
|
47
|
+
flattenExtend(extendOflattenExtend, stack, context)
|
|
48
|
+
}
|
|
49
|
+
return stack
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const flattenExtend = (extend, stack, context) => {
|
|
53
|
+
if (!extend) return stack
|
|
54
|
+
if (isArray(extend)) return extractArrayExtend(extend, stack, context)
|
|
55
|
+
if (isString(extend)) extend = fallbackStringExtend(extend, context)
|
|
56
|
+
stack.push(extend)
|
|
57
|
+
if (extend.extend) deepExtend(extend, stack, context)
|
|
58
|
+
return stack
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const deepMergeExtend = (element, extend) => {
|
|
62
|
+
for (const e in extend) {
|
|
63
|
+
if (e === 'parent' || e === 'node' || e === '__element') continue
|
|
64
|
+
const elementProp = element[e]
|
|
65
|
+
const extendProp = extend[e]
|
|
66
|
+
if (elementProp === undefined) {
|
|
67
|
+
element[e] = extendProp
|
|
68
|
+
} else if (isObject(elementProp) && isObject(extendProp)) {
|
|
69
|
+
deepMergeExtend(elementProp, extendProp)
|
|
70
|
+
} else if (isArray(elementProp) && isArray(extendProp)) {
|
|
71
|
+
element[e] = elementProp.concat(extendProp)
|
|
72
|
+
} else if (isArray(elementProp) && isObject(extendProp)) {
|
|
73
|
+
const obj = deepMergeExtend({}, elementProp)
|
|
74
|
+
element[e] = deepMergeExtend(obj, extendProp)
|
|
75
|
+
} else if (elementProp === undefined && isFunction(extendProp)) {
|
|
76
|
+
element[e] = extendProp
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return element
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const cloneAndMergeArrayExtend = stack => {
|
|
83
|
+
return stack.reduce((a, c) => {
|
|
84
|
+
return deepMergeExtend(a, deepClone(c))
|
|
85
|
+
}, {})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const fallbackStringExtend = (
|
|
89
|
+
extend,
|
|
90
|
+
context,
|
|
91
|
+
options = {},
|
|
92
|
+
variant
|
|
93
|
+
) => {
|
|
94
|
+
const COMPONENTS = context?.components || options.components
|
|
95
|
+
const PAGES = context?.pages || options.pages
|
|
96
|
+
if (isString(extend)) {
|
|
97
|
+
const componentExists =
|
|
98
|
+
COMPONENTS &&
|
|
99
|
+
(COMPONENTS[extend + '.' + variant] ||
|
|
100
|
+
COMPONENTS[extend] ||
|
|
101
|
+
COMPONENTS['smbls.' + extend])
|
|
102
|
+
const pageExists = PAGES && extend.charCodeAt(0) === 47 && PAGES[extend]
|
|
103
|
+
if (componentExists) return componentExists
|
|
104
|
+
else if (pageExists) return pageExists
|
|
105
|
+
else {
|
|
106
|
+
if (options.verbose && isNotProduction()) {
|
|
107
|
+
console.warn('Extend is string but component was not found:', extend)
|
|
108
|
+
}
|
|
109
|
+
return {}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return extend
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// joint stacks
|
|
116
|
+
export const jointStacks = (extendStack, childExtendStack) => {
|
|
117
|
+
return []
|
|
118
|
+
.concat(extendStack.slice(0, 1))
|
|
119
|
+
.concat(childExtendStack.slice(0, 1))
|
|
120
|
+
.concat(extendStack.slice(1))
|
|
121
|
+
.concat(childExtendStack.slice(1))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// init
|
|
125
|
+
export const getExtendStack = (extend, context) => {
|
|
126
|
+
if (!extend) return []
|
|
127
|
+
if (extend.__hash) return getHashedExtend(extend) || []
|
|
128
|
+
const stack = flattenExtend(extend, [], context)
|
|
129
|
+
return getExtendStackRegistry(extend, stack)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const getExtendMerged = extend => {
|
|
133
|
+
const stack = getExtendStack(extend)
|
|
134
|
+
return cloneAndMergeArrayExtend(stack)
|
|
135
|
+
}
|
package/utils/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isFunction, lowercaseFirstLetter } from '@domql/utils'
|
|
4
|
+
|
|
5
|
+
export const propagateEventsFromProps = (element) => {
|
|
6
|
+
const { props, on } = element
|
|
7
|
+
for (const v in props) {
|
|
8
|
+
if (v.charCodeAt(0) !== 111 || v.charCodeAt(1) !== 110) continue // 'on'
|
|
9
|
+
const eventName = lowercaseFirstLetter(v.slice(2))
|
|
10
|
+
const origEvent = on[eventName]
|
|
11
|
+
const funcFromProps = props[v]
|
|
12
|
+
if (isFunction(origEvent)) {
|
|
13
|
+
on[eventName] = (...args) => {
|
|
14
|
+
const originalEventRetunrs = origEvent(...args)
|
|
15
|
+
if (originalEventRetunrs !== false) return funcFromProps(...args)
|
|
16
|
+
}
|
|
17
|
+
} else on[eventName] = funcFromProps
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const propagateEventsFromElement = (element) => {
|
|
22
|
+
const { on } = element
|
|
23
|
+
for (const param in element) {
|
|
24
|
+
if (param.charCodeAt(0) !== 111 || param.charCodeAt(1) !== 110 || !Object.prototype.hasOwnProperty.call(element, param)) continue
|
|
25
|
+
const fn = element[param]
|
|
26
|
+
if (!isFunction(fn)) continue
|
|
27
|
+
const eventName = lowercaseFirstLetter(param.slice(2))
|
|
28
|
+
const origEvent = on[eventName]
|
|
29
|
+
if (isFunction(origEvent)) {
|
|
30
|
+
on[eventName] = (...args) => {
|
|
31
|
+
const ret = origEvent(...args)
|
|
32
|
+
if (ret !== false) return fn(...args)
|
|
33
|
+
}
|
|
34
|
+
} else on[eventName] = fn
|
|
35
|
+
}
|
|
36
|
+
}
|