@jackens/nnn 2024.3.2 → 2024.3.3
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 +25 -25
- package/nnn.js +57 -57
- package/package.json +3 -2
- package/readme.md +239 -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
|
*
|
|
@@ -151,6 +126,31 @@ export declare const is: {
|
|
|
151
126
|
<T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
|
|
152
127
|
};
|
|
153
128
|
|
|
129
|
+
/**
|
|
130
|
+
* The type of arguments of the `jc` helper.
|
|
131
|
+
*/
|
|
132
|
+
export type JcNode = {
|
|
133
|
+
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The type of arguments of the `jc` helper.
|
|
138
|
+
*/
|
|
139
|
+
export type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A simple CSS-in-JS helper.
|
|
143
|
+
*
|
|
144
|
+
* The `root` parameter provides a hierarchical description of CSS rules.
|
|
145
|
+
*
|
|
146
|
+
* - 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.
|
|
147
|
+
* - 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`).
|
|
148
|
+
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
149
|
+
* - 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}`).
|
|
150
|
+
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
151
|
+
*/
|
|
152
|
+
export declare const jc: (root: JcRoot, splitter?: string) => string;
|
|
153
|
+
|
|
154
154
|
/**
|
|
155
155
|
* `JSON.parse` with “JavaScript turned on”.
|
|
156
156
|
*
|
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"
|
|
@@ -141,9 +88,9 @@ var chartable = ({
|
|
|
141
88
|
const zxValues = [];
|
|
142
89
|
const xLabels = [];
|
|
143
90
|
const zLabels = [];
|
|
144
|
-
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col,
|
|
91
|
+
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c) => {
|
|
145
92
|
const x = r - 1;
|
|
146
|
-
const z =
|
|
93
|
+
const z = c - +headerColumn;
|
|
147
94
|
const value = col.innerText;
|
|
148
95
|
if (x >= 0 && z >= 0) {
|
|
149
96
|
zxValues[z] = zxValues[z] ?? [];
|
|
@@ -303,6 +250,59 @@ var fixTypography = (node) => {
|
|
|
303
250
|
// src/nnn/has.ts
|
|
304
251
|
var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
|
|
305
252
|
|
|
253
|
+
// src/nnn/jc.ts
|
|
254
|
+
var _jc = (node, prefix, result, split) => {
|
|
255
|
+
const queue = [[node, prefix]];
|
|
256
|
+
while (queue.length > 0) {
|
|
257
|
+
const [style0, prefix0] = queue.shift() ?? [];
|
|
258
|
+
if (style0 == null || prefix0 == null) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (is(Array, style0)) {
|
|
262
|
+
result.push(prefix0, prefix0 !== "" ? "{" : "", style0.join(";"), prefix0 !== "" ? "}" : "");
|
|
263
|
+
} else {
|
|
264
|
+
const todo = [];
|
|
265
|
+
let attributes = [];
|
|
266
|
+
let attributesPushed = false;
|
|
267
|
+
for (const key in style0) {
|
|
268
|
+
const value = style0[key];
|
|
269
|
+
if (is(String, value) || is(Number, value)) {
|
|
270
|
+
if (!attributesPushed) {
|
|
271
|
+
attributesPushed = true;
|
|
272
|
+
attributes = [];
|
|
273
|
+
todo.push([attributes, prefix0]);
|
|
274
|
+
}
|
|
275
|
+
attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
|
|
276
|
+
} else if (value != null) {
|
|
277
|
+
attributesPushed = false;
|
|
278
|
+
const prefixN = [];
|
|
279
|
+
const keyChunks = key.split(",");
|
|
280
|
+
prefix0.split(",").forEach((prefixChunk) => keyChunks.forEach((keyChunk) => prefixN.push(prefixChunk + keyChunk)));
|
|
281
|
+
todo.push([value, prefixN.join(",")]);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
queue.unshift(...todo);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
var jc = (root, splitter = "$$") => {
|
|
289
|
+
const split = (text) => text.split(splitter)[0];
|
|
290
|
+
const chunks = [];
|
|
291
|
+
for (const key in root) {
|
|
292
|
+
const value = root[key];
|
|
293
|
+
if (value != null) {
|
|
294
|
+
if (key[0] === "@") {
|
|
295
|
+
chunks.push(split(key) + "{");
|
|
296
|
+
_jc(value, "", chunks, split);
|
|
297
|
+
chunks.push("}");
|
|
298
|
+
} else {
|
|
299
|
+
_jc(value, split(key), chunks, split);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return chunks.join("");
|
|
304
|
+
};
|
|
305
|
+
|
|
306
306
|
// src/nnn/jsOnParse.ts
|
|
307
307
|
var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
308
308
|
if (is(Object, value)) {
|
|
@@ -408,6 +408,7 @@ export {
|
|
|
408
408
|
nanolight,
|
|
409
409
|
locale,
|
|
410
410
|
jsOnParse,
|
|
411
|
+
jc,
|
|
411
412
|
is,
|
|
412
413
|
has,
|
|
413
414
|
h,
|
|
@@ -415,6 +416,5 @@ export {
|
|
|
415
416
|
escapeValues,
|
|
416
417
|
escape,
|
|
417
418
|
eq,
|
|
418
|
-
chartable
|
|
419
|
-
c
|
|
419
|
+
chartable
|
|
420
420
|
};
|
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.3"
|
|
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.3</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 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`).
|
|
@@ -66,24 +66,6 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
66
66
|
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
67
67
|
- `uuid1`: A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
68
68
|
|
|
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
69
|
### EscapeMap
|
|
88
70
|
|
|
89
71
|
```ts
|
|
@@ -108,217 +90,23 @@ type HArgs1 = Partial<Record<PropertyKey, any>> | null | undefined | Node | stri
|
|
|
108
90
|
|
|
109
91
|
The type of arguments of the `h` and `s` helpers.
|
|
110
92
|
|
|
111
|
-
###
|
|
93
|
+
### JcNode
|
|
112
94
|
|
|
113
95
|
```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)
|
|
96
|
+
type JcNode = {
|
|
97
|
+
[attributeOrSelector: string]: string | number | JcNode | undefined;
|
|
98
|
+
};
|
|
279
99
|
```
|
|
280
100
|
|
|
281
|
-
|
|
282
|
-
const actual = c({
|
|
283
|
-
'.b,.c': {
|
|
284
|
-
margin: 1,
|
|
285
|
-
'.d': {
|
|
286
|
-
margin: 2
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
})
|
|
101
|
+
The type of arguments of the `jc` helper.
|
|
290
102
|
|
|
291
|
-
|
|
292
|
-
.b,.c{
|
|
293
|
-
margin:1
|
|
294
|
-
}
|
|
295
|
-
.b.d,.c.d{
|
|
296
|
-
margin:2
|
|
297
|
-
}`.replace(/\n\s*/g, '')
|
|
103
|
+
### JcRoot
|
|
298
104
|
|
|
299
|
-
|
|
105
|
+
```ts
|
|
106
|
+
type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
300
107
|
```
|
|
301
108
|
|
|
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
|
-
```
|
|
109
|
+
The type of arguments of the `jc` helper.
|
|
322
110
|
|
|
323
111
|
### chartable
|
|
324
112
|
|
|
@@ -665,6 +453,218 @@ try {
|
|
|
665
453
|
expect(is(Number, num)).toBeTrue()
|
|
666
454
|
```
|
|
667
455
|
|
|
456
|
+
### jc
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
const jc: (root: JcRoot, splitter?: string) => string;
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
A simple CSS-in-JS helper.
|
|
463
|
+
|
|
464
|
+
The `root` parameter provides a hierarchical description of CSS rules.
|
|
465
|
+
|
|
466
|
+
- 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.
|
|
467
|
+
- 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`).
|
|
468
|
+
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
469
|
+
- 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}`).
|
|
470
|
+
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
471
|
+
|
|
472
|
+
#### Usage Examples
|
|
473
|
+
|
|
474
|
+
```js
|
|
475
|
+
const actual = jc({
|
|
476
|
+
a: {
|
|
477
|
+
color: 'red',
|
|
478
|
+
margin: 1,
|
|
479
|
+
'.c': { margin: 2, padding: 2 },
|
|
480
|
+
padding: 1
|
|
481
|
+
}
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
const expected = `
|
|
485
|
+
a{
|
|
486
|
+
color:red;
|
|
487
|
+
margin:1
|
|
488
|
+
}
|
|
489
|
+
a.c{
|
|
490
|
+
margin:2;
|
|
491
|
+
padding:2
|
|
492
|
+
}
|
|
493
|
+
a{
|
|
494
|
+
padding:1
|
|
495
|
+
}`.replace(/\n\s*/g, '')
|
|
496
|
+
|
|
497
|
+
expect(actual).toStrictEqual(expected)
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
```js
|
|
501
|
+
const actual = jc({
|
|
502
|
+
a: {
|
|
503
|
+
'.b': {
|
|
504
|
+
color: 'red',
|
|
505
|
+
margin: 1,
|
|
506
|
+
'.c': { margin: 2, padding: 2 },
|
|
507
|
+
padding: 1
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
const expected = `
|
|
513
|
+
a.b{
|
|
514
|
+
color:red;
|
|
515
|
+
margin:1
|
|
516
|
+
}
|
|
517
|
+
a.b.c{
|
|
518
|
+
margin:2;
|
|
519
|
+
padding:2
|
|
520
|
+
}
|
|
521
|
+
a.b{
|
|
522
|
+
padding:1
|
|
523
|
+
}`.replace(/\n\s*/g, '')
|
|
524
|
+
|
|
525
|
+
expect(actual).toStrictEqual(expected)
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
```js
|
|
529
|
+
const actual = jc({
|
|
530
|
+
'@font-face$$1': {
|
|
531
|
+
fontFamily: 'Jackens',
|
|
532
|
+
src$$1: 'url(otf/jackens.otf)',
|
|
533
|
+
src$$2: "url(otf/jackens.otf) format('opentype')," +
|
|
534
|
+
"url(svg/jackens.svg) format('svg')",
|
|
535
|
+
fontWeight: 'normal',
|
|
536
|
+
fontStyle: 'normal'
|
|
537
|
+
},
|
|
538
|
+
'@font-face$$2': {
|
|
539
|
+
fontFamily: 'C64',
|
|
540
|
+
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
|
|
541
|
+
},
|
|
542
|
+
'@keyframes spin': {
|
|
543
|
+
'0%': { transform: 'rotate(0deg)' },
|
|
544
|
+
'100%': { transform: 'rotate(360deg)' }
|
|
545
|
+
},
|
|
546
|
+
div: {
|
|
547
|
+
border: 'solid red 1px',
|
|
548
|
+
'.c1': { 'background-color': '#000' },
|
|
549
|
+
' .c1': { backgroundColor: 'black' },
|
|
550
|
+
'.c2': { backgroundColor: 'rgb(0,0,0)' }
|
|
551
|
+
},
|
|
552
|
+
'@media(min-width:200px)': {
|
|
553
|
+
div: { margin: 0, padding: 0 },
|
|
554
|
+
span: { color: '#000' }
|
|
555
|
+
}
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
const expected = `
|
|
559
|
+
@font-face{
|
|
560
|
+
font-family:Jackens;
|
|
561
|
+
src:url(otf/jackens.otf);
|
|
562
|
+
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
563
|
+
font-weight:normal;
|
|
564
|
+
font-style:normal
|
|
565
|
+
}
|
|
566
|
+
@font-face{
|
|
567
|
+
font-family:C64;
|
|
568
|
+
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
569
|
+
}
|
|
570
|
+
@keyframes spin{
|
|
571
|
+
0%{
|
|
572
|
+
transform:rotate(0deg)
|
|
573
|
+
}
|
|
574
|
+
100%{
|
|
575
|
+
transform:rotate(360deg)
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
div{
|
|
579
|
+
border:solid red 1px
|
|
580
|
+
}
|
|
581
|
+
div.c1{
|
|
582
|
+
background-color:#000
|
|
583
|
+
}
|
|
584
|
+
div .c1{
|
|
585
|
+
background-color:black
|
|
586
|
+
}
|
|
587
|
+
div.c2{
|
|
588
|
+
background-color:rgb(0,0,0)
|
|
589
|
+
}
|
|
590
|
+
@media(min-width:200px){
|
|
591
|
+
div{
|
|
592
|
+
margin:0;
|
|
593
|
+
padding:0
|
|
594
|
+
}
|
|
595
|
+
span{
|
|
596
|
+
color:#000
|
|
597
|
+
}
|
|
598
|
+
}`.replace(/\n\s*/g, '')
|
|
599
|
+
|
|
600
|
+
expect(actual).toStrictEqual(expected)
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
```js
|
|
604
|
+
const actual = jc({
|
|
605
|
+
a: {
|
|
606
|
+
'.b,.c': {
|
|
607
|
+
margin: 1,
|
|
608
|
+
'.d': {
|
|
609
|
+
margin: 2
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
const expected = `
|
|
616
|
+
a.b,a.c{
|
|
617
|
+
margin:1
|
|
618
|
+
}
|
|
619
|
+
a.b.d,a.c.d{
|
|
620
|
+
margin:2
|
|
621
|
+
}`.replace(/\n\s*/g, '')
|
|
622
|
+
|
|
623
|
+
expect(actual).toStrictEqual(expected)
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
```js
|
|
627
|
+
const actual = jc({
|
|
628
|
+
'.b,.c': {
|
|
629
|
+
margin: 1,
|
|
630
|
+
'.d': {
|
|
631
|
+
margin: 2
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
})
|
|
635
|
+
|
|
636
|
+
const expected = `
|
|
637
|
+
.b,.c{
|
|
638
|
+
margin:1
|
|
639
|
+
}
|
|
640
|
+
.b.d,.c.d{
|
|
641
|
+
margin:2
|
|
642
|
+
}`.replace(/\n\s*/g, '')
|
|
643
|
+
|
|
644
|
+
expect(actual).toStrictEqual(expected)
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
```js
|
|
648
|
+
const actual = jc({
|
|
649
|
+
'.a,.b': {
|
|
650
|
+
margin: 1,
|
|
651
|
+
'.c,.d': {
|
|
652
|
+
margin: 2
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
})
|
|
656
|
+
|
|
657
|
+
const expected = `
|
|
658
|
+
.a,.b{
|
|
659
|
+
margin:1
|
|
660
|
+
}
|
|
661
|
+
.a.c,.a.d,.b.c,.b.d{
|
|
662
|
+
margin:2
|
|
663
|
+
}`.replace(/\n\s*/g, '')
|
|
664
|
+
|
|
665
|
+
expect(actual).toStrictEqual(expected)
|
|
666
|
+
```
|
|
667
|
+
|
|
668
668
|
### jsOnParse
|
|
669
669
|
|
|
670
670
|
```ts
|
|
@@ -783,8 +783,15 @@ A helper for highlighting JavaScript.
|
|
|
783
783
|
```js
|
|
784
784
|
const codeJs = 'const answerToLifeTheUniverseAndEverything = 42'
|
|
785
785
|
|
|
786
|
-
expect(
|
|
787
|
-
'
|
|
786
|
+
expect(nanolightJs(codeJs)).toStrictEqual([
|
|
787
|
+
['span', { class: 'keyword' }, 'const'],
|
|
788
|
+
' ',
|
|
789
|
+
['span', { class: 'literal' }, 'answerToLifeTheUniverseAndEverything'],
|
|
790
|
+
' ',
|
|
791
|
+
['span', { class: 'operator' }, '='],
|
|
792
|
+
' ',
|
|
793
|
+
['span', { class: 'number' }, '42']
|
|
794
|
+
])
|
|
788
795
|
```
|
|
789
796
|
|
|
790
797
|
### omit
|