diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0f09989 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/package.json b/package.json index 883acec..d6fc85a 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "src/htmltojsx.js", "bin": "src/cli.js", "dependencies": { + "react": "~0.13.0", "yargs": "~1.3.1", "jsdom": "~4.4.0" }, diff --git a/src/htmltojsx.js b/src/htmltojsx.js index b278bda..1b28884 100644 --- a/src/htmltojsx.js +++ b/src/htmltojsx.js @@ -35,6 +35,21 @@ var ELEMENT_ATTRIBUTE_MAPPING = { } }; +var HTMLDOMPropertyConfig = require('react/lib/HTMLDOMPropertyConfig'); + +// Populate property map with ReactJS's attribute and property mappings +// TODO handle/use .Properties value eg: MUST_USE_PROPERTY is not HTML attr +for (var propname in HTMLDOMPropertyConfig.Properties) { + if (!HTMLDOMPropertyConfig.Properties.hasOwnProperty(propname)) { + continue; + } + + var mapFrom = HTMLDOMPropertyConfig.DOMAttributeNames[propname] || propname.toLowerCase(); + + if (!ATTRIBUTE_MAPPING[mapFrom]) + ATTRIBUTE_MAPPING[mapFrom] = propname; +} + /** * Repeats a string a certain number of times. * Also: the future is bright and consists of native string repetition: @@ -468,6 +483,8 @@ StyleParser.prototype = { var key = style.substr(0, firstColon); var value = style.substr(firstColon + 1).trim(); if (key !== '') { + // Style key should be case insensitive + key = key.toLowerCase(); this.styles[key] = value; } }, this); @@ -497,6 +514,10 @@ StyleParser.prototype = { * @return {string} JSX style key */ toJSXKey: function(key) { + // Don't capitalize -ms- prefix + if(/^-ms-/.test(key)) { + key = key.substr(1); + } return hyphenToCamelCase(key); }, diff --git a/test/htmltojsx-test.js b/test/htmltojsx-test.js index c5563bb..87aa574 100644 --- a/test/htmltojsx-test.js +++ b/test/htmltojsx-test.js @@ -137,6 +137,42 @@ describe('htmltojsx', function() { .toBe('
Test
'); }); + it('should convert vendor-prefix "style" attributes', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert uppercase vendor-prefix "style" attributes', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert "style" attributes with vendor prefix-like strings in the middle and mixed case', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert -ms- prefix "style" attributes', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert "style" attributes with -ms- in the middle', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert uppercase "style" attributes', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + it('should convert "class" attribute', function() { var converter = new HTMLtoJSX({ createClass: false }); expect(converter.convert('
Test
').trim()) @@ -149,6 +185,30 @@ describe('htmltojsx', function() { .toBe(''); }); + it('should convert "maxlength" attribute to "maxLength"', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('').trim()) + .toBe(''); + }); + + it('should convert "http-equiv" attribute to "httpEquiv"', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('').trim()) + .toBe(''); + }); + + it('should convert "accept-charset" attribute to "acceptCharset"', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + + it('should convert "enctype" attribute to "encType"', function() { + var converter = new HTMLtoJSX({ createClass: false }); + expect(converter.convert('
Test
').trim()) + .toBe('
Test
'); + }); + it('should maintain value-less attributes', function() { var converter = new HTMLtoJSX({ createClass: false }); expect(converter.convert('').trim())