@domql/element 3.2.3 → 3.2.8

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 (105) hide show
  1. package/children.js +40 -12
  2. package/create.js +40 -26
  3. package/define.js +1 -1
  4. package/dist/cjs/children.js +39 -11
  5. package/dist/cjs/create.js +41 -11
  6. package/dist/cjs/define.js +1 -1
  7. package/dist/cjs/event/animationFrame.js +96 -0
  8. package/dist/cjs/event/can.js +28 -0
  9. package/dist/cjs/event/index.js +20 -0
  10. package/dist/cjs/event/on.js +84 -0
  11. package/dist/cjs/event/store.js +27 -0
  12. package/dist/cjs/extend.js +6 -6
  13. package/dist/cjs/index.js +9 -6
  14. package/dist/cjs/iterate.js +13 -13
  15. package/dist/cjs/methods/set.js +5 -0
  16. package/dist/cjs/methods/v2.js +1 -1
  17. package/dist/cjs/mixins/attr.js +3 -2
  18. package/dist/cjs/mixins/classList.js +11 -1
  19. package/dist/cjs/mixins/content.js +1 -2
  20. package/dist/cjs/mixins/html.js +1 -2
  21. package/dist/cjs/mixins/state.js +2 -2
  22. package/dist/cjs/mixins/style.js +11 -2
  23. package/dist/cjs/mixins/text.js +5 -1
  24. package/dist/cjs/node.js +8 -5
  25. package/dist/cjs/render/append.js +72 -0
  26. package/dist/cjs/render/cache.js +80 -0
  27. package/dist/cjs/render/create.js +25 -0
  28. package/dist/cjs/render/index.js +20 -0
  29. package/dist/cjs/set.js +12 -14
  30. package/dist/cjs/update.js +80 -40
  31. package/dist/cjs/utils/applyParam.js +3 -3
  32. package/dist/cjs/utils/extendUtils.js +5 -5
  33. package/dist/cjs/utils/index.js +2 -0
  34. package/dist/cjs/utils/propEvents.js +21 -4
  35. package/dist/esm/children.js +39 -11
  36. package/dist/esm/create.js +42 -11
  37. package/dist/esm/define.js +1 -1
  38. package/dist/esm/event/animationFrame.js +76 -0
  39. package/dist/esm/event/can.js +8 -0
  40. package/dist/esm/event/index.js +3 -0
  41. package/dist/esm/event/on.js +64 -0
  42. package/dist/esm/event/store.js +7 -0
  43. package/dist/esm/extend.js +7 -7
  44. package/dist/esm/index.js +8 -6
  45. package/dist/esm/iterate.js +13 -13
  46. package/dist/esm/methods/set.js +10 -0
  47. package/dist/esm/methods/v2.js +1 -1
  48. package/dist/esm/mixins/attr.js +4 -3
  49. package/dist/esm/mixins/classList.js +11 -1
  50. package/dist/esm/mixins/content.js +1 -2
  51. package/dist/esm/mixins/html.js +1 -2
  52. package/dist/esm/mixins/state.js +2 -2
  53. package/dist/esm/mixins/style.js +12 -3
  54. package/dist/esm/mixins/text.js +6 -2
  55. package/dist/esm/node.js +8 -5
  56. package/dist/esm/render/append.js +52 -0
  57. package/dist/esm/render/cache.js +60 -0
  58. package/dist/esm/render/create.js +5 -0
  59. package/dist/esm/render/index.js +3 -0
  60. package/dist/esm/set.js +12 -14
  61. package/dist/esm/update.js +80 -42
  62. package/dist/esm/utils/applyParam.js +3 -3
  63. package/dist/esm/utils/extendUtils.js +5 -5
  64. package/dist/esm/utils/index.js +1 -0
  65. package/dist/esm/utils/propEvents.js +21 -4
  66. package/dist/iife/index.js +4718 -0
  67. package/extend.js +7 -10
  68. package/index.js +9 -6
  69. package/iterate.js +20 -13
  70. package/node.js +10 -8
  71. package/package.json +42 -18
  72. package/set.js +6 -5
  73. package/update.js +90 -52
  74. package/__tests__/checkIfOnUpdate.test.js +0 -103
  75. package/__tests__/children.test.js +0 -209
  76. package/__tests__/define.test.js +0 -75
  77. package/__tests__/inheritStateUpdates.test.js +0 -79
  78. package/__tests__/renderElement.test.js +0 -131
  79. package/__tests__/resetElement.test.js +0 -44
  80. package/__tests__/set.test.js +0 -312
  81. package/__tests__/throughExecProps.test.js +0 -86
  82. package/__tests__/throughInitialDefine.test.js +0 -104
  83. package/__tests__/throughInitialExec.test.js +0 -92
  84. package/__tests__/throughUpdatedDefine.test.js +0 -92
  85. package/__tests__/throughUpdatedExec.test.js +0 -111
  86. package/__tests__/tree.test.js +0 -15
  87. package/__tests__/update.test.js +0 -256
  88. package/dist/cjs/package.json +0 -4
  89. package/methods/set.js +0 -63
  90. package/methods/v2.js +0 -83
  91. package/mixins/attr.js +0 -32
  92. package/mixins/classList.js +0 -54
  93. package/mixins/content.js +0 -65
  94. package/mixins/data.js +0 -26
  95. package/mixins/html.js +0 -21
  96. package/mixins/index.js +0 -23
  97. package/mixins/registry.js +0 -46
  98. package/mixins/scope.js +0 -23
  99. package/mixins/state.js +0 -19
  100. package/mixins/style.js +0 -16
  101. package/mixins/text.js +0 -26
  102. package/utils/applyParam.js +0 -34
  103. package/utils/extendUtils.js +0 -149
  104. package/utils/index.js +0 -3
  105. package/utils/propEvents.js +0 -19
@@ -33,7 +33,7 @@ __export(update_exports, {
33
33
  });
34
34
  module.exports = __toCommonJS(update_exports);
35
35
  var import_utils = require("@domql/utils");
36
- var import_event = require("@domql/event");
36
+ var import_event = require("./event/index.js");
37
37
  var import_state = require("@domql/state");
38
38
  var import_create = require("./create.js");
39
39
  var import_iterate = require("./iterate.js");
@@ -51,12 +51,7 @@ const UPDATE_DEFAULT_OPTIONS = {
51
51
  exclude: import_utils2.METHODS_EXL
52
52
  };
53
53
  const update = function(params = {}, opts) {
54
- const calleeElementCache = opts == null ? void 0 : opts.calleeElement;
55
- const options = (0, import_utils.deepClone)(
56
- (0, import_utils.isObject)(opts) ? (0, import_utils.deepMerge)(opts, UPDATE_DEFAULT_OPTIONS) : UPDATE_DEFAULT_OPTIONS,
57
- { exclude: ["calleeElement"] }
58
- );
59
- options.calleeElement = calleeElementCache;
54
+ const options = (0, import_utils.isObject)(opts) ? { ...UPDATE_DEFAULT_OPTIONS, ...opts } : { ...UPDATE_DEFAULT_OPTIONS };
60
55
  const element = this;
61
56
  let ref = element.__ref;
62
57
  if (!ref) ref = element.__ref = {};
@@ -84,19 +79,22 @@ const update = function(params = {}, opts) {
84
79
  if (ifFails) return;
85
80
  if (ref.__if && !options.preventPropsUpdate) {
86
81
  const hasParentProps = parent.props && (parent.props[key] || parent.props.childProps);
87
- const hasFunctionInProps = ref.__propsStack.filter((v) => (0, import_utils.isFunction)(v));
88
- const props = params.props || hasParentProps || hasFunctionInProps.length;
82
+ const hasFunctionInProps = ref.__propsStack.some(import_utils.isFunction);
83
+ const props = params.props || hasParentProps || hasFunctionInProps;
89
84
  if (props) (0, import_utils.updateProps)(props, element, parent);
90
85
  }
91
86
  if (!options.preventBeforeUpdateListener && !options.preventListeners) {
92
- const simulate = { ...params, ...element };
93
- const beforeUpdateReturns = (0, import_event.triggerEventOnUpdate)(
94
- "beforeUpdate",
95
- params,
96
- simulate,
97
- options
98
- );
99
- if (beforeUpdateReturns === false) return element;
87
+ const hasBeforeUpdate = element.on?.beforeUpdate || element.props?.onBeforeUpdate;
88
+ if (hasBeforeUpdate) {
89
+ const simulate = { ...params, ...element };
90
+ const beforeUpdateReturns = (0, import_event.triggerEventOnUpdate)(
91
+ "beforeUpdate",
92
+ params,
93
+ simulate,
94
+ options
95
+ );
96
+ if (beforeUpdateReturns === false) return element;
97
+ }
100
98
  }
101
99
  (0, import_utils.overwriteDeep)(element, params);
102
100
  (0, import_iterate.throughExecProps)(element);
@@ -106,9 +104,7 @@ const update = function(params = {}, opts) {
106
104
  (0, import_event.triggerEventOn)("beforeClassAssign", element, options);
107
105
  }
108
106
  if (!ref.__if) return false;
109
- if (!node) {
110
- return;
111
- }
107
+ if (!node) return;
112
108
  const {
113
109
  preventUpdate,
114
110
  preventDefineUpdate,
@@ -126,12 +122,16 @@ const update = function(params = {}, opts) {
126
122
  options.preventUpdateAfterCount = 1;
127
123
  } else options.preventUpdateAfterCount++;
128
124
  }
125
+ const preventUpdateSet = (0, import_utils.isArray)(preventUpdate) ? new Set(preventUpdate) : null;
126
+ const preventDefineUpdateSet = (0, import_utils.isArray)(preventDefineUpdate) ? new Set(preventDefineUpdate) : null;
129
127
  for (const param in element) {
130
128
  const prop = element[param];
131
- if (!Object.hasOwnProperty.call(element, param)) continue;
132
- const isInPreventUpdate = (0, import_utils.isArray)(preventUpdate) && preventUpdate.includes(param);
133
- const isInPreventDefineUpdate = (0, import_utils.isArray)(preventDefineUpdate) && preventDefineUpdate.includes(param);
134
- if ((0, import_utils.isUndefined)(prop) || isInPreventUpdate || isInPreventDefineUpdate || preventDefineUpdate === true || preventDefineUpdate === param || (preventStateUpdate && param) === "state" || (0, import_utils.isMethod)(param, element) || (0, import_utils.isObject)(import_mixins.REGISTRY[param])) {
129
+ if (!Object.prototype.hasOwnProperty.call(element, param)) continue;
130
+ const isInPreventUpdate = preventUpdateSet && preventUpdateSet.has(param);
131
+ const isInPreventDefineUpdate = preventDefineUpdateSet && preventDefineUpdateSet.has(param);
132
+ const isRootEventHandler = (0, import_utils.isFunction)(prop) && param.length > 2 && param.charCodeAt(0) === 111 && param.charCodeAt(1) === 110 && // 'on'
133
+ param.charCodeAt(2) >= 65 && param.charCodeAt(2) <= 90;
134
+ if ((0, import_utils.isUndefined)(prop) || isInPreventUpdate || isInPreventDefineUpdate || preventDefineUpdate === true || preventDefineUpdate === param || preventStateUpdate && param === "state" || (0, import_utils.isMethod)(param, element) || isRootEventHandler || (0, import_utils.isObject)(import_mixins.REGISTRY[param])) {
135
135
  continue;
136
136
  }
137
137
  if (preventStateUpdate === "once") options.preventStateUpdate = false;
@@ -144,7 +144,9 @@ const update = function(params = {}, opts) {
144
144
  if (options.onEachUpdate) {
145
145
  options.onEachUpdate(param, element, element.state, element.context);
146
146
  }
147
- const childUpdateCall = () => update.call(prop, params[prop], {
147
+ const childParams = params[param];
148
+ if (childParams === void 0 && !options.isForced) continue;
149
+ const childUpdateCall = () => update.call(prop, childParams, {
148
150
  ...options,
149
151
  currentSnapshot: snapshotOnCallee,
150
152
  calleeElement
@@ -152,7 +154,7 @@ const update = function(params = {}, opts) {
152
154
  if (lazyLoad) {
153
155
  import_utils.window.requestAnimationFrame(() => {
154
156
  childUpdateCall();
155
- if (!options.preventUpdateListener) {
157
+ if (!options.preventUpdateListener && !options.preventListeners) {
156
158
  (0, import_event.triggerEventOn)("lazyLoad", element, options);
157
159
  }
158
160
  });
@@ -160,23 +162,61 @@ const update = function(params = {}, opts) {
160
162
  }
161
163
  }
162
164
  if (!preventContentUpdate) {
163
- const children = params.children || element.children;
164
- const content = children ? (0, import_children.default)(children, element, opts) : element.children || params.content;
165
- if (content) {
166
- (0, import_set.setContent)(content, element, options);
165
+ const contentKey = ref.contentElementKey || "content";
166
+ const existingContent = element[contentKey];
167
+ const childrenProp = params.children || element.children;
168
+ if (childrenProp) {
169
+ const content = (0, import_children.default)(childrenProp, element, opts);
170
+ if (content && !ref.__noChildrenDifference) {
171
+ (0, import_set.setContent)(content, element, options);
172
+ } else if (existingContent?.__ref && (0, import_utils.isFunction)(existingContent.update)) {
173
+ const lazyLoad = element.props?.lazyLoad || options.lazyLoad;
174
+ const contentUpdateCall = () => update.call(existingContent, params[contentKey], {
175
+ ...options,
176
+ currentSnapshot: snapshotOnCallee,
177
+ calleeElement
178
+ });
179
+ if (lazyLoad) {
180
+ import_utils.window.requestAnimationFrame(() => {
181
+ contentUpdateCall();
182
+ if (!options.preventUpdateListener && !options.preventListeners) {
183
+ (0, import_event.triggerEventOn)("lazyLoad", element, options);
184
+ }
185
+ });
186
+ } else contentUpdateCall();
187
+ }
188
+ } else if (existingContent?.__ref && (0, import_utils.isFunction)(existingContent.update)) {
189
+ const lazyLoad = element.props?.lazyLoad || options.lazyLoad;
190
+ const contentUpdateCall = () => update.call(existingContent, params[contentKey], {
191
+ ...options,
192
+ currentSnapshot: snapshotOnCallee,
193
+ calleeElement
194
+ });
195
+ if (lazyLoad) {
196
+ import_utils.window.requestAnimationFrame(() => {
197
+ contentUpdateCall();
198
+ if (!options.preventUpdateListener && !options.preventListeners) {
199
+ (0, import_event.triggerEventOn)("lazyLoad", element, options);
200
+ }
201
+ });
202
+ } else contentUpdateCall();
203
+ } else {
204
+ const content = element.children || params.content;
205
+ if (content) {
206
+ (0, import_set.setContent)(content, element, options);
207
+ }
167
208
  }
168
209
  }
169
- if (!preventUpdateListener) {
210
+ if (!preventUpdateListener && !options.preventListeners) {
170
211
  (0, import_event.triggerEventOn)("update", element, options);
171
212
  }
172
213
  };
173
214
  const checkIfOnUpdate = (element, parent, options) => {
174
- var _a, _b, _c;
175
- if (!(0, import_utils.isFunction)(element.if) && !(0, import_utils.isFunction)((_a = element.props) == null ? void 0 : _a.if) || !parent) {
215
+ if (!(0, import_utils.isFunction)(element.if) && !(0, import_utils.isFunction)(element.props?.if) || !parent) {
176
216
  return;
177
217
  }
178
218
  const ref = element.__ref;
179
- const ifPassed = (element.if || ((_b = element.props) == null ? void 0 : _b.if))(
219
+ const ifPassed = (element.if || element.props?.if)(
180
220
  element,
181
221
  element.state,
182
222
  element.context,
@@ -204,15 +244,15 @@ const checkIfOnUpdate = (element, parent, options) => {
204
244
  const contentKey = ref.contentElementKey;
205
245
  if (element.children) {
206
246
  element.removeContent();
207
- } else if ((_c = element[contentKey]) == null ? void 0 : _c.parseDeep) {
247
+ } else if (element[contentKey]?.parseDeep) {
208
248
  element[contentKey] = element[contentKey].parseDeep();
209
249
  }
210
250
  const previousElement = element.previousElement();
211
- const previousNode = previousElement == null ? void 0 : previousElement.node;
212
- const hasPrevious = previousNode == null ? void 0 : previousNode.parentNode;
251
+ const previousNode = previousElement?.node;
252
+ const hasPrevious = previousNode?.parentNode;
213
253
  const nextElement = element.nextElement();
214
- const nextNode = nextElement == null ? void 0 : nextElement.node;
215
- const hasNext = nextNode == null ? void 0 : nextNode.parentNode;
254
+ const nextNode = nextElement?.node;
255
+ const hasNext = nextNode?.parentNode;
216
256
  const attachOptions = (hasPrevious || hasNext) && {
217
257
  position: hasPrevious ? "after" : hasNext ? "before" : null,
218
258
  node: hasPrevious && previousNode || hasNext && nextNode
@@ -243,7 +283,7 @@ const inheritStateUpdates = (element, options) => {
243
283
  const { preventUpdateTriggerStateUpdate, isHoisted, execStateFunction } = options;
244
284
  if (preventUpdateTriggerStateUpdate) return;
245
285
  if (!stateKey && !ref.__hasRootState) {
246
- element.state = parent && parent.state || {};
286
+ element.state = parent?.state || {};
247
287
  return;
248
288
  }
249
289
  const shouldForceFunctionState = (0, import_utils.isFunction)(stateKey) && !isHoisted && execStateFunction;
@@ -28,10 +28,10 @@ const applyParam = (param, element, options) => {
28
28
  const prop = (0, import_utils.exec)(element[param], element);
29
29
  const { onlyUpdate } = options;
30
30
  const DOMQLProperty = import_mixins.REGISTRY[param];
31
- const DOMQLPropertyFromContext = context && context.registry && context.registry[param];
31
+ const DOMQLPropertyFromContext = context?.registry?.[param];
32
32
  const isGlobalTransformer = DOMQLPropertyFromContext || DOMQLProperty;
33
- const hasDefine = element.define && element.define[param];
34
- const hasContextDefine = context && context.define && context.define[param];
33
+ const hasDefine = element.define?.[param];
34
+ const hasContextDefine = context?.define?.[param];
35
35
  if (!ref.__if) return;
36
36
  const hasOnlyUpdate = onlyUpdate ? onlyUpdate === param || element.lookup(onlyUpdate) : true;
37
37
  if (isGlobalTransformer && !hasContextDefine && hasOnlyUpdate) {
@@ -57,7 +57,7 @@ const getExtendStackRegistry = (extend, stack) => {
57
57
  return setHashedExtend(extend, stack);
58
58
  };
59
59
  const extractArrayExtend = (extend, stack, context) => {
60
- extend.forEach((each) => flattenExtend(each, stack, context));
60
+ for (let i = 0; i < extend.length; i++) flattenExtend(extend[i], stack, context);
61
61
  return stack;
62
62
  };
63
63
  const deepExtend = (extend, stack, context) => {
@@ -77,7 +77,7 @@ const flattenExtend = (extend, stack, context) => {
77
77
  };
78
78
  const deepMergeExtend = (element, extend) => {
79
79
  for (const e in extend) {
80
- if (["parent", "node", "__element"].indexOf(e) > -1) continue;
80
+ if (e === "parent" || e === "node" || e === "__element") continue;
81
81
  const elementProp = element[e];
82
82
  const extendProp = extend[e];
83
83
  if (elementProp === void 0) {
@@ -101,11 +101,11 @@ const cloneAndMergeArrayExtend = (stack) => {
101
101
  }, {});
102
102
  };
103
103
  const fallbackStringExtend = (extend, context, options = {}, variant) => {
104
- const COMPONENTS = context && context.components || options.components;
105
- const PAGES = context && context.pages || options.pages;
104
+ const COMPONENTS = context?.components || options.components;
105
+ const PAGES = context?.pages || options.pages;
106
106
  if ((0, import_utils.isString)(extend)) {
107
107
  const componentExists = COMPONENTS && (COMPONENTS[extend + "." + variant] || COMPONENTS[extend] || COMPONENTS["smbls." + extend]);
108
- const pageExists = PAGES && extend.startsWith("/") && PAGES[extend];
108
+ const pageExists = PAGES && extend.charCodeAt(0) === 47 && PAGES[extend];
109
109
  if (componentExists) return componentExists;
110
110
  else if (pageExists) return pageExists;
111
111
  else {
@@ -15,10 +15,12 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
20
  var utils_exports = {};
20
21
  __export(utils_exports, {
21
22
  METHODS_EXL: () => METHODS_EXL
22
23
  });
23
24
  module.exports = __toCommonJS(utils_exports);
25
+ __reExport(utils_exports, require("./extendUtils.js"), module.exports);
24
26
  const METHODS_EXL = [];
@@ -18,15 +18,16 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var propEvents_exports = {};
20
20
  __export(propEvents_exports, {
21
+ propagateEventsFromElement: () => propagateEventsFromElement,
21
22
  propagateEventsFromProps: () => propagateEventsFromProps
22
23
  });
23
24
  module.exports = __toCommonJS(propEvents_exports);
24
25
  var import_utils = require("@domql/utils");
25
26
  const propagateEventsFromProps = (element) => {
26
27
  const { props, on } = element;
27
- const eventKeysFromProps = Object.keys(props).filter((key) => key.startsWith("on"));
28
- eventKeysFromProps.forEach((v) => {
29
- const eventName = (0, import_utils.lowercaseFirstLetter)(v.split("on")[1]);
28
+ for (const v in props) {
29
+ if (v.charCodeAt(0) !== 111 || v.charCodeAt(1) !== 110) continue;
30
+ const eventName = (0, import_utils.lowercaseFirstLetter)(v.slice(2));
30
31
  const origEvent = on[eventName];
31
32
  const funcFromProps = props[v];
32
33
  if ((0, import_utils.isFunction)(origEvent)) {
@@ -35,5 +36,21 @@ const propagateEventsFromProps = (element) => {
35
36
  if (originalEventRetunrs !== false) return funcFromProps(...args);
36
37
  };
37
38
  } else on[eventName] = funcFromProps;
38
- });
39
+ }
40
+ };
41
+ const propagateEventsFromElement = (element) => {
42
+ const { on } = element;
43
+ for (const param in element) {
44
+ if (param.charCodeAt(0) !== 111 || param.charCodeAt(1) !== 110 || !Object.prototype.hasOwnProperty.call(element, param)) continue;
45
+ const fn = element[param];
46
+ if (!(0, import_utils.isFunction)(fn)) continue;
47
+ const eventName = (0, import_utils.lowercaseFirstLetter)(param.slice(2));
48
+ const origEvent = on[eventName];
49
+ if ((0, import_utils.isFunction)(origEvent)) {
50
+ on[eventName] = (...args) => {
51
+ const ret = origEvent(...args);
52
+ if (ret !== false) return fn(...args);
53
+ };
54
+ } else on[eventName] = fn;
55
+ }
39
56
  };
@@ -13,6 +13,28 @@ import {
13
13
  isString,
14
14
  matchesComponentNaming
15
15
  } from "@domql/utils";
16
+ const shallowChildrenEqual = (a, b) => {
17
+ if (a === b) return true;
18
+ if (!a || !b) return false;
19
+ if (isArray(a) && isArray(b)) {
20
+ if (a.length !== b.length) return false;
21
+ for (let i = 0; i < a.length; i++) {
22
+ if (a[i] !== b[i]) return false;
23
+ }
24
+ return true;
25
+ }
26
+ if (isObject(a) && isObject(b)) {
27
+ const keysA = Object.keys(a);
28
+ const keysB = Object.keys(b);
29
+ if (keysA.length !== keysB.length) return false;
30
+ for (let i = 0; i < keysA.length; i++) {
31
+ const key = keysA[i];
32
+ if (a[key] !== b[key]) return false;
33
+ }
34
+ return true;
35
+ }
36
+ return a === b;
37
+ };
16
38
  function setChildren(param, element, opts) {
17
39
  let { children, __ref: ref, state } = element;
18
40
  let { childrenAs } = element.props || {};
@@ -45,31 +67,37 @@ function setChildren(param, element, opts) {
45
67
  }
46
68
  }
47
69
  if (!children || isNot(children)("array", "object")) return;
48
- if (isArray(children) && children.find((v) => v == null ? void 0 : v.$$typeof)) {
49
- const filterReact = children.filter((v) => !(v == null ? void 0 : v.$$typeof));
50
- if (filterReact.length !== children.length) {
51
- const extractedReactComponents = children.filter((v) => v == null ? void 0 : v.$$typeof);
52
- element.call("renderReact", extractedReactComponents, element);
70
+ if (isArray(children) && children.some((v) => v?.$$typeof)) {
71
+ const filterReact = [];
72
+ const reactComponents = [];
73
+ for (let i = 0; i < children.length; i++) {
74
+ if (children[i]?.$$typeof) reactComponents.push(children[i]);
75
+ else filterReact.push(children[i]);
76
+ }
77
+ if (reactComponents.length) {
78
+ element.call("renderReact", reactComponents, element);
53
79
  }
54
80
  children = filterReact;
55
81
  }
82
+ let cloned;
56
83
  if (ref.__childrenCache) {
57
- const equals = JSON.stringify(children) === JSON.stringify(ref.__childrenCache);
58
- if (equals) {
84
+ if (shallowChildrenEqual(children, ref.__childrenCache)) {
59
85
  ref.__noChildrenDifference = true;
60
86
  } else {
61
- ref.__childrenCache = deepClone(children);
87
+ cloned = deepClone(children);
88
+ ref.__childrenCache = cloned;
62
89
  delete ref.__noChildrenDifference;
63
90
  }
64
91
  } else {
65
- ref.__childrenCache = deepClone(children);
92
+ cloned = deepClone(children);
93
+ ref.__childrenCache = cloned;
66
94
  }
67
95
  if (isObject(children) || isArray(children)) {
68
- children = deepClone(children);
96
+ children = cloned || deepClone(children);
69
97
  }
70
98
  const content = { tag: "fragment" };
71
99
  for (const key in children) {
72
- const value = Object.hasOwnProperty.call(children, key) && children[key];
100
+ const value = Object.prototype.hasOwnProperty.call(children, key) && children[key];
73
101
  if (isDefined(value) && value !== null && value !== false) {
74
102
  content[key] = isObjectLike(value) ? childrenAs ? { [childrenAs]: value } : value : childrenAs ? { [childrenAs]: childrenAs === "state" ? { value } : { text: value } } : { text: value };
75
103
  }
@@ -6,6 +6,7 @@ import {
6
6
  isUndefined,
7
7
  detectInfiniteLoop,
8
8
  propertizeElement,
9
+ pickupElementFromProps,
9
10
  createElement,
10
11
  applyExtends,
11
12
  createScope,
@@ -15,14 +16,36 @@ import {
15
16
  createIfConditionFlag,
16
17
  createRoot
17
18
  } from "@domql/utils";
18
- import { applyAnimationFrame, triggerEventOn } from "@domql/event";
19
- import { assignNode } from "@domql/render";
19
+ import { applyAnimationFrame, triggerEventOn } from "./event/index.js";
20
+ import { assignNode } from "./render/index.js";
20
21
  import { createState } from "@domql/state";
21
22
  import { REGISTRY } from "./mixins/index.js";
22
23
  import { addMethods } from "./methods/set.js";
23
24
  import { assignKeyAsClassname } from "./mixins/classList.js";
24
25
  import { throughInitialExec, throughInitialDefine } from "./iterate.js";
25
- const ENV = "development";
26
+ import { filterAttributesByTagName } from "attrs-in-props";
27
+ const EXCLUDED_ATTRS = /* @__PURE__ */ new Set(["class", "style"]);
28
+ const applyPropsAsAttrs = (element) => {
29
+ const { tag, props, context } = element;
30
+ if (!tag || !props) return;
31
+ const autoAttrs = filterAttributesByTagName(tag, props, context?.cssPropsRegistry);
32
+ const filtered = {};
33
+ for (const key in autoAttrs) {
34
+ if (!EXCLUDED_ATTRS.has(key)) filtered[key] = autoAttrs[key];
35
+ }
36
+ let hasFiltered = false;
37
+ for (const _k in filtered) {
38
+ hasFiltered = true;
39
+ break;
40
+ }
41
+ if (!hasFiltered) return;
42
+ if (!element.attr) {
43
+ element.attr = filtered;
44
+ } else if (typeof element.attr === "object") {
45
+ element.attr = { ...filtered, ...element.attr };
46
+ }
47
+ };
48
+ const ENV = process.env.NODE_ENV;
26
49
  const create = (props, parentEl, passedKey, options = OPTIONS.create || {}, attachOptions) => {
27
50
  cacheOptions(options);
28
51
  const element = createElement(props, parentEl, passedKey, options, ROOT);
@@ -42,6 +65,8 @@ const create = (props, parentEl, passedKey, options = OPTIONS.create || {}, atta
42
65
  if (element.scope === "state") element.scope = element.state;
43
66
  createIfConditionFlag(element, parent);
44
67
  initProps(element, parent, options);
68
+ pickupElementFromProps.call(element, element, { cachedKeys: [] });
69
+ applyPropsAsAttrs(element);
45
70
  if (element.scope === "props" || element.scope === true) {
46
71
  element.scope = element.props;
47
72
  }
@@ -65,7 +90,12 @@ const cacheOptions = (options) => {
65
90
  }
66
91
  };
67
92
  const resetOptions = (element, parent, options) => {
68
- if (Object.keys(options).length) {
93
+ let hasKeys = false;
94
+ for (const _k in options) {
95
+ hasKeys = true;
96
+ break;
97
+ }
98
+ if (hasKeys) {
69
99
  OPTIONS.defaultOptions = options;
70
100
  if (options.ignoreChildExtends) delete options.ignoreChildExtends;
71
101
  }
@@ -75,9 +105,9 @@ const addElementIntoParentChildren = (element, parent) => {
75
105
  parent.__ref.__children.push(element.key);
76
106
  }
77
107
  };
108
+ let _uniqIdCounter = 1;
78
109
  const visitedElements = /* @__PURE__ */ new WeakMap();
79
110
  const renderElement = (element, parent, options, attachOptions) => {
80
- var _a, _b, _c;
81
111
  if (visitedElements.has(element)) {
82
112
  if (ENV === "test" || ENV === "development") {
83
113
  console.warn("Cyclic rendering detected:", element.__ref.path);
@@ -89,7 +119,7 @@ const renderElement = (element, parent, options, attachOptions) => {
89
119
  const isInfiniteLoopDetected = detectInfiniteLoop(ref.path);
90
120
  if (ref.__uniqId || isInfiniteLoopDetected) return;
91
121
  createNode(element, options);
92
- ref.__uniqId = Math.random();
122
+ ref.__uniqId = _uniqIdCounter++;
93
123
  };
94
124
  if (ENV === "test" || ENV === "development") {
95
125
  createNestedChild();
@@ -104,14 +134,14 @@ const renderElement = (element, parent, options, attachOptions) => {
104
134
  if (path.includes("demoComponent")) {
105
135
  path.splice(0, path.indexOf("demoComponent") + 1);
106
136
  }
107
- const isDemoComponent = (_b = (_a = element.lookup((el) => el.state.key)) == null ? void 0 : _a.state) == null ? void 0 : _b.key;
137
+ const isDemoComponent = element.lookup((el) => el.state.key)?.state?.key;
108
138
  element.warn(
109
139
  "Error happened in:",
110
140
  isDemoComponent ? isDemoComponent + " " : "" + path.join(".")
111
141
  );
112
142
  element.verbose();
113
143
  element.error(e, options);
114
- if ((_c = element.on) == null ? void 0 : _c.error) {
144
+ if (element.on?.error) {
115
145
  element.on.error(e, element, element.state, element.context, options);
116
146
  }
117
147
  }
@@ -135,6 +165,7 @@ const onlyResolveExtends = (element, parent, key, options) => {
135
165
  if (element.scope === "state") element.scope = element.state;
136
166
  createIfConditionFlag(element, parent);
137
167
  initProps(element, parent, options);
168
+ pickupElementFromProps.call(element, element, { cachedKeys: [] });
138
169
  if (element.scope === "props" || element.scope === true) {
139
170
  element.scope = element.props;
140
171
  }
@@ -150,9 +181,9 @@ const onlyResolveExtends = (element, parent, key, options) => {
150
181
  if (isUndefined(element[k]) || isMethod(k, element) || isObject(REGISTRY[k])) {
151
182
  continue;
152
183
  }
153
- const hasDefine = element.define && element.define[k];
154
- const contextHasDefine = element.context && element.context.define && element.context.define[k];
155
- const optionsHasDefine = options.define && options.define[k];
184
+ const hasDefine = element.define?.[k];
185
+ const contextHasDefine = element.context?.define?.[k];
186
+ const optionsHasDefine = options.define?.[k];
156
187
  if (!ref.__skipCreate && REGISTRY[k] && !optionsHasDefine) {
157
188
  continue;
158
189
  } else if (element[k] && !hasDefine && !optionsHasDefine && !contextHasDefine) {
@@ -1,5 +1,5 @@
1
1
  import { report } from "@domql/report";
2
- import { REGISTRY } from "./mixins";
2
+ import { REGISTRY } from "./mixins/index.js";
3
3
  var define_default = (params, options = {}) => {
4
4
  const { overwrite } = options;
5
5
  for (const param in params) {
@@ -0,0 +1,76 @@
1
+ const registerFrameListener = (el) => {
2
+ if (!el || !el.__ref) {
3
+ throw new Error("Element reference is invalid");
4
+ }
5
+ const { __ref: ref } = el;
6
+ if (!ref.root) {
7
+ throw new Error("Root reference is invalid");
8
+ }
9
+ if (!ref.root.data) {
10
+ throw new Error("Data are undefined");
11
+ }
12
+ const { frameListeners } = ref.root.data;
13
+ if (frameListeners && !frameListeners.has(el)) {
14
+ frameListeners.add(el);
15
+ }
16
+ };
17
+ const processFrameListeners = (frameListeners) => {
18
+ for (const element of frameListeners) {
19
+ if (!element.__ref.__frameHandler) {
20
+ const handler = element.on?.frame || element.onFrame || element.props?.onFrame;
21
+ if (handler) element.__ref.__frameHandler = handler;
22
+ else {
23
+ frameListeners.delete(element);
24
+ continue;
25
+ }
26
+ }
27
+ if (!element.node?.parentNode) {
28
+ frameListeners.delete(element);
29
+ delete element.__ref.__frameHandler;
30
+ } else {
31
+ try {
32
+ element.__ref.__frameHandler(element, element.state, element.context);
33
+ } catch (e) {
34
+ console.warn(e);
35
+ frameListeners.delete(element);
36
+ delete element.__ref.__frameHandler;
37
+ }
38
+ }
39
+ }
40
+ };
41
+ const startFrameLoop = (frameListeners) => {
42
+ if (_frameRunning) return;
43
+ _frameRunning = true;
44
+ function requestFrame() {
45
+ if (frameListeners.size === 0) {
46
+ _frameRunning = false;
47
+ return;
48
+ }
49
+ processFrameListeners(frameListeners);
50
+ window.requestAnimationFrame(requestFrame);
51
+ }
52
+ window.requestAnimationFrame(requestFrame);
53
+ };
54
+ const applyAnimationFrame = (element) => {
55
+ if (!element) {
56
+ throw new Error("Element is invalid");
57
+ }
58
+ const { on, props, __ref: ref } = element;
59
+ if (!ref.root || !ref.root.data) return;
60
+ const { frameListeners } = ref.root.data;
61
+ if (frameListeners && (on?.frame || element.onFrame || props?.onFrame)) {
62
+ registerFrameListener(element);
63
+ startFrameLoop(frameListeners);
64
+ }
65
+ };
66
+ let _frameRunning = false;
67
+ const initAnimationFrame = () => {
68
+ const frameListeners = /* @__PURE__ */ new Set();
69
+ startFrameLoop(frameListeners);
70
+ return frameListeners;
71
+ };
72
+ export {
73
+ applyAnimationFrame,
74
+ initAnimationFrame,
75
+ registerFrameListener
76
+ };
@@ -0,0 +1,8 @@
1
+ import { report } from "@domql/report";
2
+ import { isValidHtmlTag } from "@domql/utils";
3
+ const canRenderTag = (tag) => {
4
+ return isValidHtmlTag(tag || "div") || report("HTMLInvalidTag");
5
+ };
6
+ export {
7
+ canRenderTag
8
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./on.js";
2
+ export * from "./can.js";
3
+ export * from "./animationFrame.js";