|
1 |
| -/** |
2 |
| - * @typedef {import('hast').Root} HastRoot |
3 |
| - * @typedef {import('hast').Element} HastElement |
4 |
| - * @typedef {import('hast').Properties} Properties |
5 |
| - * @typedef {HastRoot['children'][number]} HastChild |
6 |
| - * @typedef {import('property-information').html['property'][string]} Info |
7 |
| - * @typedef {html|svg} Schema |
8 |
| - */ |
9 |
| - |
10 |
| -/** |
11 |
| - * @typedef {string|number} HStyleValue |
12 |
| - * @typedef {Object.<string, HStyleValue>} HStyle |
13 |
| - * @typedef {string|number|boolean|null|undefined} HPrimitiveValue |
14 |
| - * @typedef {Array.<string|number>} HArrayValue |
15 |
| - * @typedef {HPrimitiveValue|HArrayValue} HPropertyValue |
16 |
| - * @typedef {{[property: string]: HPropertyValue|HStyle}} HProperties |
17 |
| - * |
18 |
| - * @typedef {string|number|null|undefined} HPrimitiveChild |
19 |
| - * @typedef {HastChild|HastRoot} HNodeChild |
20 |
| - * @typedef {Array.<HPrimitiveChild|HNodeChild>} HArrayChild |
21 |
| - * @typedef {HPrimitiveChild|HNodeChild|HArrayChild} HChild |
22 |
| - */ |
23 |
| - |
24 |
| -import {html, svg, find, normalize} from 'property-information' |
25 |
| -import {parseSelector} from 'hast-util-parse-selector' |
26 |
| -import {parse as spaces} from 'space-separated-tokens' |
27 |
| -import {parse as commas} from 'comma-separated-tokens' |
28 |
| -import {svgCaseSensitiveTagNames} from './svg-case-sensitive-tag-names.js' |
29 |
| - |
30 |
| -var buttonTypes = new Set(['menu', 'submit', 'reset', 'button']) |
31 |
| - |
32 |
| -var own = {}.hasOwnProperty |
33 |
| - |
34 |
| -export const h = factory(html, 'div') |
35 |
| - |
36 |
| -export const s = factory(svg, 'g', svgCaseSensitiveTagNames) |
37 |
| - |
38 |
| -/** |
39 |
| - * @param {Schema} schema |
40 |
| - * @param {string} defaultTagName |
41 |
| - * @param {Array.<string>} [caseSensitive] |
42 |
| - */ |
43 |
| -function factory(schema, defaultTagName, caseSensitive) { |
44 |
| - var adjust = caseSensitive && createAdjustMap(caseSensitive) |
45 |
| - |
46 |
| - const h = |
47 |
| - /** |
48 |
| - * @type {{ |
49 |
| - * (): HastRoot |
50 |
| - * (selector: null|undefined, ...children: HChild[]): HastRoot |
51 |
| - * (selector: string, properties: HProperties, ...children: HChild[]): HastElement |
52 |
| - * (selector: string, ...children: HChild[]): HastElement |
53 |
| - * }} |
54 |
| - */ |
55 |
| - ( |
56 |
| - /** |
57 |
| - * Hyperscript compatible DSL for creating virtual hast trees. |
58 |
| - * |
59 |
| - * @param {string|null} [selector] |
60 |
| - * @param {HProperties|HChild} [properties] |
61 |
| - * @param {...HChild} [children] |
62 |
| - */ |
63 |
| - function (selector, properties, ...children) { |
64 |
| - var index = -1 |
65 |
| - /** @type {HastRoot|HastElement} */ |
66 |
| - var node |
67 |
| - /** @type {string} */ |
68 |
| - var name |
69 |
| - /** @type {string} */ |
70 |
| - var key |
71 |
| - |
72 |
| - if (selector === undefined || selector === null) { |
73 |
| - node = {type: 'root', children: []} |
74 |
| - // @ts-ignore Properties are not supported for roots. |
75 |
| - children.unshift(properties) |
76 |
| - } else { |
77 |
| - node = parseSelector(selector, defaultTagName) |
78 |
| - // Normalize the name. |
79 |
| - name = node.tagName.toLowerCase() |
80 |
| - if (adjust && own.call(adjust, name)) name = adjust[name] |
81 |
| - node.tagName = name |
82 |
| - |
83 |
| - // Handle props. |
84 |
| - if (isProperties(properties, name)) { |
85 |
| - for (key in properties) { |
86 |
| - if (own.call(properties, key)) { |
87 |
| - addProperty(schema, node.properties, key, properties[key]) |
88 |
| - } |
89 |
| - } |
90 |
| - } else { |
91 |
| - children.unshift(properties) |
92 |
| - } |
93 |
| - } |
94 |
| - |
95 |
| - // Handle children. |
96 |
| - while (++index < children.length) { |
97 |
| - addChild(node.children, children[index]) |
98 |
| - } |
99 |
| - |
100 |
| - if (name === 'template') { |
101 |
| - node.content = {type: 'root', children: node.children} |
102 |
| - node.children = [] |
103 |
| - } |
104 |
| - |
105 |
| - return node |
106 |
| - } |
107 |
| - ) |
108 |
| - |
109 |
| - return h |
110 |
| -} |
111 |
| - |
112 |
| -/** |
113 |
| - * @param {HProperties|HChild} value |
114 |
| - * @param {string} name |
115 |
| - * @returns {value is HProperties} |
116 |
| - */ |
117 |
| -function isProperties(value, name) { |
118 |
| - if ( |
119 |
| - value === null || |
120 |
| - value === undefined || |
121 |
| - typeof value !== 'object' || |
122 |
| - Array.isArray(value) |
123 |
| - ) { |
124 |
| - return false |
125 |
| - } |
126 |
| - |
127 |
| - if (name === 'input' || !value.type || typeof value.type !== 'string') { |
128 |
| - return true |
129 |
| - } |
130 |
| - |
131 |
| - if (Array.isArray(value.children)) { |
132 |
| - return false |
133 |
| - } |
134 |
| - |
135 |
| - if (name === 'button') { |
136 |
| - return buttonTypes.has(value.type.toLowerCase()) |
137 |
| - } |
138 |
| - |
139 |
| - return !('value' in value) |
140 |
| -} |
141 |
| - |
142 |
| -/** |
143 |
| - * @param {Schema} schema |
144 |
| - * @param {Properties} properties |
145 |
| - * @param {string} key |
146 |
| - * @param {HStyle|HPropertyValue} value |
147 |
| - * @returns {void} |
148 |
| - */ |
149 |
| -function addProperty(schema, properties, key, value) { |
150 |
| - var info = find(schema, key) |
151 |
| - var index = -1 |
152 |
| - /** @type {HPropertyValue} */ |
153 |
| - var result |
154 |
| - /** @type {Array.<string|number>} */ |
155 |
| - var finalResult |
156 |
| - |
157 |
| - // Ignore nullish and NaN values. |
158 |
| - if (value === undefined || value === null) return |
159 |
| - |
160 |
| - if (typeof value === 'number') { |
161 |
| - // Ignore NaN. |
162 |
| - if (Number.isNaN(value)) return |
163 |
| - |
164 |
| - result = value |
165 |
| - } |
166 |
| - // Booleans. |
167 |
| - else if (typeof value === 'boolean') { |
168 |
| - result = value |
169 |
| - } |
170 |
| - // Handle list values. |
171 |
| - else if (typeof value === 'string') { |
172 |
| - if (info.spaceSeparated) { |
173 |
| - result = spaces(value) |
174 |
| - } else if (info.commaSeparated) { |
175 |
| - result = commas(value) |
176 |
| - } else if (info.commaOrSpaceSeparated) { |
177 |
| - result = spaces(commas(value).join(' ')) |
178 |
| - } else { |
179 |
| - result = parsePrimitive(info, info.property, value) |
180 |
| - } |
181 |
| - } else if (Array.isArray(value)) { |
182 |
| - result = value.concat() |
183 |
| - } else { |
184 |
| - result = info.property === 'style' ? style(value) : String(value) |
185 |
| - } |
186 |
| - |
187 |
| - if (Array.isArray(result)) { |
188 |
| - finalResult = [] |
189 |
| - |
190 |
| - while (++index < result.length) { |
191 |
| - // @ts-ignore Assume no booleans in array. |
192 |
| - finalResult[index] = parsePrimitive(info, info.property, result[index]) |
193 |
| - } |
194 |
| - |
195 |
| - result = finalResult |
196 |
| - } |
197 |
| - |
198 |
| - // Class names (which can be added both on the `selector` and here). |
199 |
| - if (info.property === 'className' && Array.isArray(properties.className)) { |
200 |
| - // @ts-ignore Assume no booleans in `className`. |
201 |
| - result = properties.className.concat(result) |
202 |
| - } |
203 |
| - |
204 |
| - properties[info.property] = result |
205 |
| -} |
206 |
| - |
207 |
| -/** |
208 |
| - * @param {Array.<HastChild>} nodes |
209 |
| - * @param {HChild} value |
210 |
| - * @returns {void} |
211 |
| - */ |
212 |
| -function addChild(nodes, value) { |
213 |
| - var index = -1 |
214 |
| - |
215 |
| - if (value === undefined || value === null) { |
216 |
| - // Empty. |
217 |
| - } else if (typeof value === 'string' || typeof value === 'number') { |
218 |
| - nodes.push({type: 'text', value: String(value)}) |
219 |
| - } else if (Array.isArray(value)) { |
220 |
| - while (++index < value.length) { |
221 |
| - addChild(nodes, value[index]) |
222 |
| - } |
223 |
| - } else if (typeof value === 'object' && 'type' in value) { |
224 |
| - if (value.type === 'root') { |
225 |
| - // @ts-ignore it looks like a root, TS… |
226 |
| - addChild(nodes, value.children) |
227 |
| - } else { |
228 |
| - nodes.push(value) |
229 |
| - } |
230 |
| - } else { |
231 |
| - throw new Error('Expected node, nodes, or string, got `' + value + '`') |
232 |
| - } |
233 |
| -} |
234 |
| - |
235 |
| -/** |
236 |
| - * Parse a single primitives. |
237 |
| - * |
238 |
| - * @param {Info} info |
239 |
| - * @param {string} name |
240 |
| - * @param {HPrimitiveValue} value |
241 |
| - * @returns {HPrimitiveValue} |
242 |
| - */ |
243 |
| -function parsePrimitive(info, name, value) { |
244 |
| - if (typeof value === 'string') { |
245 |
| - if (info.number && value && !Number.isNaN(Number(value))) { |
246 |
| - return Number(value) |
247 |
| - } |
248 |
| - |
249 |
| - if ( |
250 |
| - (info.boolean || info.overloadedBoolean) && |
251 |
| - (value === '' || normalize(value) === normalize(name)) |
252 |
| - ) { |
253 |
| - return true |
254 |
| - } |
255 |
| - } |
256 |
| - |
257 |
| - return value |
258 |
| -} |
259 |
| - |
260 |
| -/** |
261 |
| - * @param {HStyle} value |
262 |
| - * @returns {string} |
263 |
| - */ |
264 |
| -function style(value) { |
265 |
| - /** @type {Array.<string>} */ |
266 |
| - var result = [] |
267 |
| - /** @type {string} */ |
268 |
| - var key |
269 |
| - |
270 |
| - for (key in value) { |
271 |
| - if (own.call(value, key)) { |
272 |
| - result.push([key, value[key]].join(': ')) |
273 |
| - } |
274 |
| - } |
275 |
| - |
276 |
| - return result.join('; ') |
277 |
| -} |
278 |
| - |
279 |
| -/** |
280 |
| - * @param {Array.<string>} values |
281 |
| - * @returns {Object.<string, string>} |
282 |
| - */ |
283 |
| -function createAdjustMap(values) { |
284 |
| - /** @type {Object.<string, string>} */ |
285 |
| - var result = {} |
286 |
| - var index = -1 |
287 |
| - |
288 |
| - while (++index < values.length) { |
289 |
| - result[values[index].toLowerCase()] = values[index] |
290 |
| - } |
291 |
| - |
292 |
| - return result |
293 |
| -} |
| 1 | +export {h, s} from './lib/index.js' |
0 commit comments