Skip to content

Commit f0fbbff

Browse files
feat: upgrade react-property to get react-dom 17 DOM/SVG properties
remarkablemark/react-dom-core#14
1 parent 9ebecd4 commit f0fbbff

File tree

4 files changed

+35
-45
lines changed

4 files changed

+35
-45
lines changed

lib/attributes-to-props.js

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
var reactProperty = require('react-property');
22
var utilities = require('./utilities');
33

4-
var hasOwnProperty = Object.prototype.hasOwnProperty;
5-
64
/**
75
* Converts HTML/SVG DOM attributes to React props.
86
*
97
* @param {object} [attributes={}] - HTML/SVG DOM attributes.
108
* @return {object} - React props.
119
*/
12-
function attributesToProps(attributes) {
10+
module.exports = function attributesToProps(attributes) {
1311
attributes = attributes || {};
1412

1513
var attributeName;
1614
var attributeNameLowerCased;
1715
var attributeValue;
18-
var property;
16+
var propName;
17+
var propertyInfo;
1918
var props = {};
2019

2120
for (attributeName in attributes) {
@@ -27,22 +26,23 @@ function attributesToProps(attributes) {
2726
continue;
2827
}
2928

30-
// convert HTML attribute to React prop
29+
// convert HTML/SVG attribute to React prop
3130
attributeNameLowerCased = attributeName.toLowerCase();
32-
if (hasOwnProperty.call(reactProperty.html, attributeNameLowerCased)) {
33-
property = reactProperty.html[attributeNameLowerCased];
34-
props[property.propertyName] =
35-
property.hasBooleanValue ||
36-
(property.hasOverloadedBooleanValue && !attributeValue)
37-
? true
38-
: attributeValue;
39-
continue;
40-
}
41-
42-
// convert SVG attribute to React prop
43-
if (hasOwnProperty.call(reactProperty.svg, attributeName)) {
44-
property = reactProperty.svg[attributeName];
45-
props[property.propertyName] = attributeValue;
31+
propName = reactProperty.possibleStandardNames[attributeNameLowerCased];
32+
33+
if (propName) {
34+
props[propName] = attributeValue;
35+
propertyInfo = reactProperty.getPropertyInfo(propName);
36+
switch (propertyInfo && propertyInfo.type) {
37+
case reactProperty.BOOLEAN:
38+
props[propName] = true;
39+
break;
40+
case reactProperty.OVERLOADED_BOOLEAN:
41+
if (attributeValue === '') {
42+
props[propName] = true;
43+
}
44+
break;
45+
}
4646
continue;
4747
}
4848

@@ -56,6 +56,4 @@ function attributesToProps(attributes) {
5656
utilities.setStyleProp(attributes.style, props);
5757

5858
return props;
59-
}
60-
61-
module.exports = attributesToProps;
59+
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"dependencies": {
4040
"domhandler": "4.2.2",
4141
"html-dom-parser": "1.0.2",
42-
"react-property": "1.0.2",
42+
"react-property": "2.0.0",
4343
"style-to-js": "1.1.0"
4444
},
4545
"devDependencies": {

test/__snapshots__/attributes-to-props.test.js.snap

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ Object {
3535
"controls": true,
3636
"default": true,
3737
"disabled": true,
38+
"draggable": "false",
3839
"formNoValidate": true,
3940
"hidden": true,
4041
"ismap": "",
4142
"itemScope": true,
4243
"loop": true,
4344
"multiple": true,
4445
"muted": true,
46+
"noModule": true,
4547
"noValidate": true,
46-
"nomodule": "",
4748
"open": true,
4849
"playsInline": true,
4950
"readOnly": true,
@@ -88,21 +89,12 @@ Object {
8889
}
8990
`;
9091

91-
exports[`attributesToProps with SVG attribute keeps incorrectly capitalized attributes 1`] = `
92-
Object {
93-
"XLINK:HREF": "#",
94-
"YChannelSelector": "G",
95-
"ZoomAndPan": "disable",
96-
}
97-
`;
98-
9992
exports[`attributesToProps with custom attribute converts attributes named after Object properties 1`] = `
10093
Object {
10194
"__defineGetter__": "",
10295
"__defineSetter__": "",
10396
"__lookupGetter__": "",
10497
"__lookupSetter__": "",
105-
"constructor": "",
10698
"hasOwnProperty": "",
10799
"isPrototypeOf": "",
108100
"propertyIsEnumerable": "",

test/attributes-to-props.test.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ describe('attributesToProps with HTML attribute', () => {
7575
checked: 'true',
7676
controls: '',
7777
default: '',
78+
draggable: 'false',
7879
disabled: 'disabled',
7980
formnovalidate: 'true',
8081
hidden: 'true',
@@ -118,13 +119,22 @@ describe('attributesToProps with SVG attribute', () => {
118119
expect(attributesToProps(attributes)).toMatchSnapshot();
119120
});
120121

121-
it('keeps incorrectly capitalized attributes', () => {
122+
/**
123+
* SVG elements and attributes should all be entered in the case shown here since XML is case-sensitive (unlike HTML).
124+
*
125+
* @see {@link https://developer.mozilla.org/docs/Web/SVG/Tutorial/Introduction#before_you_start}
126+
*/
127+
it('fixes incorrectly capitalized attributes', () => {
122128
const attributes = {
123129
'XLINK:HREF': '#',
124130
YChannelSelector: 'G',
125131
ZoomAndPan: 'disable'
126132
};
127-
expect(attributesToProps(attributes)).toMatchSnapshot();
133+
expect(attributesToProps(attributes)).toEqual({
134+
xlinkHref: '#',
135+
yChannelSelector: 'G',
136+
zoomAndPan: 'disable'
137+
});
128138
});
129139
});
130140

@@ -164,7 +174,6 @@ describe('attributesToProps with custom attribute', () => {
164174
__lookupGetter__: '',
165175
__lookupSetter__: '',
166176
__proto__: '',
167-
constructor: '',
168177
hasOwnProperty: '',
169178
isPrototypeOf: '',
170179
propertyIsEnumerable: '',
@@ -194,13 +203,4 @@ describe('utilities.PRESERVE_CUSTOM_ATTRIBUTES=false', () => {
194203
};
195204
expect(attributesToProps(attributes)).toEqual(emptyProps);
196205
});
197-
198-
it('omits incorrectly capitalized attributes', () => {
199-
const attributes = {
200-
'XLINK:HREF': '#',
201-
YChannelSelector: 'G',
202-
ZoomAndPan: 'disable'
203-
};
204-
expect(attributesToProps(attributes)).toEqual(emptyProps);
205-
});
206206
});

0 commit comments

Comments
 (0)