Skip to content

Commit fab1517

Browse files
wadackelDaniel15
authored andcommitted
Add feature for SVG attributes conversion (#136)
* Remove unnecessary whitespaces * Add test for convert of svg attributes * Refactor object iteration * Add SVG attributes conversion
1 parent 5c387c5 commit fab1517

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

src/htmltojsx.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,37 @@ var ELEMENT_ATTRIBUTE_MAPPING = {
3636
};
3737

3838
var HTMLDOMPropertyConfig = require('react-dom/lib/HTMLDOMPropertyConfig');
39+
var SVGDOMPropertyConfig = require('react-dom/lib/SVGDOMPropertyConfig');
3940

40-
// Populate property map with ReactJS's attribute and property mappings
41-
// TODO handle/use .Properties value eg: MUST_USE_PROPERTY is not HTML attr
42-
for (var propname in HTMLDOMPropertyConfig.Properties) {
43-
if (!HTMLDOMPropertyConfig.Properties.hasOwnProperty(propname)) {
44-
continue;
41+
/**
42+
* Iterates over elements of object invokes iteratee for each element
43+
*
44+
* @param {object} obj Collection object
45+
* @param {function} iteratee Callback function called in iterative processing
46+
* @param {any} context This arg (aka Context)
47+
*/
48+
function eachObj(obj, iteratee, context) {
49+
for (var key in obj) {
50+
if (obj.hasOwnProperty(key)) {
51+
iteratee.call(context || obj, key, obj[key]);
52+
}
4553
}
54+
}
4655

47-
var mapFrom = HTMLDOMPropertyConfig.DOMAttributeNames[propname] || propname.toLowerCase();
56+
// Populate property map with ReactJS's attribute and property mappings
57+
// TODO handle/use .Properties value eg: MUST_USE_PROPERTY is not HTML attr
58+
function mappingAttributesFromReactConfig(config) {
59+
eachObj(config.Properties, function(propname) {
60+
var mapFrom = config.DOMAttributeNames[propname] || propname.toLowerCase();
4861

49-
if (!ATTRIBUTE_MAPPING[mapFrom])
50-
ATTRIBUTE_MAPPING[mapFrom] = propname;
62+
if (!ATTRIBUTE_MAPPING[mapFrom])
63+
ATTRIBUTE_MAPPING[mapFrom] = propname;
64+
});
5165
}
5266

67+
mappingAttributesFromReactConfig(HTMLDOMPropertyConfig);
68+
mappingAttributesFromReactConfig(SVGDOMPropertyConfig);
69+
5370
/**
5471
* Repeats a string a certain number of times.
5572
* Also: the future is bright and consists of native string repetition:
@@ -562,12 +579,9 @@ StyleParser.prototype = {
562579
*/
563580
toJSXString: function() {
564581
var output = [];
565-
for (var key in this.styles) {
566-
if (!this.styles.hasOwnProperty(key)) {
567-
continue;
568-
}
569-
output.push(this.toJSXKey(key) + ': ' + this.toJSXValue(this.styles[key]));
570-
}
582+
eachObj(this.styles, function(key, value) {
583+
output.push(this.toJSXKey(key) + ': ' + this.toJSXValue(value));
584+
}, this);
571585
return output.join(', ');
572586
},
573587

test/htmltojsx-test.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,19 @@ describe('htmltojsx', function() {
142142
expect(converter.convert('<div style="-moz-hyphens: auto; -webkit-hyphens: auto">Test</div>').trim())
143143
.toBe('<div style={{MozHyphens: \'auto\', WebkitHyphens: \'auto\'}}>Test</div>');
144144
});
145-
145+
146146
it('should convert uppercase vendor-prefix "style" attributes', function() {
147147
var converter = new HTMLtoJSX({ createClass: false });
148148
expect(converter.convert('<div style="-MOZ-HYPHENS: auto; -WEBKIT-HYPHENS: auto">Test</div>').trim())
149149
.toBe('<div style={{MozHyphens: \'auto\', WebkitHyphens: \'auto\'}}>Test</div>');
150150
});
151-
151+
152152
it('should convert "style" attributes with vendor prefix-like strings in the middle and mixed case', function() {
153153
var converter = new HTMLtoJSX({ createClass: false });
154154
expect(converter.convert('<div style="myclass-MOZ-HYPHENS: auto; myclass-WEBKIT-HYPHENS: auto">Test</div>').trim())
155155
.toBe('<div style={{myclassMozHyphens: \'auto\', myclassWebkitHyphens: \'auto\'}}>Test</div>');
156156
});
157-
157+
158158
it('should convert -ms- prefix "style" attributes', function() {
159159
var converter = new HTMLtoJSX({ createClass: false });
160160
expect(converter.convert('<div style="-ms-hyphens: auto">Test</div>').trim())
@@ -170,7 +170,7 @@ describe('htmltojsx', function() {
170170
it('should convert uppercase "style" attributes', function() {
171171
var converter = new HTMLtoJSX({ createClass: false });
172172
expect(converter.convert('<div style="TEXT-ALIGN: center">Test</div>').trim())
173-
.toBe('<div style={{textAlign: \'center\'}}>Test</div>');
173+
.toBe('<div style={{textAlign: \'center\'}}>Test</div>');
174174
});
175175

176176
it('should convert "class" attribute', function() {
@@ -232,6 +232,12 @@ describe('htmltojsx', function() {
232232
expect(converter.convert('<input type="checkbox" checked>').trim())
233233
.toBe('<input type="checkbox" defaultChecked />');
234234
});
235+
236+
it('should convert SVG attributes', function() {
237+
var converter = new HTMLtoJSX({ createClass: false });
238+
expect(converter.convert('<svg height="100" width="100"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" fill-rule="evenodd"/></svg>').trim())
239+
.toBe('<svg height={100} width={100}><circle cx={50} cy={50} r={40} stroke="black" strokeWidth={3} fill="red" fillRule="evenodd" /></svg>');
240+
});
235241
});
236242

237243
describe('special tags', function() {

0 commit comments

Comments
 (0)