7
7
* @typedef {import('../state.js').State } State
8
8
*/
9
9
10
+ /**
11
+ * @typedef {Record<string, string> } Style
12
+ */
13
+
10
14
import { stringify as commas } from 'comma-separated-tokens'
11
15
import { svg , find , hastToReact } from 'property-information'
12
16
import { stringify as spaces } from 'space-separated-tokens'
@@ -17,6 +21,8 @@ import {
17
21
import styleToObject from 'style-to-object'
18
22
19
23
const own = { } . hasOwnProperty
24
+ const cap = / [ A - Z ] / g
25
+ const dashSomething = / - ( [ a - z ] ) / g
20
26
21
27
/**
22
28
* Turn a hast element into an estree node.
@@ -77,26 +83,30 @@ export function element(node, state) {
77
83
}
78
84
79
85
if ( prop === 'style' ) {
80
- /** @type {Record<string, string> } */
81
- // @ts -expect-error Assume `value` is an object otherwise.
82
- const styleValue =
83
- typeof value === 'string' ? parseStyle ( value , node . tagName ) : value
86
+ let styleObject =
87
+ typeof value === 'object'
88
+ ? value
89
+ : parseStyle ( String ( value ) , node . tagName )
90
+
91
+ if ( state . stylePropertyNameCase === 'css' ) {
92
+ styleObject = transformStyleToCssCasing ( styleObject )
93
+ }
84
94
85
95
/** @type {Array<Property> } */
86
96
const cssProperties = [ ]
87
97
/** @type {string } */
88
98
let cssProp
89
99
90
- for ( cssProp in styleValue ) {
100
+ for ( cssProp in styleObject ) {
91
101
// eslint-disable-next-line max-depth
92
- if ( own . call ( styleValue , cssProp ) ) {
102
+ if ( own . call ( styleObject , cssProp ) ) {
93
103
cssProperties . push ( {
94
104
type : 'Property' ,
95
105
method : false ,
96
106
shorthand : false ,
97
107
computed : false ,
98
108
key : { type : 'Identifier' , name : cssProp } ,
99
- value : { type : 'Literal' , value : String ( styleValue [ cssProp ] ) } ,
109
+ value : { type : 'Literal' , value : String ( styleObject [ cssProp ] ) } ,
100
110
kind : 'init'
101
111
} )
102
112
}
@@ -174,11 +184,11 @@ export function element(node, state) {
174
184
* CSS text.
175
185
* @param {string } tagName
176
186
* Element name.
177
- * @returns {Record<string, string> }
187
+ * @returns {Style }
178
188
* Props.
179
189
*/
180
190
function parseStyle ( value , tagName ) {
181
- /** @type {Record<string, string> } */
191
+ /** @type {Style } */
182
192
const result = { }
183
193
184
194
try {
@@ -203,25 +213,68 @@ function parseStyle(value, tagName) {
203
213
* Nothing.
204
214
*/
205
215
function iterator ( name , value ) {
206
- if ( name . slice ( 0 , 4 ) === '-ms-' ) name = 'ms-' + name . slice ( 4 )
207
- result [ name . replace ( / - ( [ a - z ] ) / g, styleReplacer ) ] = value
216
+ let key = name
217
+
218
+ if ( key . slice ( 0 , 2 ) !== '--' ) {
219
+ // See: <https://alanhogan.com/code/vendor-prefixed-css-property-names-in-javascript>
220
+ if ( key . slice ( 0 , 4 ) === '-ms-' ) key = 'ms-' + key . slice ( 4 )
221
+ key = key . replace ( dashSomething , toCamel )
222
+ }
223
+
224
+ result [ key ] = value
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Transform a DOM casing style object to a CSS casing style object.
230
+ *
231
+ * @param {Style } domCasing
232
+ * @returns {Style }
233
+ */
234
+ function transformStyleToCssCasing ( domCasing ) {
235
+ /** @type {Style } */
236
+ const cssCasing = { }
237
+ /** @type {string } */
238
+ let from
239
+
240
+ for ( from in domCasing ) {
241
+ if ( own . call ( domCasing , from ) ) {
242
+ let to = from . replace ( cap , toDash )
243
+ // Handle `ms-xxx` -> `-ms-xxx`.
244
+ if ( to . slice ( 0 , 3 ) === 'ms-' ) to = '-' + to
245
+ cssCasing [ to ] = domCasing [ from ]
246
+ }
208
247
}
248
+
249
+ return cssCasing
209
250
}
210
251
211
252
/**
212
- * Uppercase `$1`.
253
+ * Make `$1` capitalized .
213
254
*
214
255
* @param {string } _
215
256
* Whatever.
216
257
* @param {string } $1
217
- * an ASCII alphabetic .
258
+ * Single ASCII alphabetical .
218
259
* @returns {string }
219
- * Uppercased `$1`.
260
+ * Capitalized `$1`.
220
261
*/
221
- function styleReplacer ( _ , $1 ) {
262
+ function toCamel ( _ , $1 ) {
222
263
return $1 . toUpperCase ( )
223
264
}
224
265
266
+ /**
267
+ * Make `$0` dash cased.
268
+ *
269
+ * @param {string } $0
270
+ * Capitalized ASCII leter.
271
+ * @returns {string }
272
+ * Dash and lower letter.
273
+ */
274
+ function toDash ( $0 ) {
275
+ return '-' + $0 . toLowerCase ( )
276
+ }
277
+
225
278
/**
226
279
* Checks if the given string is a valid identifier name.
227
280
*
0 commit comments