@jackens/nnn 2024.2.27 → 2024.3.2
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 +61 -61
- package/package.json +1 -1
- package/readme.md +240 -219
package/nnn.d.ts
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
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
|
+
|
|
1
26
|
/**
|
|
2
27
|
* A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
3
28
|
*
|
|
@@ -126,31 +151,6 @@ export declare const is: {
|
|
|
126
151
|
<T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
|
|
127
152
|
};
|
|
128
153
|
|
|
129
|
-
/**
|
|
130
|
-
* The type of arguments of the `jcss` helper.
|
|
131
|
-
*/
|
|
132
|
-
export type JcssNode = {
|
|
133
|
-
[attributeOrSelector: string]: string | number | JcssNode | undefined;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* The type of arguments of the `jcss` helper.
|
|
138
|
-
*/
|
|
139
|
-
export type JcssRoot = Partial<Record<PropertyKey, JcssNode>>;
|
|
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 jcss: (root: JcssRoot, splitter?: string) => string;
|
|
153
|
-
|
|
154
154
|
/**
|
|
155
155
|
* `JSON.parse` with “JavaScript turned on”.
|
|
156
156
|
*
|
package/nnn.js
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
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
|
+
|
|
4
57
|
// src/nnn/h.ts
|
|
5
58
|
var NS = {
|
|
6
59
|
xlink: "http://www.w3.org/1999/xlink"
|
|
@@ -88,9 +141,9 @@ var chartable = ({
|
|
|
88
141
|
const zxValues = [];
|
|
89
142
|
const xLabels = [];
|
|
90
143
|
const zLabels = [];
|
|
91
|
-
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col,
|
|
144
|
+
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c2) => {
|
|
92
145
|
const x = r - 1;
|
|
93
|
-
const z =
|
|
146
|
+
const z = c2 - +headerColumn;
|
|
94
147
|
const value = col.innerText;
|
|
95
148
|
if (x >= 0 && z >= 0) {
|
|
96
149
|
zxValues[z] = zxValues[z] ?? [];
|
|
@@ -215,11 +268,8 @@ var eq = (x, y) => {
|
|
|
215
268
|
var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
|
|
216
269
|
var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
|
|
217
270
|
|
|
218
|
-
// src/nnn/has.ts
|
|
219
|
-
var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
|
|
220
|
-
|
|
221
271
|
// src/nnn/fixTypography.ts
|
|
222
|
-
var TAGS_TO_SKIP =
|
|
272
|
+
var TAGS_TO_SKIP = ["IFRAME", "NOSCRIPT", "PRE", "SCRIPT", "STYLE", "TEXTAREA"];
|
|
223
273
|
var fixTypography = (node) => {
|
|
224
274
|
const queue = [node];
|
|
225
275
|
while (queue.length > 0) {
|
|
@@ -228,7 +278,7 @@ var fixTypography = (node) => {
|
|
|
228
278
|
node0.childNodes.forEach((childNode) => {
|
|
229
279
|
if (childNode instanceof Text) {
|
|
230
280
|
queue.push(childNode);
|
|
231
|
-
} else if (childNode instanceof Element && !
|
|
281
|
+
} else if (childNode instanceof Element && !TAGS_TO_SKIP.includes(childNode.tagName)) {
|
|
232
282
|
queue.push(childNode);
|
|
233
283
|
}
|
|
234
284
|
});
|
|
@@ -250,58 +300,8 @@ var fixTypography = (node) => {
|
|
|
250
300
|
}
|
|
251
301
|
};
|
|
252
302
|
|
|
253
|
-
// src/nnn/
|
|
254
|
-
var
|
|
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 jcss = (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
|
-
_jcss(value, "", chunks, split);
|
|
297
|
-
chunks.push("}");
|
|
298
|
-
} else {
|
|
299
|
-
_jcss(value, split(key), chunks, split);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
return chunks.join("");
|
|
304
|
-
};
|
|
303
|
+
// src/nnn/has.ts
|
|
304
|
+
var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
|
|
305
305
|
|
|
306
306
|
// src/nnn/jsOnParse.ts
|
|
307
307
|
var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
@@ -408,7 +408,6 @@ export {
|
|
|
408
408
|
nanolight,
|
|
409
409
|
locale,
|
|
410
410
|
jsOnParse,
|
|
411
|
-
jcss,
|
|
412
411
|
is,
|
|
413
412
|
has,
|
|
414
413
|
h,
|
|
@@ -416,5 +415,6 @@ export {
|
|
|
416
415
|
escapeValues,
|
|
417
416
|
escape,
|
|
418
417
|
eq,
|
|
419
|
-
chartable
|
|
418
|
+
chartable,
|
|
419
|
+
c
|
|
420
420
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.2
|
|
5
|
+
<sub>Version: <code class="version">2024.3.2</code></sub>
|
|
6
|
+
|
|
7
|
+
## Examples
|
|
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/)
|
|
6
14
|
|
|
7
15
|
## Installation
|
|
8
16
|
|
|
@@ -32,11 +40,12 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
32
40
|
|
|
33
41
|
## Exports
|
|
34
42
|
|
|
43
|
+
- `CNode`: The type of arguments of the `c` helper.
|
|
44
|
+
- `CRoot`: The type of arguments of the `c` helper.
|
|
35
45
|
- `EscapeMap`: The type of arguments of the `escapeValues` and `escape` helpers.
|
|
36
46
|
- `HArgs`: The type of arguments of the `h` and `s` helpers.
|
|
37
47
|
- `HArgs1`: The type of arguments of the `h` and `s` helpers.
|
|
38
|
-
- `
|
|
39
|
-
- `JcssRoot`: The type of arguments of the `jcss` helper.
|
|
48
|
+
- `c`: A simple CSS-in-JS helper.
|
|
40
49
|
- `chartable`: A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
41
50
|
- `eq`: A helper that checks equality of the given arguments.
|
|
42
51
|
- `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
@@ -45,7 +54,6 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
45
54
|
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
46
55
|
- `has`: A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
47
56
|
- `is`: A helper that checks if the given argument is of a certain type.
|
|
48
|
-
- `jcss`: A simple CSS-in-JS helper.
|
|
49
57
|
- `jsOnParse`: `JSON.parse` with “JavaScript turned on”.
|
|
50
58
|
- `locale`: Language translations helper.
|
|
51
59
|
- `nanolight`: A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
@@ -58,6 +66,24 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
58
66
|
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
59
67
|
- `uuid1`: A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
60
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
|
+
|
|
61
87
|
### EscapeMap
|
|
62
88
|
|
|
63
89
|
```ts
|
|
@@ -82,23 +108,217 @@ type HArgs1 = Partial<Record<PropertyKey, any>> | null | undefined | Node | stri
|
|
|
82
108
|
|
|
83
109
|
The type of arguments of the `h` and `s` helpers.
|
|
84
110
|
|
|
85
|
-
###
|
|
111
|
+
### c
|
|
86
112
|
|
|
87
113
|
```ts
|
|
88
|
-
|
|
89
|
-
[attributeOrSelector: string]: string | number | JcssNode | undefined;
|
|
90
|
-
};
|
|
114
|
+
const c: (root: CRoot, splitter?: string) => string;
|
|
91
115
|
```
|
|
92
116
|
|
|
93
|
-
|
|
117
|
+
A simple CSS-in-JS helper.
|
|
94
118
|
|
|
95
|
-
|
|
119
|
+
The `root` parameter provides a hierarchical description of CSS rules.
|
|
96
120
|
|
|
97
|
-
|
|
98
|
-
|
|
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)
|
|
99
153
|
```
|
|
100
154
|
|
|
101
|
-
|
|
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)
|
|
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).toStrictEqual(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).toStrictEqual(expected)
|
|
321
|
+
```
|
|
102
322
|
|
|
103
323
|
### chartable
|
|
104
324
|
|
|
@@ -432,216 +652,17 @@ expect(is(Object, fakeFooBar)).toBeTrue()
|
|
|
432
652
|
expect(iz(Object, fakeFooBar)).toBeFalse()
|
|
433
653
|
```
|
|
434
654
|
|
|
435
|
-
### jcss
|
|
436
|
-
|
|
437
|
-
```ts
|
|
438
|
-
const jcss: (root: JcssRoot, splitter?: string) => string;
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
A simple CSS-in-JS helper.
|
|
442
|
-
|
|
443
|
-
The `root` parameter provides a hierarchical description of CSS rules.
|
|
444
|
-
|
|
445
|
-
- 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.
|
|
446
|
-
- 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`).
|
|
447
|
-
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
448
|
-
- 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}`).
|
|
449
|
-
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
450
|
-
|
|
451
|
-
#### Usage Examples
|
|
452
|
-
|
|
453
|
-
```js
|
|
454
|
-
const actual = jcss({
|
|
455
|
-
a: {
|
|
456
|
-
color: 'red',
|
|
457
|
-
margin: 1,
|
|
458
|
-
'.c': { margin: 2, padding: 2 },
|
|
459
|
-
padding: 1
|
|
460
|
-
}
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
const expected = `
|
|
464
|
-
a{
|
|
465
|
-
color:red;
|
|
466
|
-
margin:1
|
|
467
|
-
}
|
|
468
|
-
a.c{
|
|
469
|
-
margin:2;
|
|
470
|
-
padding:2
|
|
471
|
-
}
|
|
472
|
-
a{
|
|
473
|
-
padding:1
|
|
474
|
-
}`.replace(/\n\s*/g, '')
|
|
475
|
-
|
|
476
|
-
expect(actual).toStrictEqual(expected)
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
```js
|
|
480
|
-
const actual = jcss({
|
|
481
|
-
a: {
|
|
482
|
-
'.b': {
|
|
483
|
-
color: 'red',
|
|
484
|
-
margin: 1,
|
|
485
|
-
'.c': { margin: 2, padding: 2 },
|
|
486
|
-
padding: 1
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
})
|
|
490
|
-
|
|
491
|
-
const expected = `
|
|
492
|
-
a.b{
|
|
493
|
-
color:red;
|
|
494
|
-
margin:1
|
|
495
|
-
}
|
|
496
|
-
a.b.c{
|
|
497
|
-
margin:2;
|
|
498
|
-
padding:2
|
|
499
|
-
}
|
|
500
|
-
a.b{
|
|
501
|
-
padding:1
|
|
502
|
-
}`.replace(/\n\s*/g, '')
|
|
503
|
-
|
|
504
|
-
expect(actual).toStrictEqual(expected)
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
```js
|
|
508
|
-
const actual = jcss({
|
|
509
|
-
'@font-face$$1': {
|
|
510
|
-
fontFamily: 'Jackens',
|
|
511
|
-
src$$1: 'url(otf/jackens.otf)',
|
|
512
|
-
src$$2: "url(otf/jackens.otf) format('opentype')," +
|
|
513
|
-
"url(svg/jackens.svg) format('svg')",
|
|
514
|
-
fontWeight: 'normal',
|
|
515
|
-
fontStyle: 'normal'
|
|
516
|
-
},
|
|
517
|
-
'@font-face$$2': {
|
|
518
|
-
fontFamily: 'C64',
|
|
519
|
-
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
|
|
520
|
-
},
|
|
521
|
-
'@keyframes spin': {
|
|
522
|
-
'0%': { transform: 'rotate(0deg)' },
|
|
523
|
-
'100%': { transform: 'rotate(360deg)' }
|
|
524
|
-
},
|
|
525
|
-
div: {
|
|
526
|
-
border: 'solid red 1px',
|
|
527
|
-
'.c1': { 'background-color': '#000' },
|
|
528
|
-
' .c1': { backgroundColor: 'black' },
|
|
529
|
-
'.c2': { backgroundColor: 'rgb(0,0,0)' }
|
|
530
|
-
},
|
|
531
|
-
'@media(min-width:200px)': {
|
|
532
|
-
div: { margin: 0, padding: 0 },
|
|
533
|
-
span: { color: '#000' }
|
|
534
|
-
}
|
|
535
|
-
})
|
|
536
|
-
|
|
537
|
-
const expected = `
|
|
538
|
-
@font-face{
|
|
539
|
-
font-family:Jackens;
|
|
540
|
-
src:url(otf/jackens.otf);
|
|
541
|
-
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
542
|
-
font-weight:normal;
|
|
543
|
-
font-style:normal
|
|
544
|
-
}
|
|
545
|
-
@font-face{
|
|
546
|
-
font-family:C64;
|
|
547
|
-
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
548
|
-
}
|
|
549
|
-
@keyframes spin{
|
|
550
|
-
0%{
|
|
551
|
-
transform:rotate(0deg)
|
|
552
|
-
}
|
|
553
|
-
100%{
|
|
554
|
-
transform:rotate(360deg)
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
div{
|
|
558
|
-
border:solid red 1px
|
|
559
|
-
}
|
|
560
|
-
div.c1{
|
|
561
|
-
background-color:#000
|
|
562
|
-
}
|
|
563
|
-
div .c1{
|
|
564
|
-
background-color:black
|
|
565
|
-
}
|
|
566
|
-
div.c2{
|
|
567
|
-
background-color:rgb(0,0,0)
|
|
568
|
-
}
|
|
569
|
-
@media(min-width:200px){
|
|
570
|
-
div{
|
|
571
|
-
margin:0;
|
|
572
|
-
padding:0
|
|
573
|
-
}
|
|
574
|
-
span{
|
|
575
|
-
color:#000
|
|
576
|
-
}
|
|
577
|
-
}`.replace(/\n\s*/g, '')
|
|
578
|
-
|
|
579
|
-
expect(actual).toStrictEqual(expected)
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
```js
|
|
583
|
-
const actual = jcss({
|
|
584
|
-
a: {
|
|
585
|
-
'.b,.c': {
|
|
586
|
-
margin: 1,
|
|
587
|
-
'.d': {
|
|
588
|
-
margin: 2
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
})
|
|
593
|
-
|
|
594
|
-
const expected = `
|
|
595
|
-
a.b,a.c{
|
|
596
|
-
margin:1
|
|
597
|
-
}
|
|
598
|
-
a.b.d,a.c.d{
|
|
599
|
-
margin:2
|
|
600
|
-
}`.replace(/\n\s*/g, '')
|
|
601
|
-
|
|
602
|
-
expect(actual).toStrictEqual(expected)
|
|
603
|
-
```
|
|
604
|
-
|
|
605
655
|
```js
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
margin: 1,
|
|
609
|
-
'.d': {
|
|
610
|
-
margin: 2
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
})
|
|
656
|
+
const num = 42
|
|
657
|
+
const str = '42'
|
|
614
658
|
|
|
615
|
-
|
|
616
|
-
.b,.c{
|
|
617
|
-
margin:1
|
|
618
|
-
}
|
|
619
|
-
.b.d,.c.d{
|
|
620
|
-
margin:2
|
|
621
|
-
}`.replace(/\n\s*/g, '')
|
|
622
|
-
|
|
623
|
-
expect(actual).toStrictEqual(expected)
|
|
624
|
-
```
|
|
659
|
+
expect(is(Number, num)).toBeTrue()
|
|
625
660
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
margin: 1,
|
|
630
|
-
'.c,.d': {
|
|
631
|
-
margin: 2
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
})
|
|
635
|
-
|
|
636
|
-
const expected = `
|
|
637
|
-
.a,.b{
|
|
638
|
-
margin:1
|
|
639
|
-
}
|
|
640
|
-
.a.c,.a.d,.b.c,.b.d{
|
|
641
|
-
margin:2
|
|
642
|
-
}`.replace(/\n\s*/g, '')
|
|
661
|
+
try {
|
|
662
|
+
num.constructor = str.constructor
|
|
663
|
+
} catch { /* empty */ }
|
|
643
664
|
|
|
644
|
-
expect(
|
|
665
|
+
expect(is(Number, num)).toBeTrue()
|
|
645
666
|
```
|
|
646
667
|
|
|
647
668
|
### jsOnParse
|