@fictjs/runtime 0.0.12 → 0.0.13

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/src/constants.ts CHANGED
@@ -5,6 +5,11 @@
5
5
  * Borrowed from dom-expressions for comprehensive DOM support.
6
6
  */
7
7
 
8
+ const isDev =
9
+ typeof __DEV__ !== 'undefined'
10
+ ? __DEV__
11
+ : typeof process === 'undefined' || process.env?.NODE_ENV !== 'production'
12
+
8
13
  // ============================================================================
9
14
  // Boolean Attributes
10
15
  // ============================================================================
@@ -13,50 +18,52 @@
13
18
  * Complete list of boolean attributes (lowercase)
14
19
  * These attributes are set as empty strings when true, removed when false
15
20
  */
16
- const booleans = [
17
- 'allowfullscreen',
18
- 'async',
19
- 'alpha', // HTMLInputElement
20
- 'autofocus', // HTMLElement prop
21
- 'autoplay',
22
- 'checked',
23
- 'controls',
24
- 'default',
25
- 'disabled',
26
- 'formnovalidate',
27
- 'hidden', // HTMLElement prop
28
- 'indeterminate',
29
- 'inert', // HTMLElement prop
30
- 'ismap',
31
- 'loop',
32
- 'multiple',
33
- 'muted',
34
- 'nomodule',
35
- 'novalidate',
36
- 'open',
37
- 'playsinline',
38
- 'readonly',
39
- 'required',
40
- 'reversed',
41
- 'seamless', // HTMLIframeElement - non-standard
42
- 'selected',
43
- // Experimental attributes
44
- 'adauctionheaders',
45
- 'browsingtopics',
46
- 'credentialless',
47
- 'defaultchecked',
48
- 'defaultmuted',
49
- 'defaultselected',
50
- 'defer',
51
- 'disablepictureinpicture',
52
- 'disableremoteplayback',
53
- 'preservespitch',
54
- 'shadowrootclonable',
55
- 'shadowrootcustomelementregistry',
56
- 'shadowrootdelegatesfocus',
57
- 'shadowrootserializable',
58
- 'sharedstoragewritable',
59
- ] as const
21
+ const booleans = isDev
22
+ ? [
23
+ 'allowfullscreen',
24
+ 'async',
25
+ 'alpha', // HTMLInputElement
26
+ 'autofocus', // HTMLElement prop
27
+ 'autoplay',
28
+ 'checked',
29
+ 'controls',
30
+ 'default',
31
+ 'disabled',
32
+ 'formnovalidate',
33
+ 'hidden', // HTMLElement prop
34
+ 'indeterminate',
35
+ 'inert', // HTMLElement prop
36
+ 'ismap',
37
+ 'loop',
38
+ 'multiple',
39
+ 'muted',
40
+ 'nomodule',
41
+ 'novalidate',
42
+ 'open',
43
+ 'playsinline',
44
+ 'readonly',
45
+ 'required',
46
+ 'reversed',
47
+ 'seamless', // HTMLIframeElement - non-standard
48
+ 'selected',
49
+ // Experimental attributes
50
+ 'adauctionheaders',
51
+ 'browsingtopics',
52
+ 'credentialless',
53
+ 'defaultchecked',
54
+ 'defaultmuted',
55
+ 'defaultselected',
56
+ 'defer',
57
+ 'disablepictureinpicture',
58
+ 'disableremoteplayback',
59
+ 'preservespitch',
60
+ 'shadowrootclonable',
61
+ 'shadowrootcustomelementregistry',
62
+ 'shadowrootdelegatesfocus',
63
+ 'shadowrootserializable',
64
+ 'sharedstoragewritable',
65
+ ]
66
+ : []
60
67
 
61
68
  export const BooleanAttributes = new Set<string>(booleans)
62
69
 
@@ -68,38 +75,42 @@ export const BooleanAttributes = new Set<string>(booleans)
68
75
  * Properties that should be set via DOM property (not attribute)
69
76
  * Includes camelCase versions of boolean attributes
70
77
  */
71
- export const Properties = new Set<string>([
72
- // Core properties
73
- 'className',
74
- 'value',
78
+ const properties = isDev
79
+ ? [
80
+ // Core properties
81
+ 'className',
82
+ 'value',
75
83
 
76
- // CamelCase booleans
77
- 'readOnly',
78
- 'noValidate',
79
- 'formNoValidate',
80
- 'isMap',
81
- 'noModule',
82
- 'playsInline',
84
+ // CamelCase booleans
85
+ 'readOnly',
86
+ 'noValidate',
87
+ 'formNoValidate',
88
+ 'isMap',
89
+ 'noModule',
90
+ 'playsInline',
83
91
 
84
- // Experimental (camelCase)
85
- 'adAuctionHeaders',
86
- 'allowFullscreen',
87
- 'browsingTopics',
88
- 'defaultChecked',
89
- 'defaultMuted',
90
- 'defaultSelected',
91
- 'disablePictureInPicture',
92
- 'disableRemotePlayback',
93
- 'preservesPitch',
94
- 'shadowRootClonable',
95
- 'shadowRootCustomElementRegistry',
96
- 'shadowRootDelegatesFocus',
97
- 'shadowRootSerializable',
98
- 'sharedStorageWritable',
92
+ // Experimental (camelCase)
93
+ 'adAuctionHeaders',
94
+ 'allowFullscreen',
95
+ 'browsingTopics',
96
+ 'defaultChecked',
97
+ 'defaultMuted',
98
+ 'defaultSelected',
99
+ 'disablePictureInPicture',
100
+ 'disableRemotePlayback',
101
+ 'preservesPitch',
102
+ 'shadowRootClonable',
103
+ 'shadowRootCustomElementRegistry',
104
+ 'shadowRootDelegatesFocus',
105
+ 'shadowRootSerializable',
106
+ 'sharedStorageWritable',
99
107
 
100
- // All lowercase booleans
101
- ...booleans,
102
- ])
108
+ // All lowercase booleans
109
+ ...booleans,
110
+ ]
111
+ : []
112
+
113
+ export const Properties = new Set<string>(properties)
103
114
 
104
115
  // ============================================================================
105
116
  // Child Properties
@@ -132,104 +143,105 @@ export const Aliases: Record<string, string> = {
132
143
  * Maps lowercase attribute names to their camelCase property equivalents
133
144
  * Only for specific elements that have these properties
134
145
  */
135
- export const PropAliases: Record<
136
- string,
137
- string | { $: string; [tagName: string]: string | number }
138
- > = {
139
- // Direct mapping
140
- class: 'className',
146
+ const PropAliases: Record<string, string | { $: string; [tagName: string]: string | number }> =
147
+ isDev
148
+ ? {
149
+ // Direct mapping
150
+ class: 'className',
141
151
 
142
- // Element-specific mappings
143
- novalidate: {
144
- $: 'noValidate',
145
- FORM: 1,
146
- },
147
- formnovalidate: {
148
- $: 'formNoValidate',
149
- BUTTON: 1,
150
- INPUT: 1,
151
- },
152
- ismap: {
153
- $: 'isMap',
154
- IMG: 1,
155
- },
156
- nomodule: {
157
- $: 'noModule',
158
- SCRIPT: 1,
159
- },
160
- playsinline: {
161
- $: 'playsInline',
162
- VIDEO: 1,
163
- },
164
- readonly: {
165
- $: 'readOnly',
166
- INPUT: 1,
167
- TEXTAREA: 1,
168
- },
152
+ // Element-specific mappings
153
+ novalidate: {
154
+ $: 'noValidate',
155
+ FORM: 1,
156
+ },
157
+ formnovalidate: {
158
+ $: 'formNoValidate',
159
+ BUTTON: 1,
160
+ INPUT: 1,
161
+ },
162
+ ismap: {
163
+ $: 'isMap',
164
+ IMG: 1,
165
+ },
166
+ nomodule: {
167
+ $: 'noModule',
168
+ SCRIPT: 1,
169
+ },
170
+ playsinline: {
171
+ $: 'playsInline',
172
+ VIDEO: 1,
173
+ },
174
+ readonly: {
175
+ $: 'readOnly',
176
+ INPUT: 1,
177
+ TEXTAREA: 1,
178
+ },
169
179
 
170
- // Experimental element-specific
171
- adauctionheaders: {
172
- $: 'adAuctionHeaders',
173
- IFRAME: 1,
174
- },
175
- allowfullscreen: {
176
- $: 'allowFullscreen',
177
- IFRAME: 1,
178
- },
179
- browsingtopics: {
180
- $: 'browsingTopics',
181
- IMG: 1,
182
- },
183
- defaultchecked: {
184
- $: 'defaultChecked',
185
- INPUT: 1,
186
- },
187
- defaultmuted: {
188
- $: 'defaultMuted',
189
- AUDIO: 1,
190
- VIDEO: 1,
191
- },
192
- defaultselected: {
193
- $: 'defaultSelected',
194
- OPTION: 1,
195
- },
196
- disablepictureinpicture: {
197
- $: 'disablePictureInPicture',
198
- VIDEO: 1,
199
- },
200
- disableremoteplayback: {
201
- $: 'disableRemotePlayback',
202
- AUDIO: 1,
203
- VIDEO: 1,
204
- },
205
- preservespitch: {
206
- $: 'preservesPitch',
207
- AUDIO: 1,
208
- VIDEO: 1,
209
- },
210
- shadowrootclonable: {
211
- $: 'shadowRootClonable',
212
- TEMPLATE: 1,
213
- },
214
- shadowrootdelegatesfocus: {
215
- $: 'shadowRootDelegatesFocus',
216
- TEMPLATE: 1,
217
- },
218
- shadowrootserializable: {
219
- $: 'shadowRootSerializable',
220
- TEMPLATE: 1,
221
- },
222
- sharedstoragewritable: {
223
- $: 'sharedStorageWritable',
224
- IFRAME: 1,
225
- IMG: 1,
226
- },
227
- }
180
+ // Experimental element-specific
181
+ adauctionheaders: {
182
+ $: 'adAuctionHeaders',
183
+ IFRAME: 1,
184
+ },
185
+ allowfullscreen: {
186
+ $: 'allowFullscreen',
187
+ IFRAME: 1,
188
+ },
189
+ browsingtopics: {
190
+ $: 'browsingTopics',
191
+ IMG: 1,
192
+ },
193
+ defaultchecked: {
194
+ $: 'defaultChecked',
195
+ INPUT: 1,
196
+ },
197
+ defaultmuted: {
198
+ $: 'defaultMuted',
199
+ AUDIO: 1,
200
+ VIDEO: 1,
201
+ },
202
+ defaultselected: {
203
+ $: 'defaultSelected',
204
+ OPTION: 1,
205
+ },
206
+ disablepictureinpicture: {
207
+ $: 'disablePictureInPicture',
208
+ VIDEO: 1,
209
+ },
210
+ disableremoteplayback: {
211
+ $: 'disableRemotePlayback',
212
+ AUDIO: 1,
213
+ VIDEO: 1,
214
+ },
215
+ preservespitch: {
216
+ $: 'preservesPitch',
217
+ AUDIO: 1,
218
+ VIDEO: 1,
219
+ },
220
+ shadowrootclonable: {
221
+ $: 'shadowRootClonable',
222
+ TEMPLATE: 1,
223
+ },
224
+ shadowrootdelegatesfocus: {
225
+ $: 'shadowRootDelegatesFocus',
226
+ TEMPLATE: 1,
227
+ },
228
+ shadowrootserializable: {
229
+ $: 'shadowRootSerializable',
230
+ TEMPLATE: 1,
231
+ },
232
+ sharedstoragewritable: {
233
+ $: 'sharedStorageWritable',
234
+ IFRAME: 1,
235
+ IMG: 1,
236
+ },
237
+ }
238
+ : {}
228
239
 
229
240
  /**
230
241
  * Get the property alias for a given attribute and tag name
231
242
  */
232
243
  export function getPropAlias(prop: string, tagName: string): string | undefined {
244
+ if (!isDev) return undefined
233
245
  const a = PropAliases[prop]
234
246
  if (typeof a === 'object') {
235
247
  return a[tagName] ? a['$'] : undefined
@@ -250,30 +262,34 @@ export const $$EVENTS = '_$FICT_DELEGATE'
250
262
  * Events that should use event delegation for performance
251
263
  * These events bubble and are commonly used across many elements
252
264
  */
253
- export const DelegatedEvents = new Set<string>([
254
- 'beforeinput',
255
- 'click',
256
- 'dblclick',
257
- 'contextmenu',
258
- 'focusin',
259
- 'focusout',
260
- 'input',
261
- 'keydown',
262
- 'keyup',
263
- 'mousedown',
264
- 'mousemove',
265
- 'mouseout',
266
- 'mouseover',
267
- 'mouseup',
268
- 'pointerdown',
269
- 'pointermove',
270
- 'pointerout',
271
- 'pointerover',
272
- 'pointerup',
273
- 'touchend',
274
- 'touchmove',
275
- 'touchstart',
276
- ])
265
+ const delegatedEvents = isDev
266
+ ? [
267
+ 'beforeinput',
268
+ 'click',
269
+ 'dblclick',
270
+ 'contextmenu',
271
+ 'focusin',
272
+ 'focusout',
273
+ 'input',
274
+ 'keydown',
275
+ 'keyup',
276
+ 'mousedown',
277
+ 'mousemove',
278
+ 'mouseout',
279
+ 'mouseover',
280
+ 'mouseup',
281
+ 'pointerdown',
282
+ 'pointermove',
283
+ 'pointerout',
284
+ 'pointerover',
285
+ 'pointerup',
286
+ 'touchend',
287
+ 'touchmove',
288
+ 'touchstart',
289
+ ]
290
+ : []
291
+
292
+ export const DelegatedEvents = new Set<string>(delegatedEvents)
277
293
 
278
294
  // ============================================================================
279
295
  // SVG Support
@@ -282,85 +298,89 @@ export const DelegatedEvents = new Set<string>([
282
298
  /**
283
299
  * SVG element names (excluding common ones that overlap with HTML)
284
300
  */
285
- export const SVGElements = new Set<string>([
286
- 'altGlyph',
287
- 'altGlyphDef',
288
- 'altGlyphItem',
289
- 'animate',
290
- 'animateColor',
291
- 'animateMotion',
292
- 'animateTransform',
293
- 'circle',
294
- 'clipPath',
295
- 'color-profile',
296
- 'cursor',
297
- 'defs',
298
- 'desc',
299
- 'ellipse',
300
- 'feBlend',
301
- 'feColorMatrix',
302
- 'feComponentTransfer',
303
- 'feComposite',
304
- 'feConvolveMatrix',
305
- 'feDiffuseLighting',
306
- 'feDisplacementMap',
307
- 'feDistantLight',
308
- 'feDropShadow',
309
- 'feFlood',
310
- 'feFuncA',
311
- 'feFuncB',
312
- 'feFuncG',
313
- 'feFuncR',
314
- 'feGaussianBlur',
315
- 'feImage',
316
- 'feMerge',
317
- 'feMergeNode',
318
- 'feMorphology',
319
- 'feOffset',
320
- 'fePointLight',
321
- 'feSpecularLighting',
322
- 'feSpotLight',
323
- 'feTile',
324
- 'feTurbulence',
325
- 'filter',
326
- 'font',
327
- 'font-face',
328
- 'font-face-format',
329
- 'font-face-name',
330
- 'font-face-src',
331
- 'font-face-uri',
332
- 'foreignObject',
333
- 'g',
334
- 'glyph',
335
- 'glyphRef',
336
- 'hkern',
337
- 'image',
338
- 'line',
339
- 'linearGradient',
340
- 'marker',
341
- 'mask',
342
- 'metadata',
343
- 'missing-glyph',
344
- 'mpath',
345
- 'path',
346
- 'pattern',
347
- 'polygon',
348
- 'polyline',
349
- 'radialGradient',
350
- 'rect',
351
- 'set',
352
- 'stop',
353
- 'svg',
354
- 'switch',
355
- 'symbol',
356
- 'text',
357
- 'textPath',
358
- 'tref',
359
- 'tspan',
360
- 'use',
361
- 'view',
362
- 'vkern',
363
- ])
301
+ const svgElements = isDev
302
+ ? [
303
+ 'altGlyph',
304
+ 'altGlyphDef',
305
+ 'altGlyphItem',
306
+ 'animate',
307
+ 'animateColor',
308
+ 'animateMotion',
309
+ 'animateTransform',
310
+ 'circle',
311
+ 'clipPath',
312
+ 'color-profile',
313
+ 'cursor',
314
+ 'defs',
315
+ 'desc',
316
+ 'ellipse',
317
+ 'feBlend',
318
+ 'feColorMatrix',
319
+ 'feComponentTransfer',
320
+ 'feComposite',
321
+ 'feConvolveMatrix',
322
+ 'feDiffuseLighting',
323
+ 'feDisplacementMap',
324
+ 'feDistantLight',
325
+ 'feDropShadow',
326
+ 'feFlood',
327
+ 'feFuncA',
328
+ 'feFuncB',
329
+ 'feFuncG',
330
+ 'feFuncR',
331
+ 'feGaussianBlur',
332
+ 'feImage',
333
+ 'feMerge',
334
+ 'feMergeNode',
335
+ 'feMorphology',
336
+ 'feOffset',
337
+ 'fePointLight',
338
+ 'feSpecularLighting',
339
+ 'feSpotLight',
340
+ 'feTile',
341
+ 'feTurbulence',
342
+ 'filter',
343
+ 'font',
344
+ 'font-face',
345
+ 'font-face-format',
346
+ 'font-face-name',
347
+ 'font-face-src',
348
+ 'font-face-uri',
349
+ 'foreignObject',
350
+ 'g',
351
+ 'glyph',
352
+ 'glyphRef',
353
+ 'hkern',
354
+ 'image',
355
+ 'line',
356
+ 'linearGradient',
357
+ 'marker',
358
+ 'mask',
359
+ 'metadata',
360
+ 'missing-glyph',
361
+ 'mpath',
362
+ 'path',
363
+ 'pattern',
364
+ 'polygon',
365
+ 'polyline',
366
+ 'radialGradient',
367
+ 'rect',
368
+ 'set',
369
+ 'stop',
370
+ 'svg',
371
+ 'switch',
372
+ 'symbol',
373
+ 'text',
374
+ 'textPath',
375
+ 'tref',
376
+ 'tspan',
377
+ 'use',
378
+ 'view',
379
+ 'vkern',
380
+ ]
381
+ : []
382
+
383
+ export const SVGElements = new Set<string>(svgElements)
364
384
 
365
385
  /**
366
386
  * SVG attribute namespaces
@@ -377,80 +397,84 @@ export const SVGNamespace: Record<string, string> = {
377
397
  /**
378
398
  * CSS properties that don't need a unit (like 'px')
379
399
  */
380
- export const UnitlessStyles = new Set<string>([
381
- 'animationIterationCount',
382
- 'animation-iteration-count',
383
- 'borderImageOutset',
384
- 'border-image-outset',
385
- 'borderImageSlice',
386
- 'border-image-slice',
387
- 'borderImageWidth',
388
- 'border-image-width',
389
- 'boxFlex',
390
- 'box-flex',
391
- 'boxFlexGroup',
392
- 'box-flex-group',
393
- 'boxOrdinalGroup',
394
- 'box-ordinal-group',
395
- 'columnCount',
396
- 'column-count',
397
- 'columns',
398
- 'flex',
399
- 'flexGrow',
400
- 'flex-grow',
401
- 'flexPositive',
402
- 'flex-positive',
403
- 'flexShrink',
404
- 'flex-shrink',
405
- 'flexNegative',
406
- 'flex-negative',
407
- 'flexOrder',
408
- 'flex-order',
409
- 'gridRow',
410
- 'grid-row',
411
- 'gridRowEnd',
412
- 'grid-row-end',
413
- 'gridRowSpan',
414
- 'grid-row-span',
415
- 'gridRowStart',
416
- 'grid-row-start',
417
- 'gridColumn',
418
- 'grid-column',
419
- 'gridColumnEnd',
420
- 'grid-column-end',
421
- 'gridColumnSpan',
422
- 'grid-column-span',
423
- 'gridColumnStart',
424
- 'grid-column-start',
425
- 'fontWeight',
426
- 'font-weight',
427
- 'lineClamp',
428
- 'line-clamp',
429
- 'lineHeight',
430
- 'line-height',
431
- 'opacity',
432
- 'order',
433
- 'orphans',
434
- 'tabSize',
435
- 'tab-size',
436
- 'widows',
437
- 'zIndex',
438
- 'z-index',
439
- 'zoom',
440
- 'fillOpacity',
441
- 'fill-opacity',
442
- 'floodOpacity',
443
- 'flood-opacity',
444
- 'stopOpacity',
445
- 'stop-opacity',
446
- 'strokeDasharray',
447
- 'stroke-dasharray',
448
- 'strokeDashoffset',
449
- 'stroke-dashoffset',
450
- 'strokeMiterlimit',
451
- 'stroke-miterlimit',
452
- 'strokeOpacity',
453
- 'stroke-opacity',
454
- 'strokeWidth',
455
- 'stroke-width',
456
- ])
400
+ const unitlessList = isDev
401
+ ? [
402
+ 'animationIterationCount',
403
+ 'animation-iteration-count',
404
+ 'borderImageOutset',
405
+ 'border-image-outset',
406
+ 'borderImageSlice',
407
+ 'border-image-slice',
408
+ 'borderImageWidth',
409
+ 'border-image-width',
410
+ 'boxFlex',
411
+ 'box-flex',
412
+ 'boxFlexGroup',
413
+ 'box-flex-group',
414
+ 'boxOrdinalGroup',
415
+ 'box-ordinal-group',
416
+ 'columnCount',
417
+ 'column-count',
418
+ 'columns',
419
+ 'flex',
420
+ 'flexGrow',
421
+ 'flex-grow',
422
+ 'flexPositive',
423
+ 'flex-positive',
424
+ 'flexShrink',
425
+ 'flex-shrink',
426
+ 'flexNegative',
427
+ 'flex-negative',
428
+ 'flexOrder',
429
+ 'flex-order',
430
+ 'gridRow',
431
+ 'grid-row',
432
+ 'gridRowEnd',
433
+ 'grid-row-end',
434
+ 'gridRowSpan',
435
+ 'grid-row-span',
436
+ 'gridRowStart',
437
+ 'grid-row-start',
438
+ 'gridColumn',
439
+ 'grid-column',
440
+ 'gridColumnEnd',
441
+ 'grid-column-end',
442
+ 'gridColumnSpan',
443
+ 'grid-column-span',
444
+ 'gridColumnStart',
445
+ 'grid-column-start',
446
+ 'fontWeight',
447
+ 'font-weight',
448
+ 'lineClamp',
449
+ 'line-clamp',
450
+ 'lineHeight',
451
+ 'line-height',
452
+ 'opacity',
453
+ 'order',
454
+ 'orphans',
455
+ 'tabSize',
456
+ 'tab-size',
457
+ 'widows',
458
+ 'zIndex',
459
+ 'z-index',
460
+ 'zoom',
461
+ 'fillOpacity',
462
+ 'fill-opacity',
463
+ 'floodOpacity',
464
+ 'flood-opacity',
465
+ 'stopOpacity',
466
+ 'stop-opacity',
467
+ 'strokeDasharray',
468
+ 'stroke-dasharray',
469
+ 'strokeDashoffset',
470
+ 'stroke-dashoffset',
471
+ 'strokeMiterlimit',
472
+ 'stroke-miterlimit',
473
+ 'strokeOpacity',
474
+ 'stroke-opacity',
475
+ 'strokeWidth',
476
+ 'stroke-width',
477
+ ]
478
+ : ['opacity', 'zIndex']
479
+
480
+ export const UnitlessStyles = new Set<string>(unitlessList)