@wordpress/element 5.16.0 → 5.17.0

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/create-interpolate-element.js +19 -49
  3. package/build/create-interpolate-element.js.map +1 -1
  4. package/build/index.js +0 -11
  5. package/build/index.js.map +1 -1
  6. package/build/platform.android.js +3 -4
  7. package/build/platform.android.js.map +1 -1
  8. package/build/platform.ios.js +3 -4
  9. package/build/platform.ios.js.map +1 -1
  10. package/build/platform.js +0 -2
  11. package/build/platform.js.map +1 -1
  12. package/build/raw-html.js +5 -6
  13. package/build/raw-html.js.map +1 -1
  14. package/build/react-platform.js +0 -2
  15. package/build/react-platform.js.map +1 -1
  16. package/build/react-platform.native.js +0 -3
  17. package/build/react-platform.native.js.map +1 -1
  18. package/build/react.js +1 -7
  19. package/build/react.js.map +1 -1
  20. package/build/serialize.js +37 -100
  21. package/build/serialize.js.map +1 -1
  22. package/build/utils.js +0 -4
  23. package/build/utils.js.map +1 -1
  24. package/build-module/create-interpolate-element.js +19 -47
  25. package/build-module/create-interpolate-element.js.map +1 -1
  26. package/build-module/index.js.map +1 -1
  27. package/build-module/platform.android.js +2 -2
  28. package/build-module/platform.android.js.map +1 -1
  29. package/build-module/platform.ios.js +2 -2
  30. package/build-module/platform.ios.js.map +1 -1
  31. package/build-module/platform.js +0 -1
  32. package/build-module/platform.js.map +1 -1
  33. package/build-module/raw-html.js +6 -4
  34. package/build-module/raw-html.js.map +1 -1
  35. package/build-module/react-platform.js +8 -8
  36. package/build-module/react-platform.js.map +1 -1
  37. package/build-module/react-platform.native.js +1 -1
  38. package/build-module/react-platform.native.js.map +1 -1
  39. package/build-module/react.js +31 -33
  40. package/build-module/react.js.map +1 -1
  41. package/build-module/serialize.js +39 -89
  42. package/build-module/serialize.js.map +1 -1
  43. package/build-module/utils.js +0 -2
  44. package/build-module/utils.js.map +1 -1
  45. package/build-types/platform.d.ts +2 -2
  46. package/build-types/react-platform.d.ts +8 -8
  47. package/build-types/react-platform.d.ts.map +1 -1
  48. package/build-types/react.d.ts +29 -29
  49. package/build-types/react.d.ts.map +1 -1
  50. package/package.json +3 -3
  51. package/tsconfig.tsbuildinfo +1 -1
@@ -30,17 +30,18 @@
30
30
  */
31
31
  import { isPlainObject } from 'is-plain-object';
32
32
  import { paramCase as kebabCase } from 'change-case';
33
+
33
34
  /**
34
35
  * WordPress dependencies
35
36
  */
36
-
37
37
  import { escapeHTML, escapeAttribute, isValidAttributeName } from '@wordpress/escape-html';
38
+
38
39
  /**
39
40
  * Internal dependencies
40
41
  */
41
-
42
42
  import { createContext, Fragment, StrictMode, forwardRef } from './react';
43
43
  import RawHTML from './raw-html';
44
+
44
45
  /** @typedef {import('./react').WPElement} WPElement */
45
46
 
46
47
  const {
@@ -50,20 +51,21 @@ const {
50
51
  const ForwardRef = forwardRef(() => {
51
52
  return null;
52
53
  });
54
+
53
55
  /**
54
56
  * Valid attribute types.
55
57
  *
56
58
  * @type {Set<string>}
57
59
  */
58
-
59
60
  const ATTRIBUTES_TYPES = new Set(['string', 'boolean', 'number']);
61
+
60
62
  /**
61
63
  * Element tags which can be self-closing.
62
64
  *
63
65
  * @type {Set<string>}
64
66
  */
65
-
66
67
  const SELF_CLOSING_TAGS = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
68
+
67
69
  /**
68
70
  * Boolean attributes are attributes whose presence as being assigned is
69
71
  * meaningful, even if only empty.
@@ -79,8 +81,8 @@ const SELF_CLOSING_TAGS = new Set(['area', 'base', 'br', 'col', 'command', 'embe
79
81
  *
80
82
  * @type {Set<string>}
81
83
  */
82
-
83
84
  const BOOLEAN_ATTRIBUTES = new Set(['allowfullscreen', 'allowpaymentrequest', 'allowusermedia', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'download', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch']);
85
+
84
86
  /**
85
87
  * Enumerated attributes are attributes which must be of a specific value form.
86
88
  * Like boolean attributes, these are meaningful if specified, even if not of a
@@ -101,8 +103,8 @@ const BOOLEAN_ATTRIBUTES = new Set(['allowfullscreen', 'allowpaymentrequest', 'a
101
103
  *
102
104
  * @type {Set<string>}
103
105
  */
104
-
105
106
  const ENUMERATED_ATTRIBUTES = new Set(['autocapitalize', 'autocomplete', 'charset', 'contenteditable', 'crossorigin', 'decoding', 'dir', 'draggable', 'enctype', 'formenctype', 'formmethod', 'http-equiv', 'inputmode', 'kind', 'method', 'preload', 'scope', 'shape', 'spellcheck', 'translate', 'type', 'wrap']);
107
+
106
108
  /**
107
109
  * Set of CSS style properties which support assignment of unitless numbers.
108
110
  * Used in rendering of style properties, where `px` unit is assumed unless
@@ -121,8 +123,8 @@ const ENUMERATED_ATTRIBUTES = new Set(['autocapitalize', 'autocomplete', 'charse
121
123
  *
122
124
  * @type {Set<string>}
123
125
  */
124
-
125
126
  const CSS_PROPERTIES_SUPPORTS_UNITLESS = new Set(['animation', 'animationIterationCount', 'baselineShift', 'borderImageOutset', 'borderImageSlice', 'borderImageWidth', 'columnCount', 'cx', 'cy', 'fillOpacity', 'flexGrow', 'flexShrink', 'floodOpacity', 'fontWeight', 'gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart', 'lineHeight', 'opacity', 'order', 'orphans', 'r', 'rx', 'ry', 'shapeImageThreshold', 'stopOpacity', 'strokeDasharray', 'strokeDashoffset', 'strokeMiterlimit', 'strokeOpacity', 'strokeWidth', 'tabSize', 'widows', 'x', 'y', 'zIndex', 'zoom']);
127
+
126
128
  /**
127
129
  * Returns true if the specified string is prefixed by one of an array of
128
130
  * possible prefixes.
@@ -132,10 +134,10 @@ const CSS_PROPERTIES_SUPPORTS_UNITLESS = new Set(['animation', 'animationIterati
132
134
  *
133
135
  * @return {boolean} Whether string has prefix.
134
136
  */
135
-
136
137
  export function hasPrefix(string, prefixes) {
137
138
  return prefixes.some(prefix => string.indexOf(prefix) === 0);
138
139
  }
140
+
139
141
  /**
140
142
  * Returns true if the given prop name should be ignored in attributes
141
143
  * serialization, or false otherwise.
@@ -144,10 +146,10 @@ export function hasPrefix(string, prefixes) {
144
146
  *
145
147
  * @return {boolean} Whether attribute should be ignored.
146
148
  */
147
-
148
149
  function isInternalAttribute(attribute) {
149
150
  return 'key' === attribute || 'children' === attribute;
150
151
  }
152
+
151
153
  /**
152
154
  * Returns the normal form of the element's attribute value for HTML.
153
155
  *
@@ -156,14 +158,11 @@ function isInternalAttribute(attribute) {
156
158
  *
157
159
  * @return {*} Normalized attribute value.
158
160
  */
159
-
160
-
161
161
  function getNormalAttributeValue(attribute, value) {
162
162
  switch (attribute) {
163
163
  case 'style':
164
164
  return renderStyle(value);
165
165
  }
166
-
167
166
  return value;
168
167
  }
169
168
  /**
@@ -172,34 +171,33 @@ function getNormalAttributeValue(attribute, value) {
172
171
  *
173
172
  * List from: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute.
174
173
  */
175
-
176
-
177
174
  const SVG_ATTRIBUTE_WITH_DASHES_LIST = ['accentHeight', 'alignmentBaseline', 'arabicForm', 'baselineShift', 'capHeight', 'clipPath', 'clipRule', 'colorInterpolation', 'colorInterpolationFilters', 'colorProfile', 'colorRendering', 'dominantBaseline', 'enableBackground', 'fillOpacity', 'fillRule', 'floodColor', 'floodOpacity', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontWeight', 'glyphName', 'glyphOrientationHorizontal', 'glyphOrientationVertical', 'horizAdvX', 'horizOriginX', 'imageRendering', 'letterSpacing', 'lightingColor', 'markerEnd', 'markerMid', 'markerStart', 'overlinePosition', 'overlineThickness', 'paintOrder', 'panose1', 'pointerEvents', 'renderingIntent', 'shapeRendering', 'stopColor', 'stopOpacity', 'strikethroughPosition', 'strikethroughThickness', 'strokeDasharray', 'strokeDashoffset', 'strokeLinecap', 'strokeLinejoin', 'strokeMiterlimit', 'strokeOpacity', 'strokeWidth', 'textAnchor', 'textDecoration', 'textRendering', 'underlinePosition', 'underlineThickness', 'unicodeBidi', 'unicodeRange', 'unitsPerEm', 'vAlphabetic', 'vHanging', 'vIdeographic', 'vMathematical', 'vectorEffect', 'vertAdvY', 'vertOriginX', 'vertOriginY', 'wordSpacing', 'writingMode', 'xmlnsXlink', 'xHeight'].reduce((map, attribute) => {
178
175
  // The keys are lower-cased for more robust lookup.
179
176
  map[attribute.toLowerCase()] = attribute;
180
177
  return map;
181
178
  }, {});
179
+
182
180
  /**
183
181
  * This is a map of all case-sensitive SVG attributes. Map(lowercase key => proper case attribute).
184
182
  * The keys are lower-cased for more robust lookup.
185
183
  * Note that this list only contains attributes that contain at least one capital letter.
186
184
  * Lowercase attributes don't need mapping, since we lowercase all attributes by default.
187
185
  */
188
-
189
186
  const CASE_SENSITIVE_SVG_ATTRIBUTES = ['allowReorder', 'attributeName', 'attributeType', 'autoReverse', 'baseFrequency', 'baseProfile', 'calcMode', 'clipPathUnits', 'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes', 'filterUnits', 'glyphRef', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', 'keySplines', 'keyTimes', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform', 'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits', 'refX', 'refY', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY', 'textLength', 'viewBox', 'viewTarget', 'xChannelSelector', 'yChannelSelector'].reduce((map, attribute) => {
190
187
  // The keys are lower-cased for more robust lookup.
191
188
  map[attribute.toLowerCase()] = attribute;
192
189
  return map;
193
190
  }, {});
191
+
194
192
  /**
195
193
  * This is a map of all SVG attributes that have colons.
196
194
  * Keys are lower-cased and stripped of their colons for more robust lookup.
197
195
  */
198
-
199
196
  const SVG_ATTRIBUTES_WITH_COLONS = ['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'xmlns:xlink'].reduce((map, attribute) => {
200
197
  map[attribute.replace(':', '').toLowerCase()] = attribute;
201
198
  return map;
202
199
  }, {});
200
+
203
201
  /**
204
202
  * Returns the normal form of the element's attribute name for HTML.
205
203
  *
@@ -207,18 +205,14 @@ const SVG_ATTRIBUTES_WITH_COLONS = ['xlink:actuate', 'xlink:arcrole', 'xlink:hre
207
205
  *
208
206
  * @return {string} Normalized attribute name.
209
207
  */
210
-
211
208
  function getNormalAttributeName(attribute) {
212
209
  switch (attribute) {
213
210
  case 'htmlFor':
214
211
  return 'for';
215
-
216
212
  case 'className':
217
213
  return 'class';
218
214
  }
219
-
220
215
  const attributeLowerCase = attribute.toLowerCase();
221
-
222
216
  if (CASE_SENSITIVE_SVG_ATTRIBUTES[attributeLowerCase]) {
223
217
  return CASE_SENSITIVE_SVG_ATTRIBUTES[attributeLowerCase];
224
218
  } else if (SVG_ATTRIBUTE_WITH_DASHES_LIST[attributeLowerCase]) {
@@ -226,9 +220,9 @@ function getNormalAttributeName(attribute) {
226
220
  } else if (SVG_ATTRIBUTES_WITH_COLONS[attributeLowerCase]) {
227
221
  return SVG_ATTRIBUTES_WITH_COLONS[attributeLowerCase];
228
222
  }
229
-
230
223
  return attributeLowerCase;
231
224
  }
225
+
232
226
  /**
233
227
  * Returns the normal form of the style property name for HTML.
234
228
  *
@@ -240,19 +234,16 @@ function getNormalAttributeName(attribute) {
240
234
  *
241
235
  * @return {string} Normalized property name.
242
236
  */
243
-
244
-
245
237
  function getNormalStylePropertyName(property) {
246
238
  if (property.startsWith('--')) {
247
239
  return property;
248
240
  }
249
-
250
241
  if (hasPrefix(property, ['ms', 'O', 'Moz', 'Webkit'])) {
251
242
  return '-' + kebabCase(property);
252
243
  }
253
-
254
244
  return kebabCase(property);
255
245
  }
246
+
256
247
  /**
257
248
  * Returns the normal form of the style property value for HTML. Appends a
258
249
  * default pixel unit if numeric, not a unitless property, and not zero.
@@ -262,15 +253,13 @@ function getNormalStylePropertyName(property) {
262
253
  *
263
254
  * @return {*} Normalized property value.
264
255
  */
265
-
266
-
267
256
  function getNormalStylePropertyValue(property, value) {
268
257
  if (typeof value === 'number' && 0 !== value && !CSS_PROPERTIES_SUPPORTS_UNITLESS.has(property)) {
269
258
  return value + 'px';
270
259
  }
271
-
272
260
  return value;
273
261
  }
262
+
274
263
  /**
275
264
  * Serializes a React element to string.
276
265
  *
@@ -280,74 +269,60 @@ function getNormalStylePropertyValue(property, value) {
280
269
  *
281
270
  * @return {string} Serialized element.
282
271
  */
283
-
284
-
285
272
  export function renderElement(element, context, legacyContext = {}) {
286
273
  if (null === element || undefined === element || false === element) {
287
274
  return '';
288
275
  }
289
-
290
276
  if (Array.isArray(element)) {
291
277
  return renderChildren(element, context, legacyContext);
292
278
  }
293
-
294
279
  switch (typeof element) {
295
280
  case 'string':
296
281
  return escapeHTML(element);
297
-
298
282
  case 'number':
299
283
  return element.toString();
300
284
  }
301
-
302
285
  const {
303
286
  type,
304
287
  props
305
- } =
306
- /** @type {{type?: any, props?: any}} */
288
+ } = /** @type {{type?: any, props?: any}} */
307
289
  element;
308
-
309
290
  switch (type) {
310
291
  case StrictMode:
311
292
  case Fragment:
312
293
  return renderChildren(props.children, context, legacyContext);
313
-
314
294
  case RawHTML:
315
295
  const {
316
296
  children,
317
297
  ...wrapperProps
318
298
  } = props;
319
- return renderNativeComponent(!Object.keys(wrapperProps).length ? null : 'div', { ...wrapperProps,
299
+ return renderNativeComponent(!Object.keys(wrapperProps).length ? null : 'div', {
300
+ ...wrapperProps,
320
301
  dangerouslySetInnerHTML: {
321
302
  __html: children
322
303
  }
323
304
  }, context, legacyContext);
324
305
  }
325
-
326
306
  switch (typeof type) {
327
307
  case 'string':
328
308
  return renderNativeComponent(type, props, context, legacyContext);
329
-
330
309
  case 'function':
331
310
  if (type.prototype && typeof type.prototype.render === 'function') {
332
311
  return renderComponent(type, props, context, legacyContext);
333
312
  }
334
-
335
313
  return renderElement(type(props, legacyContext), context, legacyContext);
336
314
  }
337
-
338
315
  switch (type && type.$$typeof) {
339
316
  case Provider.$$typeof:
340
317
  return renderChildren(props.children, props.value, legacyContext);
341
-
342
318
  case Consumer.$$typeof:
343
319
  return renderElement(props.children(context || type._currentValue), context, legacyContext);
344
-
345
320
  case ForwardRef.$$typeof:
346
321
  return renderElement(type.render(props), context, legacyContext);
347
322
  }
348
-
349
323
  return '';
350
324
  }
325
+
351
326
  /**
352
327
  * Serializes a native component type to string.
353
328
  *
@@ -359,10 +334,8 @@ export function renderElement(element, context, legacyContext = {}) {
359
334
  *
360
335
  * @return {string} Serialized element.
361
336
  */
362
-
363
337
  export function renderNativeComponent(type, props, context, legacyContext = {}) {
364
338
  let content = '';
365
-
366
339
  if (type === 'textarea' && props.hasOwnProperty('value')) {
367
340
  // Textarea children can be assigned as value prop. If it is, render in
368
341
  // place of children. Ensure to omit so it is not assigned as attribute
@@ -379,19 +352,16 @@ export function renderNativeComponent(type, props, context, legacyContext = {})
379
352
  } else if (typeof props.children !== 'undefined') {
380
353
  content = renderChildren(props.children, context, legacyContext);
381
354
  }
382
-
383
355
  if (!type) {
384
356
  return content;
385
357
  }
386
-
387
358
  const attributes = renderAttributes(props);
388
-
389
359
  if (SELF_CLOSING_TAGS.has(type)) {
390
360
  return '<' + type + attributes + '/>';
391
361
  }
392
-
393
362
  return '<' + type + attributes + '>' + content + '</' + type + '>';
394
363
  }
364
+
395
365
  /** @typedef {import('./react').WPComponent} WPComponent */
396
366
 
397
367
  /**
@@ -404,25 +374,20 @@ export function renderNativeComponent(type, props, context, legacyContext = {})
404
374
  *
405
375
  * @return {string} Serialized element
406
376
  */
407
-
408
377
  export function renderComponent(Component, props, context, legacyContext = {}) {
409
- const instance = new
410
- /** @type {import('react').ComponentClass} */
378
+ const instance = new /** @type {import('react').ComponentClass} */
411
379
  Component(props, legacyContext);
412
-
413
- if (typeof // Ignore reason: Current prettier reformats parens and mangles type assertion
380
+ if (typeof
381
+ // Ignore reason: Current prettier reformats parens and mangles type assertion
414
382
  // prettier-ignore
415
-
416
383
  /** @type {{getChildContext?: () => unknown}} */
417
384
  instance.getChildContext === 'function') {
418
- Object.assign(legacyContext,
419
- /** @type {{getChildContext?: () => unknown}} */
420
- instance.getChildContext());
385
+ Object.assign(legacyContext, /** @type {{getChildContext?: () => unknown}} */instance.getChildContext());
421
386
  }
422
-
423
387
  const html = renderElement(instance.render(), context, legacyContext);
424
388
  return html;
425
389
  }
390
+
426
391
  /**
427
392
  * Serializes an array of children to string.
428
393
  *
@@ -432,18 +397,16 @@ export function renderComponent(Component, props, context, legacyContext = {}) {
432
397
  *
433
398
  * @return {string} Serialized children.
434
399
  */
435
-
436
400
  function renderChildren(children, context, legacyContext = {}) {
437
401
  let result = '';
438
402
  children = Array.isArray(children) ? children : [children];
439
-
440
403
  for (let i = 0; i < children.length; i++) {
441
404
  const child = children[i];
442
405
  result += renderElement(child, context, legacyContext);
443
406
  }
444
-
445
407
  return result;
446
408
  }
409
+
447
410
  /**
448
411
  * Renders a props object as a string of HTML attributes.
449
412
  *
@@ -451,57 +414,51 @@ function renderChildren(children, context, legacyContext = {}) {
451
414
  *
452
415
  * @return {string} Attributes string.
453
416
  */
454
-
455
-
456
417
  export function renderAttributes(props) {
457
418
  let result = '';
458
-
459
419
  for (const key in props) {
460
420
  const attribute = getNormalAttributeName(key);
461
-
462
421
  if (!isValidAttributeName(attribute)) {
463
422
  continue;
464
423
  }
424
+ let value = getNormalAttributeValue(key, props[key]);
465
425
 
466
- let value = getNormalAttributeValue(key, props[key]); // If value is not of serializeable type, skip.
467
-
426
+ // If value is not of serializeable type, skip.
468
427
  if (!ATTRIBUTES_TYPES.has(typeof value)) {
469
428
  continue;
470
- } // Don't render internal attribute names.
471
-
429
+ }
472
430
 
431
+ // Don't render internal attribute names.
473
432
  if (isInternalAttribute(key)) {
474
433
  continue;
475
434
  }
435
+ const isBooleanAttribute = BOOLEAN_ATTRIBUTES.has(attribute);
476
436
 
477
- const isBooleanAttribute = BOOLEAN_ATTRIBUTES.has(attribute); // Boolean attribute should be omitted outright if its value is false.
478
-
437
+ // Boolean attribute should be omitted outright if its value is false.
479
438
  if (isBooleanAttribute && value === false) {
480
439
  continue;
481
440
  }
441
+ const isMeaningfulAttribute = isBooleanAttribute || hasPrefix(key, ['data-', 'aria-']) || ENUMERATED_ATTRIBUTES.has(attribute);
482
442
 
483
- const isMeaningfulAttribute = isBooleanAttribute || hasPrefix(key, ['data-', 'aria-']) || ENUMERATED_ATTRIBUTES.has(attribute); // Only write boolean value as attribute if meaningful.
484
-
443
+ // Only write boolean value as attribute if meaningful.
485
444
  if (typeof value === 'boolean' && !isMeaningfulAttribute) {
486
445
  continue;
487
446
  }
447
+ result += ' ' + attribute;
488
448
 
489
- result += ' ' + attribute; // Boolean attributes should write attribute name, but without value.
449
+ // Boolean attributes should write attribute name, but without value.
490
450
  // Mere presence of attribute name is effective truthiness.
491
-
492
451
  if (isBooleanAttribute) {
493
452
  continue;
494
453
  }
495
-
496
454
  if (typeof value === 'string') {
497
455
  value = escapeAttribute(value);
498
456
  }
499
-
500
457
  result += '="' + value + '"';
501
458
  }
502
-
503
459
  return result;
504
460
  }
461
+
505
462
  /**
506
463
  * Renders a style object as a string attribute value.
507
464
  *
@@ -509,33 +466,26 @@ export function renderAttributes(props) {
509
466
  *
510
467
  * @return {string} Style attribute value.
511
468
  */
512
-
513
469
  export function renderStyle(style) {
514
470
  // Only generate from object, e.g. tolerate string value.
515
471
  if (!isPlainObject(style)) {
516
472
  return style;
517
473
  }
518
-
519
474
  let result;
520
-
521
475
  for (const property in style) {
522
476
  const value = style[property];
523
-
524
477
  if (null === value || undefined === value) {
525
478
  continue;
526
479
  }
527
-
528
480
  if (result) {
529
481
  result += ';';
530
482
  } else {
531
483
  result = '';
532
484
  }
533
-
534
485
  const normalName = getNormalStylePropertyName(property);
535
486
  const normalValue = getNormalStylePropertyValue(property, value);
536
487
  result += normalName + ':' + normalValue;
537
488
  }
538
-
539
489
  return result;
540
490
  }
541
491
  export default renderElement;