attrs-in-props 3.14.6 → 3.14.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/index.js +1331 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# attrs-in-props
|
|
2
2
|
|
|
3
|
+
## 3.14.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Manual patch bump triggered via workflow_dispatch (scope: @symbo.ls).
|
|
8
|
+
No source change behind this bump — released to refresh dist or
|
|
9
|
+
coordinate a cross-package version line.
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
- @symbo.ls/utils@3.14.15
|
|
12
|
+
|
|
13
|
+
## 3.14.7
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Manual patch bump triggered via workflow_dispatch (scope: @symbo.ls).
|
|
18
|
+
No source change behind this bump — released to refresh dist or
|
|
19
|
+
coordinate a cross-package version line.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @symbo.ls/utils@3.14.11
|
|
22
|
+
|
|
3
23
|
## 3.14.6
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/index.js
ADDED
|
@@ -0,0 +1,1331 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isDefined, isFunction, isString } from '@symbo.ls/utils'
|
|
4
|
+
|
|
5
|
+
export const ARIA_ROLES = [
|
|
6
|
+
'alert',
|
|
7
|
+
'alertdialog',
|
|
8
|
+
'application',
|
|
9
|
+
'article',
|
|
10
|
+
'banner',
|
|
11
|
+
'button',
|
|
12
|
+
'cell',
|
|
13
|
+
'checkbox',
|
|
14
|
+
'columnheader',
|
|
15
|
+
'combobox',
|
|
16
|
+
'complementary',
|
|
17
|
+
'contentinfo',
|
|
18
|
+
'definition',
|
|
19
|
+
'dialog',
|
|
20
|
+
'directory',
|
|
21
|
+
'document',
|
|
22
|
+
'feed',
|
|
23
|
+
'figure',
|
|
24
|
+
'form',
|
|
25
|
+
'grid',
|
|
26
|
+
'gridcell',
|
|
27
|
+
'group',
|
|
28
|
+
'heading',
|
|
29
|
+
'img',
|
|
30
|
+
'link',
|
|
31
|
+
'list',
|
|
32
|
+
'listbox',
|
|
33
|
+
'listitem',
|
|
34
|
+
'log',
|
|
35
|
+
'main',
|
|
36
|
+
'marquee',
|
|
37
|
+
'math',
|
|
38
|
+
'menu',
|
|
39
|
+
'menubar',
|
|
40
|
+
'menuitem',
|
|
41
|
+
'menuitemcheckbox',
|
|
42
|
+
'menuitemradio',
|
|
43
|
+
'navigation',
|
|
44
|
+
'none',
|
|
45
|
+
'note',
|
|
46
|
+
'option',
|
|
47
|
+
'presentation',
|
|
48
|
+
'progressbar',
|
|
49
|
+
'radio',
|
|
50
|
+
'radiogroup',
|
|
51
|
+
'region',
|
|
52
|
+
'row',
|
|
53
|
+
'rowgroup',
|
|
54
|
+
'rowheader',
|
|
55
|
+
'scrollbar',
|
|
56
|
+
'search',
|
|
57
|
+
'searchbox',
|
|
58
|
+
'separator',
|
|
59
|
+
'slider',
|
|
60
|
+
'spinbutton',
|
|
61
|
+
'status',
|
|
62
|
+
'switch',
|
|
63
|
+
'tab',
|
|
64
|
+
'table',
|
|
65
|
+
'tablist',
|
|
66
|
+
'tabpanel',
|
|
67
|
+
'term',
|
|
68
|
+
'textbox',
|
|
69
|
+
'timer',
|
|
70
|
+
'toolbar',
|
|
71
|
+
'tooltip',
|
|
72
|
+
'tree',
|
|
73
|
+
'treegrid',
|
|
74
|
+
'treeitem'
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
export const HTML_ATTRIBUTES = {
|
|
78
|
+
default: [
|
|
79
|
+
'accesskey',
|
|
80
|
+
'autofocus',
|
|
81
|
+
'class',
|
|
82
|
+
'contenteditable',
|
|
83
|
+
'contextmenu',
|
|
84
|
+
'dir',
|
|
85
|
+
'draggable',
|
|
86
|
+
'hidden',
|
|
87
|
+
'id',
|
|
88
|
+
'lang',
|
|
89
|
+
'part',
|
|
90
|
+
'placeholder',
|
|
91
|
+
'slot',
|
|
92
|
+
'spellcheck',
|
|
93
|
+
'style',
|
|
94
|
+
'tabindex',
|
|
95
|
+
'title',
|
|
96
|
+
'translate',
|
|
97
|
+
'inert',
|
|
98
|
+
'radiogroup',
|
|
99
|
+
'role',
|
|
100
|
+
'about',
|
|
101
|
+
'datatype',
|
|
102
|
+
'inlist',
|
|
103
|
+
'prefix',
|
|
104
|
+
'property',
|
|
105
|
+
'resource',
|
|
106
|
+
'typeof',
|
|
107
|
+
'vocab',
|
|
108
|
+
'autocapitalize',
|
|
109
|
+
'autocorrect',
|
|
110
|
+
'autosave',
|
|
111
|
+
'color',
|
|
112
|
+
'itemprop',
|
|
113
|
+
'itemscope',
|
|
114
|
+
'itemtype',
|
|
115
|
+
'itemid',
|
|
116
|
+
'itemref',
|
|
117
|
+
'results',
|
|
118
|
+
'security',
|
|
119
|
+
'unselectable',
|
|
120
|
+
'is'
|
|
121
|
+
],
|
|
122
|
+
|
|
123
|
+
a: [
|
|
124
|
+
'accesskey',
|
|
125
|
+
'charset',
|
|
126
|
+
'coords',
|
|
127
|
+
'download',
|
|
128
|
+
'href',
|
|
129
|
+
'hreflang',
|
|
130
|
+
'name',
|
|
131
|
+
'rel',
|
|
132
|
+
'rev',
|
|
133
|
+
'shape',
|
|
134
|
+
'target',
|
|
135
|
+
'type'
|
|
136
|
+
],
|
|
137
|
+
|
|
138
|
+
aria: [
|
|
139
|
+
'aria-activedescendant',
|
|
140
|
+
'aria-atomic',
|
|
141
|
+
'aria-autocomplete',
|
|
142
|
+
'aria-checked',
|
|
143
|
+
'aria-colcount',
|
|
144
|
+
'aria-colindex',
|
|
145
|
+
'aria-colspan',
|
|
146
|
+
'aria-controls',
|
|
147
|
+
'aria-current',
|
|
148
|
+
'aria-describedby',
|
|
149
|
+
'aria-details',
|
|
150
|
+
'aria-dropeffect',
|
|
151
|
+
'aria-errormessage',
|
|
152
|
+
'aria-expanded',
|
|
153
|
+
'aria-flowto',
|
|
154
|
+
'aria-grabbed',
|
|
155
|
+
'aria-haspopup',
|
|
156
|
+
'aria-hidden',
|
|
157
|
+
'aria-invalid',
|
|
158
|
+
'aria-keyshortcuts',
|
|
159
|
+
'aria-label',
|
|
160
|
+
'aria-labelledby',
|
|
161
|
+
'aria-level',
|
|
162
|
+
'aria-live',
|
|
163
|
+
'aria-modal',
|
|
164
|
+
'aria-multiline',
|
|
165
|
+
'aria-multiselectable',
|
|
166
|
+
'aria-orientation',
|
|
167
|
+
'aria-owns',
|
|
168
|
+
'aria-placeholder',
|
|
169
|
+
'aria-posinset',
|
|
170
|
+
'aria-pressed',
|
|
171
|
+
'aria-readonly',
|
|
172
|
+
'aria-relevant',
|
|
173
|
+
'aria-required',
|
|
174
|
+
'aria-roledescription',
|
|
175
|
+
'aria-rowcount',
|
|
176
|
+
'aria-rowindex',
|
|
177
|
+
'aria-rowspan',
|
|
178
|
+
'aria-selected',
|
|
179
|
+
'aria-setsize',
|
|
180
|
+
'aria-sort',
|
|
181
|
+
'aria-valuemax',
|
|
182
|
+
'aria-valuemin',
|
|
183
|
+
'aria-valuenow',
|
|
184
|
+
'aria-valuetext'
|
|
185
|
+
],
|
|
186
|
+
|
|
187
|
+
anchor: [
|
|
188
|
+
'download',
|
|
189
|
+
'href',
|
|
190
|
+
'hreflang',
|
|
191
|
+
'media',
|
|
192
|
+
'ping',
|
|
193
|
+
'rel',
|
|
194
|
+
'target',
|
|
195
|
+
'type',
|
|
196
|
+
'referrerpolicy'
|
|
197
|
+
],
|
|
198
|
+
|
|
199
|
+
audio: [
|
|
200
|
+
'autoplay',
|
|
201
|
+
'controls',
|
|
202
|
+
'crossorigin',
|
|
203
|
+
'loop',
|
|
204
|
+
'muted',
|
|
205
|
+
'preload',
|
|
206
|
+
'src'
|
|
207
|
+
],
|
|
208
|
+
|
|
209
|
+
area: [
|
|
210
|
+
'alt',
|
|
211
|
+
'coords',
|
|
212
|
+
'download',
|
|
213
|
+
'href',
|
|
214
|
+
'hreflang',
|
|
215
|
+
'media',
|
|
216
|
+
'referrerpolicy',
|
|
217
|
+
'rel',
|
|
218
|
+
'shape',
|
|
219
|
+
'target',
|
|
220
|
+
'ping'
|
|
221
|
+
],
|
|
222
|
+
|
|
223
|
+
base: [
|
|
224
|
+
'href',
|
|
225
|
+
'target'
|
|
226
|
+
],
|
|
227
|
+
|
|
228
|
+
blockquote: [
|
|
229
|
+
'cite'
|
|
230
|
+
],
|
|
231
|
+
|
|
232
|
+
button: [
|
|
233
|
+
'disabled',
|
|
234
|
+
'form',
|
|
235
|
+
'formaction',
|
|
236
|
+
'formenctype',
|
|
237
|
+
'formmethod',
|
|
238
|
+
'formnovalidate',
|
|
239
|
+
'formtarget',
|
|
240
|
+
'name',
|
|
241
|
+
'type',
|
|
242
|
+
'value'
|
|
243
|
+
],
|
|
244
|
+
|
|
245
|
+
canvas: [
|
|
246
|
+
'height',
|
|
247
|
+
'width'
|
|
248
|
+
],
|
|
249
|
+
|
|
250
|
+
col: [
|
|
251
|
+
'span',
|
|
252
|
+
'width'
|
|
253
|
+
],
|
|
254
|
+
|
|
255
|
+
colgroup: [
|
|
256
|
+
'span'
|
|
257
|
+
],
|
|
258
|
+
|
|
259
|
+
data: [
|
|
260
|
+
'value'
|
|
261
|
+
],
|
|
262
|
+
|
|
263
|
+
details: [
|
|
264
|
+
'open'
|
|
265
|
+
],
|
|
266
|
+
|
|
267
|
+
del: [
|
|
268
|
+
'cite',
|
|
269
|
+
'datetime'
|
|
270
|
+
],
|
|
271
|
+
|
|
272
|
+
dialog: [
|
|
273
|
+
'open'
|
|
274
|
+
],
|
|
275
|
+
|
|
276
|
+
embed: [
|
|
277
|
+
'height',
|
|
278
|
+
'src',
|
|
279
|
+
'type',
|
|
280
|
+
'width'
|
|
281
|
+
],
|
|
282
|
+
|
|
283
|
+
fieldset: [
|
|
284
|
+
'disabled',
|
|
285
|
+
'form',
|
|
286
|
+
'name'
|
|
287
|
+
],
|
|
288
|
+
|
|
289
|
+
form: [
|
|
290
|
+
'acceptcharset',
|
|
291
|
+
'action',
|
|
292
|
+
'autocomplete',
|
|
293
|
+
'enctype',
|
|
294
|
+
'method',
|
|
295
|
+
'name',
|
|
296
|
+
'novalidate',
|
|
297
|
+
'target',
|
|
298
|
+
'rel'
|
|
299
|
+
],
|
|
300
|
+
|
|
301
|
+
html: [
|
|
302
|
+
'manifest'
|
|
303
|
+
],
|
|
304
|
+
|
|
305
|
+
iframe: [
|
|
306
|
+
'allow',
|
|
307
|
+
'allowfullscreen',
|
|
308
|
+
'allowtransparency',
|
|
309
|
+
'frameborder',
|
|
310
|
+
'height',
|
|
311
|
+
'loading',
|
|
312
|
+
'marginheight',
|
|
313
|
+
'marginwidth',
|
|
314
|
+
'mozallowfullscreen',
|
|
315
|
+
'name',
|
|
316
|
+
'referrerpolicy',
|
|
317
|
+
'sandbox',
|
|
318
|
+
'scrolling',
|
|
319
|
+
'seamless',
|
|
320
|
+
'src',
|
|
321
|
+
'srcdoc',
|
|
322
|
+
'webkitallowfullscreen',
|
|
323
|
+
'width'
|
|
324
|
+
],
|
|
325
|
+
|
|
326
|
+
img: [
|
|
327
|
+
'alt',
|
|
328
|
+
'crossorigin',
|
|
329
|
+
'decoding',
|
|
330
|
+
'height',
|
|
331
|
+
'ismap',
|
|
332
|
+
'loading',
|
|
333
|
+
'referrerpolicy',
|
|
334
|
+
'sizes',
|
|
335
|
+
'src',
|
|
336
|
+
'srcset',
|
|
337
|
+
'usemap',
|
|
338
|
+
'width'
|
|
339
|
+
],
|
|
340
|
+
|
|
341
|
+
ins: [
|
|
342
|
+
'cite',
|
|
343
|
+
'datetime'
|
|
344
|
+
],
|
|
345
|
+
|
|
346
|
+
input: [
|
|
347
|
+
'accept',
|
|
348
|
+
'alt',
|
|
349
|
+
'autocomplete',
|
|
350
|
+
'capture',
|
|
351
|
+
'checked',
|
|
352
|
+
'crossorigin',
|
|
353
|
+
'disabled',
|
|
354
|
+
'form',
|
|
355
|
+
'formaction',
|
|
356
|
+
'formenctype',
|
|
357
|
+
'formmethod',
|
|
358
|
+
'formnovalidate',
|
|
359
|
+
'formtarget',
|
|
360
|
+
'height',
|
|
361
|
+
'indeterminate',
|
|
362
|
+
'list',
|
|
363
|
+
'max',
|
|
364
|
+
'maxlength',
|
|
365
|
+
'min',
|
|
366
|
+
'minlength',
|
|
367
|
+
'multiple',
|
|
368
|
+
'name',
|
|
369
|
+
'pattern',
|
|
370
|
+
'placeholder',
|
|
371
|
+
'readonly',
|
|
372
|
+
'required',
|
|
373
|
+
'size',
|
|
374
|
+
'src',
|
|
375
|
+
'step',
|
|
376
|
+
'type',
|
|
377
|
+
'value',
|
|
378
|
+
'width'
|
|
379
|
+
],
|
|
380
|
+
|
|
381
|
+
keygen: [
|
|
382
|
+
'challenge',
|
|
383
|
+
'disabled',
|
|
384
|
+
'form',
|
|
385
|
+
'keytype',
|
|
386
|
+
'keyparams',
|
|
387
|
+
'name'
|
|
388
|
+
],
|
|
389
|
+
|
|
390
|
+
label: [
|
|
391
|
+
'form',
|
|
392
|
+
'for'
|
|
393
|
+
],
|
|
394
|
+
|
|
395
|
+
li: [
|
|
396
|
+
'value'
|
|
397
|
+
],
|
|
398
|
+
|
|
399
|
+
link: [
|
|
400
|
+
'as',
|
|
401
|
+
'crossorigin',
|
|
402
|
+
'href',
|
|
403
|
+
'hreflang',
|
|
404
|
+
'integrity',
|
|
405
|
+
'media',
|
|
406
|
+
'imagesrcset',
|
|
407
|
+
'imagesizes',
|
|
408
|
+
'referrerpolicy',
|
|
409
|
+
'rel',
|
|
410
|
+
'sizes',
|
|
411
|
+
'type',
|
|
412
|
+
'charset'
|
|
413
|
+
],
|
|
414
|
+
|
|
415
|
+
map: [
|
|
416
|
+
'name'
|
|
417
|
+
],
|
|
418
|
+
|
|
419
|
+
menu: [
|
|
420
|
+
'type'
|
|
421
|
+
],
|
|
422
|
+
|
|
423
|
+
media: [
|
|
424
|
+
'autoplay',
|
|
425
|
+
'controls',
|
|
426
|
+
'currenttime',
|
|
427
|
+
'defaultmuted',
|
|
428
|
+
'defaultplaybackrate',
|
|
429
|
+
'loop',
|
|
430
|
+
'mediagroup',
|
|
431
|
+
'muted',
|
|
432
|
+
'playsinline',
|
|
433
|
+
'preload',
|
|
434
|
+
'src',
|
|
435
|
+
'volume'
|
|
436
|
+
],
|
|
437
|
+
|
|
438
|
+
meta: [
|
|
439
|
+
'charset',
|
|
440
|
+
'content',
|
|
441
|
+
'http-equiv',
|
|
442
|
+
'name',
|
|
443
|
+
'media'
|
|
444
|
+
],
|
|
445
|
+
|
|
446
|
+
meter: [
|
|
447
|
+
'form',
|
|
448
|
+
'high',
|
|
449
|
+
'low',
|
|
450
|
+
'max',
|
|
451
|
+
'min',
|
|
452
|
+
'optimum',
|
|
453
|
+
'value'
|
|
454
|
+
],
|
|
455
|
+
|
|
456
|
+
quote: [
|
|
457
|
+
'cite'
|
|
458
|
+
],
|
|
459
|
+
|
|
460
|
+
object: [
|
|
461
|
+
'classid',
|
|
462
|
+
'data',
|
|
463
|
+
'form',
|
|
464
|
+
'height',
|
|
465
|
+
'name',
|
|
466
|
+
'type',
|
|
467
|
+
'usemap',
|
|
468
|
+
'width',
|
|
469
|
+
'wmode'
|
|
470
|
+
],
|
|
471
|
+
|
|
472
|
+
ol: [
|
|
473
|
+
'reversed',
|
|
474
|
+
'start',
|
|
475
|
+
'type'
|
|
476
|
+
],
|
|
477
|
+
|
|
478
|
+
optgroup: [
|
|
479
|
+
'disabled',
|
|
480
|
+
'label'
|
|
481
|
+
],
|
|
482
|
+
|
|
483
|
+
option: [
|
|
484
|
+
'disabled',
|
|
485
|
+
'label',
|
|
486
|
+
'selected',
|
|
487
|
+
'value'
|
|
488
|
+
],
|
|
489
|
+
|
|
490
|
+
output: [
|
|
491
|
+
'form',
|
|
492
|
+
'for',
|
|
493
|
+
'name'
|
|
494
|
+
],
|
|
495
|
+
|
|
496
|
+
param: [
|
|
497
|
+
'name',
|
|
498
|
+
'value'
|
|
499
|
+
],
|
|
500
|
+
|
|
501
|
+
progress: [
|
|
502
|
+
'max',
|
|
503
|
+
'value'
|
|
504
|
+
],
|
|
505
|
+
|
|
506
|
+
slot: [
|
|
507
|
+
'name'
|
|
508
|
+
],
|
|
509
|
+
|
|
510
|
+
script: [
|
|
511
|
+
'async',
|
|
512
|
+
'charset',
|
|
513
|
+
'crossorigin',
|
|
514
|
+
'defer',
|
|
515
|
+
'integrity',
|
|
516
|
+
'nomodule',
|
|
517
|
+
'nonce',
|
|
518
|
+
'referrerpolicy',
|
|
519
|
+
'src',
|
|
520
|
+
'type'
|
|
521
|
+
],
|
|
522
|
+
|
|
523
|
+
select: [
|
|
524
|
+
'autocomplete',
|
|
525
|
+
'disabled',
|
|
526
|
+
'form',
|
|
527
|
+
'multiple',
|
|
528
|
+
'name',
|
|
529
|
+
'required',
|
|
530
|
+
'size',
|
|
531
|
+
'value',
|
|
532
|
+
|
|
533
|
+
'onchange'
|
|
534
|
+
],
|
|
535
|
+
|
|
536
|
+
source: [
|
|
537
|
+
'height',
|
|
538
|
+
'media',
|
|
539
|
+
'sizes',
|
|
540
|
+
'src',
|
|
541
|
+
'srcset',
|
|
542
|
+
'type',
|
|
543
|
+
'width'
|
|
544
|
+
],
|
|
545
|
+
|
|
546
|
+
style: [
|
|
547
|
+
'media',
|
|
548
|
+
'nonce',
|
|
549
|
+
'scoped',
|
|
550
|
+
'type'
|
|
551
|
+
],
|
|
552
|
+
|
|
553
|
+
table: [
|
|
554
|
+
'align',
|
|
555
|
+
'bgcolor',
|
|
556
|
+
'border',
|
|
557
|
+
'cellpadding',
|
|
558
|
+
'cellspacing',
|
|
559
|
+
'frame',
|
|
560
|
+
'rules',
|
|
561
|
+
'summary',
|
|
562
|
+
'width'
|
|
563
|
+
],
|
|
564
|
+
|
|
565
|
+
textarea: [
|
|
566
|
+
'autocomplete',
|
|
567
|
+
'cols',
|
|
568
|
+
'dirname',
|
|
569
|
+
'disabled',
|
|
570
|
+
'form',
|
|
571
|
+
'maxlength',
|
|
572
|
+
'minlength',
|
|
573
|
+
'name',
|
|
574
|
+
'placeholder',
|
|
575
|
+
'readonly',
|
|
576
|
+
'required',
|
|
577
|
+
'rows',
|
|
578
|
+
'value',
|
|
579
|
+
'wrap'
|
|
580
|
+
],
|
|
581
|
+
|
|
582
|
+
td: [
|
|
583
|
+
'align',
|
|
584
|
+
'colspan',
|
|
585
|
+
'headers',
|
|
586
|
+
'rowspan',
|
|
587
|
+
'scope',
|
|
588
|
+
'abbr',
|
|
589
|
+
'height',
|
|
590
|
+
'width',
|
|
591
|
+
'valign'
|
|
592
|
+
],
|
|
593
|
+
|
|
594
|
+
th: [
|
|
595
|
+
'align',
|
|
596
|
+
'colspan',
|
|
597
|
+
'headers',
|
|
598
|
+
'rowspan',
|
|
599
|
+
'scope',
|
|
600
|
+
'abbr'
|
|
601
|
+
],
|
|
602
|
+
|
|
603
|
+
time: [
|
|
604
|
+
'datetime'
|
|
605
|
+
],
|
|
606
|
+
|
|
607
|
+
track: [
|
|
608
|
+
'default',
|
|
609
|
+
'kind',
|
|
610
|
+
'label',
|
|
611
|
+
'src',
|
|
612
|
+
'srclang'
|
|
613
|
+
],
|
|
614
|
+
|
|
615
|
+
video: [
|
|
616
|
+
'autoplay',
|
|
617
|
+
'controls',
|
|
618
|
+
'crossorigin',
|
|
619
|
+
'disablepictureinpicture',
|
|
620
|
+
'disableremoteplayback',
|
|
621
|
+
'height',
|
|
622
|
+
'loop',
|
|
623
|
+
'muted',
|
|
624
|
+
'playsinline',
|
|
625
|
+
'poster',
|
|
626
|
+
'preload',
|
|
627
|
+
'src',
|
|
628
|
+
'width'
|
|
629
|
+
],
|
|
630
|
+
|
|
631
|
+
svg: [
|
|
632
|
+
'className',
|
|
633
|
+
'class',
|
|
634
|
+
'color',
|
|
635
|
+
'height',
|
|
636
|
+
'id',
|
|
637
|
+
'lang',
|
|
638
|
+
'max',
|
|
639
|
+
'media',
|
|
640
|
+
'method',
|
|
641
|
+
'min',
|
|
642
|
+
'name',
|
|
643
|
+
'style',
|
|
644
|
+
'target',
|
|
645
|
+
'type',
|
|
646
|
+
'width',
|
|
647
|
+
|
|
648
|
+
// Other HTML properties supported by SVG elements in browsers
|
|
649
|
+
'role',
|
|
650
|
+
'tabindex',
|
|
651
|
+
'crossorigin',
|
|
652
|
+
|
|
653
|
+
// SVG Specific attributes
|
|
654
|
+
'accent-height',
|
|
655
|
+
'accumulate',
|
|
656
|
+
'additive',
|
|
657
|
+
'alignment-baseline',
|
|
658
|
+
'allowReorder',
|
|
659
|
+
'alphabetic',
|
|
660
|
+
'amplitude',
|
|
661
|
+
'arabic-form',
|
|
662
|
+
'ascent',
|
|
663
|
+
'attributeName',
|
|
664
|
+
'attributeType',
|
|
665
|
+
'autoReverse',
|
|
666
|
+
'azimuth',
|
|
667
|
+
'baseFrequency',
|
|
668
|
+
'baseline-shift',
|
|
669
|
+
'baseProfile',
|
|
670
|
+
'bbox',
|
|
671
|
+
'begin',
|
|
672
|
+
'bias',
|
|
673
|
+
'by',
|
|
674
|
+
'calcMode',
|
|
675
|
+
'cap-height',
|
|
676
|
+
'clip',
|
|
677
|
+
'clip-path',
|
|
678
|
+
'clipPathUnits',
|
|
679
|
+
'clip-rule',
|
|
680
|
+
'color-interpolation',
|
|
681
|
+
'color-interpolation-filters',
|
|
682
|
+
'color-profile',
|
|
683
|
+
'color-rendering',
|
|
684
|
+
'contentScriptType',
|
|
685
|
+
'contentStyleType',
|
|
686
|
+
'cursor',
|
|
687
|
+
'cx',
|
|
688
|
+
'cy',
|
|
689
|
+
'd',
|
|
690
|
+
'decelerate',
|
|
691
|
+
'descent',
|
|
692
|
+
'diffuseConstant',
|
|
693
|
+
'direction',
|
|
694
|
+
'display',
|
|
695
|
+
'divisor',
|
|
696
|
+
'dominant-baseline',
|
|
697
|
+
'dur',
|
|
698
|
+
'dx',
|
|
699
|
+
'dy',
|
|
700
|
+
'edgeMode',
|
|
701
|
+
'elevation',
|
|
702
|
+
'enable-background',
|
|
703
|
+
'end',
|
|
704
|
+
'exponent',
|
|
705
|
+
'externalResourcesRequired',
|
|
706
|
+
'fill',
|
|
707
|
+
'fill-opacity',
|
|
708
|
+
'fill-rule',
|
|
709
|
+
'filter',
|
|
710
|
+
'filterRes',
|
|
711
|
+
'filterUnits',
|
|
712
|
+
'flood-color',
|
|
713
|
+
'flood-opacity',
|
|
714
|
+
'focusable',
|
|
715
|
+
'font-family',
|
|
716
|
+
'font-size',
|
|
717
|
+
'font-size-adjust',
|
|
718
|
+
'font-stretch',
|
|
719
|
+
'font-style',
|
|
720
|
+
'font-variant',
|
|
721
|
+
'font-weight',
|
|
722
|
+
'format',
|
|
723
|
+
'from',
|
|
724
|
+
'fx',
|
|
725
|
+
'fy',
|
|
726
|
+
'g1',
|
|
727
|
+
'g2',
|
|
728
|
+
'glyph-name',
|
|
729
|
+
'glyph-orientation-horizontal',
|
|
730
|
+
'glyph-orientation-vertical',
|
|
731
|
+
'glyphRef',
|
|
732
|
+
'gradientTransform',
|
|
733
|
+
'gradientUnits',
|
|
734
|
+
'hanging',
|
|
735
|
+
'href',
|
|
736
|
+
'horiz-adv-x',
|
|
737
|
+
'horiz-origin-x',
|
|
738
|
+
'ideographic',
|
|
739
|
+
'image-rendering',
|
|
740
|
+
'in2',
|
|
741
|
+
'in',
|
|
742
|
+
'intercept',
|
|
743
|
+
'k1',
|
|
744
|
+
'k2',
|
|
745
|
+
'k3',
|
|
746
|
+
'k4',
|
|
747
|
+
'k',
|
|
748
|
+
'kernelMatrix',
|
|
749
|
+
'kernelUnitLength',
|
|
750
|
+
'kerning',
|
|
751
|
+
'keyPoints',
|
|
752
|
+
'keySplines',
|
|
753
|
+
'keyTimes',
|
|
754
|
+
'lengthAdjust',
|
|
755
|
+
'letter-spacing',
|
|
756
|
+
'lighting-color',
|
|
757
|
+
'limitingConeAngle',
|
|
758
|
+
'local',
|
|
759
|
+
'marker-end',
|
|
760
|
+
'markerHeight',
|
|
761
|
+
'marker-mid',
|
|
762
|
+
'marker-start',
|
|
763
|
+
'markerUnits',
|
|
764
|
+
'markerWidth',
|
|
765
|
+
'mask',
|
|
766
|
+
'maskContentUnits',
|
|
767
|
+
'maskUnits',
|
|
768
|
+
'mathematical',
|
|
769
|
+
'mode',
|
|
770
|
+
'numOctaves',
|
|
771
|
+
'offset',
|
|
772
|
+
'opacity',
|
|
773
|
+
'operator',
|
|
774
|
+
'order',
|
|
775
|
+
'orient',
|
|
776
|
+
'orientation',
|
|
777
|
+
'origin',
|
|
778
|
+
'overflow',
|
|
779
|
+
'overline-position',
|
|
780
|
+
'overline-thickness',
|
|
781
|
+
'paint-order',
|
|
782
|
+
'panose-1',
|
|
783
|
+
'path',
|
|
784
|
+
'pathLength',
|
|
785
|
+
'patternContentUnits',
|
|
786
|
+
'patternTransform',
|
|
787
|
+
'patternUnits',
|
|
788
|
+
'pointer-events',
|
|
789
|
+
'points',
|
|
790
|
+
'pointsAtX',
|
|
791
|
+
'pointsAtY',
|
|
792
|
+
'pointsAtZ',
|
|
793
|
+
'preserveAlpha',
|
|
794
|
+
'preserveAspectRatio',
|
|
795
|
+
'primitiveUnits',
|
|
796
|
+
'r',
|
|
797
|
+
'radius',
|
|
798
|
+
'refX',
|
|
799
|
+
'refY',
|
|
800
|
+
'rendering-intent',
|
|
801
|
+
'repeatCount',
|
|
802
|
+
'repeatDur',
|
|
803
|
+
'requiredExtensions',
|
|
804
|
+
'requiredFeatures',
|
|
805
|
+
'restart',
|
|
806
|
+
'result',
|
|
807
|
+
'rotate',
|
|
808
|
+
'rx',
|
|
809
|
+
'ry',
|
|
810
|
+
'scale',
|
|
811
|
+
'seed',
|
|
812
|
+
'shape-rendering',
|
|
813
|
+
'slope',
|
|
814
|
+
'spacing',
|
|
815
|
+
'specularConstant',
|
|
816
|
+
'specularExponent',
|
|
817
|
+
'speed',
|
|
818
|
+
'spreadMethod',
|
|
819
|
+
'startOffset',
|
|
820
|
+
'stdDeviation',
|
|
821
|
+
'stemh',
|
|
822
|
+
'stemv',
|
|
823
|
+
'stitchTiles',
|
|
824
|
+
'stop-color',
|
|
825
|
+
'stop-opacity',
|
|
826
|
+
'strikethrough-position',
|
|
827
|
+
'strikethrough-thickness',
|
|
828
|
+
'string',
|
|
829
|
+
'stroke',
|
|
830
|
+
'stroke-dasharray',
|
|
831
|
+
'stroke-dashoffset',
|
|
832
|
+
'stroke-linecap',
|
|
833
|
+
'stroke-linejoin',
|
|
834
|
+
'stroke-miterlimit',
|
|
835
|
+
'stroke-opacity',
|
|
836
|
+
'stroke-width',
|
|
837
|
+
'surfaceScale',
|
|
838
|
+
'systemLanguage',
|
|
839
|
+
'tableValues',
|
|
840
|
+
'targetX',
|
|
841
|
+
'targetY',
|
|
842
|
+
'text-anchor',
|
|
843
|
+
'text-decoration',
|
|
844
|
+
'textLength',
|
|
845
|
+
'text-rendering',
|
|
846
|
+
'to',
|
|
847
|
+
'transform',
|
|
848
|
+
'u1',
|
|
849
|
+
'u2',
|
|
850
|
+
'underline-position',
|
|
851
|
+
'underline-thickness',
|
|
852
|
+
'unicode',
|
|
853
|
+
'unicode-bidi',
|
|
854
|
+
'unicode-range',
|
|
855
|
+
'units-per-em',
|
|
856
|
+
'v-alphabetic',
|
|
857
|
+
'values',
|
|
858
|
+
'vector-effect',
|
|
859
|
+
'version',
|
|
860
|
+
'vert-adv-y',
|
|
861
|
+
'vert-origin-x',
|
|
862
|
+
'vert-origin-y',
|
|
863
|
+
'v-hanging',
|
|
864
|
+
'v-ideographic',
|
|
865
|
+
'viewBox',
|
|
866
|
+
'viewTarget',
|
|
867
|
+
'visibility',
|
|
868
|
+
'v-mathematical',
|
|
869
|
+
'widths',
|
|
870
|
+
'word-spacing',
|
|
871
|
+
'writing-mode',
|
|
872
|
+
'x1',
|
|
873
|
+
'x2',
|
|
874
|
+
'x',
|
|
875
|
+
'xChannelSelector',
|
|
876
|
+
'x-height',
|
|
877
|
+
'xlink:actuate',
|
|
878
|
+
'xlink:arcrole',
|
|
879
|
+
'xlink:href',
|
|
880
|
+
'xlink:role',
|
|
881
|
+
'xlink:show',
|
|
882
|
+
'xlink:title',
|
|
883
|
+
'xlink:type',
|
|
884
|
+
'xml:base',
|
|
885
|
+
'xml:lang',
|
|
886
|
+
'xmlns',
|
|
887
|
+
'xmlns:xlink',
|
|
888
|
+
'xml:space',
|
|
889
|
+
'y1',
|
|
890
|
+
'y2',
|
|
891
|
+
'y',
|
|
892
|
+
'yChannelSelector',
|
|
893
|
+
'z',
|
|
894
|
+
'zoomAndPan'
|
|
895
|
+
]
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
export const DOM_EVENTS = [
|
|
899
|
+
// Clipboard Events
|
|
900
|
+
'oncopy',
|
|
901
|
+
'oncut',
|
|
902
|
+
'onpaste',
|
|
903
|
+
|
|
904
|
+
// Composition Events
|
|
905
|
+
'oncompositionend',
|
|
906
|
+
'oncompositionstart',
|
|
907
|
+
'oncompositionupdate',
|
|
908
|
+
|
|
909
|
+
// Focus Events
|
|
910
|
+
'onfocus',
|
|
911
|
+
'onfocusin',
|
|
912
|
+
'onfocusout',
|
|
913
|
+
'onblur',
|
|
914
|
+
|
|
915
|
+
// Form Events
|
|
916
|
+
'onchange',
|
|
917
|
+
'onbeforeinput',
|
|
918
|
+
'oninput',
|
|
919
|
+
'onreset',
|
|
920
|
+
'onsubmit',
|
|
921
|
+
'oninvalid',
|
|
922
|
+
'onformdata',
|
|
923
|
+
|
|
924
|
+
// Image Events
|
|
925
|
+
'onload',
|
|
926
|
+
'onerror', // also a Media Event
|
|
927
|
+
|
|
928
|
+
// Detail Events
|
|
929
|
+
'ontoggle',
|
|
930
|
+
|
|
931
|
+
// Keyboard Events
|
|
932
|
+
'onkeydown',
|
|
933
|
+
'onkeypress',
|
|
934
|
+
'onkeyup',
|
|
935
|
+
|
|
936
|
+
// Media Events
|
|
937
|
+
'onabort',
|
|
938
|
+
'oncanplay',
|
|
939
|
+
'oncanplaythrough',
|
|
940
|
+
'oncuechange',
|
|
941
|
+
'ondurationchange',
|
|
942
|
+
'onemptied',
|
|
943
|
+
'onencrypted',
|
|
944
|
+
'onended',
|
|
945
|
+
'onloadeddata',
|
|
946
|
+
'onloadedmetadata',
|
|
947
|
+
'onloadstart',
|
|
948
|
+
'onpause',
|
|
949
|
+
'onplay',
|
|
950
|
+
'onplaying',
|
|
951
|
+
'onprogress',
|
|
952
|
+
'onratechange',
|
|
953
|
+
'onseeked',
|
|
954
|
+
'onseeking',
|
|
955
|
+
'onstalled',
|
|
956
|
+
'onsuspend',
|
|
957
|
+
'ontimeupdate',
|
|
958
|
+
'onvolumechange',
|
|
959
|
+
'onwaiting',
|
|
960
|
+
|
|
961
|
+
// MouseEvents
|
|
962
|
+
'onauxclick',
|
|
963
|
+
'onclick',
|
|
964
|
+
'oncontextmenu',
|
|
965
|
+
'ondblclick',
|
|
966
|
+
'ondrag',
|
|
967
|
+
'ondragend',
|
|
968
|
+
'ondragenter',
|
|
969
|
+
'ondragexit',
|
|
970
|
+
'ondragleave',
|
|
971
|
+
'ondragover',
|
|
972
|
+
'ondragstart',
|
|
973
|
+
'ondrop',
|
|
974
|
+
'onmousedown',
|
|
975
|
+
'onmouseenter',
|
|
976
|
+
'onmouseleave',
|
|
977
|
+
'onmousemove',
|
|
978
|
+
'onmouseout',
|
|
979
|
+
'onmouseover',
|
|
980
|
+
'onmouseup',
|
|
981
|
+
|
|
982
|
+
// Selection Events
|
|
983
|
+
'onselect',
|
|
984
|
+
'onselectionchange',
|
|
985
|
+
'onselectstart',
|
|
986
|
+
|
|
987
|
+
// Touch Events
|
|
988
|
+
'ontouchcancel',
|
|
989
|
+
'ontouchend',
|
|
990
|
+
'ontouchmove',
|
|
991
|
+
'ontouchstart',
|
|
992
|
+
|
|
993
|
+
// Pointer Events
|
|
994
|
+
'ongotpointercapture',
|
|
995
|
+
'onpointercancel',
|
|
996
|
+
'onpointerdown',
|
|
997
|
+
'onpointerenter',
|
|
998
|
+
'onpointerleave',
|
|
999
|
+
'onpointermove',
|
|
1000
|
+
'onpointerout',
|
|
1001
|
+
'onpointerover',
|
|
1002
|
+
'onpointerup',
|
|
1003
|
+
'onlostpointercapture',
|
|
1004
|
+
|
|
1005
|
+
// UI Events
|
|
1006
|
+
'onscroll',
|
|
1007
|
+
'onresize',
|
|
1008
|
+
|
|
1009
|
+
// Wheel Events
|
|
1010
|
+
'onwheel',
|
|
1011
|
+
|
|
1012
|
+
// Animation Events
|
|
1013
|
+
'onanimationstart',
|
|
1014
|
+
'onanimationend',
|
|
1015
|
+
'onanimationiteration',
|
|
1016
|
+
|
|
1017
|
+
// Transition Events
|
|
1018
|
+
'ontransitionstart',
|
|
1019
|
+
'ontransitionrun',
|
|
1020
|
+
'ontransitionend',
|
|
1021
|
+
'ontransitioncancel',
|
|
1022
|
+
|
|
1023
|
+
// Svelte Transition Events
|
|
1024
|
+
'onoutrostart',
|
|
1025
|
+
'onoutroend',
|
|
1026
|
+
'onintrostart',
|
|
1027
|
+
'onintroend',
|
|
1028
|
+
|
|
1029
|
+
// Message Events
|
|
1030
|
+
'onmessage',
|
|
1031
|
+
'onmessageerror',
|
|
1032
|
+
|
|
1033
|
+
// Document Events
|
|
1034
|
+
'onvisibilitychange',
|
|
1035
|
+
|
|
1036
|
+
// Global Events
|
|
1037
|
+
'oncancel',
|
|
1038
|
+
'onclose',
|
|
1039
|
+
'onfullscreenchange',
|
|
1040
|
+
'onfullscreenerror'
|
|
1041
|
+
]
|
|
1042
|
+
|
|
1043
|
+
// Convert camelCase aria/data attrs to kebab-case: ariaLabel → aria-label, dataTestId → data-test-id
|
|
1044
|
+
const camelToAttr = (key) => {
|
|
1045
|
+
if (key.startsWith('aria') && key.length > 4 && key.charCodeAt(4) >= 65 && key.charCodeAt(4) <= 90) {
|
|
1046
|
+
return 'aria-' + key.charAt(4).toLowerCase() + key.slice(5).replace(/([A-Z])/g, (m) => '-' + m.toLowerCase())
|
|
1047
|
+
}
|
|
1048
|
+
if (key.startsWith('data') && key.length > 4 && key.charCodeAt(4) >= 65 && key.charCodeAt(4) <= 90) {
|
|
1049
|
+
return 'data-' + key.charAt(4).toLowerCase() + key.slice(5).replace(/([A-Z])/g, (m) => '-' + m.toLowerCase())
|
|
1050
|
+
}
|
|
1051
|
+
return null
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
export const checkAttributeByTagName = (tag, attribute) => {
|
|
1055
|
+
// aria-* and data-* are valid on all elements
|
|
1056
|
+
if (attribute.startsWith('aria-') || attribute.startsWith('data-')) return true
|
|
1057
|
+
// camelCase aria/data attrs
|
|
1058
|
+
if (camelToAttr(attribute)) return true
|
|
1059
|
+
|
|
1060
|
+
// Global attributes (`title`, `id`, `class`, `role`, `tabindex`, `hidden`,
|
|
1061
|
+
// `lang`, `dir`, `draggable`, `contenteditable`, `spellcheck`, `slot`, …)
|
|
1062
|
+
// apply to every tag. Prior behavior only consulted HTML_ATTRIBUTES.default
|
|
1063
|
+
// for tags WITHOUT a per-tag list, which silently dropped global attrs on
|
|
1064
|
+
// every typed tag (button/a/img/input/...). Always allow defaults first,
|
|
1065
|
+
// then tag-specific extras.
|
|
1066
|
+
if (HTML_ATTRIBUTES.default.includes(attribute)) return true
|
|
1067
|
+
|
|
1068
|
+
if (Object.prototype.hasOwnProperty.call(HTML_ATTRIBUTES, tag)) {
|
|
1069
|
+
const attributes = HTML_ATTRIBUTES[tag]
|
|
1070
|
+
return attributes.includes(attribute)
|
|
1071
|
+
}
|
|
1072
|
+
return false
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
export const checkEventFunctions = (key) => {
|
|
1076
|
+
if (!isString(key)) return false
|
|
1077
|
+
const normalizedKey = key.toLowerCase()
|
|
1078
|
+
return DOM_EVENTS.includes(normalizedKey)
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
export const filterAttributesByTagName = (tag, props, cssProps) => {
|
|
1082
|
+
const filteredObject = {}
|
|
1083
|
+
|
|
1084
|
+
for (const key in props) {
|
|
1085
|
+
if (Object.prototype.hasOwnProperty.call(props, key)) {
|
|
1086
|
+
if (cssProps && key in cssProps) continue
|
|
1087
|
+
|
|
1088
|
+
// aria: { label: 'foo', expanded: true } → aria-label, aria-expanded
|
|
1089
|
+
// Function values are stored as-is here; `executeAttr` is the single
|
|
1090
|
+
// place that resolves reactive (el, state) → string for HTML attrs.
|
|
1091
|
+
// We funnel aria/data through `attr` instead of duplicating execution
|
|
1092
|
+
// logic so v3.14 reactive aria/data attributes work with the same
|
|
1093
|
+
// re-render cycle as `attr.foo` — see FA-L1.
|
|
1094
|
+
if (key === 'aria' && props[key] && typeof props[key] === 'object') {
|
|
1095
|
+
for (const ariaKey in props[key]) {
|
|
1096
|
+
if (isDefined(props[key][ariaKey])) {
|
|
1097
|
+
filteredObject['aria-' + ariaKey] = props[key][ariaKey]
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
continue
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// data: { testId: 'foo' } → data-test-id
|
|
1104
|
+
if (key === 'data' && props[key] && typeof props[key] === 'object') {
|
|
1105
|
+
for (const dataKey in props[key]) {
|
|
1106
|
+
if (isDefined(props[key][dataKey])) {
|
|
1107
|
+
const kebab = dataKey.replace(/([A-Z])/g, (m) => '-' + m.toLowerCase())
|
|
1108
|
+
filteredObject['data-' + kebab] = props[key][dataKey]
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
continue
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
const isAttribute = checkAttributeByTagName(tag, key)
|
|
1115
|
+
const isEvent = checkEventFunctions(key)
|
|
1116
|
+
if (isDefined(props[key]) && (isAttribute || isEvent)) {
|
|
1117
|
+
const attrName = camelToAttr(key) || key
|
|
1118
|
+
filteredObject[attrName] = props[key]
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
return filteredObject
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
export const executeAttr = (elem, element) => {
|
|
1127
|
+
const attrObj = {}
|
|
1128
|
+
if (elem.attr) {
|
|
1129
|
+
for (const attrProp in elem.attr) {
|
|
1130
|
+
attrObj[attrProp] = elem.attr[attrProp](element, element.state, element.context)
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
// FA-L1: aria.X and data.X with FUNCTION values must execute the same way
|
|
1134
|
+
// as attr.X. Without this, `aria: { label: (el, s) => s.text }` writes a
|
|
1135
|
+
// function reference to the DOM attribute and renders as `null`.
|
|
1136
|
+
// Static (non-function) aria/data values are already promoted to flat
|
|
1137
|
+
// attributes by `filterAttributesByTagName`; we only handle functions
|
|
1138
|
+
// here to avoid double-write.
|
|
1139
|
+
if (elem.aria && typeof elem.aria === 'object') {
|
|
1140
|
+
for (const ariaKey in elem.aria) {
|
|
1141
|
+
const v = elem.aria[ariaKey]
|
|
1142
|
+
if (typeof v === 'function') {
|
|
1143
|
+
attrObj['aria-' + ariaKey] = v(element, element.state, element.context)
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
if (elem.data && typeof elem.data === 'object') {
|
|
1148
|
+
for (const dataKey in elem.data) {
|
|
1149
|
+
const v = elem.data[dataKey]
|
|
1150
|
+
if (typeof v === 'function') {
|
|
1151
|
+
const kebab = dataKey.replace(/([A-Z])/g, (m) => '-' + m.toLowerCase())
|
|
1152
|
+
attrObj['data-' + kebab] = v(element, element.state, element.context)
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return attrObj
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Resolves a prop value: executes dynamic values and replaces template literals.
|
|
1161
|
+
* Shared logic for src, href, action, poster, data, etc.
|
|
1162
|
+
*/
|
|
1163
|
+
export const resolvePropValue = (el, value) => {
|
|
1164
|
+
let resolved = el.call('exec', value, el)
|
|
1165
|
+
if (!resolved) return
|
|
1166
|
+
if (isString(resolved) && resolved.includes('{{')) {
|
|
1167
|
+
resolved = el.call('replaceLiteralsWithObjectFields', resolved)
|
|
1168
|
+
}
|
|
1169
|
+
return resolved
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
* Resolve a file URL from context.files or context.assets.
|
|
1174
|
+
* Handles absolute URLs (passthrough), /files/ and /assets/ prefix routing,
|
|
1175
|
+
* and lookup for bundler-resolved paths. An explicit `/files/` or `/assets/`
|
|
1176
|
+
* prefix is authoritative — we do NOT cross-route between the two maps.
|
|
1177
|
+
*/
|
|
1178
|
+
export const resolveFileSource = (el, value) => {
|
|
1179
|
+
let src = (el.preSrc || '') + (resolvePropValue(el, value) || '')
|
|
1180
|
+
if (!src) return
|
|
1181
|
+
|
|
1182
|
+
try { new URL(src); return src } catch (e) { } // absolute URL — passthrough
|
|
1183
|
+
|
|
1184
|
+
const { context } = el
|
|
1185
|
+
if (!context.files && !context.assets) return src
|
|
1186
|
+
|
|
1187
|
+
if (src.startsWith('/assets/')) {
|
|
1188
|
+
const key = src.slice(8)
|
|
1189
|
+
const asset = context.assets && (context.assets[src] || context.assets[key])
|
|
1190
|
+
if (asset && asset.content) return asset.content.src
|
|
1191
|
+
return src
|
|
1192
|
+
}
|
|
1193
|
+
if (src.startsWith('/files/')) {
|
|
1194
|
+
const key = src.slice(7)
|
|
1195
|
+
const file = context.files && (context.files[src] || context.files[key])
|
|
1196
|
+
if (file && file.content) return file.content.src
|
|
1197
|
+
return src
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
// Unprefixed: try assets first (newer system), then files.
|
|
1201
|
+
if (context.assets) {
|
|
1202
|
+
const asset = context.assets[src]
|
|
1203
|
+
if (asset && asset.content) return asset.content.src
|
|
1204
|
+
}
|
|
1205
|
+
if (context.files) {
|
|
1206
|
+
const file = context.files[src]
|
|
1207
|
+
if (file && file.content) return file.content.src
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
return src
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Auto-resolve attribute transformers.
|
|
1215
|
+
* Attributes listed here are automatically resolved from props
|
|
1216
|
+
* via resolvePropValue (exec + template literal replacement).
|
|
1217
|
+
* src and poster also resolve from context.files for media elements.
|
|
1218
|
+
*/
|
|
1219
|
+
export const ATTR_TRANSFORMS = {
|
|
1220
|
+
src: (el) => resolveFileSource(el, el.src),
|
|
1221
|
+
href: (el) => resolvePropValue(el, el.href),
|
|
1222
|
+
action: (el) => resolvePropValue(el, el.action),
|
|
1223
|
+
poster: (el) => resolveFileSource(el, el.poster),
|
|
1224
|
+
data: (el) => resolvePropValue(el, el.data)
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* Applies ATTR_TRANSFORMS for valid attributes on the element's tag.
|
|
1229
|
+
* Returns resolved attribute values from props.
|
|
1230
|
+
*/
|
|
1231
|
+
export const applyAttrTransforms = (element) => {
|
|
1232
|
+
const tag = element.tag || 'div'
|
|
1233
|
+
const result = {}
|
|
1234
|
+
for (const attr in ATTR_TRANSFORMS) {
|
|
1235
|
+
if (element[attr] !== undefined && checkAttributeByTagName(tag, attr)) {
|
|
1236
|
+
const val = ATTR_TRANSFORMS[attr](element)
|
|
1237
|
+
if (val !== undefined) result[attr] = val
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return result
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Resolve a case value from context.cases.
|
|
1245
|
+
* Returns true/false, or undefined if case is not defined.
|
|
1246
|
+
*/
|
|
1247
|
+
const resolveCase = (caseKey, element) => {
|
|
1248
|
+
const caseFn = element.context?.cases?.[caseKey]
|
|
1249
|
+
if (caseFn === undefined) return undefined
|
|
1250
|
+
if (isFunction(caseFn)) return caseFn.call(element, element)
|
|
1251
|
+
return !!caseFn
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Evaluate whether a conditional prefix key is active.
|
|
1256
|
+
* Supports $ (global cases), . (truthy), ! (falsy) prefixes.
|
|
1257
|
+
*/
|
|
1258
|
+
const evaluateCondition = (prefix, caseKey, element) => {
|
|
1259
|
+
if (prefix === '$') {
|
|
1260
|
+
let result = resolveCase(caseKey, element)
|
|
1261
|
+
if (result === undefined) result = !!element[caseKey]
|
|
1262
|
+
return result
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// . and ! prefixes: check element/state first, then context.cases
|
|
1266
|
+
let isTruthy = element[caseKey] === true || element.state[caseKey]
|
|
1267
|
+
if (!isTruthy) {
|
|
1268
|
+
const caseResult = resolveCase(caseKey, element)
|
|
1269
|
+
if (caseResult !== undefined) isTruthy = caseResult
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
return prefix === '.' ? !!isTruthy : !isTruthy
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
const CONDITIONAL_PREFIXES = new Set(['$', '.', '!'])
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* Extract HTML attributes from conditional blocks ($, ., !) in props.
|
|
1279
|
+
* Returns an attr object with functions that re-evaluate on each update.
|
|
1280
|
+
*/
|
|
1281
|
+
export const extractConditionalAttrs = (props, tag, cssProps) => {
|
|
1282
|
+
const result = {}
|
|
1283
|
+
|
|
1284
|
+
const addConditionalAttr = (attrName, attrVal, prefix, caseKey) => {
|
|
1285
|
+
const capturedVal = attrVal
|
|
1286
|
+
result[attrName] = (el) => {
|
|
1287
|
+
if (!evaluateCondition(prefix, caseKey, el)) return undefined
|
|
1288
|
+
return isFunction(capturedVal) ? capturedVal(el) : capturedVal
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
for (const key in props) {
|
|
1293
|
+
const prefix = key.charAt(0)
|
|
1294
|
+
if (!CONDITIONAL_PREFIXES.has(prefix)) continue
|
|
1295
|
+
|
|
1296
|
+
const block = props[key]
|
|
1297
|
+
if (!block || typeof block !== 'object') continue
|
|
1298
|
+
|
|
1299
|
+
const caseKey = key.slice(1)
|
|
1300
|
+
|
|
1301
|
+
for (const attrKey in block) {
|
|
1302
|
+
if (cssProps && attrKey in cssProps) continue
|
|
1303
|
+
|
|
1304
|
+
// aria: { label: 'foo' } inside conditional block
|
|
1305
|
+
if (attrKey === 'aria' && block[attrKey] && typeof block[attrKey] === 'object') {
|
|
1306
|
+
for (const ariaKey in block[attrKey]) {
|
|
1307
|
+
addConditionalAttr('aria-' + ariaKey, block[attrKey][ariaKey], prefix, caseKey)
|
|
1308
|
+
}
|
|
1309
|
+
continue
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// data: { testId: 'foo' } inside conditional block
|
|
1313
|
+
if (attrKey === 'data' && block[attrKey] && typeof block[attrKey] === 'object') {
|
|
1314
|
+
for (const dataKey in block[attrKey]) {
|
|
1315
|
+
const kebab = dataKey.replace(/([A-Z])/g, (m) => '-' + m.toLowerCase())
|
|
1316
|
+
addConditionalAttr('data-' + kebab, block[attrKey][dataKey], prefix, caseKey)
|
|
1317
|
+
}
|
|
1318
|
+
continue
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
const isAttribute = checkAttributeByTagName(tag, attrKey)
|
|
1322
|
+
const isEvent = checkEventFunctions(attrKey)
|
|
1323
|
+
if (!isAttribute && !isEvent) continue
|
|
1324
|
+
|
|
1325
|
+
const attrName = camelToAttr(attrKey) || attrKey
|
|
1326
|
+
addConditionalAttr(attrName, block[attrKey], prefix, caseKey)
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
return result
|
|
1331
|
+
}
|
package/package.json
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"name": "attrs-in-props",
|
|
3
3
|
"description": "Utilize props as attributes",
|
|
4
4
|
"author": "symbo.ls",
|
|
5
|
-
"version": "3.14.
|
|
5
|
+
"version": "3.14.8",
|
|
6
6
|
"repository": "https://github.com/symbo-ls/smbls",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "./dist/esm/index.js",
|
|
9
9
|
"main": "./dist/cjs/index.js",
|
|
10
10
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@symbo.ls/utils": "^3.14.
|
|
12
|
+
"@symbo.ls/utils": "^3.14.15"
|
|
13
13
|
},
|
|
14
14
|
"source": "index.js",
|
|
15
15
|
"browser": "./dist/esm/index.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|
|
28
|
+
"*.js",
|
|
28
29
|
"*.md",
|
|
29
30
|
"LICENSE"
|
|
30
31
|
],
|