@jackens/nnn 2024.3.2 → 2024.3.5
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/nnn.d.ts +30 -25
- package/nnn.js +59 -57
- package/package.json +3 -2
- package/readme.md +248 -232
package/nnn.d.ts
CHANGED
|
@@ -1,28 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The type of arguments of the `c` helper.
|
|
3
|
-
*/
|
|
4
|
-
export type CNode = {
|
|
5
|
-
[attributeOrSelector: string]: string | number | CNode | undefined;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The type of arguments of the `c` helper.
|
|
10
|
-
*/
|
|
11
|
-
export type CRoot = Partial<Record<PropertyKey, CNode>>;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A simple CSS-in-JS helper.
|
|
15
|
-
*
|
|
16
|
-
* The `root` parameter provides a hierarchical description of CSS rules.
|
|
17
|
-
*
|
|
18
|
-
* - Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
19
|
-
* - All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
20
|
-
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
21
|
-
* - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
22
|
-
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
23
|
-
*/
|
|
24
|
-
export declare const c: (root: CRoot, splitter?: string) => string;
|
|
25
|
-
|
|
26
1
|
/**
|
|
27
2
|
* A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
28
3
|
*
|
|
@@ -132,6 +107,11 @@ export declare const s: {
|
|
|
132
107
|
(tagOrNode: string | Node, ...args1: HArgs1[]): Node;
|
|
133
108
|
};
|
|
134
109
|
|
|
110
|
+
/**
|
|
111
|
+
* A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
112
|
+
*/
|
|
113
|
+
export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
114
|
+
|
|
135
115
|
/**
|
|
136
116
|
* A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
137
117
|
*/
|
|
@@ -151,6 +131,31 @@ export declare const is: {
|
|
|
151
131
|
<T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
|
|
152
132
|
};
|
|
153
133
|
|
|
134
|
+
/**
|
|
135
|
+
* The type of arguments of the `jc` helper.
|
|
136
|
+
*/
|
|
137
|
+
export type JcNode = {
|
|
138
|
+
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The type of arguments of the `jc` helper.
|
|
143
|
+
*/
|
|
144
|
+
export type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
148
|
+
*
|
|
149
|
+
* The `root` parameter provides a hierarchical description of CSS rules.
|
|
150
|
+
*
|
|
151
|
+
* - Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
152
|
+
* - All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
153
|
+
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
154
|
+
* - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
155
|
+
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
156
|
+
*/
|
|
157
|
+
export declare const jc: (root: JcRoot, splitter?: string) => string;
|
|
158
|
+
|
|
154
159
|
/**
|
|
155
160
|
* `JSON.parse` with “JavaScript turned on”.
|
|
156
161
|
*
|
package/nnn.js
CHANGED
|
@@ -1,59 +1,6 @@
|
|
|
1
1
|
// src/nnn/is.ts
|
|
2
2
|
var is = (type, arg) => arg?.constructor === type;
|
|
3
3
|
|
|
4
|
-
// src/nnn/c.ts
|
|
5
|
-
var _c = (node, prefix, result, split) => {
|
|
6
|
-
const queue = [[node, prefix]];
|
|
7
|
-
while (queue.length > 0) {
|
|
8
|
-
const [style0, prefix0] = queue.shift() ?? [];
|
|
9
|
-
if (style0 == null || prefix0 == null) {
|
|
10
|
-
continue;
|
|
11
|
-
}
|
|
12
|
-
if (is(Array, style0)) {
|
|
13
|
-
result.push(prefix0, prefix0 !== "" ? "{" : "", style0.join(";"), prefix0 !== "" ? "}" : "");
|
|
14
|
-
} else {
|
|
15
|
-
const todo = [];
|
|
16
|
-
let attributes = [];
|
|
17
|
-
let attributesPushed = false;
|
|
18
|
-
for (const key in style0) {
|
|
19
|
-
const value = style0[key];
|
|
20
|
-
if (is(String, value) || is(Number, value)) {
|
|
21
|
-
if (!attributesPushed) {
|
|
22
|
-
attributesPushed = true;
|
|
23
|
-
attributes = [];
|
|
24
|
-
todo.push([attributes, prefix0]);
|
|
25
|
-
}
|
|
26
|
-
attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
|
|
27
|
-
} else if (value != null) {
|
|
28
|
-
attributesPushed = false;
|
|
29
|
-
const prefixN = [];
|
|
30
|
-
const keyChunks = key.split(",");
|
|
31
|
-
prefix0.split(",").forEach((prefixChunk) => keyChunks.forEach((keyChunk) => prefixN.push(prefixChunk + keyChunk)));
|
|
32
|
-
todo.push([value, prefixN.join(",")]);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
queue.unshift(...todo);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var c = (root, splitter = "$$") => {
|
|
40
|
-
const split = (text) => text.split(splitter)[0];
|
|
41
|
-
const chunks = [];
|
|
42
|
-
for (const key in root) {
|
|
43
|
-
const value = root[key];
|
|
44
|
-
if (value != null) {
|
|
45
|
-
if (key[0] === "@") {
|
|
46
|
-
chunks.push(split(key) + "{");
|
|
47
|
-
_c(value, "", chunks, split);
|
|
48
|
-
chunks.push("}");
|
|
49
|
-
} else {
|
|
50
|
-
_c(value, split(key), chunks, split);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return chunks.join("");
|
|
55
|
-
};
|
|
56
|
-
|
|
57
4
|
// src/nnn/h.ts
|
|
58
5
|
var NS = {
|
|
59
6
|
xlink: "http://www.w3.org/1999/xlink"
|
|
@@ -117,6 +64,7 @@ var _h = (namespaceURI) => {
|
|
|
117
64
|
};
|
|
118
65
|
var h = _h();
|
|
119
66
|
var s = _h("http://www.w3.org/2000/svg");
|
|
67
|
+
var svgUse = (id, ...args) => s("svg", ["use", { "xlink:href": "#" + id }], ...args);
|
|
120
68
|
|
|
121
69
|
// src/nnn/chartable.ts
|
|
122
70
|
var COLORS = ["#e22", "#e73", "#fc3", "#ad4", "#4d9", "#3be", "#45d", "#c3e"];
|
|
@@ -141,9 +89,9 @@ var chartable = ({
|
|
|
141
89
|
const zxValues = [];
|
|
142
90
|
const xLabels = [];
|
|
143
91
|
const zLabels = [];
|
|
144
|
-
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col,
|
|
92
|
+
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c) => {
|
|
145
93
|
const x = r - 1;
|
|
146
|
-
const z =
|
|
94
|
+
const z = c - +headerColumn;
|
|
147
95
|
const value = col.innerText;
|
|
148
96
|
if (x >= 0 && z >= 0) {
|
|
149
97
|
zxValues[z] = zxValues[z] ?? [];
|
|
@@ -303,6 +251,59 @@ var fixTypography = (node) => {
|
|
|
303
251
|
// src/nnn/has.ts
|
|
304
252
|
var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
|
|
305
253
|
|
|
254
|
+
// src/nnn/jc.ts
|
|
255
|
+
var _jc = (node, prefix, result, split) => {
|
|
256
|
+
const queue = [[node, prefix]];
|
|
257
|
+
while (queue.length > 0) {
|
|
258
|
+
const [style0, prefix0] = queue.shift() ?? [];
|
|
259
|
+
if (style0 == null || prefix0 == null) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (is(Array, style0)) {
|
|
263
|
+
result.push(prefix0, prefix0 !== "" ? "{" : "", style0.join(";"), prefix0 !== "" ? "}" : "");
|
|
264
|
+
} else {
|
|
265
|
+
const todo = [];
|
|
266
|
+
let attributes = [];
|
|
267
|
+
let attributesPushed = false;
|
|
268
|
+
for (const key in style0) {
|
|
269
|
+
const value = style0[key];
|
|
270
|
+
if (is(String, value) || is(Number, value)) {
|
|
271
|
+
if (!attributesPushed) {
|
|
272
|
+
attributesPushed = true;
|
|
273
|
+
attributes = [];
|
|
274
|
+
todo.push([attributes, prefix0]);
|
|
275
|
+
}
|
|
276
|
+
attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
|
|
277
|
+
} else if (value != null) {
|
|
278
|
+
attributesPushed = false;
|
|
279
|
+
const prefixN = [];
|
|
280
|
+
const keyChunks = key.split(",");
|
|
281
|
+
prefix0.split(",").forEach((prefixChunk) => keyChunks.forEach((keyChunk) => prefixN.push(prefixChunk + keyChunk)));
|
|
282
|
+
todo.push([value, prefixN.join(",")]);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
queue.unshift(...todo);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var jc = (root, splitter = "$$") => {
|
|
290
|
+
const split = (text) => text.split(splitter)[0];
|
|
291
|
+
const chunks = [];
|
|
292
|
+
for (const key in root) {
|
|
293
|
+
const value = root[key];
|
|
294
|
+
if (value != null) {
|
|
295
|
+
if (key[0] === "@") {
|
|
296
|
+
chunks.push(split(key) + "{");
|
|
297
|
+
_jc(value, "", chunks, split);
|
|
298
|
+
chunks.push("}");
|
|
299
|
+
} else {
|
|
300
|
+
_jc(value, split(key), chunks, split);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return chunks.join("");
|
|
305
|
+
};
|
|
306
|
+
|
|
306
307
|
// src/nnn/jsOnParse.ts
|
|
307
308
|
var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
308
309
|
if (is(Object, value)) {
|
|
@@ -398,6 +399,7 @@ var uuid1 = ({
|
|
|
398
399
|
};
|
|
399
400
|
export {
|
|
400
401
|
uuid1,
|
|
402
|
+
svgUse,
|
|
401
403
|
s,
|
|
402
404
|
refsInfo,
|
|
403
405
|
pro,
|
|
@@ -408,6 +410,7 @@ export {
|
|
|
408
410
|
nanolight,
|
|
409
411
|
locale,
|
|
410
412
|
jsOnParse,
|
|
413
|
+
jc,
|
|
411
414
|
is,
|
|
412
415
|
has,
|
|
413
416
|
h,
|
|
@@ -415,6 +418,5 @@ export {
|
|
|
415
418
|
escapeValues,
|
|
416
419
|
escape,
|
|
417
420
|
eq,
|
|
418
|
-
chartable
|
|
419
|
-
c
|
|
421
|
+
chartable
|
|
420
422
|
};
|
package/package.json
CHANGED
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"HyperScript",
|
|
21
21
|
"in",
|
|
22
22
|
"is",
|
|
23
|
-
"
|
|
23
|
+
"jc",
|
|
24
|
+
"JS-to-CSS",
|
|
24
25
|
"JSON",
|
|
25
26
|
"jsOnParse",
|
|
26
27
|
"locale",
|
|
@@ -42,5 +43,5 @@
|
|
|
42
43
|
"types": "nnn.d.ts",
|
|
43
44
|
"name": "@jackens/nnn",
|
|
44
45
|
"type": "module",
|
|
45
|
-
"version": "2024.3.
|
|
46
|
+
"version": "2024.3.5"
|
|
46
47
|
}
|
package/readme.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.3.
|
|
5
|
+
<sub>Version: <code class="version">2024.3.5</code></sub>
|
|
6
6
|
|
|
7
7
|
## Examples
|
|
8
8
|
|
|
9
|
-
- [Chartable Demo](/nnn/chartable/)
|
|
10
|
-
- [Chessboard Demo](/nnn/chessboard/)
|
|
11
|
-
- [Documentation](/nnn/doc/)
|
|
12
|
-
- [Gant Chart Demo](/nnn/gantt/)
|
|
13
|
-
- [Responsive Web Design Demo](/nnn/rwd/)
|
|
9
|
+
- [Chartable Demo](https://jackens.github.io/nnn/chartable/)
|
|
10
|
+
- [Chessboard Demo](https://jackens.github.io/nnn/chessboard/)
|
|
11
|
+
- [Documentation](https://jackens.github.io/nnn/doc/)
|
|
12
|
+
- [Gant Chart Demo](https://jackens.github.io/nnn/gantt/)
|
|
13
|
+
- [Responsive Web Design Demo](https://jackens.github.io/nnn/rwd/)
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -40,12 +40,11 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
40
40
|
|
|
41
41
|
## Exports
|
|
42
42
|
|
|
43
|
-
- `CNode`: The type of arguments of the `c` helper.
|
|
44
|
-
- `CRoot`: The type of arguments of the `c` helper.
|
|
45
43
|
- `EscapeMap`: The type of arguments of the `escapeValues` and `escape` helpers.
|
|
46
44
|
- `HArgs`: The type of arguments of the `h` and `s` helpers.
|
|
47
45
|
- `HArgs1`: The type of arguments of the `h` and `s` helpers.
|
|
48
|
-
- `
|
|
46
|
+
- `JcNode`: The type of arguments of the `jc` helper.
|
|
47
|
+
- `JcRoot`: The type of arguments of the `jc` helper.
|
|
49
48
|
- `chartable`: A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
50
49
|
- `eq`: A helper that checks equality of the given arguments.
|
|
51
50
|
- `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
@@ -54,6 +53,7 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
54
53
|
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
55
54
|
- `has`: A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
56
55
|
- `is`: A helper that checks if the given argument is of a certain type.
|
|
56
|
+
- `jc`: A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
57
57
|
- `jsOnParse`: `JSON.parse` with “JavaScript turned on”.
|
|
58
58
|
- `locale`: Language translations helper.
|
|
59
59
|
- `nanolight`: A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
@@ -64,26 +64,9 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
64
64
|
- `pro`: A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty object.
|
|
65
65
|
- `refsInfo`: A helper that provides information about the given `refs`.
|
|
66
66
|
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
67
|
+
- `svgUse`: A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
67
68
|
- `uuid1`: A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
68
69
|
|
|
69
|
-
### CNode
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
type CNode = {
|
|
73
|
-
[attributeOrSelector: string]: string | number | CNode | undefined;
|
|
74
|
-
};
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
The type of arguments of the `c` helper.
|
|
78
|
-
|
|
79
|
-
### CRoot
|
|
80
|
-
|
|
81
|
-
```ts
|
|
82
|
-
type CRoot = Partial<Record<PropertyKey, CNode>>;
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
The type of arguments of the `c` helper.
|
|
86
|
-
|
|
87
70
|
### EscapeMap
|
|
88
71
|
|
|
89
72
|
```ts
|
|
@@ -108,217 +91,23 @@ type HArgs1 = Partial<Record<PropertyKey, any>> | null | undefined | Node | stri
|
|
|
108
91
|
|
|
109
92
|
The type of arguments of the `h` and `s` helpers.
|
|
110
93
|
|
|
111
|
-
###
|
|
94
|
+
### JcNode
|
|
112
95
|
|
|
113
96
|
```ts
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
A simple CSS-in-JS helper.
|
|
118
|
-
|
|
119
|
-
The `root` parameter provides a hierarchical description of CSS rules.
|
|
120
|
-
|
|
121
|
-
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
122
|
-
- All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
123
|
-
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
124
|
-
- Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
125
|
-
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
126
|
-
|
|
127
|
-
#### Usage Examples
|
|
128
|
-
|
|
129
|
-
```js
|
|
130
|
-
const actual = c({
|
|
131
|
-
a: {
|
|
132
|
-
color: 'red',
|
|
133
|
-
margin: 1,
|
|
134
|
-
'.c': { margin: 2, padding: 2 },
|
|
135
|
-
padding: 1
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
const expected = `
|
|
140
|
-
a{
|
|
141
|
-
color:red;
|
|
142
|
-
margin:1
|
|
143
|
-
}
|
|
144
|
-
a.c{
|
|
145
|
-
margin:2;
|
|
146
|
-
padding:2
|
|
147
|
-
}
|
|
148
|
-
a{
|
|
149
|
-
padding:1
|
|
150
|
-
}`.replace(/\n\s*/g, '')
|
|
151
|
-
|
|
152
|
-
expect(actual).toStrictEqual(expected)
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
```js
|
|
156
|
-
const actual = c({
|
|
157
|
-
a: {
|
|
158
|
-
'.b': {
|
|
159
|
-
color: 'red',
|
|
160
|
-
margin: 1,
|
|
161
|
-
'.c': { margin: 2, padding: 2 },
|
|
162
|
-
padding: 1
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
const expected = `
|
|
168
|
-
a.b{
|
|
169
|
-
color:red;
|
|
170
|
-
margin:1
|
|
171
|
-
}
|
|
172
|
-
a.b.c{
|
|
173
|
-
margin:2;
|
|
174
|
-
padding:2
|
|
175
|
-
}
|
|
176
|
-
a.b{
|
|
177
|
-
padding:1
|
|
178
|
-
}`.replace(/\n\s*/g, '')
|
|
179
|
-
|
|
180
|
-
expect(actual).toStrictEqual(expected)
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
```js
|
|
184
|
-
const actual = c({
|
|
185
|
-
'@font-face$$1': {
|
|
186
|
-
fontFamily: 'Jackens',
|
|
187
|
-
src$$1: 'url(otf/jackens.otf)',
|
|
188
|
-
src$$2: "url(otf/jackens.otf) format('opentype')," +
|
|
189
|
-
"url(svg/jackens.svg) format('svg')",
|
|
190
|
-
fontWeight: 'normal',
|
|
191
|
-
fontStyle: 'normal'
|
|
192
|
-
},
|
|
193
|
-
'@font-face$$2': {
|
|
194
|
-
fontFamily: 'C64',
|
|
195
|
-
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
|
|
196
|
-
},
|
|
197
|
-
'@keyframes spin': {
|
|
198
|
-
'0%': { transform: 'rotate(0deg)' },
|
|
199
|
-
'100%': { transform: 'rotate(360deg)' }
|
|
200
|
-
},
|
|
201
|
-
div: {
|
|
202
|
-
border: 'solid red 1px',
|
|
203
|
-
'.c1': { 'background-color': '#000' },
|
|
204
|
-
' .c1': { backgroundColor: 'black' },
|
|
205
|
-
'.c2': { backgroundColor: 'rgb(0,0,0)' }
|
|
206
|
-
},
|
|
207
|
-
'@media(min-width:200px)': {
|
|
208
|
-
div: { margin: 0, padding: 0 },
|
|
209
|
-
span: { color: '#000' }
|
|
210
|
-
}
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
const expected = `
|
|
214
|
-
@font-face{
|
|
215
|
-
font-family:Jackens;
|
|
216
|
-
src:url(otf/jackens.otf);
|
|
217
|
-
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
218
|
-
font-weight:normal;
|
|
219
|
-
font-style:normal
|
|
220
|
-
}
|
|
221
|
-
@font-face{
|
|
222
|
-
font-family:C64;
|
|
223
|
-
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
224
|
-
}
|
|
225
|
-
@keyframes spin{
|
|
226
|
-
0%{
|
|
227
|
-
transform:rotate(0deg)
|
|
228
|
-
}
|
|
229
|
-
100%{
|
|
230
|
-
transform:rotate(360deg)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
div{
|
|
234
|
-
border:solid red 1px
|
|
235
|
-
}
|
|
236
|
-
div.c1{
|
|
237
|
-
background-color:#000
|
|
238
|
-
}
|
|
239
|
-
div .c1{
|
|
240
|
-
background-color:black
|
|
241
|
-
}
|
|
242
|
-
div.c2{
|
|
243
|
-
background-color:rgb(0,0,0)
|
|
244
|
-
}
|
|
245
|
-
@media(min-width:200px){
|
|
246
|
-
div{
|
|
247
|
-
margin:0;
|
|
248
|
-
padding:0
|
|
249
|
-
}
|
|
250
|
-
span{
|
|
251
|
-
color:#000
|
|
252
|
-
}
|
|
253
|
-
}`.replace(/\n\s*/g, '')
|
|
254
|
-
|
|
255
|
-
expect(actual).toStrictEqual(expected)
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
```js
|
|
259
|
-
const actual = c({
|
|
260
|
-
a: {
|
|
261
|
-
'.b,.c': {
|
|
262
|
-
margin: 1,
|
|
263
|
-
'.d': {
|
|
264
|
-
margin: 2
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
const expected = `
|
|
271
|
-
a.b,a.c{
|
|
272
|
-
margin:1
|
|
273
|
-
}
|
|
274
|
-
a.b.d,a.c.d{
|
|
275
|
-
margin:2
|
|
276
|
-
}`.replace(/\n\s*/g, '')
|
|
277
|
-
|
|
278
|
-
expect(actual).toStrictEqual(expected)
|
|
97
|
+
type JcNode = {
|
|
98
|
+
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
99
|
+
};
|
|
279
100
|
```
|
|
280
101
|
|
|
281
|
-
|
|
282
|
-
const actual = c({
|
|
283
|
-
'.b,.c': {
|
|
284
|
-
margin: 1,
|
|
285
|
-
'.d': {
|
|
286
|
-
margin: 2
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
})
|
|
102
|
+
The type of arguments of the `jc` helper.
|
|
290
103
|
|
|
291
|
-
|
|
292
|
-
.b,.c{
|
|
293
|
-
margin:1
|
|
294
|
-
}
|
|
295
|
-
.b.d,.c.d{
|
|
296
|
-
margin:2
|
|
297
|
-
}`.replace(/\n\s*/g, '')
|
|
104
|
+
### JcRoot
|
|
298
105
|
|
|
299
|
-
|
|
106
|
+
```ts
|
|
107
|
+
type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
300
108
|
```
|
|
301
109
|
|
|
302
|
-
|
|
303
|
-
const actual = c({
|
|
304
|
-
'.a,.b': {
|
|
305
|
-
margin: 1,
|
|
306
|
-
'.c,.d': {
|
|
307
|
-
margin: 2
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
const expected = `
|
|
313
|
-
.a,.b{
|
|
314
|
-
margin:1
|
|
315
|
-
}
|
|
316
|
-
.a.c,.a.d,.b.c,.b.d{
|
|
317
|
-
margin:2
|
|
318
|
-
}`.replace(/\n\s*/g, '')
|
|
319
|
-
|
|
320
|
-
expect(actual).toStrictEqual(expected)
|
|
321
|
-
```
|
|
110
|
+
The type of arguments of the `jc` helper.
|
|
322
111
|
|
|
323
112
|
### chartable
|
|
324
113
|
|
|
@@ -665,6 +454,218 @@ try {
|
|
|
665
454
|
expect(is(Number, num)).toBeTrue()
|
|
666
455
|
```
|
|
667
456
|
|
|
457
|
+
### jc
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
const jc: (root: JcRoot, splitter?: string) => string;
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
464
|
+
|
|
465
|
+
The `root` parameter provides a hierarchical description of CSS rules.
|
|
466
|
+
|
|
467
|
+
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
468
|
+
- All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
469
|
+
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
470
|
+
- Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
471
|
+
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
472
|
+
|
|
473
|
+
#### Usage Examples
|
|
474
|
+
|
|
475
|
+
```js
|
|
476
|
+
const actual = jc({
|
|
477
|
+
a: {
|
|
478
|
+
color: 'red',
|
|
479
|
+
margin: 1,
|
|
480
|
+
'.c': { margin: 2, padding: 2 },
|
|
481
|
+
padding: 1
|
|
482
|
+
}
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
const expected = `
|
|
486
|
+
a{
|
|
487
|
+
color:red;
|
|
488
|
+
margin:1
|
|
489
|
+
}
|
|
490
|
+
a.c{
|
|
491
|
+
margin:2;
|
|
492
|
+
padding:2
|
|
493
|
+
}
|
|
494
|
+
a{
|
|
495
|
+
padding:1
|
|
496
|
+
}`.replace(/\n\s*/g, '')
|
|
497
|
+
|
|
498
|
+
expect(actual).toStrictEqual(expected)
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
```js
|
|
502
|
+
const actual = jc({
|
|
503
|
+
a: {
|
|
504
|
+
'.b': {
|
|
505
|
+
color: 'red',
|
|
506
|
+
margin: 1,
|
|
507
|
+
'.c': { margin: 2, padding: 2 },
|
|
508
|
+
padding: 1
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
const expected = `
|
|
514
|
+
a.b{
|
|
515
|
+
color:red;
|
|
516
|
+
margin:1
|
|
517
|
+
}
|
|
518
|
+
a.b.c{
|
|
519
|
+
margin:2;
|
|
520
|
+
padding:2
|
|
521
|
+
}
|
|
522
|
+
a.b{
|
|
523
|
+
padding:1
|
|
524
|
+
}`.replace(/\n\s*/g, '')
|
|
525
|
+
|
|
526
|
+
expect(actual).toStrictEqual(expected)
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
```js
|
|
530
|
+
const actual = jc({
|
|
531
|
+
'@font-face$$1': {
|
|
532
|
+
fontFamily: 'Jackens',
|
|
533
|
+
src$$1: 'url(otf/jackens.otf)',
|
|
534
|
+
src$$2: "url(otf/jackens.otf) format('opentype')," +
|
|
535
|
+
"url(svg/jackens.svg) format('svg')",
|
|
536
|
+
fontWeight: 'normal',
|
|
537
|
+
fontStyle: 'normal'
|
|
538
|
+
},
|
|
539
|
+
'@font-face$$2': {
|
|
540
|
+
fontFamily: 'C64',
|
|
541
|
+
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
|
|
542
|
+
},
|
|
543
|
+
'@keyframes spin': {
|
|
544
|
+
'0%': { transform: 'rotate(0deg)' },
|
|
545
|
+
'100%': { transform: 'rotate(360deg)' }
|
|
546
|
+
},
|
|
547
|
+
div: {
|
|
548
|
+
border: 'solid red 1px',
|
|
549
|
+
'.c1': { 'background-color': '#000' },
|
|
550
|
+
' .c1': { backgroundColor: 'black' },
|
|
551
|
+
'.c2': { backgroundColor: 'rgb(0,0,0)' }
|
|
552
|
+
},
|
|
553
|
+
'@media(min-width:200px)': {
|
|
554
|
+
div: { margin: 0, padding: 0 },
|
|
555
|
+
span: { color: '#000' }
|
|
556
|
+
}
|
|
557
|
+
})
|
|
558
|
+
|
|
559
|
+
const expected = `
|
|
560
|
+
@font-face{
|
|
561
|
+
font-family:Jackens;
|
|
562
|
+
src:url(otf/jackens.otf);
|
|
563
|
+
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
564
|
+
font-weight:normal;
|
|
565
|
+
font-style:normal
|
|
566
|
+
}
|
|
567
|
+
@font-face{
|
|
568
|
+
font-family:C64;
|
|
569
|
+
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
570
|
+
}
|
|
571
|
+
@keyframes spin{
|
|
572
|
+
0%{
|
|
573
|
+
transform:rotate(0deg)
|
|
574
|
+
}
|
|
575
|
+
100%{
|
|
576
|
+
transform:rotate(360deg)
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
div{
|
|
580
|
+
border:solid red 1px
|
|
581
|
+
}
|
|
582
|
+
div.c1{
|
|
583
|
+
background-color:#000
|
|
584
|
+
}
|
|
585
|
+
div .c1{
|
|
586
|
+
background-color:black
|
|
587
|
+
}
|
|
588
|
+
div.c2{
|
|
589
|
+
background-color:rgb(0,0,0)
|
|
590
|
+
}
|
|
591
|
+
@media(min-width:200px){
|
|
592
|
+
div{
|
|
593
|
+
margin:0;
|
|
594
|
+
padding:0
|
|
595
|
+
}
|
|
596
|
+
span{
|
|
597
|
+
color:#000
|
|
598
|
+
}
|
|
599
|
+
}`.replace(/\n\s*/g, '')
|
|
600
|
+
|
|
601
|
+
expect(actual).toStrictEqual(expected)
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
```js
|
|
605
|
+
const actual = jc({
|
|
606
|
+
a: {
|
|
607
|
+
'.b,.c': {
|
|
608
|
+
margin: 1,
|
|
609
|
+
'.d': {
|
|
610
|
+
margin: 2
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
const expected = `
|
|
617
|
+
a.b,a.c{
|
|
618
|
+
margin:1
|
|
619
|
+
}
|
|
620
|
+
a.b.d,a.c.d{
|
|
621
|
+
margin:2
|
|
622
|
+
}`.replace(/\n\s*/g, '')
|
|
623
|
+
|
|
624
|
+
expect(actual).toStrictEqual(expected)
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
```js
|
|
628
|
+
const actual = jc({
|
|
629
|
+
'.b,.c': {
|
|
630
|
+
margin: 1,
|
|
631
|
+
'.d': {
|
|
632
|
+
margin: 2
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
})
|
|
636
|
+
|
|
637
|
+
const expected = `
|
|
638
|
+
.b,.c{
|
|
639
|
+
margin:1
|
|
640
|
+
}
|
|
641
|
+
.b.d,.c.d{
|
|
642
|
+
margin:2
|
|
643
|
+
}`.replace(/\n\s*/g, '')
|
|
644
|
+
|
|
645
|
+
expect(actual).toStrictEqual(expected)
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
```js
|
|
649
|
+
const actual = jc({
|
|
650
|
+
'.a,.b': {
|
|
651
|
+
margin: 1,
|
|
652
|
+
'.c,.d': {
|
|
653
|
+
margin: 2
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
const expected = `
|
|
659
|
+
.a,.b{
|
|
660
|
+
margin:1
|
|
661
|
+
}
|
|
662
|
+
.a.c,.a.d,.b.c,.b.d{
|
|
663
|
+
margin:2
|
|
664
|
+
}`.replace(/\n\s*/g, '')
|
|
665
|
+
|
|
666
|
+
expect(actual).toStrictEqual(expected)
|
|
667
|
+
```
|
|
668
|
+
|
|
668
669
|
### jsOnParse
|
|
669
670
|
|
|
670
671
|
```ts
|
|
@@ -783,8 +784,15 @@ A helper for highlighting JavaScript.
|
|
|
783
784
|
```js
|
|
784
785
|
const codeJs = 'const answerToLifeTheUniverseAndEverything = 42'
|
|
785
786
|
|
|
786
|
-
expect(
|
|
787
|
-
'
|
|
787
|
+
expect(nanolightJs(codeJs)).toStrictEqual([
|
|
788
|
+
['span', { class: 'keyword' }, 'const'],
|
|
789
|
+
' ',
|
|
790
|
+
['span', { class: 'literal' }, 'answerToLifeTheUniverseAndEverything'],
|
|
791
|
+
' ',
|
|
792
|
+
['span', { class: 'operator' }, '='],
|
|
793
|
+
' ',
|
|
794
|
+
['span', { class: 'number' }, '42']
|
|
795
|
+
])
|
|
788
796
|
```
|
|
789
797
|
|
|
790
798
|
### omit
|
|
@@ -950,6 +958,14 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
|
|
|
950
958
|
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
|
|
951
959
|
- All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or modified.
|
|
952
960
|
|
|
961
|
+
### svgUse
|
|
962
|
+
|
|
963
|
+
```ts
|
|
964
|
+
const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
968
|
+
|
|
953
969
|
### uuid1
|
|
954
970
|
|
|
955
971
|
```ts
|