@domql/element 3.1.1 → 3.2.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.
Files changed (90) hide show
  1. package/README.md +4 -6
  2. package/__tests__/checkIfOnUpdate.test.js +12 -12
  3. package/__tests__/children.test.js +34 -38
  4. package/__tests__/inheritStateUpdates.test.js +12 -12
  5. package/__tests__/renderElement.test.js +11 -11
  6. package/__tests__/resetElement.test.js +6 -6
  7. package/__tests__/set.test.js +32 -36
  8. package/__tests__/throughExecProps.test.js +12 -12
  9. package/__tests__/throughInitialDefine.test.js +16 -16
  10. package/__tests__/throughInitialExec.test.js +16 -16
  11. package/__tests__/throughUpdatedDefine.test.js +14 -14
  12. package/__tests__/throughUpdatedExec.test.js +17 -16
  13. package/__tests__/update.test.js +54 -54
  14. package/children.js +5 -6
  15. package/create.js +18 -20
  16. package/dist/cjs/children.js +4 -2
  17. package/dist/cjs/create.js +16 -16
  18. package/dist/cjs/extend.js +88 -0
  19. package/dist/cjs/iterate.js +76 -20
  20. package/dist/cjs/mixins/content.js +73 -0
  21. package/dist/cjs/mixins/html.js +1 -1
  22. package/dist/cjs/mixins/registry.js +2 -2
  23. package/dist/cjs/mixins/scope.js +1 -1
  24. package/dist/cjs/mixins/state.js +2 -2
  25. package/dist/cjs/mixins/text.js +4 -4
  26. package/dist/cjs/node.js +15 -15
  27. package/dist/cjs/set.js +22 -27
  28. package/dist/cjs/update.js +24 -33
  29. package/dist/cjs/utils/applyParam.js +4 -4
  30. package/dist/cjs/utils/extendUtils.js +132 -0
  31. package/dist/cjs/utils/propEvents.js +39 -0
  32. package/dist/esm/children.js +5 -3
  33. package/dist/esm/create.js +16 -16
  34. package/dist/esm/extend.js +74 -0
  35. package/dist/esm/iterate.js +77 -22
  36. package/dist/esm/mixins/content.js +53 -0
  37. package/dist/esm/mixins/html.js +1 -1
  38. package/dist/esm/mixins/registry.js +1 -1
  39. package/dist/esm/mixins/scope.js +1 -1
  40. package/dist/esm/mixins/state.js +3 -3
  41. package/dist/esm/mixins/text.js +4 -4
  42. package/dist/esm/node.js +15 -15
  43. package/dist/esm/set.js +23 -28
  44. package/dist/esm/update.js +24 -33
  45. package/dist/esm/utils/applyParam.js +5 -5
  46. package/dist/esm/utils/extendUtils.js +119 -0
  47. package/dist/esm/utils/propEvents.js +19 -0
  48. package/extend.js +98 -0
  49. package/iterate.js +80 -25
  50. package/mixins/content.js +65 -0
  51. package/mixins/html.js +1 -1
  52. package/mixins/registry.js +1 -1
  53. package/mixins/scope.js +1 -1
  54. package/mixins/state.js +3 -3
  55. package/mixins/text.js +4 -4
  56. package/node.js +15 -15
  57. package/package.json +8 -8
  58. package/set.js +23 -28
  59. package/update.js +25 -34
  60. package/utils/applyParam.js +5 -5
  61. package/utils/extendUtils.js +149 -0
  62. package/utils/propEvents.js +19 -0
  63. package/dist/cjs/__tests__/checkIfOnUpdate.test.js +0 -73
  64. package/dist/cjs/__tests__/children.test.js +0 -177
  65. package/dist/cjs/__tests__/define.test.js +0 -75
  66. package/dist/cjs/__tests__/inheritStateUpdates.test.js +0 -62
  67. package/dist/cjs/__tests__/renderElement.test.js +0 -138
  68. package/dist/cjs/__tests__/resetElement.test.js +0 -35
  69. package/dist/cjs/__tests__/set.test.js +0 -256
  70. package/dist/cjs/__tests__/throughExecProps.test.js +0 -62
  71. package/dist/cjs/__tests__/throughInitialDefine.test.js +0 -79
  72. package/dist/cjs/__tests__/throughInitialExec.test.js +0 -73
  73. package/dist/cjs/__tests__/throughUpdatedDefine.test.js +0 -69
  74. package/dist/cjs/__tests__/throughUpdatedExec.test.js +0 -84
  75. package/dist/cjs/__tests__/tree.test.js +0 -11
  76. package/dist/cjs/__tests__/update.test.js +0 -222
  77. package/dist/esm/__tests__/checkIfOnUpdate.test.js +0 -73
  78. package/dist/esm/__tests__/children.test.js +0 -177
  79. package/dist/esm/__tests__/define.test.js +0 -53
  80. package/dist/esm/__tests__/inheritStateUpdates.test.js +0 -62
  81. package/dist/esm/__tests__/renderElement.test.js +0 -116
  82. package/dist/esm/__tests__/resetElement.test.js +0 -35
  83. package/dist/esm/__tests__/set.test.js +0 -256
  84. package/dist/esm/__tests__/throughExecProps.test.js +0 -62
  85. package/dist/esm/__tests__/throughInitialDefine.test.js +0 -79
  86. package/dist/esm/__tests__/throughInitialExec.test.js +0 -73
  87. package/dist/esm/__tests__/throughUpdatedDefine.test.js +0 -69
  88. package/dist/esm/__tests__/throughUpdatedExec.test.js +0 -84
  89. package/dist/esm/__tests__/tree.test.js +0 -11
  90. package/dist/esm/__tests__/update.test.js +0 -222
package/dist/esm/node.js CHANGED
@@ -12,7 +12,7 @@ import { applyParam } from "./utils/applyParam.js";
12
12
  import setChildren from "./children.js";
13
13
  import { setContent } from "./set.js";
14
14
  const ENV = "development";
15
- const createNode = async (element, opts) => {
15
+ const createNode = (element, opts) => {
16
16
  let { node, tag, __ref: ref } = element;
17
17
  if (!ref.__if) return element;
18
18
  let isNewNode;
@@ -21,42 +21,42 @@ const createNode = async (element, opts) => {
21
21
  if (tag === "shadow") {
22
22
  node = element.node = element.parent.node.attachShadow({ mode: "open" });
23
23
  } else node = element.node = cacheNode(element);
24
- await triggerEventOn("attachNode", element, opts);
24
+ triggerEventOn("attachNode", element, opts);
25
25
  }
26
26
  if (ENV === "test" || ENV === "development" || opts.alowRefReference) {
27
27
  node.ref = element;
28
28
  if (isFunction(node.setAttribute)) node.setAttribute("key", element.key);
29
29
  }
30
- await throughExecProps(element);
31
- await throughInitialDefine(element);
32
- await throughInitialExec(element);
33
- await applyEventsOnNode(element, { isNewNode, ...opts });
30
+ throughExecProps(element);
31
+ throughInitialDefine(element);
32
+ throughInitialExec(element);
33
+ applyEventsOnNode(element, { isNewNode, ...opts });
34
34
  for (const param in element) {
35
35
  const value = element[param];
36
36
  if (!Object.hasOwnProperty.call(element, param) || isUndefined(value) || isMethod(param, element) || isObject(REGISTRY[param])) {
37
37
  continue;
38
38
  }
39
- const isElement = await applyParam(param, element, opts);
39
+ const isElement = applyParam(param, element, opts);
40
40
  if (isElement) {
41
41
  const { hasDefine, hasContextDefine } = isElement;
42
42
  if (element[param] && !hasDefine && !hasContextDefine) {
43
- const createAsync = async () => {
44
- await create(value, element, param, opts);
43
+ const createAsync = () => {
44
+ create(value, element, param, opts);
45
45
  };
46
46
  if (element.props && element.props.lazyLoad || opts.lazyLoad) {
47
- window.requestAnimationFrame(async () => {
48
- await createAsync();
47
+ window.requestAnimationFrame(() => {
48
+ createAsync();
49
49
  if (!opts.preventUpdateListener) {
50
- await triggerEventOn("lazyLoad", element, opts);
50
+ triggerEventOn("lazyLoad", element, opts);
51
51
  }
52
52
  });
53
- } else await createAsync();
53
+ } else createAsync();
54
54
  }
55
55
  }
56
56
  }
57
- const content = element.children ? await setChildren(element.children, element, opts) : element.content || element.content;
57
+ const content = element.children ? setChildren(element.children, element, opts) : element.content || element.content;
58
58
  if (content) {
59
- await setContent(content, element, opts);
59
+ setContent(content, element, opts);
60
60
  }
61
61
  return element;
62
62
  };
package/dist/esm/set.js CHANGED
@@ -1,4 +1,4 @@
1
- import { deepContains, execPromise, isFunction, OPTIONS } from "@domql/utils";
1
+ import { deepContains, exec, isFunction, OPTIONS } from "@domql/utils";
2
2
  import { create } from "./create.js";
3
3
  import { triggerEventOn, triggerEventOnUpdate } from "@domql/event";
4
4
  const setContentKey = (element, opts = {}) => {
@@ -9,45 +9,40 @@ const setContentKey = (element, opts = {}) => {
9
9
  }
10
10
  return ref.contentElementKey;
11
11
  };
12
- const reset = async (options) => {
12
+ const reset = (options) => {
13
13
  const element = void 0;
14
- await create(element, element.parent, void 0, {
14
+ create(element, element.parent, void 0, {
15
15
  ignoreChildExtends: true,
16
16
  ...OPTIONS.defaultOptions,
17
17
  ...OPTIONS.create,
18
18
  ...options
19
19
  });
20
20
  };
21
- const resetContent = async (params, element, opts) => {
21
+ const resetContent = (params, element, opts) => {
22
22
  var _a;
23
23
  const contentElementKey = setContentKey(element, opts);
24
24
  if ((_a = element[contentElementKey]) == null ? void 0 : _a.node) removeContent(element, opts);
25
- const contentElem = await create(
26
- params,
27
- element,
28
- contentElementKey || "content",
29
- {
30
- ignoreChildExtends: true,
31
- ...OPTIONS.defaultOptions,
32
- ...OPTIONS.create,
33
- ...opts
34
- }
35
- );
25
+ const contentElem = create(params, element, contentElementKey || "content", {
26
+ ignoreChildExtends: true,
27
+ ...OPTIONS.defaultOptions,
28
+ ...OPTIONS.create,
29
+ ...opts
30
+ });
36
31
  if (contentElementKey !== "content") opts.contentElementKey = "content";
37
32
  return contentElem;
38
33
  };
39
- const updateContent = async function(params, opts) {
34
+ const updateContent = function(params, opts) {
40
35
  const element = this;
41
36
  const contentElementKey = setContentKey(element, opts);
42
37
  if (!element[contentElementKey]) return;
43
38
  if (element[contentElementKey].update) {
44
- await element[contentElementKey].update(params, opts);
39
+ element[contentElementKey].update(params, opts);
45
40
  }
46
41
  };
47
- async function setContent(param, element, opts) {
48
- const content = await execPromise(param, element);
42
+ function setContent(param, element, opts) {
43
+ const content = exec(param, element);
49
44
  if (content && element) {
50
- await set.call(element, content, opts);
45
+ set.call(element, content, opts);
51
46
  }
52
47
  }
53
48
  const removeContent = function(el, opts = {}) {
@@ -79,7 +74,7 @@ const removeContent = function(el, opts = {}) {
79
74
  }
80
75
  delete element[contentElementKey];
81
76
  };
82
- const set = async function(params, options = {}, el) {
77
+ const set = function(params, options = {}, el) {
83
78
  var _a;
84
79
  const element = el || this;
85
80
  const { __ref: ref } = element;
@@ -93,7 +88,7 @@ const set = async function(params, options = {}, el) {
93
88
  const childrenIsDifferentFromCache = childHasChanged && __contentRef && Object.keys(params).length === Object.keys(content).length && deepContains(params, content);
94
89
  if ((content == null ? void 0 : content.update) && !childHasChanged && !childrenIsDifferentFromCache) {
95
90
  if (!options.preventBeforeUpdateListener && !options.preventListeners) {
96
- const beforeUpdateReturns = await triggerEventOnUpdate(
91
+ const beforeUpdateReturns = triggerEventOnUpdate(
97
92
  "beforeUpdate",
98
93
  params,
99
94
  element,
@@ -101,9 +96,9 @@ const set = async function(params, options = {}, el) {
101
96
  );
102
97
  if (beforeUpdateReturns === false) return element;
103
98
  }
104
- await content.update(params);
99
+ content.update(params);
105
100
  if (!options.preventUpdateListener && !options.preventListeners) {
106
- await triggerEventOn("update", element, options);
101
+ triggerEventOn("update", element, options);
107
102
  }
108
103
  return;
109
104
  }
@@ -121,14 +116,14 @@ const set = async function(params, options = {}, el) {
121
116
  }
122
117
  }
123
118
  if (lazyLoad) {
124
- window.requestAnimationFrame(async () => {
125
- await resetContent(params, element, options);
119
+ window.requestAnimationFrame(() => {
120
+ resetContent(params, element, options);
126
121
  if (!options.preventUpdateListener) {
127
- await triggerEventOn("lazyLoad", element, options);
122
+ triggerEventOn("lazyLoad", element, options);
128
123
  }
129
124
  });
130
125
  } else {
131
- await resetContent(params, element, options);
126
+ resetContent(params, element, options);
132
127
  }
133
128
  };
134
129
  var set_default = set;
@@ -39,7 +39,7 @@ const UPDATE_DEFAULT_OPTIONS = {
39
39
  calleeElement: false,
40
40
  exclude: METHODS_EXL
41
41
  };
42
- const update = async function(params = {}, opts) {
42
+ const update = function(params = {}, opts) {
43
43
  const calleeElementCache = opts == null ? void 0 : opts.calleeElement;
44
44
  const options = deepClone(
45
45
  isObject(opts) ? deepMerge(opts, UPDATE_DEFAULT_OPTIONS) : UPDATE_DEFAULT_OPTIONS,
@@ -55,7 +55,7 @@ const update = async function(params = {}, opts) {
55
55
  );
56
56
  if (snapshotHasUpdated) return;
57
57
  if (!options.preventListeners) {
58
- await triggerEventOnUpdate("startUpdate", params, element, options);
58
+ triggerEventOnUpdate("startUpdate", params, element, options);
59
59
  }
60
60
  const { parent, node, key } = element;
61
61
  const { exclude, preventInheritAtCurrentState } = options;
@@ -67,9 +67,9 @@ const update = async function(params = {}, opts) {
67
67
  params = { text: params };
68
68
  }
69
69
  params = propertizeUpdate.call(element, params);
70
- const inheritState = await inheritStateUpdates(element, options);
70
+ const inheritState = inheritStateUpdates(element, options);
71
71
  if (inheritState === false) return;
72
- const ifFails = await checkIfOnUpdate(element, parent, options);
72
+ const ifFails = checkIfOnUpdate(element, parent, options);
73
73
  if (ifFails) return;
74
74
  if (ref.__if && !options.preventPropsUpdate) {
75
75
  const hasParentProps = parent.props && (parent.props[key] || parent.props.childProps);
@@ -79,7 +79,7 @@ const update = async function(params = {}, opts) {
79
79
  }
80
80
  if (!options.preventBeforeUpdateListener && !options.preventListeners) {
81
81
  const simulate = { ...params, ...element };
82
- const beforeUpdateReturns = await triggerEventOnUpdate(
82
+ const beforeUpdateReturns = triggerEventOnUpdate(
83
83
  "beforeUpdate",
84
84
  params,
85
85
  simulate,
@@ -92,7 +92,7 @@ const update = async function(params = {}, opts) {
92
92
  throughUpdatedExec(element, { ignore: UPDATE_DEFAULT_OPTIONS });
93
93
  throughUpdatedDefine(element);
94
94
  if (!options.isForced && !options.preventListeners) {
95
- await triggerEventOn("beforeClassAssign", element, options);
95
+ triggerEventOn("beforeClassAssign", element, options);
96
96
  }
97
97
  if (!ref.__if) return false;
98
98
  if (!node) {
@@ -124,7 +124,7 @@ const update = async function(params = {}, opts) {
124
124
  continue;
125
125
  }
126
126
  if (preventStateUpdate === "once") options.preventStateUpdate = false;
127
- const isElement = await applyParam(param, element, options);
127
+ const isElement = applyParam(param, element, options);
128
128
  if (isElement) {
129
129
  const { hasDefine, hasContextDefine } = isElement;
130
130
  const canUpdate = isObject(prop) && !hasDefine && !hasContextDefine && !preventRecursive;
@@ -133,33 +133,33 @@ const update = async function(params = {}, opts) {
133
133
  if (options.onEachUpdate) {
134
134
  options.onEachUpdate(param, element, element.state, element.context);
135
135
  }
136
- const childUpdateCall = async () => await update.call(prop, params[prop], {
136
+ const childUpdateCall = () => update.call(prop, params[prop], {
137
137
  ...options,
138
138
  currentSnapshot: snapshotOnCallee,
139
139
  calleeElement
140
140
  });
141
141
  if (lazyLoad) {
142
- window.requestAnimationFrame(async () => {
143
- await childUpdateCall();
142
+ window.requestAnimationFrame(() => {
143
+ childUpdateCall();
144
144
  if (!options.preventUpdateListener) {
145
- await triggerEventOn("lazyLoad", element, options);
145
+ triggerEventOn("lazyLoad", element, options);
146
146
  }
147
147
  });
148
- } else await childUpdateCall();
148
+ } else childUpdateCall();
149
149
  }
150
150
  }
151
151
  if (!preventContentUpdate) {
152
152
  const children = params.children || element.children;
153
- const content = children ? await setChildren(children, element, opts) : element.children || params.content;
153
+ const content = children ? setChildren(children, element, opts) : element.children || params.content;
154
154
  if (content) {
155
- await setContent(content, element, options);
155
+ setContent(content, element, options);
156
156
  }
157
157
  }
158
158
  if (!preventUpdateListener) {
159
- await triggerEventOn("update", element, options);
159
+ triggerEventOn("update", element, options);
160
160
  }
161
161
  };
162
- const checkIfOnUpdate = async (element, parent, options) => {
162
+ const checkIfOnUpdate = (element, parent, options) => {
163
163
  var _a, _b, _c;
164
164
  if (!isFunction(element.if) && !isFunction((_a = element.props) == null ? void 0 : _a.if) || !parent) {
165
165
  return;
@@ -208,7 +208,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
208
208
  };
209
209
  delete element.__ref;
210
210
  delete element.parent;
211
- const createdElement = await create(
211
+ const createdElement = create(
212
212
  element,
213
213
  parent,
214
214
  element.key,
@@ -216,11 +216,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
216
216
  attachOptions
217
217
  );
218
218
  if (options.preventUpdate !== true && element.on && isFunction(element.on.update)) {
219
- await applyEvent(
220
- element.on.update,
221
- createdElement,
222
- createdElement.state
223
- );
219
+ applyEvent(element.on.update, createdElement, createdElement.state);
224
220
  }
225
221
  return createdElement;
226
222
  }
@@ -229,7 +225,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
229
225
  delete ref.__if;
230
226
  }
231
227
  };
232
- const inheritStateUpdates = async (element, options) => {
228
+ const inheritStateUpdates = (element, options) => {
233
229
  const { __ref: ref } = element;
234
230
  const stateKey = ref.__state;
235
231
  const { parent, state } = element;
@@ -253,7 +249,7 @@ const inheritStateUpdates = async (element, options) => {
253
249
  const keyInParentState = findInheritedState(element, element.parent);
254
250
  if (!keyInParentState || options.preventInheritedStateUpdate) return;
255
251
  if (!options.preventBeforeStateUpdateListener && !options.preventListeners) {
256
- const initStateReturns = await triggerEventOnUpdate(
252
+ const initStateReturns = triggerEventOnUpdate(
257
253
  "beforeStateUpdate",
258
254
  keyInParentState,
259
255
  element,
@@ -261,19 +257,14 @@ const inheritStateUpdates = async (element, options) => {
261
257
  );
262
258
  if (initStateReturns === false) return element;
263
259
  }
264
- const newState = await createStateUpdate(element, parent, options);
260
+ const newState = createStateUpdate(element, parent, options);
265
261
  if (!options.preventStateUpdateListener && !options.preventListeners) {
266
- await triggerEventOnUpdate(
267
- "stateUpdate",
268
- newState.parse(),
269
- element,
270
- options
271
- );
262
+ triggerEventOnUpdate("stateUpdate", newState.parse(), element, options);
272
263
  }
273
264
  };
274
- const createStateUpdate = async (element, parent, options) => {
265
+ const createStateUpdate = (element, parent, options) => {
275
266
  const __stateChildren = element.state.__children;
276
- const newState = await createState(element, parent);
267
+ const newState = createState(element, parent);
277
268
  element.state = newState;
278
269
  for (const child in __stateChildren) {
279
270
  if (newState[child]) newState.__children[child] = __stateChildren[child];
@@ -1,8 +1,8 @@
1
- import { isFunction } from "@domql/utils";
1
+ import { exec, isFunction } from "@domql/utils";
2
2
  import { REGISTRY } from "../mixins/index.js";
3
- const applyParam = async (param, element, options) => {
3
+ const applyParam = (param, element, options) => {
4
4
  const { node, context, __ref: ref } = element;
5
- const prop = element[param];
5
+ const prop = exec(element[param], element);
6
6
  const { onlyUpdate } = options;
7
7
  const DOMQLProperty = REGISTRY[param];
8
8
  const DOMQLPropertyFromContext = context && context.registry && context.registry[param];
@@ -13,9 +13,9 @@ const applyParam = async (param, element, options) => {
13
13
  const hasOnlyUpdate = onlyUpdate ? onlyUpdate === param || element.lookup(onlyUpdate) : true;
14
14
  if (isGlobalTransformer && !hasContextDefine && hasOnlyUpdate) {
15
15
  if (isFunction(isGlobalTransformer)) {
16
- await isGlobalTransformer(prop, element, node, options);
17
- return;
16
+ isGlobalTransformer(prop, element, node, options);
18
17
  }
18
+ return;
19
19
  }
20
20
  return { hasDefine, hasContextDefine };
21
21
  };
@@ -0,0 +1,119 @@
1
+ import {
2
+ isArray,
3
+ isFunction,
4
+ isObject,
5
+ isString,
6
+ deepClone,
7
+ isNotProduction
8
+ } from "@domql/utils";
9
+ const generateHash = () => Math.random().toString(36).substring(2);
10
+ const extendStackRegistry = {};
11
+ const extendCachedRegistry = {};
12
+ const getHashedExtend = (extend) => {
13
+ return extendStackRegistry[extend.__hash];
14
+ };
15
+ const setHashedExtend = (extend, stack) => {
16
+ const hash = generateHash();
17
+ if (!isString(extend)) {
18
+ extend.__hash = hash;
19
+ }
20
+ extendStackRegistry[hash] = stack;
21
+ return stack;
22
+ };
23
+ const getExtendStackRegistry = (extend, stack) => {
24
+ if (extend.__hash) {
25
+ return stack.concat(getHashedExtend(extend));
26
+ }
27
+ return setHashedExtend(extend, stack);
28
+ };
29
+ const extractArrayExtend = (extend, stack, context) => {
30
+ extend.forEach((each) => flattenExtend(each, stack, context));
31
+ return stack;
32
+ };
33
+ const deepExtend = (extend, stack, context) => {
34
+ const extendOflattenExtend = extend.extend;
35
+ if (extendOflattenExtend) {
36
+ flattenExtend(extendOflattenExtend, stack, context);
37
+ }
38
+ return stack;
39
+ };
40
+ const flattenExtend = (extend, stack, context) => {
41
+ if (!extend) return stack;
42
+ if (isArray(extend)) return extractArrayExtend(extend, stack, context);
43
+ if (isString(extend)) extend = fallbackStringExtend(extend, context);
44
+ stack.push(extend);
45
+ if (extend.extend) deepExtend(extend, stack, context);
46
+ return stack;
47
+ };
48
+ const deepMergeExtend = (element, extend) => {
49
+ for (const e in extend) {
50
+ if (["parent", "node", "__element"].indexOf(e) > -1) continue;
51
+ const elementProp = element[e];
52
+ const extendProp = extend[e];
53
+ if (elementProp === void 0) {
54
+ element[e] = extendProp;
55
+ } else if (isObject(elementProp) && isObject(extendProp)) {
56
+ deepMergeExtend(elementProp, extendProp);
57
+ } else if (isArray(elementProp) && isArray(extendProp)) {
58
+ element[e] = elementProp.concat(extendProp);
59
+ } else if (isArray(elementProp) && isObject(extendProp)) {
60
+ const obj = deepMergeExtend({}, elementProp);
61
+ element[e] = deepMergeExtend(obj, extendProp);
62
+ } else if (elementProp === void 0 && isFunction(extendProp)) {
63
+ element[e] = extendProp;
64
+ }
65
+ }
66
+ return element;
67
+ };
68
+ const cloneAndMergeArrayExtend = (stack) => {
69
+ return stack.reduce((a, c) => {
70
+ return deepMergeExtend(a, deepClone(c));
71
+ }, {});
72
+ };
73
+ const fallbackStringExtend = (extend, context, options = {}, variant) => {
74
+ const COMPONENTS = context && context.components || options.components;
75
+ const PAGES = context && context.pages || options.pages;
76
+ if (isString(extend)) {
77
+ const componentExists = COMPONENTS && (COMPONENTS[extend + "." + variant] || COMPONENTS[extend] || COMPONENTS["smbls." + extend]);
78
+ const pageExists = PAGES && extend.startsWith("/") && PAGES[extend];
79
+ if (componentExists) return componentExists;
80
+ else if (pageExists) return pageExists;
81
+ else {
82
+ if (options.verbose && isNotProduction()) {
83
+ console.warn("Extend is string but component was not found:", extend);
84
+ }
85
+ return {};
86
+ }
87
+ }
88
+ return extend;
89
+ };
90
+ const jointStacks = (extendStack, childExtendStack) => {
91
+ return [].concat(extendStack.slice(0, 1)).concat(childExtendStack.slice(0, 1)).concat(extendStack.slice(1)).concat(childExtendStack.slice(1));
92
+ };
93
+ const getExtendStack = (extend, context) => {
94
+ if (!extend) return [];
95
+ if (extend.__hash) return getHashedExtend(extend) || [];
96
+ const stack = flattenExtend(extend, [], context);
97
+ return getExtendStackRegistry(extend, stack);
98
+ };
99
+ const getExtendMerged = (extend) => {
100
+ const stack = getExtendStack(extend);
101
+ return cloneAndMergeArrayExtend(stack);
102
+ };
103
+ export {
104
+ cloneAndMergeArrayExtend,
105
+ deepExtend,
106
+ deepMergeExtend,
107
+ extendCachedRegistry,
108
+ extendStackRegistry,
109
+ extractArrayExtend,
110
+ fallbackStringExtend,
111
+ flattenExtend,
112
+ generateHash,
113
+ getExtendMerged,
114
+ getExtendStack,
115
+ getExtendStackRegistry,
116
+ getHashedExtend,
117
+ jointStacks,
118
+ setHashedExtend
119
+ };
@@ -0,0 +1,19 @@
1
+ import { isFunction, lowercaseFirstLetter } from "@domql/utils";
2
+ const propagateEventsFromProps = (element) => {
3
+ const { props, on } = element;
4
+ const eventKeysFromProps = Object.keys(props).filter((key) => key.startsWith("on"));
5
+ eventKeysFromProps.forEach((v) => {
6
+ const eventName = lowercaseFirstLetter(v.split("on")[1]);
7
+ const origEvent = on[eventName];
8
+ const funcFromProps = props[v];
9
+ if (isFunction(origEvent)) {
10
+ on[eventName] = (...args) => {
11
+ const originalEventRetunrs = origEvent(...args);
12
+ if (originalEventRetunrs !== false) return funcFromProps(...args);
13
+ };
14
+ } else on[eventName] = funcFromProps;
15
+ });
16
+ };
17
+ export {
18
+ propagateEventsFromProps
19
+ };
package/extend.js ADDED
@@ -0,0 +1,98 @@
1
+ 'use strict'
2
+
3
+ import { isFunction, exec, isProduction } from '@domql/utils'
4
+ import {
5
+ getExtendStack,
6
+ jointStacks,
7
+ cloneAndMergeArrayExtend,
8
+ deepMergeExtend,
9
+ fallbackStringExtend
10
+ } from './utils/index.js'
11
+
12
+ let mainExtend
13
+
14
+ /**
15
+ * Checks whether element has `extend` or is a part
16
+ * of parent's `childExtend` extend
17
+ */
18
+ export const applyExtend = (element, parent, options = {}) => {
19
+ if (isFunction(element)) element = exec(element, parent)
20
+
21
+ const { props, __ref } = element
22
+ let extend = props?.extends || element.extends || element.extend
23
+ const variant = props?.variant
24
+ const context = element.context || parent.context
25
+
26
+ extend = fallbackStringExtend(extend, context, options, variant)
27
+
28
+ const extendStack = getExtendStack(extend, context)
29
+
30
+ // if (isProduction()) delete element.extend
31
+ delete element.extend
32
+
33
+ let childExtendStack = []
34
+ if (parent) {
35
+ element.parent = parent
36
+ // Assign parent attr to the element
37
+ if (!options.ignoreChildExtend && !(props && props.ignoreChildExtend)) {
38
+ childExtendStack = getExtendStack(parent.childExtend, context)
39
+
40
+ // if (!options.ignoreChildExtend && !(props && exec(props, element).ignoreChildExtend)) {
41
+ // const ignoreChildExtendRecursive = props && exec(props, element).ignoreChildExtendRecursive
42
+
43
+ const ignoreChildExtendRecursive =
44
+ props && props.ignoreChildExtendRecursive
45
+ if (parent.childExtendRecursive && !ignoreChildExtendRecursive) {
46
+ const canExtendRecursive = element.key !== '__text'
47
+ if (canExtendRecursive) {
48
+ const childExtendRecursiveStack = getExtendStack(
49
+ parent.childExtendRecursive,
50
+ context
51
+ )
52
+ // add error if childExtendRecursive contains element which goes to infinite loop
53
+ childExtendStack = childExtendStack.concat(childExtendRecursiveStack)
54
+ element.childExtendRecursive = parent.childExtendRecursive
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ const extendLength = extendStack.length
61
+ const childExtendLength = childExtendStack.length
62
+
63
+ let stack = []
64
+ if (extendLength && childExtendLength) {
65
+ stack = jointStacks(extendStack, childExtendStack)
66
+ } else if (extendLength) {
67
+ stack = extendStack
68
+ } else if (childExtendLength) {
69
+ stack = childExtendStack
70
+ } else if (!context.defaultExtends) return element
71
+
72
+ if (context.defaultExtends) {
73
+ if (!mainExtend) {
74
+ const defaultOptionsExtend = getExtendStack(
75
+ context.defaultExtends,
76
+ context
77
+ )
78
+ mainExtend = cloneAndMergeArrayExtend(defaultOptionsExtend)
79
+ delete mainExtend.extend
80
+ }
81
+ stack = [].concat(stack, mainExtend)
82
+ }
83
+
84
+ if (__ref) __ref.__extend = stack
85
+ let mergedExtend = cloneAndMergeArrayExtend(stack)
86
+
87
+ const COMPONENTS = (context && context.components) || options.components
88
+ const component = exec(element.component || mergedExtend.component, element)
89
+ if (component && COMPONENTS && COMPONENTS[component]) {
90
+ const componentExtend = cloneAndMergeArrayExtend(
91
+ getExtendStack(COMPONENTS[component])
92
+ )
93
+ mergedExtend = deepMergeExtend(componentExtend, mergedExtend)
94
+ }
95
+
96
+ const merged = deepMergeExtend(element, mergedExtend)
97
+ return merged
98
+ }