@domql/element 3.5.1 → 3.6.3

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/README.md CHANGED
@@ -16,4 +16,22 @@ const Poster = {
16
16
  }
17
17
 
18
18
  DOM.create(Poster, document.body)
19
- ```
19
+ ```
20
+
21
+ ### html mixin
22
+
23
+ The `html` mixin sets raw HTML content on an element. It supports both direct assignment and props:
24
+
25
+ ```javascript
26
+ // Direct assignment (el.html)
27
+ const MyComponent = {
28
+ html: '<strong>Hello</strong>'
29
+ }
30
+
31
+ // Via props (el.props.html) — works as an alias
32
+ const MyComponent = {
33
+ props: { html: '<strong>Hello</strong>' }
34
+ }
35
+ ```
36
+
37
+ `el.html` takes priority when both are set. `props.html` is used as a fallback when `el.html` is not defined.
package/create.js CHANGED
@@ -150,7 +150,9 @@ const resetOptions = (element, parent, options) => {
150
150
 
151
151
  const addElementIntoParentChildren = (element, parent) => {
152
152
  if (parent.__ref && parent.__ref.__children) {
153
- parent.__ref.__children.push(element.key)
153
+ if (!parent.__ref.__children.includes(element.key)) {
154
+ parent.__ref.__children.push(element.key)
155
+ }
154
156
  }
155
157
  }
156
158
 
@@ -111,7 +111,9 @@ const resetOptions = (element, parent, options) => {
111
111
  };
112
112
  const addElementIntoParentChildren = (element, parent) => {
113
113
  if (parent.__ref && parent.__ref.__children) {
114
- parent.__ref.__children.push(element.key);
114
+ if (!parent.__ref.__children.includes(element.key)) {
115
+ parent.__ref.__children.push(element.key);
116
+ }
115
117
  }
116
118
  };
117
119
  let _uniqIdCounter = 1;
@@ -64,7 +64,8 @@ const processFrameListeners = (frameListeners) => {
64
64
  }
65
65
  };
66
66
  const startFrameLoop = (frameListeners) => {
67
- if (_frameRunning) return;
67
+ const raf = typeof window !== "undefined" && window.requestAnimationFrame;
68
+ if (_frameRunning || !raf) return;
68
69
  _frameRunning = true;
69
70
  function requestFrame() {
70
71
  if (frameListeners.size === 0) {
@@ -72,9 +73,9 @@ const startFrameLoop = (frameListeners) => {
72
73
  return;
73
74
  }
74
75
  processFrameListeners(frameListeners);
75
- window.requestAnimationFrame(requestFrame);
76
+ raf(requestFrame);
76
77
  }
77
- window.requestAnimationFrame(requestFrame);
78
+ raf(requestFrame);
78
79
  };
79
80
  const applyAnimationFrame = (element) => {
80
81
  if (!element) {
@@ -24,7 +24,7 @@ __export(html_exports, {
24
24
  module.exports = __toCommonJS(html_exports);
25
25
  var import_utils = require("@domql/utils");
26
26
  function html(param, element, node) {
27
- const prop = (0, import_utils.exec)(element?.props?.html || param, element);
27
+ const prop = (0, import_utils.exec)(param ?? element?.props?.html, element);
28
28
  const { __ref } = element;
29
29
  if (prop !== __ref.__html) {
30
30
  if (node.nodeName === "SVG") node.textContent = prop;
@@ -53,7 +53,9 @@ const REGISTRY = {
53
53
  extends: {},
54
54
  children: {},
55
55
  content: {},
56
+ childExtend: {},
56
57
  childExtends: {},
58
+ childExtendRecursive: {},
57
59
  childExtendsRecursive: {},
58
60
  props: {},
59
61
  if: {},
package/dist/cjs/set.js CHANGED
@@ -105,6 +105,16 @@ const removeContent = function(el, opts = {}) {
105
105
  };
106
106
  const set = function(params, options = {}, el) {
107
107
  const element = el || this;
108
+ const { __ref: ref } = element;
109
+ if (ref.__settingContent) return element;
110
+ ref.__settingContent = true;
111
+ try {
112
+ return _setInner(params, options, element);
113
+ } finally {
114
+ ref.__settingContent = false;
115
+ }
116
+ };
117
+ const _setInner = function(params, options, element) {
108
118
  const { __ref: ref } = element;
109
119
  const contentElementKey = setContentKey(element, options);
110
120
  const content = element[contentElementKey];
@@ -130,18 +140,20 @@ const set = function(params, options = {}, el) {
130
140
  }
131
141
  return;
132
142
  }
133
- if (!params) return element;
143
+ if (!params || typeof params !== "object") return element;
134
144
  let { childExtends, props, tag } = params;
135
145
  if (!props) props = params.props = {};
136
146
  if (tag === "fragment") {
137
- if (!childExtends && element.childExtends) {
138
- params.childExtends = element.childExtends;
147
+ const elementChildExtends = element.childExtends || element.childExtend;
148
+ if (!childExtends && elementChildExtends) {
149
+ params.childExtends = elementChildExtends;
139
150
  props.ignoreChildExtends = true;
140
151
  }
141
- if (!props?.childProps && element.props?.childProps) {
142
- props.childProps = element.props.childProps;
143
- props.ignoreChildProps = true;
152
+ const elementChildProps = element.childProps || element.props?.childProps;
153
+ if (!props?.childProps && elementChildProps) {
154
+ props.childProps = elementChildProps;
144
155
  }
156
+ props.ignoreChildProps = true;
145
157
  }
146
158
  if (lazyLoad) {
147
159
  window.requestAnimationFrame(() => {
@@ -215,6 +215,34 @@ const update = function(params = {}, opts) {
215
215
  (0, import_event.triggerEventOn)("update", element, options);
216
216
  }
217
217
  };
218
+ const findSiblingAttachOptions = (element, parent) => {
219
+ const { __children } = parent.__ref || {};
220
+ if (!__children) return false;
221
+ const currentIndex = __children.indexOf(element.key);
222
+ let previousNode;
223
+ for (let i = currentIndex - 1; i >= 0; i--) {
224
+ const sibling = parent[__children[i]];
225
+ if (sibling?.node?.parentNode) {
226
+ previousNode = sibling.node;
227
+ break;
228
+ }
229
+ }
230
+ if (previousNode) {
231
+ return { position: "after", node: previousNode };
232
+ }
233
+ let nextNode;
234
+ for (let i = currentIndex + 1; i < __children.length; i++) {
235
+ const sibling = parent[__children[i]];
236
+ if (sibling?.node?.parentNode) {
237
+ nextNode = sibling.node;
238
+ break;
239
+ }
240
+ }
241
+ if (nextNode) {
242
+ return { position: "before", node: nextNode };
243
+ }
244
+ return false;
245
+ };
218
246
  const checkIfOnUpdate = (element, parent, options) => {
219
247
  if (!(0, import_utils.isFunction)(element.if) && !(0, import_utils.isFunction)(element.props?.if) || !parent) {
220
248
  return;
@@ -251,16 +279,7 @@ const checkIfOnUpdate = (element, parent, options) => {
251
279
  } else if (element[contentKey]?.parseDeep) {
252
280
  element[contentKey] = element[contentKey].parseDeep();
253
281
  }
254
- const previousElement = element.previousElement();
255
- const previousNode = previousElement?.node;
256
- const hasPrevious = previousNode?.parentNode;
257
- const nextElement = element.nextElement();
258
- const nextNode = nextElement?.node;
259
- const hasNext = nextNode?.parentNode;
260
- const attachOptions = (hasPrevious || hasNext) && {
261
- position: hasPrevious ? "after" : hasNext ? "before" : null,
262
- node: hasPrevious && previousNode || hasNext && nextNode
263
- };
282
+ const attachOptions = findSiblingAttachOptions(element, parent);
264
283
  delete element.__ref;
265
284
  delete element.parent;
266
285
  const createdElement = (0, import_create.create)(
@@ -102,7 +102,9 @@ const resetOptions = (element, parent, options) => {
102
102
  };
103
103
  const addElementIntoParentChildren = (element, parent) => {
104
104
  if (parent.__ref && parent.__ref.__children) {
105
- parent.__ref.__children.push(element.key);
105
+ if (!parent.__ref.__children.includes(element.key)) {
106
+ parent.__ref.__children.push(element.key);
107
+ }
106
108
  }
107
109
  };
108
110
  let _uniqIdCounter = 1;
@@ -39,7 +39,8 @@ const processFrameListeners = (frameListeners) => {
39
39
  }
40
40
  };
41
41
  const startFrameLoop = (frameListeners) => {
42
- if (_frameRunning) return;
42
+ const raf = typeof window !== "undefined" && window.requestAnimationFrame;
43
+ if (_frameRunning || !raf) return;
43
44
  _frameRunning = true;
44
45
  function requestFrame() {
45
46
  if (frameListeners.size === 0) {
@@ -47,9 +48,9 @@ const startFrameLoop = (frameListeners) => {
47
48
  return;
48
49
  }
49
50
  processFrameListeners(frameListeners);
50
- window.requestAnimationFrame(requestFrame);
51
+ raf(requestFrame);
51
52
  }
52
- window.requestAnimationFrame(requestFrame);
53
+ raf(requestFrame);
53
54
  };
54
55
  const applyAnimationFrame = (element) => {
55
56
  if (!element) {
@@ -1,6 +1,6 @@
1
1
  import { exec } from "@domql/utils";
2
2
  function html(param, element, node) {
3
- const prop = exec(element?.props?.html || param, element);
3
+ const prop = exec(param ?? element?.props?.html, element);
4
4
  const { __ref } = element;
5
5
  if (prop !== __ref.__html) {
6
6
  if (node.nodeName === "SVG") node.textContent = prop;
@@ -19,7 +19,9 @@ const REGISTRY = {
19
19
  extends: {},
20
20
  children: {},
21
21
  content: {},
22
+ childExtend: {},
22
23
  childExtends: {},
24
+ childExtendRecursive: {},
23
25
  childExtendsRecursive: {},
24
26
  props: {},
25
27
  if: {},
package/dist/esm/set.js CHANGED
@@ -75,6 +75,16 @@ const removeContent = function(el, opts = {}) {
75
75
  };
76
76
  const set = function(params, options = {}, el) {
77
77
  const element = el || this;
78
+ const { __ref: ref } = element;
79
+ if (ref.__settingContent) return element;
80
+ ref.__settingContent = true;
81
+ try {
82
+ return _setInner(params, options, element);
83
+ } finally {
84
+ ref.__settingContent = false;
85
+ }
86
+ };
87
+ const _setInner = function(params, options, element) {
78
88
  const { __ref: ref } = element;
79
89
  const contentElementKey = setContentKey(element, options);
80
90
  const content = element[contentElementKey];
@@ -100,18 +110,20 @@ const set = function(params, options = {}, el) {
100
110
  }
101
111
  return;
102
112
  }
103
- if (!params) return element;
113
+ if (!params || typeof params !== "object") return element;
104
114
  let { childExtends, props, tag } = params;
105
115
  if (!props) props = params.props = {};
106
116
  if (tag === "fragment") {
107
- if (!childExtends && element.childExtends) {
108
- params.childExtends = element.childExtends;
117
+ const elementChildExtends = element.childExtends || element.childExtend;
118
+ if (!childExtends && elementChildExtends) {
119
+ params.childExtends = elementChildExtends;
109
120
  props.ignoreChildExtends = true;
110
121
  }
111
- if (!props?.childProps && element.props?.childProps) {
112
- props.childProps = element.props.childProps;
113
- props.ignoreChildProps = true;
122
+ const elementChildProps = element.childProps || element.props?.childProps;
123
+ if (!props?.childProps && elementChildProps) {
124
+ props.childProps = elementChildProps;
114
125
  }
126
+ props.ignoreChildProps = true;
115
127
  }
116
128
  if (lazyLoad) {
117
129
  window.requestAnimationFrame(() => {
@@ -202,6 +202,34 @@ const update = function(params = {}, opts) {
202
202
  triggerEventOn("update", element, options);
203
203
  }
204
204
  };
205
+ const findSiblingAttachOptions = (element, parent) => {
206
+ const { __children } = parent.__ref || {};
207
+ if (!__children) return false;
208
+ const currentIndex = __children.indexOf(element.key);
209
+ let previousNode;
210
+ for (let i = currentIndex - 1; i >= 0; i--) {
211
+ const sibling = parent[__children[i]];
212
+ if (sibling?.node?.parentNode) {
213
+ previousNode = sibling.node;
214
+ break;
215
+ }
216
+ }
217
+ if (previousNode) {
218
+ return { position: "after", node: previousNode };
219
+ }
220
+ let nextNode;
221
+ for (let i = currentIndex + 1; i < __children.length; i++) {
222
+ const sibling = parent[__children[i]];
223
+ if (sibling?.node?.parentNode) {
224
+ nextNode = sibling.node;
225
+ break;
226
+ }
227
+ }
228
+ if (nextNode) {
229
+ return { position: "before", node: nextNode };
230
+ }
231
+ return false;
232
+ };
205
233
  const checkIfOnUpdate = (element, parent, options) => {
206
234
  if (!isFunction(element.if) && !isFunction(element.props?.if) || !parent) {
207
235
  return;
@@ -238,16 +266,7 @@ const checkIfOnUpdate = (element, parent, options) => {
238
266
  } else if (element[contentKey]?.parseDeep) {
239
267
  element[contentKey] = element[contentKey].parseDeep();
240
268
  }
241
- const previousElement = element.previousElement();
242
- const previousNode = previousElement?.node;
243
- const hasPrevious = previousNode?.parentNode;
244
- const nextElement = element.nextElement();
245
- const nextNode = nextElement?.node;
246
- const hasNext = nextNode?.parentNode;
247
- const attachOptions = (hasPrevious || hasNext) && {
248
- position: hasPrevious ? "after" : hasNext ? "before" : null,
249
- node: hasPrevious && previousNode || hasNext && nextNode
250
- };
269
+ const attachOptions = findSiblingAttachOptions(element, parent);
251
270
  delete element.__ref;
252
271
  delete element.parent;
253
272
  const createdElement = create(
@@ -57,7 +57,7 @@ var DomqlElement = (() => {
57
57
  return (typeof HTMLElement === "object" ? obj instanceof window2.HTMLElement : obj && typeof obj === "object" && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === "string") || false;
58
58
  };
59
59
  var isDOMNode = (obj) => {
60
- return typeof window2 !== "undefined" && (obj instanceof window2.Node || obj instanceof window2.Window || obj === window2 || obj === document);
60
+ return typeof window2 !== "undefined" && (window2.Node && obj instanceof window2.Node || window2.Window && obj instanceof window2.Window || obj === window2 || obj === document);
61
61
  };
62
62
 
63
63
  // ../utils/dist/esm/types.js
@@ -801,6 +801,7 @@ var DomqlElement = (() => {
801
801
 
802
802
  // ../utils/dist/esm/extends.js
803
803
  var ENV2 = process.env.NODE_ENV;
804
+ var isSourcemapEnabled = (options) => options.sourcemap !== false && ENV2 !== "production";
804
805
  var createExtendsFromKeys = (key) => {
805
806
  if (key.includes("+")) {
806
807
  return key.split("+").filter(matchesComponentNaming);
@@ -874,17 +875,17 @@ var DomqlElement = (() => {
874
875
  }
875
876
  return setHashedExtend(extend, stack);
876
877
  };
877
- var extractArrayExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set()) => {
878
+ var extractArrayExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set(), nameStack, componentNameMap) => {
878
879
  for (const each of extend) {
879
880
  if (isArray(each)) {
880
- extractArrayExtend(each, stack, context, processed);
881
+ extractArrayExtend(each, stack, context, processed, nameStack, componentNameMap);
881
882
  } else {
882
- flattenExtend(each, stack, context, processed);
883
+ flattenExtend(each, stack, context, processed, nameStack, void 0, componentNameMap);
883
884
  }
884
885
  }
885
886
  return stack;
886
887
  };
887
- var deepExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set()) => {
888
+ var deepExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set(), nameStack, currentName, componentNameMap) => {
888
889
  const extendOflattenExtend = extend.extends || extend.extend;
889
890
  const cleanExtend = { ...extend };
890
891
  delete cleanExtend.extends;
@@ -896,26 +897,32 @@ var DomqlElement = (() => {
896
897
  }
897
898
  if (hasKeys) {
898
899
  stack.push(cleanExtend);
900
+ if (nameStack) nameStack.push(currentName);
899
901
  }
900
902
  if (extendOflattenExtend) {
901
- flattenExtend(extendOflattenExtend, stack, context, processed);
903
+ flattenExtend(extendOflattenExtend, stack, context, processed, nameStack, currentName, componentNameMap);
902
904
  }
903
905
  return stack;
904
906
  };
905
- var flattenExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set()) => {
907
+ var flattenExtend = (extend, stack, context, processed = /* @__PURE__ */ new Set(), nameStack, parentName, componentNameMap) => {
906
908
  if (!extend) return stack;
907
909
  if (processed.has(extend)) return stack;
908
910
  if (isArray(extend)) {
909
- return extractArrayExtend(extend, stack, context, processed);
911
+ return extractArrayExtend(extend, stack, context, processed, nameStack, componentNameMap);
910
912
  }
913
+ let currentName = parentName;
911
914
  if (isString(extend)) {
915
+ currentName = extend;
912
916
  extend = mapStringsWithContextComponents(extend, context);
917
+ } else if (componentNameMap && isObject(extend) && componentNameMap.has(extend)) {
918
+ currentName = componentNameMap.get(extend);
913
919
  }
914
920
  processed.add(extend);
915
921
  if (extend?.extends || extend?.extend) {
916
- deepExtend(extend, stack, context, processed);
922
+ deepExtend(extend, stack, context, processed, nameStack, currentName, componentNameMap);
917
923
  } else if (extend) {
918
924
  stack.push(extend);
925
+ if (nameStack) nameStack.push(currentName);
919
926
  }
920
927
  return stack;
921
928
  };
@@ -928,7 +935,7 @@ var DomqlElement = (() => {
928
935
  "childExtend",
929
936
  "childExtendRecursive"
930
937
  ]);
931
- var deepMergeExtends = (element, extend) => {
938
+ var deepMergeExtends = (element, extend, sourcemap, sourceName, preBuiltSourcemap) => {
932
939
  extend = deepClone(extend);
933
940
  for (const e in extend) {
934
941
  if (MERGE_EXTENDS_SKIP.has(e)) continue;
@@ -938,11 +945,23 @@ var DomqlElement = (() => {
938
945
  if (Object.prototype.hasOwnProperty.call(extend, e) && e !== "__proto__" && e !== "constructor" && e !== "prototype") {
939
946
  if (elementProp === void 0) {
940
947
  element[e] = extendProp;
948
+ if (sourcemap && sourceName) {
949
+ if (isObject(extendProp) && !isArray(extendProp)) {
950
+ sourcemap[e] = sourcemap[e] || {};
951
+ trackSourcemapDeep(sourcemap[e], extendProp, sourceName);
952
+ } else {
953
+ sourcemap[e] = sourceName;
954
+ }
955
+ } else if (sourcemap && preBuiltSourcemap?.[e]) {
956
+ sourcemap[e] = preBuiltSourcemap[e];
957
+ }
941
958
  } else if (isObject(elementProp) && isObject(extendProp)) {
959
+ const nestedSourcemap = sourcemap ? sourcemap[e] = sourcemap[e] || {} : void 0;
960
+ const nestedPreBuilt = preBuiltSourcemap?.[e];
942
961
  if (matchesComponentNaming(e)) {
943
- element[e] = deepMergeExtends(elementProp, extendProp);
962
+ element[e] = deepMergeExtends(elementProp, extendProp, nestedSourcemap, sourceName, nestedPreBuilt);
944
963
  } else {
945
- deepMergeExtends(elementProp, extendProp);
964
+ deepMergeExtends(elementProp, extendProp, nestedSourcemap, sourceName, nestedPreBuilt);
946
965
  }
947
966
  }
948
967
  if (e === "extends" || e === "childExtends" || e === "childExtendsRecursive") {
@@ -957,10 +976,24 @@ var DomqlElement = (() => {
957
976
  }
958
977
  return element;
959
978
  };
960
- var cloneAndMergeArrayExtend = (stack) => {
961
- return stack.reduce((acc, current) => {
979
+ var trackSourcemapDeep = (sourcemap, obj, sourceName) => {
980
+ for (const key in obj) {
981
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
982
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
983
+ const val = obj[key];
984
+ if (isObject(val) && !isArray(val)) {
985
+ sourcemap[key] = sourcemap[key] || {};
986
+ trackSourcemapDeep(sourcemap[key], val, sourceName);
987
+ } else {
988
+ sourcemap[key] = sourceName;
989
+ }
990
+ }
991
+ };
992
+ var cloneAndMergeArrayExtend = (stack, sourcemap, extendNames) => {
993
+ return stack.reduce((acc, current, i) => {
962
994
  const cloned = deepClone(current);
963
- return deepMergeExtends(acc, cloned);
995
+ const sourceName = extendNames ? extendNames[i] : void 0;
996
+ return deepMergeExtends(acc, cloned, sourcemap, sourceName);
964
997
  }, {});
965
998
  };
966
999
  var mapStringsWithContextComponents = (extend, context, options = {}, variant) => {
@@ -980,11 +1013,12 @@ var DomqlElement = (() => {
980
1013
  }
981
1014
  return extend;
982
1015
  };
983
- var getExtendsStack = (extend, context) => {
1016
+ var getExtendsStack = (extend, context, nameStack, componentNameMap) => {
984
1017
  if (!extend) return [];
985
1018
  if (extend.__hash) return getHashedExtend(extend) || [];
986
1019
  const processed = /* @__PURE__ */ new Set();
987
- const stack = flattenExtend(extend, [], context, processed);
1020
+ const stack = flattenExtend(extend, [], context, processed, nameStack, void 0, componentNameMap);
1021
+ if (nameStack) return stack;
988
1022
  return getExtendsStackRegistry(extend, stack);
989
1023
  };
990
1024
  var createElementExtends = (element, parent, options = {}) => {
@@ -1062,6 +1096,8 @@ var DomqlElement = (() => {
1062
1096
  const { props, __ref: ref } = element;
1063
1097
  const context = element.context || parent.context;
1064
1098
  const variant = element.variant || props?.variant;
1099
+ const sourcemap = isSourcemapEnabled(options);
1100
+ const originalExtendNames = sourcemap ? [...ref.__extends] : null;
1065
1101
  const __extends = removeDuplicatesInArray(
1066
1102
  ref.__extends.map((val, i) => {
1067
1103
  return mapStringsWithContextComponents(
@@ -1072,15 +1108,40 @@ var DomqlElement = (() => {
1072
1108
  );
1073
1109
  })
1074
1110
  );
1075
- const stack = getExtendsStack(__extends, context);
1076
- ref.__extendsStack = stack;
1111
+ if (sourcemap) {
1112
+ const componentNameMap = /* @__PURE__ */ new WeakMap();
1113
+ for (let i = 0; i < __extends.length; i++) {
1114
+ const resolved = __extends[i];
1115
+ const originalName = originalExtendNames[i];
1116
+ if (resolved && isObject(resolved) && isString(originalName)) {
1117
+ componentNameMap.set(resolved, originalName);
1118
+ }
1119
+ }
1120
+ const nameStack = [];
1121
+ const stack = getExtendsStack(__extends, context, nameStack, componentNameMap);
1122
+ ref.__extendsStack = stack;
1123
+ ref.__extendsNames = nameStack;
1124
+ } else {
1125
+ const stack = getExtendsStack(__extends, context);
1126
+ ref.__extendsStack = stack;
1127
+ }
1077
1128
  return ref.__extendsStack;
1078
1129
  };
1079
1130
  var finalizeExtends = (element, parent, options = {}) => {
1080
1131
  const { __ref: ref } = element;
1081
1132
  const { __extendsStack } = ref;
1082
- const flattenExtends = cloneAndMergeArrayExtend(__extendsStack);
1083
- return deepMergeExtends(element, flattenExtends);
1133
+ if (isSourcemapEnabled(options)) {
1134
+ const sourcemapAcc = {};
1135
+ const extendNames = ref.__extendsNames || [];
1136
+ const flattenExtends = cloneAndMergeArrayExtend(__extendsStack, sourcemapAcc, extendNames);
1137
+ const appliedSourcemap = {};
1138
+ deepMergeExtends(element, flattenExtends, appliedSourcemap, void 0, sourcemapAcc);
1139
+ ref.__sourcemap = appliedSourcemap;
1140
+ } else {
1141
+ const flattenExtends = cloneAndMergeArrayExtend(__extendsStack);
1142
+ deepMergeExtends(element, flattenExtends);
1143
+ }
1144
+ return element;
1084
1145
  };
1085
1146
  var applyExtends = (element, parent, options = {}) => {
1086
1147
  createElementExtends(element, parent, options);
@@ -1119,6 +1180,31 @@ var DomqlElement = (() => {
1119
1180
  // ../utils/dist/esm/props.js
1120
1181
  var RE_UPPER = /^[A-Z]/;
1121
1182
  var RE_DIGITS = /^\d+$/;
1183
+ var CSS_SELECTOR_PREFIXES = /* @__PURE__ */ new Set([":", "@", "[", "*", "+", "~", "&", ">", "$", "-", ".", "!"]);
1184
+ var ELEMENT_INDICATOR_KEYS = /* @__PURE__ */ new Set([
1185
+ "extend",
1186
+ "props",
1187
+ "text",
1188
+ "tag",
1189
+ "on",
1190
+ "if",
1191
+ "childExtend",
1192
+ "children",
1193
+ "childrenAs",
1194
+ "state",
1195
+ "html",
1196
+ "attr",
1197
+ "define",
1198
+ "content"
1199
+ ]);
1200
+ var looksLikeElement = (value) => {
1201
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1202
+ for (const k in value) {
1203
+ if (ELEMENT_INDICATOR_KEYS.has(k)) return true;
1204
+ if (RE_UPPER.test(k)) return true;
1205
+ }
1206
+ return false;
1207
+ };
1122
1208
  var createProps = (element, parent, key) => {
1123
1209
  const { props, __ref: ref } = element;
1124
1210
  ref.__propsStack = [];
@@ -1141,11 +1227,27 @@ var DomqlElement = (() => {
1141
1227
  delete obj[key];
1142
1228
  continue;
1143
1229
  }
1144
- const hasDefine = isObject(this.define?.[key]);
1145
- const hasGlobalDefine = isObject(this.context?.define?.[key]);
1146
- const isElement = RE_UPPER.test(key) || RE_DIGITS.test(key);
1230
+ if (key === "childProps") {
1231
+ obj.props[key] = value;
1232
+ delete obj[key];
1233
+ cachedKeys.push(key);
1234
+ continue;
1235
+ }
1236
+ const defineValue = this.define?.[key];
1237
+ const globalDefineValue = this.context?.define?.[key];
1238
+ const hasDefine = isObject(defineValue) || isFunction(defineValue);
1239
+ const hasGlobalDefine = isObject(globalDefineValue) || isFunction(globalDefineValue);
1240
+ if (hasDefine || hasGlobalDefine) continue;
1241
+ const firstChar = key.charAt(0);
1242
+ if (CSS_SELECTOR_PREFIXES.has(firstChar)) {
1243
+ obj.props[key] = value;
1244
+ delete obj[key];
1245
+ cachedKeys.push(key);
1246
+ continue;
1247
+ }
1248
+ const isElement = RE_UPPER.test(key) || RE_DIGITS.test(key) || looksLikeElement(value);
1147
1249
  const isBuiltin = DOMQ_PROPERTIES.has(key);
1148
- if (!isElement && !isBuiltin && !hasDefine && !hasGlobalDefine) {
1250
+ if (!isElement && !isBuiltin) {
1149
1251
  obj.props[key] = value;
1150
1252
  delete obj[key];
1151
1253
  cachedKeys.push(key);
@@ -1165,8 +1267,13 @@ var DomqlElement = (() => {
1165
1267
  continue;
1166
1268
  }
1167
1269
  if (cachedKeys.includes(key)) continue;
1168
- const hasDefine = isObject(this.define?.[key]);
1169
- const hasGlobalDefine = isObject(this.context?.define?.[key]);
1270
+ if (key === "childProps") continue;
1271
+ const firstChar = key.charAt(0);
1272
+ if (CSS_SELECTOR_PREFIXES.has(firstChar)) continue;
1273
+ const defineValue = this.define?.[key];
1274
+ const globalDefineValue = this.context?.define?.[key];
1275
+ const hasDefine = isObject(defineValue) || isFunction(defineValue);
1276
+ const hasGlobalDefine = isObject(globalDefineValue) || isFunction(globalDefineValue);
1170
1277
  const isElement = RE_UPPER.test(key) || RE_DIGITS.test(key);
1171
1278
  const isBuiltin = DOMQ_PROPERTIES.has(key);
1172
1279
  if (isElement || isBuiltin || hasDefine || hasGlobalDefine) {
@@ -1201,7 +1308,7 @@ var DomqlElement = (() => {
1201
1308
  const parentProps = parent.props;
1202
1309
  if (!parentProps) return propsStack;
1203
1310
  const matchParentKeyProps = parentProps[element.key];
1204
- const matchParentChildProps = parentProps.childProps;
1311
+ const matchParentChildProps = parentProps.childProps || parent.childProps;
1205
1312
  const ignoreChildProps = element.props?.ignoreChildProps;
1206
1313
  if (matchParentChildProps && !ignoreChildProps) {
1207
1314
  const childProps = objectizeStringProperty(matchParentChildProps);
@@ -2151,7 +2258,8 @@ ${element}` : "";
2151
2258
  }
2152
2259
  };
2153
2260
  var startFrameLoop = (frameListeners) => {
2154
- if (_frameRunning) return;
2261
+ const raf = typeof window !== "undefined" && window.requestAnimationFrame;
2262
+ if (_frameRunning || !raf) return;
2155
2263
  _frameRunning = true;
2156
2264
  function requestFrame() {
2157
2265
  if (frameListeners.size === 0) {
@@ -2159,9 +2267,9 @@ ${element}` : "";
2159
2267
  return;
2160
2268
  }
2161
2269
  processFrameListeners(frameListeners);
2162
- window.requestAnimationFrame(requestFrame);
2270
+ raf(requestFrame);
2163
2271
  }
2164
- window.requestAnimationFrame(requestFrame);
2272
+ raf(requestFrame);
2165
2273
  };
2166
2274
  var applyAnimationFrame = (element) => {
2167
2275
  if (!element) {
@@ -2544,7 +2652,7 @@ ${element}` : "";
2544
2652
 
2545
2653
  // mixins/html.js
2546
2654
  function html(param, element, node) {
2547
- const prop = exec(element?.props?.html || param, element);
2655
+ const prop = exec(param ?? element?.props?.html, element);
2548
2656
  const { __ref } = element;
2549
2657
  if (prop !== __ref.__html) {
2550
2658
  if (node.nodeName === "SVG") node.textContent = prop;
@@ -2635,7 +2743,9 @@ ${element}` : "";
2635
2743
  extends: {},
2636
2744
  children: {},
2637
2745
  content: {},
2746
+ childExtend: {},
2638
2747
  childExtends: {},
2748
+ childExtendRecursive: {},
2639
2749
  childExtendsRecursive: {},
2640
2750
  props: {},
2641
2751
  if: {},
@@ -2849,6 +2959,16 @@ ${element}` : "";
2849
2959
  };
2850
2960
  var set = function(params, options = {}, el) {
2851
2961
  const element = el || this;
2962
+ const { __ref: ref } = element;
2963
+ if (ref.__settingContent) return element;
2964
+ ref.__settingContent = true;
2965
+ try {
2966
+ return _setInner(params, options, element);
2967
+ } finally {
2968
+ ref.__settingContent = false;
2969
+ }
2970
+ };
2971
+ var _setInner = function(params, options, element) {
2852
2972
  const { __ref: ref } = element;
2853
2973
  const contentElementKey = setContentKey(element, options);
2854
2974
  const content = element[contentElementKey];
@@ -2874,18 +2994,20 @@ ${element}` : "";
2874
2994
  }
2875
2995
  return;
2876
2996
  }
2877
- if (!params) return element;
2997
+ if (!params || typeof params !== "object") return element;
2878
2998
  let { childExtends, props, tag } = params;
2879
2999
  if (!props) props = params.props = {};
2880
3000
  if (tag === "fragment") {
2881
- if (!childExtends && element.childExtends) {
2882
- params.childExtends = element.childExtends;
3001
+ const elementChildExtends = element.childExtends || element.childExtend;
3002
+ if (!childExtends && elementChildExtends) {
3003
+ params.childExtends = elementChildExtends;
2883
3004
  props.ignoreChildExtends = true;
2884
3005
  }
2885
- if (!props?.childProps && element.props?.childProps) {
2886
- props.childProps = element.props.childProps;
2887
- props.ignoreChildProps = true;
3006
+ const elementChildProps = element.childProps || element.props?.childProps;
3007
+ if (!props?.childProps && elementChildProps) {
3008
+ props.childProps = elementChildProps;
2888
3009
  }
3010
+ props.ignoreChildProps = true;
2889
3011
  }
2890
3012
  if (lazyLoad) {
2891
3013
  window.requestAnimationFrame(() => {
@@ -3495,6 +3617,34 @@ ${element}` : "";
3495
3617
  triggerEventOn("update", element, options);
3496
3618
  }
3497
3619
  };
3620
+ var findSiblingAttachOptions = (element, parent) => {
3621
+ const { __children } = parent.__ref || {};
3622
+ if (!__children) return false;
3623
+ const currentIndex = __children.indexOf(element.key);
3624
+ let previousNode;
3625
+ for (let i = currentIndex - 1; i >= 0; i--) {
3626
+ const sibling = parent[__children[i]];
3627
+ if (sibling?.node?.parentNode) {
3628
+ previousNode = sibling.node;
3629
+ break;
3630
+ }
3631
+ }
3632
+ if (previousNode) {
3633
+ return { position: "after", node: previousNode };
3634
+ }
3635
+ let nextNode;
3636
+ for (let i = currentIndex + 1; i < __children.length; i++) {
3637
+ const sibling = parent[__children[i]];
3638
+ if (sibling?.node?.parentNode) {
3639
+ nextNode = sibling.node;
3640
+ break;
3641
+ }
3642
+ }
3643
+ if (nextNode) {
3644
+ return { position: "before", node: nextNode };
3645
+ }
3646
+ return false;
3647
+ };
3498
3648
  var checkIfOnUpdate = (element, parent, options) => {
3499
3649
  if (!isFunction(element.if) && !isFunction(element.props?.if) || !parent) {
3500
3650
  return;
@@ -3531,16 +3681,7 @@ ${element}` : "";
3531
3681
  } else if (element[contentKey]?.parseDeep) {
3532
3682
  element[contentKey] = element[contentKey].parseDeep();
3533
3683
  }
3534
- const previousElement2 = element.previousElement();
3535
- const previousNode = previousElement2?.node;
3536
- const hasPrevious = previousNode?.parentNode;
3537
- const nextElement2 = element.nextElement();
3538
- const nextNode = nextElement2?.node;
3539
- const hasNext = nextNode?.parentNode;
3540
- const attachOptions = (hasPrevious || hasNext) && {
3541
- position: hasPrevious ? "after" : hasNext ? "before" : null,
3542
- node: hasPrevious && previousNode || hasNext && nextNode
3543
- };
3684
+ const attachOptions = findSiblingAttachOptions(element, parent);
3544
3685
  delete element.__ref;
3545
3686
  delete element.parent;
3546
3687
  const createdElement = create(
@@ -4649,7 +4790,9 @@ ${element}` : "";
4649
4790
  };
4650
4791
  var addElementIntoParentChildren = (element, parent) => {
4651
4792
  if (parent.__ref && parent.__ref.__children) {
4652
- parent.__ref.__children.push(element.key);
4793
+ if (!parent.__ref.__children.includes(element.key)) {
4794
+ parent.__ref.__children.push(element.key);
4795
+ }
4653
4796
  }
4654
4797
  };
4655
4798
  var _uniqIdCounter = 1;
@@ -51,7 +51,8 @@ const processFrameListeners = (frameListeners) => {
51
51
  }
52
52
 
53
53
  const startFrameLoop = (frameListeners) => {
54
- if (_frameRunning) return
54
+ const raf = typeof window !== 'undefined' && window.requestAnimationFrame
55
+ if (_frameRunning || !raf) return
55
56
  _frameRunning = true
56
57
 
57
58
  function requestFrame () {
@@ -60,10 +61,10 @@ const startFrameLoop = (frameListeners) => {
60
61
  return
61
62
  }
62
63
  processFrameListeners(frameListeners)
63
- window.requestAnimationFrame(requestFrame)
64
+ raf(requestFrame)
64
65
  }
65
66
 
66
- window.requestAnimationFrame(requestFrame)
67
+ raf(requestFrame)
67
68
  }
68
69
 
69
70
  export const applyAnimationFrame = element => {
package/mixins/html.js CHANGED
@@ -7,7 +7,7 @@ import { exec } from '@domql/utils'
7
7
  * an original one as a child
8
8
  */
9
9
  export function html (param, element, node) {
10
- const prop = exec(element?.props?.html || param, element)
10
+ const prop = exec(param ?? element?.props?.html, element)
11
11
  const { __ref } = element
12
12
  if (prop !== __ref.__html) {
13
13
  if (node.nodeName === 'SVG') node.textContent = prop
@@ -23,7 +23,9 @@ export const REGISTRY = {
23
23
  extends: {},
24
24
  children: {},
25
25
  content: {},
26
+ childExtend: {},
26
27
  childExtends: {},
28
+ childExtendRecursive: {},
27
29
  childExtendsRecursive: {},
28
30
  props: {},
29
31
  if: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@domql/element",
3
- "version": "3.5.1",
3
+ "version": "3.6.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "./dist/esm/index.js",
@@ -8,29 +8,23 @@
8
8
  "exports": {
9
9
  ".": {
10
10
  "import": "./dist/esm/index.js",
11
- "require": "./dist/cjs/index.js",
12
- "browser": "./dist/esm/index.js",
13
- "default": "./dist/esm/index.js"
11
+ "require": "./dist/cjs/index.js"
14
12
  },
15
13
  "./event": {
16
14
  "import": "./dist/esm/event/index.js",
17
- "require": "./dist/cjs/event/index.js",
18
- "default": "./dist/esm/event/index.js"
15
+ "require": "./dist/cjs/event/index.js"
19
16
  },
20
17
  "./render": {
21
18
  "import": "./dist/esm/render/index.js",
22
- "require": "./dist/cjs/render/index.js",
23
- "default": "./dist/esm/render/index.js"
19
+ "require": "./dist/cjs/render/index.js"
24
20
  },
25
21
  "./*.js": {
26
22
  "import": "./dist/esm/*.js",
27
- "require": "./dist/cjs/*.js",
28
- "default": "./dist/esm/*.js"
23
+ "require": "./dist/cjs/*.js"
29
24
  },
30
25
  "./*": {
31
26
  "import": "./dist/esm/*.js",
32
- "require": "./dist/cjs/*.js",
33
- "default": "./dist/esm/*.js"
27
+ "require": "./dist/cjs/*.js"
34
28
  }
35
29
  },
36
30
  "source": "index.js",
@@ -52,10 +46,10 @@
52
46
  "build:iife": "cross-env NODE_ENV=$NODE_ENV esbuild index.js --bundle --target=es2020 --format=iife --global-name=DomqlElement --outfile=dist/iife/index.js --define:process.env.NODE_ENV=process.env.NODE_ENV"
53
47
  },
54
48
  "dependencies": {
55
- "@domql/report": "^3.5.1",
56
- "@domql/state": "^3.5.1",
57
- "@domql/utils": "^3.5.1",
58
- "attrs-in-props": "^3.5.1"
49
+ "@domql/report": "^3.6.3",
50
+ "@domql/state": "^3.6.3",
51
+ "@domql/utils": "^3.6.3",
52
+ "attrs-in-props": "^3.6.3"
59
53
  },
60
54
  "gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
61
55
  "devDependencies": {
@@ -64,5 +58,8 @@
64
58
  "browser": "./dist/esm/index.js",
65
59
  "unpkg": "./dist/iife/index.js",
66
60
  "jsdelivr": "./dist/iife/index.js",
67
- "sideEffects": false
61
+ "sideEffects": false,
62
+ "publishConfig": {
63
+ "access": "public"
64
+ }
68
65
  }
package/set.js CHANGED
@@ -98,6 +98,20 @@ export const set = function (params, options = {}, el) {
98
98
  const element = el || this
99
99
  const { __ref: ref } = element
100
100
 
101
+ // Guard against infinite set loops
102
+ if (ref.__settingContent) return element
103
+ ref.__settingContent = true
104
+
105
+ try {
106
+ return _setInner(params, options, element)
107
+ } finally {
108
+ ref.__settingContent = false
109
+ }
110
+ }
111
+
112
+ const _setInner = function (params, options, element) {
113
+ const { __ref: ref } = element
114
+
101
115
  const contentElementKey = setContentKey(element, options)
102
116
  const content = element[contentElementKey]
103
117
  const __contentRef = content && content.__ref
@@ -130,21 +144,26 @@ export const set = function (params, options = {}, el) {
130
144
  return
131
145
  }
132
146
 
133
- if (!params) return element
147
+ if (!params || typeof params !== 'object') return element
134
148
 
135
149
  let { childExtends, props, tag } = params
136
150
  if (!props) props = params.props = {}
137
151
 
138
152
  if (tag === 'fragment') {
139
- if (!childExtends && element.childExtends) {
140
- params.childExtends = element.childExtends
153
+ const elementChildExtends = element.childExtends || element.childExtend
154
+ if (!childExtends && elementChildExtends) {
155
+ params.childExtends = elementChildExtends
141
156
  props.ignoreChildExtends = true
142
157
  }
143
158
 
144
- if (!props?.childProps && element.props?.childProps) {
145
- props.childProps = element.props.childProps
146
- props.ignoreChildProps = true
159
+ const elementChildProps = element.childProps || element.props?.childProps
160
+ if (!props?.childProps && elementChildProps) {
161
+ props.childProps = elementChildProps
147
162
  }
163
+
164
+ // Prevent the fragment from inheriting parent's childProps via inheritParentProps
165
+ // (childProps is already forwarded explicitly above for the fragment's children)
166
+ props.ignoreChildProps = true
148
167
  }
149
168
 
150
169
  if (lazyLoad) {
package/update.js CHANGED
@@ -288,6 +288,43 @@ export const update = function (params = {}, opts) {
288
288
  }
289
289
  }
290
290
 
291
+ const findSiblingAttachOptions = (element, parent) => {
292
+ const { __children } = parent.__ref || {}
293
+ if (!__children) return false
294
+
295
+ const currentIndex = __children.indexOf(element.key)
296
+
297
+ // Walk backwards to find nearest previous sibling with a DOM node
298
+ let previousNode
299
+ for (let i = currentIndex - 1; i >= 0; i--) {
300
+ const sibling = parent[__children[i]]
301
+ if (sibling?.node?.parentNode) {
302
+ previousNode = sibling.node
303
+ break
304
+ }
305
+ }
306
+
307
+ if (previousNode) {
308
+ return { position: 'after', node: previousNode }
309
+ }
310
+
311
+ // Walk forwards to find nearest next sibling with a DOM node
312
+ let nextNode
313
+ for (let i = currentIndex + 1; i < __children.length; i++) {
314
+ const sibling = parent[__children[i]]
315
+ if (sibling?.node?.parentNode) {
316
+ nextNode = sibling.node
317
+ break
318
+ }
319
+ }
320
+
321
+ if (nextNode) {
322
+ return { position: 'before', node: nextNode }
323
+ }
324
+
325
+ return false
326
+ }
327
+
291
328
  const checkIfOnUpdate = (element, parent, options) => {
292
329
  if ((!isFunction(element.if) && !isFunction(element.props?.if)) || !parent) {
293
330
  return
@@ -331,18 +368,7 @@ const checkIfOnUpdate = (element, parent, options) => {
331
368
  element[contentKey] = element[contentKey].parseDeep()
332
369
  }
333
370
 
334
- const previousElement = element.previousElement()
335
- const previousNode = previousElement?.node // document.body.contains(previousElement.node)
336
- const hasPrevious = previousNode?.parentNode // document.body.contains(previousElement.node)
337
-
338
- const nextElement = element.nextElement()
339
- const nextNode = nextElement?.node // document.body.contains(previousElement.node)
340
- const hasNext = nextNode?.parentNode
341
-
342
- const attachOptions = (hasPrevious || hasNext) && {
343
- position: hasPrevious ? 'after' : hasNext ? 'before' : null,
344
- node: (hasPrevious && previousNode) || (hasNext && nextNode)
345
- }
371
+ const attachOptions = findSiblingAttachOptions(element, parent)
346
372
 
347
373
  delete element.__ref
348
374
  delete element.parent