@jackens/nnn 2024.7.13 → 2024.7.14
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 +49 -40
- package/nnn.js +58 -58
- package/package.json +2 -2
- package/readme.md +253 -244
package/nnn.d.ts
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
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 JS-to-CSS (aka 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
|
|
19
|
+
* those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
20
|
+
* - All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` →
|
|
21
|
+
* `src`, `@font-face$$1` → `@font-face`).
|
|
22
|
+
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-`
|
|
23
|
+
* character preceding them (e.g. `fontFamily` → `font-family`).
|
|
24
|
+
* - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g.
|
|
25
|
+
* `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
26
|
+
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
27
|
+
*/
|
|
28
|
+
export declare const c: (root: CRoot, splitter?: string) => string;
|
|
29
|
+
|
|
1
30
|
/**
|
|
2
31
|
* A tiny helper for CSV parsing.
|
|
3
32
|
*
|
|
@@ -41,19 +70,21 @@ export type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined |
|
|
|
41
70
|
export type HArgs = [string | Node, ...HArgs1[]];
|
|
42
71
|
|
|
43
72
|
/**
|
|
44
|
-
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
73
|
+
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
74
|
+
* `HTMLElement`s (see also `s`).
|
|
45
75
|
*
|
|
46
76
|
* - The first argument of type `string` specifies the tag of the element to be created.
|
|
47
77
|
* - The first argument of type `Node` specifies the element to be modified.
|
|
48
78
|
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
49
|
-
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
50
|
-
* (Note that `$` is not a valid attribute name character.)
|
|
51
|
-
*
|
|
52
|
-
* An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
79
|
+
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
80
|
+
* modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
81
|
+
* `setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
53
82
|
* - All other arguments of type `null` or `undefined` are simply ignored.
|
|
54
83
|
* - All other arguments of type `Node` are appended to the element being created or modified.
|
|
55
|
-
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
56
|
-
*
|
|
84
|
+
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
85
|
+
* created or modified.
|
|
86
|
+
* - All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or
|
|
87
|
+
* modified.
|
|
57
88
|
*/
|
|
58
89
|
export declare const h: {
|
|
59
90
|
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): HTMLElementTagNameMap[T];
|
|
@@ -62,19 +93,21 @@ export declare const h: {
|
|
|
62
93
|
};
|
|
63
94
|
|
|
64
95
|
/**
|
|
65
|
-
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
96
|
+
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
97
|
+
* `SVGElement`s (see also `h`).
|
|
66
98
|
*
|
|
67
99
|
* - The first argument of type `string` specifies the tag of the element to be created.
|
|
68
100
|
* - The first argument of type `Node` specifies the element to be modified.
|
|
69
101
|
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
70
|
-
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
71
|
-
* (Note that `$` is not a valid attribute name character.)
|
|
72
|
-
*
|
|
73
|
-
* An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
102
|
+
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
103
|
+
* modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
104
|
+
* `setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
74
105
|
* - All other arguments of type `null` or `undefined` are simply ignored.
|
|
75
106
|
* - All other arguments of type `Node` are appended to the element being created or modified.
|
|
76
|
-
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
77
|
-
*
|
|
107
|
+
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
108
|
+
* created or modified.
|
|
109
|
+
* - All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or
|
|
110
|
+
* modified.
|
|
78
111
|
*/
|
|
79
112
|
export declare const s: {
|
|
80
113
|
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): SVGElementTagNameMap[T];
|
|
@@ -107,31 +140,6 @@ export declare const is: {
|
|
|
107
140
|
<T extends abstract new (...args: Partial<Array<any>>) => unknown>(type: T, arg: unknown): arg is InstanceType<T>;
|
|
108
141
|
};
|
|
109
142
|
|
|
110
|
-
/**
|
|
111
|
-
* The type of arguments of the `jc` helper.
|
|
112
|
-
*/
|
|
113
|
-
export type JcNode = {
|
|
114
|
-
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* The type of arguments of the `jc` helper.
|
|
119
|
-
*/
|
|
120
|
-
export type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
124
|
-
*
|
|
125
|
-
* The `root` parameter provides a hierarchical description of CSS rules.
|
|
126
|
-
*
|
|
127
|
-
* - 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.
|
|
128
|
-
* - 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`).
|
|
129
|
-
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
130
|
-
* - 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}`).
|
|
131
|
-
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
132
|
-
*/
|
|
133
|
-
export declare const jc: (root: JcRoot, splitter?: string) => string;
|
|
134
|
-
|
|
135
143
|
/**
|
|
136
144
|
* `JSON.parse` with “JavaScript turned on”.
|
|
137
145
|
*
|
|
@@ -180,7 +188,8 @@ export declare const omit: <T extends Partial<Record<PropertyKey, unknown>>, K e
|
|
|
180
188
|
export declare const plUral: (singular: string, plural2: string, plural5: string, value: number) => string;
|
|
181
189
|
|
|
182
190
|
/**
|
|
183
|
-
* A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
191
|
+
* A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
192
|
+
* object.
|
|
184
193
|
*/
|
|
185
194
|
export declare const pro: (ref: unknown) => any;
|
|
186
195
|
|
package/nnn.js
CHANGED
|
@@ -1,3 +1,59 @@
|
|
|
1
|
+
// src/nnn/is.ts
|
|
2
|
+
var is = (type, arg) => arg?.constructor === type;
|
|
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
|
+
|
|
1
57
|
// src/nnn/csvParse.ts
|
|
2
58
|
var csvParse = (text, { header = true, separator = "," } = {}) => {
|
|
3
59
|
const regExp = new RegExp(`${separator}|(?<!")\\s*"((?:[^"]|"")*)"\\s*(?!")`, "g");
|
|
@@ -16,9 +72,6 @@ var csvParse = (text, { header = true, separator = "," } = {}) => {
|
|
|
16
72
|
var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
|
|
17
73
|
var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
|
|
18
74
|
|
|
19
|
-
// src/nnn/is.ts
|
|
20
|
-
var is = (type, arg) => arg?.constructor === type;
|
|
21
|
-
|
|
22
75
|
// src/nnn/h.ts
|
|
23
76
|
var NS = {
|
|
24
77
|
xlink: "http://www.w3.org/1999/xlink"
|
|
@@ -119,59 +172,6 @@ var fixTypography = (node) => {
|
|
|
119
172
|
// src/nnn/has.ts
|
|
120
173
|
var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
|
|
121
174
|
|
|
122
|
-
// src/nnn/jc.ts
|
|
123
|
-
var _jc = (node, prefix, result, split) => {
|
|
124
|
-
const queue = [[node, prefix]];
|
|
125
|
-
while (queue.length > 0) {
|
|
126
|
-
const [style0, prefix0] = queue.shift() ?? [];
|
|
127
|
-
if (style0 == null || prefix0 == null) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (is(Array, style0)) {
|
|
131
|
-
result.push(prefix0, prefix0 !== "" ? "{" : "", style0.join(";"), prefix0 !== "" ? "}" : "");
|
|
132
|
-
} else {
|
|
133
|
-
const todo = [];
|
|
134
|
-
let attributes = [];
|
|
135
|
-
let attributesPushed = false;
|
|
136
|
-
for (const key in style0) {
|
|
137
|
-
const value = style0[key];
|
|
138
|
-
if (is(String, value) || is(Number, value)) {
|
|
139
|
-
if (!attributesPushed) {
|
|
140
|
-
attributesPushed = true;
|
|
141
|
-
attributes = [];
|
|
142
|
-
todo.push([attributes, prefix0]);
|
|
143
|
-
}
|
|
144
|
-
attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
|
|
145
|
-
} else if (value != null) {
|
|
146
|
-
attributesPushed = false;
|
|
147
|
-
const prefixN = [];
|
|
148
|
-
const keyChunks = key.split(",");
|
|
149
|
-
prefix0.split(",").forEach((prefixChunk) => keyChunks.forEach((keyChunk) => prefixN.push(prefixChunk + keyChunk)));
|
|
150
|
-
todo.push([value, prefixN.join(",")]);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
queue.unshift(...todo);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
var jc = (root, splitter = "$$") => {
|
|
158
|
-
const split = (text) => text.split(splitter)[0];
|
|
159
|
-
const chunks = [];
|
|
160
|
-
for (const key in root) {
|
|
161
|
-
const value = root[key];
|
|
162
|
-
if (value != null) {
|
|
163
|
-
if (key[0] === "@") {
|
|
164
|
-
chunks.push(split(key) + "{");
|
|
165
|
-
_jc(value, "", chunks, split);
|
|
166
|
-
chunks.push("}");
|
|
167
|
-
} else {
|
|
168
|
-
_jc(value, split(key), chunks, split);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return chunks.join("");
|
|
173
|
-
};
|
|
174
|
-
|
|
175
175
|
// src/nnn/jsOnParse.ts
|
|
176
176
|
var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
177
177
|
if (is(Object, value)) {
|
|
@@ -280,12 +280,12 @@ export {
|
|
|
280
280
|
nanolight,
|
|
281
281
|
locale,
|
|
282
282
|
jsOnParse,
|
|
283
|
-
jc,
|
|
284
283
|
is,
|
|
285
284
|
has,
|
|
286
285
|
h,
|
|
287
286
|
fixTypography,
|
|
288
287
|
escapeValues,
|
|
289
288
|
escape,
|
|
290
|
-
csvParse
|
|
289
|
+
csvParse,
|
|
290
|
+
c
|
|
291
291
|
};
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"description": "Jackens’ JavaScript helpers.",
|
|
4
4
|
"homepage": "https://jackens.github.io/nnn/doc/",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"c",
|
|
6
7
|
"CSS-in-JS",
|
|
7
8
|
"CSV",
|
|
8
9
|
"csvParse",
|
|
@@ -14,7 +15,6 @@
|
|
|
14
15
|
"HyperScript",
|
|
15
16
|
"in",
|
|
16
17
|
"is",
|
|
17
|
-
"jc",
|
|
18
18
|
"JS-to-CSS",
|
|
19
19
|
"JSON",
|
|
20
20
|
"jsOnParse",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"name": "@jackens/nnn",
|
|
37
37
|
"type": "module",
|
|
38
38
|
"types": "nnn.d.ts",
|
|
39
|
-
"version": "2024.7.
|
|
39
|
+
"version": "2024.7.14"
|
|
40
40
|
}
|
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.7.
|
|
5
|
+
<sub>Version: <code class="version">2024.7.14</code></sub>
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -31,24 +31,24 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
31
31
|
or:
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.7.
|
|
34
|
+
import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.7.14/nnn.js'
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Exports
|
|
38
38
|
|
|
39
|
+
- `CNode`: The type of arguments of the `c` helper.
|
|
40
|
+
- `CRoot`: The type of arguments of the `c` helper.
|
|
39
41
|
- `EscapeMap`: The type of arguments of the `escapeValues` and `escape` helpers.
|
|
40
42
|
- `HArgs`: The type of arguments of the `h` and `s` helpers.
|
|
41
43
|
- `HArgs1`: The type of arguments of the `h` and `s` helpers.
|
|
42
|
-
- `
|
|
43
|
-
- `JcRoot`: The type of arguments of the `jc` helper.
|
|
44
|
+
- `c`: A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
44
45
|
- `csvParse`: A tiny helper for CSV parsing.
|
|
45
46
|
- `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
46
47
|
- `escapeValues`: A generic helper for escaping `values` by given `escapeMap`.
|
|
47
48
|
- `fixTypography`: A helper that implements typographic corrections specific to Polish typography.
|
|
48
|
-
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
49
|
+
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
49
50
|
- `has`: A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
50
51
|
- `is`: A helper that checks if the given argument is of a certain type.
|
|
51
|
-
- `jc`: A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
52
52
|
- `jsOnParse`: `JSON.parse` with “JavaScript turned on”.
|
|
53
53
|
- `locale`: Language translations helper.
|
|
54
54
|
- `nanolight`: A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
@@ -56,12 +56,30 @@ import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.7.13/nnn.js'
|
|
|
56
56
|
- `omit`: A helper that implements TypeScript’s `Omit` utility type.
|
|
57
57
|
- `pick`: A helper that implements TypeScript’s `Pick` utility type.
|
|
58
58
|
- `plUral`: A helper for choosing the correct singular and plural.
|
|
59
|
-
- `pro`: A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
59
|
+
- `pro`: A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
60
60
|
- `refsInfo`: A helper that provides information about the given `refs`.
|
|
61
|
-
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
61
|
+
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
62
62
|
- `svgUse`: A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
63
63
|
- `uuid1`: A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
64
64
|
|
|
65
|
+
### CNode
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
type CNode = {
|
|
69
|
+
[attributeOrSelector: string]: string | number | CNode | undefined;
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The type of arguments of the `c` helper.
|
|
74
|
+
|
|
75
|
+
### CRoot
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
type CRoot = Partial<Record<PropertyKey, CNode>>;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The type of arguments of the `c` helper.
|
|
82
|
+
|
|
65
83
|
### EscapeMap
|
|
66
84
|
|
|
67
85
|
```ts
|
|
@@ -86,23 +104,221 @@ type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined | Node |
|
|
|
86
104
|
|
|
87
105
|
The type of arguments of the `h` and `s` helpers.
|
|
88
106
|
|
|
89
|
-
###
|
|
107
|
+
### c
|
|
90
108
|
|
|
91
109
|
```ts
|
|
92
|
-
|
|
93
|
-
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
94
|
-
};
|
|
110
|
+
const c: (root: CRoot, splitter?: string) => string;
|
|
95
111
|
```
|
|
96
112
|
|
|
97
|
-
|
|
113
|
+
A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
114
|
+
|
|
115
|
+
The `root` parameter provides a hierarchical description of CSS rules.
|
|
98
116
|
|
|
99
|
-
|
|
117
|
+
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of
|
|
118
|
+
those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
119
|
+
- All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` →
|
|
120
|
+
`src`, `@font-face$$1` → `@font-face`).
|
|
121
|
+
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-`
|
|
122
|
+
character preceding them (e.g. `fontFamily` → `font-family`).
|
|
123
|
+
- Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g.
|
|
124
|
+
`{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.
|
|
100
126
|
|
|
101
|
-
|
|
102
|
-
|
|
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).to.deep.equal(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).to.deep.equal(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).to.deep.equal(expected)
|
|
103
256
|
```
|
|
104
257
|
|
|
105
|
-
|
|
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).to.deep.equal(expected)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
const actual = c({
|
|
283
|
+
'.b,.c': {
|
|
284
|
+
margin: 1,
|
|
285
|
+
'.d': {
|
|
286
|
+
margin: 2
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
const expected = `
|
|
292
|
+
.b,.c{
|
|
293
|
+
margin:1
|
|
294
|
+
}
|
|
295
|
+
.b.d,.c.d{
|
|
296
|
+
margin:2
|
|
297
|
+
}`.replace(/\n\s*/g, '')
|
|
298
|
+
|
|
299
|
+
expect(actual).to.deep.equal(expected)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
```js
|
|
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).to.deep.equal(expected)
|
|
321
|
+
```
|
|
106
322
|
|
|
107
323
|
### csvParse
|
|
108
324
|
|
|
@@ -220,19 +436,21 @@ const h: {
|
|
|
220
436
|
};
|
|
221
437
|
```
|
|
222
438
|
|
|
223
|
-
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
439
|
+
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
440
|
+
`HTMLElement`s (see also `s`).
|
|
224
441
|
|
|
225
442
|
- The first argument of type `string` specifies the tag of the element to be created.
|
|
226
443
|
- The first argument of type `Node` specifies the element to be modified.
|
|
227
444
|
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
228
|
-
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
229
|
-
(Note that `$` is not a valid attribute name character.)
|
|
230
|
-
|
|
231
|
-
An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
445
|
+
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
446
|
+
modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
447
|
+
`setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
232
448
|
- All other arguments of type `null` or `undefined` are simply ignored.
|
|
233
449
|
- All other arguments of type `Node` are appended to the element being created or modified.
|
|
234
|
-
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
235
|
-
|
|
450
|
+
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
451
|
+
created or modified.
|
|
452
|
+
- All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or
|
|
453
|
+
modified.
|
|
236
454
|
|
|
237
455
|
#### Usage Examples
|
|
238
456
|
|
|
@@ -419,218 +637,6 @@ try {
|
|
|
419
637
|
expect(is(Number, num)).to.be.true
|
|
420
638
|
```
|
|
421
639
|
|
|
422
|
-
### jc
|
|
423
|
-
|
|
424
|
-
```ts
|
|
425
|
-
const jc: (root: JcRoot, splitter?: string) => string;
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
429
|
-
|
|
430
|
-
The `root` parameter provides a hierarchical description of CSS rules.
|
|
431
|
-
|
|
432
|
-
- 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.
|
|
433
|
-
- 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`).
|
|
434
|
-
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
435
|
-
- 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}`).
|
|
436
|
-
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
437
|
-
|
|
438
|
-
#### Usage Examples
|
|
439
|
-
|
|
440
|
-
```js
|
|
441
|
-
const actual = jc({
|
|
442
|
-
a: {
|
|
443
|
-
color: 'red',
|
|
444
|
-
margin: 1,
|
|
445
|
-
'.c': { margin: 2, padding: 2 },
|
|
446
|
-
padding: 1
|
|
447
|
-
}
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
const expected = `
|
|
451
|
-
a{
|
|
452
|
-
color:red;
|
|
453
|
-
margin:1
|
|
454
|
-
}
|
|
455
|
-
a.c{
|
|
456
|
-
margin:2;
|
|
457
|
-
padding:2
|
|
458
|
-
}
|
|
459
|
-
a{
|
|
460
|
-
padding:1
|
|
461
|
-
}`.replace(/\n\s*/g, '')
|
|
462
|
-
|
|
463
|
-
expect(actual).to.deep.equal(expected)
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
```js
|
|
467
|
-
const actual = jc({
|
|
468
|
-
a: {
|
|
469
|
-
'.b': {
|
|
470
|
-
color: 'red',
|
|
471
|
-
margin: 1,
|
|
472
|
-
'.c': { margin: 2, padding: 2 },
|
|
473
|
-
padding: 1
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
})
|
|
477
|
-
|
|
478
|
-
const expected = `
|
|
479
|
-
a.b{
|
|
480
|
-
color:red;
|
|
481
|
-
margin:1
|
|
482
|
-
}
|
|
483
|
-
a.b.c{
|
|
484
|
-
margin:2;
|
|
485
|
-
padding:2
|
|
486
|
-
}
|
|
487
|
-
a.b{
|
|
488
|
-
padding:1
|
|
489
|
-
}`.replace(/\n\s*/g, '')
|
|
490
|
-
|
|
491
|
-
expect(actual).to.deep.equal(expected)
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
```js
|
|
495
|
-
const actual = jc({
|
|
496
|
-
'@font-face$$1': {
|
|
497
|
-
fontFamily: 'Jackens',
|
|
498
|
-
src$$1: 'url(otf/jackens.otf)',
|
|
499
|
-
src$$2: "url(otf/jackens.otf) format('opentype')," +
|
|
500
|
-
"url(svg/jackens.svg) format('svg')",
|
|
501
|
-
fontWeight: 'normal',
|
|
502
|
-
fontStyle: 'normal'
|
|
503
|
-
},
|
|
504
|
-
'@font-face$$2': {
|
|
505
|
-
fontFamily: 'C64',
|
|
506
|
-
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
|
|
507
|
-
},
|
|
508
|
-
'@keyframes spin': {
|
|
509
|
-
'0%': { transform: 'rotate(0deg)' },
|
|
510
|
-
'100%': { transform: 'rotate(360deg)' }
|
|
511
|
-
},
|
|
512
|
-
div: {
|
|
513
|
-
border: 'solid red 1px',
|
|
514
|
-
'.c1': { 'background-color': '#000' },
|
|
515
|
-
' .c1': { backgroundColor: 'black' },
|
|
516
|
-
'.c2': { backgroundColor: 'rgb(0,0,0)' }
|
|
517
|
-
},
|
|
518
|
-
'@media(min-width:200px)': {
|
|
519
|
-
div: { margin: 0, padding: 0 },
|
|
520
|
-
span: { color: '#000' }
|
|
521
|
-
}
|
|
522
|
-
})
|
|
523
|
-
|
|
524
|
-
const expected = `
|
|
525
|
-
@font-face{
|
|
526
|
-
font-family:Jackens;
|
|
527
|
-
src:url(otf/jackens.otf);
|
|
528
|
-
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
529
|
-
font-weight:normal;
|
|
530
|
-
font-style:normal
|
|
531
|
-
}
|
|
532
|
-
@font-face{
|
|
533
|
-
font-family:C64;
|
|
534
|
-
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
535
|
-
}
|
|
536
|
-
@keyframes spin{
|
|
537
|
-
0%{
|
|
538
|
-
transform:rotate(0deg)
|
|
539
|
-
}
|
|
540
|
-
100%{
|
|
541
|
-
transform:rotate(360deg)
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
div{
|
|
545
|
-
border:solid red 1px
|
|
546
|
-
}
|
|
547
|
-
div.c1{
|
|
548
|
-
background-color:#000
|
|
549
|
-
}
|
|
550
|
-
div .c1{
|
|
551
|
-
background-color:black
|
|
552
|
-
}
|
|
553
|
-
div.c2{
|
|
554
|
-
background-color:rgb(0,0,0)
|
|
555
|
-
}
|
|
556
|
-
@media(min-width:200px){
|
|
557
|
-
div{
|
|
558
|
-
margin:0;
|
|
559
|
-
padding:0
|
|
560
|
-
}
|
|
561
|
-
span{
|
|
562
|
-
color:#000
|
|
563
|
-
}
|
|
564
|
-
}`.replace(/\n\s*/g, '')
|
|
565
|
-
|
|
566
|
-
expect(actual).to.deep.equal(expected)
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
```js
|
|
570
|
-
const actual = jc({
|
|
571
|
-
a: {
|
|
572
|
-
'.b,.c': {
|
|
573
|
-
margin: 1,
|
|
574
|
-
'.d': {
|
|
575
|
-
margin: 2
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
})
|
|
580
|
-
|
|
581
|
-
const expected = `
|
|
582
|
-
a.b,a.c{
|
|
583
|
-
margin:1
|
|
584
|
-
}
|
|
585
|
-
a.b.d,a.c.d{
|
|
586
|
-
margin:2
|
|
587
|
-
}`.replace(/\n\s*/g, '')
|
|
588
|
-
|
|
589
|
-
expect(actual).to.deep.equal(expected)
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
```js
|
|
593
|
-
const actual = jc({
|
|
594
|
-
'.b,.c': {
|
|
595
|
-
margin: 1,
|
|
596
|
-
'.d': {
|
|
597
|
-
margin: 2
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
const expected = `
|
|
603
|
-
.b,.c{
|
|
604
|
-
margin:1
|
|
605
|
-
}
|
|
606
|
-
.b.d,.c.d{
|
|
607
|
-
margin:2
|
|
608
|
-
}`.replace(/\n\s*/g, '')
|
|
609
|
-
|
|
610
|
-
expect(actual).to.deep.equal(expected)
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
```js
|
|
614
|
-
const actual = jc({
|
|
615
|
-
'.a,.b': {
|
|
616
|
-
margin: 1,
|
|
617
|
-
'.c,.d': {
|
|
618
|
-
margin: 2
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
})
|
|
622
|
-
|
|
623
|
-
const expected = `
|
|
624
|
-
.a,.b{
|
|
625
|
-
margin:1
|
|
626
|
-
}
|
|
627
|
-
.a.c,.a.d,.b.c,.b.d{
|
|
628
|
-
margin:2
|
|
629
|
-
}`.replace(/\n\s*/g, '')
|
|
630
|
-
|
|
631
|
-
expect(actual).to.deep.equal(expected)
|
|
632
|
-
```
|
|
633
|
-
|
|
634
640
|
### jsOnParse
|
|
635
641
|
|
|
636
642
|
```ts
|
|
@@ -824,7 +830,8 @@ expect(car(42)).to.deep.equal('cars')
|
|
|
824
830
|
const pro: (ref: unknown) => any;
|
|
825
831
|
```
|
|
826
832
|
|
|
827
|
-
A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
833
|
+
A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
834
|
+
object.
|
|
828
835
|
|
|
829
836
|
#### Usage Examples
|
|
830
837
|
|
|
@@ -909,19 +916,21 @@ const s: {
|
|
|
909
916
|
};
|
|
910
917
|
```
|
|
911
918
|
|
|
912
|
-
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
919
|
+
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
920
|
+
`SVGElement`s (see also `h`).
|
|
913
921
|
|
|
914
922
|
- The first argument of type `string` specifies the tag of the element to be created.
|
|
915
923
|
- The first argument of type `Node` specifies the element to be modified.
|
|
916
924
|
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
917
|
-
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
918
|
-
(Note that `$` is not a valid attribute name character.)
|
|
919
|
-
|
|
920
|
-
An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
925
|
+
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
926
|
+
modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
927
|
+
`setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
921
928
|
- All other arguments of type `null` or `undefined` are simply ignored.
|
|
922
929
|
- All other arguments of type `Node` are appended to the element being created or modified.
|
|
923
|
-
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
924
|
-
|
|
930
|
+
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
931
|
+
created or modified.
|
|
932
|
+
- All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or
|
|
933
|
+
modified.
|
|
925
934
|
|
|
926
935
|
### svgUse
|
|
927
936
|
|