@wordpress/element 5.15.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.
- package/CHANGELOG.md +4 -0
- package/build/create-interpolate-element.js +19 -49
- package/build/create-interpolate-element.js.map +1 -1
- package/build/index.js +0 -11
- package/build/index.js.map +1 -1
- package/build/platform.android.js +3 -4
- package/build/platform.android.js.map +1 -1
- package/build/platform.ios.js +3 -4
- package/build/platform.ios.js.map +1 -1
- package/build/platform.js +0 -2
- package/build/platform.js.map +1 -1
- package/build/raw-html.js +5 -6
- package/build/raw-html.js.map +1 -1
- package/build/react-platform.js +0 -2
- package/build/react-platform.js.map +1 -1
- package/build/react-platform.native.js +0 -3
- package/build/react-platform.native.js.map +1 -1
- package/build/react.js +1 -7
- package/build/react.js.map +1 -1
- package/build/serialize.js +37 -100
- package/build/serialize.js.map +1 -1
- package/build/utils.js +0 -4
- package/build/utils.js.map +1 -1
- package/build-module/create-interpolate-element.js +19 -47
- package/build-module/create-interpolate-element.js.map +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/platform.android.js +2 -2
- package/build-module/platform.android.js.map +1 -1
- package/build-module/platform.ios.js +2 -2
- package/build-module/platform.ios.js.map +1 -1
- package/build-module/platform.js +0 -1
- package/build-module/platform.js.map +1 -1
- package/build-module/raw-html.js +6 -4
- package/build-module/raw-html.js.map +1 -1
- package/build-module/react-platform.js +8 -8
- package/build-module/react-platform.js.map +1 -1
- package/build-module/react-platform.native.js +1 -1
- package/build-module/react-platform.native.js.map +1 -1
- package/build-module/react.js +31 -33
- package/build-module/react.js.map +1 -1
- package/build-module/serialize.js +39 -89
- package/build-module/serialize.js.map +1 -1
- package/build-module/utils.js +0 -2
- package/build-module/utils.js.map +1 -1
- package/build-types/platform.d.ts +2 -2
- package/build-types/react-platform.d.ts +8 -8
- package/build-types/react-platform.d.ts.map +1 -1
- package/build-types/react.d.ts +29 -29
- package/build-types/react.d.ts.map +1 -1
- package/package.json +3 -3
- 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', {
|
|
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
|
-
|
|
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
|
-
|
|
467
|
-
|
|
426
|
+
// If value is not of serializeable type, skip.
|
|
468
427
|
if (!ATTRIBUTES_TYPES.has(typeof value)) {
|
|
469
428
|
continue;
|
|
470
|
-
}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|