@jackens/nnn 2026.9.3 → 2026.9.7
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/package.json +13 -13
- package/readme.md +333 -251
package/package.json
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"name": "@jackens/nnn",
|
|
3
|
+
"version": "2026.9.7",
|
|
3
4
|
"description": "Jackens’ JavaScript helpers.",
|
|
4
5
|
"keywords": [
|
|
5
|
-
"autovivify",
|
|
6
|
-
"c",
|
|
7
6
|
"CSS-in-JS",
|
|
8
7
|
"CSV parse",
|
|
9
8
|
"DOM",
|
|
10
|
-
"escape",
|
|
11
|
-
"h",
|
|
12
|
-
"highlight",
|
|
13
9
|
"HyperScript",
|
|
14
10
|
"JS-to-CSS",
|
|
15
11
|
"Monokai",
|
|
16
|
-
"nanolight",
|
|
17
|
-
"nnn",
|
|
18
|
-
"Responsive Web Design",
|
|
19
12
|
"RWD",
|
|
13
|
+
"Responsive Web Design",
|
|
20
14
|
"SVG",
|
|
15
|
+
"autovivify",
|
|
16
|
+
"c",
|
|
17
|
+
"escape",
|
|
18
|
+
"h",
|
|
19
|
+
"highlight",
|
|
20
|
+
"nanolight",
|
|
21
|
+
"nnn",
|
|
21
22
|
"tokenize",
|
|
22
23
|
"tokenizer",
|
|
23
24
|
"typography",
|
|
@@ -27,9 +28,8 @@
|
|
|
27
28
|
"vivify"
|
|
28
29
|
],
|
|
29
30
|
"license": "MIT",
|
|
30
|
-
"
|
|
31
|
-
"name": "@jackens/nnn",
|
|
31
|
+
"author": "Jackens",
|
|
32
32
|
"type": "module",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"main": "nnn.js",
|
|
34
|
+
"types": "nnn.d.ts"
|
|
35
35
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nnn
|
|
2
2
|
|
|
3
|
-
A collection of Jackens’ JavaScript helper utilities (version: `2026.9.
|
|
3
|
+
A collection of Jackens’ JavaScript helper utilities (version: `2026.9.7`).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,6 +18,9 @@ npm i @jackens/nnn
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
import {
|
|
21
|
+
CNode,
|
|
22
|
+
HArgs,
|
|
23
|
+
HArgs1,
|
|
21
24
|
c,
|
|
22
25
|
createEscape,
|
|
23
26
|
createTokenizer,
|
|
@@ -145,7 +148,7 @@ A CSS string representing the compiled rules.
|
|
|
145
148
|
#### Usage Examples
|
|
146
149
|
|
|
147
150
|
```ts
|
|
148
|
-
const
|
|
151
|
+
const actual = c({
|
|
149
152
|
a: {
|
|
150
153
|
color: 'red',
|
|
151
154
|
margin: 1,
|
|
@@ -154,22 +157,25 @@ const actual1 = c({
|
|
|
154
157
|
},
|
|
155
158
|
})
|
|
156
159
|
|
|
157
|
-
const
|
|
158
|
-
a{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
a.c{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
a{
|
|
167
|
-
|
|
168
|
-
}
|
|
160
|
+
const expected = `
|
|
161
|
+
a{
|
|
162
|
+
color:red;
|
|
163
|
+
margin:1
|
|
164
|
+
}
|
|
165
|
+
a.c{
|
|
166
|
+
margin:2;
|
|
167
|
+
padding:2
|
|
168
|
+
}
|
|
169
|
+
a{
|
|
170
|
+
padding:1
|
|
171
|
+
}
|
|
172
|
+
`.replace(/\n\s*/g, '')
|
|
169
173
|
|
|
170
|
-
expect(
|
|
174
|
+
expect(actual).toBe(expected)
|
|
175
|
+
```
|
|
171
176
|
|
|
172
|
-
|
|
177
|
+
```ts
|
|
178
|
+
const actual = c({
|
|
173
179
|
a: {
|
|
174
180
|
'.b': {
|
|
175
181
|
color: 'red',
|
|
@@ -180,22 +186,25 @@ const actual2 = c({
|
|
|
180
186
|
},
|
|
181
187
|
})
|
|
182
188
|
|
|
183
|
-
const
|
|
184
|
-
a.b{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
a.b.c{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
a.b{
|
|
193
|
-
|
|
194
|
-
}
|
|
189
|
+
const expected = `
|
|
190
|
+
a.b{
|
|
191
|
+
color:red;
|
|
192
|
+
margin:1
|
|
193
|
+
}
|
|
194
|
+
a.b.c{
|
|
195
|
+
margin:2;
|
|
196
|
+
padding:2
|
|
197
|
+
}
|
|
198
|
+
a.b{
|
|
199
|
+
padding:1
|
|
200
|
+
}
|
|
201
|
+
`.replace(/\n\s*/g, '')
|
|
195
202
|
|
|
196
|
-
expect(
|
|
203
|
+
expect(actual).toBe(expected)
|
|
204
|
+
```
|
|
197
205
|
|
|
198
|
-
|
|
206
|
+
```ts
|
|
207
|
+
const actual = c({
|
|
199
208
|
'@font-face$$1': {
|
|
200
209
|
'font-family': 'Jackens',
|
|
201
210
|
src$$1: 'url(otf/jackens.otf)',
|
|
@@ -225,51 +234,54 @@ const actual3 = c({
|
|
|
225
234
|
},
|
|
226
235
|
})
|
|
227
236
|
|
|
228
|
-
const
|
|
229
|
-
@font-face{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
@font-face{
|
|
237
|
-
font-family:C64;
|
|
238
|
-
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
239
|
-
}
|
|
240
|
-
@keyframes spin{
|
|
241
|
-
0%{
|
|
242
|
-
transform:rotate(0deg)
|
|
237
|
+
const expected = `
|
|
238
|
+
@font-face{
|
|
239
|
+
font-family:Jackens;
|
|
240
|
+
src:url(otf/jackens.otf);
|
|
241
|
+
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
242
|
+
font-weight:normal;
|
|
243
|
+
font-style:normal
|
|
243
244
|
}
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
@font-face{
|
|
246
|
+
font-family:C64;
|
|
247
|
+
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
248
|
+
}
|
|
249
|
+
@keyframes spin{
|
|
250
|
+
0%{
|
|
251
|
+
transform:rotate(0deg)
|
|
252
|
+
}
|
|
253
|
+
100%{
|
|
254
|
+
transform:rotate(360deg)
|
|
255
|
+
}
|
|
246
256
|
}
|
|
247
|
-
}
|
|
248
|
-
div{
|
|
249
|
-
border:solid red 1px
|
|
250
|
-
}
|
|
251
|
-
div.c1{
|
|
252
|
-
background-color:#000
|
|
253
|
-
}
|
|
254
|
-
div .c1{
|
|
255
|
-
background-color:black
|
|
256
|
-
}
|
|
257
|
-
div.c2{
|
|
258
|
-
background-color:rgb(0,0,0)
|
|
259
|
-
}
|
|
260
|
-
@media(min-width:200px){
|
|
261
257
|
div{
|
|
262
|
-
|
|
263
|
-
|
|
258
|
+
border:solid red 1px
|
|
259
|
+
}
|
|
260
|
+
div.c1{
|
|
261
|
+
background-color:#000
|
|
264
262
|
}
|
|
265
|
-
|
|
266
|
-
color
|
|
263
|
+
div .c1{
|
|
264
|
+
background-color:black
|
|
267
265
|
}
|
|
268
|
-
|
|
266
|
+
div.c2{
|
|
267
|
+
background-color:rgb(0,0,0)
|
|
268
|
+
}
|
|
269
|
+
@media(min-width:200px){
|
|
270
|
+
div{
|
|
271
|
+
margin:0;
|
|
272
|
+
padding:0
|
|
273
|
+
}
|
|
274
|
+
span{
|
|
275
|
+
color:#000
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
`.replace(/\n\s*/g, '')
|
|
269
279
|
|
|
270
|
-
expect(
|
|
280
|
+
expect(actual).toBe(expected)
|
|
281
|
+
```
|
|
271
282
|
|
|
272
|
-
|
|
283
|
+
```ts
|
|
284
|
+
const actual = c({
|
|
273
285
|
a: {
|
|
274
286
|
'.b,.c': {
|
|
275
287
|
margin: 1,
|
|
@@ -280,17 +292,20 @@ const actual4 = c({
|
|
|
280
292
|
},
|
|
281
293
|
})
|
|
282
294
|
|
|
283
|
-
const
|
|
284
|
-
a.b,a.c{
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
a.b.d,a.c.d{
|
|
288
|
-
|
|
289
|
-
}
|
|
295
|
+
const expected = `
|
|
296
|
+
a.b,a.c{
|
|
297
|
+
margin:1
|
|
298
|
+
}
|
|
299
|
+
a.b.d,a.c.d{
|
|
300
|
+
margin:2
|
|
301
|
+
}
|
|
302
|
+
`.replace(/\n\s*/g, '')
|
|
290
303
|
|
|
291
|
-
expect(
|
|
304
|
+
expect(actual).toBe(expected)
|
|
305
|
+
```
|
|
292
306
|
|
|
293
|
-
|
|
307
|
+
```ts
|
|
308
|
+
const actual = c({
|
|
294
309
|
'.b,.c': {
|
|
295
310
|
margin: 1,
|
|
296
311
|
'.d': {
|
|
@@ -299,17 +314,20 @@ const actual5 = c({
|
|
|
299
314
|
},
|
|
300
315
|
})
|
|
301
316
|
|
|
302
|
-
const
|
|
303
|
-
.b,.c{
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
.b.d,.c.d{
|
|
307
|
-
|
|
308
|
-
}
|
|
317
|
+
const expected = `
|
|
318
|
+
.b,.c{
|
|
319
|
+
margin:1
|
|
320
|
+
}
|
|
321
|
+
.b.d,.c.d{
|
|
322
|
+
margin:2
|
|
323
|
+
}
|
|
324
|
+
`.replace(/\n\s*/g, '')
|
|
309
325
|
|
|
310
|
-
expect(
|
|
326
|
+
expect(actual).toBe(expected)
|
|
327
|
+
```
|
|
311
328
|
|
|
312
|
-
|
|
329
|
+
```ts
|
|
330
|
+
const actual = c({
|
|
313
331
|
'.a,.b': {
|
|
314
332
|
margin: 1,
|
|
315
333
|
'.c,.d': {
|
|
@@ -318,17 +336,20 @@ const actual6 = c({
|
|
|
318
336
|
},
|
|
319
337
|
})
|
|
320
338
|
|
|
321
|
-
const
|
|
322
|
-
.a,.b{
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
.a.c,.a.d,.b.c,.b.d{
|
|
326
|
-
|
|
327
|
-
}
|
|
339
|
+
const expected = `
|
|
340
|
+
.a,.b{
|
|
341
|
+
margin:1
|
|
342
|
+
}
|
|
343
|
+
.a.c,.a.d,.b.c,.b.d{
|
|
344
|
+
margin:2
|
|
345
|
+
}
|
|
346
|
+
`.replace(/\n\s*/g, '')
|
|
328
347
|
|
|
329
|
-
expect(
|
|
348
|
+
expect(actual).toBe(expected)
|
|
349
|
+
```
|
|
330
350
|
|
|
331
|
-
|
|
351
|
+
```ts
|
|
352
|
+
const actual = c({
|
|
332
353
|
':root$$monokai': {
|
|
333
354
|
'--': {
|
|
334
355
|
bg: '#faf4f2',
|
|
@@ -378,7 +399,7 @@ const actual7 = c({
|
|
|
378
399
|
},
|
|
379
400
|
})
|
|
380
401
|
|
|
381
|
-
const
|
|
402
|
+
const expected = `
|
|
382
403
|
:root{
|
|
383
404
|
--bg:#faf4f2;
|
|
384
405
|
--fg:#29242a;
|
|
@@ -412,9 +433,10 @@ const expected7 = `
|
|
|
412
433
|
--punctuation:#727072;
|
|
413
434
|
--string:#ffd866
|
|
414
435
|
}
|
|
415
|
-
}
|
|
436
|
+
}
|
|
437
|
+
`.replace(/\n\s*/g, '')
|
|
416
438
|
|
|
417
|
-
expect(
|
|
439
|
+
expect(actual).toBe(expected)
|
|
418
440
|
```
|
|
419
441
|
|
|
420
442
|
### createEscape
|
|
@@ -457,31 +479,31 @@ const escapeFn = (value: any): string =>
|
|
|
457
479
|
const sql = createEscape(escapeFn)
|
|
458
480
|
|
|
459
481
|
const actual = sql`
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
482
|
+
SELECT *
|
|
483
|
+
FROM table_name
|
|
484
|
+
WHERE column_name IN (
|
|
485
|
+
${[
|
|
486
|
+
true,
|
|
487
|
+
null,
|
|
488
|
+
undefined,
|
|
489
|
+
NaN,
|
|
490
|
+
Infinity,
|
|
491
|
+
42,
|
|
492
|
+
'42',
|
|
493
|
+
"4'2",
|
|
494
|
+
/42/,
|
|
495
|
+
new Date(323325000000),
|
|
496
|
+
]}
|
|
497
|
+
)`
|
|
476
498
|
|
|
477
499
|
const expected = `
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
500
|
+
SELECT *
|
|
501
|
+
FROM table_name
|
|
502
|
+
WHERE column_name IN (
|
|
503
|
+
b'1', NULL, NULL, NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00'
|
|
504
|
+
)`
|
|
483
505
|
|
|
484
|
-
expect(actual).
|
|
506
|
+
expect(actual).toBe(expected)
|
|
485
507
|
```
|
|
486
508
|
|
|
487
509
|
### createTokenizer
|
|
@@ -528,15 +550,15 @@ and returns an array of decorated tokens.
|
|
|
528
550
|
#### Usage Examples
|
|
529
551
|
|
|
530
552
|
```ts
|
|
531
|
-
const
|
|
553
|
+
const tokenizer = createTokenizer(
|
|
532
554
|
(chunk, metadata) => ({ chunk, metadata }),
|
|
533
555
|
['keyword', /\b(if|else|for)\b/],
|
|
534
556
|
['string', /"[^"]*"/]
|
|
535
557
|
)
|
|
536
558
|
|
|
537
|
-
const
|
|
559
|
+
const result = tokenizer('if "hello" else "world"')
|
|
538
560
|
|
|
539
|
-
expect(
|
|
561
|
+
expect(result).toEqual([
|
|
540
562
|
{ chunk: 'if', metadata: 'keyword' },
|
|
541
563
|
{ chunk: ' ', metadata: undefined },
|
|
542
564
|
{ chunk: '"hello"', metadata: 'string' },
|
|
@@ -545,92 +567,108 @@ expect(result1).to.deep.equal([
|
|
|
545
567
|
{ chunk: ' ', metadata: undefined },
|
|
546
568
|
{ chunk: '"world"', metadata: 'string' },
|
|
547
569
|
])
|
|
570
|
+
```
|
|
548
571
|
|
|
549
|
-
|
|
572
|
+
```ts
|
|
573
|
+
const tokenizer = createTokenizer(
|
|
550
574
|
(chunk, metadata) => `${metadata}:${chunk}`,
|
|
551
575
|
['tag', 'BEGIN'],
|
|
552
576
|
['end', 'END']
|
|
553
577
|
)
|
|
554
578
|
|
|
555
|
-
const
|
|
579
|
+
const result = tokenizer('aBEGINbENDc')
|
|
556
580
|
|
|
557
|
-
expect(
|
|
581
|
+
expect(result).toEqual([
|
|
558
582
|
'undefined:a',
|
|
559
583
|
'tag:BEGIN',
|
|
560
584
|
'undefined:b',
|
|
561
585
|
'end:END',
|
|
562
586
|
'undefined:c',
|
|
563
587
|
])
|
|
588
|
+
```
|
|
564
589
|
|
|
565
|
-
|
|
590
|
+
```ts
|
|
591
|
+
const tokenizer = createTokenizer(
|
|
566
592
|
chunk => chunk,
|
|
567
593
|
['test', /test/]
|
|
568
594
|
)
|
|
569
595
|
|
|
570
|
-
const
|
|
596
|
+
const result = tokenizer('')
|
|
571
597
|
|
|
572
|
-
expect(
|
|
598
|
+
expect(result).toEqual([])
|
|
599
|
+
```
|
|
573
600
|
|
|
574
|
-
|
|
601
|
+
```ts
|
|
602
|
+
const tokenizer = createTokenizer(
|
|
575
603
|
(chunk, metadata) => ({ chunk, metadata }),
|
|
576
604
|
['start', /^test/]
|
|
577
605
|
)
|
|
578
606
|
|
|
579
|
-
const
|
|
607
|
+
const result = tokenizer('test here')
|
|
580
608
|
|
|
581
|
-
expect(
|
|
609
|
+
expect(result).toEqual([
|
|
582
610
|
{ chunk: 'test', metadata: 'start' },
|
|
583
611
|
{ chunk: ' here', metadata: undefined },
|
|
584
612
|
])
|
|
613
|
+
```
|
|
585
614
|
|
|
586
|
-
|
|
615
|
+
```ts
|
|
616
|
+
const tokenizer = createTokenizer(
|
|
587
617
|
(chunk, metadata) => metadata,
|
|
588
618
|
['later', /x/],
|
|
589
619
|
['earlier', /y/]
|
|
590
620
|
)
|
|
591
621
|
|
|
592
|
-
const
|
|
622
|
+
const result = tokenizer('yx')
|
|
593
623
|
|
|
594
|
-
expect(
|
|
624
|
+
expect(result).toEqual(['earlier', 'later'])
|
|
625
|
+
```
|
|
595
626
|
|
|
596
|
-
|
|
627
|
+
```ts
|
|
628
|
+
const tokenizer = createTokenizer(
|
|
597
629
|
chunk => chunk,
|
|
598
630
|
['short', 'a'],
|
|
599
631
|
['long', 'abc']
|
|
600
632
|
)
|
|
601
633
|
|
|
602
|
-
const
|
|
634
|
+
const result = tokenizer('abc')
|
|
603
635
|
|
|
604
|
-
expect(
|
|
636
|
+
expect(result).toEqual(['abc'])
|
|
637
|
+
```
|
|
605
638
|
|
|
606
|
-
|
|
639
|
+
```ts
|
|
640
|
+
const tokenizer = createTokenizer(
|
|
607
641
|
chunk => chunk,
|
|
608
642
|
['empty', ''],
|
|
609
643
|
['word', /\w+/]
|
|
610
644
|
)
|
|
611
645
|
|
|
612
|
-
const
|
|
646
|
+
const result = tokenizer('hello')
|
|
613
647
|
|
|
614
|
-
expect(
|
|
648
|
+
expect(result).toEqual(['hello'])
|
|
649
|
+
```
|
|
615
650
|
|
|
616
|
-
|
|
651
|
+
```ts
|
|
652
|
+
const tokenizer = createTokenizer(
|
|
617
653
|
chunk => chunk,
|
|
618
654
|
['test', /xyz/]
|
|
619
655
|
)
|
|
620
656
|
|
|
621
|
-
const
|
|
657
|
+
const result = tokenizer('abc')
|
|
622
658
|
|
|
623
|
-
expect(
|
|
659
|
+
expect(result).toEqual(['abc'])
|
|
660
|
+
```
|
|
624
661
|
|
|
625
|
-
|
|
662
|
+
```ts
|
|
663
|
+
const tokenizer = createTokenizer(
|
|
626
664
|
(_chunk, metadata) => metadata,
|
|
627
665
|
['a', 'a'],
|
|
628
666
|
['b', 'b']
|
|
629
667
|
)
|
|
630
668
|
|
|
631
|
-
const
|
|
669
|
+
const result = tokenizer('aabb')
|
|
632
670
|
|
|
633
|
-
expect(
|
|
671
|
+
expect(result).toEqual(['a', 'a', 'b', 'b'])
|
|
634
672
|
```
|
|
635
673
|
|
|
636
674
|
### csvParse
|
|
@@ -670,7 +708,7 @@ yyy",zzz
|
|
|
670
708
|
|
|
671
709
|
`
|
|
672
710
|
|
|
673
|
-
expect(csvParse(text)).
|
|
711
|
+
expect(csvParse(text)).toEqual([
|
|
674
712
|
['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
|
|
675
713
|
['xxx,xxx', 'yyy\nyyy', 'zzz'],
|
|
676
714
|
[' 42 ', '42', ' 17'],
|
|
@@ -716,7 +754,7 @@ const p = h(
|
|
|
716
754
|
|
|
717
755
|
fixPlTypography(p)
|
|
718
756
|
|
|
719
|
-
expect(p.innerHTML).
|
|
757
|
+
expect(p.innerHTML).toEqual(
|
|
720
758
|
'Pchnąć ' +
|
|
721
759
|
'<span style="white-space:nowrap">w </span>' +
|
|
722
760
|
'tę łódź jeża lub ośm skrzyń fig ' +
|
|
@@ -775,61 +813,66 @@ The created or modified `HTMLElement`.
|
|
|
775
813
|
```ts
|
|
776
814
|
const b = h('b')
|
|
777
815
|
|
|
778
|
-
expect(b.outerHTML).
|
|
816
|
+
expect(b.outerHTML).toBe('<b></b>')
|
|
779
817
|
|
|
780
818
|
const i = h('i', 'text')
|
|
781
819
|
|
|
782
820
|
h(b, i)
|
|
783
821
|
|
|
784
|
-
expect(i.outerHTML).
|
|
822
|
+
expect(i.outerHTML).toBe('<i>text</i>')
|
|
785
823
|
|
|
786
|
-
expect(b.outerHTML).
|
|
824
|
+
expect(b.outerHTML).toBe('<b><i>text</i></b>')
|
|
787
825
|
|
|
788
826
|
h(i, { $className: 'some class' })
|
|
789
827
|
|
|
790
|
-
expect(i.outerHTML).
|
|
791
|
-
'<i class="some class">text</i>'
|
|
792
|
-
)
|
|
828
|
+
expect(i.outerHTML).toBe('<i class="some class">text</i>')
|
|
793
829
|
|
|
794
|
-
expect(b.outerHTML).
|
|
830
|
+
expect(b.outerHTML).toBe(
|
|
795
831
|
'<b><i class="some class">text</i></b>'
|
|
796
832
|
)
|
|
833
|
+
```
|
|
797
834
|
|
|
798
|
-
|
|
835
|
+
```ts
|
|
836
|
+
expect(h('span', 'text').outerHTML).toBe(
|
|
799
837
|
'<span>text</span>'
|
|
800
838
|
)
|
|
801
839
|
|
|
802
|
-
expect(
|
|
803
|
-
|
|
804
|
-
).to.equal('<span>text</span>')
|
|
805
|
-
|
|
806
|
-
expect(h('span', '42').outerHTML).to.equal(
|
|
807
|
-
'<span>42</span>'
|
|
840
|
+
expect(h('span', { $innerText: 'text' }).outerHTML).toBe(
|
|
841
|
+
'<span>text</span>'
|
|
808
842
|
)
|
|
809
843
|
|
|
810
|
-
expect(h('span', 42).outerHTML).
|
|
844
|
+
expect(h('span', '42').outerHTML).toBe('<span>42</span>')
|
|
811
845
|
|
|
846
|
+
expect(h('span', 42).outerHTML).toBe('<span>42</span>')
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
```ts
|
|
812
850
|
expect(
|
|
813
851
|
h('div', { style: 'margin:0;padding:0' }).outerHTML
|
|
814
|
-
).
|
|
852
|
+
).toBe('<div style="margin:0;padding:0"></div>')
|
|
815
853
|
|
|
816
854
|
expect(
|
|
817
855
|
h('div', { $style: 'margin:0;padding:0' }).outerHTML
|
|
818
|
-
).
|
|
856
|
+
).toBe('<div style="margin: 0px; padding: 0px;"></div>')
|
|
819
857
|
|
|
820
858
|
expect(
|
|
821
|
-
h('div', { $style: { margin: 0, padding: 0 } })
|
|
822
|
-
|
|
859
|
+
h('div', { $style: { margin: 0, padding: 0 } })
|
|
860
|
+
.outerHTML
|
|
861
|
+
).toBe('<div style="margin: 0px; padding: 0px;"></div>')
|
|
862
|
+
```
|
|
823
863
|
|
|
864
|
+
```ts
|
|
824
865
|
const input1 = h('input', { value: 42 })
|
|
825
866
|
const input2 = h('input', { $value: '42' })
|
|
826
867
|
|
|
827
|
-
expect(input1.value).
|
|
828
|
-
expect(input2.value).
|
|
868
|
+
expect(input1.value).toBe('42')
|
|
869
|
+
expect(input2.value).toBe('42')
|
|
829
870
|
|
|
830
|
-
expect(input1.outerHTML).
|
|
831
|
-
expect(input2.outerHTML).
|
|
871
|
+
expect(input1.outerHTML).toBe('<input value="42">')
|
|
872
|
+
expect(input2.outerHTML).toBe('<input>')
|
|
873
|
+
```
|
|
832
874
|
|
|
875
|
+
```ts
|
|
833
876
|
const checkbox1 = h('input', {
|
|
834
877
|
type: 'checkbox',
|
|
835
878
|
checked: true,
|
|
@@ -840,38 +883,42 @@ const checkbox2 = h('input', {
|
|
|
840
883
|
$checked: true,
|
|
841
884
|
})
|
|
842
885
|
|
|
843
|
-
expect(checkbox1.checked).
|
|
844
|
-
expect(checkbox2.checked).
|
|
886
|
+
expect(checkbox1.checked).toBe(true)
|
|
887
|
+
expect(checkbox2.checked).toBe(true)
|
|
845
888
|
|
|
846
|
-
expect(checkbox1.outerHTML).
|
|
889
|
+
expect(checkbox1.outerHTML).toBe(
|
|
847
890
|
'<input type="checkbox" checked="">'
|
|
848
891
|
)
|
|
849
892
|
|
|
850
|
-
expect(checkbox2.outerHTML).
|
|
893
|
+
expect(checkbox2.outerHTML).toBe(
|
|
851
894
|
'<input type="checkbox">'
|
|
852
895
|
)
|
|
896
|
+
```
|
|
853
897
|
|
|
898
|
+
```ts
|
|
854
899
|
const div = h('div')
|
|
855
900
|
|
|
856
|
-
expect(div.key).
|
|
901
|
+
expect(div.key).toBeUndefined()
|
|
857
902
|
|
|
858
903
|
h(div, { $key: { one: 1 } })
|
|
859
904
|
|
|
860
|
-
expect(div.key).
|
|
905
|
+
expect(div.key).toEqual({ one: 1 })
|
|
861
906
|
|
|
862
907
|
h(div, { $key: { two: 2 } })
|
|
863
908
|
|
|
864
|
-
expect(div.key).
|
|
909
|
+
expect(div.key).toEqual({ one: 1, two: 2 })
|
|
910
|
+
```
|
|
865
911
|
|
|
912
|
+
```ts
|
|
866
913
|
const elemWithClass = h('div', { class: 'test' })
|
|
867
914
|
|
|
868
|
-
expect(elemWithClass.getAttribute('class')).
|
|
915
|
+
expect(elemWithClass.getAttribute('class')).toBe('test')
|
|
869
916
|
|
|
870
917
|
const elemWithText = h('div', 'initial')
|
|
871
918
|
|
|
872
919
|
h(elemWithText, ' more')
|
|
873
920
|
|
|
874
|
-
expect(elemWithText.outerHTML).
|
|
921
|
+
expect(elemWithText.outerHTML).toBe(
|
|
875
922
|
'<div>initial more</div>'
|
|
876
923
|
)
|
|
877
924
|
|
|
@@ -881,7 +928,7 @@ const elemWithNested = h(
|
|
|
881
928
|
['b', 'world']
|
|
882
929
|
)
|
|
883
930
|
|
|
884
|
-
expect(elemWithNested.outerHTML).
|
|
931
|
+
expect(elemWithNested.outerHTML).toBe(
|
|
885
932
|
'<div><span>hello</span><b>world</b></div>'
|
|
886
933
|
)
|
|
887
934
|
```
|
|
@@ -920,7 +967,7 @@ const codeJs =
|
|
|
920
967
|
'const answerToLifeTheUniverseAndEverything = ' +
|
|
921
968
|
"{ 42: 42 }['42'] /* 42 */"
|
|
922
969
|
|
|
923
|
-
expect(nanolightTs(codeJs)).
|
|
970
|
+
expect(nanolightTs(codeJs)).toEqual([
|
|
924
971
|
['span', { class: 'keyword1' }, 'const'],
|
|
925
972
|
' ',
|
|
926
973
|
[
|
|
@@ -1002,7 +1049,7 @@ const style: CNode = {
|
|
|
1002
1049
|
|
|
1003
1050
|
rwd(style, '.r6', 200, 50, [6], [3], [1, 1, 2])
|
|
1004
1051
|
|
|
1005
|
-
expect(style).
|
|
1052
|
+
expect(style).toEqual({
|
|
1006
1053
|
body: {
|
|
1007
1054
|
margin: 0,
|
|
1008
1055
|
},
|
|
@@ -1077,29 +1124,49 @@ The created or modified `SVGElement`.
|
|
|
1077
1124
|
#### Usage Examples
|
|
1078
1125
|
|
|
1079
1126
|
```ts
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
const svg1 = s('svg', { 'xlink:href': true })
|
|
1127
|
+
const svg = s('svg', { 'xlink:href': true })
|
|
1083
1128
|
|
|
1084
|
-
expect(
|
|
1129
|
+
expect(
|
|
1130
|
+
svg.getAttributeNS(
|
|
1131
|
+
'http://www.w3.org/1999/xlink',
|
|
1132
|
+
'href'
|
|
1133
|
+
)
|
|
1134
|
+
).toBe('')
|
|
1135
|
+
```
|
|
1085
1136
|
|
|
1086
|
-
|
|
1137
|
+
```ts
|
|
1138
|
+
const svg = s('svg', { 'xlink:href': false })
|
|
1087
1139
|
|
|
1088
|
-
expect(
|
|
1140
|
+
expect(
|
|
1141
|
+
svg.getAttributeNS(
|
|
1142
|
+
'http://www.w3.org/1999/xlink',
|
|
1143
|
+
'href'
|
|
1144
|
+
)
|
|
1145
|
+
).toBeNull()
|
|
1146
|
+
```
|
|
1089
1147
|
|
|
1090
|
-
|
|
1148
|
+
```ts
|
|
1149
|
+
const svg = s('svg', {
|
|
1091
1150
|
'xlink:href': 'http://example.com',
|
|
1092
1151
|
})
|
|
1093
1152
|
|
|
1094
|
-
expect(
|
|
1095
|
-
|
|
1096
|
-
|
|
1153
|
+
expect(
|
|
1154
|
+
svg.getAttributeNS(
|
|
1155
|
+
'http://www.w3.org/1999/xlink',
|
|
1156
|
+
'href'
|
|
1157
|
+
)
|
|
1158
|
+
).toBe('http://example.com')
|
|
1159
|
+
```
|
|
1097
1160
|
|
|
1098
|
-
|
|
1161
|
+
```ts
|
|
1162
|
+
const svg = s('svg', { 'xlink:title': 42 })
|
|
1099
1163
|
|
|
1100
|
-
expect(
|
|
1101
|
-
|
|
1102
|
-
|
|
1164
|
+
expect(
|
|
1165
|
+
svg.getAttributeNS(
|
|
1166
|
+
'http://www.w3.org/1999/xlink',
|
|
1167
|
+
'title'
|
|
1168
|
+
)
|
|
1169
|
+
).toBe('42')
|
|
1103
1170
|
```
|
|
1104
1171
|
|
|
1105
1172
|
### svgUse
|
|
@@ -1138,47 +1205,54 @@ An `SVGSVGElement` containing a `<use>` element.
|
|
|
1138
1205
|
#### Usage Examples
|
|
1139
1206
|
|
|
1140
1207
|
```ts
|
|
1141
|
-
const XLINK_NS = 'http://www.w3.org/1999/xlink'
|
|
1142
|
-
|
|
1143
1208
|
const svg = svgUse('icon-home')
|
|
1144
1209
|
|
|
1145
|
-
expect(svg.children.length).
|
|
1210
|
+
expect(svg.children.length).toBe(1)
|
|
1146
1211
|
|
|
1147
1212
|
const useElement = svg.children[0]
|
|
1148
1213
|
|
|
1149
1214
|
expect(
|
|
1150
|
-
useElement.getAttributeNS(
|
|
1151
|
-
|
|
1215
|
+
useElement.getAttributeNS(
|
|
1216
|
+
'http://www.w3.org/1999/xlink',
|
|
1217
|
+
'href'
|
|
1218
|
+
)
|
|
1219
|
+
).toBe('#icon-home')
|
|
1152
1220
|
|
|
1153
1221
|
const svgWithViewBox = svgUse('icon-star', {
|
|
1154
1222
|
viewBox: '0 0 24 24',
|
|
1155
1223
|
})
|
|
1156
1224
|
|
|
1157
|
-
expect(svgWithViewBox.getAttribute('viewBox')).
|
|
1225
|
+
expect(svgWithViewBox.getAttribute('viewBox')).toBe(
|
|
1158
1226
|
'0 0 24 24'
|
|
1159
1227
|
)
|
|
1160
1228
|
|
|
1161
1229
|
const useViewBox = svgWithViewBox.children[0]
|
|
1162
1230
|
|
|
1163
1231
|
expect(
|
|
1164
|
-
useViewBox.getAttributeNS(
|
|
1165
|
-
|
|
1232
|
+
useViewBox.getAttributeNS(
|
|
1233
|
+
'http://www.w3.org/1999/xlink',
|
|
1234
|
+
'href'
|
|
1235
|
+
)
|
|
1236
|
+
).toBe('#icon-star')
|
|
1166
1237
|
|
|
1167
1238
|
const svgWithClass = svgUse('icon-menu', {
|
|
1168
1239
|
class: 'icon-btn',
|
|
1169
1240
|
})
|
|
1170
1241
|
|
|
1171
|
-
expect(svgWithClass.getAttribute('class')).
|
|
1242
|
+
expect(svgWithClass.getAttribute('class')).toBe(
|
|
1172
1243
|
'icon-btn'
|
|
1173
1244
|
)
|
|
1174
1245
|
|
|
1175
|
-
expect(svgWithClass.children.length).
|
|
1246
|
+
expect(svgWithClass.children.length).toBe(1)
|
|
1176
1247
|
|
|
1177
1248
|
const useClass = svgWithClass.children[0]
|
|
1178
1249
|
|
|
1179
|
-
expect(
|
|
1180
|
-
|
|
1181
|
-
|
|
1250
|
+
expect(
|
|
1251
|
+
useClass.getAttributeNS(
|
|
1252
|
+
'http://www.w3.org/1999/xlink',
|
|
1253
|
+
'href'
|
|
1254
|
+
)
|
|
1255
|
+
).toBe('#icon-menu')
|
|
1182
1256
|
|
|
1183
1257
|
const svgWithMultipleAttrs = svgUse('icon-settings', {
|
|
1184
1258
|
width: 24,
|
|
@@ -1186,23 +1260,26 @@ const svgWithMultipleAttrs = svgUse('icon-settings', {
|
|
|
1186
1260
|
class: 'icon',
|
|
1187
1261
|
})
|
|
1188
1262
|
|
|
1189
|
-
expect(svgWithMultipleAttrs.getAttribute('width')).
|
|
1263
|
+
expect(svgWithMultipleAttrs.getAttribute('width')).toBe(
|
|
1190
1264
|
'24'
|
|
1191
1265
|
)
|
|
1192
1266
|
|
|
1193
|
-
expect(
|
|
1194
|
-
|
|
1195
|
-
)
|
|
1267
|
+
expect(svgWithMultipleAttrs.getAttribute('height')).toBe(
|
|
1268
|
+
'24'
|
|
1269
|
+
)
|
|
1196
1270
|
|
|
1197
|
-
expect(svgWithMultipleAttrs.getAttribute('class')).
|
|
1271
|
+
expect(svgWithMultipleAttrs.getAttribute('class')).toBe(
|
|
1198
1272
|
'icon'
|
|
1199
1273
|
)
|
|
1200
1274
|
|
|
1201
1275
|
const useMultiple = svgWithMultipleAttrs.children[0]
|
|
1202
1276
|
|
|
1203
1277
|
expect(
|
|
1204
|
-
useMultiple.getAttributeNS(
|
|
1205
|
-
|
|
1278
|
+
useMultiple.getAttributeNS(
|
|
1279
|
+
'http://www.w3.org/1999/xlink',
|
|
1280
|
+
'href'
|
|
1281
|
+
)
|
|
1282
|
+
).toBe('#icon-settings')
|
|
1206
1283
|
```
|
|
1207
1284
|
|
|
1208
1285
|
### uuidV1
|
|
@@ -1237,47 +1314,49 @@ for (let i = 1; i <= 22136; ++i) {
|
|
|
1237
1314
|
const uuid = uuidV1()
|
|
1238
1315
|
|
|
1239
1316
|
if (i === 1) {
|
|
1240
|
-
expect(uuid.split('-')[3]).
|
|
1317
|
+
expect(uuid.split('-')[3]).toBe('8001')
|
|
1241
1318
|
}
|
|
1242
1319
|
|
|
1243
1320
|
if (i === 4095) {
|
|
1244
|
-
expect(uuid.split('-')[3]).
|
|
1321
|
+
expect(uuid.split('-')[3]).toBe('8fff')
|
|
1245
1322
|
}
|
|
1246
1323
|
|
|
1247
1324
|
if (i === 4096) {
|
|
1248
|
-
expect(uuid.split('-')[3]).
|
|
1325
|
+
expect(uuid.split('-')[3]).toBe('9000')
|
|
1249
1326
|
}
|
|
1250
1327
|
|
|
1251
1328
|
if (i === 9029) {
|
|
1252
|
-
expect(uuid.split('-')[3]).
|
|
1329
|
+
expect(uuid.split('-')[3]).toBe('a345')
|
|
1253
1330
|
}
|
|
1254
1331
|
|
|
1255
1332
|
if (i === 13398) {
|
|
1256
|
-
expect(uuid.split('-')[3]).
|
|
1333
|
+
expect(uuid.split('-')[3]).toBe('b456')
|
|
1257
1334
|
}
|
|
1258
1335
|
|
|
1259
1336
|
if (i === 16384) {
|
|
1260
|
-
expect(uuid.split('-')[3]).
|
|
1337
|
+
expect(uuid.split('-')[3]).toBe('8000')
|
|
1261
1338
|
}
|
|
1262
1339
|
|
|
1263
1340
|
if (i === 17767) {
|
|
1264
|
-
expect(uuid.split('-')[3]).
|
|
1341
|
+
expect(uuid.split('-')[3]).toBe('8567')
|
|
1265
1342
|
}
|
|
1266
1343
|
}
|
|
1344
|
+
```
|
|
1267
1345
|
|
|
1346
|
+
```ts
|
|
1268
1347
|
expect(
|
|
1269
1348
|
uuidV1(new Date(), '000123456789abc').split('-')[4]
|
|
1270
|
-
).
|
|
1349
|
+
).toBe('123456789abc')
|
|
1271
1350
|
|
|
1272
1351
|
expect(
|
|
1273
1352
|
uuidV1(new Date(), '123456789').split('-')[4]
|
|
1274
|
-
).
|
|
1353
|
+
).toBe('000123456789')
|
|
1275
1354
|
|
|
1276
1355
|
expect(
|
|
1277
1356
|
uuidV1(new Date(323325000000)).startsWith(
|
|
1278
1357
|
'c1399400-9a71-11bd'
|
|
1279
1358
|
)
|
|
1280
|
-
).
|
|
1359
|
+
).toBe(true)
|
|
1281
1360
|
```
|
|
1282
1361
|
|
|
1283
1362
|
### vivify
|
|
@@ -1345,7 +1424,7 @@ const ref: any = {}
|
|
|
1345
1424
|
|
|
1346
1425
|
vivify(ref).one.two[3][4]
|
|
1347
1426
|
|
|
1348
|
-
expect(ref).
|
|
1427
|
+
expect(ref).toEqual({
|
|
1349
1428
|
one: {
|
|
1350
1429
|
two: [undefined, undefined, undefined, []],
|
|
1351
1430
|
},
|
|
@@ -1353,7 +1432,7 @@ expect(ref).to.deep.equal({
|
|
|
1353
1432
|
|
|
1354
1433
|
vivify(ref).one.two[3][4] = 5
|
|
1355
1434
|
|
|
1356
|
-
expect(ref).
|
|
1435
|
+
expect(ref).toEqual({
|
|
1357
1436
|
one: {
|
|
1358
1437
|
two: [
|
|
1359
1438
|
undefined,
|
|
@@ -1366,7 +1445,7 @@ expect(ref).to.deep.equal({
|
|
|
1366
1445
|
|
|
1367
1446
|
vivify(ref).one.two[3].length = 1
|
|
1368
1447
|
|
|
1369
|
-
expect(ref).
|
|
1448
|
+
expect(ref).toEqual({
|
|
1370
1449
|
one: {
|
|
1371
1450
|
two: [undefined, undefined, undefined, [undefined]],
|
|
1372
1451
|
},
|
|
@@ -1374,15 +1453,15 @@ expect(ref).to.deep.equal({
|
|
|
1374
1453
|
|
|
1375
1454
|
vivify(ref).one.two[3] = 4
|
|
1376
1455
|
|
|
1377
|
-
expect(ref).
|
|
1456
|
+
expect(ref).toEqual({
|
|
1378
1457
|
one: {
|
|
1379
1458
|
two: [undefined, undefined, undefined, 4],
|
|
1380
1459
|
},
|
|
1381
1460
|
})
|
|
1382
1461
|
|
|
1383
|
-
expect(vivify(ref).one.two.length).
|
|
1462
|
+
expect(vivify(ref).one.two.length).toBe(4)
|
|
1384
1463
|
|
|
1385
|
-
expect(ref).
|
|
1464
|
+
expect(ref).toEqual({
|
|
1386
1465
|
one: {
|
|
1387
1466
|
two: [undefined, undefined, undefined, 4],
|
|
1388
1467
|
},
|
|
@@ -1390,60 +1469,63 @@ expect(ref).to.deep.equal({
|
|
|
1390
1469
|
|
|
1391
1470
|
vivify(ref).one.two = 3
|
|
1392
1471
|
|
|
1393
|
-
expect(ref).
|
|
1472
|
+
expect(ref).toEqual({ one: { two: 3 } })
|
|
1394
1473
|
|
|
1395
1474
|
vivify(ref).one.two = undefined
|
|
1396
1475
|
|
|
1397
|
-
expect(ref).
|
|
1476
|
+
expect(ref).toEqual({ one: { two: undefined } })
|
|
1398
1477
|
|
|
1399
1478
|
delete vivify(ref).one.two
|
|
1400
1479
|
|
|
1401
|
-
expect(ref).
|
|
1480
|
+
expect(ref).toEqual({ one: {} })
|
|
1402
1481
|
|
|
1403
|
-
expect(vivify(ref).one.toString instanceof Function).
|
|
1404
|
-
|
|
1482
|
+
expect(vivify(ref).one.toString instanceof Function).toBe(
|
|
1483
|
+
true
|
|
1484
|
+
)
|
|
1405
1485
|
|
|
1406
|
-
expect(vivify(ref).one.toString.name).
|
|
1486
|
+
expect(vivify(ref).one.toString.name).toBe('toString')
|
|
1407
1487
|
|
|
1408
|
-
expect(ref).
|
|
1488
|
+
expect(ref).toEqual({ one: {} })
|
|
1409
1489
|
|
|
1410
1490
|
delete vivify(ref).one.two.three
|
|
1411
1491
|
|
|
1412
|
-
expect(ref).
|
|
1492
|
+
expect(ref).toEqual({ one: { two: {} } })
|
|
1413
1493
|
|
|
1414
1494
|
vivify(ref).one.two.three.four
|
|
1415
1495
|
|
|
1416
|
-
expect(ref).
|
|
1496
|
+
expect(ref).toEqual({ one: { two: { three: {} } } })
|
|
1417
1497
|
|
|
1418
1498
|
vivify(ref).one.two[3]
|
|
1419
1499
|
|
|
1420
|
-
expect(ref).
|
|
1500
|
+
expect(ref).toEqual({ one: { two: { three: {} } } })
|
|
1421
1501
|
|
|
1422
1502
|
vivify(ref).one.two.three.four = 5
|
|
1423
1503
|
|
|
1424
|
-
expect(ref).
|
|
1504
|
+
expect(ref).toEqual({
|
|
1425
1505
|
one: { two: { three: { four: 5 } } },
|
|
1426
1506
|
})
|
|
1427
1507
|
|
|
1428
|
-
expect(
|
|
1429
|
-
|
|
1430
|
-
)
|
|
1508
|
+
expect(vivify(ref).one.two.three.four.toString.name).toBe(
|
|
1509
|
+
'toString'
|
|
1510
|
+
)
|
|
1431
1511
|
|
|
1432
|
-
expect(ref).
|
|
1512
|
+
expect(ref).toEqual({
|
|
1433
1513
|
one: { two: { three: { four: 5 } } },
|
|
1434
1514
|
})
|
|
1515
|
+
```
|
|
1435
1516
|
|
|
1517
|
+
```ts
|
|
1436
1518
|
const u = undefined
|
|
1437
1519
|
|
|
1438
1520
|
vivify(u).one.two = 3
|
|
1439
1521
|
|
|
1440
|
-
expect(u).
|
|
1522
|
+
expect(u).toBeUndefined()
|
|
1441
1523
|
|
|
1442
1524
|
const n = null
|
|
1443
1525
|
|
|
1444
1526
|
delete vivify(n).one.two.three
|
|
1445
1527
|
|
|
1446
|
-
expect(n).
|
|
1528
|
+
expect(n).toBeNull()
|
|
1447
1529
|
```
|
|
1448
1530
|
|
|
1449
1531
|
## License
|