@domql/element 3.4.5 → 3.4.6

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.
Files changed (47) hide show
  1. package/event/__tests__/applyAnimationFrame.test.js +114 -0
  2. package/event/__tests__/applyEvent.test.js +159 -0
  3. package/event/__tests__/applyEventUpdate.test.js +198 -0
  4. package/event/__tests__/applyEventsOnNode.test.js +216 -0
  5. package/event/__tests__/canRenderTag.test.js +50 -0
  6. package/event/__tests__/index.test.js +39 -0
  7. package/event/__tests__/initAnimationFrame.test.js +156 -0
  8. package/event/__tests__/registerFrameListener.test.js +97 -0
  9. package/event/__tests__/store.test.js +93 -0
  10. package/event/__tests__/triggerEventOn.test.js +195 -0
  11. package/event/__tests__/triggerEventOnUpdate.test.js +207 -0
  12. package/event/animationFrame.js +92 -0
  13. package/event/can.js +8 -0
  14. package/event/index.js +5 -0
  15. package/event/on.js +71 -0
  16. package/event/store.js +6 -0
  17. package/methods/set.js +73 -0
  18. package/methods/v2.js +83 -0
  19. package/mixins/attr.js +32 -0
  20. package/mixins/classList.js +62 -0
  21. package/mixins/content.js +65 -0
  22. package/mixins/data.js +26 -0
  23. package/mixins/html.js +19 -0
  24. package/mixins/index.js +23 -0
  25. package/mixins/registry.js +46 -0
  26. package/mixins/scope.js +23 -0
  27. package/mixins/state.js +18 -0
  28. package/mixins/style.js +25 -0
  29. package/mixins/text.js +31 -0
  30. package/package.json +13 -8
  31. package/render/__tests__/appendNode.test.js +53 -0
  32. package/render/__tests__/assignNode.test.js +151 -0
  33. package/render/__tests__/cacheNode.test.js +168 -0
  34. package/render/__tests__/createHTMLNode.test.js +118 -0
  35. package/render/__tests__/createNode.test.js +9 -0
  36. package/render/__tests__/detectTag.test.js +99 -0
  37. package/render/__tests__/index.test.js +56 -0
  38. package/render/__tests__/insertNodeAfter.test.js +111 -0
  39. package/render/__tests__/insertNodeBefore.test.js +65 -0
  40. package/render/append.js +61 -0
  41. package/render/cache.js +68 -0
  42. package/render/create.js +3 -0
  43. package/render/index.js +5 -0
  44. package/utils/applyParam.js +33 -0
  45. package/utils/extendUtils.js +135 -0
  46. package/utils/index.js +4 -0
  47. package/utils/propEvents.js +36 -0
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ export const createNode = (element) => {}
@@ -0,0 +1,5 @@
1
+ 'use strict'
2
+
3
+ export * from './create.js'
4
+ export * from './cache.js'
5
+ export * from './append.js'
@@ -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,4 @@
1
+ 'use strict'
2
+
3
+ export * from './extendUtils.js'
4
+ export const METHODS_EXL = [] // this is needed because of unit tests
@@ -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
+ }