Skip to content

issue #8 : case insensitive css attributes, import react's attribute map... #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 10, 2015
Merged
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
21 changes: 21 additions & 0 deletions src/htmltojsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
},

Expand Down
60 changes: 60 additions & 0 deletions test/htmltojsx-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,42 @@ describe('htmltojsx', function() {
.toBe('<div style={{fontSize: \'12pt\'}}>Test</div>');
});

it('should convert vendor-prefix "style" attributes', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div style="-moz-hyphens: auto; -webkit-hyphens: auto">Test</div>').trim())
.toBe('<div style={{MozHyphens: \'auto\', WebkitHyphens: \'auto\'}}>Test</div>');
});

it('should convert uppercase vendor-prefix "style" attributes', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div style="-MOZ-HYPHENS: auto; -WEBKIT-HYPHENS: auto">Test</div>').trim())
.toBe('<div style={{MozHyphens: \'auto\', WebkitHyphens: \'auto\'}}>Test</div>');
});

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('<div style="myclass-MOZ-HYPHENS: auto; myclass-WEBKIT-HYPHENS: auto">Test</div>').trim())
.toBe('<div style={{myclassMozHyphens: \'auto\', myclassWebkitHyphens: \'auto\'}}>Test</div>');
});

it('should convert -ms- prefix "style" attributes', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div style="-ms-hyphens: auto">Test</div>').trim())
.toBe('<div style={{msHyphens: \'auto\'}}>Test</div>');
});

it('should convert "style" attributes with -ms- in the middle', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div style="myclass-ms-hyphens: auto">Test</div>').trim())
.toBe('<div style={{myclassMsHyphens: \'auto\'}}>Test</div>');
});

it('should convert uppercase "style" attributes', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div style="TEXT-ALIGN: center">Test</div>').trim())
.toBe('<div style={{textAlign: \'center\'}}>Test</div>');
});

it('should convert "class" attribute', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<div class="awesome">Test</div>').trim())
Expand All @@ -149,6 +185,30 @@ describe('htmltojsx', function() {
.toBe('<label htmlFor="potato">Test</label>');
});

it('should convert "maxlength" attribute to "maxLength"', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<input maxlength=2></input>').trim())
.toBe('<input maxLength={2} />');
});

it('should convert "http-equiv" attribute to "httpEquiv"', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<meta http-equiv="refresh">').trim())
.toBe('<meta httpEquiv="refresh" />');
});

it('should convert "accept-charset" attribute to "acceptCharset"', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<form accept-charset="UTF-8">Test</form>').trim())
.toBe('<form acceptCharset="UTF-8">Test</form>');
});

it('should convert "enctype" attribute to "encType"', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<form method="post" enctype="application/x-www-form-urlencoded">Test</form>').trim())
.toBe('<form method="post" encType="application/x-www-form-urlencoded">Test</form>');
});

it('should maintain value-less attributes', function() {
var converter = new HTMLtoJSX({ createClass: false });
expect(converter.convert('<input disabled>').trim())
Expand Down