@iamproperty/components 7.8.2--beta1 → 7.8.2--beta3

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 (169) hide show
  1. package/assets/css/components/actionbar.component.css +1 -1
  2. package/assets/css/components/actionbar.component.css.map +1 -1
  3. package/assets/css/components/applied-filters.css +1 -1
  4. package/assets/css/components/applied-filters.css.map +1 -1
  5. package/assets/css/components/calendar.component.css +1 -1
  6. package/assets/css/components/calendar.component.css.map +1 -1
  7. package/assets/css/components/modal.component.css +1 -1
  8. package/assets/css/components/modal.component.css.map +1 -1
  9. package/assets/css/components/tabs.component.css +1 -1
  10. package/assets/css/components/tabs.component.css.map +1 -1
  11. package/assets/css/components/video-card.component.css +1 -1
  12. package/assets/css/components/video-card.component.css.map +1 -1
  13. package/assets/css/components/video-modal.component.css +1 -1
  14. package/assets/css/components/video-modal.component.css.map +1 -1
  15. package/assets/css/core.min.css +1 -1
  16. package/assets/css/core.min.css.map +1 -1
  17. package/assets/css/elements/badge-tag.css +1 -1
  18. package/assets/css/elements/badge-tag.css.map +1 -1
  19. package/assets/css/style.min.css +1 -1
  20. package/assets/css/style.min.css.map +1 -1
  21. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  22. package/assets/js/components/actionbar/actionbar.component.min.js +2 -2
  23. package/assets/js/components/address-lookup/address-lookup.component.min.js +3 -3
  24. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  25. package/assets/js/components/advanced-select/advanced-select.component.min.js +3 -3
  26. package/assets/js/components/advanced-select/advanced-select.component.min.js.map +1 -1
  27. package/assets/js/components/applied-filters/applied-filters.component.min.js +2 -2
  28. package/assets/js/components/banner/banner.component.min.js +1 -1
  29. package/assets/js/components/barchart/barchart.component.min.js +1 -1
  30. package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
  31. package/assets/js/components/bone/bone.component.min.js +1 -1
  32. package/assets/js/components/button/button.component.min.js +1 -1
  33. package/assets/js/components/calendar/calendar.component.min.js +2 -2
  34. package/assets/js/components/card/card.component.min.js +6 -6
  35. package/assets/js/components/card/card.component.min.js.map +1 -1
  36. package/assets/js/components/carousel/carousel.component.min.js +1 -1
  37. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  38. package/assets/js/components/config/config.component.min.js +1 -1
  39. package/assets/js/components/content/content.component.min.js +1 -1
  40. package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
  41. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +1 -1
  42. package/assets/js/components/fileupload/fileupload.component.min.js +1 -1
  43. package/assets/js/components/filter-card/filter-card.component.min.js +4 -4
  44. package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
  45. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  46. package/assets/js/components/form/form.component.min.js +1 -1
  47. package/assets/js/components/header/header.component.min.js +1 -1
  48. package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
  49. package/assets/js/components/input/input.component.min.js +1 -1
  50. package/assets/js/components/input-range/input-range.component.min.js +1 -1
  51. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  52. package/assets/js/components/menu/menu.component.min.js +1 -1
  53. package/assets/js/components/milestone/milestone.component.min.js +1 -1
  54. package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
  55. package/assets/js/components/modal/modal.component.min.js +2 -2
  56. package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
  57. package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js +1 -1
  58. package/assets/js/components/multiselect/multiselect.component.js +14 -1
  59. package/assets/js/components/multiselect/multiselect.component.min.js +3 -3
  60. package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
  61. package/assets/js/components/nav/nav.component.min.js +1 -1
  62. package/assets/js/components/notification/notification.component.min.js +1 -1
  63. package/assets/js/components/pagination/pagination.component.min.js +1 -1
  64. package/assets/js/components/password/password.component.min.js +1 -1
  65. package/assets/js/components/popover/popover.component.min.js +1 -1
  66. package/assets/js/components/rank/rank.component.min.js +1 -1
  67. package/assets/js/components/rankings/rankings.component.min.js +1 -1
  68. package/assets/js/components/rating/rating.component.min.js +1 -1
  69. package/assets/js/components/record-card/record-card.component.min.js +4 -4
  70. package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
  71. package/assets/js/components/search/search.component.min.js +5 -5
  72. package/assets/js/components/search/search.component.min.js.map +1 -1
  73. package/assets/js/components/skeleton/skeleton.component.min.js +1 -1
  74. package/assets/js/components/slider/slider.component.min.js +1 -1
  75. package/assets/js/components/split-button/split-button.component.min.js +1 -1
  76. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +4 -4
  77. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
  78. package/assets/js/components/std-nav/std-nav.component.min.js +1 -1
  79. package/assets/js/components/std-nav-standalone/std-nav-standalone.component.min.js +1 -1
  80. package/assets/js/components/table/table.component.min.js +1 -1
  81. package/assets/js/components/table-ajax/table-ajax.component.min.js +1 -1
  82. package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
  83. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
  84. package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
  85. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  86. package/assets/js/components/tag/tag.component.min.js +1 -1
  87. package/assets/js/components/tooltip/tooltip.component.min.js +1 -1
  88. package/assets/js/components/video/video.component.min.js +1 -1
  89. package/assets/js/components/video-card/video-card.component.min.js +6 -6
  90. package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
  91. package/assets/js/components/video-modal/video-modal.component.min.js +2 -2
  92. package/assets/js/components/word-count/word-count.component.min.js +1 -1
  93. package/assets/js/modules/advanced-select.js +6 -3
  94. package/assets/js/modules/advanced-select.test.js +28 -0
  95. package/assets/js/modules/applied-filters.test.js +21 -0
  96. package/assets/js/modules/card.module.js +3 -2
  97. package/assets/js/modules/card.module.test.js +20 -0
  98. package/assets/js/modules/carousel.test.js +18 -0
  99. package/assets/js/modules/chart.module.test.js +22 -0
  100. package/assets/js/modules/chart.test.js +15 -0
  101. package/assets/js/modules/content.test.js +20 -0
  102. package/assets/js/modules/data-layer.test.js +12 -0
  103. package/assets/js/modules/dialogs.test.js +13 -0
  104. package/assets/js/modules/drawer.test.js +16 -0
  105. package/assets/js/modules/dropdown.test.js +31 -0
  106. package/assets/js/modules/dynamicEvents.test.js +19 -0
  107. package/assets/js/modules/fileupload.test.js +17 -0
  108. package/assets/js/modules/filterlist.test.js +18 -0
  109. package/assets/js/modules/{helper.test.js → helpers.test.js} +42 -2
  110. package/assets/js/modules/integration-tests.test.js +12 -0
  111. package/assets/js/modules/milestone-group.test.js +18 -0
  112. package/assets/js/modules/milestone.test.js +31 -0
  113. package/assets/js/modules/modal.test.js +18 -0
  114. package/assets/js/modules/nav.test.js +37 -0
  115. package/assets/js/modules/notification.test.js +11 -0
  116. package/assets/js/modules/orderablelist.test.js +15 -0
  117. package/assets/js/modules/pagination.test.js +21 -0
  118. package/assets/js/modules/password.test.js +33 -0
  119. package/assets/js/modules/table.test.js +42 -0
  120. package/assets/js/modules/tabs.test.js +23 -0
  121. package/assets/js/modules/test-dom.js +725 -0
  122. package/assets/js/modules/test-globals.js +7 -0
  123. package/assets/js/modules/test-utils.js +26 -0
  124. package/assets/js/modules/test.js +20 -1
  125. package/assets/js/modules/testimonial.test.js +14 -0
  126. package/assets/js/modules/videos.test.js +37 -0
  127. package/assets/js/scripts.bundle.js +1 -1
  128. package/assets/js/scripts.bundle.min.js +1 -1
  129. package/assets/sass/components/modal.component.scss +1 -2
  130. package/assets/sass/elements/badge-tag.css +1 -1
  131. package/assets/sass/utilities/border.css +1 -1
  132. package/assets/ts/components/multiselect/multiselect.component.ts +20 -1
  133. package/assets/ts/modules/advanced-select.test.ts +33 -0
  134. package/assets/ts/modules/advanced-select.ts +6 -2
  135. package/assets/ts/modules/applied-filters.test.ts +25 -0
  136. package/assets/ts/modules/card.module.test.ts +24 -0
  137. package/assets/ts/modules/card.module.ts +2 -1
  138. package/assets/ts/modules/carousel.test.ts +27 -0
  139. package/assets/ts/modules/chart.module.test.ts +26 -0
  140. package/assets/ts/modules/chart.test.ts +19 -0
  141. package/assets/ts/modules/content.test.ts +24 -0
  142. package/assets/ts/modules/data-layer.test.ts +15 -0
  143. package/assets/ts/modules/dialogs.test.ts +17 -0
  144. package/assets/ts/modules/drawer.test.ts +20 -0
  145. package/assets/ts/modules/dropdown.test.ts +38 -0
  146. package/assets/ts/modules/dynamicEvents.test.ts +23 -0
  147. package/assets/ts/modules/fileupload.test.ts +21 -0
  148. package/assets/ts/modules/filterlist.test.ts +22 -0
  149. package/assets/ts/modules/{helper.test.ts → helpers.test.ts} +63 -2
  150. package/assets/ts/modules/integration-tests.test.ts +15 -0
  151. package/assets/ts/modules/milestone-group.test.ts +22 -0
  152. package/assets/ts/modules/milestone.test.ts +35 -0
  153. package/assets/ts/modules/modal.test.ts +22 -0
  154. package/assets/ts/modules/nav.test.ts +41 -0
  155. package/assets/ts/modules/notification.test.ts +15 -0
  156. package/assets/ts/modules/orderablelist.test.ts +19 -0
  157. package/assets/ts/modules/pagination.test.ts +25 -0
  158. package/assets/ts/modules/password.test.ts +40 -0
  159. package/assets/ts/modules/table.test.ts +57 -0
  160. package/assets/ts/modules/tabs.test.ts +27 -0
  161. package/assets/ts/modules/test-dom.ts +798 -0
  162. package/assets/ts/modules/test-globals.ts +7 -0
  163. package/assets/ts/modules/test-utils.ts +29 -0
  164. package/assets/ts/modules/test.ts +28 -1
  165. package/assets/ts/modules/testimonial.test.ts +17 -0
  166. package/assets/ts/modules/videos.test.ts +33 -0
  167. package/dist/components.es.js +24 -24
  168. package/dist/components.umd.js +113 -113
  169. package/package.json +1 -1
@@ -0,0 +1,798 @@
1
+ /* eslint-disable */
2
+
3
+ const toKebab = (value) => value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
4
+ const toDatasetKey = (value) => value.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
5
+
6
+ const splitSelector = (selector, separator = ',') => {
7
+ const parts = [];
8
+ let current = '';
9
+ let depth = 0;
10
+ let quote = '';
11
+
12
+ for (const char of selector) {
13
+ if (quote) {
14
+ current += char;
15
+ if (char === quote) quote = '';
16
+ continue;
17
+ }
18
+
19
+ if (char === '"' || char === "'") {
20
+ quote = char;
21
+ current += char;
22
+ continue;
23
+ }
24
+
25
+ if (char === '(' || char === '[') depth++;
26
+ if (char === ')' || char === ']') depth--;
27
+
28
+ if (char === separator && depth === 0) {
29
+ parts.push(current.trim());
30
+ current = '';
31
+ continue;
32
+ }
33
+
34
+ current += char;
35
+ }
36
+
37
+ if (current.trim()) parts.push(current.trim());
38
+
39
+ return parts;
40
+ };
41
+
42
+ const splitTokens = (selector) => {
43
+ const tokens = [];
44
+ let current = '';
45
+ let depth = 0;
46
+ let quote = '';
47
+
48
+ for (const char of selector.trim()) {
49
+ if (quote) {
50
+ current += char;
51
+ if (char === quote) quote = '';
52
+ continue;
53
+ }
54
+
55
+ if (char === '"' || char === "'") {
56
+ quote = char;
57
+ current += char;
58
+ continue;
59
+ }
60
+
61
+ if (char === '(' || char === '[') depth++;
62
+ if (char === ')' || char === ']') depth--;
63
+
64
+ if (depth === 0 && (char === ' ' || char === '>')) {
65
+ if (current.trim()) tokens.push(current.trim());
66
+ if (char === '>') tokens.push('>');
67
+ current = '';
68
+ continue;
69
+ }
70
+
71
+ current += char;
72
+ }
73
+
74
+ if (current.trim()) tokens.push(current.trim());
75
+
76
+ return tokens;
77
+ };
78
+
79
+ const stripQuotes = (value) => value.replace(/^["']|["']$/g, '');
80
+
81
+ class TestClassList {
82
+ constructor(element) {
83
+ this.element = element;
84
+ this.items = new Set();
85
+ }
86
+
87
+ add(...classes) {
88
+ classes.filter(Boolean).forEach((className) => this.items.add(className));
89
+ this.sync();
90
+ }
91
+
92
+ remove(...classes) {
93
+ classes.forEach((className) => this.items.delete(className));
94
+ this.sync();
95
+ }
96
+
97
+ contains(className) {
98
+ return this.items.has(className);
99
+ }
100
+
101
+ toggle(className, force) {
102
+ if (force === true) {
103
+ this.add(className);
104
+ return true;
105
+ }
106
+
107
+ if (force === false) {
108
+ this.remove(className);
109
+ return false;
110
+ }
111
+
112
+ if (this.contains(className)) {
113
+ this.remove(className);
114
+ return false;
115
+ }
116
+
117
+ this.add(className);
118
+ return true;
119
+ }
120
+
121
+ setFromString(value) {
122
+ this.items = new Set(String(value || '').split(/\s+/).filter(Boolean));
123
+ this.sync();
124
+ }
125
+
126
+ toString() {
127
+ return Array.from(this.items).join(' ');
128
+ }
129
+
130
+ sync() {
131
+ this.element.attributes.class = this.toString();
132
+ }
133
+ }
134
+
135
+ class TestStyle {
136
+ constructor() {
137
+ this.properties = {};
138
+ }
139
+
140
+ setProperty(name, value) {
141
+ this.properties[name] = String(value);
142
+ }
143
+
144
+ getPropertyValue(name) {
145
+ return this.properties[name] || '';
146
+ }
147
+
148
+ toString() {
149
+ return Object.entries(this.properties)
150
+ .map(([name, value]) => `${name}: ${value};`)
151
+ .join(' ');
152
+ }
153
+ }
154
+
155
+ export class TestElement extends EventTarget {
156
+ constructor(tagName = 'div') {
157
+ super();
158
+ this.tagName = tagName.toUpperCase();
159
+ this.nodeName = this.tagName;
160
+ this.localName = tagName.toLowerCase();
161
+ this.attributes = {};
162
+ this.dataset = {};
163
+ this.children = [];
164
+ this.parentNode = null;
165
+ this.parentElement = null;
166
+ this.classList = new TestClassList(this);
167
+ this.style = new TestStyle();
168
+ this.shadowRoot = null;
169
+ this._innerHTML = '';
170
+ this._textContent = '';
171
+ this.value = '';
172
+ this.checked = false;
173
+ this.disabled = false;
174
+ this.open = false;
175
+ this.selectedIndex = 0;
176
+ this.scrollLeft = 0;
177
+ this.scrollTop = 0;
178
+ this.scrollWidth = 0;
179
+ this.scrollHeight = 0;
180
+ this.clientWidth = 0;
181
+ this.clientHeight = 0;
182
+ this.offsetWidth = 0;
183
+ this.offsetHeight = 0;
184
+ this.offsetLeft = 0;
185
+ this.files = [];
186
+ this._rect = { left: 0, right: 0, top: 0, bottom: 0, width: 0, height: 0 };
187
+ }
188
+
189
+ get id() {
190
+ return this.getAttribute('id') || '';
191
+ }
192
+
193
+ set id(value) {
194
+ this.setAttribute('id', value);
195
+ }
196
+
197
+ get className() {
198
+ return this.classList.toString();
199
+ }
200
+
201
+ set className(value) {
202
+ this.classList.setFromString(value);
203
+ }
204
+
205
+ get textContent() {
206
+ if (this._textContent) return this._textContent;
207
+ if (this.children.length) return this.children.map((child) => child.textContent).join('');
208
+ return this._innerHTML.replace(/<[^>]+>/g, '');
209
+ }
210
+
211
+ set textContent(value) {
212
+ this._textContent = String(value);
213
+ this._innerHTML = String(value);
214
+ }
215
+
216
+ get innerText() {
217
+ return this.textContent;
218
+ }
219
+
220
+ set innerText(value) {
221
+ this.textContent = value;
222
+ }
223
+
224
+ get innerHTML() {
225
+ if (this._innerHTML) return this._innerHTML;
226
+ return this.children.map((child) => child.outerHTML).join('');
227
+ }
228
+
229
+ set innerHTML(value) {
230
+ this._innerHTML = String(value);
231
+ this._textContent = '';
232
+ this.children = [];
233
+ }
234
+
235
+ get outerHTML() {
236
+ const attributes = Object.entries(this.attributes)
237
+ .filter(([, value]) => value !== null && typeof value !== 'undefined' && value !== '')
238
+ .map(([name, value]) => ` ${name}="${String(value)}"`)
239
+ .join('');
240
+
241
+ return `<${this.localName}${attributes}>${this.innerHTML || this.textContent}</${this.localName}>`;
242
+ }
243
+
244
+ get firstChild() {
245
+ return this.children[0] || null;
246
+ }
247
+
248
+ get firstElementChild() {
249
+ return this.firstChild;
250
+ }
251
+
252
+ get nextSibling() {
253
+ if (!this.parentNode) return null;
254
+ const index = this.parentNode.children.indexOf(this);
255
+ return this.parentNode.children[index + 1] || null;
256
+ }
257
+
258
+ get nextElementSibling() {
259
+ return this.nextSibling;
260
+ }
261
+
262
+ get previousSibling() {
263
+ if (!this.parentNode) return null;
264
+ const index = this.parentNode.children.indexOf(this);
265
+ return this.parentNode.children[index - 1] || null;
266
+ }
267
+
268
+ get previousElementSibling() {
269
+ return this.previousSibling;
270
+ }
271
+
272
+ get options() {
273
+ return this.children.filter((child) => child.matches('option'));
274
+ }
275
+
276
+ setAttribute(name, value = '') {
277
+ const stringValue = String(value);
278
+ this.attributes[name] = stringValue;
279
+
280
+ if (name === 'class') this.classList.setFromString(stringValue);
281
+ if (name === 'value') this.value = stringValue;
282
+ if (name === 'type') this.type = stringValue;
283
+ if (name === 'checked') this.checked = true;
284
+ if (name === 'disabled') this.disabled = true;
285
+ if (name === 'open') this.open = true;
286
+ if (name === 'style') {
287
+ stringValue
288
+ .split(';')
289
+ .map((part) => part.trim())
290
+ .filter(Boolean)
291
+ .forEach((part) => {
292
+ const [property, ...rest] = part.split(':');
293
+ this.style.setProperty(property.trim(), rest.join(':').trim());
294
+ });
295
+ }
296
+ if (name.startsWith('data-')) this.dataset[toDatasetKey(name.slice(5))] = stringValue;
297
+ }
298
+
299
+ getAttribute(name) {
300
+ if (name in this.attributes) return this.attributes[name];
301
+ return null;
302
+ }
303
+
304
+ hasAttribute(name) {
305
+ return name in this.attributes;
306
+ }
307
+
308
+ removeAttribute(name) {
309
+ delete this.attributes[name];
310
+ if (name === 'class') this.classList.setFromString('');
311
+ if (name === 'checked') this.checked = false;
312
+ if (name === 'disabled') this.disabled = false;
313
+ if (name === 'open') this.open = false;
314
+ if (name.startsWith('data-')) delete this.dataset[toDatasetKey(name.slice(5))];
315
+ }
316
+
317
+ toggleAttribute(name, force) {
318
+ if (force === true || (force !== false && !this.hasAttribute(name))) {
319
+ this.setAttribute(name, '');
320
+ return true;
321
+ }
322
+
323
+ this.removeAttribute(name);
324
+ return false;
325
+ }
326
+
327
+ appendChild(child) {
328
+ if (!child) return child;
329
+ child.parentNode = this;
330
+ child.parentElement = this;
331
+ this.children.push(child);
332
+ this._innerHTML = '';
333
+ return child;
334
+ }
335
+
336
+ append(...items) {
337
+ items.forEach((item) => {
338
+ if (typeof item === 'string') this._innerHTML += item;
339
+ else this.appendChild(item);
340
+ });
341
+ }
342
+
343
+ prepend(...items) {
344
+ items
345
+ .slice()
346
+ .reverse()
347
+ .forEach((item) => {
348
+ if (typeof item === 'string') {
349
+ this._innerHTML = item + this._innerHTML;
350
+ } else {
351
+ item.parentNode = this;
352
+ item.parentElement = this;
353
+ this.children.unshift(item);
354
+ this._innerHTML = '';
355
+ }
356
+ });
357
+ }
358
+
359
+ before(element) {
360
+ if (!this.parentNode) return;
361
+ this.parentNode.insertBefore(element, this);
362
+ }
363
+
364
+ insertBefore(child, reference) {
365
+ child.parentNode = this;
366
+ child.parentElement = this;
367
+ const index = reference ? this.children.indexOf(reference) : -1;
368
+
369
+ if (index === -1) this.children.push(child);
370
+ else this.children.splice(index, 0, child);
371
+
372
+ this._innerHTML = '';
373
+ return child;
374
+ }
375
+
376
+ removeChild(child) {
377
+ const index = this.children.indexOf(child);
378
+ if (index !== -1) this.children.splice(index, 1);
379
+ child.parentNode = null;
380
+ child.parentElement = null;
381
+ return child;
382
+ }
383
+
384
+ remove() {
385
+ if (this.parentNode) this.parentNode.removeChild(this);
386
+ }
387
+
388
+ replaceChild(newChild, oldChild) {
389
+ const index = this.children.indexOf(oldChild);
390
+ if (index === -1) return oldChild;
391
+ newChild.parentNode = this;
392
+ newChild.parentElement = this;
393
+ oldChild.parentNode = null;
394
+ oldChild.parentElement = null;
395
+ this.children[index] = newChild;
396
+ return oldChild;
397
+ }
398
+
399
+ cloneNode(deep = false) {
400
+ const clone = new TestElement(this.localName);
401
+ Object.entries(this.attributes).forEach(([name, value]) => clone.setAttribute(name, value));
402
+ clone.value = this.value;
403
+ clone.checked = this.checked;
404
+ clone.innerHTML = this.innerHTML;
405
+ clone.textContent = this._textContent;
406
+ clone.files = Array.from(this.files || []);
407
+
408
+ if (deep) this.children.forEach((child) => clone.appendChild(child.cloneNode(true)));
409
+
410
+ return clone;
411
+ }
412
+
413
+ insertAdjacentHTML(position, html) {
414
+ if (position === 'afterbegin') this._innerHTML = String(html) + this._innerHTML;
415
+ else this._innerHTML += String(html);
416
+ }
417
+
418
+ insertAdjacentElement(position, element) {
419
+ if (position === 'afterbegin') this.prepend(element);
420
+ else this.appendChild(element);
421
+ return element;
422
+ }
423
+
424
+ querySelector(selector) {
425
+ return this.querySelectorAll(selector)[0] || null;
426
+ }
427
+
428
+ querySelectorAll(selector) {
429
+ return selectAll(this, selector);
430
+ }
431
+
432
+ getElementsByTagName(tagName) {
433
+ return this.querySelectorAll(tagName);
434
+ }
435
+
436
+ closest(selector) {
437
+ let current = this;
438
+ while (current) {
439
+ if (current.matches && current.matches(selector)) return current;
440
+ current = current.parentNode;
441
+ }
442
+
443
+ return null;
444
+ }
445
+
446
+ matches(selector) {
447
+ return matchesSelector(this, selector);
448
+ }
449
+
450
+ click() {
451
+ this.dispatchEvent(new Event('click', { bubbles: true, cancelable: true }));
452
+ }
453
+
454
+ focus() {
455
+ globalThis.document.activeElement = this;
456
+ }
457
+
458
+ blur() {
459
+ if (globalThis.document.activeElement === this) globalThis.document.activeElement = null;
460
+ }
461
+
462
+ scroll(options = {}) {
463
+ if ('left' in options) this.scrollLeft = options.left;
464
+ if ('top' in options) this.scrollTop = options.top;
465
+ this.dispatchEvent(new Event('scroll'));
466
+ }
467
+
468
+ scrollIntoView() {}
469
+
470
+ showModal() {
471
+ this.setAttribute('open', '');
472
+ this.open = true;
473
+ }
474
+
475
+ show() {
476
+ this.showModal();
477
+ }
478
+
479
+ close() {
480
+ this.removeAttribute('open');
481
+ this.open = false;
482
+ this.dispatchEvent(new Event('close'));
483
+ }
484
+
485
+ submit() {
486
+ this.dispatchEvent(new Event('submit'));
487
+ }
488
+
489
+ getBoundingClientRect() {
490
+ return this._rect;
491
+ }
492
+
493
+ setRect(rect) {
494
+ this._rect = { ...this._rect, ...rect };
495
+ }
496
+ }
497
+
498
+ export class TestDocument extends TestElement {
499
+ constructor() {
500
+ super('#document');
501
+ this.title = 'Test page';
502
+ this.documentElement = new TestElement('html');
503
+ this.body = new TestElement('body');
504
+ this.documentElement.appendChild(this.body);
505
+ this.appendChild(this.documentElement);
506
+ this.activeElement = null;
507
+ }
508
+
509
+ createElement(tagName) {
510
+ return new TestElement(tagName);
511
+ }
512
+
513
+ createDocumentFragment() {
514
+ return new TestElement('fragment');
515
+ }
516
+
517
+ getElementById(id) {
518
+ return this.querySelector(`#${id}`);
519
+ }
520
+
521
+ querySelector(selector) {
522
+ if (selector === 'body') return this.body;
523
+ if (selector === 'html') return this.documentElement;
524
+ return super.querySelector(selector);
525
+ }
526
+ }
527
+
528
+ class TestStorage {
529
+ constructor() {
530
+ this.items = {};
531
+ }
532
+
533
+ getItem(key) {
534
+ return this.items[key] || null;
535
+ }
536
+
537
+ setItem(key, value) {
538
+ this.items[key] = String(value);
539
+ }
540
+
541
+ removeItem(key) {
542
+ delete this.items[key];
543
+ }
544
+
545
+ clear() {
546
+ this.items = {};
547
+ }
548
+ }
549
+
550
+ const getDescendants = (root) => {
551
+ const descendants = [];
552
+
553
+ root.children.forEach((child) => {
554
+ descendants.push(child);
555
+ descendants.push(...getDescendants(child));
556
+ });
557
+
558
+ if (root.shadowRoot) {
559
+ descendants.push(root.shadowRoot);
560
+ descendants.push(...getDescendants(root.shadowRoot));
561
+ }
562
+
563
+ return descendants;
564
+ };
565
+
566
+ const unique = (items) => Array.from(new Set(items));
567
+
568
+ const selectAll = (root, selector) => {
569
+ if (!selector) return [];
570
+
571
+ const selectors = splitSelector(selector);
572
+ if (selectors.length > 1) return unique(selectors.flatMap((part) => selectAll(root, part)));
573
+
574
+ const normalized = selector.trim();
575
+
576
+ if (normalized.startsWith(':scope > ')) {
577
+ const childSelector = normalized.replace(':scope > ', '').trim();
578
+ return root.children.filter((child) => child.matches(childSelector));
579
+ }
580
+
581
+ const tokens = splitTokens(normalized);
582
+ if (tokens.length > 1) {
583
+ let current = [root];
584
+ let direct = false;
585
+
586
+ tokens.forEach((token) => {
587
+ if (token === '>') {
588
+ direct = true;
589
+ return;
590
+ }
591
+
592
+ current = current.flatMap((element) => {
593
+ const candidates = direct ? element.children : getDescendants(element);
594
+ return candidates.filter((candidate) => candidate.matches(token));
595
+ });
596
+ direct = false;
597
+ });
598
+
599
+ return unique(current);
600
+ }
601
+
602
+ return getDescendants(root).filter((element) => element.matches(normalized));
603
+ };
604
+
605
+ const matchesSelector = (element, selector) => {
606
+ if (!selector) return false;
607
+
608
+ const selectors = splitSelector(selector);
609
+ if (selectors.length > 1) return selectors.some((part) => matchesSelector(element, part));
610
+
611
+ let current = selector.trim();
612
+ if (current === '*') return true;
613
+ if (current.startsWith(':scope')) current = current.replace(':scope', '').trim();
614
+ if (!current) return true;
615
+
616
+ const notMatches = current.match(/:not\((.+)\)$/);
617
+ if (notMatches) {
618
+ current = current.slice(0, notMatches.index);
619
+ if (matchesSelector(element, notMatches[1])) return false;
620
+ }
621
+
622
+ const isMatches = current.match(/:is\((.+)\)/);
623
+ if (isMatches) {
624
+ const before = current.slice(0, isMatches.index);
625
+ const after = current.slice(isMatches.index + isMatches[0].length);
626
+ return splitSelector(isMatches[1]).some((part) => matchesSelector(element, `${before}${part}${after}`));
627
+ }
628
+
629
+ if (current.endsWith(':first-child')) {
630
+ current = current.replace(':first-child', '');
631
+ if (!element.parentNode || element.parentNode.children[0] !== element) return false;
632
+ }
633
+
634
+ if (current.endsWith(':last-child')) {
635
+ current = current.replace(':last-child', '');
636
+ if (!element.parentNode || element.parentNode.children[element.parentNode.children.length - 1] !== element) {
637
+ return false;
638
+ }
639
+ }
640
+
641
+ if (current.endsWith(':checked')) {
642
+ current = current.replace(':checked', '');
643
+ if (!element.checked) return false;
644
+ }
645
+
646
+ current = current.trim();
647
+
648
+ const attributeMatches = Array.from(current.matchAll(/\[([^\]=~*]+)([*]?=)?(?:"([^"]*)"|'([^']*)'|([^\]]+))?\]/g));
649
+ for (const attributeMatch of attributeMatches) {
650
+ const name = attributeMatch[1].trim();
651
+ const operator = attributeMatch[2];
652
+ const expected = stripQuotes(attributeMatch[3] || attributeMatch[4] || attributeMatch[5] || '');
653
+ const actual = name === 'class' ? element.className : element.getAttribute(name);
654
+
655
+ if (!operator && actual === null) return false;
656
+ if (operator === '=' && String(actual) !== expected) return false;
657
+ if (operator === '*=' && !String(actual || '').includes(expected)) return false;
658
+ }
659
+ current = current.replace(/\[[^\]]+\]/g, '');
660
+
661
+ const idMatch = current.match(/#([A-Za-z0-9_-]+)/);
662
+ if (idMatch && element.getAttribute('id') !== idMatch[1]) return false;
663
+ current = current.replace(/#[A-Za-z0-9_-]+/g, '');
664
+
665
+ const classMatches = Array.from(current.matchAll(/\.([A-Za-z0-9_-]+)/g)).map((match) => match[1]);
666
+ if (classMatches.some((className) => !element.classList.contains(className))) return false;
667
+ current = current.replace(/\.[A-Za-z0-9_-]+/g, '').trim();
668
+
669
+ if (current && current !== '*' && element.localName !== current.toLowerCase()) return false;
670
+
671
+ return true;
672
+ };
673
+
674
+ class TestDataTransfer {
675
+ constructor() {
676
+ this.items = {
677
+ files: [],
678
+ add: (file) => this.items.files.push(file),
679
+ };
680
+ }
681
+
682
+ get files() {
683
+ return this.items.files;
684
+ }
685
+ }
686
+
687
+ export const installTestDom = () => {
688
+ const document = new TestDocument();
689
+ const localStorage = new TestStorage();
690
+ const window = globalThis.window || new EventTarget();
691
+
692
+ window.document = document;
693
+ window.dataLayer = [];
694
+ window.controller = [];
695
+ window.innerWidth = 1024;
696
+ window.innerHeight = 768;
697
+ window.scrollY = 0;
698
+ window.pageYOffset = 0;
699
+ window.location = { href: 'http://localhost/', hash: '' };
700
+ window.history = { pushState: () => {} };
701
+ window.matchMedia = () => ({ matches: true });
702
+ window.getComputedStyle = (element) => ({
703
+ display: element.style.getPropertyValue('display') || element.getAttribute('data-display') || 'block',
704
+ fontSize: '16px',
705
+ getPropertyValue: (name) => {
706
+ if (name === 'line-height') return element.getAttribute('data-line-height') || '16px';
707
+ if (name === 'display') return element.style.getPropertyValue('display') || 'block';
708
+ if (name === 'font-size') return '16px';
709
+ return element.style.getPropertyValue(name);
710
+ },
711
+ });
712
+ window.URL = {
713
+ createObjectURL: () => 'blob:test',
714
+ };
715
+ window.setTimeout = globalThis.setTimeout.bind(globalThis);
716
+ window.clearTimeout = globalThis.clearTimeout.bind(globalThis);
717
+ window.setInterval = globalThis.setInterval.bind(globalThis);
718
+ window.clearInterval = globalThis.clearInterval.bind(globalThis);
719
+ window.localStorage = localStorage;
720
+
721
+ Object.defineProperty(globalThis, 'window', { value: window, writable: true, configurable: true });
722
+ Object.defineProperty(globalThis, 'document', { value: document, writable: true, configurable: true });
723
+ Object.defineProperty(globalThis, 'navigator', {
724
+ value: { userAgent: '', appVersion: '' },
725
+ writable: true,
726
+ configurable: true,
727
+ });
728
+
729
+ globalThis.location = window.location;
730
+ globalThis.history = window.history;
731
+ globalThis.localStorage = localStorage;
732
+ globalThis.HTMLElement = TestElement;
733
+ globalThis.Element = TestElement;
734
+ globalThis.HTMLInputElement = TestElement;
735
+ globalThis.getComputedStyle = window.getComputedStyle;
736
+ globalThis.addEventListener = window.addEventListener.bind(window);
737
+ globalThis.IntersectionObserver = class {
738
+ constructor(callback) {
739
+ this.callback = callback;
740
+ this.observed = [];
741
+ }
742
+
743
+ observe(element) {
744
+ this.observed.push(element);
745
+ this.callback([{ target: element, intersectionRatio: 1 }]);
746
+ }
747
+
748
+ disconnect() {}
749
+ };
750
+ globalThis.ResizeObserver = class {
751
+ constructor(callback) {
752
+ this.callback = callback;
753
+ }
754
+
755
+ observe(element) {
756
+ this.callback([{ target: element }]);
757
+ }
758
+ };
759
+ globalThis.MutationObserver = class {
760
+ constructor(callback) {
761
+ this.callback = callback;
762
+ }
763
+
764
+ observe() {}
765
+ disconnect() {}
766
+ };
767
+ globalThis.DataTransfer = TestDataTransfer;
768
+ globalThis.Image = class {
769
+ set src(value) {
770
+ this._src = value;
771
+ setTimeout(() => this.onload && this.onload(), 0);
772
+ }
773
+
774
+ get src() {
775
+ return this._src;
776
+ }
777
+ };
778
+
779
+ return { document, window, localStorage };
780
+ };
781
+
782
+ export const createElement = (tagName, attributes = {}, text = '') => {
783
+ const element = new TestElement(tagName);
784
+
785
+ Object.entries(attributes).forEach(([name, value]) => {
786
+ if (name === 'textContent') element.textContent = value;
787
+ else if (name === 'innerHTML') element.innerHTML = value;
788
+ else if (name === 'checked') element.checked = Boolean(value);
789
+ else if (name === 'value') {
790
+ element.value = value;
791
+ element.setAttribute('value', value);
792
+ } else element.setAttribute(toKebab(name), value);
793
+ });
794
+
795
+ if (text) element.textContent = text;
796
+
797
+ return element;
798
+ };