@jackens/nnn 2024.2.20 → 2024.2.25

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/h.js DELETED
@@ -1,213 +0,0 @@
1
- import { is } from './is.js'
2
-
3
- /**
4
- * The type of arguments of the `h` and `s` helpers.
5
- *
6
- * @typedef {Partial<Record<PropertyKey, any>> | null | undefined | Node | string | number | HArgs} HArgs1
7
- */
8
-
9
- /**
10
- * The type of arguments of the `h` and `s` helpers.
11
- *
12
- * @typedef {[string | Node, ...HArgs1[]]} HArgs
13
- */
14
-
15
- const NS = {
16
- xlink: 'http://www.w3.org/1999/xlink'
17
- }
18
-
19
- /**
20
- * @type {{
21
- * (namespaceURI?: null | undefined): {
22
- * <T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1[]): HTMLElementTagNameMap[T];
23
- * <N extends Node> (node: N, ...args1: HArgs1[]): N;
24
- * (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
25
- * };
26
- * (namespaceURI: 'http://www.w3.org/2000/svg'): {
27
- * <T extends keyof SVGElementTagNameMap> (tag: T, ...args1: HArgs1[]): SVGElementTagNameMap[T];
28
- * <N extends Node> (node: N, ...args1: HArgs1[]): N;
29
- * (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
30
- * };
31
- * }}
32
- */
33
- const _h = (/** @type {string?=} */ namespaceURI) => {
34
- const createElement = namespaceURI == null
35
- ? (/** @type {string } */ tag) => document.createElement(tag)
36
- : (/** @type {string } */ tag) => document.createElementNS(namespaceURI, tag)
37
-
38
- const h = (/** @type {string | Node} */ tagOrNode, /** @type {HArgs1[]} */ ...args) => {
39
- const node = is(String, tagOrNode) ? createElement(tagOrNode) : tagOrNode
40
-
41
- args.forEach(arg => {
42
- let child = null
43
-
44
- if (arg instanceof Node) {
45
- child = arg
46
- } else if (is(String, arg) || is(Number, arg)) {
47
- // @ts-expect-error
48
- child = new Text(arg)
49
- } else if (is(Array, arg)) {
50
- // @ts-expect-error
51
- child = h(...arg)
52
- } else if (arg != null) {
53
- for (const name in arg) {
54
- const value = arg[name]
55
-
56
- if (name[0] === '$') {
57
- const name1 = name.slice(1)
58
-
59
- if (is(Object, value)) {
60
- // @ts-expect-error
61
- node[name1] = node[name1] ?? {}
62
- // @ts-expect-error
63
- Object.assign(node[name1], value)
64
- } else {
65
- // @ts-expect-error
66
- node[name1] = value
67
- }
68
- } else if (node instanceof Element) {
69
- const indexOfColon = name.indexOf(':')
70
-
71
- if (indexOfColon >= 0) {
72
- // @ts-expect-error
73
- const /** @type {string=} */ ns = NS[name.slice(0, indexOfColon)]
74
-
75
- if (ns != null) {
76
- const basename = name.slice(indexOfColon + 1)
77
-
78
- if (value === true) {
79
- node.setAttributeNS(ns, basename, '')
80
- } else if (value === false) {
81
- node.removeAttributeNS(ns, basename)
82
- } else {
83
- node.setAttributeNS(ns, basename, is(String, value) ? value : '' + value)
84
- }
85
- }
86
- } else {
87
- if (value === true) {
88
- node.setAttribute(name, '')
89
- } else if (value === false) {
90
- node.removeAttribute(name)
91
- } else {
92
- node.setAttribute(name, is(String, value) ? value : '' + value)
93
- }
94
- }
95
- }
96
- }
97
- }
98
-
99
- if (child != null) {
100
- node.appendChild(child)
101
- }
102
- })
103
-
104
- return node
105
- }
106
-
107
- return h
108
- }
109
-
110
- /**
111
- * A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
112
- *
113
- * - The first argument of type `string` specifies the tag of the element to be created.
114
- * - The first argument of type `Node` specifies the element to be modified.
115
- * - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
116
- * Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
117
- * (Note that `$` is not a valid attribute name character.)
118
- * All other keys specify *attributes* to be set by `setAttribute`.
119
- * An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
120
- * - All other arguments of type `null` or `undefined` are simply ignored.
121
- * - All other arguments of type `Node` are appended to the element being created or modified.
122
- * - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
123
- * - All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or modified.
124
- */
125
- export const h = _h()
126
-
127
- /**
128
- * A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
129
- *
130
- * - The first argument of type `string` specifies the tag of the element to be created.
131
- * - The first argument of type `Node` specifies the element to be modified.
132
- * - All other arguments of type `Partial<Record<PropertyKey, any>>` are mappings of attributes and properties.
133
- * Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified.
134
- * (Note that `$` is not a valid attribute name character.)
135
- * All other keys specify *attributes* to be set by `setAttributeNS`.
136
- * An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
137
- * - All other arguments of type `null` or `undefined` are simply ignored.
138
- * - All other arguments of type `Node` are appended to the element being created or modified.
139
- * - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
140
- * - All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or modified.
141
- */
142
- export const s = _h('http://www.w3.org/2000/svg')
143
-
144
- export const tests = {
145
- h: (/** @type {import('chai').expect} */ expect) => {
146
- const b = h('b')
147
-
148
- expect(b.outerHTML).to.deep.equal('<b></b>')
149
-
150
- const i = h('i', 'text')
151
-
152
- h(b, i)
153
-
154
- expect(i.outerHTML).to.deep.equal('<i>text</i>')
155
- expect(b.outerHTML).to.deep.equal('<b><i>text</i></b>')
156
-
157
- h(i, { $className: 'some class' })
158
-
159
- expect(i.outerHTML).to.deep.equal('<i class="some class">text</i>')
160
- expect(b.outerHTML).to.deep.equal('<b><i class="some class">text</i></b>')
161
- },
162
-
163
- 'h: innerText vs items': (/** @type {import('chai').expect} */ expect) => {
164
- expect(h('span', 'text').outerHTML).to.deep.equal('<span>text</span>')
165
- expect(h('span', { $innerText: 'text' }).outerHTML).to.deep.equal('<span>text</span>')
166
- },
167
-
168
- 'h: style': (/** @type {import('chai').expect} */ expect) => {
169
- expect(h('div', { style: 'margin:0;padding:0' }).outerHTML)
170
- .to.deep.equal('<div style="margin:0;padding:0"></div>')
171
- expect(h('div', { $style: 'margin:0;padding:0' }).outerHTML)
172
- .to.deep.equal('<div style="margin: 0px; padding: 0px;"></div>')
173
- expect(h('div', { $style: { margin: 0, padding: 0 } }).outerHTML)
174
- .to.deep.equal('<div style="margin: 0px; padding: 0px;"></div>')
175
- },
176
-
177
- 'h: attributes vs properties': (/** @type {import('chai').expect} */ expect) => {
178
- const input1 = h('input', { value: 42 })
179
- const input2 = h('input', { $value: '42' })
180
-
181
- expect(input1.value).to.deep.equal('42')
182
- expect(input2.value).to.deep.equal('42')
183
-
184
- expect(input1.outerHTML).to.deep.equal('<input value="42">')
185
- expect(input2.outerHTML).to.deep.equal('<input>')
186
-
187
- const checkbox1 = h('input', { type: 'checkbox', checked: true })
188
- const checkbox2 = h('input', { type: 'checkbox', $checked: true })
189
-
190
- expect(checkbox1.checked).to.be.true
191
- expect(checkbox2.checked).to.be.true
192
-
193
- expect(checkbox1.outerHTML).to.deep.equal('<input type="checkbox" checked="">')
194
- expect(checkbox2.outerHTML).to.deep.equal('<input type="checkbox">')
195
- },
196
-
197
- 'h: nested properties': (/** @type {import('chai').expect} */ expect) => {
198
- const div = h('div')
199
-
200
- // @ts-expect-error
201
- expect(div.key).to.be.undefined
202
-
203
- h(div, { $key: { one: 1 } })
204
-
205
- // @ts-expect-error
206
- expect(div.key).to.deep.equal({ one: 1 })
207
-
208
- h(div, { $key: { two: 2 } })
209
-
210
- // @ts-expect-error
211
- expect(div.key).to.deep.equal({ one: 1, two: 2 })
212
- }
213
- }
package/has.d.ts DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
3
- */
4
- export function has(key: any, ref: any): boolean;
5
-
6
- export const tests: {
7
- has: (expect: Chai.ExpectStatic) => void;
8
- 'has: null': (expect: Chai.ExpectStatic) => void;
9
- };
package/has.js DELETED
@@ -1,40 +0,0 @@
1
- import { is } from './is.js'
2
-
3
- /**
4
- * A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
5
- */
6
- export const has = (/** @type {any} */ key, /** @type {any} */ ref) =>
7
- (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key)
8
-
9
- export const tests = {
10
- has: (/** @type {import('chai').expect} */ expect) => {
11
- const obj = { key: 'K', null: 'N' }
12
-
13
- expect('key' in obj).to.be.true
14
- expect(has('key', obj)).to.be.true
15
-
16
- expect('null' in obj).to.be.true
17
- expect(has('null', obj)).to.be.true
18
-
19
- // @ts-expect-error
20
- expect(null in obj).to.be.true
21
- expect(has(null, obj)).to.be.false
22
-
23
- expect('toString' in obj).to.be.true
24
- expect(has('toString', obj)).to.be.false
25
- },
26
-
27
- 'has: null': (/** @type {import('chai').expect} */ expect) => {
28
- let typeError
29
-
30
- try {
31
- // @ts-expect-error
32
- 'key' in null
33
- } catch (error) {
34
- typeError = error
35
- }
36
-
37
- expect(typeError instanceof TypeError) // Cannot use 'in' operator to search for 'key' in null
38
- expect(has('key', null)).to.be.false
39
- }
40
- }
package/is.d.ts DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * A helper that checks if the given argument is of a certain type.
3
- */
4
- export const is: {
5
- (type: BigIntConstructor, arg: any): arg is bigint;
6
- (type: BooleanConstructor, arg: any): arg is boolean;
7
- (type: NumberConstructor, arg: any): arg is number;
8
- (type: StringConstructor, arg: any): arg is string;
9
- (type: SymbolConstructor, arg: any): arg is symbol;
10
- (type: undefined, arg: any): arg is null | undefined;
11
- <T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
12
- };
13
-
14
- export const tests: {
15
- is: (expect: Chai.ExpectStatic) => void;
16
- 'is: toString.call': (expect: Chai.ExpectStatic) => void;
17
- };
package/is.js DELETED
@@ -1,65 +0,0 @@
1
- /**
2
- * A helper that checks if the given argument is of a certain type.
3
- *
4
- * @template {abstract new (...args: any[]) => any} T
5
- *
6
- * @type {{
7
- * (type: BigIntConstructor, arg: any): arg is bigint;
8
- * (type: BooleanConstructor, arg: any): arg is boolean;
9
- * (type: NumberConstructor, arg: any): arg is number;
10
- * (type: StringConstructor, arg: any): arg is string;
11
- * (type: SymbolConstructor, arg: any): arg is symbol;
12
- * (type: undefined, arg: any): arg is undefined | null;
13
- * <T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
14
- * }}
15
- *
16
- * @return {arg is bigint | boolean | number | string | symbol | undefined | null | InstanceType<T>}
17
- */
18
- export const is = (/** @type {T} */ type, /** @type {any} */ arg) => arg?.constructor === type
19
-
20
- export const tests = {
21
- is: (/** @type {import('chai').expect} */ expect) => {
22
- expect(is(Number, 42)).to.be.true
23
- expect(is(Number, Number(42))).to.be.true
24
- // eslint-disable-next-line no-new-wrappers
25
- expect(is(Number, new Number(42))).to.be.true
26
- expect(is(Number, NaN)).to.be.true
27
- expect(is(String, '42')).to.be.true
28
- expect(is(String, String('42'))).to.be.true
29
- // eslint-disable-next-line no-new-wrappers
30
- expect(is(String, new String('42'))).to.be.true
31
- expect(is(Symbol, Symbol('42'))).to.be.true
32
- expect(is(Symbol, Object(Symbol('42')))).to.be.true
33
- expect(is(undefined, undefined)).to.be.true
34
- expect(is(undefined, null)).to.be.true
35
- expect(is(Object, {})).to.be.true
36
- expect(is(Array, [])).to.be.true
37
- expect(is(RegExp, /42/)).to.be.true
38
- expect(is(Date, new Date(42))).to.be.true
39
- expect(is(Set, new Set(['42', 42]))).to.be.true
40
- expect(is(Map, new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]))).to.be.true
41
- },
42
-
43
- 'is: toString.call': (/** @type {import('chai').expect} */ expect) => {
44
- const iz = (/** @type {any} */ type, /** @type {any} */ arg) => ({}).toString.call(arg).slice(8, -1) === type?.name
45
-
46
- class FooBar { }
47
-
48
- expect(is(FooBar, new FooBar())).to.be.true
49
- expect(iz(FooBar, new FooBar())).to.be.false
50
-
51
- expect(is(Object, new FooBar())).to.be.false
52
- expect(iz(Object, new FooBar())).to.be.true
53
-
54
- const fakeFooBar = {}
55
-
56
- // @ts-expect-error
57
- fakeFooBar[Symbol.toStringTag] = FooBar.name
58
-
59
- expect(is(FooBar, fakeFooBar)).to.be.false
60
- expect(iz(FooBar, fakeFooBar)).to.be.true
61
-
62
- expect(is(Object, fakeFooBar)).to.be.true
63
- expect(iz(Object, fakeFooBar)).to.be.false
64
- }
65
- }
package/jcss.d.ts DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * The type of arguments of the `jcss` helper.
3
- */
4
- export type JcssNode = {
5
- [attributeOrSelector: string]: string | number | JcssNode | undefined;
6
- };
7
-
8
- /**
9
- * The type of arguments of the `jcss` helper.
10
- */
11
- export type JcssRoot = Partial<Record<PropertyKey, JcssNode>>;
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 function jcss(root: JcssRoot, splitter?: string): string;
25
-
26
- export const tests: {
27
- 'jcss: #1': (expect: Chai.ExpectStatic) => void;
28
- 'jcss: #2': (expect: Chai.ExpectStatic) => void;
29
- 'jcss: #3': (expect: Chai.ExpectStatic) => void;
30
- 'jcss: #4': (expect: Chai.ExpectStatic) => void;
31
- 'jcss: #5': (expect: Chai.ExpectStatic) => void;
32
- 'jcss: #6': (expect: Chai.ExpectStatic) => void;
33
- };
package/jcss.js DELETED
@@ -1,293 +0,0 @@
1
- import { is } from './is.js'
2
-
3
- /**
4
- * The type of arguments of the `jcss` helper.
5
- *
6
- * @typedef {{
7
- * [attributeOrSelector: string]: string | number | JcssNode | undefined;
8
- * }} JcssNode
9
- */
10
-
11
- /**
12
- * The type of arguments of the `jcss` helper.
13
- *
14
- * @typedef {Partial<Record<PropertyKey, JcssNode>>} JcssRoot
15
- */
16
-
17
- const _jcss = (
18
- /** @type {JcssNode} */ node,
19
- /** @type {string} */ prefix,
20
- /** @type {string[]} */ result,
21
- /** @type {(text: string) => string} */ split
22
- ) => {
23
- const /** @type {[JcssNode | string[], string][]} */ queue = [[node, prefix]]
24
-
25
- while (queue.length > 0) {
26
- const [style0, prefix0] = queue.shift() ?? []
27
-
28
- if (style0 == null || prefix0 == null) {
29
- continue
30
- }
31
-
32
- if (is(Array, style0)) {
33
- result.push(prefix0, prefix0 !== '' ? '{' : '', style0.join(';'), prefix0 !== '' ? '}' : '')
34
- } else {
35
- const /** @type {[JcssNode | string[], string][]} */ todo = []
36
- let /** @type {string[]} */ attributes = []
37
- let attributesPushed = false
38
-
39
- for (const key in style0) {
40
- const value = style0[key]
41
-
42
- if (is(String, value) || is(Number, value)) {
43
- if (!attributesPushed) {
44
- attributesPushed = true
45
- attributes = []
46
- todo.push([attributes, prefix0])
47
- }
48
-
49
- attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => '-' + letter.toLowerCase())}:${value}`)
50
- } else if (value != null) {
51
- attributesPushed = false
52
-
53
- const /** @type {string[]} */ prefixN = []
54
- const keyChunks = key.split(',')
55
-
56
- prefix0.split(',').forEach(prefixChunk => keyChunks.forEach(keyChunk => prefixN.push(prefixChunk + keyChunk)))
57
-
58
- todo.push([value, prefixN.join(',')])
59
- }
60
- }
61
-
62
- queue.unshift(...todo)
63
- }
64
- }
65
- }
66
-
67
- /**
68
- * A simple CSS-in-JS helper.
69
- *
70
- * The `root` parameter provides a hierarchical description of CSS rules.
71
- *
72
- * - 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.
73
- * - 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`).
74
- * - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
75
- * - 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}`).
76
- * - Top-level keys that begin with `@` are not concatenated with sub-object keys.
77
- */
78
- export const jcss = (/** @type {JcssRoot} */ root, splitter = '$$') => {
79
- const split = (/** @type {string} */ text) => text.split(splitter)[0]
80
- const /** @type {string[]} */ chunks = []
81
-
82
- for (const key in root) {
83
- const value = root[key]
84
-
85
- if (value != null) {
86
- if (key[0] === '@') {
87
- chunks.push(split(key) + '{')
88
- _jcss(value, '', chunks, split)
89
- chunks.push('}')
90
- } else {
91
- _jcss(value, split(key), chunks, split)
92
- }
93
- }
94
- }
95
-
96
- return chunks.join('')
97
- }
98
-
99
- export const tests = {
100
- 'jcss: #1': (/** @type {import('chai').expect} */ expect) => {
101
- const actual = jcss({
102
- a: {
103
- color: 'red',
104
- margin: 1,
105
- '.c': { margin: 2, padding: 2 },
106
- padding: 1
107
- }
108
- })
109
-
110
- const expected = `
111
- a{
112
- color:red;
113
- margin:1
114
- }
115
- a.c{
116
- margin:2;
117
- padding:2
118
- }
119
- a{
120
- padding:1
121
- }`.replace(/\n\s*/g, '')
122
-
123
- expect(actual).to.deep.equal(expected)
124
- },
125
-
126
- 'jcss: #2': (/** @type {import('chai').expect} */ expect) => {
127
- const actual = jcss({
128
- a: {
129
- '.b': {
130
- color: 'red',
131
- margin: 1,
132
- '.c': { margin: 2, padding: 2 },
133
- padding: 1
134
- }
135
- }
136
- })
137
-
138
- const expected = `
139
- a.b{
140
- color:red;
141
- margin:1
142
- }
143
- a.b.c{
144
- margin:2;
145
- padding:2
146
- }
147
- a.b{
148
- padding:1
149
- }`.replace(/\n\s*/g, '')
150
-
151
- expect(actual).to.deep.equal(expected)
152
- },
153
-
154
- 'jcss: #3': (/** @type {import('chai').expect} */ expect) => {
155
- const actual = jcss({
156
- '@font-face$$1': {
157
- fontFamily: 'Jackens',
158
- src$$1: 'url(otf/jackens.otf)',
159
- src$$2: "url(otf/jackens.otf) format('opentype')," +
160
- "url(svg/jackens.svg) format('svg')",
161
- fontWeight: 'normal',
162
- fontStyle: 'normal'
163
- },
164
- '@font-face$$2': {
165
- fontFamily: 'C64',
166
- src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
167
- },
168
- '@keyframes spin': {
169
- '0%': { transform: 'rotate(0deg)' },
170
- '100%': { transform: 'rotate(360deg)' }
171
- },
172
- div: {
173
- border: 'solid red 1px',
174
- '.c1': { 'background-color': '#000' },
175
- ' .c1': { backgroundColor: 'black' },
176
- '.c2': { backgroundColor: 'rgb(0,0,0)' }
177
- },
178
- '@media(min-width:200px)': {
179
- div: { margin: 0, padding: 0 },
180
- span: { color: '#000' }
181
- }
182
- })
183
-
184
- const expected = `
185
- @font-face{
186
- font-family:Jackens;
187
- src:url(otf/jackens.otf);
188
- src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
189
- font-weight:normal;
190
- font-style:normal
191
- }
192
- @font-face{
193
- font-family:C64;
194
- src:url(fonts/C64_Pro_Mono-STYLE.woff)
195
- }
196
- @keyframes spin{
197
- 0%{
198
- transform:rotate(0deg)
199
- }
200
- 100%{
201
- transform:rotate(360deg)
202
- }
203
- }
204
- div{
205
- border:solid red 1px
206
- }
207
- div.c1{
208
- background-color:#000
209
- }
210
- div .c1{
211
- background-color:black
212
- }
213
- div.c2{
214
- background-color:rgb(0,0,0)
215
- }
216
- @media(min-width:200px){
217
- div{
218
- margin:0;
219
- padding:0
220
- }
221
- span{
222
- color:#000
223
- }
224
- }`.replace(/\n\s*/g, '')
225
-
226
- expect(actual).to.deep.equal(expected)
227
- },
228
-
229
- 'jcss: #4': (/** @type {import('chai').expect} */ expect) => {
230
- const actual = jcss({
231
- a: {
232
- '.b,.c': {
233
- margin: 1,
234
- '.d': {
235
- margin: 2
236
- }
237
- }
238
- }
239
- })
240
-
241
- const expected = `
242
- a.b,a.c{
243
- margin:1
244
- }
245
- a.b.d,a.c.d{
246
- margin:2
247
- }`.replace(/\n\s*/g, '')
248
-
249
- expect(actual).to.deep.equal(expected)
250
- },
251
-
252
- 'jcss: #5': (/** @type {import('chai').expect} */ expect) => {
253
- const actual = jcss({
254
- '.b,.c': {
255
- margin: 1,
256
- '.d': {
257
- margin: 2
258
- }
259
- }
260
- })
261
-
262
- const expected = `
263
- .b,.c{
264
- margin:1
265
- }
266
- .b.d,.c.d{
267
- margin:2
268
- }`.replace(/\n\s*/g, '')
269
-
270
- expect(actual).to.deep.equal(expected)
271
- },
272
-
273
- 'jcss: #6': (/** @type {import('chai').expect} */ expect) => {
274
- const actual = jcss({
275
- '.a,.b': {
276
- margin: 1,
277
- '.c,.d': {
278
- margin: 2
279
- }
280
- }
281
- })
282
-
283
- const expected = `
284
- .a,.b{
285
- margin:1
286
- }
287
- .a.c,.a.d,.b.c,.b.d{
288
- margin:2
289
- }`.replace(/\n\s*/g, '')
290
-
291
- expect(actual).to.deep.equal(expected)
292
- }
293
- }
package/jsOnParse.d.ts DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * `JSON.parse` with “JavaScript turned on”.
3
- *
4
- * Objects having *exactly* one property which is present in the `handlers` map, i.e. objects of the form:
5
- *
6
- * ```js
7
- * { "«handlerName»": [«params»] }
8
- * ```
9
- *
10
- * are replaced by the result of call
11
- *
12
- * ```js
13
- * handlers['«handlerName»'](...«params»)
14
- * ```
15
- */
16
- export function jsOnParse(handlers: Partial<Record<PropertyKey, Function>>, text: string): any;
17
-
18
- export namespace tests {
19
- function jsOnParse(expect: Chai.ExpectStatic): void;
20
- }